简体   繁体   English

创建Joomla用户配置文件插件

[英]Creating Joomla user profile plug-in

I've taken a direct clone of the User Profile plug-in for my Joomla 2.5.9 install. 我直接克隆了用户配置文件插件,用于我的Joomla 2.5.9安装。

I've renamed the plugin and the files accordingly to 'profiletest' similar to the old 1.6 tutorial . 我已经将插件和文件重命名为'profiletest',类似于旧的1.6 教程

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. 但是,当您注册时,我从未看到#__user_profiles表已更新。

Lots of code here but it's a copy of the User profile plug-in (/plugins/user/profile/). 这里有很多代码,但它是User profile插件的副本(/ plugins / user / profile /)。 Here is the profiletest.php onUserAfterSave function: 这是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;
}

It never inserts anything into the DB because it never goes into this if statement: 它永远不会在DB中插入任何东西,因为它永远不会进入这个if语句:

if ($userId && $result && isset($data['profiletest']) && (count($data['profiletest'])))

Basically this condition fails: $data['profiletest'] 基本上这种情况失败了: $data['profiletest']

Seems pretty basic as all I've changed in the plugin is 'profile' to 'profiletest'. 看起来非常基本,因为我在插件中更改的是'profile'到'profiletest'。 However to solve this I think you need to see what my other function called onContentPrepareData . 但是要解决这个问题,我认为你需要看看我的另一个函数叫做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. 这可能会影响onUserAfterSave函数。

EDIT Here is the function onContentPrepareForm : 编辑这是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(); var_dump($data); exit(); just inside onUserAfterSave : 就在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" }

So the key function here is actually the one that you are not including: onContentPrepareForm . 所以这里的关键功能实际上是你不包括的那个: 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] . 如果您检查任何字段(让我们使用地址1),它应该具有如下名称: jform[profile][address1] We want this to be jform[profiletype][address1] and then your code will work. 我们希望这是jform[profiletype][address1] ,然后你的代码就可以了。

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. $data变量应该包含提交表单中的所有信息。 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. 这匹配名称开头具有jform所有内容,因为这是Joomla用于注册表单的标准控件。

$data will then contain some individual items and the array profile . 然后$data将包含一些单独的项和数组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 . 要更新该名称,请找到plugins/user/profile/profiles/profile.xml profileprofiletype fields名称从profile更改为profiletype Now when submitted $data will contain the array element profiletype and the rest of the queries will run. 现在提交时, $data将包含数组元素profiletype ,其余查询将运行。

First of all use JDump or var_dump() the array $data->profiletest to check you have data. 首先使用JDump或var_dump()数组$data->profiletest来检查你是否有数据。 If not then I guess you will need to go analyse the onContentPrepareForm method. 如果没有,那么我想你需要去分析onContentPrepareForm方法。 If not then go and check the UserID is pulling in a valid result. 如果没有,那么去检查UserID是否正在提取有效结果。 One of the two must be giving a invalid result to 'fail' the if statement. 其中一个必须给出“失败”if语句的无效结果。 Once you've done that post back here with the results :) 一旦你完成了这篇文章回到这里结果:)

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. 我认为你在这里有一个问题:'profiletest。%'你不应该把php连接运算符放在引号中,它将它作为字符串的一部分。 Personally, I usually concatenate the % before writing the query. 就个人而言,我通常在编写查询之前连接%。 But $db->quote('profiletest.'.$k).' 但$ db-> quote('profiletest。'。$ k)。 which you have later is more along the lines of what you want. 你以后拥有的更符合你想要的。

Since $data['profiletest'] fails 由于$ data ['profiletest']失败

The change of name from profile to profiletest has not been registered in xml 名称从配置文件更改为profiletest尚未在xml中注册

please make the following changes if u haven't. 如果你还没有,请进行以下更改。

In plugins\\user\\profile\\profiles\\profile.xml 在plugins \\ user \\ profile \\ profiles \\ profile.xml中

change <fields name="profile"> to <fields name="profiletest"> <fields name="profile"> to <fields name="profiletest">

Also in user\\profile\\profile.xml 也在user \\ profile \\ profile.xml中

change <filename plugin="profile">profile.php</filename> 更改<filename plugin="profile">profile.php</filename>

to

<filename plugin="profile">profiletest.php</filename>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM