Location: PHPKode > scripts > Cell CAPTCHA > cell-captcha/cellCaptcha.php
<?php
/**
* cellCaptcha File
* Generates CAPTCHA using Table Cells
* @author Kevin Matory <hide@address.com>
* @version 1.0
* GNU General Public License (Version 2.1, March 7th, 2006)
*
* This program is free software; you can redistribute
* it and/or modify it under the terms of the GNU
* General Public License as published by the Free
* Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/*
  1. $c->fillColor = '#000': Set the cell background color or
     $c->fillContent = '*' : fill it with some content.

  2. Set cell width and height (in pixels) $c->cellW = 4, $c->cellH = 4
  3. $c->setMessage() : Set the message. If left empty, a random string
     of characters will be generated ( $c->randCharLen : default 5) characters long.

  4. echo $c->draw() : Output to the screen.

  The other variables are up to you if you wish to use. This class
  is simple enough that you can alter to your liking.

*/

class cellCaptcha {

      public $finalMsgArray = array();
      public $gotLower = true;  //If your font contains lowercase letters, the default does
      public $randomColor = false; //Do you want to use a random color for the positive captcha cells
      public $randomBGColor = false; //If you want a random background color
      public $verifyCaseSensative = true; //Self-explanitory
      public $useLetterSpacing = false; //Do you want to use letter spacing. Your font may already be spaced.
      public $letterSpacing = 1; //How much spacing (cell) you want to use between each letter 1 = 1 cell/td

      public $useWordSpacing = true; //Use word spacing?
      public $wordSpacing = 6;       //How many cells in between each word

      public $attributesArray = array(); //For whatever attributes you set

      public $fillColor = '#000000'; //Fill Color for positive cells
      public $fillContent = '';  //To put content in positive cell

      public $negFillColor = 'transparent'; //If you want the negative cells to be something other than transparent
      public $negativeContent = '';         //If for some reason you want content negative cells

      public $rows;
      public $randCharLen = 5; //For random characters generated for captcha
      public $cellH = 6;  //cell height (which is actually a div inside a td)
      public $cellW = 4;  //cell width
      public $tblBorderSize = 0; //self-explanatory
      public $cellpadding = 0;  //self-explanatory
      public $cellspacing = 1;  //self-explanatory

      /* attributes */
      public $tblBGColor = 'transparent'; //table background color
      public $tblClassName = 'cellCaptcha'; //table classname
      public $tblID = 'cellCaptcha'; //table classname
      public $tblTitle = 'Please type the letters you see'; //self-explanatory
      public $tblSummary = ''; //self-explanatory

      /*
      + Add more style content. Don't includ the style= or any quotes.
        The same goes for for $addedPostCellStyle, $addedNegCellStyle
      */
      public $addedTableStyle = 'border:1px solid #ffffff;';
      public $tblBGPicUrl = ''; //if you want to add a background pic to table - uses css

      public $addedPosCellStyle = 'border-left:1px solid #000000;'; //+ if you want to add more style
      public $addedNegCellStyle = 'border-left:1px solid #000000;'; //+ if you want to add more style

      /*
        The next 2 are somewhat wildcard items. Add a class or id or whatever as a string.
        example: $xx->posClassName = someClassName';
      */
      public $posClassName = '';
      public $negClassName = '';




function cellCaptcha($chars,$matrix){
         $this->chars = $chars;
         $this->matrix = $matrix;
         if( !is_array($chars) || !count($chars) ) die('Argument 1 should be an array and should not be empty!');
         if( !is_array($matrix) || !count($matrix) ) die('Argument 2 should be an array and should not be empty!');
}

//This is a random password gen I got off the net somewhere
private function randomChar($len = 8)
{       if(is_numeric($this->randCharLen)) $len = $this->randCharLen;
        $vowels = array('a', 'e', 'i', 'o', 'u', 'y');
        $confusing = array('I', 'l', '1', 'O', '0');
        $replacements = array('A', 'k', '3', 'U', '9');
        $choices = array(0 => rand(0, 1), 1 => rand(0, 1), 2 => rand(0, 2));
        $parts = array(0 => '', 1 => '', 2 => '');

        if ($choices[0]) $parts[0] = rand(1, rand(9,99));
        if ($choices[1]) $parts[2] = rand(1, rand(9,99));

        $len -= (strlen($parts[0]) + strlen($parts[2]));
        for ($i = 0; $i < $len; $i++)
        {
                if ($i % 2 == 0)
                {
                        do $con = chr(rand(97, 122));
                        while (in_array($con, $vowels));
                        $parts[1] .= $con;
                }
                else
                {
                        $parts[1] .= $vowels[array_rand($vowels)];
                }
        }
        if ($choices[2]) $parts[1] = ucfirst($parts[1]);
        if ($choices[2] == 2) $parts[1] = strrev($parts[1]);

        $r = $parts[0] . $parts[1] . $parts[2];
        $r = str_replace($confusing, $replacements, $r);

        return $r;
}


/*
  RANDOM COLOR GENERATOR 3
*/
private function random_color(){
    mt_srand((double)microtime()*1000000);
    $c = '';
    while(strlen($c)<6){
        $c .= sprintf("%02X", mt_rand(0, 255));
    }
    return '#'.$c;
}

public function verifyCaptcha($userText){
            $userText = trim($userText);
              if( $this->verifyCaseSensative )
                  return ( strcmp($_SESSION['captchaText'], $userText) === 0 );
                else
                  return ( strcasecmp($_SESSION['captchaText'], $userText) === 0 );

}

//instead of multi-level arrays, accumulate bits into rows
//of strings that spell out the word
public function setMessage($msg='') {

    $msg = trim($msg);
    if( !strlen($msg) ) $msg = $this->randomChar();
    if( !$this->gotLower ) $msg = strtoupper($msg);
    $maxRows = 0;
    $columnCounts = array();
    $characters = str_split($msg);
    foreach($characters as $char){
            $char = trim($char);
            $count = count($this->chars[$char]);
            if( $count > $maxRows ) $maxRows = $count;
            $column = $this->matrix[ $this->chars[$char][0] ];
            $columnCounts[ $char ] = strlen($column);

    }

    $bits = '';
    $numZeros = '';
      for($j=0;$j<$maxRows;$j++){
          for($i=0;$i<count($characters);$i++){
              $currChar = trim($characters[$i]); //trim the character

                /*
                  If there is no strlen, then this is whitespace.
                  Assuming a break between words.
                */
                if( !strlen($currChar) && $this->useWordSpacing){
                    $bits .= str_repeat('0',$this->wordSpacing);
                    continue;
                }else{
                       /*
                        Retrieve the array associated with this
                        character. $currLetter is an array
                       */
                       $currLetter = $this->chars[$currChar];

                       /*
                         $tmp is a string. $currLetter[ $j ] is
                         the VALUE of the $j index in the $currLetter
                         array. The Value is a number representing
                         which string in the matrix to return that
                         will be a part of building the HTML "graphic"
                         for that character.
                       */
                       $tmp = $this->matrix[ $currLetter[$j] ];
                     }
                     /*
                       If $tmp is not a string, then fill with zeros (whitespace).
                       It's probably reached more rows than this letter has.
                       The characters in the font I built all have differing
                       number of rows and columns.
                     */
                     if( !strlen($tmp) ){
                       $bits .= str_repeat('0',$columnCounts[$currChar]);

                     }else
                       $bits .= $tmp;

                     /* if you need to add space between the letters */
                     if( $this->useLetterSpacing ) $bits .= str_repeat('0',$this->letterSpacing);

              }

        $this->finalMsgArray[ ] = $bits;
        $bits = '';
      }

    if( !isset($_SESSION) ) session_start();
    $_SESSION['captchaText'] = $msg;

   return $this->finalMsgArray;
}

public function draw($finalMsgArray='') {

  $this->tblBGPicUrl = trim($this->tblBGPicUrl);
  $this->tblBGColor = trim($this->tblBGColor);

  if( is_array($finalMsgArray) && count($finalMsgArray) ) $this->finalMsgArray = $finalMsgArray;
  if($this->randomColor || !strlen( trim($this->fillColor) ) ) $this->fillColor = $this->random_color();

  $matrix = "\n".'<table align="center" border="'.$this->tblBorderSize.'" cellpadding ="'.$this->cellpadding
            .'" cellspacing="'.$this->cellspacing.'"'."\n";

  $tableStyle = array();
  $tblStyle = '';

  if( strlen($this->tblBGPicUrl) ) $tableStyle[ ] = 'background-image:url('.$this->tblBGPicUrl.');';
   elseif( strlen($this->tblBGColor) )  $tableStyle[ ] = 'background-color:'.$this->tblBGColor.';';
    elseif($this->randomBGColor) $tableStyle[ ] = 'background-color:'.$this->random_color().';';

  if( count($tableStyle) ) $tblStyle = implode('',$tableStyle);
  if( strlen($this->addedTableStyle) ) $tblStyle .= $this->addedTableStyle;
  if( strlen($tblStyle) ) $matrix .= ' style="'.$tblStyle.'"';

  $PCN = trim($this->posClassName);
  $NCN = trim($this->negClassName);

  $this->tblTitle = trim($this->tblTitle);
  if( strlen($this->tblTitle) ) $matrix .= ' title="'.$this->tblTitle.'"';

  $this->tblSummary = trim($this->tblSummary);
  if( strlen($this->tblSummary) ) $matrix .= ' title="'.$this->tblSummary.'"';

  $this->tblClassName = trim($this->tblClassName);
  if(strlen($this->tblClassName)) $matrix .= ' class="'.$this->tblClassName.'"';

  $this->tblID = trim($this->tblID);
  if(strlen($this->tblID)) $matrix .= ' id="'.$this->tblID.'"';

  $matrix .= '>';

  $x=0; $y=0;
   foreach($this->finalMsgArray as $line){
     $cells = str_split($line);
       foreach($cells as $cell){
             if($cell){
			        $column .= "\n".'<td><div id="x'.$x.'y'.$y.'" style="width:'
                               .$this->cellW.'px;height:'.$this->cellH.'px;background: '
                               .$this->fillColor.';text-align:center;';

                    $this->addedPosCellStyle = trim($this->addedPosCellStyle);
                    if( strlen($this->addedPosCellStyle) ) $column .= $this->addedPosCellStyle;
                    $column .= '"';
                    if( strlen($PCN) ) $column .= ' class="'.$PCN.'"';
                    $column .= '>'.$this->fillContent.'</div></td> ';

              }else{
			        $column .= "\n".'<td><div id="x'.$x.'y'.$y.'" style="width:'
                               .$this->cellW.'px;height:'.$this->cellH.'px;background: '
                               .$this->negFillColor.';text-align:center;';

                    $this->addedNegCellStyle = trim($this->addedNegCellStyle);
                    if( strlen($this->addedNegCellStyle) ) $column .= $this->addedNegCellStyle;
                     $column .= '"';
                    if( strlen($NCN) ) $column .= ' class="'.$NCN.'"';
                    $column .= '>'.$this->negativeContent.'</div></td> ';

                   }
              $x++;
           }

      $row .= "\n".'<tr>'.$column."\n".'</tr> ';
      $y++;
      $column = '';
   }

  return $matrix.$row.'</table>'."\n";
}

}//end of cellCaptcha class
?>
Return current item: Cell CAPTCHA