Registration PHP Code for Multiple PSB™ Hosts
Multiple PSB™ Hosts, also called hosts of administrators, host the PSB™ administrators, each of which administers (manages) a PSB™. Administrators may choose to sign themselves up as a PSB™ user if they wish—this will include them on the PSB™ (personal status board) display. Here is a diagram named The Personal Status Board (PSB™) Hosting Diagram that will help you see how all the parts fit together: Servers, databases, MySQL, host of administrators, administrators, users, and PSB™s. Check it out.
Users and administrators never see the file below—only the PSB™ host sees it, so he will have to replace the "yourusername", "yourpassword" and "yourdatabase" with legitimate names (in the configure.php file) that will enable the MySQL connection to be made and the database to be chosen. That's why include_once"configure.php" is the first PHP code on the page. Only one database will be used to host all PSB™s, and each administrator's data will be entered into the host's "members" table (that contains users password, administrator password, administrator user name, email address, date of joining, and IP of administrator). Each administrator gets 2 other tables as well that are for his group only. The first table contains his group's statuses and comments, which any group member may change, as well as all first names of group members, which only the administrator can edit. The second table contains the current meanings of the 100 status codes—which the administrator may change if his group wants it.
Below, the table "members" gets created if it doesn't exist, and it gets set to autoincrement so that new users will get added at the end of the table. Next, the variable "register" is checked. If it is set it means the form was filled out, since it's the form submit input that sends the value "Register" via POST. Now the values of the username, admin_password, users_password, and email are received via POST as well. Today's date and the user's IP address are also put into PHP variables for storing in the "members" table. The administrator's user name is checked to make sure the name isn't already in the MySQL table. If it is, the administrator is warned and returned to the input form. Otherwise, the registration process proceeds.
When the administrator input his data, the first names of his group members (including the administrator, usually) were solicited, and the number of people input was saved in the form field named "num" and this number gets POSTed along with the other inputs. Next to the "num" input field is a button that reads "Add people before Registering", and clicking on this runs a function that actually creates a number of input boxes equal to the number of people the administrator indicates he wants to add. First names are input into these boxes, and a validation function is run to determine if they entered something other than letters, numbers and underline or less than 1 or more than 12 characters (which creates a warning alert). The creation of these input boxes also sticks a name, "people[]", on each of these fields and the input validation script is run as a result of an onBlur event, which means when the user leaves the field. Hitting the Enter key often will submit a form, but to prevent that, a function based on the onkeydown Window event is utilized.
Anyway, all the user first names that get input also get POSTed to the script, requiring a page reload. But now the script has enough data to create the needed MySQL tables.
<?
include_once"configure.php";
$sql = "CREATE TABLE IF NOT EXISTS members (
id int(11) NOT NULL auto_increment,
username varchar(255) NOT NULL,
admin_password varchar(255) NOT NULL,
users_password varchar(255) NOT NULL,
email varchar(255) NOT NULL,
ip varchar(255) NOT NULL,
date varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1";
// Execute query
mysql_query($sql);
if(isset($_POST['register'])){
$username = $_POST['username'];
$password = $_POST['admin_password'];
$upassword = $_POST['users_password'];
$email = $_POST['email'];
$memip = $_SERVER['REMOTE_ADDR'];
$date = date("d-m-Y");
$checkformembers = mysql_query("SELECT * FROM members WHERE username = '$username'");
if(mysql_num_rows($checkformembers) != 0){echo '<script language="javascript">alert("Username already in use. Please try again.")</script>;';
}else{
$num=$_POST['num'];
Below, the username entered is used, once "_psb" is appended to it, as the name of the MySQL psb table where the first names, statuses, and comments are stored. The table is created on the spot with the N field (from 1 to num) as the auto-incrementing primary key. The ID field is not primary, and if you care why, check out add-group-member.html. Remarkably, even though the name of those first name input boxes that were made-on-the-fly were all "people[]" (with no numbers or variables inside), when this page's PHP gets these values via POSTing the page to itself, they're in a nice, neat people() array. The remarkableness is further compounded by the fact that IE has a disasterous bug in which the setAttribute function during a createElement function (if the element created is an input box and the attribute added is "name") actually fails to work and no name is added. And yet, miracle of miracles, when the data gets POSTed to PHP, even though the names never got into the form in IE, the people() array arrives fully intact and fully filled with data, even though it is the NAME attribute of the input boxes that POST is supposed to reference to get its data! Curiouser and curiouser . . .
Of course, that's not the only bug in the soup. PHP has a dandy in its array_unique function which is supposed to dump any duplicate names, leaving only unique data. In our tests, it killed a good name now and then as well, leaving a data gap. Notice that we defined a couple of arrays and pushed the names POSTed to PHP into the first one. Then we ran the array_keys(array_flip()) function as a workaround for the broken array_unique function. It's not the function's purpose, but it worked, which is all that matters, though we're not all that sure why it works! When we put in duplicate names, the array_keys(array_flip()) function dumped them, and the
count() function detected fewer elements in the array and this caused us to give a warning message. The MySQL INSERT loaded the table with the cleaned array data—all standard stuff.
$a=$username."_psb";
$sql = "CREATE TABLE $a
(
N int(2) NOT NULL AUTO_INCREMENT,
Firstname varchar(12) NOT NULL,
ID int(2) NOT NULL,
Status char(2) NOT NULL,
Comment varchar(55) NOT NULL,
PRIMARY KEY(N)
)";
// Execute query
mysql_query($sql);
$myArray=array();$myArray1=array();
for($i=0;$i<$num;$i++){
array_push ($myArray, $_POST['people'][$i]);
}
$myArray1=array_keys(array_flip($myArray));//array_unique has BUG!
$c=count($myArray1);
if($num>$c){echo '<script language="javascript">alert("One or more duplicate names were deleted.");</script>';}
for($i=0;$i<$c;$i++){
$b=$myArray1[$i];
$j= $i + 1;
mysql_query("INSERT INTO $a (N, Firstname, ID, Status, Comment)
VALUES('','$b','$j','99','')");
}
$a=$username."_meaning";
$sql = "CREATE TABLE $a
(
sorter int(3) NOT NULL,
meaning varchar(57) NOT NULL,
PRIMARY KEY(sorter)
)";
// Execute query
mysql_query($sql);
mysql_query("INSERT INTO $a (sorter, meaning)
VALUES ('1','Alone (do not disturb)'),('2','Alone thinking'),('3','Alone with someone'),('4','Alone creating'),('5','Alone sleeping'),('6','Alone studying'),('7','Alone exercising'),('8','Alone feelings (sad or lonely or depressed)'),('9','Alone feelings (anxious or confused or fearful or upset)'),('10','Alone feelings (need help)'),('11','Want nurturing'),('12','Will nurture'),('13','Could nurture'),('14','I am a scheduled caregiver'),('15','Sick - need care'),('16','Sick - have care'),('17','Want stories'),('18','Will read stories'),('19','Want massage'),('20','I am being nurtured'),('21','Want P.E.T. training'),('22','Will train re: P.E.T.'),('23','Need to do problem solving'),('24','Will help problem-solve'),('25','Need active listening'),('26','Will active listen'),('27','Doing authoritative parenting activity - not P.E.T.'),('28','Want help with discipline'),('29','Will give help with discipline'),('30','Doing P.E.T. activity'),('31','Want advice'),('32','Will advise'),('33','Want group discussion'),('34','Want to talk with female'),('35','Want to talk with male'),('36','Want adult company'),('37','Want child company'),('38','Want to play'),('39','Want to play game(s)'),('40','I am in meeting'),('41','Let Us Coordinate MC party'),('42','Let Us Coordinate MC big dinner'),('43','Let Us Coordinate MC all-MC meeting'),('44','Let Us Coordinate MC MC projects'),('45','Let Us Coordinate MC music'),('46','Let Us Coordinate MC creative projects'),('47','Let Us Coordinate MC activity - open to possibilities'),('48','Let Us Coordinate MC movie in theater'),('49','Let Us Coordinate MC DVD movie on TV'),('50','I am in MC coordinating meeting'),('51','Let Us Coordinate shopping - food'),('52','Let Us Coordinate shopping - clothes'),('53','Let Us Coordinate shopping - other'),('54','Let Us Coordinate going to library'),('55','Let Us Coordinate going to concert'),('56','Let Us Coordinate going to movie'),('57','Let Us Coordinate playing sports'),('58','Let Us Coordinate seeing sporting event'),('59','Let Us Coordinate exercise'),('60','Let Us Coordinate other'),('61','I am Out at school or daycare'),('62','I am Out at work'),('63','I am Out at shopping'),('64','I am Out at library'),('65','I am Out at entertainment'),('66','I am Out with friends or date'),('67','I am Out at hospital'),('68','I am Out at vacation - out of town'),('69','I am Out at doctor'),('70','I am Out at other'),('71','Want Ride north - A.M.'),('72','Want Ride north - P.M.'),('73','Want Ride south - A.M.'),('74','Want Ride south - P.M.'),('75','Want Ride east - A.M.'),('76','Want Ride east - P.M.'),('77','Want Ride west - A.M.'),('78','Want Ride west - P.M.'),('79','Want Ride motorcycle OK'),('80','Want Passenger(s) - I will drive'),('81','Want help with project'),('82','Will help with project'),('83','Want tutor in music'),('84','Want tutor in math'),('85','Want tutor in science'),('86','Want tutor in languages'),('87','Want tutor in English or literature'),('88','Want tutor in history'),('89','Want tutor in taxes'),('90','Will tutor'),('91','Need pet caretaker'),('92','Am texting'),('93','Text me'),('94','Am emailing'),('95','Email me'),('96','Am IMing'),('97','IM me'),('98','Surfing the Net'),('99','Writing a letter'),('100','All is well')
");
$create_member = mysql_query("INSERT INTO members (id, username, admin_password, users_password, email, ip, date)
VALUES('','$username','$password','$upassword','$email','$memip','$date')");
echo '<script language="javascript">alert("Thank you for registering. Please login.");</script>';
$to = $email;
$subject = "Welcome, new PSB™ administrator!";
$message = "You've successfully registered as administrator of a PSB™ group.\n\nYour user name is ".$username.".\n\nYou may use your admin password to edit your account settings, add people to your PSB™, edit status code meanings, change your email, or even delete your whole account.\n\nDon't give your admin password to anyone in your group, but do save it somewhere safe.\n\nGive your group members the users password ONLY.\n\nYou and your group may use this users password to log in to your PSB™ and change your status and comments.\n\nEnjoy your PSB™.\n\nRegards,\n\nthe management";
$headers = "From: ".$psbhostemailaddress."\r\nReply-To: ".$email;
$mail_sent = mail($to, $subject, $message, $headers);
}}
mysql_close();
?>
Above, we create a table for the status code meanings and load it up on the spot with the standard PSB™ meanings, which each PSB™'s administrator is free to change as his group sees fit. Note we load array values (ascending numbers) for the "sorter" field otherwise the meanings would not be stored or displayed in the correct order. The sorter field is essential, and it's the PRIMARY KEY, and if it wasn't the meanings would not be useful. This is the same function that the N field serves in the PSB™ table discussed above. Next, the members table gets loaded with the group data of the currently registering administrator. This includes id, username, admin_password, users_password, email, administrator IP address, and today's date. The table, "members," gets created if it doesn't exist and it autoincrements so new administrators go last. Note that we don't actually send an id code—we send only an empty pair of single quotes, which tells MySQL to autoincrement the id field to the next value. Next we email the administrator with the standard welcoming speech. Note how we include his user name by use of the variable ".$username." in the middle of the email, using periods as concatenating tools just like the way JavaScript uses + signs. We used the administrator's address for the Reply-To address, which is standard.
Below, we disable premature submissions by preventing Enter key action. Then we use a validate() function to check the data entered into the first name field. The flag gets incremented to acknowledge the fact that there is 1 or more entries going on. If the main form detects flag = 0, a warning is shown and the administrator is kept in the form until he gives first name data—what's the point of a PSB™ with no one in it? Next, regular expressions are used to validate the input of user name, administrator password, users password, and email address.
Then, the AddFormFields() function uses the number entered in the text input field named "num" to create the specified number of input boxes for first name entry. It employs the CreateFormTextInput() function to create these elements and set their attributes, including people[] as the field names, as previously discussed, and formField.onblur=function(){validate(this);}; is set as an event attribute of each element.
The attribute formField.style.cssText = 'position:absolute;left:322px;top:'+t+'px;'; sets the style attribute—or the cssText style, if you will. Not the usual way of doing CSS, by any means! But it works. Anyway, once the elements are created, the AddFormFields() function takes over and appends these children to the parent element, the form.
The form itself is standard stuff, using an onSubmit event to run the validation script. The action is normal—the PHP page calls itself. This is common in PHP pages submitting forms. Why bother with external PHP submission scripts? There is a button with "Add people before Registering" on it for soliciting the number of people to add.
The onclick="clik=1;AddFormFields(document.peopleForm.num.value)" script is run from clicking the button, and this not only sets the "clik" flag so we know the input boxes have been created, it also sends the number entered to the form field adding function.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>PSB™ Signup Script</title>
<script language="javascript">
document.onkeydown = function(e){
e = e? e : window.event;
var k = e.keyCode? e.keyCode : e.which? e.which : null;
if (k == 13){
if (e.preventDefault) e.preventDefault();
return false;}
return true;}
var flag=0;var clik=0;
function validate(field){
var ck_userfirstname = /^[A-Za-z0-9_]{1,12}$/;
if (field.value.search(ck_userfirstname)==-1)
{field.value='';alert("Please only enter letters, numbers and underline for user first names, and enter 1 to 12 characters.");};flag=flag+1;}
function validatepassword(){
if(clik==0||clik<num_people){alert("Please enter number of people to add.");return false}
if(flag==0){alert("Please only enter letters, numbers and underline for user first names, and enter 1 to 12 characters.");return false}
var ck_username = /^[A-Za-z0-9_]{4,30}$/;
if (document.peopleForm.username.value.search(ck_username)==-1)
{alert("Please only enter letters, numbers and underline for user names, and enter 4 to 30 characters.");return false}
var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{6,12}$/;
if (document.peopleForm.users_password.value.search(ck_password)==-1)
{alert("Please only enter 6 to 12 letters, numbers and these for user password: !@#$%^&*()_");return false}
var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{6,12}$/;
if (document.peopleForm.admin_password.value.search(ck_password)==-1)
{alert("Please only enter 6 to 12 letters, numbers and these for administrator password: !@#$%^&*()_");return false}
var ck_email = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;
if (document.peopleForm.email.value.search(ck_email)==-1)
{alert("That email address is not valid.");return false}
return true}
var num_people=0;
function CreateFormTextInput (its_name,t) {
var formField = document.createElement ("input");
formField.setAttribute ('type', 'text');
formField.setAttribute ('value', "");
formField.setAttribute ('name', its_name);
formField.setAttribute ('size', '12');
formField.style.cssText = 'position:absolute;left:322px;top:'+t+'px;';
formField.onblur=function(){validate(this);};
e = document.getElementById("form");
z=t+26;
e.style.height=z+"px";
return formField;
}
function AddFormFields (num_people){
for(i=0;i<num_people;i++){
var d= 280+(i*22);
var a = 'people[]'; a = a.toString();
var textBox = CreateFormTextInput(a,d);
var br = document.createElement("br");
document.peopleForm.appendChild(br);
document.peopleForm.appendChild(textBox);}}
Netscape=(navigator.appName.indexOf("Netscape") != -1)
function fix(){if(Netscape){e=document.getElementById('side');e.style.width='122px';}}
</script>
</head>
<body onload='fix()'>
<div style='position:absolute;margin:0 0 0 150px'>
<form name="peopleForm" id='form' method="post" onsubmit="return validatepassword()" action="register.php" style='background-color:#ccc;border:4px solid blue;width:700px;'>
<table width="600" border="1" align="center">
<? echo '<tr><td colspan="2" style="font-weight:bold;color:red">'.$info.'</td></tr>'; ?>
<tr>
<td width="50%">Username:</td>
<td width="50%"><label>
<input name="username" type="text" id="username" size="30">
</label></td>
</tr>
<tr>
<td>Administrator's Password:</td>
<td><input name="admin_password" type="password" id="password" value="" size="30"></td>
</tr>
<tr>
<td>User's Password:</td>
<td><input name="users_password" type="password" id="u_password" value="" size="30"></td>
</tr>
<tr>
<td>Email:</td>
<td><input name="email" type="text" id="email" size="30"></td>
</tr>
<tr>
<tr>
<td>Number of people to add:</td>
<td><input name="num" type="text" id="num" size="30" value=''><input type="button" value="Add people before Registering" onclick="clik=1;AddFormFields(document.peopleForm.num.value)"></td>
</tr>
<tr>
<td> </td>
<td><label>
<input name="register" type="submit" id="register" value="Register">
</label> as Administrator of a PSB™ group.</td>
</tr>
</table>
</form>
</div>
<div id='side' style='padding:12px;background-color:#eee;border:1px solid black;width:140px;margin:0'>Administrator: If you want your status to be part of your PSB™, include your first name with the others in "Add people before Registering". Use the User's Password to login.</div>
</body>
</html>