andy's php projects
Script and site usage:
All of the scripts on this site are provided free for non-commercial, personal or non-profit use. If you wish to use any of these in a commercial system, please refer to the payment plan.

Support:
Support for each of the scripts is given, free of charge, on the message board. Each script has its own message board which can be accessed by clicking on the 'project forum' link (beneath the description of each project).


Proudly hosted with Dreamhost

Save $20 when signing up for Dreamhost by using the promo code amnuts20


If you find these scripts useful to you, appreciate the free support, or are just an all round nice person, then why not donate a little dosh to encourage me to continue? Every little helps!

Zend Certified Engineer logo


MadLibs

This class allows you to easily add a madlibs game to your website. You can load the madlib stories in via the file system or a database. The stories are chosen at random, and a form will be shown to the user to fill in their own words. You can use a few css styles to control how things look (madlibTable, madlibTitle, madlibStory, and madlibWord).

class.madlibs.php

The main class file.

<?php

//
// class.madlibs.php
// version 1.0.0, 3rd September, 2003
//
// Description
//
// This class allows you to easily add a madlibs game to your website.
// You can load the madlib stories in via the file system or a database.
// If using the file system, the stories must contain the title on the
// first line and then story in the rest of the file.  If using a database
// then the schema is as follows:
//
//     CREATE TABLE madlibs
//     (
//       id      int(11)      NOT NULL auto_increment,
//       title   varchar(255) NOT NULL default '',
//       story   mediumtext   NOT NULL,
//       PRIMARY KEY (id)
//     )
//
// Stories are requied to have specific tags in them for replacement.  The
// format for the tags in the stories as '{TAGNAME}'.  See the function
// 'setDefaultTags' for a list of all default tags.  The class already comes
// loaded with a vast array of tags, though you can easily add to or remove 
// from that list at run time.
//
// Examples of use
//
//    Using the file system:
//
//        require 'class.madlibs.php';
//        $ml = new madlibs();
//        $ml->useFS('./stories', '.txt');
//        $ml->displayMadlib();
//
//    Using the file system:
//
//        require 'class.madlibs.php';
//        $ml = new madlibs();
//        $ml->useDB('username', 'password', 'madlibs', 'mydb', 'localhost');
//        $ml->displayMadlib();
//
// Examples of stories
//
//        A simple test title
//        Yesterday, {OPPOSITESEX} and I went to the beach.  We had a really 
//        {ADJECTIVE} time!  We {VERB-ED} with my {NOUN}.
//
// Feedback
//
// There is message board at the following address:
//
//    http://php.amnuts.com/forums/index.php
//
// Please use that to post up any comments, questions, bug reports, etc.  You
// can also use the board to show off your use of the script.
//
// Support
//
// If you like this script, or any of my others, then please take a moment
// to consider giving a donation.  This will encourage me to make updates and
// create new scripts which I would make available to you.  If you would like
// to donate anything, then there is a link from my website to PayPal.
//
// Andrew Collington, 2003
// php@amnuts.com, http://php.amnuts.com/
//


class madlibs
{
    var 
$useType;
    var 
$dbUser;
    var 
$dbPass;
    var 
$dbHost;
    var 
$dbName;
    var 
$dbTbl;
    var 
$dbID;
    var 
$fsPath;
    var 
$fsExt;
    var 
$inText;
    var 
$outText;
    var 
$tags;
    var 
$tagPositions;


    
//
    // the constructor
    //
    
function madlibs()
    {
        
$this->useType '';
        
$this->tagPositions = array();
        
$this->inText  = array();
        
$this->outText = array();
        
$this->setDefaultTags();
    }

    
//
    // set the default replacement tags
    //
    
function setDefaultTags()
    {
        
$this->tags =
            array(
                
'VERB'            => 'A verb',
                
'VERB-ED'         => 'A verb ending in \'ed\'',
                
'VERB-ING'        => 'A verb ending in \'ing\'',
                
'VERB-S'          => 'A verb ending in \'s\'',
                
'NOUN'            => 'A noun',
                
'NOUN-PLURAL'     => 'A plural noun',
                
'ADJECTIVE'       => 'An adjective',
                
'ADVERB'          => 'An adverb',
                
'EMOTION'         => 'An emotion',
                
'NUMBER'          => 'A number',
                
'PLACE'           => 'The name of a place',
                
'ROOM'            => 'The name of a room',
                
'FOOD'            => 'The name of some food',
                
'MALE'            => 'A man\'s name',
                
'FEMALE'          => 'A woman\'s name',
                
'OPPOSITESEX'     => 'Name of a member of the opposite sex',
                
'SAMESEX'         => 'Name of a member of the same sex',
                
'ANIMAL'          => 'An animal',
                
'ANIMAL-PLURAL'   => 'An animal (plural)',
                
'FUNNY'           => 'Something funny',
                
'BODYPART'        => 'A body part',
                
'BODYPART-PLURAL' => 'A body part (plural)',
                
'CELEBRITY'       => 'The name of a celebrity',
                
'MADEUP'          => 'Just make up a word'
            
);
    }


    
//
    // allows you to add new tags to the list on the fly
    // $name is the tag name, eg, 'VERB'
    // $description is the text displayed to the user, eg, 'A verb'
    //
    
function addTag($name$description)
    {
        
$this->tags[$name] = $description;
        return (
array_key_exists($name$this->tags)) ? TRUE FALSE;
    }


    
//
    // allows you to remove a tag from the tag list on the fly
    // $name is the tag name, eg, 'VERB'
    //
    
function deleteTag($name)
    {
        if (
array_key_exists($name$this->tags))
        {
            
$this->tags[$name] = NULL;
            unset(
$this->tags[$name]);
            return 
TRUE;
        }
        else
        {
            return 
FALSE;
        }
    }


    
//
    // sets the class to use a MySQL database for the story storage area
    // $user is the username used to access to database
    // $pass is the password for the user account
    // $table is the table name that stores the story information
    // $database is the name of the database that contains the $table
    // $host is the host address of the database
    //
    
function useDB($user='username'$pass='password'$table='madlibs'$database='demo'$host='localhost')
    {
        
$this->useType 'db';
        
$this->dbUser  $user;
        
$this->dbPass  $pass;
        
$this->dbHost  $host;
        
$this->dbName  $database;
        
$this->dbTbl   $table;
        
$this->dbID    NULL;

        
$this->dbID = @mysql_connect($this->dbHost$this->dbUser$this->dbPass) or die("Unable to connect to mysql server: {$this->dbHost}");
        @
mysql_select_db($this->dbName$this->dbID) or die("Unable to select database: {$this->dbName}");
    }


    
//
    // sets the class to use the file system for the story storage area
    // $path is the path to the story files
    // $extension is the extensions of the story files, including the period if one is used
    // the name of the file is arbitrary
    //
    
function useFS($path 'stories'$extension '.txt')
    {
        
$this->useType 'fs';
        
$this->fsPath  $path;
        
$this->fsExt   $extension;
    }


    
//
    // loads the story information
    //
    
function getStory()
    {
        if (
$this->useType == 'db')
        {
            
$sql "SELECT * FROM {$this->dbTbl} " .
                    (
$_POST['id'] ? "WHERE id = {$_POST['id']}"ORDER BY RAND() LIMIT 1");
            
$result = @mysql_query($sql$this->dbID);
            if (
mysql_num_rows($result))
            {
                
$data = @mysql_fetch_object($result);
                
$this->inText['id']    = $data->id;
                
$this->inText['title'] = trim(stripslashes($data->title));
                
$this->inText['story'] = trim(stripslashes($data->story));
            }
        }
        else if (
$this->useType == 'fs')
        {
            if (
$_POST['id'])
            {
                
$file basename($_POST['id']);
            }
            else
            {
                
$filelist = array();
                if (
$dir = @opendir($this->fsPath))
                {
                    while ((
$file readdir($dir)) !== FALSE)
                    {
                        if (
$file == '.' || $file == '..') continue;
                        if (
preg_match("/{$this->fsExt}$/"$file))
                        {
                            
$filelist[] = $file;
                        }
                    }
                    
closedir($dir);
                    
srand((float)microtime() * 10000000);
                    
$file $filelist[array_rand($filelist)];
                }
            }

            
$data = array();
            
$data = @file($this->fsPath '/' $file);
            if (!empty(
$data))
            {
                
$this->inText['id']    = $file;
                
$this->inText['title'] = trim(@array_shift($data));
                
$this->inText['story'] = trim(@join(''$data));
            }
        }
    }


    
//
    // displays the madlib
    // if the form hasn't been displayed then it will show the form, else it
    // will show the story complete with madlib sustitutions
    //
    
function displayMadlib()
    {
        
$this->getStory();
        if (!isset(
$_POST['positions']))
        {
            if (
$this->inText['story'])
            {
                
$this->getTagPositions();
                
$this->showForm();
            }
            else
            {
                echo 
'No madlib story has been loaded.';
            }
        }
        else
        {
            if (
$this->inText['story'])
            {
                
$this->decompPositions($_POST['positions']);
                
$this->replaceTags($_POST['word']);
                echo 
'<div class="madlibTitle">'$this->outText['title'], "</div>\n";
                echo 
'<div class="madlibStory">'nl2br($this->outText['story']), "</div>\n";
            }
            else
            {
                echo 
'No madlib story has been loaded.';
            }
        }
    }


    
//
    // displays the form the user's words
    //
    
function showForm()
    {
        echo 
'<form name="madlibForm" action="'$_SERVER['PHP_SELF'], '" method="post">';
        echo 
'<input type="hidden" name="id" value="'urlencode($this->inText['id']), '">';
        echo 
'<input type="hidden" name="positions" value="'$this->compPositions(), '">';
        
        echo 
"<p>Please enter the following:</p>\n";
        echo 
'<table border="0" cellpadding="5" cellspacing="0" class="madlibTable">';
        foreach (
$this->tagPositions as $id => $type)
        {
            echo 
'<tr><td>'$this->tags[$type], '</td><td><input type="textbox" name="word['$id']"></td></tr>'"\n";
        }
        echo 
'<tr><td colspan="2" align="center"><input type="submit" value="see your madlib"></td></tr>';
        echo 
"\n</table>\n</form>\n";
    }


    
//
    // determines where in the tags lie
    //
    
function getTagPositions()
    {
        foreach (
$this->tags as $key => $desc)
        {
            
$positions = array();
            
$tag '{' $key '}';
            
$positions $this->multi_strpos($tag$this->inText['story']);
            if (!empty(
$positions))
            {
                foreach (
$positions as $place)
                {
                    
$this->tagPositions[$place] = $key;
                }
            }
        }
        
ksort($this->tagPositions);
    }
    

    
//
    // does the tag substitution for the finished story
    //
    
function replaceTags($word_list)
    {
        
$this->outText $this->inText;
        if (!empty(
$this->tagPositions))
        {
            
$tags array_reverse($this->tagPositionsTRUE);
            foreach (
$tags as $position => $type)
            {
                
$tag '{' $type '}';
                
$this->outText['story'] = substr_replace($this->outText['story'], '<span class="madlibWord">' $word_list[$position] . '</span>'$positionstrlen($tag));
            }
        }
    }


    
//
    // function to determine multiple occurrences of a word in a string
    // from a post by arduenn at hotpop dot com on the php.net comments
    //
    
function multi_strpos($pattern$sequence)
    {
        
$n = -1;
        while (
ereg($pattern$sequence))
        {
            
$n++;
            
$fragment split($pattern$sequence);
            
$trimsize = (strlen($fragment[0]))+1;
            
$sequence "*".substr($sequence$trimsize);
            
$position[$n] = (strlen($fragment[0]) + $position[($n-1)]);
        }
        return 
$position;
    }


    
//
    // compresses the tag position array for use in a form
    //
    
function compPositions()
    {
        return 
urlencode(base64_encode(serialize($this->tagPositions)));
    }


    
//
    // decompresses the tag information array from a string
    // $positions is the compressed structure
    //
    
function decompPositions($positions)
    {
        
$this->tagPositions unserialize(base64_decode(urldecode($positions)));
    }

}

?>
10.1kb in size
last modified Jan 13, 2009 at 3:05pm
9648 views, 6764 downloads

example-story-beach.txt

An example of a madlib story file if you use the file system instead of MySQL as your story repository area.

386b in size
last modified May 6, 2006 at 9:55pm
6206 views, 5579 downloads

example-story-mall.txt

An example of a madlib story file if you use the file system instead of MySQL as your story repository area.

578b in size
last modified May 6, 2006 at 9:55pm
5507 views, 5341 downloads

schema.sql

An example of the table data for if you decide to use MySQL as your story repository instead of the file system.

1.23kb in size
last modified May 6, 2006 at 9:55pm
5553 downloads

test.madlibs.php

An example use of the madlibs class.

924b in size
last modified May 6, 2006 at 9:55pm
6583 views, 5720 downloads
list all projects :: this project's forum :: script in action
added Sep 3, 2003 at 6:35pm :: updated Sep 3, 2003 at 6:35pm :: 5 files :: 40246 views

© Andrew Collington, 2002-2007.