dolibarr 24.0.0-beta
DoliDB.class.php
Go to the documentation of this file.
1<?php
2/*
3 * Copyright (C) 2013-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
4 * Copyright (C) 2014-2015 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
27require_once DOL_DOCUMENT_ROOT.'/core/db/Database.interface.php';
28
29
33abstract class DoliDB implements Database
34{
39
41 public $db;
43 public $type;
45 public $forcecharset = 'utf8';
47 public $forcecollate = 'utf8_unicode_ci';
48
50 private $_results; // @phpstan-ignore-line
51
53 public $connected;
55 public $database_selected;
57 public $database_name;
59 public $database_user;
61 public $database_host;
63 public $database_port;
65 public $transaction_opened;
67 public $lastquery;
69 public $lastqueryerror;
71 public $lasterror;
73 public $lasterrno;
74
76 public $prefix_db;
77
79 public $ok;
81 public $error;
82
83
84
91 public function prefix()
92 {
93 return (empty($this->prefix_db) ? MAIN_DB_PREFIX : $this->prefix_db);
94 }
95
104 public function ifsql($test, $resok, $resko)
105 {
106 //return 'IF('.$test.','.$resok.','.$resko.')'; // Not sql standard
107 return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)';
108 }
109
116 public function stddevpop($nameoffield)
117 {
118 return 'STDDEV_POP('.$nameoffield.')';
119 }
120
128 public function hintindex($nameofindex, $mode = 1)
129 {
130 return '';
131 }
132
133
142 public function regexpsql($subject, $pattern, $sqlstring = 0)
143 {
144 if ($sqlstring) {
145 return "(". $subject ." REGEXP '" . $this->escape($pattern) . "')";
146 }
147
148 return "('". $this->escape($subject) ."' REGEXP '" . $this->escape($pattern) . "')";
149 }
150
151
160 public function idate($param, $gm = 'tzserver')
161 {
162 // TODO $param should be gmt, so we should have default $gm to 'gmt' instead of default 'tzserver'
163 return dol_print_date($param, "%Y-%m-%d %H:%M:%S", $gm);
164 }
165
171 public function lasterrno()
172 {
173 return $this->lasterrno;
174 }
175
187 public function sanitize($stringtosanitize, $allowsimplequote = 0, $allowsequals = 0, $allowsspace = 0, $allowschars = 1)
188 {
189 $result = preg_replace('/[^0-9_\-\.,'.($allowschars ? '\p{L}' : '').($allowsequals ? '=' : '').($allowsimplequote ? "\'" : '').($allowsspace ? ' ' : '').']/ui', '', $stringtosanitize);
190 //$result = preg_replace('/[^0-9_\-\.,'.($allowschars ? 'a-z' : '').($allowsequals ? '=' : '').($allowsimplequote ? "\'" : '').($allowsspace ? ' ' : '').']/i', '', $stringtosanitize);
191
192 if ($allowsimplequote == 1) {
193 // Remove all quotes that are inside a string and not around
194 $tmpchars = explode(',', $result);
195 $newstringarray = array();
196 foreach ($tmpchars as $tmpchar) {
197 $reg = array();
198 if (preg_match('/^\'(.*)\'$/', $tmpchar, $reg)) {
199 $newstringarray[] = "'".str_replace("'", "", $reg[1])."'";
200 } else {
201 $newstringarray[] = str_replace("'", "", $tmpchar);
202 }
203 }
204 $result = implode(',', $newstringarray);
205 }
206
207 return $result;
208 }
209
216 public function begin($textinlog = '')
217 {
218 if (!$this->transaction_opened) {
219 $ret = $this->query("BEGIN");
220 if ($ret) {
221 $this->transaction_opened++;
222 dol_syslog("BEGIN Transaction".($textinlog ? ' '.$textinlog : ''), LOG_DEBUG);
223 dol_syslog('', 0, 1);
224 return 1;
225 } else {
226 return 0;
227 }
228 } else {
229 $this->transaction_opened++;
230 dol_syslog('', 0, 1);
231 return 1;
232 }
233 }
234
241 public function commit($log = '')
242 {
243 dol_syslog('', 0, -1);
244 if ($this->transaction_opened <= 1) {
245 $ret = $this->query("COMMIT");
246 if ($ret) {
247 $this->transaction_opened = 0;
248 dol_syslog("COMMIT Transaction".($log ? ' '.$log : ''), LOG_DEBUG);
249 return 1;
250 } else {
251 return 0;
252 }
253 } else {
254 $this->transaction_opened--;
255 return 1;
256 }
257 }
258
265 public function rollback($log = '')
266 {
267 dol_syslog('', 0, -1);
268 if ($this->transaction_opened <= 1) {
269 $ret = $this->query("ROLLBACK");
270 $this->transaction_opened = 0;
271 dol_syslog("ROLLBACK Transaction".($log ? ' '.$log : ''), LOG_DEBUG);
272 return $ret;
273 } else {
274 $this->transaction_opened--;
275 return 1;
276 }
277 }
278
286 public function plimit($limit = 0, $offset = 0)
287 {
288 global $conf;
289 if (empty($limit)) {
290 return "";
291 }
292 if ($limit < 0) {
293 $limit = $conf->liste_limit;
294 }
295 if ($offset > 0) {
296 return " LIMIT ".((int) $offset).",".((int) $limit)." ";
297 } else {
298 return " LIMIT ".((int) $limit)." ";
299 }
300 }
301
307 public function getVersionArray()
308 {
309 return preg_split("/[\.,-]/", $this->getVersion());
310 }
311
317 public function lastquery()
318 {
319 return $this->lastquery;
320 }
321
329 public function order($sortfield = '', $sortorder = '')
330 {
331 if (!empty($sortfield)) {
332 $oldsortorder = '';
333 $return = '';
334
335 // If text is "field1, f(a,b,c) as xxx, field2", we must convert string into 'field1,xxx,field2'
336 $sortfield = preg_replace('/[a-z_]+\‍([^\‍)]*\‍) as ([\w]+)/i', '\1', $sortfield);
337
338 $fields = explode(',', $sortfield);
339 $orders = (!empty($sortorder) ? explode(',', $sortorder) : array());
340 $i = 0;
341
342
343 foreach ($fields as $val) {
344 // Sanitized fieldname
345 $fieldname = preg_replace('/[^0-9a-z_\.]/i', '', $val);
346 if (!$fieldname) {
347 continue;
348 }
349
350 if (!$return) {
351 $return .= ' ORDER BY ';
352 } else {
353 $return .= ', ';
354 }
355
356 // Add field
357 $return .= $fieldname;
358
359 $tmpsortorder = (empty($orders[$i]) ? '' : trim($orders[$i]));
360
361 // Only ASC and DESC values are valid SQL
362 if (strtoupper($tmpsortorder) === 'ASC') {
363 $oldsortorder = 'ASC';
364 $return .= ' ASC';
365 } elseif (strtoupper($tmpsortorder) === 'DESC') {
366 $oldsortorder = 'DESC';
367 $return .= ' DESC';
368 } else {
369 $return .= ' '.($oldsortorder ? $oldsortorder : 'ASC');
370 }
371
372 $i++;
373 }
374 return $return;
375 } else {
376 return '';
377 }
378 }
379
385 public function lasterror()
386 {
387 return $this->lasterror;
388 }
389
399 public function jdate($string, $gm = 'tzserver')
400 {
401 // TODO $string should be converted into a GMT timestamp, so param gm should be set to true by default instead of false
402
403 $string = (string) $string;
404 if ($string == '' || $string == '0' || $string == "0000-00-00 00:00:00") {
405 return '';
406 }
407 $string = preg_replace('/([^0-9])/i', '', $string);
408 $tmp = $string.'000000';
409 $date = dol_mktime((int) substr($tmp, 8, 2), (int) substr($tmp, 10, 2), (int) substr($tmp, 12, 2), (int) substr($tmp, 4, 2), (int) substr($tmp, 6, 2), (int) substr($tmp, 0, 4), $gm);
410
411 return $date;
412 }
413
419 public function lastqueryerror()
420 {
421 return $this->lastqueryerror;
422 }
423
432 public function getRow($sql)
433 {
434 $sql .= ' LIMIT 1';
435
436 $resql = $this->query($sql);
437 if ($resql) {
438 $obj = $this->fetch_object($resql);
439 if ($obj) {
440 $this->free($resql);
441 return $obj;
442 } else {
443 return 0;
444 }
445 }
446
447 return false;
448 }
449
458 public function getRows($sql)
459 {
460 if (!preg_match('/LIMIT \d+(?:(?:,\ *\d*)|(?:\ +OFFSET\ +\d*))?\ *;?$/', $sql)) {
461 trigger_error(__CLASS__ .'::'.__FUNCTION__.'() query must have a LIMIT clause', E_USER_ERROR);
462 }
463
464 $resql = $this->query($sql);
465 if ($resql) {
466 $results = array();
467 if ($this->num_rows($resql) > 0) {
468 while ($obj = $this->fetch_object($resql)) {
469 $results[] = $obj;
470 }
471 }
472 $this->free($resql);
473 return $results;
474 }
475
476 return false;
477 }
478
485 public function getNextAutoIncrementId($table)
486 {
487 $this->lasterror = 'getNextAutoIncrementId() not implemented for this driver. Failed to get next ID for table '.$table;
488
489 return -1;
490 }
491
500 public function prepare($sql)
501 {
502 $this->lasterror = 'prepare() not implemented for this driver. Failed to prepare '.$sql;
503
504 return false;
505 }
506}
Class to manage Dolibarr database access.
getNextAutoIncrementId($table)
Get the last ID of an auto-increment field of a table.
commit($log='')
Validate a database transaction.
hintindex($nameofindex, $mode=1)
Return SQL string to force an index.
idate($param, $gm='tzserver')
Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date fiel...
const LABEL
Force subclass to implement LABEL - description of DB type.
ifsql($test, $resok, $resko)
Format a SQL IF.
getVersionArray()
Return version of database server into an array.
lastqueryerror()
Return last query in error.
begin($textinlog='')
Start transaction.
rollback($log='')
Cancel a transaction and go back to initial data values.
lasterror()
Return last error label.
getRow($sql)
Return first result from query as object Note : This method executes a given SQL query and retrieves ...
lasterrno()
Return last error code.
lastquery()
Return last request executed with query()
plimit($limit=0, $offset=0)
Define limits and offset of request.
stddevpop($nameoffield)
Return SQL string to aggregate using the Standard Deviation of population.
prefix()
Return the DB prefix found into prefix_db (if it was set manually by doing $dbhandler->prefix_db=....
sanitize($stringtosanitize, $allowsimplequote=0, $allowsequals=0, $allowsspace=0, $allowschars=1)
Sanitize a string for SQL forging.
prepare($sql)
Prepare a SQL statement for execution.
regexpsql($subject, $pattern, $sqlstring=0)
Format a SQL REGEXP.
getRows($sql)
Return all results from query as an array of objects.
order($sortfield='', $sortorder='')
Define sort criteria of request.
const VERSIONMIN
Force subclass to implement VERSIONMIN - required DB version.
jdate($string, $gm='tzserver')
Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true) 19700101020000 -...
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Class to manage Dolibarr database access for an SQL database.
query($query, $usesavepoint=0, $type='auto', $result_mode=0)
Execute a SQL request and return the resultset.
getVersion()
Return version of database server.
escape($stringtoencode)
Escape a string to insert data.
fetch_object($resultset)
Returns the current line (as an object) for the resultset cursor.
num_rows($resultset)
Return number of lines for result of a SELECT.
free($resultset=null)
Free last resultset used.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php