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

Restricting visibility of database items


Go to End


19 Posts   3058 Views

Avatar
marc79

Community Member, 65 Posts

4 May 2011 at 1:58am

Hi,

I am relatively new to Silverstripe and currently working on a project for site that is selling CD's.

On the site I want to display the track names of each CD on the CD's Product page. So following Tutorial 5 I have so far used the $has_many relationship to link and CD with a track. Meaning that currently When you edit a CD's product page you can add in tracks and then associate them to that CD in the same way Mentors are linked to Students in the tutorial.

However, this isn't ideal for my site as for each CD you can see all available tracks for all CD's, and while you can't add a track to more than one CD it is an unmanageably long list. So, what I am trying to figure out is if there is a way to only show the relevant tracks when editing a CD product page.

The ideal way would be to only show tracks that were added for that CD. So if editing CD One you would only see tracks that were added there and then when editing CD Two you wouldn't see any of the tracks that were added for CD one.

I hope that makes sense and that someone can help point me in the right direction.

Thanks in advance.

Marc

P.s. let me know if you'd like me to post my code, what I have used is the same as tutorial 5 Student - Mentor relation - http://doc.silverstripe.org/sapphire/en/tutorials/5-dataobject-relationship-management

Avatar
swaiba

Forum Moderator, 1899 Posts

4 May 2011 at 2:17am

Always best to post (the summary / relevant parts of) your code, I'd use ModelAdmin for this and I'd control the EditForm via inserting/replacing/removing from the FieldSet using getCMSFields.

Avatar
marc79

Community Member, 65 Posts

4 May 2011 at 2:26am

Hi swaiba,

Thanks for your fast reply.

The key elements of my code are:

class ProductPage extends Page {

static $db = array(
'VolumeNumber' => 'Text',
'TrackNumber' => 'Text',
'TrackName' => 'Text',
);

static $has_many = array(
'VolumeTracks' => 'Track',
);

function getCMSFields() {
$fields = parent::getCMSFields();

. . . . .

$tablefield = new HasManyComplexTableField(
$this,
'VolumeTracks',
'Track',
array(
'VolumeNumber' => 'VolumeNmber',
'TrackNumber' => 'TrackNumber',
'TrackName' => 'TrackName'
),
'getCMSFields_forPopup'
);

$fields->addFieldToTab( 'Root.Content.Track', $tablefield );

return $fields;

}

}

and on the DataObject page

class Track extends DataObject {

static $db = array(
'VolumeNumber' => 'Text',
'TrackNumber' => 'Text',
'TrackName' => 'Text',
);

static $has_one =array(
'TrackProduct' => 'ProductPage'
);

function getCMSFields_forPopup() {
$fields = new FieldSet();

$fields->push( new TextField( 'VolumeNumber', 'Volume Number' ) );
$fields->push( new TextField( 'TrackNumber' ) );
$fields->push( new TextField( 'TrackName' ) );

return $fields;
}

}

Which all works great. I think that all I need to do is pull the current PageID when adding a new field and then filter by the current page when displaying one the frontend.

I'll also have a look at ModelAdmin.

Cheers

Marc

Avatar
swaiba

Forum Moderator, 1899 Posts

4 May 2011 at 2:29am

Edited: 04/05/2011 2:29am

looks like you can add a 6th param onto your HasManyComplexTableField (http://api.silverstripe.org/2.4/forms/fields-relational/HasManyComplexTableField.html), something like this...

'TrackProductID='.$this->ID

Avatar
marc79

Community Member, 65 Posts

4 May 2011 at 3:08am

I have tried the ModelAdmin, which looks like it could be a good solution, but at the moment it just hangs when I try to add a new CD Track and then when I refresh the database an new line has been added but with all default data. This will need more investigation. I feel I am closer with what I have, if I can get it to do this last little bit.

I've just tried adding the extra param to the Table but it comes out like the attached screen grab.

In the database the table does include a column for the ProductID but this only gets used once you click the check box on the left. And it does already filter the content on the frontend correctly it is just in admin that I want the checkbox to be automatically 'checked' based on the page you are editing and then not to display any that weren't created on that page. As you can see from the screen grab row three is greyed out and you can't check it because it has already been assigned to another CD.

Thanks again

Marc

Avatar
marc79

Community Member, 65 Posts

4 May 2011 at 4:13am

So. I think I am going to use the ModelAdmin approach as it seems to work well and also has the import from CSV option. All I need to figure out now is how to query that data based on a variable of current page. e.g. If current page is CD One pull back all tracks stored in Model admin that have been assigned the 'category' CD One.

Avatar
swaiba

Forum Moderator, 1899 Posts

4 May 2011 at 4:18am

these are also things that can be set on ModelAdmin (in regards to choosing from the results)...

		$hasOneCTF->setPermissions(array('edit','show'));
		$hasOneCTF->Markable = false;

if you convert this to ModelAdmin, I'll have a quick look at it again to see what the issue is, I think with a has_many there you will not need to do anything in the getCMSFields at all - the scaffolding should be enough...

Avatar
marc79

Community Member, 65 Posts

4 May 2011 at 4:27am

Edited: 04/05/2011 4:27am

Hi,

Thanks for the post but you have lost me a bit on that one.

I have now moved away from everything I was doing before and just using ModelAdmin.

--

TrackAdmin.php:

class TrackAdmin extends ModelAdmin {

public static $managed_models = array(
'CDTracks',
'CDVolumes'
);

static $url_segment = 'cdtracks';
static $menu_title = 'Track Admin';

}

--

CDTracks.php:

class CDTracks extends DataObject {

static $db = array(
'TrackName' => 'Varchar',
'TrackNumber' => 'Varchar',
'TrackDescription' => 'Text'
);

static $has_one = array(
'CDVolumes' => 'CDVolumes'
);

static $searchable_fields = array(
'TrackName',
'TrackNumber'
);

}

--

CDVolumes.php:

class CDVolumes extends DataObject {
static $db = array(
'Volume' => 'Text'
);
}

---

I'd then added a CDVolumeID field to the ProductPage

$fields->addFieldToTab('Root.Content.Main', new TextField('CDVolumesID','CDVolumesID'));

Along with a basic query to the db to pull back the tracks.

public function CDTracks()

{
return DataObject::get("CDTracks");
}

My next step was going to be to amend that query so that I can link the CDVolumeID in the 'CDTracks' with the CDVolumeID of the Current page. Would that be the right approach or am I making thing to messy?

Cheers

Marc

Go to Top