How To Edit Register Page In Prestahop
In today's tutorial, nosotros will run across how to add new fields to the customer accost in Prestashop.
UPDATE! If yous prefer a simple solution, I created a module that automates the process and does much more, notice information technology here
Download Project Files
- Version used: Prestashop i.6 (compatible with Prestashop 1.5)
Plan of activity
In order to add a new field to the address registration form, nosotros will be adding a couple of overrides, too as creating a new database field and modifying the address template file. If y'all are not familiar with Prestashop overrides, check out my commodity on how to extend Prestashop objects (although we will have to use a slightly different technique).
The address class and database table
First things starting time, nosotros need something to play with. We desire the customer to exist able to fill in a field which doesn't currently exist, therefore let's login to the database, admission the ps_address table and create a new field: my_custom_field. I made it a 64 long VARCHAR field.
Next nosotros need to tell the address object (class) that it has a new field to bargain with. Create a new file inside override/classes/ and call it Address.php. Add the post-obit inside php tags:
class Address extends AddressCore { public $my_custom_field; public static $definition = array( 'table' => 'address', 'primary' => 'id_address', 'fields' => array( 'id_customer' => array('type' => cocky::TYPE_INT, 'validate' => 'isNullOrUnsignedId', 'copy_post' => false), 'id_manufacturer' => array('blazon' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId', 'copy_post' => faux), 'id_supplier' => array('type' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId', 'copy_post' => imitation), 'id_warehouse' => array('blazon' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId', 'copy_post' => false), 'id_country' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => truthful), 'id_state' => array('type' => self::TYPE_INT, 'validate' => 'isNullOrUnsignedId'), 'alias' => assortment('type' => cocky::TYPE_STRING, 'validate' => 'isGenericName', 'required' => truthful, 'size' => 32), 'company' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 64), 'lastname' => array('blazon' => self::TYPE_STRING, 'validate' => 'isName', 'required' => true, 'size' => 32), 'firstname' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => true, 'size' => 32), 'vat_number' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'), 'address1' => array('blazon' => self::TYPE_STRING, 'validate' => 'isAddress', 'required' => true, 'size' => 128), 'address2' => array('blazon' => self::TYPE_STRING, 'validate' => 'isAddress', 'size' => 128), 'postcode' => array('type' => self::TYPE_STRING, 'validate' => 'isPostCode', 'size' => 12), 'city' => array('blazon' => self::TYPE_STRING, 'validate' => 'isCityName', 'required' => true, 'size' => 64), 'other' => array('blazon' => self::TYPE_STRING, 'validate' => 'isMessage', 'size' => 300), 'phone' => assortment('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'size' => 32), 'phone_mobile' => array('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'size' => 32), 'dni' => array('type' => cocky::TYPE_STRING, 'validate' => 'isDniLite', 'size' => xvi), 'deleted' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'copy_post' => imitation), 'date_add' => assortment('type' => self::TYPE_DATE, 'validate' => 'isDateFormat', 'copy_post' => imitation), 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat', 'copy_post' => fake), 'my_custom_field' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 64), ), ); } Explanation: if you read my article on how to extend Prestashop Objects, you will discover I approached this override a little differently. I am not assigning the new field upon instance creation, but I am direct overriding its definition. The reason is simple: the Address definition is chosen statically when creating a new address in the front office, and if we added the new field in the construct method, we would have missed information technology from the list.
Delight notice that this definition comes from Prestashop one.six.0.5, and I therefore recommend to employ your own from the original Address class, in case you accept a different Prestashop version.
The back office Address Controller
Nosotros are one-half the manner through already, and at this point we need to override the dorsum office controller responsible for displaying the address modification form for each customer.
Create a new file named AdminAddressesController.php in override/controllers/admin/. We need to extend the renderForm() method; thus, head over the master controllers/admin folder, open up up the original AdminAddressesController.php, locate the renderForm() method and copy it. Then, add the following inside php tags in our new controller override:
Class AdminAddressesController extends AdminAddressesControllerCore { } And paste the renderForm() code inside the class. Here is how mine looks similar, taken from Prestashop 1.6.0.5:
Course AdminAddressesController extends AdminAddressesControllerCore { public part renderForm() { $this->fields_form = array( 'legend' => array( 'title' => $this->l('Addresses'), 'icon' => 'icon-envelope-alt' ), 'input' => array( array( 'type' => 'text_customer', 'label' => $this->l('Customer'), 'name' => 'id_customer', 'required' => false, ), array( 'type' => 'text', 'label' => $this->l('Identification Number'), 'name' => 'dni', 'required' => false, 'col' => 'iv', 'hint' => $this->l('DNI / NIF / NIE') ), assortment( 'blazon' => 'text', 'label' => $this->l('Address alias'), 'name' => 'alias', 'required' => true, 'col' => '4', 'hint' => $this->l('Invalid characters:').' <>;=#{}' ), array( 'blazon' => 'text', 'label' => $this->l('Domicile telephone'), 'proper noun' => 'telephone', 'required' => imitation, 'col' => 'four', 'hint' => Configuration::get('PS_ONE_PHONE_AT_LEAST') ? sprintf($this->l('You must annals at to the lowest degree ane phone number.')) : '' ), array( 'blazon' => 'text', 'characterization' => $this->50('Mobile phone'), 'name' => 'phone_mobile', 'required' => false, 'col' => '4', 'hint' => Configuration::get('PS_ONE_PHONE_AT_LEAST') ? sprintf($this->50('You lot must annals at least one phone number.')) : '' ), assortment( 'type' => 'textarea', 'label' => $this->l('Other'), 'name' => 'other', 'required' => false, 'cols' => 15, 'rows' => three, 'hint' => $this->l('Forbidden characters:').' <>;=#{}' ), ), 'submit' => array( 'title' => $this->fifty('Salve'), ) ); $id_customer = (int)Tools::getValue('id_customer'); if (!$id_customer && Validate::isLoadedObject($this->object)) $id_customer = $this->object->id_customer; if ($id_customer) { $client = new Customer((int)$id_customer); $token_customer = Tools::getAdminToken('AdminCustomers'.(int)(Tab::getIdFromClassName('AdminCustomers')).(int)$this->context->employee->id); } $this->tpl_form_vars = array( 'customer' => isset($customer) ? $client : zip, 'tokenCustomer' => isset ($token_customer) ? $token_customer : null ); // Order address fields depending on country format $addresses_fields = $this->processAddressFormat(); // we use delivery address $addresses_fields = $addresses_fields['dlv_all_fields']; $temp_fields = array(); foreach ($addresses_fields as $addr_field_item) { if ($addr_field_item == 'company') { $temp_fields[] = array( 'type' => 'text', 'label' => $this->l('Company'), 'name' => 'company', 'required' => false, 'col' => 'iv', 'hint' => $this->l('Invalid characters:').' <>;=#{}' ); $temp_fields[] = assortment( 'type' => 'text', 'label' => $this->50('VAT number'), 'col' => 'ii', 'proper noun' => 'vat_number' ); } else if ($addr_field_item == 'lastname') { if (isset($customer) && !Tools::isSubmit('submit'.strtoupper($this->table)) && Validate::isLoadedObject($customer) && !Validate::isLoadedObject($this->object)) $default_value = $customer->lastname; else $default_value = ''; $temp_fields[] = array( 'blazon' => 'text', 'label' => $this->l('Terminal Name'), 'proper name' => 'lastname', 'required' => truthful, 'col' => '4', 'hint' => $this->l('Invalid characters:').' 0-9!&lt;&gt;,;?=+()@#"�{}_$%:', 'default_value' => $default_value, ); } else if ($addr_field_item == 'firstname') { if (isset($customer) && !Tools::isSubmit('submit'.strtoupper($this->tabular array)) && Validate::isLoadedObject($customer) && !Validate::isLoadedObject($this->object)) $default_value = $customer->firstname; else $default_value = ''; $temp_fields[] = array( 'type' => 'text', 'label' => $this->fifty('First Name'), 'name' => 'firstname', 'required' => true, 'col' => 'iv', 'hint' => $this->50('Invalid characters:').' 0-9!&lt;&gt;,;?=+()@#"�{}_$%:', 'default_value' => $default_value, ); } else if ($addr_field_item == 'address1') { $temp_fields[] = array( 'type' => 'text', 'label' => $this->l('Address'), 'proper noun' => 'address1', 'col' => '6', 'required' => true, ); } else if ($addr_field_item == 'address2') { $temp_fields[] = array( 'type' => 'text', 'label' => $this->l('Address').' (2)', 'name' => 'address2', 'col' => '6', 'required' => false, ); } elseif ($addr_field_item == 'postcode') { $temp_fields[] = array( 'type' => 'text', 'label' => $this->l('Zip/Postal Code'), 'name' => 'postcode', 'col' => 'two', 'required' => true, ); } else if ($addr_field_item == 'urban center') { $temp_fields[] = array( 'type' => 'text', 'characterization' => $this->l('Urban center'), 'proper noun' => 'city', 'col' => '4', 'required' => true, ); } else if ($addr_field_item == 'state' || $addr_field_item == 'Land:name') { $temp_fields[] = array( 'type' => 'select', 'label' => $this->50('Country'), 'name' => 'id_country', 'required' => false, 'col' => '4', 'default_value' => (int)$this->context->country->id, 'options' => array( 'query' => Country::getCountries($this->context->linguistic communication->id), 'id' => 'id_country', 'name' => 'name' ) ); $temp_fields[] = assortment( 'type' => 'select', 'label' => $this->fifty('State'), 'proper name' => 'id_state', 'required' => simulated, 'col' => '4', 'options' => assortment( 'query' => array(), 'id' => 'id_state', 'name' => 'name' ) ); } } // merge accost format with the rest of the form array_splice($this->fields_form['input'], 3, 0, $temp_fields); return parent::renderForm(); } } Nosotros must edit the $this->fields_form variable to add a new input field; correct afterwards this:
array( 'type' => 'text', 'label' => $this->fifty('Identification Number'), 'proper noun' => 'dni', 'required' => simulated, 'col' => '4', 'hint' => $this->l('DNI / NIF / NIE') ), Add the following
array( 'type' => 'text', 'label' => $this->l('My custom field'), 'proper noun' => 'my_custom_field', 'required' => false, 'col' => '4', 'hint' => $this->fifty('Only a custom field!') ), Note: brand sure the "proper name" matches the one of the new attribute previously added to both the database and Address class object!
Lastly, at the cease of the method, change:
return parent::renderForm();
To
render AdminController::renderForm();
Then that the new fields list is non replaced by the original ane.
If the Address course or/and controller were not previously overridden, at this signal yous must reach the cache/ folder and erase class_index.php; equally always. Later doing it, overrides will take place.
The Front Function Address Template
As very last step, permit's now add together the custom field to the front function template, so it tin be filled in by clients when they register. Open up up address.tpl, located in the theme folder. I am using the default bootstrap template, so your file might look differently in case you have a custom ane! Locate:
{if $field_name eq 'vat_number'} <div id="vat_area"> <div id="vat_number"> <div class="course-group"> <label for="vat-number">{l s='VAT number'}</label> <input type="text" class="form-control validate" information-validate="{$address_validation.$field_name.validate}" id="vat-number" proper name="vat_number" value="{if isset($smarty.post.vat_number)}{$smarty.postal service.vat_number}{else}{if isset($address->vat_number)}{$address->vat_number|escape:'html':'UTF-viii'}{/if}{/if}" /> </div> </div> </div> {/if} And right later on information technology, add:
{if $field_name eq 'my_custom_field'} <div id="vat_area"> <div id="my_custom_field"> <div class="grade-grouping"> <label for="my-custom-field">{l due south='My Custom Field'}</characterization> <input blazon="text" class="form-control validate" data-validate="{$address_validation.$field_name.validate}" id="my-custom-field" name="my_custom_field" value="{if isset($smarty.post.my_custom_field)}{$smarty.post.my_custom_field}{else}{if isset($address->my_custom_field)}{$address->my_custom_field|escape:'html':'UTF-viii'}{/if}{/if}" /> </div> </div> </div> {/if} Save and refresh, we're done!
TIP: if you don't see whatever change in the front office, make sure you plough on recompilation from Advanced Parameters > Functioning, and clear Smarty cache besides
Optional: Making the new field mandatory
If yous really need your customers to input something in that new field, than another override is necessary. Create a new file inside override/controllers/front and call it AddressController.php. Paste the following inside php tags, advertising always:
Class AddressController extends AddressControllerCore { } We need to override the processSubmitAddress() method. Therefore, if your Prestashop version is not 1.6.0.5, go ahead and re-create your original ane within this new override; otherwise y'all can utilise the following:
protected function processSubmitAddress() { $address = new Address(); $this->errors = $accost->validateController(); $accost->id_customer = (int)$this->context->customer->id; // Check folio token if ($this->context->customer->isLogged() && !$this->isTokenValid()) $this->errors[] = Tools::displayError('Invalid token.'); // Cheque phone if (Configuration::get('PS_ONE_PHONE_AT_LEAST') && !Tools::getValue('phone') && !Tools::getValue('phone_mobile')) $this->errors[] = Tools::displayError('You must annals at least one phone number.'); if ($accost->id_country) { // Check country if (!($country = new Country($address->id_country)) || !Validate::isLoadedObject($country)) throw new PrestaShopException('Country cannot be loaded with address->id_country'); if ((int)$country->contains_states && !(int)$address->id_state) $this->errors[] = Tools::displayError('This country requires you to chose a Land.'); $postcode = Tools::getValue('postcode'); /* Bank check zip code format */ if ($country->zip_code_format && !$country->checkZipCode($postcode)) $this->errors[] = sprintf(Tools::displayError('The Nada/Postal code you\'ve entered is invalid. It must follow this format: %southward'), str_replace('C', $country->iso_code, str_replace('Northward', '0', str_replace('L', 'A', $country->zip_code_format)))); elseif(empty($postcode) && $country->need_zip_code) $this->errors[] = Tools::displayError('A Zip/Postal code is required.'); elseif ($postcode && !Validate::isPostCode($postcode)) $this->errors[] = Tools::displayError('The Zip/Postal code is invalid.'); // Cheque land DNI if ($country->isNeedDni() && (!Tools::getValue('dni') || !Validate::isDniLite(Tools::getValue('dni')))) $this->errors[] = Tools::displayError('The identification number is wrong or has already been used.'); else if (!$country->isNeedDni()) $address->dni = null; } // Check if the alias exists if (!$this->context->customer->is_guest && !empty($_POST['allonym']) && (int)$this->context->customer->id > 0) { $id_address = Tools::getValue('id_address'); if(Configuration::become('PS_ORDER_PROCESS_TYPE') && (int)Tools::getValue('opc_id_address_'.Tools::getValue('type')) > 0) $id_address = Tools::getValue('opc_id_address_'.Tools::getValue('type')); if (Db::getInstance()->getValue(' SELECT count(*) FROM '._DB_PREFIX_.'address WHERE `alias` = \''.pSql($_POST['alias']).'\' AND id_address != '.(int)$id_address.' AND id_customer = '.(int)$this->context->customer->id.' AND deleted = 0') > 0) $this->errors[] = sprintf(Tools::displayError('The allonym "%due south" has already been used. Please select another one.'), Tools::safeOutput($_POST['alias'])); } // Check the requires fields which are settings in the BO $this->errors = array_merge($this->errors, $address->validateFieldsRequiredDatabase()); // Don't proceed this procedure if nosotros have errors ! if ($this->errors && !$this->ajax) return; // If nosotros edit this address, delete erstwhile address and create a new i if (Validate::isLoadedObject($this->_address)) { if (Validate::isLoadedObject($country) && !$country->contains_states) $address->id_state = 0; $address_old = $this->_address; if (Customer::customerHasAddress($this->context->client->id, (int)$address_old->id)) { if ($address_old->isUsed()) $address_old->delete(); else { $address->id = (int)($address_old->id); $address->date_add = $address_old->date_add; } } } if ($this->ajax && Tools::getValue('type') == 'invoice' && Configuration::get('PS_ORDER_PROCESS_TYPE')) { $this->errors = array_unique(array_merge($this->errors, $address->validateController())); if (count($this->errors)) { $return = array( 'hasError' => (bool)$this->errors, 'errors' => $this->errors ); dice(Tools::jsonEncode($return)); } } // Save address if ($effect = $address->save()) { // Update id accost of the current cart if necessary if (isset($address_old) && $address_old->isUsed()) $this->context->cart->updateAddressId($address_old->id, $address->id); else // Update cart address $this->context->cart->autosetProductAddress(); if ((bool)(Tools::getValue('select_address', fake)) == truthful OR (Tools::getValue('blazon') == 'invoice' && Configuration::get('PS_ORDER_PROCESS_TYPE'))) $this->context->cart->id_address_invoice = (int)$accost->id; elseif (Configuration::become('PS_ORDER_PROCESS_TYPE')) $this->context->cart->id_address_invoice = (int)$this->context->cart->id_address_delivery; $this->context->cart->update(); if ($this->ajax) { $return = array( 'hasError' => (bool)$this->errors, 'errors' => $this->errors, 'id_address_delivery' => (int)$this->context->cart->id_address_delivery, 'id_address_invoice' => (int)$this->context->cart->id_address_invoice ); dice(Tools::jsonEncode($return)); } // Redirect to old folio or electric current page if ($back = Tools::getValue('back')) { if ($back == Tools::secureReferrer(Tools::getValue('back'))) Tools::redirect(html_entity_decode($back)); $mod = Tools::getValue('mod'); Tools::redirect('index.php?controller='.$dorsum.($modernistic ? '&back='.$mod : '')); } else Tools::redirect('index.php?controller=addresses'); } $this->errors[] = Tools::displayError('An error occurred while updating your address.'); } Right before the // CHeck Phone annotate, add:
if ( !Tools::getValue('my_custom_field')) $this->errors[] = Tools::displayError('The custom field is mandatory!'); So that an error volition exist thrown if your clients leave that field empty!
Call up to erase the class index file over again, of form.
Adding the new field to the address format in Prestashop
As a side note, be aware that in society to brandish the new field we added we need to change the address format for each country. I am not currently aware of a simple way to apply address changes to all countries at one time. Therefore, head over to Localization > Countries, click on a country proper name and add together the new field to the address box:
What for new Customer Fields?
Throughout this tutorial, nosotros added a new field to the Address object. However, it is also possible to create a new basic customer field, to sit along proper name, lastname and e-mail in the very basic registration (even without an address). To practise so, y'all can simply use the aforementioned process to the Customer grade, and relative controllers. Just be aware that you will need to edit a couple of different template files: identity.tpl and hallmark.tpl, equally well every bit order-opc-new-account.tpl if you use the one page checkout!
UPDATE! If you lot prefer a unproblematic solution, I created a module that automates the procedure and does much more, find it here
Additional Resources
- How to extend Prestashop objects
Source: http://nemops.com/new-customer-address-fields-prestashop/
Posted by: beringerwhely1977.blogspot.com

0 Response to "How To Edit Register Page In Prestahop"
Post a Comment