I'm making a PrestaShop 1.6 module and something weird is happening. In the configure page of this module I offer the user two forms. One to configure an automatic email and other to test the e-mail. My problem is that after submitting the second form the $this->context->smarty is null giving me this error:
Fatal error: Call to a member function assign() on null in /Users/andre/Projects/Web/xxx/modules/closecustomerthreademail/closecustomerthreademail.php on line 90
In line 90 I have: $this->context->smarty->assign('module_dir', $this->_path); which is inside of this function:
public function getContent()
{
/**
* If values have been submitted in the form, process.
*/
if (((bool)Tools::isSubmit('submitClosecustomerthreademailModule')) == true) {
$this->postProcess();
}
$this->context->smarty->assign('module_dir', $this->_path);
$output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/configure.tpl');
return $output.$this->renderForm();
}
This is how I add two forms in the screen (renderForm method): return $helper->generateForm(array($this->getConfigForm(), $this->getTestForm()));
The postProcess. Sorry for pasting so much code, I'm trying to provide all the details I find relevant.
protected function postProcess()
{
if(Tools::isSubmit('test_form')) {
$this->sendTestEmailTo(Tools::getValue('CLOSECUSTOMERTHREADEMAIL_EMAIL_TO_TEST'));
}
elseif(Tools::isSubmit('config_form')) {
$form_values = $this->getConfigFormValues('config_form');
foreach (array_keys($form_values) as $key) {
Configuration::updateValue($key, Tools::getValue($key));
}
}
}
The sendTestEmailTo just has an IF statement and then call this function:
public function sendEmail($to_email, $to_name = null){
$id_lang = $this->context->language->id;
$template_dir = _PS_MODULE_DIR_.$this->name.'/views/templates/email/';
$vars = array(
'{html}' => Configuration::get('CLOSECUSTOMERTHREADEMAIL_EMAIL_HTML_BODY'),
'{text}' => Configuration::get('CLOSECUSTOMERTHREADEMAIL_EMAIL_TEXT_BODY')
);
require(_PS_CONFIG_DIR_.'config.inc.php');
require_once(_PS_ROOT_DIR_.'/init.php');
$send = Mail::Send(
(int)$id_lang,
'email',
Configuration::get('CLOSECUSTOMERTHREADEMAIL_EMAIL_SUBJECT'),
$vars,
$to_email,
$to_name,
null,
null,
null,
null,
$template_dir,
false,
(int)$this->context->shop->id,
null
);
return $send;
}
I'm failing to see what could be causing $this->context->smarty to be null. Would you have any tips to help me investigate?
EDIT
The construct method:
public function __construct()
{
$this->name = 'closecustomerthreademail';
$this->tab = 'others';
$this->version = '1.0.0';
$this->author = 'andre';
$this->need_instance = 0;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Close Customer Thread e-mail');
$this->description = $this->l('Sends an e-mail whenever you close a customer thread');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
I'm glad that you've solved. But I guess that the problem is this:
require(_PS_CONFIG_DIR_.'config.inc.php');
require_once(_PS_ROOT_DIR_.'/init.php');
Remove those lines :), you shouldn't never include that files in a class method.
I couldn't figure out before the delivery so I had to do this to solve, a redirect:
protected function postProcess()
{
if(Tools::isSubmit('test_form')) {
$this->sendTestEmailTo(Tools::getValue('CLOSECUSTOMERTHREADEMAIL_EMAIL_TO_TEST'));
}
elseif(Tools::isSubmit('config_form')) {
$form_values = $this->getConfigFormValues('config_form');
foreach (array_keys($form_values) as $key) {
Configuration::updateValue($key, Tools::getValue($key));
}
}
$actual_link = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
Tools::redirectAdmin($actual_link);
}
Related
I was able to create a menu tab in the back office but when I click on it, I get
Page not found.
The controller is missing or invalid.
Here's the code for my controller -
<?php
class AdminModuleNameConvert extends ModuleAdminController {
public function __construct() {
$this->bootstrap = true;
parent::__construct();
}
}
Using the solution provided by ethercreation, I get the controller to load, but it shows me
Try width :
In your module : modulenameconverter
class modulenameconverter extends Module
{
public function __construct(Context $context = null)
{
$this->name = 'modulenameconverter';
$this->version = '1';
$this->bootstrap = true;
$this->author = 'Stackoverflow';
$this->displayName = $this->l('modulenameconverter');
$this->description = $this->l('Module name converter');
parent::__construct();
}
public function install()
{
$tab = new Tab();
$tab->class_name = 'Adminmodulenameconverter';
$tab->module = 'modulenameconverter';
$tab->name[1] = 'modulenameconverter';
$tab->id_parent = 2;
$tab->active = 1;
if (!$tab->save()) {
return false;
}
return parent::install();
}
public function uninstall()
{
$id_tab = (int)Tab::getIdFromClassName('Adminmodulenameconverter');
$tab = new Tab($id_tab);
if (Validate::isLoadedObject($tab)) {
if (!$tab->delete()) {
return false;
}
} else {
return false;
}
return parent::uninstall();
}
}
In module/controllers/admin/AdminModulenameconverterController.php
class AdminNameconverterController extends ModuleAdminController
{
public function __construct()
{
parent::__construct();
$this->bootstrap = true;
$this->id_lang = $this->context->language->id;
$this->default_form_language = $this->context->language->id;
}
public function initContent()
{
parent::initContent();
}
}
I was having the exact same issue and it appears that I was not configuring the tab parameters correctly... I was trying to pass an array for the "$this->module" parameter so Prestashop could not find the module because in the database, the module linked to the tab was equal to ""...
So my best advice in this case is to always check your database fields to see if they are correctly filled.
To conclude : It's always the silliest issues that makes the biggest headaches... -_-'
How to add custom input field in Product image form using hooks.I am trying to add a new check box in product image form but i do not know how to create it by using modules as well as i am not able to override core product page template.I am createing directory structure inside themes/classic/module/module_name/.....
If some can write the main module php file of Prestashop 1.7 I am very thankful to you.
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class youmodule extends Module
{
protected $config_form = false;
public function __construct()
{
$this->name = 'youmodule';
$this->tab = 'administration';
$this->version = '1.0.0';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('youmodule');
$this->description = $this->l('youmodule');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
public function install()
{
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('displayAdminProductsExtra');
}
public function uninstall()
{
return parent::uninstall();
}
public function hookDisplayAdminProductsExtra($params)
{
$id_product = Tools::getValue('id_product');
//YOURCODE
$this->smarty->assign(array(
'yourvariable' => $yourvariabl
));
return $this->display(__FILE__, '/views/templates/admin/product.tpl');
}
}
my website application is mostly model around a User Model which has all the key data that needed for most of the times.
Once the user is logged into the website I would like to keep it as a persistent variable across all the controllers. How do i achieve this as i cannot use session to hold a class object of Type Model.
My application is based on phalcon. However any suggestions are welcome.
I suggest you to write a simple class for user authentication & other user data manipulation, i wrote this Component and using in my project :
use Phalcon\Mvc\User\Component;
class Auth extends Component {
public function login($credentials) {
if(!isset($credentials['email'],$credentials['password'])) {
return FALSE;
}
if($this->isAuthorized()) {
return true;
}
$user = Users::findFirstByEmail($credentials['email']);
if($user == false) {
//block user for seconds
return false;
}
if($this->security->checkHash($credentials['password'],$user->password) && $user->status == 1) {
$this->_saveSuccessLogin($user);
$this->_setUserLoginSession($user);
return true;
} else {
return false;
}
}
public function isAuthorized() {
return $this->session->has('auth');
}
public function logout() {
$this->session->remove('auth');
return true;
}
public function user($key = null) {
if(!$this->isAuthorized()) {
return null;
}
if(is_null($key)) {
return $this->session->get('auth');
} else {
$user = $this->session->get('auth');
return array_key_exists($key, $user) ? $user[$key] : null;
}
}
private function _saveSuccessLogin(Users $user){
$userLogin = new UserLogins();
$userLogin->user_id = $user->id;
$userLogin->ip = $this->request->getClientAddress();
$userLogin->user_agent = $this->request->getUserAgent();
$userLogin->dns = gethostbyaddr($userLogin->ip);
if(!$userLogin->save()) {
return false;
}
return true;
}
private function _setUserLoginSession(Users $user) {
if(!$user) {
return false;
}
$this->session->set('auth',array(
'id' => $user->id,
'firstname' => $user->firstname,
'lastname' => $user->lastname,
'email' => $user->email,
'role_id' => $user->role_id
));
return true;
}
}
And in my services.php added into DI with this code :
$di->setShared('auth', function () {
return new Auth();
});
So when i want to get user info i use this :
$this->auth->user('email')
Also you can add more functionality to this component & modify it.
I hope that's useful for You.
You can use memcached and save it as key => value:
userId => serialized User model
I am new to prestashop. I wanted learn how the code will flow .
ex. how product are inserting in database ?
how product data is fetching and displaying in store page ?
please help me .
you should open PrestaShop Product class.
you can get all product data using this:
$product = new Product($id_product);
if add a new product:
$product = new Product();
write all parameters like:
$product->name = 'test';
$product->reference = '35GH';
$product->save();
If u print out product array you will see all parameters. GOod luck, have fun. And even lot of information in stackoverflow how to php add product and etc.
If you want to work on products like you want to add products,delete products,want some customization then first you have to create a new module. For that you have to create a new folder in that location with you module name
C:\wamp\www\prestashop\modules\your_module_name
Then after you have to create a file named your_module_name.php in that folder
C:\wamp\www\prestashop\modules\your_module_name\your_module_name.php
After then you have to code in that file like:
your_module_name.php
class your_module_name extends Module
{
public function __construct()
{
$this->name = 'your_module_name';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'abc';
$this->need_instance = 0;
//$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Your Module Name');
$this->description = $this->l('This is the module for facilitate user to purchase particular product.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
if (!Configuration::get('your_module_name')) {
$this->warning = $this->l('No name provided');
}
}
public function install()
{
if (Shop::isFeatureActive()) {
Shop::setContext(Shop::CONTEXT_ALL);
}
if (!parent::install())
{
return false;
}
$defaultsettings = $this->getDefaultSettings();
$defaultsettings = serialize($defaultsettings);
Configuration::updateValue('your_module_name', $defaultsettings);
return true;
}
public function uninstall()
{
if (!parent::uninstall()) {
return false;
}
return true;
}
public function getContent()
{
$output = null;
$product = new Product($id_product);
$product->name = 'test';
$product->reference = '35GH';
$product->save();
}
Now in that getContent method you can perform operations on products.I hope it would help you.
I am trying to add some functionality to my shop and have spent the past two days trying to come to grasp with how smarty actually works within prestashop or rather in general.
I have so far made a module that can install, on install it creates a tab on the left menu, I can click on the tab and it will load the controller but this is where i get stuck... I can't figure out how to display custom content within that state.
What i would like is very simple, just a paragraph of text and a button. When clicking the button i will do a few things and record a few things then show the results as a simple report.
So for starters... I'd like to create the page with the paragraph and button.
So i have created a folder in the module diretory called priceupdate
Inside of this there is:
/priceupdate.php
<?php
if (!defined('_PS_VERSION_'))
exit;
class PriceUpdate extends Module
{
public function __construct()
{
$this->name = 'priceupdate';
$this->tab = 'quick_bulk_update';
$this->version = '0.8';
$this->author = 'Me';
$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Pricing Update');
$this->description = $this->l('Adds functionality relating to maintaining product my prices.');
$this->confirmUninstall = $this->l('Are you sure you would like to uninstall?');
}
public function install()
{
if (!parent::install()
|| !$this->installModuleTab('AdminPricingUpdate', array(1=>'Pricing Update'), 0))
return false;
return true;
}
public function uninstall()
{
if (!parent::uninstall()
|| !$this->uninstallModuleTab('AdminPricingUpdate', array(1=>'Pricing Update'), 0))
return false;
return true;
}
private function installModuleTab($tabClass, $tabName, $idTabParent)
{
$tab = new Tab();
$tab->name = $tabName;
$tab->class_name = $tabClass;
$tab->module = $this->name;
$tab->id_parent = $idTabParent;
if(!$tab->save())
return false;
return true;
}
private function uninstallModuleTab($tabClass)
{
$idTab = Tab::getIdFromClassName($tabClass);
if($idTab != 0)
{
$tab = new Tab($idTab);
$tab->delete();
return true;
}
return false;
}
}
?>
And
/controllers/admin/AdminPricingUpdateController.php
<?php
class AdminPricingUpdateController extends AdminController
{
public function __construct()
{
$this->lang = (!isset($this->context->cookie) || !is_object($this->context->cookie)) ? intval(Configuration::get('PS_LANG_DEFAULT')) : intval($this->context->cookie->id_lang);
parent::__construct();
}
public function display(){
parent::display();
}
public function renderList() {
return $this->context->smarty->fetch(dirname(__FILE__).'/content.tpl');
}
}
?>
This works however where I am stuck relates to the content.tpl part. What goes inside of this the content.tpl file in order to get it to make a blank page of content within the content area of the admin section?
I've looked through the manual and spent countless hours on forums looking though questions, tried to figure it out by breaking down other modules but i've found it too complex to really understand what is what.
If anyone could help me to understand this or point me to a source of info on this specific subject then it would be greatly appreciated, thanks!
Check that answer
If you need "a blank page of content within the content area of the admin section" you need to make the content.tpl blank.
Note in my example that you do not have to set the name of the template if it's called "content.tpl".