View file It's Me/main-file/assets/external/simpleCaptcha/simpleCaptcha.php

File size: 5.99Kb
<?php
// This is the handler for simpleCaptcha image requests. The simpleCaptcha 
// answer (hash) is placed in the session along with other data, so session 
// vars are required for this plug-in (hence the seesion_start() call below).
session_start();


// TODO: Rule for porting to another language


// The class (and all requests) are handled at the end of the script
class SimpleCaptcha {

  // ------------------------------------------------- //
  // -------------------- EDIT THESE ----------------- //
  // ------------------------------------------------- //
  // 
  // Note that if they are relative paths, they must be 
  // relative to THIS script!
  private $images = array(
    // NAME          =>  IMAGE_FILE
      'house'        => 'captchaImages/01.png',
      'key'          => 'captchaImages/02.png',
      'flag'         => 'captchaImages/03.png',
      'clock'        => 'captchaImages/04.png',
      'bug'          => 'captchaImages/05.png',
      'pen'          => 'captchaImages/06.png',
      'light bulb'   => 'captchaImages/07.png',
      'musical note' => 'captchaImages/08.png',
      'heart'        => 'captchaImages/09.png',
      'world'        => 'captchaImages/10.png'
  );

  // You should change this for security reasons, 10-20 characters is good
  private $salt = "o^G-j7%8W3xP!2_";

  // ------------------------------------------------- //
  // ------------------- STOP EDITING ---------------- //
  // ------------------------------------------------- //
  // (All other options should be edited in the plugin JavaScript.)



  const MIN_IMAGES = 3;
  const DEFAULT_NUM_IMAGES = 5;
  private $sessionData = null;
  private $answer = null;

  public function __construct() {
    $this->getDataFromSession();

    if (!$this->sessionData) {
      $this->resetSessionData();
    }
  }

  public function resetSessionData() {
    $this->sessionData = array(
      'time'   => time(),
      'images' => array(),
      'salt'   => null
    );
    $this->sessionData['salt'] = $this->salt . $this->sessionData['time'];
  }

  public function getImageByHash($hash) {
    if (isset($this->sessionData['images'][$hash])) {
      $fn = $this->sessionData['images'][$hash];

      if (file_exists($fn)) {
        $mime = null;
        if (function_exists("finfo_open")) {
          // PHP 5.3
          $finfo = finfo_open(FILEINFO_MIME_TYPE);
          $mime = finfo_file($finfo, $fn);

        } else if (function_exists("mime_content_type")) {
          // PHP 5.2
          $mime = mime_content_type($fn);
        }

        if (!$mime) { $mime = "image/png"; }

        header("Content-Type: {$mime}");
        readfile($fn);
        exit;

      } else {
        throw new InvalidArgumentException("That captcha image file does not exist", 404);
      }
    } else {
      throw new InvalidArgumentException("No captcha image exists with that hash: ".json_encode($this->sessionData->images), 404);
    }
  }

  public function getAllImageData() {
    $iData = array(
      'text'   => '',
      'images' => array()
    );

    if (!isset($this->images) || !is_array($this->images) || sizeof($this->images) < SimpleCaptcha::MIN_IMAGES) {
      throw new InvalidArgumentException("There aren\'t enough images on the server!", 400);
    }

    $numImages = SimpleCaptcha::DEFAULT_NUM_IMAGES;
    if (isset($_REQUEST['numImages']) && 
        intval($_REQUEST['numImages']) && 
        intval($_REQUEST['numImages']) > SimpleCaptcha::MIN_IMAGES) {
      $numImages = intval($_REQUEST['numImages']);
    }
    $totalSize = sizeof($this->images);
    $numImages = min(array($totalSize, $numImages));
    
    $keys = array_keys($this->images);
    $used = array();
    
    mt_srand(((float) microtime() * 587) / 33); // add some randomness

    for ($i=0; $i<$numImages; ++$i) {
      $r = rand(0, $totalSize-1);
      while (array_search($keys[$r], $used) !== false) {
        $r = rand(0, $totalSize-1);
      }
      array_push($used, $keys[$r]);
    }
    
    $iData['text'] = $used[rand(0, $numImages-1)];
    $this->answer = sha1($iData['text'] . $this->sessionData['salt']);

    shuffle($used);

    for ($i=0; $i<sizeof($used); ++$i) {
      $hash = sha1($used[$i] . $this->sessionData['salt']);
      array_push($iData['images'], $hash);
      $this->sessionData['images'][$hash] = $this->images[$used[$i]];
    }

    return $iData;
  }


  public function writeSessionData() {
    $_SESSION['simpleCaptchaAnswer'] = $this->answer;
    $_SESSION['simpleCaptchaData'] = json_encode($this->sessionData);
    // And for backward compatibility...
    $_SESSION['simpleCaptchaTimestamp'] = $this->sessionData['time'];
  }

  public function getDataFromSession() {
    if (isset($_SESSION['simpleCaptchaData'])) {
      $this->sessionData = json_decode($_SESSION['simpleCaptchaData'], true);
    }
    if (isset($_SESSION['simpleCaptchaAnswer'])) {
      $this->answer = $_SESSION['simpleCaptchaAnswer'];
    }
  }


  // Static helper methods

  public static function getProtocol() {
    $protocol = "HTTP/1.1";
    if(isset($_SERVER['SERVER_PROTOCOL'])) {
      $protocol = $_SERVER['SERVER_PROTOCOL'];
    }
    return $protocol;
  }

}


// ------------------- Handle Incoming Requests ------------------- //

$sc = new SimpleCaptcha();
try {

  if (isset($_REQUEST['hash'])) {
    // Just getting one image file by it's hash
    $sc->getImageByHash($_REQUEST['hash']);

  } else {
    // Getting all image data and hashes
    $sc->resetSessionData();
    $imageData = $sc->getAllImageData();

    // Finish up by writing data to the session and the ouput buffer
    $sc->writeSessionData();
    header("Content-Type: application/json");
    echo json_encode($imageData);
  }

} catch (InvalidArgumentException $iae) {
  $code = $iae->getCode();
  if (!$code) { $code = 400; }
  header(SimpleCaptcha::getProtocol()." {$code} ".$iae->getMessage());
  echo $iae->getMessage();

} catch (Exception $e) {
  $code = $e->getCode();
  if (!$code) { $code = 500; }
  header(SimpleCaptcha::getProtocol()." {$code} ".$e->getMessage());
  echo $e->getMessage();
}

exit; // make sure we stop the script
?>