Creating a module with both front-end and back-end controllers
Last updated
Was this helpful?
Last updated
Was this helpful?
Table of contents
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
/* models/opinion.php */class
Opinion extends
ObjectModel{ public
$id_opinion; public
$id_customer; public
$opinion; public
$active;
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 ) ));
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; }}
<?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'); }}
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)
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>
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; }}
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.