Subversion Repositories PHPX

Rev

Rev 27 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

1
<?php

require_once __LIB__ . '/../global.inc';

/* NOTE: Obsolete with autoloader */
//require_once 'Zend/Registry.php';
//require_once 'Zend/Db/Table.php';

/**
 * @property-read array $lastId The last generated ID
 * @property-read array $result The result of the last query
 *
 * @author rvejseli, tlahn
 */

class Database
{
  private $db_host = DB_HOST;
  private $db_user = DB_USER;
  private $db_pass = DB_PASS;
  private $db_name = DB_NAME;

  private $connection = false;
  private $_result = array();

  /**
   * The last inserted ID
   *
   * @var int
   */

  private $_lastId;

  /* Anlegen der Instanz */
  private static $instance = NULL;

  /* Konstruktor private, damit die Klasse nur aus sich selbst heraus instanziiert werden kann. */
  private function __construct()
  {
    $this->connect();
    $this->_resetLastID();
  }

  /**
   * Returns a singleton Database instance
   * @return Database
   */

  public static function getInstance()
  {
    if (self::$instance === NULL)
    {
      self::$instance = new self;
    }

    return self::$instance;
  }

  /* Klonen per 'clone()' von aussen verbieten. */
  private function __clone() {}

  /**
   * Universal getter
   *
   * @param string $name
   */

  public function __get($name)
  {
    switch ($name)
    {
      case 'lastId':
      case 'result':
        return $this->{"_$name"};
    }
  }

  /**
   * Connects to the Database
   */

  public function connect()
  {
    if (!$this->connection)
    {
      $myconn = @mysql_connect($this->db_host, $this->db_user, $this->db_pass);
      if ($myconn)
      {
        $seldb = @mysql_select_db($this->db_name, $myconn);
        if ($seldb)
        {
          $this->connection = true;
          return true;
        }
        else
        {
          return false;
        }
      }
      else
      {
        return false;
      }
    }
    else
    {
      return true;
    }
  }

  /**
   * Resets the last ID to a default value, indicating that no rows where inserted
   */

  private function _resetLastID()
  {
    $this->_lastId = -1;
  }

  public function setDatabase($name)
  {
    if ($this->connection)
    {
      if (@mysql_close())
      {
        $this->connection = false;
        $this->_result = null;
        $this->db_name = $name;
        $this->connect();
      }
    }
  }

  /**
   * Makes an encoding-safe database query
   *
   * @param string $query
   * @param string encoding
   *   The encoding in which the query result should be returned from the DBMS.
   *   The default is 'utf8'.
   * @return resource|null
   *   The query result if successful, <code>null</code> otherwise
   */

  private function _query($query, $encoding = 'utf8')
  {
    $this->_resetLastID();

    if (mysql_query("SET CHARACTER SET $encoding"))
    {
      if (DEBUG > 1)
      {
        echo "<pre>$query</pre>";
      }

      return @mysql_query($query);
    }
    else
    {
      /* DEBUG */
      echo mysql_errno() . ':' . mysql_error();
      exit;
    }

    return null;
  }

  private function _tableExists($table)
  {
    $tablesInDb = $this->_query("SHOW TABLES FROM {$this->db_name} LIKE '{$table}'");
    if ($tablesInDb)
    {
      if (mysql_num_rows($tablesInDb) == 1)
      {
        return true;
      }
      else
      {
        return false;
      }
    }
  }
 
  /**
   * Determines if an array is associative (does not have a '0' key)
   *
   * @param array $a
   * @return boolean
   *   <code>true</code> if <var>$a</var> is associative,
   *   <code>false</code> otherwise
   */

  private function _isAssociativeArray(array $a)
  {
    return !array_key_exists(0, $a);
  }

  /**
   * Escapes an associative array so that its string representation can be used
   * in a query.
   *
   * NOTE: Intentionally does not check whether the array actually is associative!
   *
   * @param array &$array
   *   The array to be escaped
   * @return array
   *   The escaped array
   */

  private function _escapeArray(array &$array)
  {
    foreach ($array as $column => &$value)
    {
      if (is_string($value))
      {
        $value = mysql_real_escape_string($value);
      }

      $value = "`" . mysql_real_escape_string($column) . "`='{$value}'";
    }
   
    return $array;
  }
 
  /**
   * Constructs the WHERE part of a query
   *
   * @param string|array $where Condition
   * @return string
   */

  private function _where($where)
  {
    if (!is_null($where))
    {
      if (is_array($where))
      {
        if (count($where) < 1)
        {
          return '';
        }
       
        if ($this->_isAssociativeArray($where))
        {
          $this->_escapeArray($where);
        }

        $where = '(' . join(') AND (', $where) . ')';
      }

      return ' WHERE ' . $where;
    }
   
    return '';
  }
 
  /**
   * Selects data from one or more tables; the resulting records are stored
   * in the <code>result</code> property.
   *
   * @param string|array[string] $tables Table(s) to select from
   * @param string|array[string] $columns Column(s) to select from (optional)
   * @param string|array $where Condition (optional)
   * @param string $order Sort order (optional)
   * @param string $limit Limit (optional)
   * @return bool
   * @throws <code>Exception</code> if the query fails
   */

  public function select($tables, $columns = null, $where = null, $order = null, $limit = null)
  {
    $this->_result = array();

    if (is_null($columns))
    {
      $columns = array('*');
    }
   
    if (!is_array($columns))
    {
      $columns = array($columns);
    }

    $columns = join(',', $columns);
   
    if (!is_array($tables))
    {
      $tables = array($tables);
    }

    $tables = join(',', $tables);

    $q = "SELECT $columns FROM $tables" . $this->_where($where);

    if (!is_null($order))
    {
      $q .= " ORDER BY $order";
    }

    if (!is_null($limit))
    {
      $q .= " LIMIT $limit";
    }
   
    if (DEBUG > 1)
    {
      echo "<pre>$q</pre>";
    }

    /* DEBUG */
//    debug($q);

    $_result = $this->_query($q);
    if ($_result)
    {
      $this->numResults = mysql_num_rows($_result);
      for ($i = 0, $len = $this->numResults; $i < $len; ++$i)
      {
        $_results = mysql_fetch_array($_result);

        /* DEBUG */
        //        debug($_results);

        $keys = array_keys($_results);
        foreach ($keys as $key)
        {
          if (!is_int($key))
          {
            if (mysql_num_rows($_result) > 0)
            {
              $this->_result[$i][$key] = $_results[$key];
            }
            else if (mysql_num_rows($_result) < 1)
            {
              $this->_result = null;
            }
          }
        }
      }

      return $q;
    }
    else
    {
      throw new Exception(mysql_error() . ". Query: " . $q);
    }
  }

  /**
   * Inserts a record into a table.<p>The AUTO_INCREMENT value of the inserted
   * row, if any (> 0), is stored in the {@link $lastId} property of
   * the <code>Database</code> instance.</p>
   *
   * @param string $table
   *   Table name
   * @param array|string $values
   *   Associative array of column-value pairs, indexed array,
   *   or comma-separated list of values.  If <var>$values</var> is not
   *   an associative array, <var>$cols</var> must be passed if the
   *   values are not in column order (see below).
   * @param array|string $cols
   *   Indexed array, or comma-separated list of column names.
   *   Needs only be passed if <var>$values</var> is not an associative array
   *   and the values are not in column order (default: <code>null</code>);
   *   is ignored otherwise.  <strong>You SHOULD NOT rely on column order.</strong>
   * @return bool
   *   <code>true</code> if successful, <code>false</code> otherwise
   */

  public function insert($table, $values, $cols = null)
  {
    if ($cols != null)
    {
      $cols = ' ('
      . (is_array($cols)
      ? join(',', array_map(create_function('$s', 'return "`$s`";'), $cols))
      : $cols) . ')';
    }
    else
    {
      $cols = '';
    }

    /* DEBUG */
    //          debug($values);

    if ($this->_isAssociativeArray($values))
    {
      $this->_escapeArray($values);

      $cols = '';
      $values = 'SET ' . join(', ', $values);
    }
    else
    {
      foreach ($values as &$value)
      {
        if (is_string($value))
        {
          $value = "'" . mysql_real_escape_string($value) . "'";
        }
      }
       
      $values = ' VALUES (' . join(', ', $values) . ')';
    }

    $insert = "INSERT INTO `{$table}` {$cols} {$values}";

    /* DEBUG */
//    echo "Insert:<br>";
//    debug($insert);

    $ins = $this->_query($insert);
    $this->_lastId = mysql_insert_id();

    if ($ins)
    {
      return true;
    }
    else
    {
      return false;
    }
  }

  /**
   * Deletes records from a table
   *
   * @param string $table
   * @param string|array|null $where  Condition for deletion
   * @return bool
   */

  public function delete($table, $where = null)
  {
    $delete = "DELETE FROM `{$table}`" . $this->_where($where);

    /* DEBUG */
                // debug($delete);
    // $result = true;

    $result = $this->_query($delete);

    return ($result) ? true : false;
  }

  /**
   * Updates one or more records
   *
   * @param string|array $tables
   *   Table name
   * @param array $values
   *   Associative array of column-value pairs
   * @param array|string $where
   *   Only the records matching this condition are updated
   * @return string|bool
   */

  public function update($tables, $updates, $where = null)
  {
    if (!$tables)
    {
      throw new InvalidArgumentException('No table specified');
    }
     
    if (is_array($tables))
    {
      $tables = join(',', $tables);
    }
     
    if (!$updates)
    {
      throw new InvalidArgumentException('No values specified');
    }
     
    $updates = join(',', $this->_escapeArray($updates));
         
    $query = "UPDATE {$tables} SET {$updates}" . $this->_where($where);
   
    /* DEBUG */
//    echo "Update:<br>";
//    debug($query);
   
    $_result = $this->_query($query);

    if (!$_result)
    {
      //debug(mysql_error());
      return false;
    }

    return $query;
  }

  /**
   * Inserts a row into a table or updates an existing one
   *
   * @param string $sTable
   *   Table name
   * @param array $aValues
   *   Associative array of column-value pairs to be updated/inserted
   * @param string|array $condition
   *   If there are no records matching this condition, a row will be inserted;
   *   otherwise matching records are updated
   * @return mixed
   */

  public function updateOrInsert($sTable, $aValues, $condition)
  {
    $result = $this->select($sTable, '*', $condition);
    if (!$result)
    {
      exit;
    }

    //    debug($this->result);
    if (count($this->result) > 0)
    {
      $result = $this->update($sTable, $aValues, $condition);
    }
    else
    {
      $result = $this->insert($sTable, $aValues);
    }

    return $result;
  }

  /**
   * @see Database::updateOrInsert()
   */

  public function insertOrUpdate($sTable, $aValues, $condition)
  {
    return $this->updateOrInsert($sTable, $aValues, $condition);
  }

  public function getResult()
  {
    return $this->result;
  }
}
?>