Creating Joomla user profile plug
I've taken a direct clone of the User Profile plug-in for my Joomla 2.5.9 install.
I've renamed the plugin and the files accordingly to 'profiletest' similar to the old 1.6 tutorial.
I've added a new input to the form and everything works on the backend and the new entry shows up as expected in the registration form on the front end. However when you register I never see the #__user_profiles
table updated.
Lots of code here but it's a copy of the User profile plug-in (/plugins/user/profile/). Here is the profiletest.php onUserAfterSave function:
function onUserAfterSave($data, $isNew, $result, $error)
{
$userId = JArrayHelper::getValue($data, 'id', 0, 'int');
if ($userId && $result && isset($data['profiletest']) && (count($data['profiletest'])))
{
try
{
//Sanitize the date
if (!empty($data['profiletest']['dob']))
{
$date = new JDate($data['profiletest']['dob']);
$data['profiletest']['dob'] = $date->format('Y-m-d');
}
$db = JFactory::getDbo();
$db->setQuery(
'DELETE FROM #__user_profiles WHERE user_id = '.$userId .
" AND profile_key LIKE 'profiletest.%'"
);
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
$tuples = array();
$order = 1;
foreach ($data['profiletest'] as $k => $v)
{
$tuples[] = '('.$userId.', '.$db->quote('profiletest.'.$k).', '.$db->quote(json_encode($v)).', '.$order++.')';
}
$db->setQuery('INSERT INTO #__user_profiles VALUES '.implode(', ', $tuples));
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
catch (JException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
}
return true;
}
It never inserts anything into the DB because it never goes into this if statement:
if ($userId && $result && isset($data['profiletest']) && (count($data['profiletest'])))
Basically this condition fails: $data['profiletest']
Seems pretty basic as all I've changed in the plugin is 'profile' to 'profiletest'. However to solve this I think you need to see what my other function called onContentPrepareData
. Although again it is not doing anything different other than the name change. Sorry for the long dump.
function onContentPrepareData($context, $data)
{
// Check we are manipulating a valid form.
if (!in_array($context, array('com_users.profile', 'com_users.user', 'com_users.registration', 'com_admin.profile')))
{
return true;
}
if (is_object($data))
{
$userId = isset($data->id) ? $data->id : 0;
JLog::add('Do I get into onContentPrepareData?');
if (!isset($data->profiletest) and $userId > 0)
{
// Load the profile data from the database.
$db = JFactory::getDbo();
$db->setQuery(
'SELECT profile_key, profile_value FROM #__user_profiles' .
' WHERE user_id = '.(int) $userId." AND profile_key LIKE 'profiletest.%'" .
' ORDER BY ordering'
);
$results = $db->loadRowList();
JLog::add('Do I get sql result: '.$results);
// Check for a database error.
if ($db->getErrorNum())
{
$this->_subject->setError($db->getErrorMsg());
return false;
}
// Merge the profile data.
$data->profiletest= array();
foreach ($results as $v)
{
$k = str_replace('profiletest.', '', $v[0]);
$data->profiletest[$k] = json_decode($v[1], true);
if ($data->profiletest[$k] === null)
{
$data->profiletest[$k] = $v[1];
}
}
}
if (!JHtml::isRegistered('users.url'))
{
JHtml::register('users.url', array(__CLASS__, 'url'));
}
if (!JHtml::isRegistered('users.calendar'))
{
JHtml::register('users.calendar', array(__CLASS__, 'calendar'));
}
if (!JHtml::isRegistered('users.tos'))
{
JHtml::register('users.tos', array(__CLASS__, 'tos'));
}
}
return true;
}
Again I notice I never get in here:
if (!isset($data->profiletest) and $userId > 0)
Which probably affects the onUserAfterSave
function.
EDIT Here is the function onContentPrepareForm
:
function onContentPrepareForm($form, $data)
{
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
return false;
}
// Check we are manipulating a valid form.
$name = $form->getName();
if (!in_array($name, array('com_admin.profile', 'com_users.user', 'com_users.profile', 'com_users.registration')))
{
return true;
}
// Add the registration fields to the form.
JForm::addFormPath(dirname(__FILE__) . '/profiles');
$form->loadFile('profile', false);
$fields = array(
'address1',
'address2',
'city',
'region',
'country',
'postal_code',
'phone',
'website',
'favoritebook',
'aboutme',
'dob',
'tos',
);
$tosarticle = $this->params->get('register_tos_article');
$tosenabled = $this->params->get('register-require_tos', 0);
// We need to be in the registration form, field needs to be enabled and we need an article ID
if ($name != 'com_users.registration' || !$tosenabled || !$tosarticle)
{
// We only want the TOS in the registration form
$form->removeField('tos', 'profiletest');
}
else
{
// Push the TOS article ID into the TOS field.
$form->setFieldAttribute('tos', 'article', $tosarticle, 'profiletest');
}
foreach ($fields as $field)
{
// Case using the users manager in admin
if ($name == 'com_users.user')
{
// Remove the field if it is disabled in registration and profile
if ($this->params->get('register-require_' . $field, 1) == 0
&& $this->params->get('profile-require_' . $field, 1) == 0)
{
$form->removeField($field, 'profiletest');
}
}
// Case registration
elseif ($name == 'com_users.registration')
{
// Toggle whether the field is required.
if ($this->params->get('register-require_' . $field, 1) > 0)
{
$form->setFieldAttribute($field, 'required', ($this->params->get('register-require_' . $field) == 2) ? 'required' : '', 'profiletest');
}
else
{
$form->removeField($field, 'profiletest');
}
}
// Case profile in site or admin
elseif ($name == 'com_users.profile' || $name == 'com_admin.profile')
{
// Toggle whether the field is required.
if ($this->params->get('profile-require_' . $field, 1) > 0)
{
$form->setFieldAttribute($field, 'required', ($this->params->get('profile-require_' . $field) == 2) ? 'required' : '', 'profiletest');
}
else
{
$form->removeField($field, 'profiletest');
}
}
}
return true;
}
What am I doing wrong?
EDIT var_dump($data); exit();
var_dump($data); exit();
just inside onUserAfterSave
:
array(20) { ["isRoot"]=> NULL ["id"]=> int(1291) ["name"]=> string(4) "test" ["username"]=> string(4) "test" ["email"]=> string(22) "test@test.com" ["password"]=> string(65) "5757d7ea6f205f0ee9102e41f66939b4:7dTHzEolpDFKa9P2wmZ4SYSjJSedWFXe" ["password_clear"]=> string(4) "test" ["usertype"]=> NULL ["block"]=> NULL ["sendEmail"]=> int(0) ["registerDate"]=> string(19) "2013-03-05 17:00:40" ["lastvisitDate"]=> NULL ["activation"]=> NULL ["params"]=> string(2) "{}" ["groups"]=> array(1) { [0]=> string(1) "2" } ["guest"]=> int(1) ["lastResetTime"]=> NULL ["resetCount"]=> NULL ["aid"]=> int(0) ["password2"]=> string(4) "test" }
First of all use JDump or var_dump() the array $data->profiletest
to check you have data. If not then I guess you will need to go analyse the onContentPrepareForm
method. If not then go and check the UserID is pulling in a valid result. One of the two must be giving a invalid result to 'fail' the if statement. Once you've done that post back here with the results :)
So the key function here is actually the one that you are not including: onContentPrepareForm
. This is the function that builds the form that the user fills out. You have not updated the field names within this, so the checks in the code that you have included fail.
If you go to the registration page with your plugin turned on, you should see all of the fields for the profile plugin. If you inspect any of the fields (let's use Address 1), it should have a name like so: jform[profile][address1]
. We want this to be jform[profiletype][address1]
and then your code will work.
Before getting to that though, let me explain the code a bit. The $data
variable should have all the information from the form that was submitted. This matches everything that has jform
at the start of the name, since that is the standard control used for the registration form by Joomla.
$data
will then contain some individual items and the array profile
. To update that name, find the file that was at plugins/user/profile/profiles/profile.xml
and change the fields
name from profile
to profiletype
. Now when submitted $data
will contain the array element profiletype
and the rest of the queries will run.
I think you have a problem here: 'profiletest.%' You shouldn't put the php concatenate operator inside the quote, it is treating that as part of the string. Personally, I usually concatenate the % before writing the query. But $db->quote('profiletest.'.$k).' which you have later is more along the lines of what you want.
链接地址: http://www.djcxy.com/p/69634.html上一篇: 在代码块中组织文件
下一篇: 创建Joomla用户配置文件插件