> For the complete documentation index, see [llms.txt](https://docs.prestashop-project.org/1-5-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.prestashop-project.org/1-5-documentation/english-documentation/developer-guide/creating-a-module-with-both-front-end-and-back-end-controllers.md).

# Creating a module with both front-end and back-end controllers

**Table of contents**

* [Creating a module with both front-end and back-end controllers](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingamodulewithbothfront-endandback-endcontrollers)
  * [Creating a new data table](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatinganewdatatable)
  * [Creating the model](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingthemodel)
    * [Variables](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Variables)
    * [Model definition](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Modeldefinition)
    * [Functions](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Functions)
  * [Creating the module's bootstrap file](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingthemodule'sbootstrapfile)
  * [Creating the hook's view](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingthehook'sview)
  * [Creating the front-office controller](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingthefront-officecontroller)
  * [Creating the back-office controller](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Creatingtheback-officecontroller)
  * [Adding the controller to the back-office](http://doc.prestashop.com/display/PS15/Creating+a+module+with+both+front-end+and+back-end+controllers#Creatingamodulewithbothfront-endandback-endcontrollers-Addingthecontrollertotheback-office)

## Creating a module with both front-end and back-end controllers <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingamodulewithbothfront-endandback-endco" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingamodulewithbothfront-endandback-endco"></a>

### Creating a new data table <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatinganewdatatable" id="creatingamodulewithbothfront-endandback-endcontrollers-creatinganewdatatable"></a>

Add a new table to your PrestaShop database. Name this table `ps_opinion`.

| `id_opinion \| int(10) unsignedid_customer \| int(10) unsignedopinion \| enum('AVERAGE','GOOD','VERY_GOOD')active \| tinyint(1) unsigned` |
| ----------------------------------------------------------------------------------------------------------------------------------------- |

### Creating the model <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingthemodel" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingthemodel"></a>

#### Variables <a href="#creatingamodulewithbothfront-endandback-endcontrollers-variables" id="creatingamodulewithbothfront-endandback-endcontrollers-variables"></a>

| `/* models/opinion.php */class` `Opinion extends` `ObjectModel{  public` `$id_opinion;  public` `$id_customer;  public` `$opinion;  public` `$active;` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ |

#### Model definition <a href="#creatingamodulewithbothfront-endandback-endcontrollers-modeldefinition" id="creatingamodulewithbothfront-endandback-endcontrollers-modeldefinition"></a>

| `public` `static` `$definition` `= array(    'table'` `=> 'opinion',    'primary'` `=> 'id_opinion',    'multilang'` `=> false,    'fields'` `=> array(      'id_opinion'` `=> array(          'type'` `=> ObjectModel :: TYPE_INT        ),      'id_customer'` `=> array(          'type'` `=> ObjectModel :: TYPE_INT,          'required'` `=> true        ),      'opinion'` `=> array(          'type'` `=> ObjectModel :: TYPE_STRING,          'required'` `=> true        ),      'active'` `=> array(          'type'` `=> ObjectModel :: TYPE_BOOL,          required' => true        )      ));` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

#### Functions <a href="#creatingamodulewithbothfront-endandback-endcontrollers-functions" id="creatingamodulewithbothfront-endandback-endcontrollers-functions"></a>

| `public` `static` `function` `findAll()  {    $sql` `= 'select * from '` `. _DB_PREFIX_ . 'opinion where active = 1';    if` `($rows` `= Db :: getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sql)) {        return` `ObjectModel :: hydrateCollection(__CLASS__, $rows);    }    return` `array();  }  public` `function` `getCustomerName()  {    $customer` `= new` `Customer($this->id_customer);    return` `$customer->firstname . ' '` `. $customer->lastname;  }}` |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### Creating the module's bootstrap file <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingthemodulesbootstrapfile" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingthemodulesbootstrapfile"></a>

| `<?phprequire_once` `dirname(__FILE__) . '/models/Opinion.php';class` `CustomerOpinion extends` `Module{  public` `function` `__construct()  {    $this->name = 'customeropinion';    $this->tab = 'front_office_features';    $this->version = 1.0;    $this->author = 'Me';    $this->displayName = $this->l('Customer Opinion');    $this->description = $this->l('Customer Opinion');    parent::__construct();  }  public` `function` `install()  {    return` `parent::install()    && $this->registerHook('leftColumn');  }  public` `function` `hookDisplayLeftColumn($params) {    return` `$this->display(__FILE__, 'left-column.tpl');  }}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

### Creating the hook's view <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingthehooksview" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingthehooksview"></a>

The `left-column.tpl` file is located in the `/views/templates/hook` folder.

| `{* Filename: left-column.tpl *}<a href="{$link->getModuleLink('customeropinion')}">{l s='Give my opinion'` `mod='customeropinion'}</a>` |
| ---------------------------------------------------------------------------------------------------------------------------------------- |

The `getModuleLink()` function makes it possible to add a link to the module's controller.\
Here is its signature: `$link->getModuleLink($module, $controller = 'default', array $params = array(), $ssl = false, $id_lang = null)`

### Creating the front-office controller <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingthefront-officecontroller" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingthefront-officecontroller"></a>

The module's controller, `default.php`, is located in the `/controllers/front` folder.

| `class` `helloWorldDefaultModuleFrontController extends` `ModuleFrontController{  public` `function` `initContent()  {    parent::initContent();    if` `($_SERVER['REQUEST_METHOD'] == 'POST') {      if` `($opinion` `= Tools::getValue('opinion', false)) {        $opinionObj` `= new` `Opinion();        $opinionObj->id_customer = $this->context->customer->id;        $opinionObj->active = false;        $opinionObj->opinion = $opinion;        $opinionObj->add();        $link` `= new` `Link();        Tools::redirect($link->getModuleLink('customeropinion', 'default'));      }    }    $opinions` `= Opinion::findAll();    $this->context->smarty->assign('opinions', $opinions);    $this->setTemplate('form.tpl');  }}` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

The template for the controller, `form.tpl`, is located in the `/views/templates/front` folder.

| `<h2>{l s='Give your opinion'` `mod='customeropinion'}</h2><form method="post"` `class="std">  <fieldset>    <label for="opinion"` `id="opinion">{l s='Our website is...'` `mod='customeropinion'}</label>    <select name="opinion">      <option>--</option>      <option value="VERY_GOOD">{l s='Very Good'` `mod='customeropinion'}</option>      <option value="GOOD">{l s='Good'` `mod='customeropinion'}</option>      <option value="AVERAGE">{l s='Average'` `mod='customeropinion'}</option>    </select>    <input type="submit"` `class="button"` `value="{l s='Give my opinion' mod='customeropinion'}"` `/>  </fieldset></form><hr /><h3>{l s='What people think'` `mod='customeropinion'}</h3><table style="width: 100%;">  {foreach` `from=$opinions` `item=opinion}  <tr>    <td>{$opinion->getCustomerName()}</td>    <td>{$opinion->opinion}</td>  </tr>  {/foreach}</table>` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

### Creating the back-office controller <a href="#creatingamodulewithbothfront-endandback-endcontrollers-creatingtheback-officecontroller" id="creatingamodulewithbothfront-endandback-endcontrollers-creatingtheback-officecontroller"></a>

The module's controller, `AdminOpinion.php`, is located in the `/controllers/admin` folder.

By convention, all back-office controllers should be named with the "Admin" prefix.

| `class` `AdminOpinionController extends` `ModuleAdminController{  public` `function` `__construct()  {    $this->table = 'opinion';    $this->className = 'Opinion';    parent::__construct();    $this->fields_list = array(        'id_opinion'` `=> array(            'title'` `=> '#'        ),        'id_customer'` `=> array(            'title'` `=> $this->module->l('Customer'),            'callback'` `=> 'getCustomerName'        ),        'opinion'` `=> array(            'title'` `=> $this->module->l('Opinion')        ),        'active'` `=> array(            'title'` `=> $this->module->l('Valider'),            'active'` `=> 'status'        )    );    $this->actions = array('delete');  }  public` `function` `getCustomerName($echo, $row)  {    $id_customer` `= $row['id_customer'];    $customer` `= new` `Customer($id_customer);    return` `$customer->firstname . ' '` `. $customer->lastname;  }}` |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### Adding the controller to the back-office <a href="#creatingamodulewithbothfront-endandback-endcontrollers-addingthecontrollertotheback-office" id="creatingamodulewithbothfront-endandback-endcontrollers-addingthecontrollertotheback-office"></a>

In its current state, the module's controller will not appear automatically in the back-office interface: you have to add it yourself, manually.

This is done using the tool in the "Menus" pages, under the "Administration" menu. See the documentation for this page in the PrestaShop 1.5 User Guide.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.prestashop-project.org/1-5-documentation/english-documentation/developer-guide/creating-a-module-with-both-front-end-and-back-end-controllers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
