src/Page/Product.php
public function getCMSFields()
    {
        $self = $this;

        $this->beforeUpdateCMSFields(
            function (FieldList $fields) use ($self) {
                $fields->fieldByName('Root.Main.Title')
                    ->setTitle(_t(__CLASS__ . '.PageTitle', 'Product Title'));

                $fields->addFieldsToTab('Root.Main', [
                    TextField::create('InternalItemID', _t(__CLASS__ . '.InternalItemID', 'Product Code/SKU'), '', 30),
                    DropdownField::create('ParentID', _t(__CLASS__ . '.Category', 'Category'), $self->getCategoryOptions())
                        ->setDescription(_t(__CLASS__ . '.CategoryDescription', 'This is the parent page or default category.')),
                    ListboxField::create(
                        'ProductCategories',
                        _t(__CLASS__ . '.AdditionalCategories', 'Additional Categories'),
                        $self->getCategoryOptionsNoParent()
                    ),
                    TextField::create('Model', _t(__CLASS__ . '.Model', 'Model'), '', 30),
                    CheckboxField::create('Featured', _t(__CLASS__ . '.Featured', 'Featured Product')),
                    CheckboxField::create('AllowPurchase', _t(__CLASS__ . '.AllowPurchase', 'Allow product to be purchased'), 1),
                ], 'Content');

                $fields->addFieldsToTab(
                    'Root.Pricing',
                    [
                        TextField::create('BasePrice', $this->fieldLabel('BasePrice'))
                        ->setDescription(_t(__CLASS__ . '.PriceDesc', 'Base price to sell this product at.'))
                        ->setMaxLength(12),
                    ]
                );

                $fieldSubstitutes = [
                    'LengthUnit' => $self::config()->length_unit
                ];

                $fields->addFieldsToTab(
                    'Root.Shipping',
                    [
                    TextField::create(
                        'Weight',
                        _t(
                            __CLASS__ . '.WeightWithUnit',
                            'Weight ({WeightUnit})',
                            '',
                            [
                            'WeightUnit' => self::config()->weight_unit
                            ]
                        ),
                        '',
                        12
                    ),
                    TextField::create(
                        'Height',
                        _t(__CLASS__ . '.HeightWithUnit', 'Height ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    TextField::create(
                        'Width',
                        _t(__CLASS__ . '.WidthWithUnit', 'Width ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    TextField::create(
                        'Depth',
                        _t(__CLASS__ . '.DepthWithUnit', 'Depth ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    ]
                );

                if (!$fields->dataFieldByName('Image')) {
                    $fields->addFieldToTab(
                        'Root.Images',
                        UploadField::create('Image', _t(__CLASS__ . '.Image', 'Product Image'))
                    );
                }
            }
        );

        return parent::getCMSFields();
    }
public function getCMSFields()
    {
        $self = $this;

        $this->beforeUpdateCMSFields(
            function (FieldList $fields) use ($self) {
                $fields->fieldByName('Root.Main.Title')
                    ->setTitle(_t(__CLASS__ . '.PageTitle', 'Product Title'));

                $fields->addFieldsToTab('Root.Main', [
                    TextField::create('InternalItemID', _t(__CLASS__ . '.InternalItemID', 'Product Code/SKU'), '', 30),
                    DropdownField::create('ParentID', _t(__CLASS__ . '.Category', 'Category'), $self->getCategoryOptions())
                        ->setDescription(_t(__CLASS__ . '.CategoryDescription', 'This is the parent page or default category.')),
                    ListboxField::create(
                        'ProductCategories',
                        _t(__CLASS__ . '.AdditionalCategories', 'Additional Categories'),
                        $self->getCategoryOptionsNoParent()
                    ),
                    TextField::create('Model', _t(__CLASS__ . '.Model', 'Model'), '', 30),
                    CheckboxField::create('Featured', _t(__CLASS__ . '.Featured', 'Featured Product')),
                    CheckboxField::create('AllowPurchase', _t(__CLASS__ . '.AllowPurchase', 'Allow product to be purchased'), 1),
                ], 'Content');

                $fields->addFieldsToTab(
                    'Root.Pricing',
                    [
                        TextField::create('BasePrice', $this->fieldLabel('BasePrice'))
                        ->setDescription(_t(__CLASS__ . '.PriceDesc', 'Base price to sell this product at.'))
                        ->setMaxLength(12),
                    ]
                );

                $fieldSubstitutes = [
                    'LengthUnit' => $self::config()->length_unit
                ];

                $fields->addFieldsToTab(
                    'Root.Shipping',
                    [
                    TextField::create(
                        'Weight',
                        _t(
                            __CLASS__ . '.WeightWithUnit',
                            'Weight ({WeightUnit})',
                            '',
                            [
                            'WeightUnit' => self::config()->weight_unit
                            ]
                        ),
                        '',
                        12
                    ),
                    TextField::create(
                        'Height',
                        _t(__CLASS__ . '.HeightWithUnit', 'Height ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    TextField::create(
                        'Width',
                        _t(__CLASS__ . '.WidthWithUnit', 'Width ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    TextField::create(
                        'Depth',
                        _t(__CLASS__ . '.DepthWithUnit', 'Depth ({LengthUnit})', '', $fieldSubstitutes),
                        '',
                        12
                    ),
                    ]
                );

                if (!$fields->dataFieldByName('Image')) {
                    $fields->addFieldToTab(
                        'Root.Images',
                        UploadField::create('Image', _t(__CLASS__ . '.Image', 'Product Image'))
                    );
                }
            }
        );

        return parent::getCMSFields();
    }
Add product fields to CMS

@return FieldList updated field list