Post by marvmen21 » Mon Mar 07, 2011 4:54 am

Customising the registration form can be one of the more tedious modifications some of us have to do. This is because of the number of files you have to edit. This vqmod will allow you to do so without touching the core files (Thanks Qphoria). This will add the field to all registration pages (standard registration, check out registration, and affiliate registration) , customer edit, affiliate edit, and admin edit cust and affiliate.
Update December 6th , 2011
This will continue to be a free vqmod; However, if you need personalized support and want to contribute a little to opencart, please buy it here for just 10 bucks: http://www.opencart.com/index.php?route ... on_id=4186
The commercial version includes Free Installation and free small customizations like changing the name of the field, the position where it is added, making it required or not, and the type of field (Text field, text field with date picker, drop down select, radio select).
***=>Demo:(In this case, it's a birth date field with date picker added using this vqmod) http://devoc.technopolaris.com/index.ph ... t/register

**For other customizations, please be sure to contact me before purchasing. Email me to: dev at technopolaris dot com


Best Regards,
marvmen21


Thanks
Changelog...

EDIT (September 20th): VQMOD UPDATED TO WORK WITH 1.5.X. This version is working fine with no known errors yet. Please let me know if you do find something wrong, or anything that could be done to improve it. The name of the field I used is "cedu" so you need to change that to your new custom field's name (Be careful to respect capitalization), and well..obviously you also need to add that field to the cust table in your database.

File: New_Field_Registration_Form_1.0.2
What the vqmod does: Adds a new field ("cedu") to the registration form, cust edit, and customer form in the backend.

EDIT (October 3th): VQMOD UPDATED TO WORK WITH 1.5.1.3 Very small update since there were two small changes in two lines from the admin/controller file introduced in this release.
This New version now also adds the "new field" to the checkout/registration form which I had forgotten to include in the previous versions.
New_Field_Registration_Form_1.1.xml
EDIT (October 14th): Now adds the field to the affiliate section See post below,
http://forum.opencart.com/viewtopic.php ... 66#p205466

Or download here: http://forum.opencart.com/download/file.php?id=7502

PS. Thanks to ckonig for the help provided .
Marvin M.

Attachments

Updated to work with OC 1.5.1.3 and adds the field to the checkout/registration form, too

New version for OC 1.5.X

Last edited by marvmen21 on Wed Dec 07, 2011 9:07 pm, edited 11 times in total.

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by ckonig » Mon Mar 07, 2011 11:15 pm

It's always great to find out somebody already did the job you're doing. I've spend half the day to do the exact same thing. I will take a look at yours and mine and give you a feedback tomorrow.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by ckonig » Tue Mar 08, 2011 5:55 pm

Thank you!
I totally forgot to mod the system/library files to add a get Method, thats a nice one! As said, i did almost the same work before, and I merged your contribution with mine. This way, I also got rid of your problem concerning the empty field in the frontend.
But I have a question about your query manipulation. Wouldn't it be better to only add the field to the begin of the query, ignoring what comes after, so i can copy & paste the script as often as I want to?
For example with the UPDATE query:

Code: Select all

<operation>
		<search position="replace"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET firstname = '" . $this->db->escape($data['firstname']) . "',]]></search>
		<add trim="true"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET expert_id = '" . $this->db->escape($data['expert_id']) . "', firstname = '" . $this->db->escape($data['firstname']) . "',]]></add>
	</operation>
In my opinion this can only work one time, if I want to use two instances of this mod, I need to change it to:

Code: Select all

<operation>
		<search position="replace"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET ]]></search>
		<add trim="true"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET expert_id = '" . $this->db->escape($data['expert_id']) . "', ]]></add>
	</operation>
This way I can use this script more than one and I dont have to mind what other scripts are doing with the query.

I also added the extra field into the backend views (list and detail view). If you're interested, here's my version (actually my field is called "expert_id"). I hope this helps.
Last edited by ckonig on Thu Mar 10, 2011 9:26 pm, edited 1 time in total.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by marvmen21 » Thu Mar 10, 2011 9:22 pm

Yep! you're right about the query, better the way you did it! Great, thanks a lot.
If you're interested, here's my version
I don't see the attached file, I'd love to take a look at it so I can benefit from your modifications.

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by ckonig » Thu Mar 10, 2011 9:27 pm

I did not see it either ;) I guess I didn't upload it before. Now it's there, enjoy!

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by marvmen21 » Fri Mar 11, 2011 3:26 am

thanks a lot!

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by marvmen21 » Sat Mar 12, 2011 1:05 am

Wouldn't it be better to only add the field to the begin of the query, ignoring what comes after, so i can copy & paste the script as often as I want to?


I have a doubt about the way you did it, now that I checked your xml I remember why I didn't use

Code: Select all

<search position="replace"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET ]]></search>
in the search line as you did. The thing is that "update". DB_PREFIX."customer SET actually appears more than 5 times in the code; therefore, if you tell script to add your field after that line, the vqmod will add it several times in different parts of the code. Not sure if that could cause a problem.

I went to the vqcahe folder to see the changes being made by the xml and I could see our code in the <add trim="true"><![CDATA[our code ]]></add> was added in some parts it is not supposed to be. Take a look below.

vqcache_catalog_model_account_customer.php

Code: Select all

<?php
class ModelAccountCustomer extends Model {
	public function addCustomer($data) {
$data['cedu'] = ucwords(strtolower(trim($data['cedu'])));
      	
		$data['firstname'] = ucwords(strtolower(trim($data['firstname'])));
		$data['lastname'] = ucwords(strtolower(trim($data['lastname'])));
		$data['company'] = ucwords(strtolower(trim($data['company'])));
		$data['address_1'] = ucwords(strtolower(trim($data['address_1'])));
		$data['address_2'] = ucwords(strtolower(trim($data['address_2'])));
		$data['city'] = ucwords(strtolower(trim($data['city'])));
		$data['postcode'] = strtoupper(trim($data['postcode']));
	
		$this->db->query("INSERT INTO " . DB_PREFIX . "customer SET store_id = '" . (int)$this->config->get('config_store_id') . "', cedu = '" . $this->db->escape($data['cedu']) . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "', password = '" . $this->db->escape(md5($data['password'])) . "', newsletter = '" . (int)$data['newsletter'] . "', customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "', status = '1', date_added = NOW()");
      	
		$customer_id = $this->db->getLastId();
			
      	$this->db->query("INSERT INTO " . DB_PREFIX . "address SET customer_id = '" . (int)$customer_id . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', company = '" . $this->db->escape($data['company']) . "', address_1 = '" . $this->db->escape($data['address_1']) . "', address_2 = '" . $this->db->escape($data['address_2']) . "', city = '" . $this->db->escape($data['city']) . "', postcode = '" . $this->db->escape($data['postcode']) . "', country_id = '" . (int)$data['country_id'] . "', zone_id = '" . (int)$data['zone_id'] . "'");
		
		$address_id = $this->db->getLastId();

      	$this->db->query("UPDATE " . DB_PREFIX . "customer SET cedu = '" . $this->db->escape($data['cedu']) . "', address_id = '" . (int)$address_id . "' WHERE customer_id = '" . (int)$customer_id . "'");
		
		if (!$this->config->get('config_customer_approval')) {
			$this->db->query("UPDATE " . DB_PREFIX . "customer SET cedu = '" . $this->db->escape($data['cedu']) . "', approved = '1' WHERE customer_id = '" . (int)$customer_id . "'");
		}		
	}
	
	public function editCustomer($data) {
$data['cedu'] = ucwords(strtolower(trim($data['cedu'])));
		$data['firstname'] = ucwords(strtolower(trim($data['firstname'])));
		$data['lastname'] = ucwords(strtolower(trim($data['lastname'])));
		
		$this->db->query("UPDATE " . DB_PREFIX . "customer SET cedu = '" . $this->db->escape($data['cedu']) . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "' WHERE customer_id = '" . (int)$this->customer->getId() . "'");
	}

	public function editPassword($email, $password) {
      	$this->db->query("UPDATE " . DB_PREFIX . "customer SET cedu = '" . $this->db->escape($data['cedu']) . "', password = '" . $this->db->escape(md5($password)) . "' WHERE email = '" . $this->db->escape($email) . "'");
	}

	public function editNewsletter($newsletter) {
		$this->db->query("UPDATE " . DB_PREFIX . "customer SET cedu = '" . $this->db->escape($data['cedu']) . "', newsletter = '" . (int)$newsletter . "' WHERE customer_id = '" . (int)$this->customer->getId() . "'");
	}
			
	public function getCustomer($customer_id) {
		$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer WHERE customer_id = '" . (int)$customer_id . "'");
		
		return $query->row;
	}
	
	public function getTotalCustomersByEmail($email) {
		$query = $this->db->query("SELECT COUNT(*) AS total FROM " . DB_PREFIX . "customer WHERE email = '" . $this->db->escape($email) . "'");
		
		return $query->row['total'];
	}
you can see my field"cedu" after the following lines, and I think it's not suppose to be there.
$address_id = $this->db->getLastId();
if (!$this->config->get('config_customer_approval'))
public function editPassword($email, $password) {
public function editNewsletter($newsletter) {

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by ckonig » Mon Mar 14, 2011 4:46 pm

Thanks a lot! I wasn't aware of this, until now I only tested on the Backend :(
But yeah, if I try to change my password or to subscribe to the newsletter via the frontend, I get bad errors...

change the password

Code: Select all

Notice: Undefined variable: data in .../vqmod/vqcache/vqcache_catalog_model_account_customer.php on line 40
Notice: Undefined variable: data in .../vqmod/vqcache/vqcache_catalog_model_account_customer.php on line
change newsletter settings

Code: Select all

Notice: Undefined variable: data in .../vqmod/vqcache/vqcache_catalog_model_account_customer.php on line 44Notice: Undefined variable: data in .../vqmod/vqcache/vqcache_catalog_model_account_customer.php on line 44
Did you figure out more points of failure?

But well, I still want to have this script to be repeatable, because I need more than one field to be added to the customer.

I took a closer look and found, that I dont have to add the fields at the beginning of the query, they can also be placed in the middle, as long as you don't refer to the fields after it. So I changed the affected code to

Code: Select all

<operation>
		<search position="replace"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "',]]></search>
		<add trim="true"><![CDATA[$this->db->query("UPDATE " . DB_PREFIX . "customer SET firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', expert_id = '" . $this->db->escape($data['expert_id']) . "', ]]></add>
	</operation>
and now the editPassword and editNewsletter functions are not changed anymore.

Again, thanks a lot!!! I would not have found this on my own...

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by ckonig » Fri Mar 18, 2011 11:03 pm

I found a new mistake in the create account form.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by ckonig » Tue Mar 22, 2011 10:15 pm

Hey marvmen!
I found a problem that is caused by the usage of the offset attribute.
Actually, this seems to be problematic when another vqmod tries to hook on the same code, I'd rather hook directly before or after the line instead of using the offset. I ran into bad problems with it! So I changed it again, there are still some offsets left, but right now they make no problems in my project.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by marvmen21 » Mon Mar 28, 2011 7:47 am

Hi, where are you seeing errors? it's cuz mine is working fine and I think that the offset attribute shouldn't cause any issue unless another vqmod is modifying exactly the same line, but again...if that is the case, it's not because of the offset attribute.

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by ckonig » Fri Apr 01, 2011 10:05 pm

I was really thinking a long time about this problem.
Then I made two xml files to see what really happens
They both want to insert code at almost the same spot.
a.xml is using the offset attribute
b.xml hooks directly after the line

If you let only b.xml run you get

Code: Select all

public function index() {
		if (!$this->customer->isLogged()) {
			$this->session->data['redirect'] = HTTPS_SERVER . 'index.php?route=account/edit';

				
				//inserted by b
if you let only a.xml run you get

Code: Select all

public function index() {

				
				//1
				//2
				//3
				//4
				//5
so far so good

if we let a and b run together we WANT TO see

Code: Select all

public function index() {

				
				//1
				//2
				//3
				//4
				//5
				
			
		if (!$this->customer->isLogged()) {
			$this->session->data['redirect'] = HTTPS_SERVER . 'index.php?route=account/edit';

				
				//inserted by b
but what we REALLY get is

Code: Select all

public function index() {

				

				
				//inserted by b
				
			
				//1
				//2
				//3
				//4
				//5
				
			
		if (!$this->customer->isLogged()) {
			$this->session->data['redirect'] = HTTPS_SERVER . 'index.php?route=account/edit';
Conclusion:
The insertion of b.xml, which actuall has to take part inside of the IF block, is not anymore at the place where it should be.

From my point of view this is the prove that using the offset is rather a problem than a solution.

Of course you can rename a.xml to x.xml, then the result is more what you wanted, but I think we should design our vqmods to be independent from each other.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by Qphoria » Fri Apr 01, 2011 10:23 pm

Yes it is true... the use of offset is more of a workaround than a solution. If possible you should always try to find a better way. There really is no good way to improve offset to do what you are after. I can warn people against using offset except in extreme situations.

for b.xml it would be safer to use:

Code: Select all

<search position="after">$this->session->data['redirect'] = HTTPS_SERVER . 'index.php?route=account/edit';</search>
Or if you are basing it on the alphabetical order a.xml, then b.xml.. then you can make b search for "/5" and go after that.

Not really anything I can do about it.. just when you give people matches and gasoline..they need to exercise control.
"With Great vQmod comes Great Responsibility" ;)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by ckonig » Fri Apr 01, 2011 10:33 pm

Well my question would be, why would anyone need to use the offset at all?
To hook directly after / before a line that appears more than one time?

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by marvmen21 » Sun Apr 03, 2011 3:55 am

Umm, now I see your point, but what can we do when the line we are searching for is repeated several times in the code? Actually, this the reason why I used the offset attribute. The thing is that if the line in the search tag is repeated three times, for example, in the code, the vqmod will insert your <add>code </add> after those lines, and you will end up with lot's of errors due to double code placed where it shouldn't be. :-\

You want to thank me for my time! :) Click here to donate


Active Member

Posts

Joined
Tue Nov 09, 2010 4:54 am

Post by ckonig » Thu Apr 07, 2011 3:51 am

I think I may have found an answer to that question. I did not even know about it (or at least I thought it´s not implemented yet), but you can use the index attribute for it.
- Optional attribute "index" for specifying which instances of a search tag should be acted on
- If the search string is "echo" and there are 5 echos in the file, but only want to replace the 1st and 3rd, use index="1,3"
Sometimes I have to remind myself... RTFM

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by ckonig » Tue May 10, 2011 8:12 pm

found and fixed another error...
The pagination was not set correctly because the filtering inside of the model took only place at the getCustomers function. Now the getTotalCustomers function is also included, so the pagination is displayed correctly.
Also the sort is now working correctly.

User avatar
Active Member

Posts

Joined
Wed Feb 16, 2011 4:26 pm
Location - Netherlands

Post by WebDev22 » Wed May 18, 2011 1:28 am

Thanks for all the hard work. Is that very last file that was uploaded (customer_expert_id.xml), the only file needed to set this up?

Active Member

Posts

Joined
Tue Apr 05, 2011 8:35 pm

Post by WebDev22 » Wed May 18, 2011 2:41 am

Where can I find instructions on how to implement this? Is the only file needed the one called customer_expert_id_1.xml? If so, where does it need to be uploaded? Thanks for the help.

Active Member

Posts

Joined
Tue Apr 05, 2011 8:35 pm

Post by WebDev22 » Wed May 18, 2011 2:55 am

Okay. Some things are beginning to make sense, but I'm still a ways off from getting this right. It looks like the file goes into the XML folder under vqmod. I put ckonig's file there and see where "Expert ID" was added to my form.

I'd like to be able to create a new section, with four new fields, two of them required. So you would have the following:

Your Personal Details
Your Address
Your Market Info (New section)
Your Password
Newsletter

Is this possible?

Active Member

Posts

Joined
Tue Apr 05, 2011 8:35 pm
Who is online

Users browsing this forum: No registered users and 12 guests