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.

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
Reply


297 Posts   59251 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, 220 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, 1840 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';
	}