Jump to Main Content
Content > XOOPS > SmartProfile Module - A XOOPS Profile Module
SmartProfile Module - A XOOPS Profile Module

The stable and forward-directed XOOPS 2.0.x trunk doesn't officially have an easy way to make modifications to registration profile fields, such as what is available in the 2.2.x "fork" that is being officially merged back into the 2.0.x branch. However, SmartFactory's SmartProfile module provides that functionality.

Note: this SmartProfile module was still buggy and development on it seems to have stalled (since the CVS 2007-06-15 aka 1.03). I ran into a number of issues with it working well and correctly in XOOPS 2.3.x branch, and have finally migrated over to the Profile Module as included in the XOOPS 2.3.x+ branch. Migration is fairly easy.

Latest Version: 1.0 | Dev: (CVS 2007-06-15 aka 1.03)

My Version: MB02 (Incorporates all noted below)

This module by SmartFactory, developed by the same developer that brought the xoops 2.2.x branch and its profiles module, provides the ability to have customizable profiles in XOOPS. This functionality included in the XOOPS 2.2.x fork was sorely missing in XOOPS 2.0.x fork. SmartProfiles also requires the SmartObjects framework (a collection of functions used by SmartFactory projects).

SmartProfiles 1.0 requires PHP5. The CVS version 1.03 supposedly is PHP4 ready. Some of the original bugs and enhancements I had suggested for 1.0 showed up in 1.03. Below are notes on my changes to the 1.03 unofficial release version. I had done some extensive work on the 1.0 PHP 5 version and then they released the CVS noted above which is supposed to support PHP4 as well. I've noted below if any of the changes were fixed (or added) in the CVS version.

My Version

This download includes all the changes noted below. I've also updated the SQL to include the basic default fields that my clients generally want to have (name, address, state, country, newsletter, etc.) -- note that the country one isn't quite working yet and needs a manual fix in the database. This should hopefully make it easier to get started (still easier to delete and pull back than add and construct). It also includes a modification to the admin fields page to show more information that was contributed by akitson. It also includes an extras folder with updated edituser.php, register.php, user.php, and userinfo.php files to redirect those basic functions to the module (ala xoops 2.2.x).



  • SmartObjects 0.9 (new 1.0 final now available)
  • XOOPS 2.0.13 or later
  • PHP 5 (unless you use a PHP4 port)
  • Globals On (uses the _REQUEST var)

First install SmartObjects framework, also by SmartFactory. Then install this just like any XOOPS module. You will also need to update a number of files related to registration and user information (implement similar to what is done in the XOOPS 2.2.x files) so that you use the correct registration and user-info functions:

  • edituser.php
  • register.php
  • user.php
  • userinfo.php

SmartProfile Defects

SmartProfile Bug Tracker

I have generally logged the errors and requests to the SmartFactory website, to XOOPS forums, and/or here. Noted are defects that are an issue in the CVS version noted above. Also, there are a number of pieces of HTML that are embedded into the code. My creedo is that no HTML should be put in the code in general because you can't dissect it easily and present it differently in the templates. I haven't necessarily reported all those (yet), and I've only "fixed" those I've needed to have show differently.

Registration Form

Primary User Fields Lost

Update: This one is fixed in the CVS version except for the disclaimer one below. This appears to be philosophical. The author indicated a preference for this behavior; my clients (and I) don't. As a user, I've already checked it once, so why check it every page.

In multi-step registrations, the primary user fields (uname, email, pass, agree_disc) were not being created in the database resulting in an error saying no e-mail could be sent (it was bounced to admin). The problem is that the fields weren't POSTed from the registration form beyond step 1. Make the following changes:

register.php: after old line 74:

$newuser->setVar('pass', isset($_POST['pass']) ? md5(trim($_POST['pass'])) : '');

add new lines 75-78:

$_SESSION['smartprofile']['uname'] = $newuser->getVar('uname');
$_SESSION['smartprofile']['email'] = $newuser->getVar('email');
$_SESSION['smartprofile']['agree_disc'] = $agree_disc;
$_SESSION['smartprofile']['pass'] = $newuser->getVar('pass');

Required Field Verification

The registration form wasn't verifying for required fields. I found out that the form verification javascript wasn't displaying, fixed in the template. Also, it wasn't working in Microsoft IE because IE requires the name attribute.

templates/smartprofile_register.html - replace old lines 37-38:

<form id="<{$regform.name}>" action="<{$regform.action}>" method="<{$regform.method}>" <{$regform.extra}> >

with new lines 37-39:

<form id="<{$regform.name}>" name="<{$regform.name}>" action="<{$regform.action}>" method="<{$regform.method}>" <{$regform.extra}> >

Note: verification is via javascript and quite limited in scope (i.e., drop downs required aren't really that useful -- to some degree this is a failing of XOOPS forms, though, and not the module). There should be some other code on the server side on this, though, to actually verify as the javascript verification is just to reduce server load.

Required Field Indication

The registration form (and all XOOPS forms) should display the required fields as being required. This wasn't occurring.

register.php - assign() function - after old line 227:

$elements[$n]['hidden'] = $ele->isHidden();

add new lines: 228-232:

foreach ( array_keys($form->_required) as $key) {
  if ($elements[$n]['name'] == $form->_required[$key]->_name) {
    $elements[$n]['required'] = true;

To display, edit templates/profile_register.html - line 43:

<td class="head"><{if $element.required}><span class="form_required">* </span><{/if}><strong><{$element.caption}></strong><{if $element.description != ""}><br /><{$element.description}><{/if}></td>

That dealt with all required fields but the disclaimer -- another issue to deal with. (Note: the /class/xoopsform/form.php would be the logical place for this, but in this case, the /modules/profile/register.php has a function that supercedes this, so I put it there for this mode).

Defaults Not Loaded

I noticed that some fields weren't being set per the defaults specified in the module. Turns out it was only the original XOOPS core fields and those defaults weren't loaded before displaying the form. I fixed it by adding a function and changing one line of code. The problem is that when the $newuser is created it doesn't get the defaults from the field options stored in this module.

register.php - edit old line 39:

$newuser = isset($_SESSION['smartprofile']['uid']) ? $member_handler->getUser($_SESSION['smartprofile']['uid']) : $member_handler->createUser();


$newuser = isset($_SESSION['smartprofile']['uid']) ? $member_handler->getUser($_SESSION['smartprofile']['uid']) : createNewUser($member_handler);

add function (near bottom of file):

// Function to load Field Defaults from Module
function createNewUser ($member_handler) {
  $user = $member_handler->createUser();
  $profile_handler =& xoops_getmodulehandler('profile');
  $fields =& $profile_handler->loadFields();
  $userfields = $profile_handler->getUserVars();
  if (count($fields) > 0) {
    foreach (array_keys($fields) as $i) {
      $fieldname = $fields[$i]->getVar('field_name');
      if (in_array($fieldname,$userfields)) {
  return $user;

Blank Screen

Some users complained of a blank screen. I got this after registering and going back to the registration page (which is where you are directed by the index page if not logged in). After the user was activated, it would work again without blank screen.

This occurs because the user was registered but not activated yet, and the $_SESSION['smartprofile']['uid'] was still stored in the session, the page tried to pull the user from the database and could but the user was still deactivated and there was no code for that so the system went blank.

So, I put in a cleanser line of code to dump that session if you hit the register page again at the beginning (without any posted values). Realistically, it should be fine that way, but there is likely a better way to deal with this (it might go better in the postSaveProcess function).

register.php - before old line 146:

include_once 'include/forms.php';

add new line 146:

$_SESSION['smartprofile'] = array();

Disclaimer Shows More than Once

The disclaimer shows in every registration step prior to save. akitson had contributed PHP4 code with this fix in it, but this does it, too, checking the step info.

include/forms.php file - replace old lines 282:

if ($xoopsModuleConfig['display_disclaimer'] != 0 && $xoopsModuleConfig['disclaimer'] != '') {

with new line 282:

if ($next_step == 0 && $xoopsModuleConfig['display_disclaimer'] != 0 && $xoopsModuleConfig['disclaimer'] != '') {

Register Should Redirect if Logged In

Update: This still exists in CVS

The register form should redirect to the user page if the user is logged in. The following code inserted at the top of the page should do that (otherwise they can register again), insert before line 35:

if ($xoopsUser) {
  header('location: userinfo.php?uid='.$xoopsUser->getVar('uid'));

Deactivate Referral URL Ill-Formed

After deactivating a user from the userinfo page using the deactivate button, the referring URL is ill-formed. Change line 33 to:

redirect_header("../userinfo.php?uid=".$user->getVar('uid'), 3, $message);


Options Field - Length

Because I wanted to include drop down selects for states/provinces and countries, I had to extend the size of this field to accommodate by changing it from varchar(255) to text in the database (now included in the installation SQL statements).

Options Field - Apostrophes

Also, field with array options containing apostrophe's doesn't retrieve correctly. The data os stored with addslashes, so upon retrieval for display, we have to remove it. The code fix I did was in the getEditElement function of the field class.

class/field.php - replace old line 80 (83 in CVS):

$options[$optkey] = $optval;


$options[$optkey] = $myts->stripSlashesGPC($optval);

which requires this line which I added as the first line of the getEditElement function as new line 68:

$myts =& MyTextSanitizer::getInstance();

After this change, while displaying properly on the user side, it still displays incorrectly on the Admin side so that must be handled differently.

Date Value Requires Conversion Prior to Storing

Update: This still exists in the CVS version.

For a date field, the module stores the POSTed date which is YYYY-MM-DD (and HH:MM:SS for datetime). The value needs to be converted to a unix timestamp prior to storing it in the database. There were several places to fix this.

This deals with changing the text date to a unix time stamp in the register page so the expected value is where it should be.

register.php - line 64


$_SESSION['smartprofile'][$fieldname] = $_POST[$fieldname];


if ('date' == $fields[$i]->getVar('field_type') || 'longdate' == $fields[$i]->getVar('field_type')) {
  // change text time back to unix timestamp
  $_SESSION['smartprofile'][$fieldname] = strtotime($_POST[$fieldname]);
} elseif ('datetime' == $fields[$i]->getVar('field_type')) {
  // change text datetime back to unix timestamp
  $_SESSION['smartprofile'][$fieldname] = strtotime($_POST[$fieldname]['date']) + $_POST[$fieldname]['time'];
} else {
  $_SESSION['smartprofile'][$fieldname] = $_POST[$fieldname];

This deals with storing the default value as a serialized text variable as expected when pulling the value from storage by the field class.

admin/field.php - replace old lines 213-219:

//Check for multiple selections
if (is_array($_REQUEST['field_default'])) {
  $obj->setVar('field_default', serialize($_REQUEST['field_default']));
  else {
  $obj->setVar('field_default', $_REQUEST['field_default']);

with new lines 213-225:

if (is_array($_REQUEST['field_default'])) {
  if ('datetime' == $obj->getVar('field_type')) {
    $obj->setVar('field_default',strtotime($_REQUEST['field_default']['date']) + $_REQUEST['field_default']['time']);
  } else {
    $obj->setVar('field_default', serialize($_REQUEST['field_default']));
} else {
  if ('date' == $obj->getVar('field_type') || 'longdate' == $obj->getVar('field_type')) {
  } else {
    $obj->setVar('field_default', $_REQUEST['field_default']);

Date Values Restricted to 1970 or Later

Update: Fixed in the CVS version.

There were a couple of issues I found on this one. Date values weren't allowed prior to 1970-01-01 (the unix timestamp of zero (0)). The field class restricted the value to greater than zero. I took care of that with this code:

class/field.php - delete if-statement lines in 250-262:

case "date":
  if ($value > 0) {
    return formatTimestamp($value, 's');
  return "";

case "datetime":
  if ($value > 0) {
    return formatTimestamp($value, 'm');
  return "";


case "date":
  return formatTimestamp($value, 's');

case "datetime":
  return formatTimestamp($value, 'm');

I then tried some old dates. I could go as far back as some time in 1902 before database field size became an issue. Changing field size would allow dates further back.

User Information

E-mail Address Viewable by Anonymous Users

I don't think that anonymous users should be able to see a user's e-mail address even if the user says it's okay to display. So I changed line 107 in userinfo.php to be:

if ($thisUser->getVar('user_viewemail') == 1 && is_object($xoopsUser)) {

Send Private Message

The private message (PM) function was no longer displaying on the user page, so I added that back in.

userinfo.php - edit old line 109 from:

$email = "";



add after old line 194:

$xoopsTpl->assign('uname', $thisUser->getVar('uname'));

new lines 195-197:

$xoopsTpl->assign('name', $thisUser->getVar('name'));
$xoopsTpl->assign('user_pmlink', "javascript:openWithSelfMain('".XOOPS_URL."/pmlite.php?send2=1&amp;to_userid=".$thisUser->getVar('uid')."', 'pmlite', 450, 380);");
$xoopsTpl->assign('user_pmlink_imgsrc_alttxt', sprintf(_SENDPMTO,$thisUser->getVar('name')));

language/lang/main.php - add:

define("_PROFILE_MA_SENDPM", "Send Email");

Edit User

Edit User Fails xoopsSecurity

The ability to edit users first in admin and then also by users was failing. I found that it was because of the xoopsSecurity checks without the code being put on the page.

include/forms.php - just before old line 441:

return $form;

add new line 441:

$form->addElement(new XoopsFormHiddenToken());

Edit User as Admin Doesn't Save Data

An admin using the edit user form in the module admin couldn't save the user profile information. The editablefields wasn't pulling the correct permissions info causing the profile fields to be empty. Fix in admin/user.php, change line 139 from:

$editable_fields =& $gperm_handler->getItemIds('profile_edit', $xoopsUser->getGroups(), $xoopsModule->getVar('mid'));


$editable_fields =& $gperm_handler->getItemIds('smartprofile_edit', $xoopsUser->getGroups(), $xoopsModule->getVar('mid'));

UserInfo Self-Delete Link Incorrect

In the smartprofile_userinfo.html template, there is this code for the user to delete themselves, but the link points to the admin page and not the edituser page:

<{if $user_candelete == true}>
  <form method="post" action="<{$xoops_url}>/modules/smartprofile/admin/deactivate.php"><input type="hidden" name="uid" value="<{$user_uid}>"><input type="button" value="<{$smarty.const._PROFILE_MA_DEACTIVATE}>" onclick="submit();" /></form>

change to:

<{if $user_candelete == true}>
  <form method="post" action="<{$xoops_url}>/modules/smartprofile/edituser.php"><input type="hidden" name="uid" value="<{$user_uid}>"><input type="button" value="<{$smarty.const._PROFILE_MA_DELACCOUNT}>" onclick="submit();" /></form>

TimeZone Allows Multiple Select

The select statement for TimeZone allows more than one selection. ???? Why?

Change Email

New Email Won't Submit

I couldn't get the e-mail change form to actually submit. The issue is that in line 34, the code checks for an OR where it should be an AND (!POST method or not set "oldmail" variable). Changed from an OR (||) to an AND (&&) fixed it.

Newmail Field Missing

I couldn't get the form to work because it's trying to store the entered e-mail in a newemail variable in the profile class and then store and retrieve it. Since the field didn't exist in the database, it couldn't store it nor thus retrieve it. The post-installation script uses a addProfileFields() call to insert a field. It didn't work on my installation, so I had to add the field manually because this doesn't work otherwise, and it fails silently otherwise.

Duplicate Email Allowed for Entry

I can set the e-mail to one that already exists in the database and it won't warn me. However, when I try to activate it, then it gives me the error. Why not check before sending the activation/confirmation email?

Admin Visibility Permissions

The drop-down link in permissions that takes you to visibility doesn't work correctly in this version. The problem is that the code uses the php header command to change the location via re-direct, but this doesn't work if output has already occurred. Thus, in the permissions.php file, I had to move


These I have not yet posted anywhere:

Email Change Request should be templated just like the other pages. I'm not a fan of the XoopsForm except if it were more templateable.

Category Display in Register Form: to get the Categories to show in the register form on each step, I commented out line 276 in include/forms.php. Didn't work. Still need to work on this. Pending.

Deleting a field in the administrator gives an error but still works. It calls a getmodulehandler('fieldcategory') but this class doesn't exist. Hey, it works. And how often are you gonna delete anyways?

I had a problem with the calendar javascript for date fields. It turns out it was a script in the theme that was conflicting with it (coral_reef). Changed themes, no problem!

Can't get longdate to work (not sure why I would want to, either, maybe disable?)

Profile data isn't verified on the server side for field constraints prior to committing to the database. It's only "verified" by required by client-side javascript.

AK's additional fields on the admin fields form doesn't update step on submit for Date/Select fields (maybe others, too).

Enhancement Requests

Rules (min/max length for text; min/max numbers, phone numbers, etc.)

Search page - Currently, I can't control searches by username and e-mail. They always display. You can obfuscate it, but one can still submit a form to do a search. From a privacy standpoint, this needs to change and allow control for every field, and then if no fields are accessible by permission, then it should also not be shown at all.

Need a "resend activation" capability.

Need a "deactivate permanently" (no re-activation by the user) capability.

Ability to receive notification of registration submissions when confirmation is set to require confirmation, before the user actually confirms.

Old Notes that I didn't want to remove for some reason.

PHP5 to PHP4 Port

Update: According to one SmartFactory post, this CVS Version took care of the entire PHP4 issue, but I didn't find that to be the case. If on PHP4, you'll need to look for these issues.

Many thanks to akitson (aka Ashley Kitson) who did the original PHP5 to PHP4 port of this module (v0.2). I based my port upon that as well (the changes are really pretty minimal).

Change PHP5 to PHP4 issues

  • __construct
  • returned object methods [object->method1(var1, var2)->method2();]
  • =& calls for xoops_getmodulehandler
  • instanceof instead of is_a

Files Changed:

  • register.php
  • userinfo.php
  • admin/visibility.php
  • class/category.php
  • class/field.php - also classes improperly camel-cased for XoopsObjectHandler
  • class/profile.php - also classes improperly camel-cased for XoopsObjectHandler
  • class/regstep.php
  • class/visibility.php
  • include/forms.php
  • language/english/admin.php (missing _PROFILE_AM_SHOW)

Obsolete Solutions

Before this, we had the Photos and Profiles Hack, a less than desirable, but somewhat workable, solution.  It required hacks to many of the core files making upgrades much harder to accomplish, especially if you are already hacking those files. I did this hacking for one of my sites, and it was hard to keep up with all the time involved for each update. NOT RECOMMENDED!!

Other Pages
Previous Page Social Bookmarking News Module Next Page
Comments are solely the opionion of the author and not to be construed as the opinion of anyone else.

Poster Thread
Posted: 2007/7/11 14:35  Updated: 2007/7/11 14:35
Just popping in
Joined: 2007/7/11
Posts: 2
 Re: Profile Module
so does your version have all these changes made? if so can I download your version to install on my site? I have an old xoops version so this would help.

Poster Thread
Posted: 2008/2/1 20:30  Updated: 2008/2/1 20:30
Just popping in
Joined: 2008/2/1
Posts: 2
 Re: Profile Module

excelent and very usefull article. Thank you!

At the smartfactory web site they say for v1.0:
System Requirements:
XOOPS 2.0.16
PHP 5.0x+
SmartObject v0.9+

While you say
SmartObjects 0.9
XOOPS 2.0.13
PHP 5 (unless you use a PHP4 port)
Globals On (uses the _REQUEST var)

Do you have any experience runung this on Is your version available for download somewhere?

Poster Thread
Posted: 2008/2/20 21:19  Updated: 2008/2/20 21:19
Just popping in
Joined: 2008/2/1
Posts: 2
 Re: Profile Module
There is a problem with smartprofile when auto activate new account is selected - the account is not activated.

adding this to smartprofile/register.php:

fixed the problem. I'm not very shure this is the right plase tho.

Poster Thread
Posted: 2008/3/2 19:57  Updated: 2008/3/2 19:57
Just popping in
Joined: 2008/3/2
Posts: 1
 Re: Profile Module
Thanks for this page..especially the blank page tip.

Without this I would have given up on SmartProfiles.

Another tip I fixed a problem with.. http://smartfactory.ca/modules/newbb/ ... ost_id=8305#forumpost8305



(c) 2006-2007 - Mark Boyden
Privacy - Legal Stuff - Contacts