lmarcelocc Posted December 19, 2014 Share Posted December 19, 2014 (edited) Hi all, i'm trying to create a prestashop module, i'm a little used to MVC but this one is getting me crazy I have this controller in my: /prestashop16/modules/myModuleName/controllers include_once dirname(__FILE__).'/../../classes/Interaction.php'; class AdminJobstatusController extends ModuleAdminController { public function __construct() { $this->bootstrap = true; $this->display = 'list'; $this->meta_title = $this->l('Job Repair Status'); parent::__construct(); if (!$this->module->active) Tools::redirectAdmin($this->context->link->getAdminLink('AdminHome')); parent::__construct(); } public function setMedia() { // Add default css parent::setMedia(); return; } public function initToolBarTitle() { $this->toolbar_title[] = $this->l('Job Repair Status'); } public function initPageHeaderToolbar() { parent::initPageHeaderToolbar(); unset($this->page_header_toolbar_btn['back']); } public function postProcess() { } public function renderList(){ $this->toolbar_title[] = $this->l('All Jobs'); $fields_list = array( 'orderId' => array( 'title' => $this->l('Order'), 'width' => 140, 'type' => 'text' ), 'status' => array( 'title' => $this->l('Status'), 'width' => 140, 'type' => 'int' ), 'estimatedTime' => array( 'title' => $this->l('Estimated Repair Time'), 'width' => 140, 'type' => 'text' ), 'pickuptime' => array( 'title' => $this->l('Pickup Datetime'), 'width' => 140, 'type' => 'text' ), 'updated' => array( 'title' => $this->l('Last update'), 'width' => 140, 'type' => 'text' ), ); $helper = new HelperList(); $helper->shopLinkType = ''; $helper->simple_header = false; // Actions to be displayed in the "Actions" column $helper->actions = array('edit', 'delete', 'view'); $helper->identifier = 'id'; $helper->show_toolbar = true; $helper->title = $this->l('All jobs'); $helper->specificConfirmDelete = true; $helper->token = $this->context->controller->token; $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->module->name; // Call webservice $info = Interaction::getWebServiceInfo().$this->_displayInfo(); return $info.$helper->generateList(Interaction::getAllJobs(), $fields_list); } public function renderView() { $jobId = Tools::getValue('id'); if (!Validate::isInt($jobId)) $this->errors[] = Tools::displayError('Can\'t get job id!.'); if($jobId) $this->base_tpl_view = 'edit_job.tpl'; // $this->content = $this->createTemplate(dirname(__MODULE_DIR__) . '/../../views/templates/admin/edit_job.tpl')->fetch(); // $tpl = $this->context->smarty->createTemplate(dirname(__FILE__) . '/../../views/templates/admin/edit_job.tpl'); // return $tpl->fetch(); return parent::renderView(); } } This controller have this method: renderList() wich create the list with no problems with the correct actions, like mentioned in: $helper->actions = array('edit', 'delete', 'view'); Now what I want to achieve is: 1 - I know that if I click on edit will send some url params like 'id'. How can I do something with it in my controller? In cakePHP we do something like editAction(){} 2 - After do my stuff with user interaction, how can I set a template to it? With $this->base_tpl_view? I have my templates files in /prestashop16/modules/myModuleName/views/templates/admin/myModuleName/helpers/view Thanks in advance for your time. Best regards, Marcelo Edited December 19, 2014 by lmarcelocc (see edit history) Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 19, 2014 Author Share Posted December 19, 2014 (edited) Soz, I thought i found a good solution but not :S Still wait for your knowledge Edited December 19, 2014 by lmarcelocc (see edit history) Link to comment Share on other sites More sharing options...
gonebdg - webindoshop.com Posted December 19, 2014 Share Posted December 19, 2014 For action = edit, you need to define renderForm() method on your controller for example : public function renderForm() { // make sure object is loaded if (!($obj = $this->loadObject(true))) return; $this->fields_form = array( // array fields for the form, similiar with array on your renderList() // for reference, you can see the available Prestashop AdminController // e.g : ...\controllers\admin\AdminCustomersController.php ); // then ... let the parent controller class handle it (update object) return parent::renderForm(); } 1 Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 19, 2014 Author Share Posted December 19, 2014 Thank you gonebdg But, and if I want to upgrade 2 custom tables with parent controller ? And if I add new action 'Add' ho can i handle it? Sorry and thank you for your patience. Best regards and wish you a nice weekend. Marcelo Link to comment Share on other sites More sharing options...
gonebdg - webindoshop.com Posted December 20, 2014 Share Posted December 20, 2014 Usually i create my Admin module controller and determine the required variables in class constructor, also create custom classes file for the data which will be processed (add/edit/delete) by this controller.So the data will be treated as an object, because that was the reason why I use PHP OOP and MVC pattern (Prestashop) example : <?php /* ** My Admin Module Controller ** Module name : mymodulename (as defined on module file, $this->name) ** With this controller I will be able to Add/Edit/Delete data (object) that i want ** Controller Class name doesn't have to use or same as the module name ** In here the class name is Admin + Name + Controller ** "Name" will be used as directory name where the necessary template helper file placed ** e.g: view.tpl ** ..\modules\mymodulename\views\templates\admin\name\helpers\view\view.tpl */ class AdminNameController extends ModuleAdminController { public function __construct() { $this->bootstrap = true; $this->module = 'mymodulename'; // valid module name $this->table = 'db_table_name'; // DB table name where your object data stored $this->className = 'MyObjectClassName'; // The class name of my object $this->lang = false; $this->explicitSelect = true; $this->allow_export = true; $this->delete = true; $this->context = Context::getContext(); $this->orderBy = 'id_object'; // DB column field which hold my object ID $this->_orderWay = 'DESC'; $this->fields_list = $this->fieldList(); $this->shopLinkType = 'shop'; $this->actions = array('view', 'edit', 'delete'); $this->bulk_actions = array( 'delete' => array( 'text' => $this->l('Delete selected'), 'icon' => 'icon-trash', 'confirm' => $this->l('Delete selected object?') ) ); parent::__construct(); } public function fieldList() { // determine object fields in here. it will be processed by renderList() method // Note: fieldList can also determined directly on class constructor return $fields_list; } /* Function used to render the list to display for this controller */ public function renderList() { // No need to use/override this method if not necessary return $list; } /* Function used to render the view page */ public function renderView() { // form to add/edit my object are dermined here return parent::renderForm(); } /* Function used to render the form for this controller */ public function renderForm() { // form to add/edit my object are dermined here return parent::renderForm(); } } If everytings is ok, and i've created the renderForm() method for my controller, the "Add new" action menu will automatically available. On the top right of the data list table (rendered by my controller) there will be an action menu icon [+] which created automatically by Prestashop system. The parent classes AdminController.php will handle the process with processAdd() method If i click this icon menu, i can create new object value without having to bother writing my php code on my controller. Unless there is customizations needed or special circumstances which require me to extend processAdd() method. I suggest you to take a look deep inside Prestashop classes controller files :AdminModuleController.php and AdminController.phpand then start to create your Admin Module Controller file based on the available Prestashop Admin Controller. 2 Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 22, 2014 Author Share Posted December 22, 2014 Thank you very much gonebdg Will follow your tips. Merry christmas Thanks, Marcelo Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 23, 2014 Author Share Posted December 23, 2014 (edited) Hello gonebdg, i'm follow your advises and now i'm able to add / update my DB with an object, but now i have some doubts with whats the best way to do what i want, now I have something like in my controller: include_once dirname(__FILE__).'/../../classes/Save.php'; class AdminJobstatusController extends ModuleAdminController { public function __construct() { $this->bootstrap = true; $this->module = 'jobStatus'; // valid module name $this->table = 'jobStatus'; // DB table name where your object data stored $this->className = 'jobStatusObj'; // The class name of my object $this->lang = false; $this->explicitSelect = true; $this->allow_export = true; $this->delete = true; $this->context = Context::getContext(); $this->orderBy = 'id_jobStatus'; // DB column field which hold my object ID $this->_orderWay = 'DESC'; $this->fields_list = $this->fieldList(); $this->shopLinkType = ''; $this->shopLinkType = 'shop'; $this->actions = array('view', 'edit', 'delete'); $this->bulk_actions = array( 'delete' => array( 'text' => $this->l('Delete selected'), 'icon' => 'icon-trash', 'confirm' => $this->l('Delete selected object?') ) ); parent::__construct(); } public function renderForm() { // form to add/edit my object are dermined here // make sure object is loaded if (!($obj = $this->loadObject(true))) return; // Get order states available on store $orderStates = OrderState::getOrderStates((int)$this->context->language->id); foreach ($orderStates as $status) $this->statuses_array[] = array('id_order_state' => $status['id_order_state'], 'status' => $status['name']); // array fields for the form, similiar with array on your renderList() // for reference, you can see the available Prestashop AdminController // e.g : ...\controllers\admin\AdminCustomersController.php $this->fields_form = array( 'legend' => array( 'title' => (Tools::getValue('id_jobStatus')) ? sprintf($this->l('Add information to job: #%s'), Interaction::getOrderIdByJobId(Tools::getValue('id_jobStatus'))) : $this->l('Add new job'), 'icon' => 'icon-angle-double-right' ), 'input' => array( array( 'type' => 'select', 'label' => $this->l('Select status'), 'name' => 'status', 'required' => true, 'options' => array( 'query' => $this->statuses_array, 'id' => 'id_order_state', 'name' => 'status' ), 'col' => '4', 'desc' => $this->l('To create new status go to Orders -> Statuses.'), 'hint' => $this->l('To create new status go to Orders -> Statuses.') ), array( 'type' => 'text', 'label' => $this->l('Message'), 'name' => 'message', 'required' => false, 'col' => '6', 'suffix' => '<i class="icon-envelope-o"></i>', 'desc' => $this->l('Message to save/send to customer.'), 'hint' => $this->l('Message to save/send to customer.') ), array( 'type' => 'text', 'validation' => 'isInt', 'label' => $this->l('Time estimated to finish the job.'), 'name' => 'estimatedTime', 'required' => false, 'col' => '1', 'suffix' => '<i class="icon-clock-o"></i>', 'desc' => $this->l('(days)'), 'hint' => $this->l('(days)') ), array( 'type' => 'datetime', 'label' => $this->l('Pickup time'), 'name' => 'pickupTime', 'required' => false, 'col' => '6', 'desc' => $this->l('When customer can pickup/receive his product.'), 'hint' => $this->l('When customer can pickup/receive his product.') ), array( 'type' => 'switch', 'label' => $this->l('Advise customer by email?'), 'name' => 'emailSent', 'is_bool' => true, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Yes') ), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('No') ) ), 'desc' => $this->l('If you would like to advise customer by email about status update.') ), ), 'submit' => array( 'title' => $this->l( 'Save' ), 'class' => 'btn btn-default pull-right', 'name' => 'saveAction', ) ); // then ... let the parent controller class handle it (update object) return parent::renderForm(); } } and my Model: class jobStatusObj extends ObjectModel { /** * @see ObjectModel::$definition */ public static $definition = array( 'table' => 'jobStatus', 'primary' => 'id_jobStatus', 'fields' => array( // 'id_jobStatus' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), 'orderId' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 25, 'required' => false), 'status' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), 'estimatedTime' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => false), 'pickupTime' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'), // 'idJobStatus' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), // 'emailSent' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true), // 'message' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 250, 'required' => true), ), ); } My problem: I have two db tables: Table name: jobStatus Table name: jobStatusHistory Note: My form to add / edit have all the fields necessary to fill all this two tables. 1º I want to use the same object to save in both tables, how can I achieve that? Probably in my model in $definition variable. 2º For 1º goes fine I think I should make difeference in my renderForm() method, because when add new one i will need to set orderId (this is supposed to be an order Id create in BO), or should I make orderId my primary key and set it in my model? Hope you can give me another good tip or maybe someone else Best regards, Marcelo Edited December 29, 2014 by lmarcelocc (see edit history) Link to comment Share on other sites More sharing options...
gonebdg - webindoshop.com Posted December 28, 2014 Share Posted December 28, 2014 Sure you can. You can create object methods to achieve thatBut the variables which will be saved in separate DB table can not be added within the object property $definition.Object property $definition is to define variables belong to the specified DB table or to define variables related to multilingual, multishop or object associations. I'm not sure if i'm understand your second question. If you need to set a value for orderId, you just have to add it on your form or you can automatically retrieving the value with the existing object. 1 Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 29, 2014 Author Share Posted December 29, 2014 (edited) Sure you can. You can create object methods to achieve that But the variables which will be saved in separate DB table can not be added within the object property $definition. Object property $definition is to define variables belong to the specified DB table or to define variables related to multilingual, multishop or object associations. I'm not sure if i'm understand your second question. If you need to set a value for orderId, you just have to add it on your form or you can automatically retrieving the value with the existing object. Hello, forget my second question I get it, now I understand clear $definition property. So, I have to use/create some methods in my controller to get the user inputed values, validate them, and then, maybe for better structure, create some other class with my custom methods and call them to save that info in the other table? Which method should I override to threat data and then save it like mencioned above? processAdd() ? Maybe something like ? public function processAdd() { // Validate user input data $customer_email = strval(Tools::getValue('email')); /* ... */ if (Validate::isEmail($customer_email)) // All fine with all fields // Call custom class methods to save in the other table } Should be this the right method to achieve what I want? Or perhaps there's some other that will be more correct to use here? Thank you for your patience gonebdg. Best wishes, Marcelo Edited December 29, 2014 by lmarcelocc (see edit history) Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 30, 2014 Author Share Posted December 30, 2014 Hello, i'm getting there, is now working as expected, thanks gonebdg. Now i'm trying to do another thing and I have looked to helperList and can't find it, in my: $fields_list = array( 'id_jobStatus' => array( 'title' => $this->l('ID'), 'align' => 'text-center', 'class' => 'fixed-width-xs' ), 'orderId' => array( 'title' => $this->l('Order'), 'width' => 140, 'type' => 'text' ), 'customerEmail' => array( 'title' => $this->l('Customer Email'), 'width' => 140, 'type' => 'text' ), 'status' => array( 'title' => $this->l('Status'), 'width' => 140, 'type' => 'int' ) ); so, status fields is an int, i'm getting it from OrderState::getOrderStates and saving it in my custom table, I want to show it by status name instead of id. How can I achieve this? Hope someone can help me. Thanks in advance. Best regards, Marcelo Link to comment Share on other sites More sharing options...
gonebdg - webindoshop.com Posted December 30, 2014 Share Posted December 30, 2014 (edited) I guess you should override parent method renderList() something like this : /* ** Override renderList() method to show order state name instead ID ** @see public function renderList() ; /classes/controller/AdminController.php ** In here "status" is a field which hold id_order_state */ public function renderList() { if (!($this->fields_list && is_array($this->fields_list))) return false; $this->getList($this->context->language->id); // Start Modification $nb_list = count($this->_list); for($i=0;$i <= $nb_list;$i++) { if (isset($this->_list[$i]['status']) && $status = $this->_list[$i]['status']) { // instantiate object OrderState $order_state = new OrderState((int)$status, (int)$this->context->language->id); // Show OrderState name instead ID $this->_list[$i]['status'] = $order_state->name; } } // End Modification // instantiate object HelperList $helper = new HelperList(); // Empty list is ok if (!is_array($this->_list)) { $this->displayWarning($this->l('Bad SQL query', 'Helper').'<br />'.htmlspecialchars($this->_list_error)); return false; } $this->setHelperDisplay($helper); $helper->tpl_vars = $this->tpl_list_vars; $helper->tpl_delete_link_vars = $this->tpl_delete_link_vars; // For compatibility reasons, we have to check standard actions in class attributes foreach ($this->actions_available as $action) { if (!in_array($action, $this->actions) && isset($this->$action) && $this->$action) $this->actions[] = $action; } $list = $helper->generateList($this->_list, $this->fields_list); return $list; } NOTE: This is just an example and untested, then maybe this example won't working as expected, but i hope this example can help you to figuring out how to achieve your purpose. AND don't forget to change your field_list "status" type from "int" to "text" Edited December 30, 2014 by gonebdg - webindoshop.com (see edit history) 1 Link to comment Share on other sites More sharing options...
lmarcelocc Posted December 30, 2014 Author Share Posted December 30, 2014 Just wonderfull! Will test it ASAP. Thank you again Link to comment Share on other sites More sharing options...
SilviaPimenta Posted February 22, 2017 Share Posted February 22, 2017 Hello, I'm working on a module in version 1.6 of prestashop. N amine listing I am trying to together with the edit button appear also a send butt that will open in another window and will show a form, the code looks like this: $ Helper-> actions = array ('edit', 'send'); But I still can not show the button on the form. Thanks for your help. Regards, Sílvia Pimenta. Hello, I'm working on a module in version 1.6 of prestashop. N amine listing I am trying to together with the edit button appear also a send butt that will open in another window and will show a form, the code looks like this: $ Helper-> actions = array ('edit', 'send'); But I still can not show the button on the form. Thanks for your help. Regards, Sílvia Pimenta. Link to comment Share on other sites More sharing options...
nimafam Posted February 17, 2020 Share Posted February 17, 2020 On 12/20/2014 at 10:51 AM, gonebdg - webindoshop.com said: Usually i create my Admin module controller and determine the required variables in class constructor, also create custom classes file for the data which will be processed (add/edit/delete) by this controller. So the data will be treated as an object, because that was the reason why I use PHP OOP and MVC pattern (Prestashop) example : <?php /* ** My Admin Module Controller ** Module name : mymodulename (as defined on module file, $this->name) ** With this controller I will be able to Add/Edit/Delete data (object) that i want ** Controller Class name doesn't have to use or same as the module name ** In here the class name is Admin + Name + Controller ** "Name" will be used as directory name where the necessary template helper file placed ** e.g: view.tpl ** ..\modules\mymodulename\views\templates\admin\name\helpers\view\view.tpl */ class AdminNameController extends ModuleAdminController { public function __construct() { $this->bootstrap = true; $this->module = 'mymodulename'; // valid module name $this->table = 'db_table_name'; // DB table name where your object data stored $this->className = 'MyObjectClassName'; // The class name of my object $this->lang = false; $this->explicitSelect = true; $this->allow_export = true; $this->delete = true; $this->context = Context::getContext(); $this->orderBy = 'id_object'; // DB column field which hold my object ID $this->_orderWay = 'DESC'; $this->fields_list = $this->fieldList(); $this->shopLinkType = 'shop'; $this->actions = array('view', 'edit', 'delete'); $this->bulk_actions = array( 'delete' => array( 'text' => $this->l('Delete selected'), 'icon' => 'icon-trash', 'confirm' => $this->l('Delete selected object?') ) ); parent::__construct(); } public function fieldList() { // determine object fields in here. it will be processed by renderList() method // Note: fieldList can also determined directly on class constructor return $fields_list; } /* Function used to render the list to display for this controller */ public function renderList() { // No need to use/override this method if not necessary return $list; } /* Function used to render the view page */ public function renderView() { // form to add/edit my object are dermined here return parent::renderForm(); } /* Function used to render the form for this controller */ public function renderForm() { // form to add/edit my object are dermined here return parent::renderForm(); } } If everytings is ok, and i've created the renderForm() method for my controller, the "Add new" action menu will automatically available. On the top right of the data list table (rendered by my controller) there will be an action menu icon [+] which created automatically by Prestashop system. The parent classes AdminController.php will handle the process with processAdd() method If i click this icon menu, i can create new object value without having to bother writing my php code on my controller. Unless there is customizations needed or special circumstances which require me to extend processAdd() method. I suggest you to take a look deep inside Prestashop classes controller files :AdminModuleController.php and AdminController.php and then start to create your Admin Module Controller file based on the available Prestashop Admin Controller. Hi thank you for your explain, I have module admin controller in prestashop 1.7 and I setTemplate() in initContent() method and now I want to use Helperlist and render list method but my own template overrides on renderList() and list is not show in admin module controller page. how can I use custom template and render list width helper? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now