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

Customised Control method active records only [SOLVED]


Go to End


4 Posts   1413 Views

Avatar
EdP

Community Member, 14 Posts

26 August 2010 at 4:15am

Edited: 26/08/2010 8:27pm

I am new to Silverstripe but pretty competent at PHP.

I have set up a test site along the lines of the staff pages tutorial, but have added a new boolean field called Active so that I can hide some entries from public display. Everything is working well in the CMS.

I am stuck working out how to display only the Active (child) records through a template. In mysite/code/ I have this:

PerformerType.php:

<?php
class PerformerType extends Page {
	static $allowed_children = array('Performer');

	static $db = array(
	);
	static $has_many = array('Performers' => 'Performer'
	);
}
 
class PerformerType_Controller extends Page_Controller {
		
	function ActivePerformers() {
		return DataObject::get('Performer', 'Active');
	}
}
?>

Performer.php:
<?php
class Performer extends Page {
	static $has_one = array('PerformerType' => 'PerformerType',
						    'PerformerPhoto' => 'Image'
	);
	static $defaults = array('Active' => true);
	static $db = array('Active' => 'Boolean');
	
	static $singular_name = 'Performer';
	static $plural_name = 'Performers';

	function getCMSFields() {
	
		$fields = parent::getCMSFields();
		$fields->addFieldToTab('Root.Content.Main', $datefield, 'Content');*/
		$fields->addFieldToTab('Root.Content.Main', new CheckboxField('Active', 'Active - will not show if inactive'), 'Content');
		$fields->addFieldToTab("Root.Content.Image", new ImageField('PerformerPhoto'));
		return $fields;
	}
}
class Performer_Controller extends Page_Controller {
 
}
?>

The ActivePerformers function, when used on a template as a control in templates/mytheme/PerformerType.ss, returns all active Performers, irrespective of category (PerformerType). The Children control correctly returns rows in the relevant category, but ignores the Active field.

Any help much appreciated - I am afraid I have found working my way around the documentation rather frustrating.

Avatar
Willr

Forum Moderator, 5523 Posts

26 August 2010 at 1:05pm

Edited: 26/08/2010 1:05pm

DataObject::get('Performer', 'Active');

The second parameter needs to be an expression rather than just 'Active'. Perhaps use the actual expression

DataObject::get('Performer', "\"Active\" = '1'");

The funny escaping is the format for db abstracted queries - http://doc.silverstripe.org/coding-conventions#writing_queries_for_database_abstraction . I think simply "Active = '1'" will work on MySQL.

It also seems a bit strange that you have a Performer relationship as well as a parent - child. Bit redundant.

Sorry if the docs aren't as clear as they should, we are busy working on the new version as we speak.

Avatar
EdP

Community Member, 14 Posts

26 August 2010 at 8:24pm

Edited: 26/08/2010 8:26pm

Thank you. The issue wasn't escaping in the end, I rewrote the function as follows so that only active children were returned (rather than all active items irrespective of category):

class PerformerType_Controller extends Page_Controller {
		
	function ActivePerformers() {
		return DataObject::get("Performer", "ParentID = $this->ID AND Active");
	}
}

I have also removed the 'redundant' relationship. I only put it in because page 52 of the SilverStripe book seemed to suggest that one must define both ends of a relationship. Maybe this is only true of many_many, or maybe your shiny new documentation will clarify even further!

Avatar
Willr

Forum Moderator, 5523 Posts

26 August 2010 at 9:02pm

Edited: 26/08/2010 9:03pm

You do need to normally declare both ends of the relationship (has_one, has_many, many_many) but in your case this is unneeded as you already have a parent <-> child relationship which as you setup you have the performers under the type. So creating another relationship just to map the children to the parent is duplicating the functionality of the ParentID.

If your performers weren't direct children of your type then a relationship would be the right way to go. Hope that explains it a bit better :)