Eric Kaburu
Eric Kaburu

Reputation: 17

Silverstripe Framework Model Admin, Data Object Relations and OptionsetField saving into the Database

I am building an online shop. I am trying to implement a has_one : has_many relationship for DataObjects am managing using ModelAdmin with the use of radio buttons (OptionsetField in Silverstripe), but I have 2 problems.

  1. The relations values are not getting saved into the database when I click save in the CMS.

  2. The state does not persist so that when I log into the CMS next time I can see which radio button I selected last time.

Next is my code

---- Model Admin ----

<?php

class ProductAdmin extends ModelAdmin {

    private static $menu_title = 'Store Manager';

    private static $url_segment = 'StoreManager';

    private static $managed_models = array (
        'Product'=>array('title'=>'All Store Products'),
        'ProductCategory'=>array('title'=>'Product Categories'),
        'ProductSubcategory'=>array('title' => 'Product Sub Categories')
    );

    public $showImportForm = false;

    }

---- Category ----

<?php

    class ProductCategory extends DataObject {

        private static $db = array (
            'Title' => 'Varchar',
        );

        /**
         * This relation links the Category to the Menu Items e.g. Category BoysClothing will be related to Boys * Menu Item.
         */
        private static $has_one = array(
            'Page' => 'Page'
        );

        private static $has_many = array (
            'Subcategories' => 'ProductSubcategory'
        );
        public function getCMSFields(){
            $fields = FieldList::create(TabSet::create('Root'));

            $fields->addFieldsToTab('Root.Main', array(
                TextField::create('Title', 'Name of Category'),

                OptionsetField::create(
                    'Page', //name
                    'Page this category belongs to', //title
                    SiteTree::get()->filter(array('ShowInMenus' => '1'))->map('ID', 'Title'),
                    1
                )

            )//close array of fields
            );//end adding fields to main tab 

            return $fields;
        }
}

---- Product Sub Category ----

<?php

    class ProductSubcategory extends DataObject {

        private static $db = array (
            'Title' => 'Varchar',
        );

        /**
         * This relation links the Sub Category to the Category e.g. Category Khakis will be related to Boys 
         * Category
         *
         */
        private static $has_one = array(
            'Category' => 'ProductCategory'
        );//will lead to creation of column BoysPageID on the table BoysCategory

        private static $has_many = array (
            'Products' => 'Product'
        );

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

            $fields->addFieldsToTab('Root.Main', array(
                TextField::create('Title', 'Name of Sub Category'),
                DropdownField::create(
                  'Category',
                  'Category this subcategory belongs to',
                  ProductCategory::get()->map('ID', 'Title')
                )


            )//close array of fields
            );//end adding fields to main tab 

            return $fields;
        }


    }//end class

    ---- Product ----
    <?php

    class Product extends DataObject{
        private static $db = array (
            'Title'     => 'Varchar(255)',
            'Price'     => 'Varchar',
            'Colors'    => 'Varchar',
            'Sizes'     => 'Varchar',
            'FeaturedOnHomepage' => 'Boolean'
        );

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


        static $summary_fields = array (
            'Title' => 'Name',
            'Price' => 'Price',
            'FeaturedOnHomepage.Nice' => 'Featured?',
            'Thumbnail' => 'Picture'
        );



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

            $fields->addFieldsToTab('Root.Main', array(
                TextField::create('Title', 'Name of product'),
                TextField::create('Price', 'Price of product'),
                TextField::create('Colors', 'Available Colors'), //Make this a checkbox set or multiselect drop down
                TextField::create('Sizes', 'Available Sizes'), //Make this a checkbox set or multiselect drop down
                CheckboxField::create('FeaturedOnHomepage', 'Feature On HomePage'),
                CheckboxSetField::create(
                    'ProductSubcategory',
                    'Sub categories this product belongs to',
                    ProductSubcategory::get()->map('ID', 'Title')
                ),
                $primary_photo = UploadField::create('PrimaryPhoto', 'Product Primary Photo')
            )//close array of fields
            );//end adding fields to main tab 

            //Add other photos related to this image in a deifferent tab
            $other_product_photos = UploadField::create('ProductImages', 'Product Photo');
            $fields->addFieldsToTab('Root.Other Photos', $other_product_photos);

            //limit image extensions
            $primary_photo->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
            $other_product_photos->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));

            //set Folders
            $primary_photo->setFolderName('ProductPhotos');
            $other_product_photos->setFolderName('ProductPhotos');


            //return
            return $fields;
        }


        public function Link(){
            $sview_link = "prods/sview/";
            return $sview_link.$this->ID;
        }

        public function getThumbnail(){
            if($this->PrimaryPhoto()->ID){
                return $this->PrimaryPhoto()->setWidth(80);
            }else{
                return 'No Image';
            }
        }


    }//close class Product

Upvotes: 0

Views: 355

Answers (1)

wmk
wmk

Reputation: 4626

As Page is a has_one relation you need to add the suffix ID to the formfield (yes, that's annoying for beginners).

So

            OptionsetField::create(
                'PageID', //name
                'Page this category belongs to', //title
                SiteTree::get()->filter(array('ShowInMenus' => '1'))->map('ID', 'Title'),
                1
            )

should work. The same for the Category has_one in SubCategory.

You already stated in your code

//will lead to creation of column BoysPageID on the table BoysCategory

that's cause the has_one relation Foo is saved in DB as FooID, so we need to add the ID manually to the formfield.

Upvotes: 0

Related Questions