This is an advanced tutorial on extending fields in Joomla user registration using the core plugin provided with Joomla. Those who are new to Joomla and PhP coding should be careful while playing with plugins. I suggest webmasters to use already existing Joomla extensions which are offered under Free/paid category in Joomla Extensions Directory, that can meet your purpose. Before proceeding you should know what is a plugin and how it works. Basically this plugin tutorial is for those who does not want to add many component, plugins etc from third party and get their site compromised. Therefore it uses only the core joomla structure.
In this tutorial I will make a clone of the profile plugin found in the (Plugins) Directory under (User) sub-directory. As seen in the image below you should copy the folder entirely and rename it.
As I am going to create fields for a photographers community therefore I will add some fields related to Photography only. Remember also to copy the language files found in (adminitrator/language/en-GB/en-GB.plg_user_profile.ini) and also (adminitrator/language/en-GB/en-GB.plg_user_profile.sys.ini) to the new folder. I have created a folder named (photographersprofile) and copied all the files to that folder. It need not necessarily be in the plugin folder but can be taken to desktop or any convenient location. After working on this we have to install the plugin and then only the plugin starts working.
Please insert your text here![/nextpage]For all the Joomla extensions, an xml file is a must, where the extension details can be found, such as name, authour, url , files, folders, parameters etc. As we have copied the files we just have to change the names in the (photographersprofile.xml) file accordingly. The attached image will guide you on what parameters to be changed.
We are not going to add any extra files but we have to rename the files accordingly. The file structure in the photographersplugin directory will be like this:
plg_user_photographersprofile
—–> en-GB.plg_user_photographersprofile.ini (Changed)
—–> en-GB.plg_user_photographersprofile.sys.ini (Changed)
—–> photographersprofile.php (Changed)
—–> photographersprofile.xml (Changed)
—–>field (Not Changed)
———-> dob.php (Not Changed)
———-> tos.php (Not Changed)
—–>profiles (Not Changed)
———-> profile.xml (Not Changed)
Note: As per Joomla Extensions rules you should have an empty (index.html) in each folder which is mandatory for your extension to get listed in JED. This is for site security.
After changing the (photographersprofile.xml) file, all the files can be compressed and installed but it is better to update all the files with the required changes and then install it finally. Therefore we will start with (profile.xml) file found under the (profiles) folder.
Before proceeding further we need to analyze what extra fields we need for a photography sharing website. I am going to collect data such as Camera Brand, Camera Model, Camera Lens and Experience Level from the photographers who register in my site. The field types for each will be
Camera Brand -> List type where users can chose from (Nikon, Canon, Olympus, Sony etc)
Camera Model -> Text Area type where users can enter the model they possess like, Nikon D3300, Canon EOS etc
Camera Lens -> Text Area type where Users enter the lens they are having.
Experience Level-> List type (Freshers, Intermediate and Professional)
In the (profile.xml) file this will be the changes or additions
<field name="camera" type="list" id="camera" size="5" class="inputbox" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_DESC" multiple="true" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LABEL"> <option value="Canon">Canon</option> <option value="Nikon">Nikon</option> <option value="Olympus">Olympus</option> <option value="Sony">Sony</option> <option value="Bower">Bower</option> <option value="Casio">Casio</option> <option value="Contour">Contour</option> <option value="Cullmann">Cullmann</option> <option value="Drift">Drift</option> <option value="Giottos">Giottos</option> <option value="Hoya">Hoya</option> <option value="Intova">Intova</option> <option value="Joby">Joby</option> <option value="Kodak">Kodak</option> <option value="Lenspen">Lenspen</option> <option value="Lowepro">Lowepro</option> <option value="Nissin">Nissin</option> <option value="Pentax">Pentax</option> <option value="PrecisionDesign">Precision Design</option> <option value="Quantum">Quantum</option> <option value="Rokinon">Rokinon</option> <option value="Slik">Slik</option> <option value="Tamrac">Tamrac</option> <option value="Tamron">Tamron</option> <option value="Tiffen">Tiffen</option> <option value="Velbon">Velbon</option> <option value="Others">Others</option> </field> <field name="cameramodel" type="textarea" id="cameramodel" rows="3" cols="5" filter="raw" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_LABEL" size="30" /> <field name="cameralens" type="textarea" id="cameralens" rows="3" cols="5" filter="raw" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_LABEL" size="30" /> <field name="experience" type="list" id="experience" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_DESC" filter="string" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_LABEL" > <option value="Fresher">Fresher</option> <option value="Intermediate">Intermediate</option> <option value="Professional">Professional</option> </field>
As mentioned in the code there are four extra fields added in the “profile.xml” file. if you need any other fields you can add that too but remember the changes need to be reflected in two other files (photographersprofile.php) and (photographersprofile.xml) file. In the (photographersprofile.xml) there are two fieldsets one for first time registration and another for editing the profile fields. So we need to enter the fields in register and profile fields.
In register fields we have:
<field name="register-require_camera" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="register-require_cameramodel" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="register-require_cameralens" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="register-require_experience" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field>
In the profile field changes we have
<field name="profile-require_camera" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="profile-require_cameramodel" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERAMODEL_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="profile-require_cameralens" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_CAMERA_LENS_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field> <field name="profile-require_experience" type="list" description="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_DESC" label="PLG_USER_PHOTOGRAPHERSPROFILE_FIELD_EXPERIENCE_LABEL" > <option value="2">JOPTION_REQUIRED</option> <option value="1">JOPTION_OPTIONAL</option> <option value="0">JDISABLED</option> </field>
All the characters in bold looking like machine level language will be replaced in human readable language in the language files. Looking at bottom of the language files will give an idea on how to change the language files.
Next very important file which needs to be updated is the (photographersprofile.php) file. major hurdle will be the field where we are allowing multiple brand name selection. As arays cannot be stored directly in database we have to use json to store the data in database converting the array to a string.
i) Before Showing the form to user
When the user opens the registration form these extra fields should be shown. Therefore in the function onContentPrepareForm we add the extra fields under the fields array and also to descriptions.
$form->setFieldAttribute('camera', 'description', 'PLG_USER_PHOTOGRAPHERSPROFILE_FILL_FIELD_DESC_SITE', 'profile'); $form->setFieldAttribute('cameramodel', 'description', 'PLG_USER_PHOTOGRAPHERSPROFILE_FILL_FIELD_DESC_SITE', 'profile'); $form->setFieldAttribute('cameralens', 'description', 'PLG_USER_PHOTOGRAPHERSPROFILE_FILL_FIELD_DESC_SITE', 'profile'); $form->setFieldAttribute('experience', 'description', 'PLG_USER_PHOTOGRAPHERSPROFILE_FILL_FIELD_DESC_SITE', 'profile');
ii) Saving into Database
Before saving the array into the database it needs to be converted to string so in the function onUserBeforeSave we add the following lines
if (isset($data['profile']['camera']) && is_array($data['profile']['camera'])) { $registry = new JRegistry; $registry->loadArray($data['profile']['camera']); $data['profile']['camera'] = (string) $registry; $this->camera = $data['profile']['camera']; }
iii) Retrieving from database and converting to array
When we retrieve the data it will be a json encoded string which needs to be decoded. So in the function onContentPrepareData we add this lines
if($k === "camera"){ $registry = new JRegistry; $registry->loadString(json_decode($v[1], true)); $v[1] = $registry->toArray(); $data->profile[$k] = $v[1]; }
This will convert it back to an array.
iv) Displaying input data in the front end
In the function onContentPrepareData add this lines
if (!JHtml::isRegistered('users.camera')) { JHtml::register('users.camera', array(__CLASS__, 'camera')); }
This will search for a function named camera. The purpose of this function is to output the data back to the user. So it has to converted back from an array to a string using implode function. There are also other options on displaying arrays at frontend. if you have knowledge of PhP you can display in varius other formats. The function is given below
public static function camera($value) { if (empty($value)) { return JText::_('PLG_USER_PHOTOGRAPHERSPROFILE_NO_INFO_PROVIDED'); } else { // Convert website url to utf8 for display return implode(',',$value); } }
This completes our plugin coding but we need to change the language files too. The photographersplugin is attached for download with this article which can help you to locate the changes made in the language files. All the changes are at the bottom. After all the necessary changes to the plugin we can zip it and then install it at the backend.