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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

DataObject::get_one(); doesn't work anymore (since Update to 2.4.2)


Go to End


15 Posts   4575 Views

Avatar
oleze

Community Member, 65 Posts

9 October 2010 at 10:54am

Edited: 09/10/2010 10:55am

Yes, there is a row with the right classname in Sitetree and Sitetree_Live.
Here is the code from NewsHolder.php

<?php
/**
 * Defines the NewsHolder page type
 */
class NewsHolder extends Page {
   static $db = array(
   );
   static $has_one = array(
   );
 
   static $allowed_children = array('NewsPage');
   
   static $icon = "themes/mytheme/images/treeicons/news";
   
   static $defaults = array ( 
   'ShowInMenus' => false
   );
}
 
class NewsHolder_Controller extends Page_Controller {
 	function rss() {
  		$rss = new RSSFeed($this->Children(), $this->Link(), "My News");
  		$rss->outputToBrowser();
	}
	
	function init() {
   		RSSFeed::linkToFeed($this->Link() . "rss");	
   		parent::init();
	}
}
 
?>

Avatar
swaiba

Forum Moderator, 1899 Posts

9 October 2010 at 11:14am

hmmm that data is fine then, you don't need a table if you have no data there, sorry to say I'm stumped.

For my own sanity I've made a basic DataObject::get_one test to make sure it works.

The only thing I can suggest now is to take the debugging into sapphire\core\model\DataObject.php and debug show / log what is going on there!

Avatar
Sean

Forum Moderator, 922 Posts

9 October 2010 at 2:36pm

Edited: 09/10/2010 2:42pm

Try switching ShowInMenus on NewsHolder to 1 and see if the get_one() works?

This, for example, should definitely work, as it takes no consideration of whether the page should be visible in menus or not:

function LatestNews($num=3) { 
	$holderID = DB::query('SELECT "ID" FROM "SiteTree_Live" WHERE "ClassName" = \'NewsHolder\'')->value();
	return ($holderID) ? DataObject::get("NewsPage", "ParentID = $holderID", "Date DESC", "", $num) : false; 
}   

However, I don't recommend using the above for anything but debugging purposes. Mostly, because it does not augment any queries that modules or the Versioned extension may make.

Cheers,
Sean

Avatar
oleze

Community Member, 65 Posts

9 October 2010 at 10:46pm

So I tried a lot of other things to get it working (including your code). Nothing helped. Because the site is in development at the moment, I cleared my database and booom. It works. Damn, I hoped I'll never get an error like this again.

Avatar
pter

Community Member, 38 Posts

12 October 2010 at 3:04pm

Edited: 12/10/2010 3:37pm

There are two facets to this:

1. Someone has introduced a ParentID into the Page object. Not sure how (decorator?) but when you upgrade to 2.4.2 from 2.4.0 and do the dev/build you can see it being created (Page.ParentID & Page_live.ParentID).

2. As I have now learnt to my own joy developers are advised to ALWAYS qualify your database table references.

I even myself had previously assumed (yes, Ass, You, Me) that as SiteTree was the basis for all Pages (Page being an extension of SiteTree) there would be no need for another ParentID in child objects and have never bothered to fully qualify it as I have done for nearly all other fields where they may appear in another object and get picked up in the DataObject::get's huge database join.

E.g. while I would have gone

$theThingies = DataObject::get('Thingie','"Thingie"."ID" = 0');
$theThingies = DataObject::get('Thingie','ParentID = 0');
$thePages = DataObject::get('SiteTree','"ParentID" = 0');

Where the first will always be valid and has to be done as you could never be sure there wasn't another object with field name ID, but the next two I always considered okay (as covered in my assumptions above). So I have had to whip through all my code and change occurrences like the 2nd & 3rd to

$theThingies = DataObject::get('Thingie','"SiteTree"."ParentID" = 0');
$thePages = DataObject::get('SiteTree','"SiteTree"."ParentID" = 0');

So go through any of your own code and check you always qualify your dB search strings. And use the double quotes ("Page"."Afield") so that the data query engine will properly automagic that into Page or Page_live as appropriate.

And, yes, if you like to use double quotes to start strings and delimit inside with single quotes that also means going through all that code and reversing the usage. E.g. "ParentID = ".$this->ID now has to be '"SiteTree"."ParentID"'.$this->ID. So the string is now delimited by ' so you can use " to wrap the table and field names. Of course you can always be a step better than me and stick to always double quotes but escape embedded ones.

Silverstripe people - was there a reason for this new field? And where does it come from? I've done a quick scan of code but cannot locate it. Fair enough that we should code to avoid ambiguity but why was a ParentID field needed in page the first place? Unless there is an intent to step above or abandon SiteTree? Not following development news I have no idea so feel free to tell me where to get off (O:

Pter

Avatar
swaiba

Forum Moderator, 1899 Posts

13 October 2010 at 11:05pm

I've now expiernced this... I upgraded to 2.4.2, then after there being too many reasons not to use it downgraded back to 2.4.0 and suddenly a DataObject::get_by_id was causing the software to fail by running out of memory!

I replaced the get_by_id with get_one with the ID=$ID and it works - very strange!

Avatar
pter

Community Member, 38 Posts

14 October 2010 at 7:44am

Edited: 14/10/2010 7:50am

While I'm sure there will be some issues with upgrades my problem turns out to be caused by my approach to the module I was making - I extended the Hierarchy object then used add_extension in my module's _config.php to add to, e.g., Page.

Previous versions up to and including 2.4.0 didn't mind but, and I have to presume this is correct behaviour that was not being followed by previous versions, SS generates a linking ParentID variable for the extended class (e.g. Page.ParentID, BlogEntry.ParentID). Does not happen for SiteTree which already has a ParentID from including Hierarchy. I now try to find a different way to extend the Hierarchy object's stageChildren() function (in Yet Another Hide Pages In The CMS Module).

Go to Top