APICHANGE: removed page comments from core. Please see the github.com account for page comments functionality

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@114821 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Will Rossiter 2010-12-11 05:43:08 +00:00
parent 073563a24e
commit 815e9efd94
13 changed files with 232 additions and 264 deletions

View File

@ -26,8 +26,7 @@ class ContentController extends Controller {
'widget/$ID!' => 'handleWidget' 'widget/$ID!' => 'handleWidget'
); );
public static $allowed_actions = array ( public static $allowed_actions = array(
'PageComments',
'successfullyinstalled', 'successfullyinstalled',
'deleteinstallfiles' // secured through custom code 'deleteinstallfiles' // secured through custom code
); );
@ -383,21 +382,6 @@ HTML;
} }
} }
/**
* Returns a page comment system
*/
function PageComments() {
$hasComments = DB::query("SELECT COUNT(*) FROM \"PageComment\" WHERE \"PageComment\".\"ParentID\" = '". Convert::raw2sql($this->ID) . "'")->value();
if(($this->data() && $this->data()->ProvideComments) || ($hasComments > 0 && PageCommentInterface::$show_comments_when_disabled)) {
return new PageCommentInterface($this, 'PageComments', $this->data());
} else {
if(isset($_REQUEST['executeForm']) && $_REQUEST['executeForm'] == 'PageComments.PostCommentForm') {
echo "Comments have been disabled for this page";
die();
}
}
}
function SiteConfig() { function SiteConfig() {
if(method_exists($this->dataRecord, 'getSiteConfig')) { if(method_exists($this->dataRecord, 'getSiteConfig')) {
return $this->dataRecord->getSiteConfig(); return $this->dataRecord->getSiteConfig();
@ -541,5 +525,3 @@ HTML
); );
} }
} }
?>

View File

@ -453,7 +453,6 @@ class DataObjectSet extends ViewableData implements IteratorAggregate, Countable
/** /**
* Allows us to use multiple pagination GET variables on the same page (eg. if you have search results and page comments on a single page) * Allows us to use multiple pagination GET variables on the same page (eg. if you have search results and page comments on a single page)
* *
* Example: @see PageCommentInterface::Comments()
* @param string $var The variable to go in the GET string (Defaults to 'start') * @param string $var The variable to go in the GET string (Defaults to 'start')
*/ */
public function setPaginationGetVar($var) { public function setPaginationGetVar($var) {
@ -836,7 +835,7 @@ class DataObjectSet extends ViewableData implements IteratorAggregate, Countable
*/ */
public function sort($fieldname, $direction = "ASC") { public function sort($fieldname, $direction = "ASC") {
if($this->items) { if($this->items) {
if (preg_match('/(.+?)(\s+?)(A|DE)SC$/', $fieldname, $matches)) { if (is_string($fieldname) && preg_match('/(.+?)(\s+?)(A|DE)SC$/', $fieldname, $matches)) {
$fieldname = $matches[1]; $fieldname = $matches[1];
$direction = $matches[3].'SC'; $direction = $matches[3].'SC';
} }
@ -1011,24 +1010,31 @@ class DataObjectSet extends ViewableData implements IteratorAggregate, Countable
/** /**
* Sort a 2D array by particular column. * Sort a 2D array by particular column.
* @param array $data The array to sort. * @param array $data The array to sort.
* @param string $column The name of the column you wish to sort by. * @param mixed $column The name of the column you wish to sort by, or an array of column=>directions to sort by.
* @param string $direction Direction to sort by, either "ASC" or "DESC". * @param string $direction Direction to sort by, either "ASC" or "DESC".
* @param boolean $preserveIndexes Preserve indexes * @param boolean $preserveIndexes Preserve indexes
*/ */
function column_sort(&$data, $column, $direction = "ASC", $preserveIndexes = true) { function column_sort(&$data, $column, $direction = "ASC", $preserveIndexes = true) {
global $column_sort_field, $column_sort_multiplier; global $column_sort_field;
// We have to keep numeric diretions for legacy // if we were only given a string for column, move it into an array
if(is_numeric($direction)) { if (is_string($column)) $column = array($column => $direction);
$column_sort_multiplier = $direction;
} elseif($direction == "ASC") { // convert directions to integers
$column_sort_multiplier = 1; foreach ($column as $k => $v) {
} elseif($direction == "DESC") { if ($v == 'ASC') {
$column_sort_multiplier = -1; $column[$k] = 1;
} else { }
$column_sort_multiplier = 0; elseif ($v == 'DESC') {
$column[$k] = -1;
}
elseif (!is_numeric($v)) {
$column[$k] = 0;
}
} }
$column_sort_field = $column; $column_sort_field = $column;
if($preserveIndexes) { if($preserveIndexes) {
uasort($data, "column_sort_callback_basic"); uasort($data, "column_sort_callback_basic");
} else { } else {
@ -1040,12 +1046,23 @@ function column_sort(&$data, $column, $direction = "ASC", $preserveIndexes = tru
* Callback used by column_sort * Callback used by column_sort
*/ */
function column_sort_callback_basic($a, $b) { function column_sort_callback_basic($a, $b) {
global $column_sort_field, $column_sort_multiplier; global $column_sort_field;
$result = 0;
if($a->$column_sort_field == $b->$column_sort_field) { // loop through each sort field
$result = 0; foreach ($column_sort_field as $field => $multiplier) {
} else { // if A < B then no further examination is necessary
$result = ($a->$column_sort_field < $b->$column_sort_field) ? -1 * $column_sort_multiplier : 1 * $column_sort_multiplier; if ($a->$field < $b->$field) {
$result = -1 * $multiplier;
break;
}
// if A > B then no further examination is necessary
elseif ($a->$field > $b->$field) {
$result = $multiplier;
break;
}
// A == B means we need to compare the two using the next field
// if this was the last field, then function returns that objects
// are equivalent
} }
return $result; return $result;

View File

@ -637,6 +637,9 @@ abstract class SS_Database {
/** /**
* Show a message about database alteration * Show a message about database alteration
*
* @param string message to display
* @param string type one of [created|changed|repaired|obsolete|deleted|error]
*/ */
function alterationMessage($message,$type=""){ function alterationMessage($message,$type=""){
if(!$this->supressOutput) { if(!$this->supressOutput) {

View File

@ -14,6 +14,7 @@
* @package cms * @package cms
*/ */
class SiteConfig extends DataObject implements PermissionProvider { class SiteConfig extends DataObject implements PermissionProvider {
static $db = array( static $db = array(
"Title" => "Varchar(255)", "Title" => "Varchar(255)",
"Tagline" => "Varchar(255)", "Tagline" => "Varchar(255)",
@ -50,57 +51,11 @@ class SiteConfig extends DataObject implements PermissionProvider {
new DropdownField("Theme", _t('SiteConfig.THEME', 'Theme'), $this->getAvailableThemes(), '', null, _t('SiteConfig.DEFAULTTHEME', '(Use default theme)')) new DropdownField("Theme", _t('SiteConfig.THEME', 'Theme'), $this->getAvailableThemes(), '', null, _t('SiteConfig.DEFAULTTHEME', '(Use default theme)'))
), ),
new Tab('Access', new Tab('Access',
new HeaderField('WhoCanViewHeader', _t('SiteConfig.VIEWHEADER', "Who can view pages on this site?"), 2), new HeaderField('WhoCanViewHeader', _t('SiteConfig.VIEWHEADER', "Who can view pages on this site?"), 2)
$viewersOptionsField = new OptionsetField("CanViewType"),
$viewerGroupsField = new TreeMultiselectField("ViewerGroups", _t('SiteTree.VIEWERGROUPS', "Viewer Groups")),
new HeaderField('WhoCanEditHeader', _t('SiteConfig.EDITHEADER', "Who can edit pages on this site?"), 2),
$editorsOptionsField = new OptionsetField("CanEditType"),
$editorGroupsField = new TreeMultiselectField("EditorGroups", _t('SiteTree.EDITORGROUPS', "Editor Groups")),
new HeaderField('WhoCanCreateTopLevelHeader', _t('SiteConfig.TOPLEVELCREATE', "Who can create pages in the root of the site?"), 2),
$topLevelCreatorsOptionsField = new OptionsetField("CanCreateTopLevelType"),
$topLevelCreatorsGroupsField = new TreeMultiselectField("CreateTopLevelGroups", _t('SiteTree.TOPLEVELCREATORGROUPS', "Top level creators"))
) )
) )
); );
$viewersOptionsSource = array();
$viewersOptionsSource["Anyone"] = _t('SiteTree.ACCESSANYONE', "Anyone");
$viewersOptionsSource["LoggedInUsers"] = _t('SiteTree.ACCESSLOGGEDIN', "Logged-in users");
$viewersOptionsSource["OnlyTheseUsers"] = _t('SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)");
$viewersOptionsField->setSource($viewersOptionsSource);
$editorsOptionsSource = array();
$editorsOptionsSource["LoggedInUsers"] = _t('SiteTree.EDITANYONE', "Anyone who can log-in to the CMS");
$editorsOptionsSource["OnlyTheseUsers"] = _t('SiteTree.EDITONLYTHESE', "Only these people (choose from list)");
$editorsOptionsField->setSource($editorsOptionsSource);
$topLevelCreatorsOptionsField->setSource($editorsOptionsSource);
// Translatable doesn't handle updateCMSFields on DataObjects,
// so add it here to save the current Locale,
// because onBeforeWrite does not work.
if(Object::has_extension('SiteConfig',"Translatable")){
$fields->push(new HiddenField("Locale"));
}
if (!Permission::check('EDIT_SITECONFIG')) {
$fields->makeFieldReadonly($viewersOptionsField);
$fields->makeFieldReadonly($viewerGroupsField);
$fields->makeFieldReadonly($editorsOptionsField);
$fields->makeFieldReadonly($editorGroupsField);
$fields->makeFieldReadonly($topLevelCreatorsOptionsField);
$fields->makeFieldReadonly($topLevelCreatorsGroupsField);
$fields->makeFieldReadonly($taglineField);
$fields->makeFieldReadonly($titleField);
}
if(file_exists(BASE_PATH . '/install.php')) {
$fields->addFieldToTab("Root.Main", new LiteralField("InstallWarningHeader",
"<p class=\"message warning\">" . _t("SiteTree.REMOVE_INSTALL_WARNING",
"Warning: You should remove install.php from this SilverStripe install for security reasons.")
. "</p>"), "Title");
}
$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);
return $fields; return $fields;

View File

@ -71,7 +71,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
"ShowInMenus" => "Boolean", "ShowInMenus" => "Boolean",
"ShowInSearch" => "Boolean", "ShowInSearch" => "Boolean",
"HomepageForDomain" => "Varchar(100)", "HomepageForDomain" => "Varchar(100)",
"ProvideComments" => "Boolean",
"Sort" => "Int", "Sort" => "Int",
"HasBrokenFile" => "Boolean", "HasBrokenFile" => "Boolean",
"HasBrokenLink" => "Boolean", "HasBrokenLink" => "Boolean",
@ -87,10 +86,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
"URLSegment" => true, "URLSegment" => true,
); );
static $has_many = array(
"Comments" => "PageComment"
);
static $many_many = array( static $many_many = array(
"LinkTracking" => "SiteTree", "LinkTracking" => "SiteTree",
"ImageTracking" => "File", "ImageTracking" => "File",
@ -527,22 +522,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return false; return false;
} }
/**
* Returns comments on this page. This will only show comments that
* have been marked as spam if "?showspam=1" is appended to the URL.
*
* @return DataObjectSet Comments on this page.
*/
public function Comments() {
$spamfilter = isset($_GET['showspam']) ? '' : "AND \"IsSpam\"=0";
$unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND \"NeedsModeration\"=0";
$comments = DataObject::get("PageComment", "\"ParentID\" = '" . Convert::raw2sql($this->ID) . "' $spamfilter $unmoderatedfilter", "\"Created\" DESC");
return $comments ? $comments : new DataObjectSet();
}
/** /**
* Create a duplicate of this node. Doesn't affect joined data - create a * Create a duplicate of this node. Doesn't affect joined data - create a
* custom overloading of this if you need such behaviour. * custom overloading of this if you need such behaviour.
@ -1817,8 +1796,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
), ),
new CheckboxField("ShowInMenus", $this->fieldLabel('ShowInMenus')), new CheckboxField("ShowInMenus", $this->fieldLabel('ShowInMenus')),
new CheckboxField("ShowInSearch", $this->fieldLabel('ShowInSearch')), new CheckboxField("ShowInSearch", $this->fieldLabel('ShowInSearch')),
/*, new TreeMultiselectField("MultipleParents", "Page appears within", "SiteTree")*/
new CheckboxField("ProvideComments", $this->fieldLabel('ProvideComments')),
new LiteralField( new LiteralField(
"HomepageForDomainInfo", "HomepageForDomainInfo",
"<p>" . "<p>" .

View File

@ -129,6 +129,7 @@ class DevelopmentAdmin extends Controller {
$renderer->writeHeader(); $renderer->writeHeader();
$renderer->writeInfo("Environment Builder", Director::absoluteBaseURL()); $renderer->writeInfo("Environment Builder", Director::absoluteBaseURL());
echo "<div style=\"margin: 0 2em\">"; echo "<div style=\"margin: 0 2em\">";
echo "<div class=\"status pending\"><h2 class='buildProgress'>Database is building.... Check below for any errors</h2><h2 class='buildCompleted'>Database has been built successfully</h2></div>";
$da = Object::create('DatabaseAdmin'); $da = Object::create('DatabaseAdmin');
return $da->handleRequest($request); return $da->handleRequest($request);
@ -180,4 +181,3 @@ class DevelopmentAdmin extends Controller {
return Object::create('CodeViewer'); return Object::create('CodeViewer');
} }
} }
?>

View File

@ -289,7 +289,7 @@ class SapphireTestReporter implements PHPUnit_Framework_TestListener {
} }
} }
$result = ($failCount > 0) ? 'fail' : 'pass'; $result = ($failCount > 0) ? 'fail' : 'pass';
echo "<div class=\"$result\">"; echo "<div class=\"status $result\">";
echo "<h2><span>$testCount</span> tests run: <span>$passCount</span> passes, <span>$failCount</span> fails, and <span>0</span> exceptions</h2>"; echo "<h2><span>$testCount</span> tests run: <span>$passCount</span> passes, <span>$failCount</span> fails, and <span>0</span> exceptions</h2>";
echo "</div>"; echo "</div>";

View File

@ -981,7 +981,6 @@ class Form extends RequestHandler {
function saveInto(DataObjectInterface $dataObject, $fieldList = null) { function saveInto(DataObjectInterface $dataObject, $fieldList = null) {
$dataFields = $this->fields->saveableFields(); $dataFields = $this->fields->saveableFields();
$lastField = null; $lastField = null;
if($dataFields) foreach($dataFields as $field) { if($dataFields) foreach($dataFields as $field) {
// Skip fields that have been exlcuded // Skip fields that have been exlcuded
if($fieldList && is_array($fieldList) && !in_array($field->Name(), $fieldList)) continue; if($fieldList && is_array($fieldList) && !in_array($field->Name(), $fieldList)) continue;

View File

@ -1,24 +1,9 @@
PageComment:
comment1:
Name: Joe
Comment: This is a test comment
comment2:
Name: Jane
Comment: This is another test comment
comment3:
Name: Bob
Comment: Another comment
comment4:
Name: Bob
Comment: Second comment by Bob
Page: Page:
home: home:
Title: Home Title: Home
Comments: =>PageComment.comment1,=>PageComment.comment2
page1: page1:
Title: First Page Title: First Page
Content: <p>Some test content</p> Content: <p>Some test content</p>
Comments: =>PageComment.comment3,=>PageComment.comment4
page2: page2:
Title: Second Page Title: Second Page
Permission: Permission:

View File

@ -7,7 +7,7 @@
*/ */
class DataObjectSetTest extends SapphireTest { class DataObjectSetTest extends SapphireTest {
static $fixture_file = 'sapphire/tests/DataObjectTest.yml'; static $fixture_file = 'sapphire/tests/DataObjectSetTest.yml';
protected $extraDataObjects = array( protected $extraDataObjects = array(
'DataObjectTest_Team', 'DataObjectTest_Team',
@ -106,9 +106,9 @@ class DataObjectSetTest extends SapphireTest {
} }
public function testMultipleOf() { public function testMultipleOf() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
$commArr = $comments->toArray(); $commArr = $comments->toArray();
$multiplesOf3 = 1; $multiplesOf3 = 0;
foreach($comments as $comment) { foreach($comments as $comment) {
if($comment->MultipleOf(3)) { if($comment->MultipleOf(3)) {
@ -119,15 +119,11 @@ class DataObjectSetTest extends SapphireTest {
} }
} }
$this->assertEquals(3, $multiplesOf3); $this->assertEquals(1, $multiplesOf3);
$this->assertFalse($commArr[0]->IsMultipleOf3); $this->assertFalse($commArr[0]->IsMultipleOf3);
$this->assertFalse($commArr[1]->IsMultipleOf3); $this->assertFalse($commArr[1]->IsMultipleOf3);
$this->assertTrue($commArr[2]->IsMultipleOf3); $this->assertTrue($commArr[2]->IsMultipleOf3);
$this->assertFalse($commArr[3]->IsMultipleOf3);
$this->assertFalse($commArr[4]->IsMultipleOf3);
$this->assertTrue($commArr[5]->IsMultipleOf3);
$this->assertFalse($commArr[6]->IsMultipleOf3);
foreach($comments as $comment) { foreach($comments as $comment) {
if($comment->MultipleOf(3, 1)) { if($comment->MultipleOf(3, 1)) {
@ -140,27 +136,23 @@ class DataObjectSetTest extends SapphireTest {
$this->assertFalse($commArr[0]->IsMultipleOf3); $this->assertFalse($commArr[0]->IsMultipleOf3);
$this->assertFalse($commArr[1]->IsMultipleOf3); $this->assertFalse($commArr[1]->IsMultipleOf3);
$this->assertTrue($commArr[2]->IsMultipleOf3); $this->assertTrue($commArr[2]->IsMultipleOf3);
$this->assertFalse($commArr[3]->IsMultipleOf3);
$this->assertFalse($commArr[4]->IsMultipleOf3);
$this->assertTrue($commArr[5]->IsMultipleOf3);
$this->assertFalse($commArr[6]->IsMultipleOf3);
} }
/** /**
* Test {@link DataObjectSet->Count()} * Test {@link DataObjectSet->Count()}
*/ */
function testCount() { function testCount() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
/* There are a total of 8 items in the set */ /* There are a total of 8 items in the set */
$this->assertEquals($comments->Count(), 8, 'There are a total of 8 items in the set'); $this->assertEquals($comments->Count(), 3, 'There are a total of 8 items in the set');
} }
/** /**
* Test {@link DataObjectSet->First()} * Test {@link DataObjectSet->First()}
*/ */
function testFirst() { function testFirst() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
/* The first object is Joe's comment */ /* The first object is Joe's comment */
$this->assertEquals($comments->First()->Name, 'Joe', 'The first object has a Name field value of "Joe"'); $this->assertEquals($comments->First()->Name, 'Joe', 'The first object has a Name field value of "Joe"');
@ -170,17 +162,17 @@ class DataObjectSetTest extends SapphireTest {
* Test {@link DataObjectSet->Last()} * Test {@link DataObjectSet->Last()}
*/ */
function testLast() { function testLast() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
/* The last object is Dean's comment */ /* The last object is Dean's comment */
$this->assertEquals($comments->Last()->Name, 'Dean', 'The last object has a Name field value of "Dean"'); $this->assertEquals($comments->Last()->Name, 'Phil', 'The last object has a Name field value of "Phil"');
} }
/** /**
* Test {@link DataObjectSet->map()} * Test {@link DataObjectSet->map()}
*/ */
function testMap() { function testMap() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
/* Now we get a map of all the PageComment records */ /* Now we get a map of all the PageComment records */
$map = $comments->map('ID', 'Title', '(Select one)'); $map = $comments->map('ID', 'Title', '(Select one)');
@ -188,31 +180,26 @@ class DataObjectSetTest extends SapphireTest {
$expectedMap = array( $expectedMap = array(
'' => '(Select one)', '' => '(Select one)',
1 => 'Joe', 1 => 'Joe',
2 => 'Jane', 2 => 'Bob',
3 => 'Bob', 3 => 'Phil'
4 => 'Bob',
5 => 'Ernie',
6 => 'Jimmy',
7 => 'Dean',
8 => 'Dean'
); );
/* There are 9 items in the map. 8 are records. 1 is the empty value */ /* There are 9 items in the map. 3 are records. 1 is the empty value */
$this->assertEquals(count($map), 9, 'There are 9 items in the map. 8 are records. 1 is the empty value'); $this->assertEquals(count($map), 4, 'There are 4 items in the map. 3 are records. 1 is the empty value');
/* We have the same map as our expected map, asserted above */ /* We have the same map as our expected map, asserted above */
/* toDropDownMap() is an alias of map() - let's make a map from that */ /* toDropDownMap() is an alias of map() - let's make a map from that */
$map2 = $comments->toDropDownMap('ID', 'Title', '(Select one)'); $map2 = $comments->toDropDownMap('ID', 'Title', '(Select one)');
/* There are 9 items in the map. 8 are records. 1 is the empty value */ /* There are 4 items in the map. 3 are records. 1 is the empty value */
$this->assertEquals(count($map), 9, 'There are 9 items in the map. 8 are records. 1 is the empty value.'); $this->assertEquals(count($map), 4, 'There are 4 items in the map. 3 are records. 1 is the empty value.');
} }
function testRemoveDuplicates() { function testRemoveDuplicates() {
// Note that PageComment and DataObjectSetTest_TeamComment are both descendants of DataObject, and don't // Note that PageComment and DataObjectSetTest_TeamComment are both descendants of DataObject, and don't
// share an inheritance relationship below that. // share an inheritance relationship below that.
$pageComments = DataObject::get('PageComment'); $pageComments = DataObject::get('DataObjectSetTest_TeamComment');
$teamComments = DataObject::get('DataObjectSetTest_TeamComment'); $teamComments = DataObject::get('DataObjectSetTest_TeamComment');
/* Test default functionality (remove by ID). We'd expect to loose all our /* Test default functionality (remove by ID). We'd expect to loose all our
@ -222,33 +209,38 @@ class DataObjectSetTest extends SapphireTest {
$allComments->merge($pageComments); $allComments->merge($pageComments);
$allComments->merge($teamComments); $allComments->merge($teamComments);
$this->assertEquals($allComments->Count(), 6);
$allComments->removeDuplicates(); $allComments->removeDuplicates();
$this->assertEquals($allComments->Count(), 11, 'Standard functionality is to remove duplicate base class/IDs'); $this->assertEquals($allComments->Count(), 3, 'Standard functionality is to remove duplicate base class/IDs');
/* Now test removing duplicates based on a common field. In this case we shall /* Now test removing duplicates based on a common field. In this case we shall
* use 'Name', so we can get all the unique commentators */ * use 'Name', so we can get all the unique commentators */
$allComments = new DataObjectSet();
$allComments->merge($pageComments); $comment = new DataObjectSetTest_TeamComment();
$allComments->merge($teamComments); $comment->Name = "Bob";
$allComments->push($comment);
$this->assertEquals($allComments->Count(), 4);
$allComments->removeDuplicates('Name'); $allComments->removeDuplicates('Name');
$this->assertEquals($allComments->Count(), 9, 'There are 9 uniquely named commentators'); $this->assertEquals($allComments->Count(), 3, 'There are 3 uniquely named commentators');
// Ensure that duplicates are removed where the base data class is the same. // Ensure that duplicates are removed where the base data class is the same.
$mixedSet = new DataObjectSet(); $mixedSet = new DataObjectSet();
$mixedSet->push(new SiteTree(array('ID' => 1))); $mixedSet->push(new SiteTree(array('ID' => 1)));
$mixedSet->push(new Page(array('ID' => 1))); // dup: same base class and ID $mixedSet->push(new Page(array('ID' => 1))); // dup: same base class and ID
$mixedSet->push(new Page(array('ID' => 1))); // dup: more than one dup of the same object $mixedSet->push(new Page(array('ID' => 1))); // dup: more than one dup of the same object
$mixedSet->push(new Page(array('ID' => 2))); // not dup: same type again, but different ID $mixedSet->push(new Page(array('ID' => 2))); // not dup: same type again, but different
$mixedSet->push(new PageComment(array('ID' => 1))); // not dup: different base type, same ID
$mixedSet->push(new SiteTree(array('ID' => 1))); // dup: another dup, not consequetive. $mixedSet->push(new SiteTree(array('ID' => 1))); // dup: another dup, not consequetive.
$mixedSet->removeDuplicates('ID'); $mixedSet->removeDuplicates('ID');
$this->assertEquals($mixedSet->Count(), 3, 'There are 3 unique data objects in a very mixed set'); $this->assertEquals($mixedSet->Count(), 2, 'There are 3 unique data objects in a very mixed set');
} }
/** /**
@ -302,9 +294,10 @@ class DataObjectSetTest extends SapphireTest {
*/ */
function testInsertFirst() { function testInsertFirst() {
// Get one comment // Get one comment
$comment = DataObject::get_one('PageComment', '"Name" = \'Joe\''); $comment = DataObject::get_one('DataObjectSetTest_TeamComment', "\"Name\" = 'Joe'");
// Get all other comments // Get all other comments
$set = DataObject::get('PageComment', '"Name" != \'Joe\''); $set = DataObject::get('DataObjectSetTest_TeamComment', '"Name" != \'Joe\'');
// Duplicate so we can use it later without another lookup // Duplicate so we can use it later without another lookup
$otherSet = clone $set; $otherSet = clone $set;
@ -327,18 +320,19 @@ class DataObjectSetTest extends SapphireTest {
* Test {@link DataObjectSet->getRange()} * Test {@link DataObjectSet->getRange()}
*/ */
function testGetRange() { function testGetRange() {
$comments = DataObject::get('PageComment', '', "\"ID\" ASC"); $comments = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
// Make sure we got all 8 comments // Make sure we got all 8 comments
$this->assertEquals($comments->Count(), 8, 'Eight comments in the database.'); $this->assertEquals($comments->Count(), 3, 'Three comments in the database.');
// Grab a range // Grab a range
$range = $comments->getRange(1, 5); $range = $comments->getRange(1, 2);
$this->assertEquals($range->Count(), 5, 'Five comments in the range.'); $this->assertEquals($range->Count(), 2, 'Two comment in the range.');
// And now grab a range that shouldn't be full. Remember counting starts at 0. // And now grab a range that shouldn't be full. Remember counting starts at 0.
$range = $comments->getRange(7, 5); $range = $comments->getRange(2, 1);
$this->assertEquals($range->Count(), 1, 'One comment in the range.'); $this->assertEquals($range->Count(), 1, 'One comment in the range.');
// Make sure it's the last one // Make sure it's the last one
$this->assertEquals($range->First(), $comments->Last(), 'The only item in the range should be the last one.'); $this->assertEquals($range->First(), $comments->Last(), 'The only item in the range should be the last one.');
} }
@ -350,8 +344,9 @@ class DataObjectSetTest extends SapphireTest {
// Test an empty set // Test an empty set
$set = new DataObjectSet(); $set = new DataObjectSet();
$this->assertFalse($set->exists(), 'Empty set doesn\'t exist.'); $this->assertFalse($set->exists(), 'Empty set doesn\'t exist.');
// Test a non-empty set // Test a non-empty set
$set = DataObject::get('PageComment', '', "\"ID\" ASC"); $set = DataObject::get('DataObjectSetTest_TeamComment', '', "\"ID\" ASC");
$this->assertTrue($set->exists(), 'Non-empty set does exist.'); $this->assertTrue($set->exists(), 'Non-empty set does exist.');
} }
@ -389,6 +384,28 @@ class DataObjectSetTest extends SapphireTest {
$this->assertEquals('Ted', $set->pop()->Name); $this->assertEquals('Ted', $set->pop()->Name);
} }
/**
* Test {@link DataObjectSet->sort()}
*/
function testSort() {
$set = new DataObjectSet(array(
array('Name'=>'Object1', 'F1'=>1, 'F2'=>2, 'F3'=>3),
array('Name'=>'Object2', 'F1'=>2, 'F2'=>1, 'F3'=>4),
array('Name'=>'Object3', 'F1'=>5, 'F2'=>2, 'F3'=>2),
));
// test a single sort ASC
$set->sort('F3', 'ASC');
$this->assertEquals($set->First()->Name, 'Object3', 'Object3 should be first in the set');
// test a single sort DESC
$set->sort('F3', 'DESC');
$this->assertEquals($set->First()->Name, 'Object2', 'Object2 should be first in the set');
// test a multi sort
$set->sort(array('F2'=>'ASC', 'F1'=>'ASC'));
$this->assertEquals($set->Last()->Name, 'Object3', 'Object3 should be last in the set');
// test a multi sort
$set->sort(array('F2'=>'ASC', 'F1'=>'DESC'));
$this->assertEquals($set->Last()->Name, 'Object1', 'Object1 should be last in the set');
}
} }
/** /**
@ -396,12 +413,13 @@ class DataObjectSetTest extends SapphireTest {
* @subpackage tests * @subpackage tests
*/ */
class DataObjectSetTest_TeamComment extends DataObject implements TestOnly { class DataObjectSetTest_TeamComment extends DataObject implements TestOnly {
static $db = array( static $db = array(
'Name' => 'Varchar', 'Name' => 'Varchar',
'Comment' => 'Text', 'Comment' => 'Text',
); );
static $has_one = array( static $has_one = array(
'Team' => 'DataObjectTest_Team', 'Team' => 'DataObjectTest_Team',
); );
} }
?>

View File

@ -0,0 +1,54 @@
Page:
home:
Title: Home
page1:
Title: First Page
Content: <p>Some test content</p>
page2:
Title: Second Page
DataObjectTest_Team:
team1:
Title: Team 1
team2:
Title: Team 2
DataObjectTest_Player:
captain1:
FirstName: Captain 1
FavouriteTeam: =>DataObjectTest_Team.team1
Teams: =>DataObjectTest_Team.team1
captain2:
FirstName: Captain 2
Teams: =>DataObjectTest_Team.team2
player1:
FirstName: Player 1
player2:
FirstName: Player 2
Teams: =>DataObjectTest_Team.team1,=>DataObjectTest_Team.team2
DataObjectTest_SubTeam:
subteam1:
Title: Subteam 1
SubclassDatabaseField: Subclassed 1
DecoratedDatabaseField: Decorated 1
subteam2_with_player_relation:
Title: Subteam 2
SubclassDatabaseField: Subclassed 2
DecoratedHasOneRelationship: =>DataObjectTest_Player.player1
subteam3_with_empty_fields:
Title: Subteam 3
DataObjectSetTest_TeamComment:
comment1:
Name: Joe
Comment: This is a team comment by Joe
Team: =>DataObjectTest_Team.team1
comment2:
Name: Bob
Comment: This is a team comment by Bob
Team: =>DataObjectTest_Team.team1
comment3:
Name: Phil
Comment: Phil is a unique guy, and comments on team2
Team: =>DataObjectTest_Team.team2

View File

@ -16,7 +16,7 @@ class DataObjectTest extends SapphireTest {
'DataObjectTest_FieldlessSubTable', 'DataObjectTest_FieldlessSubTable',
'DataObjectTest_ValidatedObject', 'DataObjectTest_ValidatedObject',
'DataObjectTest_Player', 'DataObjectTest_Player',
'DataObjectSetTest_TeamComment' 'DataObjectTest_TeamComment'
); );
function testDataIntegrityWhenTwoSubclassesHaveSameField() { function testDataIntegrityWhenTwoSubclassesHaveSameField() {
@ -101,40 +101,47 @@ class DataObjectTest extends SapphireTest {
*/ */
function testGet() { function testGet() {
// Test getting all records of a DataObject // Test getting all records of a DataObject
$comments = DataObject::get('PageComment'); $comments = DataObject::get('DataObjectTest_TeamComment');
$this->assertEquals(8, $comments->Count()); $this->assertEquals(3, $comments->Count());
// Test WHERE clause // Test WHERE clause
$comments = DataObject::get('PageComment', "\"Name\"='Bob'"); $comments = DataObject::get('DataObjectTest_TeamComment', "\"Name\"='Bob'");
$this->assertEquals(2, $comments->Count()); $this->assertEquals(1, $comments->Count());
foreach($comments as $comment) { foreach($comments as $comment) {
$this->assertEquals('Bob', $comment->Name); $this->assertEquals('Bob', $comment->Name);
} }
// Test sorting // Test sorting
$comments = DataObject::get('PageComment', '', '"Name" ASC'); $comments = DataObject::get('DataObjectTest_TeamComment', '', "\"Name\" ASC");
$this->assertEquals(8, $comments->Count()); $this->assertEquals(3, $comments->Count());
$this->assertEquals('Bob', $comments->First()->Name); $this->assertEquals('Bob', $comments->First()->Name);
$comments = DataObject::get('PageComment', '', '"Name" DESC'); $comments = DataObject::get('DataObjectTest_TeamComment', '', "\"Name\" DESC");
$this->assertEquals(8, $comments->Count()); $this->assertEquals(3, $comments->Count());
$this->assertEquals('Joe', $comments->First()->Name); $this->assertEquals('Phil', $comments->First()->Name);
// Test join // Test join
$comments = DataObject::get('PageComment', "\"SiteTree\".\"Title\"='First Page'", '', 'INNER JOIN "SiteTree" ON "PageComment"."ParentID" = "SiteTree"."ID"'); $comments = DataObject::get(
'DataObjectTest_TeamComment',
"\"DataObjectTest_Team\".\"Title\" = 'Team 1'",
"\"Name\" ASC",
"INNER JOIN \"DataObjectTest_Team\" ON \"DataObjectTest_TeamComment\".\"TeamID\" = \"DataObjectTest_Team\".\"ID\""
);
$this->assertEquals(2, $comments->Count()); $this->assertEquals(2, $comments->Count());
$this->assertEquals('Bob', $comments->First()->Name); $this->assertEquals('Bob', $comments->First()->Name);
$this->assertEquals('Bob', $comments->Last()->Name); $this->assertEquals('Joe', $comments->Last()->Name);
// Test limit // Test limit
$comments = DataObject::get('PageComment', '', '"Name" ASC', '', '1,2'); $comments = DataObject::get('DataObjectTest_TeamComment', '', "\"Name\" ASC", '', '1,2');
$this->assertEquals(2, $comments->Count()); $this->assertEquals(2, $comments->Count());
$this->assertEquals('Bob', $comments->First()->Name); $this->assertEquals('Joe', $comments->First()->Name);
$this->assertEquals('Dean', $comments->Last()->Name); $this->assertEquals('Phil', $comments->Last()->Name);
// Test container class // Test container class
$comments = DataObject::get('PageComment', '', '', '', '', 'DataObjectSet'); $comments = DataObject::get('DataObjectTest_TeamComment', '', '', '', '', 'DataObjectSet');
$this->assertEquals('DataObjectSet', get_class($comments)); $this->assertEquals('DataObjectSet', get_class($comments));
$comments = DataObject::get('PageComment', '', '', '', '', 'ComponentSet');
$comments = DataObject::get('DataObjectTest_TeamComment', '', '', '', '', 'ComponentSet');
$this->assertEquals('ComponentSet', get_class($comments)); $this->assertEquals('ComponentSet', get_class($comments));
@ -144,28 +151,31 @@ class DataObjectTest extends SapphireTest {
$this->assertEquals('Home', $page->Title); $this->assertEquals('Home', $page->Title);
// Test get_one() without caching // Test get_one() without caching
$comment1 = DataObject::get_one('PageComment', "\"Name\"='Joe'", false); $comment1 = DataObject::get_one('DataObjectTest_TeamComment', "\"Name\" = 'Joe'", false);
$comment1->Comment = "Something Else"; $comment1->Comment = "Something Else";
$comment2 = DataObject::get_one('PageComment', "\"Name\"='Joe'", false);
$comment2 = DataObject::get_one('DataObjectTest_TeamComment', "\"Name\" = 'Joe'", false);
$this->assertNotEquals($comment1->Comment, $comment2->Comment); $this->assertNotEquals($comment1->Comment, $comment2->Comment);
// Test get_one() with caching // Test get_one() with caching
$comment1 = DataObject::get_one('PageComment', "\"Name\"='Jane'", true); $comment1 = DataObject::get_one('DataObjectTest_TeamComment', "\"Name\" = 'Bob'", true);
$comment1->Comment = "Something Else"; $comment1->Comment = "Something Else";
$comment2 = DataObject::get_one('PageComment', "\"Name\"='Jane'", true);
$comment2 = DataObject::get_one('DataObjectTest_TeamComment', "\"Name\" = 'Bob'", true);
$this->assertEquals((string)$comment1->Comment, (string)$comment2->Comment); $this->assertEquals((string)$comment1->Comment, (string)$comment2->Comment);
// Test get_one() with order by without caching // Test get_one() with order by without caching
$comment = DataObject::get_one('PageComment', '', false, '"Name" ASC'); $comment = DataObject::get_one('DataObjectTest_TeamComment', '', false, "\"Name\" ASC");
$this->assertEquals('Bob', $comment->Name); $this->assertEquals('Bob', $comment->Name);
$comment = DataObject::get_one('PageComment', '', false, '"Name" DESC');
$this->assertEquals('Joe', $comment->Name); $comment = DataObject::get_one('DataObjectTest_TeamComment', '', false, "\"Name\" DESC");
$this->assertEquals('Phil', $comment->Name);
// Test get_one() with order by with caching // Test get_one() with order by with caching
$comment = DataObject::get_one('PageComment', '', true, '"Name" ASC'); $comment = DataObject::get_one('DataObjectTest_TeamComment', '', true, '"Name" ASC');
$this->assertEquals('Bob', $comment->Name); $this->assertEquals('Bob', $comment->Name);
$comment = DataObject::get_one('PageComment', '', true, '"Name" DESC'); $comment = DataObject::get_one('DataObjectTest_TeamComment', '', true, '"Name" DESC');
$this->assertEquals('Joe', $comment->Name); $this->assertEquals('Phil', $comment->Name);
} }
/** /**
@ -188,14 +198,14 @@ class DataObjectTest extends SapphireTest {
* - Test the IDs on the DataObjects are set correctly * - Test the IDs on the DataObjects are set correctly
*/ */
function testHasManyRelationships() { function testHasManyRelationships() {
$page = $this->objFromFixture('Page', 'home'); $team = $this->objFromFixture('DataObjectTest_Team', 'team1');
// Test getComponents() gets the ComponentSet of the other side of the relation // Test getComponents() gets the ComponentSet of the other side of the relation
$this->assertTrue($page->getComponents('Comments')->Count() == 2); $this->assertTrue($team->getComponents('Comments')->Count() == 2);
// Test the IDs on the DataObjects are set correctly // Test the IDs on the DataObjects are set correctly
foreach($page->getComponents('Comments') as $comment) { foreach($team->getComponents('Comments') as $comment) {
$this->assertTrue($comment->ParentID == $page->ID); $this->assertTrue($comment->TeamID == $team->ID);
} }
} }
@ -355,26 +365,6 @@ class DataObjectTest extends SapphireTest {
$this->assertFalse($page->isChanged()); $this->assertFalse($page->isChanged());
} }
function testRandomSort() {
/* If we perforn the same regularly sorted query twice, it should return the same results */
$itemsA = DataObject::get("PageComment", "", "ID");
foreach($itemsA as $item) $keysA[] = $item->ID;
$itemsB = DataObject::get("PageComment", "", "ID");
foreach($itemsB as $item) $keysB[] = $item->ID;
$this->assertEquals($keysA, $keysB);
/* If we perform the same random query twice, it shouldn't return the same results */
$itemsA = DataObject::get("PageComment", "", DB::getConn()->random());
foreach($itemsA as $item) $keysA[] = $item->ID;
$itemsB = DataObject::get("PageComment", "", DB::getConn()->random());
foreach($itemsB as $item) $keysB[] = $item->ID;
$this->assertNotEquals($keysA, $keysB);
}
function testWriteSavesToHasOneRelations() { function testWriteSavesToHasOneRelations() {
/* DataObject::write() should save to a has_one relationship if you set a field called (relname)ID */ /* DataObject::write() should save to a has_one relationship if you set a field called (relname)ID */
$team = new DataObjectTest_Team(); $team = new DataObjectTest_Team();
@ -994,6 +984,10 @@ class DataObjectTest_Team extends DataObject implements TestOnly {
'HasOneRelationship' => 'DataObjectTest_Player', 'HasOneRelationship' => 'DataObjectTest_Player',
); );
static $has_many = array(
'Comments' => 'DataObjectTest_TeamComment'
);
static $many_many = array( static $many_many = array(
'Players' => 'DataObjectTest_Player' 'Players' => 'DataObjectTest_Player'
); );
@ -1109,6 +1103,18 @@ class DataObjectTest_CEO extends DataObjectTest_Staff {
); );
} }
class DataObjectTest_TeamComment extends DataObject {
static $db = array(
'Name' => "Varchar",
"Comment" => "Text"
);
static $has_one = array(
'Team' => 'DataObjectTest_Team'
);
}
DataObject::add_extension('DataObjectTest_Team', 'DataObjectTest_Team_Decorator'); DataObject::add_extension('DataObjectTest_Team', 'DataObjectTest_Team_Decorator');
?> ?>

View File

@ -1,37 +1,9 @@
PageComment:
comment1:
Name: Joe
Comment: This is a test comment
comment2:
Name: Jane
Comment: This is another test comment
comment3:
Name: Bob
Comment: Another comment
comment4:
Name: Bob
Comment: Second comment by Bob
comment5:
Name: Ernie
Comment: This is a test comment
comment6:
Name: Jimmy
Comment: This is another test comment
comment7:
Name: Dean
Comment: Another comment
comment8:
Name: Dean
Comment: Second comment by Dean
Page: Page:
home: home:
Title: Home Title: Home
Comments: =>PageComment.comment1,=>PageComment.comment2
page1: page1:
Title: First Page Title: First Page
Content: <p>Some test content</p> Content: <p>Some test content</p>
Comments: =>PageComment.comment3,=>PageComment.comment4
page2: page2:
Title: Second Page Title: Second Page
@ -67,7 +39,7 @@ DataObjectTest_SubTeam:
subteam3_with_empty_fields: subteam3_with_empty_fields:
Title: Subteam 3 Title: Subteam 3
DataObjectSetTest_TeamComment: DataObjectTest_TeamComment:
comment1: comment1:
Name: Joe Name: Joe
Comment: This is a team comment by Joe Comment: This is a team comment by Joe
@ -79,4 +51,4 @@ DataObjectSetTest_TeamComment:
comment3: comment3:
Name: Phil Name: Phil
Comment: Phil is a unique guy, and comments on team2 Comment: Phil is a unique guy, and comments on team2
Tema: =>DataObjectTest_Team.team2 Team: =>DataObjectTest_Team.team2