<?php

##
## Copyright (c) 1998-2000 NetUSE AG
##                    Boris Erdmann, Kristian Koehntopp
##
## Copyright (c) 1998-2000 Sascha Schumann <sascha@schumann.cx>
##
## $Id: ct_sql.inc 28 2008-05-11 19:18:49Z mistral $
##
## PHPLIB Data Storage Container using a SQL database
##

class CT_Sql {
  ##
  ## Define these parameters by overwriting or by
  ## deriving your own class from it (recommened)
  ##

  var $database_table = "active_sessions";
  var $database_class = "DB_Sql";
  var $database_lock_semaphore = "";

  var $encoding_mode = "base64";

  ## end of configuration

  var $db;

  function ac_start() {
    $name = $this->database_class;
    $this->db = new $name;
  }

  function ac_get_lock() {
    if ( "" != $this->database_lock_semaphore ) {
      $query = sprintf("SELECT get_lock('%s')", $this->database_lock_semaphore);
      while ( ! $this->db->query($query)) {
        $t = 1 + time(); while ( $t > time() ) { ; }
      }
    }
  }

  function ac_release_lock() {
    if ( "" != $this->database_lock_semaphore ) {
      $query = sprintf("SELECT release_lock('%s')", $this->database_lock_semaphore);
      $this->db->query($query);
    }
  }

  function ac_gc($gc_time, $name) {
	global $cms_db;

    $timeout = time();
    $sqldate = date("YmdHis", $timeout - ($gc_time * 60));
    $this->db->query(sprintf("DELETE FROM %s WHERE changed < '%s' AND name = '%s'",
                    $cms_db[sessions],
                    $sqldate,
                    addslashes($name)));
  }

  function ac_store($id, $name, $str) {
	global $cms_db, $auth;

    $ret = true;

    switch ( $this->encoding_mode ) {
      case "slashes":
        $str = addslashes($name . ":" . $str);
      break;

      case "base64":
      default:
        $str = base64_encode($name . ":" . $str);
    };

    $name = addslashes($name);

    ## update duration of visit
    //todo HTTP_* remove
    //global $HTTP_REFERER, $HTTP_USER_AGENT, $REMOTE_ADDR;

    $ret = true;
    $now = date("YmdHis", time());
    $uquery = sprintf("update %s set val='%s', changed='%s', user_id='%s' where sid='%s' and name='%s'",
      $cms_db['sessions'],
      $str,
      $now,
      $auth->auth['uid'],
      $id,
      $name);
    $squery = sprintf("select count(*) from %s where val='%s' and changed='%s' and sid='%s' and name='%s'",
      $cms_db['sessions'],
      $str,
      $now,
      $id,
      $name);
    $iquery = sprintf("insert into %s ( sid, name, val, changed, user_id) values ('%s', '%s', '%s', '%s', '%s')",
      $cms_db['sessions'],
      $id,
      $name,
      $str,
      $now,
      $auth->auth['uid']);

    $this->db->query($uquery);

    # FIRST test to see if any rows were affected.
    #   Zero rows affected could mean either there were no matching rows
    #   whatsoever, OR that the update statement did match a row but made
    #   no changes to the table data (i.e. UPDATE tbl SET col = 'x', when
    #   "col" is _already_ set to 'x') so then,
    # SECOND, query(SELECT...) on the sid to determine if the row is in
    #   fact there,
    # THIRD, verify that there is at least one row present, and if there
    #   is not, then
    # FOURTH, insert the row as we've determined that it does not exist.

    if ( $this->db->affected_rows() == 0
        && $this->db->query($squery)
	&& $this->db->next_record() && $this->db->f(0) == 0
        && !$this->db->query($iquery)) {
        // now we have an error
        $ret = false;
    }
    return $ret;
  }

  function ac_delete($id, $name) {
    global $cms_db;

	$this->db->query(sprintf("delete from %s where name = '%s' and sid = '%s'", $cms_db[sessions], addslashes($name), $id));
  }

  function ac_get_value($id, $name) {
	global $cms_db;
    $this->db->query(sprintf("select val from %s where sid  = '%s' and name = '%s'",
      $cms_db['sessions'],
      $id,
      addslashes($name)));
    if ($this->db->next_record()) {
      $str  = $this->db->f("val");
      $str2 = base64_decode( $str );

      if ( ereg("^".$name.":.*", $str2) ) {
         $str = ereg_replace("^".$name.":", "", $str2 );
      } else {

        $str3 = stripslashes( $str );

        if ( ereg("^".$name.":.*", $str3) ) {
          $str = ereg_replace("^".$name.":", "", $str3 );
        } else {

          switch ( $this->encoding_mode ) {
            case "slashes":
              $str = stripslashes($str);
            break;

            case "base64":
            default:
              $str = base64_decode($str);
          }
        }
      };
      return $str;
    };
    return "";
  }

  // Must be overridden by user.
  function ac_newid($str, $name) {
    return $str;
  }

  function ac_halt($s) {
    $this->db->halt($s);
  }
}
?>
