建立會員設定檔外掛(profile plugin)

From Joomla! Documentation

This page is a translated version of the page Creating a profile plugin and the translation is 100% complete.

Other languages:
English • ‎español • ‎français • ‎Nederlands • ‎中文(台灣)‎
Joomla! 
2.5
Joomla! 
3.x

會員設定檔外掛是 Joomla! 2.5 Joomla 2.5新增的擴充套件,它可以延伸額外欄位到 com_user 的前台註冊和會員資料表單,以及後台的建立、編輯用戶表單。

一個簡單的範例外掛已經包含在 Joomla! 安裝當中,我們還可以讓外掛功能更複雜一些。

這個範例外掛利用了onContentPrepareForm以及onUserAfterSave 事件 (event)。

多個設定檔外掛可以被包起來,依序渲染到頁面上。

在核心的擴充套件中,有四處會使用到設定檔外掛表單。這四個地方都可以分別的依照個人喜好來應用。前台的兩個地方是會員註冊表單和會員個人資料編輯表單。管理後台是會員管理介面的編輯頁面,以及編輯帳號介面。

這個頁面呈現了一個範例的外掛,名為 profile5。它會新增一個名為 something 的單一欄位。

這是檔案結構:

profile5.php
profile5.xml
en-GB.plg_user_profile5.ini
en-GB.plg_user_profile5.sys.ini
index.html
/profiles/profile.xml

補充的欄位是在 profiles資料夾的profile.xml 檔案中加入的。請注意,檔案名稱是profile.xml ,而不是profile5.xml ,但是在檔案中,fields 和 fieldset 名稱要命名為「profile5」,也請注意,第一個字元必須要是xml標籤的 "<" 字元。只要把 profile5.xml 拖曳到瀏覽器中,有顯示正確的結構內容的話,那你就是作對了。

<?xml version="1.0" encoding="utf-8"?>
	
<form>
	<fields name="profile5">
		<fieldset name="profile5"
			label="PLG_USER_PROFILE5_SLIDER_LABEL"
		>
			<field
				name="something"
				type="text"
				id="something"
				description="PLG_USER_PROFILE5_FIELD_SOMETHING_DESC"
				filter="string"
				label="PLG_USER_PROFILE5_FIELD_SOMETHING_LABEL"
				message="PLG_USER_PROFILE5_FIELD_SOMETHING_MESSAGE"
				size="30"
			/>


		</fieldset>
	</fields>
</form>

profile5.php

 <?php
 /**
  * @version		
  * @copyright	Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  * @license		GNU General Public License version 2 or later; see LICENSE.txt
  */

 defined('JPATH_BASE') or die;

  /**
   * An example custom profile plugin.
   *
   * @package		Joomla.Plugins
   * @subpackage	user.profile
   * @version		1.6
   */
  class plgUserProfile5 extends JPlugin
  {
	/**
	 * @param	string	The context for the data
	 * @param	int		The user id
	 * @param	object
	 * @return	boolean
	 * @since	1.6
	 */
	function onContentPrepareData($context, $data)
	{
		// Check we are manipulating a valid form.
		if (!in_array($context, array('com_users.profile','com_users.registration','com_users.user','com_admin.profile'))){
			return true;
		}

		$userId = isset($data->id) ? $data->id : 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 \'profile5.%\'' .
			' ORDER BY ordering'
		);
		$results = $db->loadRowList();

		// Check for a database error.
		if ($db->getErrorNum()) {
			$this->_subject->setError($db->getErrorMsg());
			return false;
		}

		// Merge the profile data.
		$data->profile5 = array();
		foreach ($results as $v) {
			$k = str_replace('profile5.', '', $v[0]);
			$data->profile5[$k] = json_decode($v[1], true);
		}

		return true;
	}

	/**
	 * @param	JForm	The form to be altered.
	 * @param	array	The associated data for the form.
	 * @return	boolean
	 * @since	1.6
	 */
	function onContentPrepareForm($form, $data)
	{
		// Load user_profile plugin language
		$lang = JFactory::getLanguage();
		$lang->load('plg_user_profile5', JPATH_ADMINISTRATOR);

		if (!($form instanceof JForm)) {
			$this->_subject->setError('JERROR_NOT_A_FORM');
			return false;
		}
		// Check we are manipulating a valid form.
		if (!in_array($form->getName(), array('com_users.profile', 'com_users.registration','com_users.user','com_admin.profile'))) {
			return true;
		}
		if ($form->getName()=='com_users.profile')
		{
			// Add the profile fields to the form.
			JForm::addFormPath(dirname(__FILE__).'/profiles');
			$form->loadFile('profile', false);
	
			// Toggle whether the something field is required.
			if ($this->params->get('profile-require_something', 1) > 0) {
				$form->setFieldAttribute('something', 'required', $this->params->get('profile-require_something') == 2, 'profile5');
			} else {
				$form->removeField('something', 'profile5');
			}
		}

		//In this example, we treat the frontend registration and the back end user create or edit as the same. 
		elseif ($form->getName()=='com_users.registration' || $form->getName()=='com_users.user' )
		{		
			// Add the registration fields to the form.
			JForm::addFormPath(dirname(__FILE__).'/profiles');
			$form->loadFile('profile', false);
			
			// Toggle whether the something field is required.
			if ($this->params->get('register-require_something', 1) > 0) {
				$form->setFieldAttribute('something', 'required', $this->params->get('register-require_something') == 2, 'profile5');
			} else {
				$form->removeField('something', 'profile5');
			}
		}			
	}

	function onUserAfterSave($data, $isNew, $result, $error)
	{
		$userId	= JArrayHelper::getValue($data, 'id', 0, 'int');

		if ($userId && $result && isset($data['profile5']) && (count($data['profile5'])))
		{
			try
			{
				$db = JFactory::getDbo();
				$db->setQuery('DELETE FROM #__user_profiles WHERE user_id = '.$userId.' AND profile_key LIKE \'profile5.%\'');
				if (!$db->query()) {
					throw new Exception($db->getErrorMsg());
				}

				$tuples = array();
				$order	= 1;
				foreach ($data['profile5'] as $k => $v) {
					$tuples[] = '('.$userId.', '.$db->quote('profile5.'.$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;
	}

	/**
	 * Remove all user profile information for the given user ID
	 *
	 * Method is called after user data is deleted from the database
	 *
	 * @param	array		$user		Holds the user data
	 * @param	boolean		$success	True if user was succesfully stored in the database
	 * @param	string		$msg		Message
	 */
	function onUserAfterDelete($user, $success, $msg)
	{
		if (!$success) {
			return false;
		}

		$userId	= JArrayHelper::getValue($user, 'id', 0, 'int');

		if ($userId)
		{
			try
			{
				$db = JFactory::getDbo();
				$db->setQuery(
					'DELETE FROM #__user_profiles WHERE user_id = '.$userId .
					" AND profile_key LIKE 'profile5.%'"
				);

				if (!$db->query()) {
					throw new Exception($db->getErrorMsg());
				}
			}
			catch (JException $e)
			{
				$this->_subject->setError($e->getMessage());
				return false;
			}
		}

		return true;
	}


 }

profile5.xml 控制欄位在表單中是不是必填的,是停用或是選用的,由於profile5.php 中表示says to treat backend create/edit the same as registration only two sets of options are required, register and profile. 請注意:檔案的第一個字元必須是 "<"。只要把 profile5.xml 拖曳到瀏覽器中,有顯示正確的結構內容的話,那你就是作對了。

 <?xml version="1.0" encoding="utf-8"?>
	<!-- $Id:  -->
<extension version="3.1" type="plugin" group="user">
	<name>plg_user_profile5</name>
	<author>Joomla! Project</author>
	<creationDate>January 2008</creationDate>
	<copyright>(C) 2005 - 2013 Open Source Matters. All rights reserved.</copyright>
	<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
	<authorEmail>admin@joomla.org</authorEmail>
	<authorUrl>www.joomla.org</authorUrl>
	<version>3.0.0</version>
	<description>PLG_USER_PROFILE5_XML_DESCRIPTION</description>

	<files>
		<filename plugin="profile5">profile5.php</filename>
		<filename>index.html</filename>
		<folder>profiles</folder>
	</files>

	<languages>
		<language tag="en-GB">en-GB.plg_user_profile5.ini</language>
		<language tag="en-GB">en-GB.plg_user_profile5.sys.ini</language>
	</languages>

	<config>
		<fields name="params">

			<fieldset name="basic">
				<field name="register-require-user" type="spacer"
					label="PLG_USER_PROFILE5_FIELD_NAME_REGISTER_REQUIRE_USER"
				/>

				<field name="register-require_something" type="list"
					description="PLG_USER_PROFILE5_FIELD_SOMETHING_DESC"
					label="PLG_USER_PROFILE5_FIELD_SOMETHING_LABEL"
				>
					<option value="2">JOPTION_REQUIRED</option>
					<option value="1">JOPTION_OPTIONAL</option>
					<option value="0">JDISABLED</option>
				</field>

				<field name="profile-require-user" type="spacer"
					label="PLG_USER_PROFILE5_FIELD_NAME_PROFILE_REQUIRE_USER"
				/>

				<field name="profile-require_something" type="list"
					description="PLG_USER_PROFILE5_FIELD_SOMETHING_DESC"
					label="PLG_USER_PROFILE5_FIELD_SOMETHING_LABEL"
				>
					<option value="2">JOPTION_REQUIRED</option>
					<option value="1">JOPTION_OPTIONAL</option>
					<option value="0">JDISABLED</option>
				</field>

			</fieldset>

		</fields>
	</config>
 </extension>

en-GB.plg_user_profile5.ini

; 
; Joomla! Project
; Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_USER_PROFILE5_XML_DESCRIPTION="User Profile 5 Plug-in"
PLG_USER_PROFILE5="User - Profile 5"
PLG_USER_PROFILE5_SLIDER_LABEL="User Profile 5"
PLG_USER_PROFILE5_FIELD_NAME_REGISTER_REQUIRE_USER="User profile fields for registration and administrator user profile 5 forms"
PLG_USER_PROFILE5_FIELD_NAME_PROFILE_REQUIRE_USER="User profile fields for profile 5 edit form"
PLG_USER_PROFILE5_FIELD_SOMETHING_DESC="Choose an option for the something filed"
PLG_USER_PROFILE5_FIELD_SOMETHING_LABEL="Something!"
PLG_USER_PROFILE5_FIELD_SOMETHING_MESSAGE="A Message for something!"

en-GB.plg_user_profile5.sys.ini

; $Id: en-GB.plg_user_profile.sys.ini 17052 2010-05-14 14:05:58Z infograf768 $
; Joomla! Project
; Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_USER_PROFILE5="User - Profile 5 "
PLG_USER_PROFILE5_XML_DESCRIPTION="User Profile 5 Plug-in"

安裝 profile5 之後,您可以新增現有設定檔之外的其他欄位,您也可以控制哪個群組層級可以看到這些欄位。 或是,您也可以撰寫更複雜的外掛,來提供其他群組多樣化的控制項目。