Add Google Recaptcha on a SilverStripe form - captcha

I am trying to add Google Recaptcha to my custom SilverStripe form.
I have generated Google public and private keys but I do not know where to put them to show a captcha on my website.
Here is my current code:
ContactPage
class ContactPage extends Page
{
private static $db = array(
'TelCustomerSupport' => 'Varchar',
'TelProjectSupport' => 'Varchar',
'OfficeName' => 'Text',
'OfficeStreetAddress' => 'Text',
'OfficeAddressLocality' => 'Text',
'OfficePostalCode' => 'Varchar',
'OfficeMapLink' => 'Text',
'OfficeLatitude' => 'Text',
'OfficeLongitude' => 'Text',
);
public function getCMSFields()
{
$fields = parent::getCMSFields();
// Add extra fields
$fields->addFieldToTab("Root.Main", new TextField('TelCustomerSupport', 'Phone - Customer, Trade & Retail Support'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('TelProjectSupport', 'Phone - Project Support'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeName'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeStreetAddress'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeAddressLocality'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficePostalCode'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeMapLink'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeLatitude'), "Content");
$fields->addFieldToTab("Root.Main", new TextField('OfficeLongitude'), "Content");
return $fields;
}
}
class ContactPage_Controller extends NetSuitePage_Controller
{
private static $allowed_actions = array('ContactForm');
// Generate the form
public function ContactForm()
{
// Create fields
$fields = new FieldList(
TextField::create("FirstName")->setTitle(_t('Contact.FIRSTNAME')),
TextField::create("LastName")->setTitle(_t('Contact.LASTNAME')),
EmailField::create("Email")->setTitle(_t('Contact.EMAILADDRESS')),
TextField::create("Phone")->setTitle(_t('Contact.PHONENUMBER')),
DropdownField::create('Iam', _t('Contact.IAMA'), $this->translateNetsuiteConfigArray('Contact', 'Iam')),
TextField::create("SendSubject")->setTitle(_t('Contact.SUBJECT')),
HoneyPotField::create("Subject2")->setTitle('Subject2'),
TextareaField::create("Message")->setTitle(_t('Contact.MESSAGE'))->setColumns(30)->setRows(10)
new RecaptchaField('MyCaptcha')
);
// Create actions
$submitbutton = new FormAction('doContactForm', _t('Contact.SEND'));
$submitbutton->addExtraClass('btn btn-black');
$actions = new FieldList(
$submitbutton
);
$validator = ZenValidator::create();
$validator->addRequiredFields(array('FirstName', 'LastName', 'Email', 'Phone', 'Iam', 'SendSubject', 'Message'));
$validator->setConstraint('FirstName', Constraint_length::create('max', 32));
$validator->setConstraint('LastName', Constraint_length::create('max', 32));
$validator->setConstraint('Phone', Constraint_length::create('min', 7));
$validator->setConstraint('Email', Constraint_type::create('email'));
$validator->setConstraint('Phone', Constraint_type::create('digits'));
$form = new Form($this, 'ContactForm', $fields, $actions, $validator);
$form->addExtraClass('contact-form');
$form->setFormMethod('POST', true);
return $form;
}
// Deal with form submission
public function doContactForm($data, $form)
{
$submission = new ContactFormSubmission();
$form->saveInto($submission);
$submission->write();
$data['path'] = print_r($this->refererTracker->retrieveAll(), true);
$email = new Email();
$email->setTemplate('ContactFormEmail');
$email->populateTemplate($data);
$email->setTo($this->getNetsuiteConfig('Contact', 'Emails'));
$email->setFrom("no-reply#warmup.co.uk");
$email->setSubject('[warmup.co.uk] New contact from the website');
$email->populateTemplate($data);
$email->send();
$post = $this->getNetsuiteConfig('Contact');
$post->firstname = $data['FirstName'];
$post->lastname = $data['LastName'];
$post->email = $data['Email'];
$post->phone = $data['Phone'];
$post->custentity116 = $data['Iam'];
$post->custentitysubject_contact_us = $data['SendSubject'];
$post->custentitymessage_contact_us = $data['Message'];
// Check for success
if ($this->queueNetSuitePost($post)) {
return $this->redirect(Director::get_current_page()->Link()."?success=1");
}
// Redirect back with form data and error message
Session::set('FormInfo.' . $form->FormName() . '.data', $data);
Session::set('FormInfo.'.$form->FormName().'.errors', array());
$form->sessionMessage("Netsuite error", 'bad');
return $this->redirectBack();
}
// Returns true if form submitted successfully
public function Success()
{
return isset($_REQUEST['success']) && $_REQUEST['success'] == "1";
}
public function getCurrentSubsite()
{
$subsite = Subsite::currentSubsite();
if($subsite) {
return $subsite->Title;
}
return $subsite;
}
}
ContactFormSubmission
class ContactFormSubmission extends DataObject {
private static $db = array(
'FirstName' => 'Text',
'LastName' => 'Text',
'Email' => 'Text',
'Phone' => 'Text',
'Iam' => 'Text',
'Subject' => 'Text',
'Message' => 'Text'
);
}
How do I correctly add Google Recaptcha to my form?

We can add Google Nocaptcha to our form using the SilverStripe Nocaptcha module.
The easiest way to install this module is through composer with the following command:
composer require undefinedoffset/silverstripe-nocaptcha
After installing the module be sure to call dev/build?flush=all.
Next we must set the spam protector to NocaptchaProtector through our site config.yml file, as well as set the Nocaptcha keys.
mysite/_config/config.yml
# ...
FormSpamProtectionExtension:
default_spam_protector: NocaptchaProtector
NocaptchaField:
site_key: "YOUR_SITE_KEY"
secret_key: "YOUR_SECRET_KEY"
The keys are retrieved through Google when setting up a new Nocaptcha account.
Make sure to call ?flush=all after adding these settings.
We are now ready to enable spam protection on our form. To do this we simply call $form->enableSpamProtection() in our form function:
public function ContactForm()
{
// Create fields
$fields = FieldList::create(
// ...
);
// Create actions
$actions = FieldList::create(
// ...
);
$validator = ZenValidator::create();
$form = Form::create($this, 'ContactForm', $fields, $actions, $validator);
$form->enableSpamProtection();
return $form;
}
Google Nocaptcha should now be enabled on our form.

Add
new LiteralField('recaptcha_bubble', '<div id="recaptcha_bubble" class="field"></div>')
in your forms field list
Then add the google javascript with
Requirements::javascript("https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=en-GB");
After that add the function to your javascript
var recaptchaCallback = function () {
var elementExists = document.getElementById('recaptcha_bubble');
if (null != elementExists) {
grecaptcha.render('recaptcha_bubble', {
'sitekey' : 'the site key here'
});
}};
When the form will be submitted with the variable 'g-recaptcha-response'
function getPostUrlContents($url, $fields){
$result = null;
$ch = curl_init();
$timeout = 30;
$fields_string = '';
foreach($fields as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim($fields_string, '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public function checkGoogle_recaptcha_Response($code) {
$result = $this->getPostUrlContents(
'https://www.google.com/recaptcha/api/siteverify',
array(
'secret' => urlencode('secret key here'),
'response' => urlencode($code)
)
);
if (!$result) return false;
$gResult = json_decode($result, true);
if ($gResult['success']) {
return true;
}
return false;
}
public function yourForm(SS_HTTPRequest $request) {
$vars = $request->postVars();
if (!$this->checkGoogle_recaptcha_Response($vars['g-recaptcha-response'])) {
// throw error
} else {
//not a robot, do something with request
}
}

Related

What is the good approach via api to download file

Do you know how via a web page usind the IPB APi allowinfg to doynload a file. Until now I can the see the files but it's not possible to download it. My result myfile:zip.3313213213
Thank you
Below my approach :
public function getFilesInformations(int $id)
{
$curl = curl_init( $this->communityUrl . 'api/downloads/files?id=' . $id . '&download&perPage=300');
$array = [
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_USERPWD => "{$this->apiKey}:",
CURLOPT_USERAGENT => "MyUserAgent/1.0"
];
curl_setopt_array( $curl, $array);
$response = curl_exec( $curl );
return $response;
}
My other function to get the file info
public function insertFilesInformations(int $id): bool
{
$json_result = $this->getFilesInformations($id);
$result = json_decode($json_result, true);
$i = 1;
if (is_array($result)) {
foreach ($result as $value) {
if (is_array($value)) {
foreach ($value as $file) {
$download = $file['files'][0]['url'];
var_dum($download);
}
}
}
}
return $download
}
the result is something like that : https://localhost/forum/uploads/monthly_2019_12/myfile_zip.a1fb44a2cb001aa6f3596ec4c6dfba16

Override AdminProductsController

I have problem with my custom presta shop module. My module adds new field to product, field name is promotion, is a string. If i add a new product or edit existing i have no problem, i see my new field. But when i have add this field to products list then i don't see this him.
My module:
<?php
if (!defined('_PS_VERSION_'))
exit;
class OverrideTraining extends Module
{
private $_html = '';
public function __construct()
{
$this->name = 'overridetraining';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Pawel Cyrklaf';
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => '1.7.9.9');
$this->need_instance = 0;
$this->bootstrap = true;
$this->displayName = $this->l('Override Training');
$this->description = $this->l('Task to learn override');
parent::__construct();
}
public function install()
{
if (!parent::install() OR
!$this->alterProductTable() OR
!$this->registerHook('displayAdminProductsExtra'))
return false;
return true;
}
public function uninstall()
{
if (!parent::uninstall() OR
!$this->alterProductTable('remove'))
return false;
return true;
}
/**
* #param string $method
* #return bool
*/
public function alterProductTable($method = 'add')
{
if ($method == 'add')
$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'product ADD `promotion` VARCHAR (255) NOT NULL';
else
$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'product DROP COLUMN `promotion`';
if (!Db::getInstance()->Execute($sql))
return false;
return true;
}
public function hookDisplayAdminProductsExtra($params)
{
$promotion = Db::getInstance()->getValue('SELECT promotion FROM ' . _DB_PREFIX_ . 'product WHERE id_product = ' . (int)Tools::getValue('id_product'));
$this->context->smarty->assign('promotion', $promotion);
return $this->display(__FILE__, 'adminProductsExtra.tpl');
}
}
and AdminProductsController which i override
<?php
class AdminProductsController extends AdminProductsControllerCore
{
public function __construct()
{
parent::__construct();
$this->fields_list['promotion'] = array(
'title' => $this->l('Promotion'),
'align' => 'text-center',
'class' => 'fixed-width-sm',
'orderby' => false
);
}
}
What i do wrong? I have a nemo's course, on his video all works fine, but at me not working this same code.
I had the same issue on adminOrdersController, an i solved by passing a calback for the value to print try to edit your override by adding 'filter_key' and a 'calback'
public function __construct()
{
parent::__construct();
$this->fields_list['promotion'] = array(
'title' => $this->l('Promotion'),
'align' => 'text-center',
'class' => 'fixed-width-sm',
'filter_key' => 'a!promotion', // syntax: table_alias!field_name
'callback' => 'displayPromotion'
);
}
public function displayPromotion($value) {
return $value ;
}
filter key must be popolated by the alias of the table and with the name of the field that you want to show.
To know what you have to pass as string in filter_key you should check the executed query that show the products in backoffice.
into callback function you can manage or do everything you want with the value before it'll be printed.
To make Prestashop know that there ia a new fields into product table, you have also to override the Product Core class in /classes/product.php
in this file you have to add this public $promotion; just below row 293
then you have to edit the public static $definition = array() of the product table introducing the definition of your new field, so you have to put into definition array this
'promotion' => array(
'type' => self::TYPE_STRING,
'lang' => true, // or false if don't need to translate this field
'validate' => 'isCleanHtml',
'size' => 255
),
now your field should be visible in backoffice product list

Fatal error occuring when created a module in presatshop

I am creating a back office(bo) module to view the dormant users in bo,
I created module and module is installing correctly and menu is been created and I am able to uninstall it properly , but when i click the menu 'Dormant users' I am getting error in functions.php, i haven't touched this page .
Fatal error: Call to undefined method DormantUsers::viewAccess() in D:\xampp\htdocs\raffleV1.1\oknr9hexztcseff5\functions.php on line 279
Here is the link to my module
https://www.dropbox.com/s/xlg6623jwyx4nnp/dormantusers.zip?dl=0
extract and try and please check why this eror occurs. I am trying to solve this for more than 3 hours now , could not find any hint ,
What i did is the following
I created dormantusers folder in modules folder and created dormantusers.php and below is the code in that page .
<?php
if (!defined('_PS_VERSION_')) exit;
class DormantUsers extends Module
{
public function __construct()
{
$this->name = 'dormantusers';
$this->tab = 'others';
$this->version = '1.0.0';
$this->author = 'KITS';
$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('DormantUsers');
$this->description = $this->l('Allow your Back Office to View Dormant Users ');
$this->confirmUninstall = $this->l('You want to Uninstall DormantUsers ?.');
$this->_tabsArray = array(
'DormantUsers' => 'Dormant Users',
);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install()
{
return parent::install() && $this->_installTabs();
}
private function _installTabs()
{
$parentTab = new Tab();
foreach (Language::getLanguages() as $language) $parentTab->name[$language['id_lang']] = 'Dormant Users';
$parentTab->class_name = 'DormantUsers';
$parentTab->module = $this->name;
$parentTab->id_parent = 0;
if (!$parentTab->save()) return false;
else {
$idTab = $parentTab->id;
//$idEn = Language::getIdByIso('en');
foreach ($this->_tabsArray as $tabKey => $name) {
$childTab = new Tab();
foreach (Language::getLanguages() as $language) $childTab->name[$language['id_lang']] = $name;
$childTab->class_name = $tabKey;
$childTab->module = $this->name;
$childTab->id_parent = $idTab;
if (!$childTab->save()) return false;
}
}
return true;
}
public function uninstall()
{
$this->_uninstallTabs();
return parent::uninstall();
}
private function _uninstallTabs()
{
foreach ($this->_tabsArray as $tabKey => $name) {
$idTab = Tab::getIdFromClassName($tabKey);
if ($idTab != 0) {
$tab = new Tab($idTab);
$tab->delete();
}
}
$idTab = Tab::getIdFromClassName('DormantUsers');
if ($idTab != 0) {
$tab = new Tab($idTab);
$tab->delete();
}
return true;
}
/**
* Add the CSS & JavaScript files you want to be loaded in the BO.
*/
public function hookBackOfficeHeader()
{
if (Tools::getValue('module_name') == $this->name) {
}
}
}
In the controllers folder controllers/admin/DormantUsersController.php have the following code .
<?php
require_once(_PS_MODULE_DIR_.'dormantusers/dormantusers.php');
require_once(_PS_MODULE_DIR_.'dormantusers/classes/DormantUsers.php');
class DormantUsersController extends ModuleAdminController
{
public $module;
public $html;
public $tabName = 'renderForm';
public function __construct()
{
$this->tab = 'dormantusers';
$this->module = new dormantusers();
$this->addRowAction('view');
$this->explicitSelect = false;
$this->context = Context::getContext();
$this->id_lang = $this->context->language->id;
$this->lang = false;
$this->ajax = 1;
$this->path = _MODULE_DIR_.'dormantusers';
$this->default_form_language = $this->context->language->id;
$this->table = 'customers';
$this->className = 'DormantUsers';
$this->identifier = 'id_customer';
$this->allow_export = true;
$this->_select = '
firstname,
lastname,
email,
nationality,
passport_no,
date_add
';
$this->name = 'DormantUsers';
$this->bootstrap = true;
$this->initList();
parent::__construct();
}
private function initList()
{
$this->fields_list = array(
'firstname' => array(
'title' => $this->l('First Name'),
'width' => 140,
'type' => 'text',
),
'lastname' => array(
'title' => $this->l('Last Name'),
'width' => 140,
'type' => 'text',
),
'email' => array(
'title' => $this->l('Email'),
'width' => 140,
'type' => 'text',
),
'nationality' => array(
'title' => $this->l('Nationality'),
'width' => 140,
'type' => 'text',
),
'date_add' => array(
'title' => $this->l('date add'),
'width' => 140,
'type' => 'text',
),
'passport_no' => array(
'title' => $this->l('passport_no'),
'width' => 140,
'type' => 'text',
),
);
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
// Actions to be displayed in the "Actions" column
$helper->actions = array('view');
$helper->identifier = 'id_customer';
$helper->show_toolbar = true;
$helper->title = 'HelperList';
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
return $helper;
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_title = $this->l('Dormant Users List ');
parent::initPageHeaderToolbar();
}
public function initToolbar()
{
parent::initToolbar();
$this->context->smarty->assign('toolbar_scroll', 1);
$this->context->smarty->assign('show_toolbar', 1);
$this->context->smarty->assign('toolbar_btn', $this->toolbar_btn);
}
public function postProcess()
{
parent::postProcess();
}
}
You have to define function viewAccess in DormantUsersController class. Try this code
public function viewAccess($disable = false)
{
if (version_compare(_PS_VERSION_, '1.5.1.0', '<='))
return true;
return parent::viewAccess($disable);
}

Back-office tab and helper form?

Following this prestashop instruction on how to make a tab in a back-office I did a class and controller like it's need. But what if I want to use a helper form for form creation in the AdminTest controller?
class AdminTest extends AdminTab
{
public function __construct()
{
$this->table = 'test';
$this->className = 'Test';
$this->lang = false;
$this->edit = true;
$this->delete = true;
$this->fieldsDisplay = array(
'id_test' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 25),
'test' => array(
'title' => $this->l('Name'),
'width' => 200)
);
$this->identifier = 'id_test';
parent::__construct();
}
public function displayForm()
{
global $currentIndex;
$defaultLanguage = intval(Configuration::get('PS_LANG_DEFAULT'));
$languages = Language::getLanguages();
$obj = $this->loadObject(true);
$fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->l('Edit carrier'),
'image' => '../img/admin/icon_to_display.gif'
),
'input' => array(
array(
'type' => 'text',
'name' => 'shipping_method',
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'button'
)
);
$helper = new HelperForm();
// Module, token and currentIndex
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
// Language
$helper->default_form_language = $default_lang;
$helper->allow_employee_form_lang = $default_lang;
// Title and toolbar
$helper->title = $this->displayName;
$helper->show_toolbar = true; // false -> remove toolbar
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
$helper->submit_action = 'submit'.$this->name;
$helper->toolbar_btn = array(
'save' =>
array(
'desc' => $this->l('Save'),
'href' => AdminController::$currentIndex.'&configure='.$this->name.'&save'.$this->name.
'&token='.Tools::getAdminTokenLite('AdminModules'),
),
'back' => array(
'href' => AdminController::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModules'),
'desc' => $this->l('Back to list')
)
);
return $helper->generateForm($fields_form);
}
}
But it wont work. Why the helper form isn't working?
p.s. btw, also I would like to use a $this->setTemplate('mytemplate.tpl') method but it's not possible aswell.
To create a new Admin tab, I prefer to use a module in which just install a tab on Module installation.
I think it's prettier, and more easily exportable to other website.
We can use this way : Templates, Helpers ...
For exemple :
Create in your module this dir : controllers/admin
Create a new class in previous created dir adminTest.php :
class AdminTestController extends ModuleAdminController {
}
In this class, you can override all ModuleAdminController functions and use templates, helpers (look in the class AdminController)
Now in your Module :
class testModule extends Module {
public function __construct() {
$this->name = 'testmodule';
$this->tab = 'administration';
$this->version = '1.0';
$this->author = 'You';
$this->need_instance = 1;
$this->secure_key = Tools::encrypt($this->name);
parent::__construct();
$this->displayName = $this->l('Admin Test Tab Module');
$this->description = $this->l('Add a new Admin Tab in BO');
}
public function install() {
return parent::install() &&
$this->_installTab();
}
public function uninstall() {
return $this->_unInstallTabs() &&
parent::uninstall();
}
private function _installTabs() {
if (!$AdminTestId = Tab::getIdFromClassName('AdminTest')):
$tab = new Tab();
$tab->class_name = 'AdminTest';
$tab->module = $this->name;
$tab->id_parent = Tab::getIdFromClassName('AdminParentOrders'); // Under Orders Tab, To add a new Tab on First level like Orders/Customers... put 0
$tab->active = 1;
foreach (Language::getLanguages(false) as $lang):
$tab->name[(int) $lang['id_lang']] = 'Admin Test';
endforeach;
if (!$tab->save()):
return $this->_abortInstall($this->l('Unable to create the "Admin Test" tab'));
endif;
else:
$AdminTest = new Tab((int) $AdminTestId);
endif;
}
// Uninstall Tabs on Module uninstall
private function _unInstallTabs() {
// Delete the Module Back-office tab
if ($id_tab = Tab::getIdFromClassName('AdminTest')) {
$tab = new Tab((int) $id_tab);
$tab->delete();
return true;
}
}
So, when you Install your Module, a new tab is available, and you can do what you want in your AdminTestController like a real Admin Controller

call model in zend form using dependencies + zend framework 2

I am trying to fetch my category model in zend form for working out with select element with zend framework 2.
after lot of code searching I found I can either inject or pull dependencies.
Following code I did in my module.php
I want categoryTable.php(model) file in my CategoryForm.php
public function getServiceConfig()
{
return array(
'factories' => array(
'Category\Model\CategoryTable' => function($sm) {
$tableGateway = $sm->get('CategoryTableGateway');
$table = new CategoryTable($tableGateway);
//echo "<pre>";print_r($table);echo "</pre>";
return $table;
},
'CategoryTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Category());
return new TableGateway('Of_Restaurants_Category', $dbAdapter, null, $resultSetPrototype);
},
'Category\Form\CategoryForm' => function ($sm) {
$service = $sm->get('Category\Model\CategoryTable');
$form = new Form;
$form->setService($service);
return $form;
}
),
);
}
then I put following code in my controller.
$form = $this->getServiceLocator()->get("Category\Form\CategoryForm");
Then I Put following code in my CategoryForm.php
public function getCategoryTable()
{
if (!$this->categoryTable) {
$sm = $this->getServiceLocator();
$this->categoryTable = $sm->get('Category\Model\CategoryTable');
}
return $this->categoryTable;
}
And then I call it in same file like this way
public function __construct($name = null)
{
parent::__construct('category');
echo "<pre>";print_r($this->getCategoryTable());die;
.... other code
I found this error
Fatal error: Call to undefined method Category\Form\CategoryForm::getServiceLocator() in D:\wamp\www\zendapp\module\Category\src\Category\Form\CategoryForm.php on line 120
please help. and am I missing something?
I found the solution
Step :1
Here is my module.php code
public function getServiceConfig()
{
return array(
'invokables' => array(
'Category\Form\CategoryForm' => 'Category\Form\CategoryForm',
),
'factories' => array(
'Category\Model\CategoryTable' => function($sm) {
$tableGateway = $sm->get('CategoryTableGateway');
$table = new CategoryTable($tableGateway);
//echo "<pre>";print_r($table);echo "</pre>";
return $table;
},
'CategoryTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Category());
return new TableGateway('Of_Restaurants_Category', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
Step :2
Then in controller I made this change
// $form = new CategoryForm();
// Service locator now injected
$form = $this->getServiceLocator()->get('Category\Form\CategoryForm');
Step :3
Then In my categoryForm.php I made below changes
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
protected $serviceManager;
public function getCategoryTable()
{
if (!$this->categoryTable) {
$sm = $this->getServiceManager();
$this->categoryTable = $sm->get('Category\Model\CategoryTable');
}
return $this->categoryTable;
}
protected function getCatList()
{
$groups = $this->getCategoryTable()->fetchAll();
return $groups;
}
public function getServiceManager()
{
if ( is_null($this->serviceManager) ) {
throw new Exception('The ServiceManager has not been set.');
}
return $this->serviceManager;
}
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
// Call the init function of the form once the service manager is set
$this->init();
return $this;
}
public function __construct($name = null) // constructor I finished immediately
{
parent::__construct('category');
}
I add INIT() function to fetch servicemanager
public function init()
{
$this->setAttribute('method', 'post');
$options = array();
foreach ($this->getCatList() as $cat) {
$options[$cat->id] = $cat->title;
}
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'parent_id',
'options' => array(
'label' => 'Parent Category',
'empty_option' => 'Please choose Parent Category',
'value_options' => $options,
),
));
}
Hope this will help who are new ZF2.