Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
150 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
if (!defined('IN_OIDPLUS')) die();
21
 
227 daniel-mar 22
class OIDplusDataBasePluginPDO extends OIDplusDataBasePlugin {
150 daniel-mar 23
        private $pdo;
24
        private $last_query;
25
        private $prepare_cache = array();
26
 
222 daniel-mar 27
        public static function getPluginInformation() {
28
                $out = array();
29
                $out['name'] = 'PDO';
30
                $out['author'] = 'ViaThinkSoft';
31
                $out['version'] = null;
32
                $out['descriptionHTML'] = null;
33
                return $out;
34
        }
35
 
150 daniel-mar 36
        public static function name() {
37
                return "PDO";
38
        }
39
 
40
        public function query($sql, $prepared_args=null) {
41
                $this->last_query = $sql;
42
                if (is_null($prepared_args)) {
43
                        return $this->pdo->query($sql);
44
                } else {
45
 
46
 
47
                        // TEST: Emulate the prepared statement
48
/*
49
                        foreach ($prepared_args as $arg) {
50
                                $needle = '?';
51
                                $replace = "'$arg'"; // TODO: types
52
                                $pos = strpos($sql, $needle);
53
                                if ($pos !== false) {
54
                                        $sql = substr_replace($sql, $replace, $pos, strlen($needle));
55
                                }
56
                        }
57
                        return $this->pdo->query($sql);
58
*/
59
 
60
 
61
                        if (!is_array($prepared_args)) {
62
                                throw new Exception("'prepared_args' must be either NULL or an ARRAY.");
63
                        }
64
                        if (isset($this->prepare_cache[$sql])) {
65
                                $ps = $this->prepare_cache[$sql];
66
                        } else {
67
                                $ps = $this->pdo->prepare($sql);
68
                                if (!$ps) {
69
                                        throw new Exception("Cannot prepare statement '$sql'");
70
                                }
71
                                $this->prepare_cache[$sql] = $ps;
72
                        }
73
                        if (!$ps->execute($prepared_args)) {
74
                                // Note: Our plugins prepare the configs by trying to insert stuff, which raises a Primary Key exception. So we cannot throw an Exception.
75
                                return false;
76
                        }
77
                        return $ps;
78
                }
79
        }
80
        public function num_rows($res) {
81
                if (!is_object($res)) {
82
                        throw new Exception("num_rows called on non object. Last query: ".$this->last_query);
83
                } else {
84
                        return $res->rowCount();
85
                }
86
        }
87
        public function fetch_array($res) {
88
                if (!is_object($res)) {
89
                        throw new Exception("fetch_array called on non object. Last query: ".$this->last_query);
90
                } else {
91
                        return $res->fetch(PDO::FETCH_ASSOC);
92
                }
93
        }
94
        public function fetch_object($res) {
95
                if (!is_object($res)) {
96
                        throw new Exception("fetch_object called on non object. Last query: ".$this->last_query);
97
                } else {
98
                        return $res->fetch(PDO::FETCH_OBJ);
99
                }
100
        }
101
        public function insert_id() {
102
                return $this->pdo->lastInsertId();
103
        }
104
        public function error() {
105
                return $this->pdo->errorInfo()[2];
106
        }
107
        public function connect() {
108
                $html = OIDPLUS_HTML_OUTPUT;
109
 
110
                try {
111
                        $options = [
112
                        #    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
113
                            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
114
                            PDO::ATTR_EMULATE_PREPARES   => true,
115
                        ];
116
 
117
                        // Try connecting to the database
118
                        $this->pdo = new PDO(OIDPLUS_PDO_DSN, OIDPLUS_PDO_USERNAME, base64_decode(OIDPLUS_PDO_PASSWORD), $options);
119
                } catch (PDOException $e) {
120
                        if ($html) {
121
                                echo "<h1>Error</h1><p>Database connection failed! (".$e->getMessage().")</p>";
122
                                if (is_dir(__DIR__.'/../../../setup')) {
123
                                        echo '<p>If you believe that the login credentials are wrong, please run <a href="setup/">setup</a> again.</p>';
124
                                }
125
                        } else {
126
                                echo "Error: Database connection failed! (".$e->getMessage().")";
127
                                if (is_dir(__DIR__.'/../../../setup')) {
128
                                        echo ' If you believe that the login credentials are wrong, please run setup again.';
129
                                }
130
                        }
131
                        die();
132
                }
133
 
134
                $this->query("SET NAMES 'utf8'");
135
                $this->afterConnect($html);
136
                $this->connected = true;
137
        }
138
 
139
        private $intransaction = false;
140
 
141
        public function transaction_begin() {
142
                if ($this->intransaction) throw new Exception("Nested transactions are not supported by this database plugin.");
143
                $this->pdo->beginTransaction();
144
                $this->intransaction = true;
145
        }
146
 
147
        public function transaction_commit() {
148
                $this->pdo->commit();
149
                $this->intransaction = false;
150
        }
151
 
152
        public function transaction_rollback() {
153
                $this->pdo->rollBack();
154
                $this->intransaction = false;
155
        }
156
}