Aurélien
Aurélien

Reputation: 65

Two dataobject managed in one gridfied with orderable columns. Silverstripe 3.1

I'm working with Silverstripe 3.1

I would like manage in one admin model page two dataobject. Here is my first DataObject :

class Interview extends DataObject
{
    private static $db = array(
        'Name'          => 'Varchar(255)',
        'LieuExercice'  => 'Varchar(255)',
        'Presentation'  => 'Text',
    );

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

    private static $belongs_many_many = array(
        'Journal'   => 'Journal'
    );

    // Change the label in datagrid
    private static $field_labels = array(
        'NameAndExercice' => 'Nom de la personne interviewée',
        'LieuExercice' => 'Lieu d\'exercice'
    );
    public function getNameAndExercice(){
        return  new LiteralField('NameAndExercice', $this->Name  . ' <em style=\'font-size:11px\'>('.$this->LieuExercice.')</em>');
    }

    private static $summary_fields = array(
        'NameAndExercice',
    );

    public function getCMSFields() {
        $fields = FieldList::create(TabSet::create('Root'));
        $fields->addFieldsToTab('Root.Contenu', TextField::create('Name', 'Nom de la personne interviewée'));
        $fields->addFieldsToTab('Root.Contenu', TextField::create('LieuExercice', 'Lieu d\'exercice')->setDescription('Lieu d\'exercice de la personne'));
        $fields->addFieldsToTab('Root.Contenu', TextareaField::create('Presentation', 'Présentation')->setDescription('Courte présentation de la personne'));
        $fields->addFieldsToTab('Root.Contenu', $photo = UploadField::create('Photo', 'Portrait de la personne interviewée')->setDescription('Fichier image du portrait de la personne'));

        //Fields configuration
        $photo->getValidator()->setAllowedExtensions(array('png', 'jpg', 'gif', 'jpeg'));
        $photo->setFolderName('interview-photos');

        return $fields;
    }
}

And here is my 2nd DataObject :

class Article extends DataObject
{
    private static $db = array(
        'Title'          => 'Varchar(255)',

    );

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

    private static $belongs_many_many = array(
        'Journal'   => 'Journal'
    );

    public function getCMSFields() {
        $fields = FieldList::create(TabSet::create('Root'));

        $fields->addFieldsToTab('Root.Contenu', TextField::create('Title', 'Titre de l\'article'));

        $fields->addFieldsToTab('Root.Contenu', $photo = UploadField::create('Photo', 'Portrait de la personne interviewée')->setDescription('Fichier image du portrait de la personne'));

        //Fields configuration
        $photo->getValidator()->setAllowedExtensions(array('png', 'jpg', 'gif', 'jpeg'));
        $photo->setFolderName('interview-photos');

        return $fields;
    }
}

Finally, I have a 'parent' dataObject witch contain some Interviews and Article :

class Journal extends DataObject
{
    private static $db = array(
        'Title' => 'Varchar',
        'DatePublication'   => 'Date'
    );
    private static $has_one = array(
        'Couverture'        => 'Image'
    );
    private static $many_many = array(
        'Interviews'    => 'Interview',
        'Articles'      => 'Article',
    );
    private static $many_many_extraFields = array(
        'Interviews' => array(
            'SorterField' => 'Int',
        ),
        'Articles' => array(
            'SorterField' => 'Int',
        ),
    );

    public function getCMSFields(){
            $fields = FieldList::create(TabSet::create('Root'));

            $fields->addFieldsToTab('Root.Main', array(
                $titleField = TextField::create('Title', 'Titre / Numéro du journal'),
                $datePublicationField = DateField::create('DatePublication', 'Date de publication'),
                $uploadField = UploadField::create('Couverture', 'Couverture du journal')

            ));


            if($this->ID){
                $fields->insertAfter(
                    new Tab('Content', 'Contenu du journal'),
                    'Main'
                );

                //$buttonCreateMultiClass = new GridFieldAddNewMultiClass();
                //$buttonCreateMultiClass->setClasses(array('Interviews', 'Article'));

                $config = GridFieldConfig_RelationEditor::create();
                $config->addComponent(new GridFieldOrderableRows('SorterField'));

                $fields->addFieldsToTab('Root.Content', GridField::create(
                    'Interviewsz',
                    'Contenu de ce journal',
                    $this->getManyManyComponents('Interviews')->sort('SorterField'),
                    $config
                ));
            }

            // Fields configuration
            $datePublicationField->setConfig ('showcalendar', true);
            $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'gif', 'png', 'jpeg'));
            $uploadField->setFolderName('journals-couvertures');
            return $fields;

    }
}

I would like in a model admin page of Journal: - Create new Journal : OK, done - Link one or more interview to this Journal - Link one or more article to this Journal - Manage the order of article and interview inside the journal

How do this ?

Thanks for your help.

Upvotes: 2

Views: 109

Answers (1)

Mark Guinn
Mark Guinn

Reputation: 619

I would give both articles and interviews a common parent class and put both in one gridfield (as wmk suggested in the comments). I'd also suggest you use the GridFieldAddMultiClass component from this extension: https://github.com/silverstripe-australia/silverstripe-gridfieldextensions so that a user can select whether he/she wants to add an Interview or an Article. Something like the following:

class Journal extends DataObject {
    private static $has_many = ['ContentItems' => 'ContentItem'];
}

class ContentItem extends DataObject {
    private static $db => ['Sort' => 'Int'];
    private static $has_one => ['Journal' => 'Journal'];
}

class Article extends ContentItem {}
class Interview extends ContentItem {}

Then you build your single GridView off the Journal.ContentItems() relationship.

Upvotes: 3

Related Questions