How to Manually Insert a Group of Users Into an SMF Forum Using PHP

Posted in SMF (Simple Machine Forum), php by ShortLikeAFox on July 30th, 2008

This Tutorial assumes you are familiar with my post: How to Manually Insert a User Into an SMF Forum Using PHP.

I recently faced the challenge of moving 800 or so bands from a database into an SMF forum. I faced a couple of problems when making the move that I didn’t cover in the first post:

  1. The band names weren’t guaranteed to be safe for a character by character move into the SMF database. So some kind of name modifying function had to be employed.
  2. The bands don’t have passwords. So some type of password generation needs to be employed.

The steps I went about to register all of the bands in the forum went a little like this:

Open the Band Database

for each (Band){

Generate Password

Rename Band with "safe" name

Grab and generate information needed to insert the user

Insert Band into smf_members

Send Band an email with the password

}

Information I had available from the band database that was useful included: bandName, bandEmail, and bandWebsite

Here is the password generation function I used (blatently taken from totallyphp.co.uk):

function createRandomPassword() {

$chars = "abcdefghijkmnopqrstuvwxyz023456789";

srand((double)microtime()*1000000);

$i = 0;

$pass = ” ;

 

while ($i <= 7) {

$num = rand() % 33;

$tmp = substr($chars, $num, 1);

$pass = $pass . $tmp;

$i++;

}

return $pass;

}

The password created here is relatively weak, but it was good enough for my purposes. Any password generation function would work fine here. I chose this one because it would be easy for members to remember if they chose not to change it.

How to Do It:

//First connect to the band database
$username = "bandUsername ";
$host = "bandHost";
$mypassword = "bandPassword";
$db_name = "bandDatabase";

mysql_connect("$host", "$username", "$mypassword")or die("cannot connect to server");
mysql_select_db("$db_name")or die("cannot select DB");

//Now grab all of the bands from the database
$query = "SELECT * FROM allBands ";
$bands = mysql_query($query) or die ("Config Error 2222b");
$userRows = mysql_num_rows($bands);

//Now lets connect to the smf db
$host="smfhost"; // Host name
$username="smfuser; // Mysql username
$mypassword="smfpassword"; // Mysql password
$db_name="smfdatabase"; // Database name

mysql_connect("$host", "$username", "$mypassword")or die("cannot connect to server");
mysql_select_db("$db_name")or die("cannot select DB");

//$vaild_chars is going to be the array of allowed characters for usernames. I decided to only allow letters and numbers. There are other characters that could be used that wouldn’t cause a problem, but for style reasons I decided to go with only letters and numbers
$valid_chars = "a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9";
$valid_chars = explode(" ",$valid_chars);

//Now we need to loop through each band

for ($i = 0; $i < $userRows; $i++){

if ($row = mysql_fetch_assoc($bands)){

//Extract the band information
extract
($row);
//Create a password for the band
$realPassword = createRandomPassword();
//I choose to echo the bandname and password as part of my debugging and so I can see the function as it works
echo("<br/>$bandName - $realPassword");
$newBand = "";
//For each letter in the band name we are going to look to see if it matches a valid character from $valid_chars. It it does not we are going to get rid of it and truncate the band name
for ($j = 0; $j < strlen($bandName); $j++){

$temp = str_replace($valid_chars, "X", strtolower($band[$j]));
if ($temp == "X")

$newBand = $newBand.$band[$j];

}
//I echo the new name for the same reason I echo the old name and password
echo(" - $newBand");
//We have the new Band name…. now let’s start buliding the info we need to insert in the db…
$memberName = $newBand;
$realName = $newBand; //I set the real name and member name the same. The bands can change it if they want
$emailAddress = $bandEmail;
$websiteUrl = $bandWebsite; //Since I have the bands’ websites might as well enter them
$websiteTitle = $newBand;
$is_activated = 1;
$ID_POST_GROUP = 4;
$password = sha1(strtolower($memberName).$realPassword); //Password must be encrypted

//Make sure their isn’t a member with the same name in the SMF database. We don’t want to accidentally enter anyone twice
$query = "SELECT * FROM smf_members WHERE memberName = ‘$memberName’";
$result = mysql_query($query) or die ("Config Error 2222343242b");
$nrows = mysql_num_rows($result);

//If the member name is found do nothing
if ($nrows>0){}

else {

//If the user isn’t already signed up for the forums, do so and send an email….
$query = "INSERT INTO smf_members(memberName, realName, emailAddress, is_activated, ID_POST_GROUP, passwd, websiteUrl, websiteTitle ) VALUES(’$memberName’, ‘$realName’, ‘$emailAddress’, ‘$is_activated’, ‘$ID_POST_GROUP’, ‘$password’, ‘$websiteUrl’, ‘$websiteTitle’)";

$result = mysql_query($query) or die ("Config Error 2232 ");

//Now we need to send the band an email
$to=$emailAddress;
$subject="Your forum username and password ";

// From
$header="from: Me <me@mysite.com>";

// Your message
$message.="Your login and password are listed below. You can change either at anytime. If you don’t want to participate in our forums, that’s no problem. Just never log in and it will be like nothing ever happened.\r\n";
$message.="Username: $memberName Password: $realPassword \r\n";

// send email
$sentmail = mail($to,$subject,$message,$header);
if ($sentmail)

echo("- YES!");
//This is the last part of our echo. The " -YES!" will only be printed if an email is sent. So a full printout line will look something like this:
//Adam Strife - 4s6vsxag - AdamStrife - YES!

}

}
}

How to Manually Insert a User Into an SMF Forum Using PHP

Posted in SMF (Simple Machine Forum), php by ShortLikeAFox on July 28th, 2008

This specific example is for SMF 1.1.5. I can’t guarantee it will work with any other version.

So you run Simple Machine Forum Software and want to manually enter a user? No problem. I know this problem seems very specific, but the ideas explained here can be adapted to other types of forums and other database driven software packages such as Wordpress. Before we get into exactly how to do this, let’s take a look at how Simple Machine Forums keeps track of users. In the SMF database there is a table called smf_members. The smf_members structure looks like this:

Field Type Null

Key Default Extra
ID_MEMBER mediumint(8) unsigned NO PRI NULL auto_increment
memberName varchar(80) NO MUL    
dateRegistered int(10) unsigned NO MUL 0  
posts mediumint(8) unsigned NO MUL 0  
ID_GROUP smallint(5) unsigned NO MUL 0  
lngfile tinytext NO MUL    
lastLogin int(10) unsigned NO MUL 0  
realName tinytext NO      
instantMessages smallint(5) NO   0  
unreadMessages smallint(5) NO   0  
buddy_list text NO      
pm_ignore_list text NO      
messageLabels text NO      
passwd varchar(64) NO      
emailAddress tinytext NO      
personalText tinytext NO      
gender tinyint(4) unsigned NO   0  
birthdate date NO MUL 0001-01-01  
websiteTitle tinytext NO      
websiteUrl tinytext NO      
location tinytext NO      
ICQ tinytext NO      
AIM varchar(16) NO      
YIM varchar(32) NO      
MSN tinytext NO      
hideEmail tinyint(4) NO   0  
showOnline tinyint(4) NO   1  
timeFormat varchar(80) NO      
signature text NO      
timeOffset float NO   0  
avatar tinytext NO      
pm_email_notify tinyint(4) NO   0  
karmaBad smallint(5) unsigned NO   0  
karmaGood smallint(5) unsigned NO   0  
usertitle tinytext NO      
notifyAnnouncements tinyint(4) NO   1  
notifyOnce tinyint(4) NO   1  
notifySendBody tinyint(4) NO   0  
notifyTypes tinyint(4) NO   2  
memberIP tinytext NO      
memberIP2 tinytext NO      
secretQuestion tinytext NO      
secretAnswer varchar(64) NO      
ID_THEME tinyint(4) unsigned NO   0  
is_activated tinyint(3) unsigned NO   1  
validation_code varchar(10) NO      
ID_MSG_LAST_VISIT int(10) unsigned NO   0  
additionalGroups tinytext NO      
smileySet varchar(48) NO      
ID_POST_GROUP smallint(5) unsigned NO MUL 0  
totalTimeLoggedIn int(10) unsigned NO   0  
passwordSalt varchar(5) NO      

Fields we need to pay attention to:

  • memberName - Self Explanitory.
  • dateRegistered - Isn’t neccessary, but if not filled out the date registered displays as December 31st 1969. The date is saved as an epoch timestamp. Don’t know how to calculate timestamps in your head? No problem. I use the free generator found here.
  • realName - Should be inserted. When I’m not sure I just repeat memberName here.
  • emailAddress - Self Explanitory.
  • is_activated - Must be set to 1 since we are manually activating a member.
  • ID_POST_GROUP - I won’t lie. I’m not sure what this is, but it always seems to be set to 4. So…. I always set it to 4. Not the best way to program, but what can you do?
  • passwd - The password you want to give the new user. It is impossible to figure out how to enter without looking at the SMF documentation. The proper code to encrypt a SMF password for the database looks like this:

$passwd = sha1(strtolower($memberName).$password)

In the above line of code, $password is the user’s actual password.

How to Do It:

//First, connect to the SMF database

$host="hostname"; // Host name
$username="username"; // Mysql username
$mypassword="password"; // Mysql password
$db_name="username"; // Database name

mysql_connect("$host", "$username", "$mypassword")or die("cannot connect to server");
mysql_select_db("$db_name")or die("cannot select DB");

$memberName = "ironMan";
$realName = "Tony Stark";
$emailAddress = "ironMan@ironMan.com";
$is_activated = 1;
$ID_POST_GROUP = 4;

$password = “Tony1234″;

$password = sha1(strtolower($memberName).$password);

$dateRegistered = 1216951200; // 7-25-2008 2 AM

$query = "INSERT INTO smf_members(memberName, realName, emailAddress, is_activated, ID_POST_GROUP, passwd, dateRegistered) VALUES(’$memberName’, ‘$realName’, ‘$emailAddress’, ‘$is_activated’, ‘$ID_POST_GROUP’, ‘$password’, ‘$dateRegistered’)";
$result = mysql_query($query) or die ("SMF Error 101.234 ");

That’s all there is to it!

How to Make Thumbnail Images Using PHP

Posted in functions, php by ShortLikeAFox on July 22nd, 2008

So you want to create a thumbnail from a given image… PHP makes this task easy. I first wrote the function below to deal with images uploaded by users at a site I help administer. Uploaded images to this site can be jpegs, pngs, or gifs, so I had to write a function to deal with all three. This code is originally based off of a function found at webcheatsheet.com

How to Do It:

function createThumbs( $pathToImages, $fname, $pathToThumbs, $thumbWidth )
{

// parse path for the extension

$info = pathinfo($pathToImages . $fname);
// continue only if this is a JPEG image
if ( (strtolower($info['extension']) == ‘jpg’) || (strtolower($info['extension']) == ‘jpeg’) )
{

// load image and get image size
$img = imagecreatefromjpeg( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );

// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );

// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );

// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
imagejpeg( $tmp_img, "{$pathToThumbs}{$fname}" );

}

if ( strtolower($info['extension']) == ‘gif’ )
{

// load image and get image size
$img = imagecreatefromgif( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );

// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );

// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );

// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
imagegif( $tmp_img, "{$pathToThumbs}{$fname}" );

}

if ( strtolower($info['extension']) == ‘png’ )
{

// load image and get image size
$img = imagecreatefrompng( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );

// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );

// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );

// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
imagepng( $tmp_img, "{$pathToThumbs}{$fname}" );

}

}

How This Works

The function createThumbs takes four arguments.

  • $pathToImages -> The path to the folder the image file is in. It might look something like this: /home/content/username/html/list/uploads/
  • $fname -> The filename: pic1.gif, johnny.jpg, etc…
  • $pathToThumbs -> The path to the folder you want the thumbnail image to be in. You DO NOT want this to be the same path as $pathToImages, because the thumbnail image will have the same name as the original image.
  • $thumbWidth -> The width that you want the thumbnail to be in pixels.

An important note that I should make here is that this function has nothing in place, other than the file extension check, to make sure that the image files contain nothing malicious. Since the files createThumbs() works with have already been uploaded it is assumed that the files have been properly scrutinized.

The first thing createThumbs() does is call pathinfo(). pathinfo() breaks the parts of a path into an array. This is useful to us, because we need the file extension to properly create the thumbnail. Next createThumbs() checks to see if we are dealing with a jpeg. If the original file is a jpeg createThumbs creates a new image based on the original image with imagecreatefromjpeg(). The next step is to get the width and height of this image (imagesx(), imagesy()). Using $thumbWidth and the ratio of the original width and height createThumbs() sets the new width and height of the thumbnail. Using these new ratios createThumbs() creates a "blank" image that will be the same width and height of the thumbnail with imagecreatetruecolor(). imagecopyresized() is used to resize the image and save it in the "blank" just created. imagecopyresized() might seem like it takes a lot of parameters, but if you take a look at the documentation it really isn’t that complicated. Now that the thumbnail exists as a true color image all createThumbs needs to do is convert the file into a jpeg. To do this imagejpeg() is called.

That’s how the function works for jpegs. There are minimal differences for .pngs and .gifs.

How to Write Browser Specific Code with PHP

Posted in php by ShortLikeAFox on July 21st, 2008

So you want to write code that only appears on certain browsers… There are a number of reasons to want to do this. The first time I personally needed to do this occurred when I was trying to embed an mp3 on a certain page. For some reason I could not write the code so that the mp3 would play on the browsers I test on (IE, Firefox, and Opera), and validate at the same time. If I remember correctly, it was Internet Explorer that was causing the problem. The solution I came up with was to use a little PHP to find out when the user was using IE, and then embed the mp3 in non-valid code if that was the case.

This solution led to the mp3 always playing correctly and the page always validating, because the W3C validator never identifies itself as IE. This might not be the most ethical way to reach W3C compliance, but it works.

Another time I remember needing to write browser specific code is when I was having a problem with IE 6 not displaying my .png images correctly. I googled around and found a couple of solutions to the problem, but both of them ended up messing up the overall layer locations on my pages. Instead of troubleshooting that problem, I went with the quick solution and decided to display .gifs when the user had IE 6. If the user had another browser that had .png problems I figured that was too bad for him.

How to do it:

First you need to write a little line of code to figure out what browser your user has. Here is how to do that with PHP:

  • $visitorsOS = $_SERVER['HTTP_USER_AGENT'];

Here are three examples of what $visitorsOS can look like

  • Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET
  • Opera/9.51 (Windows NT 5.1; U; pl)
  • Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052906 Firefox

The first user has Internet Explorer 6, the second Opera 9.51, and the third Firefox.

Now that we know more information than we really need about the visitor’s computer we need to put that information to good use. Say you want to write code that will only appear if the user is running any version of Internet Explorer. In that case you would do this:

if (eregi(’MSIE’,$visitorsOS)){

CODE THAT WILL ONLY APPEAR IF USER HAS IE

}

else{

CODE THAT WILL APPEAR IN ALL OTHER CASES

}

I use eregi, a case insensitive regular expression match instead of ereg, a case sensitive regular expression match. I don’t remember if I do this out of paranoia, or if I actually found a case where Internet Explorer identified itself as msie. In either case eregi won’t hurt anything so it is what I use. Wanting to write the code for specific versions of IE would only require a small change. instead of …(eregi(’MSIE’…) I would use something like (eregi(’MSIE 6.0′…) if I wanted code that only appeared for MSIE 6.0.


Next entries »