Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, Ed, biapar, Willr, Ingo, swaiba

Bug Reports


Go to End


297 Posts   102002 Views

Avatar
brice

Community Member, 52 Posts

9 October 2010 at 10:41am

Running against latest trunk.

I've come across a bug where *FileDataObjectManagers throw an exception if the source class has summary_fields which pull in the value of a relative -- e.g.


static $has_one = array(
		"File"		=> "Image"
	);

  static $summary_fields = array(
		'Title'			=> 'Photo Title',
		'File.Name'		=> 'Filename',
		'CMSThumbnail'	=> 'Thumbnail',
	);

The getQuery() methods of the ManyMany & HasOne FileDataObjectManagers are the cause; they generate a query that does not include the related table.

My recommendation is to relate more closely to the ComplexTableField classes & their derivatives [ManyManyComplexTableField, etc.].. and to use parent:: methods as often as possible to alleviate maintenacne in DOM.

Anyway attached is a patch that fixes this... although an above approach would be best (e.g. a simple overload of getQuery that calls parent::getQuery() & then injects the WHERE for relatedOnly).

Index: www/dataobject_manager/code/HasManyFileDataObjectManager.php
===================================================================
--- www/dataobject_manager/code/HasManyFileDataObjectManager.php	(revision 90)
+++ www/dataobject_manager/code/HasManyFileDataObjectManager.php	(working copy)
@@ -58,23 +58,23 @@
 	
 	function getQuery($limitClause = null) {
 		if($this->customQuery) {
-			$query = $this->customQuery;
+			$query = clone $this->customQuery;
 			$query->select[] = "{$this->sourceClass}.ID AS ID";
 			$query->select[] = "{$this->sourceClass}.ClassName AS ClassName";
 			$query->select[] = "{$this->sourceClass}.ClassName AS RecordClassName";
 		}
 		else {
-			$query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter, $this->sourceSort, $limitClause, $this->sourceJoin);
+			$query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter(), $this->sourceSort, $limitClause, $this->sourceJoin);
 			
 			// Add more selected fields if they are from joined table.
 
-			$SNG = singleton($this->sourceClass);
+			/*$SNG = singleton($this->sourceClass);
 			foreach($this->FieldList() as $k => $title) {
 				if(! $SNG->hasField($k) && ! $SNG->hasMethod('get' . $k))
 					$query->select[] = $k;
-			}
+			}*/
 		}
-		return clone $query;
+		return $query;
 	}
 	
 	public function setParentClass($class)
Index: www/dataobject_manager/code/ManyManyFileDataObjectManager.php
===================================================================
--- www/dataobject_manager/code/ManyManyFileDataObjectManager.php	(revision 90)
+++ www/dataobject_manager/code/ManyManyFileDataObjectManager.php	(working copy)
@@ -132,21 +132,21 @@
 		
 	function getQuery($limitClause = null) {
 		if($this->customQuery) {
-			$query = $this->customQuery;
+			$query = clone $this->customQuery;
 			$query->select[] = "{$this->sourceClass}.ID AS ID";
 			$query->select[] = "{$this->sourceClass}.ClassName AS ClassName";
 			$query->select[] = "{$this->sourceClass}.ClassName AS RecordClassName";
 		}
 		else {
-			$query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter, $this->sourceSort, $limitClause, $this->sourceJoin);
+			$query = singleton($this->sourceClass)->extendedSQL($this->sourceFilter(), $this->sourceSort, $limitClause, $this->sourceJoin);
 			
 			// Add more selected fields if they are from joined table.
 
-			$SNG = singleton($this->sourceClass);
+			/*$SNG = singleton($this->sourceClass);
 			foreach($this->FieldList() as $k => $title) {
 				if(! $SNG->hasField($k) && ! $SNG->hasMethod('get' . $k))
 					$query->select[] = $k;
-			}
+			}*/
 			$parent = $this->controllerClass();
 			$mm = $this->manyManyTable;
 			$if_clause = "IF(`$mm`.`{$this->manyManyParentClass}ID` IS NULL, '0', '1')";
@@ -155,7 +155,7 @@
 			if($this->OnlyRelated())
 			 $query->where[] = $if_clause;
 		}
-		return clone $query;
+		return $query;
 	}

Also avail @ http://pastebin.com/J4YNf0kW

Avatar
Johnny

Community Member, 34 Posts

10 October 2010 at 4:40am

Hi UncleCheeze!

I'm using a simple DataObjectManager an experiencing some problems with the Sort feature. When I load the page, in the CMS, it sorts well. but If I edit an element, then it sorts it A-Z instead of Z-A like I specified.

Here's the code:

$fields->addFieldToTab("Root.Content.Presse", new DataObjectManager (
				$this,
				'PressArticles',
				'PressArticle',
				array('ArticleTitle' => 'Titre', 'Date'=>'Date', 'Newspaper'=>'Journal', 'Journalist'=>'Journaliste'),
				'getCMSFields_forPopup',
				"", 'Date DESC'
			));

Thanks for you help!

Avatar
Nicolaas

Forum Moderator, 224 Posts

19 October 2010 at 11:11pm

Hi Uncle

I posted a bug here: http://code.google.com/p/dataobjectmanager/issues/detail?id=3

Cheers

Nicolaas

Avatar
vovanbo

Community Member, 3 Posts

9 November 2010 at 2:46am

Edited: 09/11/2010 2:50am

Using SS 2.4.3-rc2, DataObjectManager trunk (revision 511).

Wrong generated edit link

Have following code:

class MassMediaArticle extends DataObject {
	
	static $db = array (
		'PubDate' => 'Date',
		'Header' => 'Varchar(255)',
		'URL' => 'Varchar(255)',
		'Source' => 'Varchar(255)',
		'SourceURL' => 'Varchar(255)',
		'Summary' => 'HTMLText'
	);
	
	static $has_one = array (
		'MassMediaArticlesPage' => 'MassMediaArticlesPage'
	);
	
	public function getCMSFields_forPopup()
	{
		$dateField = new DateField('PubDate');
		$dateField->setConfig('showcalendar', true);
		$dateField->setConfig('dateformat', 'dd.MM.YYYY');
		
		return new FieldSet(
			$dateField,
			new TextField('Header'),
			new TextField('URL'),
			new TextField('Source'),
			new TextField('SourceURL'),
			new SimpleTinyMCEField('Summary')
		);
	}
	
}

And in Page class:

class MassMediaArticlesPage extends Page {
	
	static $has_many = array (
		'MassMediaArticles' => 'MassMediaArticle'
	);
	
	public function getCMSFields()
	{
		$f = parent::getCMSFields();
		$manager = new DataObjectManager(
			$this,
			'MassMediaArticles',
			'MassMediaArticle',
			array('PubDate' => 'Publication Date', 'Header' => 'Header', 'Source' => 'Source' ),
			'getCMSFields_forPopup'
		);
		
		$f->addFieldToTab("Root.Content.MassMediaArticles", $manager);
		return $f;
	}
	
}

In CMS DOM generate following string for edit object like this:

http://localhost:8888/mysite/admin/EditForm/field/MassMediaArticles/item/5?SecurityID=423222417/edit?ctf[MassMediaArticles][start]=0&ctf[MassMediaArticles][per_page]=10&ctf[MassMediaArticles][showall]=0&ctf[MassMediaArticles][sort]=SortOrder&ctf[MassMediaArticles][sort_dir]=&ctf[MassMediaArticles][search]=&ctf[MassMediaArticles][filter]=

But it wrong, and popup window only show object fields (like "readonly"), all fields is inactive (call method "view"). I saw link what generated by ComplexTableField and correct above link to:

http://localhost:8888/mysite/admin/EditForm/field/MassMediaArticles/item/5/edit?SecurityID=423222417&ctf[MassMediaArticles][start]=0&ctf[MassMediaArticles][per_page]=10&ctf[MassMediaArticles][showall]=0&ctf[MassMediaArticles][sort]=SortOrder&ctf[MassMediaArticles][sort_dir]=&ctf[MassMediaArticles][search]=&ctf[MassMediaArticles][filter]=

And voila! DOM show me necessary edit popup window. Error in this part of URL - "item/5?SecurityID=423222417/edit?" instead of "item/5/edit?SecurityID=423222417&". I suppose, what this bug appear because following functions in DataObjectManager_Item not expect in URL "?SecurityID=":

function Link() {
    return Controller::join_links($this->parent->BaseLink(), '/item/' . $this->item->ID);
}

public function EditLink()
{
    return $this->Link()."/edit?".$this->parent->getQueryString();
}

Thank you for attention, and for DOM :) In awaiting of fix this issue :)

Avatar
vovanbo

Community Member, 3 Posts

9 November 2010 at 3:36am

I fix EditLink() function as below:

	public function EditLink()
	{
		return Controller::join_links($this->Link(), "/edit?".$this->parent->getQueryString());
	}

It work!

Avatar
UncleCheese

Forum Moderator, 4102 Posts

9 November 2010 at 4:10am

Thank you!!

--------------------
SilverStripe tips, tutorials, screencasts and more: http://www.leftandmain.com

Avatar
MarcusDalgren

Community Member, 288 Posts

16 November 2010 at 3:18am

DataObjectManager->setSourceId() has no effect since the sourceID() function never checks for or returns the value.
Change the sourceID() function from

	function sourceID() {
		if($this->isNested)
			return $this->controller->ID;				
		$idField = $this->form->dataFieldByName('ID'); 
		return ($idField && is_numeric($idField->Value())) ? $idField->Value() : (isset($_REQUEST['ctf']['ID']) ? $_REQUEST['ctf']['ID'] : null); 
 	}

to

	function sourceID() {
		if (isset($this->sourceID) && is_numeric($this->sourceID)) {
			return $this->sourceID;
		}
		if($this->isNested)
			return $this->controller->ID;				
		$idField = $this->form->dataFieldByName('ID'); 
		return ($idField && is_numeric($idField->Value())) ? $idField->Value() : (isset($_REQUEST['ctf']['ID']) ? $_REQUEST['ctf']['ID'] : null); 
 	}

This way the custom source ID will be returned if it's been set.

Avatar
swaiba

Forum Moderator, 1899 Posts

19 November 2010 at 2:57am

I notice this when I tried to use the Has One DOM....

casted summary fields throw a SQL error...

	public static $summary_fields = array (
		'CastedText'=>'NewTitle',
	);

	static $casting = array( "CastedText" => "Text" );
	public function CastedText() {
		return $this->NormalDBField.' - text';
	}