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   52959 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, 213 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, 4096 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, 1808 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';
   }