我直接克隆了用户配置文件插件,用于我的Joomla 2.5.9安装。
我已将插件和文件重命名为'profiletest',类似于旧版 tutorial。
我在表单中添加了一个新输入,一切都在后端工作,新条目在前端的注册表单中按预期显示。但是,当您注册时,我从未看到#__user_profiles
表已更新。
这里有很多代码,但它是用户配置文件插件的副本(/ plugins / user / profile /)。这是profiletest.php onUserAfterSave函数:
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;
}
它永远不会在数据库中插入任何东西,因为它永远不会进入这个if语句:
if ($userId && $result && isset($data['profiletest']) && (count($data['profiletest'])))
基本上这种情况失败了:$data['profiletest']
看起来非常基本,因为我在插件中更改的是'profile'到'profiletest'。但是要解决这个问题,我认为你需要看看我的另一个函数叫onContentPrepareData
。虽然名称更改除了之外没有做任何不同的事情。抱歉长时间转储。
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;
}
我再次注意到我从未进入过这里:
if (!isset($data->profiletest) and $userId > 0)
这可能会影响onUserAfterSave
功能。
编辑以下是函数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;
}
我做错了什么?
编辑 var_dump($data); exit();
位于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" }
答案 0 :(得分:3)
所以这里的关键功能实际上是你不包括的那个:onContentPrepareForm
。这是构建用户填写表单的功能。您尚未更新此字段中的字段名称,因此您所包含的代码中的检查将失败。
如果您在打开插件的情况下转到注册页面,则应该会看到配置文件插件的所有字段。如果您检查任何字段(让我们使用地址1),它应该具有如下名称:jform[profile][address1]
。我们希望这是jform[profiletype][address1]
,然后您的代码才能正常运行。
在谈到这个之前,让我解释一下代码。 $data
变量应包含已提交表单中的所有信息。这匹配名称开头有jform
的所有内容,因为这是Joomla用于注册表单的标准控件。
$data
将包含一些单独的项和数组profile
。要更新该名称,请找到位于plugins/user/profile/profiles/profile.xml
的文件,并将fields
名称从profile
更改为profiletype
。现在提交时$data
将包含数组元素profiletype
,其他查询将会运行。
答案 1 :(得分:1)
首先使用JDump或var_dump()数组$data->profiletest
来检查您是否有数据。如果没有,那么我猜您需要分析onContentPrepareForm
方法。如果没有,那么去检查UserID是否正在提取有效结果。其中一个必须给出无效的结果“失败”。 if语句。一旦你完成了这篇帖子,结果就是:)
答案 2 :(得分:0)
我认为你在这里有一个问题:'profiletest。%'你不应该把php连接运算符放在引号中,它将它作为字符串的一部分。就个人而言,我通常在编写查询之前连接%。但是$ db-> quote('profiletest。'。$ k)。'你以后拥有的更符合你想要的。
答案 3 :(得分:0)
由于$ data ['profiletest']失败
名称从个人资料更改为profiletest尚未在xml中注册
如果你还没有,请进行以下更改。在plugins \ user \ profile \ profiles \ profile.xml
中更改<fields name="profile"> to <fields name="profiletest">
也在user \ profile \ profile.xml
中更改<filename plugin="profile">profile.php</filename>
到
<filename plugin="profile">profiletest.php</filename>