Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Database
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 5
552
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 getInstance
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 query
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
240
 lastInsertId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 lastQueryRowCount
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace BuyerKiosk\Core;
4
5/*
6 * PDO Database class
7 *
8 * Usage:
9 * $db = Database::getInstance();
10 * Return array of query results, normal statement: $results = $db->query("SELECT * FROM test WHERE name = 'Bob'");
11 * Return array of query results, prepared statement (named params): $results = $db->query("SELECT * FROM test WHERE name = :name", array(":name" => "matthew"));
12 * Return int of last insert result row id: $db->lastInsertId()
13 * Return int of last query result row count: $db->lastQueryRowCount()
14 *
15 * @package BuyerKiosk\Core
16 */
17class Database {
18
19    /*
20     * Instance of the database class
21     *
22     * @static Database $instance
23     */
24    private static $instance;
25    /*
26     * Database connection
27     *
28     * @access private
29     * @var \PDO $connection
30     */
31    private $connection;
32
33    /*
34     * Constructor
35     *
36     * @param $dsn The Data Source Name. eg, "mysql:dbname=testdb;host=127.0.0.1;port=3306"
37     * @param $username
38     * @param $password
39     */
40    public function __construct($dbName = null) {
41        if(!isset($dbName)) {
42            global $db_name;
43            $dbName = $db_name;
44        }
45        global $db_user,$db_pass;
46        $this->connection = new \PDO('mysql:host=localhost;dbname='.$dbName.';charset=utf8', $db_user, $db_pass, array(
47            \PDO::ATTR_PERSISTENT => true,
48            \PDO::ATTR_TIMEOUT => "30"));
49        if (empty($this->connection)) {
50            trigger_error("Error #D001:", E_USER_ERROR);
51            return false;
52        }
53        $this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
54    }
55
56    /*
57     * Gets an instance of the Database class
58     *
59     * @static $instance
60     * @return Database An instance of the database singleton class
61     */
62    public static function getInstance() {
63        if (empty(self::$instance)) {
64            try {
65                self::$instance = new Database();
66            } catch (\PDOException $e) {
67                trigger_error("Error #D002: ".$e->getMessage(), E_USER_ERROR);
68            }
69        }
70        return self::$instance;
71    }
72
73    /*
74     * Runs a query using the current connection to the database
75     *
76     * @param string query
77     * @param array $args An array of arguments for the sanitization such as array(":name" => "foo")
78     * @return array Containing all the remaining rows in the result set.
79     */
80    public function query($query, $args = false) {
81        $tokens = array_map('trim',explode(" ",trim($query)));
82        $query = str_replace(array("\r\n", "\r", "\t"), " ", $query);
83        $query = str_replace('    ', ' ', $query);
84        try {
85            // Prepare results
86            $results=false;
87
88            // Allow for rollback if query fails
89            $this->connection->beginTransaction();
90
91            // Prepared statements
92            $sth = $this->connection->prepare($query);
93            // Execute prepared statement, with or without arguments
94            if (empty($args)) {
95                $sth->execute();
96            } else {
97                $multiple = false;
98                foreach ($args as $arg) {
99                    if (!is_array($arg)) { continue; }
100                    $multiple = true;
101                    break;
102                }
103                if ($multiple) {
104                    $i=0;$j=count($args);
105                    foreach ($args as $arg) {
106                        foreach ($arg as $k=>$v) {
107                            if ($v === "NULL") { $arg[$k] = null; }
108                        }
109                        $sth->execute($arg);
110                        $i++;
111                    }
112                } else {
113                    $i=0;$j=count($args);
114                    foreach ($args as $a=>$arg) {
115                        if ($arg === "NULL") {$args[$a] = null;}
116                        $i++;
117                    }
118                    $sth->execute($args);
119                }
120            }
121            // SELECT: Return array of data or false if 0 rows
122            if ($tokens[0] == "SELECT") {
123                $sth->setFetchMode(\PDO::FETCH_ASSOC);
124                $results = $sth->fetchAll();
125            }
126            // INSERT/UPDATE/REPLACE: Return number of affected rows / array of affected ids ?
127            // Note: lastInsertId only works if ID col on table is auto_incremented
128            elseif ($tokens[0] == "INSERT"
129                || $tokens[0] == "UPDATE"
130                || $tokens[0] == "REPLACE") {
131
132                // If sessions table, assume key = return id
133                $results = $this->connection->lastInsertId();
134            }
135            // Else: Return number of affected rows
136            else {
137                $results = $sth->rowCount();
138            }
139            // Attempt to commit changes, triggers exception if fails
140            $this->connection->commit();
141            // Rollback changes on failure
142        } catch (\PDOException $e) {
143            $msg = 'query(): ***** Caught Exception! Rolling back changes *****'.PHP_EOL.'<hr />Query:<pre>'.$query.'</pre>'.PHP_EOL.'<hr />Exception Message:<pre>'.$e->getMessage().'</pre><hr />'.PHP_EOL;
144            $this->connection->rollBack();
145            trigger_error($msg, E_USER_ERROR);
146            return false;
147        }
148        return $results;
149    }
150
151    /*
152     * Returns the last insert result row id
153     *
154     * @return int of last insert result row id
155     */
156    public function lastInsertId() {
157        return $this->connection->lastInsertId();
158    }
159
160    /*
161     * Returns the last query result row count
162     *
163     * @return int of last query result row count
164     */
165    public function lastQueryRowCount() {
166        return $this->connection->lastQueryRowCount();
167    }
168
169}