Dejsa Cocan
Dejsa Cocan

Reputation: 1569

SilverStripe - get selected checkbox fields from one admin model for use in another

I have an admin model called PortfolioItemPage which has a $many_many relationship with another admin model called MediaTypeTag. In PortfolioItemPage I have mapped all values to checkboxes from MediaTypeTag into a separate tab (this is so a portfolio item can be associated with different media tags for filtering purposes on the site).

Each PortfolioItemPage data object has a $has_many relationship with the data object PortfolioChildItem. Basically, PortfolioItemPage represents a company and PortfolioCildItem represents a sample of work from said company. (i.e. Company ABC has 6 sample portfolio pieces, Company XYZ has 4 portfolio pieces, etc)

What I'd like to do is add a checkbox list of MediaTypeTags to the PortfolioChildItem data object, but only those that have been selected by the child item's corresponding PortfolioItemPage. For example, if Company ABC (a PortfolioItemPage data object) has the following media tags selected: TV, Website, Billboard (all 3 are MediaTypeTag data objects), I want to only have those 3 media tags appear as checkbox options for each portfolio sample (each of which is a PortfolioChildItem).

I'm not sure if something like this is even possible as I've never attempted something like this before. Is this something that is doable?

Here is the code for the data objects mentioned: PortfolioChildItem

<?php
class PortfolioItemPage extends Page {

    private static $db = array(
        'Excerpt' => 'Text',
        'PreferredItem' => 'Boolean'
    );

    private static $has_one = array(
        'Thumbnail' => 'Image',
    );

    private static $has_many = array(
        'PortfolioChildItems' => 'PortfolioChildItem'
    );

    private static $many_many = array(
        'MediaTypeTags' => 'MediaTypeTag',
    );

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

        if ($this->ID) {
            $fields->addFieldToTab('Root.Media Type Tags', CheckboxSetField::create(
                'MediaTypeTags',
                'Media Type Tags',
                MediaTypeTag::get()->map()
            ));
        }

        $gridFieldConfig = GridFieldConfig_RecordEditor::create();

        $gridFieldConfig->addComponent(new GridFieldBulkUpload());

        $gridFieldConfig->addComponent(new GridFieldSortableRows('SortOrder'));
        $gridFieldConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
            'YouTubeEmbedURL' => 'YouTube Video ID',
            'SoundCloudEmbedURL' => 'SoundCloud Embed Code',
            'Thumb' => 'Thumb (135px x 135px)',
        ));

        $gridfield = new GridField(
            "ChildItems",
            "Child Items",
            $this->PortfolioChildItems(),
            $gridFieldConfig
        );

        $fields->addFieldToTab('Root.Child Items', $gridfield);

        $fields->addFieldToTab("Root.Main", new TextareaField("Excerpt"), "Content");
        $fields->addFieldToTab("Root.Main", new UploadField('Thumbnail', "Thumbnail (400px x 400px)"), "Content");

        $fields->addFieldToTab("Root.Main", new CheckboxField('PreferredItem', 'Show on all pages?', 0), "Content");


        return $fields;
    }

    public function getChildItems() {
        return $this->PortfolioChildItems()->sort('SortOrder');
    }

    public function getFormattedContent() {
        return addslashes($this->Content);
    }
}

class PortfolioItemPage_Controller extends Page_Controller {


    private static $allowed_actions = array (
    );

    public function init() {
        parent::init();
    }

}

PortfolioChildItem:

<?php
class PortfolioChildItem extends DataObject {

    private static $db = array(
        'YouTubeEmbedURL' => 'Varchar(25)',
        'SoundCloudEmbedURL' => 'Text',
        'SortOrder' => 'Int'
    );


    private static $has_one = array(
        'Banner' => 'Image',
        'Thumb' => 'Image',
        'PortfolioItemPage' => 'Page'
    );

    private static $many_many = array(
        'MediaTypeTags' => 'MediaTypeTag',
        'IndustryTags' => 'IndustryTag'
    );


    // tidy up the CMS by not showing these fields
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->removeFieldFromTab("Root.Main","PortfolioItemPageID");

        //code to create checkboxes goes here

        return $fields;
    }

    private static $field_labels = array(
        'Banner' => 'Banner (1280px x 700px)',
        'Thumb' => 'Thumb (135px x 135px)',
        'YouTubeEmbedURL' => 'YouTube Video ID (ex: OVgpJIkHmAw from video URL)',
        'SoundCloudEmbedURL' => 'SoundCloud Embed Code',
    );

    // this function creates the thumnail for the summary fields to use
    public function getThumbnail() {
        return $this->Image()->CMSThumbnail();
    }

    public function getSoundCloudURL() {
        return;
    }
}

MediaTypeTag:

<?php
class MediaTypeTag extends DataObject {

    private static $db = array(
        'Name' => 'varchar(250)',
    );

    private static $summary_fields = array(
        'Name' => 'Title',
    );

    private static $field_labels = array(
        'Name'
    );

    private static $belongs_many_many = array(
        'PortfolioItemPages' => 'PortfolioItemPage'
    );

    // tidy up the CMS by not showing these fields
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->removeByName("PortfolioItemPages");

        return $fields;
    }

    static $default_sort = "Name ASC";
}

Upvotes: 0

Views: 1026

Answers (1)

Gavin Bruce
Gavin Bruce

Reputation: 1809

You should be able to do this by getting the MediaTypeTag ids and then using those as a filter.

In the getCMSFields function on the class PortfolioChildItem add something like this.

$mediaTypeTagIDs = array();
$mediaTypeTags = $this->PortfolioItemPage()->MediaTypeTags();
if ($mediaTypeTags->count()) {
  foreach ($mediaTypeTags as $mediaTypeTag) {
    $mediaTypeTagIDs[] = $mediaTypeTag->ID;
  }
  $mediaTypeTagList = DataList::create('MediaTypeTag')->byIDs($mediaTypeTagIDs);
}

Then add $mediaTypeTagList into a grid field.

Upvotes: 2

Related Questions