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, biapar, Willr, Ingo, swaiba, simon_w

Bug Reports


Reply

297 Posts   49747 Views

Avatar
brice

9 October 2010 at 10:41am Community Member, 51 Posts

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

10 October 2010 at 4:40am Community Member, 34 Posts

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

19 October 2010 at 11:11pm Forum Moderator, 213 Posts

Hi Uncle

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

Cheers

Nicolaas

Avatar
vovanbo

9 November 2010 at 2:46am (Last edited: 9 November 2010 2:50am), Community Member, 3 Posts

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

9 November 2010 at 3:36am Community Member, 3 Posts

I fix EditLink() function as below:

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

It work!

Avatar
UncleCheese

9 November 2010 at 4:10am 4085 Posts

Thank you!!

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

Avatar
MarcusDalgren

16 November 2010 at 3:18am Community Member, 288 Posts

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

19 November 2010 at 2:57am Forum Moderator, 1796 Posts

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';
   }