classes/bfw/Database.php
changeset 0 4869aea77e21
new file mode 100644
--- /dev/null
+++ b/classes/bfw/Database.php
@@ -0,0 +1,438 @@
+<?php
+
+namespace bfw {
+
+    /**
+     * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
+     *
+     */
+    class Database implements DBInterface {
+        private static $logger = null;
+
+        private $link;
+        private static $handle = null;
+
+        private function __construct() {
+            self::$logger = \Logger::getLogger('__CLASS__');
+
+            $this->link = mysqli_connect($host = 'localhost', $user = 'ticketsystem', $password = 'ticketsystem', $database = 'ticketsystem');
+            mysqli_set_charset($this->link, 'utf8');
+        }
+
+        /**
+         * <b>Liefert das Singleton-Pattern der Datenbank-Schicht</b>
+         *
+         * Es existiert in einem Lauf, einem Scope, immer nur ein DB-Handle zur gleichen Zeit.
+         *
+         * Damit das ganze vernünftig flutscht, muss man natürlich berücksichtigen, dass ein SP state-lastig ist!
+         *
+         * Definition des States: Ein Abfrageergebnis stellt solange den State des SP da, bis eine neue Abfrage
+         * einen neuen State erzeugt.
+         *
+         * @return Database|null
+         */
+        public static function getInstance() {
+            if (self::$handle == null) {
+                self::$handle = new Database();
+            }
+
+            return self::$handle;
+        }
+
+        /**
+         * <b>Std-Abfrage Methode der DB-Klasse</b>
+         *
+         * Das übergebene SQL-Statement wird als assoziatives, ein-oder mehrdimensionales Array zurück geliefert.
+         *
+         * array = (
+         *     'id' => 1,
+         *     'name' => 'Ticket',
+         * );
+         *
+         * @param $sql
+         * @return array|null
+         */
+        public function query($sql) {
+            self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
+
+            $result = mysqli_query($this->link, $sql);
+
+            if ($result == false) {
+                return null;
+            }
+
+            if ($result->num_rows == 0) {
+                return null;
+            }
+
+            $rows = array();
+            while (($row = $result->fetch_assoc())) {
+                $rows[] = $row;
+            }
+
+
+            return $rows;
+        }
+
+        /**
+         * <b>Abfragen, die kein ResultSet zurück liefern</b>
+         *
+         * SQL-Statements, die nur TRUE oder FALSE zurück liefern,
+         * müssen per EXECUTE ausgeführt werden.
+         *
+         * @param $sql
+         * @return bool|mysqli_result
+         */
+        public function execute($sql) {
+            self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
+
+            $result = mysqli_query($this->link, $sql);
+
+            return $result;
+        }
+
+        /**
+         * <b>Die einfache Fetch-Methode für das Table-Row-Pattern</b>
+         *
+         * Es wird ein SQL Statement bezogen auf die aktuelle Tabelle zusammen
+         * gebaut. Dieses kann optional eine WHERE clause beinhalten.
+         *
+         * @param $table
+         * @param string $cond
+         * @return array|null
+         */
+        public function fetch($table, $cond = 'id > 1') {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
+
+            $sql = "
+            SELECT
+                *
+            FROM
+              $table
+            WHERE
+              $cond
+        ";
+
+            $result = mysqli_query($this->link, $sql);
+
+            if ($result == false) {
+                return null;
+            }
+
+            return $result->fetch_assoc();
+        }
+
+        /**
+         * <b>Die multiple Fetch-Methode für das Table-Row-Pattern</b>
+         *
+         * Der Rückgabewert ist ein Array mit allen Zeilen als assoziatives Array
+         *
+         * @param $table
+         * @param string $cond
+         * @return array|null
+         */
+        public function fetchAll($table, $cond = 'id > 0') {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
+
+            $sql = sprintf("
+            SELECT
+              *
+            FROM
+              `%s`
+            WHERE
+              %s
+        ", $table, $cond);
+
+            return $this->query($sql);
+        }
+
+        /**
+         * <b>Die einfache Find-Methode für das Table-Row-Pattern</b>
+         *
+         * Der Rückgabewert ist entweder die Tabellenzeile 'id' oder null
+         * im assoziativen Array.
+         *
+         * @param $table
+         * @param $id
+         * @return array|null
+         */
+        public function find($table, $id) {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
+
+            $sql = sprintf("
+            SELECT
+              *
+            FROM
+              `%s`
+            WHERE
+              `id` = %d
+        ", $table, $id);
+
+            $result = mysqli_query($this->link, $sql);
+
+            if ($result == false) {
+                return null;
+            }
+
+            return $result->fetch_assoc();
+        }
+
+        /**
+         * <b>Die multiple Find-Methode für das Table-Row-Pattern</b>
+         *
+         * Es liefert alle Reihen als assoziatives Array zurück.
+         *
+         * @param $table
+         * @return array|null
+         */
+        public function findAll($table, $sys_id = 1) {
+            self::$logger->info(sprintf('%s(%s) ', __METHOD__, $table));
+
+            $sql = sprintf("
+            SELECT
+              *
+            FROM
+              `%s`
+            WHERE
+              `id` > %d
+        ", $table, $sys_id);
+
+            return $this->query($sql);
+        }
+
+        /**
+         * <b>Liefert ein Resultset bezogen auf ein bestimmtes Feld zurück</b>
+         *
+         * @param $table
+         * @param $field
+         * @param $value
+         * @return array|null
+         */
+        public function findByField($table, $field, $value) {
+            self::$logger->info(sprintf('%s(%s, %s, %s) ', __METHOD__, $table, $field, $value));
+
+            $sql = sprintf("
+            SELECT
+              *
+            FROM
+              `%s`
+            WHERE
+              `%s` = '%s'
+        ", $table, $field, $value);
+
+            $result = mysqli_query($this->link, $sql);
+
+            if ($result == false) {
+                return null;
+            }
+
+            return $result->fetch_assoc();
+        }
+
+        /**
+         * <b>Liefert mehrere Resultsets bezogen auf ein bestimmtes Feld zurück</b>
+         *
+         * @param $table
+         * @param $field
+         * @param $value
+         * @return array|null
+         */
+        public function findAllByField($table, $field, $value) {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $field));
+
+            $sql = sprintf("
+            SELECT
+              *
+            FROM
+              `%s`
+            WHERE
+              `%s` = '%s'
+        ", $table, $field, $value);
+
+            return $this->query($sql);
+        }
+
+        /**
+         * <b>Die Standard Persist Methode erstellt einen neuen DB-Eintrag in der angegebenen Tabelle</b>
+         *
+         * @param $table
+         * @param $array
+         * @return bool|mysqli_result
+         */
+        public function persist($table, $array) {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, print_r($array, true)));
+
+            $keys = array();
+            foreach (array_keys($array) as $key) {
+                if ($key != 'id') {
+                    $keys[] = sprintf("`%s`", $key);
+                }
+            }
+
+            $fieldList = implode(", ", $keys);
+
+            $values = array();
+            foreach ($array as $key => $value) {
+                if ($key != 'id') {
+                    $values[] = sprintf("'%s'", $value);
+                }
+            }
+
+            $fields = implode(",", $values);
+
+            $sql = sprintf("
+            INSERT INTO `%s`
+            (`id`, %s) VALUES (NULL, %s)
+        ", $table, $fieldList, $fields);
+
+            return $this->execute($sql);
+        }
+
+        /**
+         * <b>Die Standard store Methode aktualisiert einen DB-Eintrag in der angegebenen Tabelle</b>
+         *
+         * @param $table
+         * @param $id
+         * @param $array
+         * @return bool
+         */
+        public function store($table, $id, $array) {
+            self::$logger->info(sprintf('%s(%s, %d, %s) ', __METHOD__, $table, $id, print_r($array, true)));
+
+            $list = array();
+            foreach ($array as $key => $value) {
+                if ($key != 'id') {
+                    $list[] = sprintf("`%s` = '%s'", $key, $value);
+                }
+            }
+
+            $listItems = implode(", ", $list);
+
+            $sql = sprintf("
+            UPDATE `%s`
+            SET %s
+            WHERE `id` = %d
+        ", $table, $listItems, $id);
+
+
+            return $this->execute($sql);
+        }
+
+        /**
+         * <b>Die Standard Delete Methode löscht einen bestehenden DB-Eintrag aus der angegebenen Tabelle</b>
+         *
+         * @param $table
+         * @param $id
+         * @return bool
+         */
+        public function delete($table, $id) {
+            self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
+
+            $sql = sprintf("
+            DELETE FROM `%s`
+            WHERE `id` = %d;
+        ", $table, $id);
+
+            return $this->execute($sql);
+        }
+
+        /**
+         * <b>Liefert die letzte, verwendete ID, die eingefügt wurde.</b>
+         *
+         * Es gilt zu beachten, dass es sich hierbei um eine state-behaftete Methode handelt.
+         *
+         * <b>Nach 3 Inserts liefert diese Methode definitiv nur den PK des letzten INSERTS.</b>
+         *
+         * @return int|string
+         */
+        public function getLastInsertedId() {
+            $lastInsertedId = mysqli_insert_id($this->link);
+
+            self::$logger->info(sprintf('%s(): %d', __METHOD__, $lastInsertedId));
+
+            return $lastInsertedId;
+        }
+
+        /**
+         * <b>Diese Methode löscht alle Tickets, History und Benutzer weg</b>
+         *
+         * Diese Methode sollte dann aufgerufen werden, wenn die Anwendung deployed wird
+         *
+         * Auf Deutsch: "Vor der Präsi alles weglöschen."
+         *
+         * @return bool
+         */
+        public function cleanup() {
+            $status = $this->execute("DELETE FROM `t_ticket` WHERE `id` > 1;");
+            $status &= $this->execute("DELETE FROM `t_history` WHERE `id` > 1;");
+            $status &= $this->execute("DELETE FROM `t_user` WHERE `id` > 2;");
+
+            $status &= $this->execute("ALTER TABLE `t_history` AUTO_INCREMENT = 1;");
+            $status &= $this->execute("ALTER TABLE `t_ticket` AUTO_INCREMENT = 1;");
+            $status &= $this->execute("ALTER TABLE `t_user` AUTO_INCREMENT = 2;");
+
+            return $status;
+        }
+
+        /**
+         * <b>Import von Datensätzen im CSV-Format(besser gesagt SSV-Format)</b>
+         *
+         * Die Tabelle 'table' wird automatisiert mit den Werten aus der SSV-Datei befüllt.
+         *
+         * @param $table
+         * @param $filename
+         * @return bool
+         */
+        public function csvImport($table, $filename) {
+            $db = Database::getInstance();
+
+            $handle = fopen($filename, 'r');
+
+            $lines = array();
+            while (!feof($handle)) {
+                $lines[] = trim(fgets($handle), "[\r\n\t]");
+            }
+
+            fclose($handle);
+
+            if (count($lines) < 2) {
+                return false;
+            }
+
+            $spaltenKoepfeArray = explode(';', $lines[0]);
+            for ($i = 0; $i < count($spaltenKoepfeArray); $i++) {
+                $spaltenKoepfeArray[$i] = sprintf("`%s`", $spaltenKoepfeArray[$i]);
+            }
+
+            $spaltenInhaltArray = array();
+            for ($i = 1; $i < count($lines); $i++) {
+                $spaltenInhaltArray[] = explode(';', $lines[$i]);
+            }
+
+            $spaltenKoepfe = implode(', ', $spaltenKoepfeArray);
+
+            foreach ($spaltenInhaltArray as $sia) {
+                for ($i = 0; $i < count($sia); $i++) {
+
+                    if ($spaltenKoepfeArray[$i] == '`last_access`') {
+                        $sia[$i] = sprintf("'%s'", date("Y-m-d H:i:s"));
+                    } else {
+                        $sia[$i] = sprintf("'%s'", $sia[$i]);
+                    }
+                }
+
+                $spaltenInhalt = implode(', ', $sia);
+                if (count($spaltenKoepfeArray) == count($sia)) {
+                    $sql = sprintf("INSERT INTO %s(id, %s) VALUES(NULL, %s);", $table, $spaltenKoepfe, $spaltenInhalt);
+                    if (!$db->execute($sql)) {
+
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+    }
+}
\ No newline at end of file