classes/bfw/Database.php
changeset 1 56e0dbd5c243
parent 0 4869aea77e21
child 2 40769b11e94f
equal deleted inserted replaced
0:4869aea77e21 1:56e0dbd5c243
     1 <?php
       
     2 
       
     3 namespace bfw {
       
     4 
       
     5     /**
       
     6      * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
       
     7      *
       
     8      */
       
     9     class Database implements DBInterface {
       
    10         private static $logger = null;
       
    11 
       
    12         private $link;
       
    13         private static $handle = null;
       
    14 
       
    15         private function __construct() {
       
    16             self::$logger = \Logger::getLogger('__CLASS__');
       
    17 
       
    18             $this->link = mysqli_connect($host = 'localhost', $user = 'ticketsystem', $password = 'ticketsystem', $database = 'ticketsystem');
       
    19             mysqli_set_charset($this->link, 'utf8');
       
    20         }
       
    21 
       
    22         /**
       
    23          * <b>Liefert das Singleton-Pattern der Datenbank-Schicht</b>
       
    24          *
       
    25          * Es existiert in einem Lauf, einem Scope, immer nur ein DB-Handle zur gleichen Zeit.
       
    26          *
       
    27          * Damit das ganze vernünftig flutscht, muss man natürlich berücksichtigen, dass ein SP state-lastig ist!
       
    28          *
       
    29          * Definition des States: Ein Abfrageergebnis stellt solange den State des SP da, bis eine neue Abfrage
       
    30          * einen neuen State erzeugt.
       
    31          *
       
    32          * @return Database|null
       
    33          */
       
    34         public static function getInstance() {
       
    35             if (self::$handle == null) {
       
    36                 self::$handle = new Database();
       
    37             }
       
    38 
       
    39             return self::$handle;
       
    40         }
       
    41 
       
    42         /**
       
    43          * <b>Std-Abfrage Methode der DB-Klasse</b>
       
    44          *
       
    45          * Das übergebene SQL-Statement wird als assoziatives, ein-oder mehrdimensionales Array zurück geliefert.
       
    46          *
       
    47          * array = (
       
    48          *     'id' => 1,
       
    49          *     'name' => 'Ticket',
       
    50          * );
       
    51          *
       
    52          * @param $sql
       
    53          * @return array|null
       
    54          */
       
    55         public function query($sql) {
       
    56             self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
       
    57 
       
    58             $result = mysqli_query($this->link, $sql);
       
    59 
       
    60             if ($result == false) {
       
    61                 return null;
       
    62             }
       
    63 
       
    64             if ($result->num_rows == 0) {
       
    65                 return null;
       
    66             }
       
    67 
       
    68             $rows = array();
       
    69             while (($row = $result->fetch_assoc())) {
       
    70                 $rows[] = $row;
       
    71             }
       
    72 
       
    73 
       
    74             return $rows;
       
    75         }
       
    76 
       
    77         /**
       
    78          * <b>Abfragen, die kein ResultSet zurück liefern</b>
       
    79          *
       
    80          * SQL-Statements, die nur TRUE oder FALSE zurück liefern,
       
    81          * müssen per EXECUTE ausgeführt werden.
       
    82          *
       
    83          * @param $sql
       
    84          * @return bool|mysqli_result
       
    85          */
       
    86         public function execute($sql) {
       
    87             self::$logger->info(sprintf('%s(%s) ', __METHOD__, $sql));
       
    88 
       
    89             $result = mysqli_query($this->link, $sql);
       
    90 
       
    91             return $result;
       
    92         }
       
    93 
       
    94         /**
       
    95          * <b>Die einfache Fetch-Methode für das Table-Row-Pattern</b>
       
    96          *
       
    97          * Es wird ein SQL Statement bezogen auf die aktuelle Tabelle zusammen
       
    98          * gebaut. Dieses kann optional eine WHERE clause beinhalten.
       
    99          *
       
   100          * @param $table
       
   101          * @param string $cond
       
   102          * @return array|null
       
   103          */
       
   104         public function fetch($table, $cond = 'id > 1') {
       
   105             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
       
   106 
       
   107             $sql = "
       
   108             SELECT
       
   109                 *
       
   110             FROM
       
   111               $table
       
   112             WHERE
       
   113               $cond
       
   114         ";
       
   115 
       
   116             $result = mysqli_query($this->link, $sql);
       
   117 
       
   118             if ($result == false) {
       
   119                 return null;
       
   120             }
       
   121 
       
   122             return $result->fetch_assoc();
       
   123         }
       
   124 
       
   125         /**
       
   126          * <b>Die multiple Fetch-Methode für das Table-Row-Pattern</b>
       
   127          *
       
   128          * Der Rückgabewert ist ein Array mit allen Zeilen als assoziatives Array
       
   129          *
       
   130          * @param $table
       
   131          * @param string $cond
       
   132          * @return array|null
       
   133          */
       
   134         public function fetchAll($table, $cond = 'id > 0') {
       
   135             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));
       
   136 
       
   137             $sql = sprintf("
       
   138             SELECT
       
   139               *
       
   140             FROM
       
   141               `%s`
       
   142             WHERE
       
   143               %s
       
   144         ", $table, $cond);
       
   145 
       
   146             return $this->query($sql);
       
   147         }
       
   148 
       
   149         /**
       
   150          * <b>Die einfache Find-Methode für das Table-Row-Pattern</b>
       
   151          *
       
   152          * Der Rückgabewert ist entweder die Tabellenzeile 'id' oder null
       
   153          * im assoziativen Array.
       
   154          *
       
   155          * @param $table
       
   156          * @param $id
       
   157          * @return array|null
       
   158          */
       
   159         public function find($table, $id) {
       
   160             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
       
   161 
       
   162             $sql = sprintf("
       
   163             SELECT
       
   164               *
       
   165             FROM
       
   166               `%s`
       
   167             WHERE
       
   168               `id` = %d
       
   169         ", $table, $id);
       
   170 
       
   171             $result = mysqli_query($this->link, $sql);
       
   172 
       
   173             if ($result == false) {
       
   174                 return null;
       
   175             }
       
   176 
       
   177             return $result->fetch_assoc();
       
   178         }
       
   179 
       
   180         /**
       
   181          * <b>Die multiple Find-Methode für das Table-Row-Pattern</b>
       
   182          *
       
   183          * Es liefert alle Reihen als assoziatives Array zurück.
       
   184          *
       
   185          * @param $table
       
   186          * @return array|null
       
   187          */
       
   188         public function findAll($table, $sys_id = 1) {
       
   189             self::$logger->info(sprintf('%s(%s) ', __METHOD__, $table));
       
   190 
       
   191             $sql = sprintf("
       
   192             SELECT
       
   193               *
       
   194             FROM
       
   195               `%s`
       
   196             WHERE
       
   197               `id` > %d
       
   198         ", $table, $sys_id);
       
   199 
       
   200             return $this->query($sql);
       
   201         }
       
   202 
       
   203         /**
       
   204          * <b>Liefert ein Resultset bezogen auf ein bestimmtes Feld zurück</b>
       
   205          *
       
   206          * @param $table
       
   207          * @param $field
       
   208          * @param $value
       
   209          * @return array|null
       
   210          */
       
   211         public function findByField($table, $field, $value) {
       
   212             self::$logger->info(sprintf('%s(%s, %s, %s) ', __METHOD__, $table, $field, $value));
       
   213 
       
   214             $sql = sprintf("
       
   215             SELECT
       
   216               *
       
   217             FROM
       
   218               `%s`
       
   219             WHERE
       
   220               `%s` = '%s'
       
   221         ", $table, $field, $value);
       
   222 
       
   223             $result = mysqli_query($this->link, $sql);
       
   224 
       
   225             if ($result == false) {
       
   226                 return null;
       
   227             }
       
   228 
       
   229             return $result->fetch_assoc();
       
   230         }
       
   231 
       
   232         /**
       
   233          * <b>Liefert mehrere Resultsets bezogen auf ein bestimmtes Feld zurück</b>
       
   234          *
       
   235          * @param $table
       
   236          * @param $field
       
   237          * @param $value
       
   238          * @return array|null
       
   239          */
       
   240         public function findAllByField($table, $field, $value) {
       
   241             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $field));
       
   242 
       
   243             $sql = sprintf("
       
   244             SELECT
       
   245               *
       
   246             FROM
       
   247               `%s`
       
   248             WHERE
       
   249               `%s` = '%s'
       
   250         ", $table, $field, $value);
       
   251 
       
   252             return $this->query($sql);
       
   253         }
       
   254 
       
   255         /**
       
   256          * <b>Die Standard Persist Methode erstellt einen neuen DB-Eintrag in der angegebenen Tabelle</b>
       
   257          *
       
   258          * @param $table
       
   259          * @param $array
       
   260          * @return bool|mysqli_result
       
   261          */
       
   262         public function persist($table, $array) {
       
   263             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, print_r($array, true)));
       
   264 
       
   265             $keys = array();
       
   266             foreach (array_keys($array) as $key) {
       
   267                 if ($key != 'id') {
       
   268                     $keys[] = sprintf("`%s`", $key);
       
   269                 }
       
   270             }
       
   271 
       
   272             $fieldList = implode(", ", $keys);
       
   273 
       
   274             $values = array();
       
   275             foreach ($array as $key => $value) {
       
   276                 if ($key != 'id') {
       
   277                     $values[] = sprintf("'%s'", $value);
       
   278                 }
       
   279             }
       
   280 
       
   281             $fields = implode(",", $values);
       
   282 
       
   283             $sql = sprintf("
       
   284             INSERT INTO `%s`
       
   285             (`id`, %s) VALUES (NULL, %s)
       
   286         ", $table, $fieldList, $fields);
       
   287 
       
   288             return $this->execute($sql);
       
   289         }
       
   290 
       
   291         /**
       
   292          * <b>Die Standard store Methode aktualisiert einen DB-Eintrag in der angegebenen Tabelle</b>
       
   293          *
       
   294          * @param $table
       
   295          * @param $id
       
   296          * @param $array
       
   297          * @return bool
       
   298          */
       
   299         public function store($table, $id, $array) {
       
   300             self::$logger->info(sprintf('%s(%s, %d, %s) ', __METHOD__, $table, $id, print_r($array, true)));
       
   301 
       
   302             $list = array();
       
   303             foreach ($array as $key => $value) {
       
   304                 if ($key != 'id') {
       
   305                     $list[] = sprintf("`%s` = '%s'", $key, $value);
       
   306                 }
       
   307             }
       
   308 
       
   309             $listItems = implode(", ", $list);
       
   310 
       
   311             $sql = sprintf("
       
   312             UPDATE `%s`
       
   313             SET %s
       
   314             WHERE `id` = %d
       
   315         ", $table, $listItems, $id);
       
   316 
       
   317 
       
   318             return $this->execute($sql);
       
   319         }
       
   320 
       
   321         /**
       
   322          * <b>Die Standard Delete Methode löscht einen bestehenden DB-Eintrag aus der angegebenen Tabelle</b>
       
   323          *
       
   324          * @param $table
       
   325          * @param $id
       
   326          * @return bool
       
   327          */
       
   328         public function delete($table, $id) {
       
   329             self::$logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));
       
   330 
       
   331             $sql = sprintf("
       
   332             DELETE FROM `%s`
       
   333             WHERE `id` = %d;
       
   334         ", $table, $id);
       
   335 
       
   336             return $this->execute($sql);
       
   337         }
       
   338 
       
   339         /**
       
   340          * <b>Liefert die letzte, verwendete ID, die eingefügt wurde.</b>
       
   341          *
       
   342          * Es gilt zu beachten, dass es sich hierbei um eine state-behaftete Methode handelt.
       
   343          *
       
   344          * <b>Nach 3 Inserts liefert diese Methode definitiv nur den PK des letzten INSERTS.</b>
       
   345          *
       
   346          * @return int|string
       
   347          */
       
   348         public function getLastInsertedId() {
       
   349             $lastInsertedId = mysqli_insert_id($this->link);
       
   350 
       
   351             self::$logger->info(sprintf('%s(): %d', __METHOD__, $lastInsertedId));
       
   352 
       
   353             return $lastInsertedId;
       
   354         }
       
   355 
       
   356         /**
       
   357          * <b>Diese Methode löscht alle Tickets, History und Benutzer weg</b>
       
   358          *
       
   359          * Diese Methode sollte dann aufgerufen werden, wenn die Anwendung deployed wird
       
   360          *
       
   361          * Auf Deutsch: "Vor der Präsi alles weglöschen."
       
   362          *
       
   363          * @return bool
       
   364          */
       
   365         public function cleanup() {
       
   366             $status = $this->execute("DELETE FROM `t_ticket` WHERE `id` > 1;");
       
   367             $status &= $this->execute("DELETE FROM `t_history` WHERE `id` > 1;");
       
   368             $status &= $this->execute("DELETE FROM `t_user` WHERE `id` > 2;");
       
   369 
       
   370             $status &= $this->execute("ALTER TABLE `t_history` AUTO_INCREMENT = 1;");
       
   371             $status &= $this->execute("ALTER TABLE `t_ticket` AUTO_INCREMENT = 1;");
       
   372             $status &= $this->execute("ALTER TABLE `t_user` AUTO_INCREMENT = 2;");
       
   373 
       
   374             return $status;
       
   375         }
       
   376 
       
   377         /**
       
   378          * <b>Import von Datensätzen im CSV-Format(besser gesagt SSV-Format)</b>
       
   379          *
       
   380          * Die Tabelle 'table' wird automatisiert mit den Werten aus der SSV-Datei befüllt.
       
   381          *
       
   382          * @param $table
       
   383          * @param $filename
       
   384          * @return bool
       
   385          */
       
   386         public function csvImport($table, $filename) {
       
   387             $db = Database::getInstance();
       
   388 
       
   389             $handle = fopen($filename, 'r');
       
   390 
       
   391             $lines = array();
       
   392             while (!feof($handle)) {
       
   393                 $lines[] = trim(fgets($handle), "[\r\n\t]");
       
   394             }
       
   395 
       
   396             fclose($handle);
       
   397 
       
   398             if (count($lines) < 2) {
       
   399                 return false;
       
   400             }
       
   401 
       
   402             $spaltenKoepfeArray = explode(';', $lines[0]);
       
   403             for ($i = 0; $i < count($spaltenKoepfeArray); $i++) {
       
   404                 $spaltenKoepfeArray[$i] = sprintf("`%s`", $spaltenKoepfeArray[$i]);
       
   405             }
       
   406 
       
   407             $spaltenInhaltArray = array();
       
   408             for ($i = 1; $i < count($lines); $i++) {
       
   409                 $spaltenInhaltArray[] = explode(';', $lines[$i]);
       
   410             }
       
   411 
       
   412             $spaltenKoepfe = implode(', ', $spaltenKoepfeArray);
       
   413 
       
   414             foreach ($spaltenInhaltArray as $sia) {
       
   415                 for ($i = 0; $i < count($sia); $i++) {
       
   416 
       
   417                     if ($spaltenKoepfeArray[$i] == '`last_access`') {
       
   418                         $sia[$i] = sprintf("'%s'", date("Y-m-d H:i:s"));
       
   419                     } else {
       
   420                         $sia[$i] = sprintf("'%s'", $sia[$i]);
       
   421                     }
       
   422                 }
       
   423 
       
   424                 $spaltenInhalt = implode(', ', $sia);
       
   425                 if (count($spaltenKoepfeArray) == count($sia)) {
       
   426                     $sql = sprintf("INSERT INTO %s(id, %s) VALUES(NULL, %s);", $table, $spaltenKoepfe, $spaltenInhalt);
       
   427                     if (!$db->execute($sql)) {
       
   428 
       
   429                         return false;
       
   430                     }
       
   431                 }
       
   432             }
       
   433 
       
   434             return true;
       
   435         }
       
   436 
       
   437     }
       
   438 }