Prestashop 1.6 - Add custom field to category

9.3k views Asked by At

I would like to know how I can add a custom field to a category and how I can edit in the back office (under the description field). the field I would like to add is name description_long

The field type is TEXT

I already have overwritten my Front office , and my field is well displayed .

override\classes\Category.php

<?php 

class Category extends CategoryCore
{

    public $description_long;

    /**
     * @see ObjectModel::$definition
     */
    public static $definition = array(
        'table' => 'category',
        'primary' => 'id_category',
        'multilang' => true,
        'multilang_shop' => true,
        'fields' => array(
            'nleft' =>              array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
            'nright' =>             array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
            'level_depth' =>        array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
            'active' =>             array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
            'id_parent' =>          array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
            'id_shop_default' =>    array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'is_root_category' =>   array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
            'position' =>           array('type' => self::TYPE_INT),
            'date_add' =>           array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
            'date_upd' =>           array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
            // Lang fields
            'name' =>               array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
            'link_rewrite' =>       array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
            'description' =>        array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
            'description_long' =>   array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'), // CUSTOM FIELD
            'meta_title' =>         array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
            'meta_description' =>   array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
            'meta_keywords' =>      array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
        ),
    );
}

Did not find any walktrough, can anyone help ?

3

There are 3 answers

4
Thony On BEST ANSWER

To anyone struggling here is a complete answer:

To Add a new description_long field to a category in Prestashop Category you need 3 steps:

  1. Update DB

Add your field named description_long to the category_lang table, you can mimic the description column characteristics

  1. Override Category class

Create a file here /override/classes/Category.php with this code:

class Category extends CategoryCore
{

    public $description_long;

    public function __construct($id_category = null, $id_lang = null, $id_shop = null){
        self::$definition['fields']['description_long'] = array('type' => self::TYPE_HTML, 'lang' => true);
        parent::__construct($id_category, $id_lang, $id_shop);
    }

}
  1. Override AdminCategoriesControllerCore class

Create a file here /override/controllers/admin/AdminCategoriesController.php with this code :

class AdminCategoriesController extends AdminCategoriesControllerCore{


    public function renderForm()
    {
        $this->fields_form_override =array(
            array(
                'type' => 'textarea',
                'label' => $this->l('Description long'),
                'name' => 'description_long',
                'lang' => true,
                'autoload_rte' => true,
                'hint' => $this->l('Invalid characters:').' <>;=#{}',
            ),
        );

        return parent::renderForm();
    }
}
1
kawashita86 On

to add a field in your backoffice you willl need to override the AdminCategoriesController, precisely the function renderForm() and add the new field in it. To achieve this create a new file AdminCategoriesController under the /override/controllers/admin/, then declare in it the extension of the original controller and copy in the renderForm function (fully) from the original core file.

class AdminCategoriesController extends AdminCategoriesControllerCore
{

    public function renderForm()
    {
        ...
    }
}

now we have to edit it in a couple of place, first we need to add the new field under the description, so search the declaration 'name' => 'description' inside your renderForm(), you will see that it's a list of array and each one is describing a form field. Right after the description array lets add our new field:

 array(
                    'type' => 'textarea',
                    'label' => $this->l('Description long'),
                    'name' => 'description_long',
                    'lang' => true,
                    'autoload_rte' => true,
                    'hint' => $this->l('Invalid characters:').' <>;=#{}',
                ),

this declaration is asking Prestashop to create a new field with the following specification:

  • a textarea field
  • a multilanguage field
  • the javascript plugin to edit

  • the name "description_long"

By declaring a field in this way we will allow prestashop to process it just like any other Class property, thus it won't require any work from our part to add and update the field in the database.

Now there's one last thing to do on our renderForm() function, right now the last instruction it is a parent::renderForm(), that in the original class was calling the AdminController to ask it to render the form, but right now since we are extending the class the instruction is calling our parent the AdminCategoriesControllerCore, overriding all our work and displaying the default form. To avoid this change the parent::renderForm to AdminController::renderForm() , explicitating the call to the interested class.

0
Samriddh Bhatt On

Add this line in your __construct function of overridden class

public function __construct($id_category = null, $id_lang = null, $id_shop = null)
    {

self::$definition['fields']['description_long'] = array('type' => self::TYPE_HTML, 'lang' => true);

parent::__construct($id_category, $id_lang, $id_shop);

}

where description_long is your new field name.