0

Hi,

would it be difficult to let's say add a record to another table on user registration? Lets say I want to add a records how many credits the user has in jos_credits table when user registers, in other words - add record with that user id and set credits to 0 initially. When they add money to a website, they will get credits.

One thing I can think of is use database trigger, but I don't like them very much. Is there another way to do it with a component for example?

Another way to partialy solve that problem would be not to add record to a credits table, and only add it when the user deposits money. The problem is - we will have to check if there is already a record created when the user adds money, so do we have insert new or update an existing, so it is waste of recourses.

2
Contributors
5
Replies
6
Views
6 Years
Discussion Span
Last Post by McLaren
1

Hi,

would it be difficult to let's say add a record to another table on user registration? Lets say I want to add a records how many credits the user has in jos_credits table when user registers, in other words - add record with that user id and set credits to 0 initially. When they add money to a website, they will get credits.

One thing I can think of is use database trigger, but I don't like them very much. Is there another way to do it with a component for example?

Another way to partialy solve that problem would be not to add record to a credits table, and only add it when the user deposits money. The problem is - we will have to check if there is already a record created when the user adds money, so do we have insert new or update an existing, so it is waste of recourses.

Joomla has a plugin system that will trigger certain events in the Joomla Framework.

The User plugins have events for saving user data, authentication etc.

see: http://docs.joomla.org/Reference:User_Events_for_Plugin_System#5.3.7_onAfterStoreUser

Here is a bit on creating a plugin: http://docs.joomla.org/Tutorial:Creating_a_Plugin_for_Joomla_1.5

Basically you will create a plugin which is an xml file and a php file. The PHP file contains a class that extends the plugin base base class. Then you define functions which handle the different events. You're interested in the onAfterStoreUser() method.

0

Thank you very much, that is whta I was looking for :)

I made such function:

function onAfterStoreUser($user, $isnew, $success, $msg)
	{
		
		if ($isnew)
		{
			// Call a function in the external app to create the user
			// ThirdPartyApp::createUser($user['id'], $args);
			
			//iterpiam irasa apie kreditus tam vartotojui
			$db =& JFactory::getDBO();
			$jAp=& JFactory::getApplication();
			    //We define a linebreak constant
			define('L', chr(10));
			    //Here is the most magic
			$db->setQuery(
			        'INSERT INTO #__credits'.L.
			        '(user_id, credit)'.L.
			        'VALUES ('.$user['id'].',0)'
			); 
			$db->query();
			    //display and convert to HTML when SQL error
			if (is_null($posts=$db->loadRowList())) {$jAp->enqueueMessage(nl2br($db->getErrorMsg()),'error'); return;}
		}
		else
		{
			// Call a function in the external app to update the user
			// ThirdPartyApp::updateUser($user['id'], $args);
		}
	}

But I don't get, why it inserts two rows there? Have you an idea?

Another thing - don't know now, what would be best to do if the insert is not succesfull. If it is not succesfull, then when user tries to buy credits, there will not be row to update. So again, I will have to check before update if the row exists in table jos_credits, which is waste of recourses, because most of the time the row for that user will exist. Can you advice something on that?


EDIT:

Found how to maka it insert only one row, now code is such:

function onAfterStoreUser($user, $isnew, $success, $msg)
	{
		
		if ($isnew)
		{
					
			$data = new stdClass();
			$data->id = null;
			$data->user_id = $user['id'];
			$data->credit = 0;
			

			$db = JFactory::getDBO();
			$jAp=& JFactory::getApplication();
			if(!$db->insertObject( '#__credits', $data, id ));
			{
				$jAp->enqueueMessage(nl2br($db->getErrorMsg()),'error'); return;
			}
		}
		else
		{
			// Call a function in the external app to update the user
			// ThirdPartyApp::updateUser($user['id'], $args);
		}
	}

So the only question remains what if insert is not succesfull?

Edited by McLaren: update

1

For the first issue, where you have duplicates. What you can do is put a unique index on the user_id row. That way a duplicate creates an error and can never exist.

Do not worry about the extra load on the db when you check if an entry exists. It is a necessary part of your logic, so do it. Foremost is that your application works well.

If you have problems later on, it most likely will not be because you're checking for an existing entry. Read some posts online on "premature optimization". You can wonder about design all day if you think of every small decision and how it affects load.

On fail of the insert, you will have to figure out what went wrong. You can either change your onstoreuser to onbeforestoreuser or whatever it is called. Then do your insert before user is stored, and if it fails, return false so that the user registration fails. Then send yourself an email, or other notice or log the error somewhere for notification later.

When updating the credits row, you should check how many rows were affected in the update. If the update did not affect any rows, then something is wrong, so notify the user and yourself.

You can also hook into the user login through a plugin. When the user logs in, check if their credits row exists. If not, create it. This works for users that already exist in the db and would not be handled by registration events.

0

In short, it is up to you what your logic is, just don't worry about optimization as an issue preventing you from writing it out to cover all scenarios. Test it afterwards for performance issues, not theoretically during your coding process. It usually makes development a lot more efficient.

0

thank you very much, interesting read :) now I will try to code this :)

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.