OPiQuotations  v.02.00.00 — October 26, 2015
 All Classes Namespaces Files Functions Variables Pages
Db.inc
Go to the documentation of this file.
1 <?php // -*- coding: utf-8 -*-
2 
3 /** \file Db.inc
4  * (October 25, 2015)
5  *
6  * \brief
7  * Class to connect and deal to the MySQL database.
8  *
9  * <img src="db_opiquotations_graph.png" width="470" height="809" border="0" alt="[DB opiquotations graph]" />
10  *
11  * Piece of OPiQuotations.
12  * https://bitbucket.org/OPiMedia/opiquotations
13  *
14  * GPLv3 --- Copyright (C) 2014, 2015 Olivier Pirson
15  * http://www.opimedia.be/
16  *
17  * @package OPiQuotations
18  */
19 namespace OPiQuotations;
20 
21 require_once 'OPiQuotations/log.inc';
22 require_once 'OPiQuotations/OPiQuotation.inc';
23 
24 
25 /**
26  * Class to connect and deal to the MySQL database.
27  */
28 class Db {
29  /**
30  * \brief
31  * Open the connection to the database $db_name.
32  *
33  * If connection fails
34  * then write a message in the errors log file.
35  *
36  * See is_connected() function.
37  *
38  * @param string $host Host name or IP address of the server
39  * @param string $user MySQL user name
40  * @param string $password MySQL password
41  * @param string $db_name Name of the database
42  */
43  public function __construct($host, $user, $password, $db_name) {
44  #DEBUG
45  assert('is_string($host)');
46  assert('is_string($user)');
47  assert('is_string($password)');
48  assert('is_string($db_name)');
49  #DEBUG_END
50 
51  \mysqli_report(MYSQLI_REPORT_OFF);
52  #DEBUG
53  assert(\mysqli_report(MYSQLI_REPORT_ALL^MYSQLI_REPORT_STRICT^MYSQLI_REPORT_INDEX) === true);
54  #DEBUG_END
55 
56  $this->connect = new \mysqli($host, $user, $password, $db_name);
57 
58  if ( $this->connect->connect_error ) {
59  to_log('mysqli connect error '.\mysqli_connect_errno().' : '.\mysqli_connect_error().'
60 '.@print_r($this->connect, true));
61  $this->connect = null;
62  } elseif ( !$this->connect->set_charset('utf8') ) {
63  to_log('mysqli::set_charset(\'utf8\') failed!
64 Server:'.$this->connect->server_info.'
65 Client:'.$this->connect->client_info.'
66 '.@print_r($this->connect, true));
67  $this->connect->close();
68  $this->connect = null;
69  }
70  }
71 
72 
73  /**
74  * \brief
75  * Close the connection to the database.
76  */
77  public function __destruct() {
78  if ( !empty($this->connect) ) {
79  $this->connect->close();
80  }
81  }
82 
83 
84 
85  /**
86  * \brief
87  * If connection is ok
88  * then return true
89  * else return false.
90  *
91  * @return bool
92  */
93  public function is_connected() {
94  return !empty($this->connect);
95  }
96 
97 
98  /**
99  * \brief
100  * Return the string with its special characters escaped
101  * for use in a SQL statement.
102  *
103  * @param string $s
104  *
105  * @return string
106  */
107  public function escape($s) {
108  #DEBUG
109  assert('is_string($s)');
110  assert('$this->is_connected()');
111  #DEBUG_END
112 
113  return $this->connect->real_escape_string($s);
114  }
115 
116 
117  /**
118  * \brief
119  * Return a associative table id => array(name, number of use)
120  * of elements of the table.
121  *
122  * @param string $table (must be 'author', 'nation', 'subject' or 'work')
123  *
124  * @return array[array]
125  */
126  public function list_to_assoc($table) {
127  #DEBUG
128  assert('is_string($table)');
129  assert('in_array($table, array(\'author\', \'nation\', \'subject\' or \'work\'))');
130  #DEBUG_END
131 
132  $quots = array();
133 
134  if (!$this->is_connected()) {
135  to_log('Db.list_to_assoc(\''.print_r($table, true).'\') impossible because is NOT connected!');
136 
137  return $quots;
138  }
139 
140  $id_names = array('author' => 'nation_author_id',
141  'nation' => 'nation_author_id');
142  $id_name = (isset($id_names[$table])
143  ? $id_names[$table]
144  : $table.'_id');
145  $is_maxim = ($table === 'nation'
146  ? ' AND `q`.`is_maxim`=1'
147  : ($table === 'author' || $table === 'work'
148  ? ' AND `q`.`is_maxim`=0'
149  : ''));
150 
151  $query = 'SELECT `t`.`id`, `t`.`name`, (SELECT COUNT(*) FROM `quotation` AS `q` WHERE `t`.`id`=`q`.`'.$id_name.'`'.$is_maxim.') AS `nb`
152 FROM `'.$table.'` AS `t`
153 ORDER BY `name` COLLATE utf8_unicode_ci;';
154 
155  $result = $this->connect->query($query);
156  if ( $result !== false ) {
157  while ($row = $result->fetch_assoc()) {
158  settype($row['id'], 'int');
159  settype($row['nb'], 'int');
160  if ($row['nb'] > 0) {
161  $quots[$row['id']] = array($row['name'], $row['nb']);
162  }
163  }
164 
165  $result->free_result();
166  }
167  else {
168  to_log('MySQL Db.list_to_assoc
169 '.$query.'
170 failed!
171 Server:'.$this->connect->server_info.'
172 Client:'.$this->connect->client_info.'
173 '.@print_r($this->connect, true));
174  }
175 
176  return $quots;
177  }
178 
179 
180  /**
181  * \brief
182  * Return the numbers of quotations and/or maxims.
183  *
184  * If $is_maxim === null then return the numbers of quotations/maxims,\n
185  * if $is_maxim === false then return the numbers of quotations,\n
186  * if $is_maxim === true then return the numbers of maxims.
187  *
188  * @param null|bool $is_maxim
189  *
190  * @return int >= 0
191  */
192  public function nb($is_maxim=null) {
193  #DEBUG
194  assert('($is_maxim === null) || is_bool($is_maxim)');
195  assert('$this->is_connected()');
196  #DEBUG_END
197 
198  if (!$this->is_connected()) {
199  to_log('Db.nb(\''.print_r($is_maxim, true).'\') impossible because is NOT connected!');
200 
201  return 0;
202  }
203 
204  $query = 'SELECT COUNT(*) AS `nb`
205 FROM `quotation` AS `q`';
206  if ($is_maxim !== null) {
207  $query .= '
208 WHERE `q`.`is_maxim`='.($is_maxim
209  ? '1'
210  : '0');
211  }
212  $query .= ';';
213 
214  $result = $this->connect->query($query);
215  if ( $result !== false ) {
216  $row = $result->fetch_assoc();
217 
218  return (int)$row['nb'];
219  }
220  else {
221  to_log('MySQL query
222 '.$query.'
223 failed!
224 Server:'.$this->connect->server_info.'
225 Client:'.$this->connect->client_info.'
226 '.@print_r($this->connect, true));
227 
228  return 0;
229  }
230  }
231 
232 
233  /**
234  * \brief
235  * Execute the MySQL query INSERT.
236  *
237  * If insertion is ok
238  * then return true,
239  * else return false.
240  *
241  * @param string $query Valid MySQL query
242  *
243  * @return bool
244  */
245  public function query_insert($query) {
246  #DEBUG
247  assert('is_string($query)');
248  assert('$this->is_connected()');
249  #DEBUG_END
250 
251  if (!$this->is_connected()) {
252  to_log('Db.query_insert(\''.print_r($query, true).'\') impossible because is NOT connected!');
253 
254  return $quots;
255  }
256 
257  $r = $this->connect->query($query);
258 
259  if (!$r) {
260  to_log('MySQL Db.query_insert
261 '.$query.'
262 failed!
263 Server:'.$this->db->connect->server_info.'
264 Client:'.$this->db->connect->client_info.'
265 '.@print_r($this->db->connect, true));
266  }
267 
268  return $r;
269  }
270 
271 
272  /**
273  * \brief
274  * Return an array with all OPiQuotation
275  * that match with the SQL $where condition
276  * in order specified by $order.
277  *
278  * @warning Use escape() with each string piece of $where if necessary.
279  *
280  * @param string $where Valid WHERE clause of the SELECT MySQL command used
281  * (see http://dev.mysql.com/doc/refman/5.1/en/select.html )
282  * @param string $order Valid ORDER clause of the SELECT MySQL command used
283  * (see http://dev.mysql.com/doc/refman/5.1/en/select.html )
284  *
285  * @return OPiQuotation[]
286  */
287  public function query_quotations($where, $order='') {
288  #DEBUG
289  assert('is_string($where)');
290  assert('is_string($order)');
291  assert('$this->is_connected()');
292  #DEBUG_END
293 
294  $quots = array();
295 
296  if (!$this->is_connected()) {
297  to_log('Db.query_quotations(\''.print_r($where, true).'\', \''.print_r($order, true).'\') impossible because is NOT connected!');
298 
299  return $quots;
300  }
301 
302  $query = array('SELECT `id`, `text`, `translation`, `is_maxim`, `is_marked`, `subject`, `nation`, `author`, `work`',
303  'FROM `vw_quotation`');
304  $where = (string)$where;
305  if ($where !== '') {
306  $query[] = $where;
307  }
308  $order = (string)$order;
309  if ($order !== '') {
310  $query[] = $order;
311  }
312 
313  $query = implode('
314 ', $query).';';
315 
316  $result = $this->connect->query($query);
317  if ( $result !== false ) {
318  while ($row = $result->fetch_assoc()) {
319  settype($row['id'], 'int');
320  settype($row['is_maxim'], 'bool');
321  settype($row['is_marked'], 'bool');
322 
323  $quots[] = new OPiQuotation($row['id'], $row['text'], $row['is_maxim'], $row['is_marked'],
324  $row['translation'],
325  $row['subject'], ($row['is_maxim']
326  ? $row['nation']
327  : $row['author']), $row['work']);
328  }
329 
330  $result->free_result();
331  }
332  else {
333  to_log('MySQL Db.query_quotations
334 '.$query.'
335 failed!
336 Server:'.$this->connect->server_info.'
337 Client:'.$this->connect->client_info.'
338 '.@print_r($this->connect, true));
339  }
340 
341  return $quots;
342  }
343 
344 
345 
346  /** @var \mysqli $connect
347  * \brief
348  * Connection to the MySQL database.
349  */
350  protected $connect;
351 }
352 
353 
354 return true;
355 
356 ?>