dolibarr 25.0.0-alpha
multicurrency.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2020 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
4 * Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
6 * Copyright (C) 2016 Pierre-Henry Favre <phf@atm-consulting.fr>
7 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/currencyrate.class.php';
32
40{
44 public $element = 'multicurrency';
45
49 public $table_element = 'multicurrency';
50
54 public $table_element_line = "multicurrency_rate";
55
59 public $rates = array();
60
64 public $id;
65
69 public $code;
70
74 public $name;
75
79 public $date_create;
80
84 public $fk_user;
85
89 public $rate;
90
94 public $rate_direct;
95
99 public $urlendpoint;
100
101
102 const MULTICURRENCY_APP_ENDPOINT_DEFAULT = 'https://api.currencylayer.com/live?access_key=__MULTICURRENCY_APP_KEY__&source=__MULTICURRENCY_APP_SOURCE__';
103
104 // Frankfurter (frankfurter.dev): free, no API key, ECB reference rates (~30 currencies).
105 // Unlike currencylayer's free tier, it accepts any source currency directly, so no
106 // USD-pivot recalculation is needed when the configured source isn't USD.
107 const MULTICURRENCY_APP_ENDPOINT_FRANKFURTER_DEFAULT = 'https://api.frankfurter.dev/v1/latest?base=__MULTICURRENCY_APP_SOURCE__';
108
109
115 public function __construct(DoliDB $db)
116 {
117 $this->db = $db;
118
119 $key = getDolGlobalString("MULTICURRENCY_APP_KEY");
120 $source = getDolGlobalString('MULTICURRENCY_APP_SOURCE', 'USD');
121 $provider = getDolGlobalString('MULTICURRENCY_APP_PROVIDER', 'currencylayer');
122 $defaultendpoint = ($provider == 'frankfurter') ? self::MULTICURRENCY_APP_ENDPOINT_FRANKFURTER_DEFAULT : self::MULTICURRENCY_APP_ENDPOINT_DEFAULT;
123 $urlendpoint = getDolGlobalString("MULTICURRENCY_APP_ENDPOINT", $defaultendpoint);
124
125 $this->urlendpoint = str_replace(array('__MULTICURRENCY_APP_KEY__', '__MULTICURRENCY_APP_SOURCE__'), array($key, $source), $urlendpoint);
126 }
127
135 public function create(User $user, $notrigger = 0)
136 {
137 global $conf, $langs;
138
139 dol_syslog('MultiCurrency::create', LOG_DEBUG);
140
141 $error = 0;
142
143 if (self::checkCodeAlreadyExists($this->code)) {
144 $error++;
145 $this->errors[] = $langs->trans('multicurrency_code_already_added');
146 return -1;
147 }
148
149 if (empty($this->entity) || $this->entity <= 0) {
150 $this->entity = $conf->entity;
151 }
152 $now = dol_now();
153
154 // Insert request
155 $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element."(";
156 $sql .= ' code,';
157 $sql .= ' name,';
158 $sql .= ' entity,';
159 $sql .= ' date_create,';
160 $sql .= ' fk_user';
161 $sql .= ') VALUES (';
162 $sql .= " '".$this->db->escape($this->code)."',";
163 $sql .= " '".$this->db->escape($this->name)."',";
164 $sql .= " ".((int) $this->entity).",";
165 $sql .= " '".$this->db->idate($now)."',";
166 $sql .= " ".((int) $user->id);
167 $sql .= ')';
168
169 $this->db->begin();
170
171 dol_syslog(__METHOD__, LOG_DEBUG);
172 $resql = $this->db->query($sql);
173 if (!$resql) {
174 $error++;
175 $this->errors[] = 'Error '.$this->db->lasterror();
176 dol_syslog('MultiCurrency::create '.implode(',', $this->errors), LOG_ERR);
177 }
178
179 if (!$error) {
180 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
181 $this->date_create = $now;
182 $this->fk_user = $user->id;
183
184 if (empty($notrigger)) {
185 $result = $this->call_trigger('CURRENCY_CREATE', $user);
186 if ($result < 0) {
187 $error++;
188 }
189 }
190 }
191
192 if ($error) {
193 $this->db->rollback();
194
195 return -1 * $error;
196 } else {
197 $this->db->commit();
198
199 return $this->id;
200 }
201 }
202
210 public function fetch($id, $code = null)
211 {
212 dol_syslog('MultiCurrency::fetch', LOG_DEBUG);
213
214 $sql = "SELECT c.rowid, c.name, c.code, c.entity, c.date_create, c.fk_user";
215 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." AS c";
216 if (!empty($code)) {
217 $sql .= " WHERE c.code = '".$this->db->escape($code)."'";
218 $sql .= " AND c.entity IN (".getEntity($this->element).")";
219 } else {
220 $sql .= ' WHERE c.rowid = '.((int) $id);
221 }
222
223 dol_syslog(__METHOD__, LOG_DEBUG);
224 $resql = $this->db->query($sql);
225
226 if ($resql) {
227 $numrows = $this->db->num_rows($resql);
228 if ($numrows) {
229 $obj = $this->db->fetch_object($resql);
230
231 $this->id = $obj->rowid;
232 $this->name = $obj->name;
233 $this->code = $obj->code;
234 $this->entity = $obj->entity;
235 $this->date_create = $obj->date_create;
236 $this->fk_user = $obj->fk_user;
237
238 $this->fetchAllCurrencyRate();
239 $this->getRate();
240 }
241 $this->db->free($resql);
242
243 if ($numrows) {
244 return 1;
245 } else {
246 return 0;
247 }
248 } else {
249 $this->errors[] = 'Error '.$this->db->lasterror();
250 dol_syslog('MultiCurrency::fetch '.implode(',', $this->errors), LOG_ERR);
251
252 return -1;
253 }
254 }
255
261 public function fetchAllCurrencyRate()
262 {
263 $sql = "SELECT cr.rowid";
264 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line." as cr";
265 $sql .= " WHERE cr.entity IN (".getEntity($this->element).")";
266 $sql .= " AND cr.fk_multicurrency = ".((int) $this->id);
267 $sql .= " ORDER BY cr.date_sync DESC";
268
269 $this->rates = array();
270
271 dol_syslog(__METHOD__, LOG_DEBUG);
272 $resql = $this->db->query($sql);
273 if ($resql) {
274 $num = $this->db->num_rows($resql);
275
276 while ($obj = $this->db->fetch_object($resql)) {
277 $rate = new CurrencyRate($this->db);
278 $rate->fetch($obj->rowid);
279
280 $this->rates[] = $rate;
281 }
282 $this->db->free($resql);
283
284 return $num;
285 } else {
286 $this->errors[] = 'Error '.$this->db->lasterror();
287 dol_syslog('MultiCurrency::fetchAllCurrencyRate '.implode(',', $this->errors), LOG_ERR);
288
289 return -1;
290 }
291 }
292
300 public function update(User $user, $notrigger = 0)
301 {
302 $error = 0;
303
304 dol_syslog('MultiCurrency::update', LOG_DEBUG);
305
306 // Clean parameters
307 $this->name = trim($this->name);
308 $this->code = trim($this->code);
309
310 // Check parameters
311 if (empty($this->code)) {
312 $error++;
313 dol_syslog('MultiCurrency::update $this->code can not be empty', LOG_ERR);
314
315 return -1;
316 }
317
318 // Update request
319 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
320 $sql .= " name = '".$this->db->escape($this->name)."',";
321 $sql .= " code = '".$this->db->escape($this->code)."'";
322 $sql .= " WHERE rowid = ".((int) $this->id);
323
324 $this->db->begin();
325
326 $resql = $this->db->query($sql);
327 if (!$resql) {
328 $error++;
329 $this->errors[] = 'Error '.$this->db->lasterror();
330 dol_syslog('MultiCurrency::update '.implode(',', $this->errors), LOG_ERR);
331 }
332
333 if (!$error && empty($notrigger)) {
334 $result = $this->call_trigger('CURRENCY_MODIFY', $user);
335 if ($result < 0) {
336 $error++;
337 }
338 }
339
340 // Commit or rollback
341 if ($error) {
342 $this->db->rollback();
343
344 return -1 * $error;
345 } else {
346 $this->db->commit();
347
348 return 1;
349 }
350 }
351
359 public function delete(User $user, $notrigger = 0)
360 {
361 dol_syslog('MultiCurrency::delete', LOG_DEBUG);
362
363 $error = 0;
364
365 $this->db->begin();
366
367 if (empty($notrigger)) {
368 $result = $this->call_trigger('CURRENCY_DELETE', $user);
369 if ($result < 0) {
370 $error++;
371 }
372 }
373
374 if (!$error) {
375 // Delete all rates before
376 if (!$this->deleteRates()) {
377 $error++;
378 $this->errors[] = 'Error '.$this->db->lasterror();
379 dol_syslog('Currency::delete '.implode(',', $this->errors), LOG_ERR);
380 }
381
382 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
383 $sql .= " WHERE rowid = ".((int) $this->id);
384
385 dol_syslog(__METHOD__, LOG_DEBUG);
386 $resql = $this->db->query($sql);
387 if (!$resql) {
388 $error++;
389 $this->errors[] = 'Error '.$this->db->lasterror();
390 dol_syslog('MultiCurrency::delete '.implode(',', $this->errors), LOG_ERR);
391 }
392 }
393
394 // Commit or rollback
395 if ($error) {
396 $this->db->rollback();
397
398 return -1 * $error;
399 } else {
400 $this->db->commit();
401
402 return 1;
403 }
404 }
405
411 public function deleteRates()
412 {
413 global $user;
414
415 foreach ($this->rates as &$rate) {
416 if ($rate->delete($user) <= 0) {
417 return false;
418 }
419 }
420
421 return true;
422 }
423
430 public function addRate($rate)
431 {
432 global $user;
433
434 $currencyRate = new CurrencyRate($this->db);
435 $currencyRate->rate = (float) price2num($rate);
436
437 if ($currencyRate->create($user, $this->id) > 0) {
438 $this->rate = $currencyRate;
439 return 1;
440 } else {
441 $this->rate = null;
442 $this->errors = $currencyRate->errors;
443 return -1;
444 }
445 }
446
454 public function addRateFromDolibarr($code, $rate)
455 {
456 global $user;
457
458 $currency = new MultiCurrency($this->db);
459 $currency->code = $code;
460 $currency->name = $code;
461
462 $sql = "SELECT label FROM ".MAIN_DB_PREFIX."c_currencies WHERE code_iso = '".$this->db->escape($code)."'";
463
464 dol_syslog(__METHOD__, LOG_DEBUG);
465 $resql = $this->db->query($sql);
466 if ($resql && ($line = $this->db->fetch_object($resql))) {
467 $currency->name = $line->label;
468 }
469
470 if ($currency->create($user) > 0) {
471 $currency->addRate($rate);
472
473 if (!empty($line)) {
474 return 2;
475 } else {
476 return 1;
477 }
478 }
479
480 return -1;
481 }
482
489 public function updateRate($rate)
490 {
491 return $this->addRate($rate);
492 }
493
499 public function getRate()
500 {
501 $sql = "SELECT cr.rowid";
502 $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line." as cr";
503 $sql .= " WHERE cr.entity IN (".getEntity($this->element).")";
504 $sql .= " AND cr.fk_multicurrency = ".((int) $this->id);
505 $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX.$this->table_element_line." AS cr2";
506 $sql .= " WHERE cr2.entity IN (".getEntity($this->element).") AND cr2.fk_multicurrency = ".((int) $this->id).")";
507
508 dol_syslog(__METHOD__, LOG_DEBUG);
509
510 $resql = $this->db->query($sql);
511 if ($resql && ($obj = $this->db->fetch_object($resql))) {
512 $this->rate = new CurrencyRate($this->db);
513 return $this->rate->fetch($obj->rowid);
514 }
515
516 return -1;
517 }
518
527 public static function getIdFromCode($dbs, $code)
528 {
529 global $conf;
530
531 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '".$dbs->escape($code)."' AND entity = ".((int) $conf->entity);
532
533 dol_syslog(__METHOD__, LOG_DEBUG);
534 $resql = $dbs->query($sql);
535 if ($resql && $obj = $dbs->fetch_object($resql)) {
536 return $obj->rowid;
537 } else {
538 return 0;
539 }
540 }
541
552 public static function getIdAndTxFromCode($dbs, $code, $date_document = 0)
553 {
554 $sql1 = "SELECT m.rowid, mc.rate, mc.rate_direct FROM ".MAIN_DB_PREFIX."multicurrency m";
555 $sql1 .= ' LEFT JOIN '.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)';
556 $sql1 .= " WHERE m.code = '".$dbs->escape($code)."'";
557 $sql1 .= " AND m.entity IN (".getEntity('multicurrency').")";
558 $sql2 = '';
559 if (getDolGlobalString('MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE') && !empty($date_document)) { // Use last known rate compared to document date
560 $tmparray = dol_getdate($date_document);
561 $sql2 .= " AND mc.date_sync <= '".$dbs->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'";
562 }
563 $sql3 = " ORDER BY mc.date_sync DESC LIMIT 1";
564
565 dol_syslog(__METHOD__, LOG_DEBUG);
566 $resql = $dbs->query($sql1.$sql2.$sql3);
567
568 if ($resql && $obj = $dbs->fetch_object($resql)) {
569 return array($obj->rowid, $obj->rate);
570 } else {
571 if (getDolGlobalString('MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE')) {
572 $resql = $dbs->query($sql1.$sql3);
573 if ($resql && $obj = $dbs->fetch_object($resql)) {
574 return array($obj->rowid, $obj->rate, $obj->rate_direct);
575 }
576 }
577
578 return array(0, 1);
579 }
580 }
581
592 public static function getAmountConversionFromInvoiceRate($fk_facture, $amount, $way = 'dolibarr', $table = 'facture', $invoice_rate = null)
593 {
594 if (!is_null($invoice_rate)) {
595 $multicurrency_tx = $invoice_rate;
596 } else {
597 $tmparray = self::getInvoiceRate($fk_facture, $table);
598 $multicurrency_tx = $tmparray['invoice_multicurrency_tx'];
599 }
600
601 if ($multicurrency_tx) {
602 if ($way == 'dolibarr') {
603 return (float) price2num($amount * $multicurrency_tx, 'MU');
604 } else {
605 return (float) price2num($amount / $multicurrency_tx, 'MU');
606 }
607 } else {
608 return false;
609 }
610 }
611
619 public static function getInvoiceRate($fk_facture, $table = 'facture')
620 {
621 global $db;
622
623 $sql = "SELECT multicurrency_tx, multicurrency_code";
624 $sql .= " FROM ".MAIN_DB_PREFIX.$db->sanitize($table);
625 $sql .= " WHERE rowid = ".((int) $fk_facture);
626
627 dol_syslog(__METHOD__, LOG_DEBUG);
628 $resql = $db->query($sql);
629 if ($resql && ($line = $db->fetch_object($resql))) {
630 return array('invoice_multicurrency_tx' => $line->multicurrency_tx, 'invoice_multicurrency_code' => $line->multicurrency_code);
631 }
632
633 return false;
634 }
635
644 public function recalculRates(&$TRate)
645 {
646 if (getDolCurrency() != getDolGlobalString('MULTICURRENCY_APP_SOURCE')) {
647 $alternate_source = 'USD'.getDolCurrency();
648 if (!empty($TRate->$alternate_source)) {
649 $coef = 1 / $TRate->$alternate_source;
650 foreach ($TRate as $attr => &$rate) {
651 $rate *= $coef;
652 }
653 $TRate->USDUSD = $coef;
654 return 1;
655 }
656
657 return -1; // Alternate source not found
658 }
659
660 return 0; // Nothing to do
661 }
662
672 public function syncRates($nu = 0, $addifnotfound = 0, $mode = "")
673 {
674 global $db, $langs;
675
676 if (getDolGlobalString('MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER')) {
677 $this->output = $langs->trans('Use of API for currency update is disabled by option MULTICURRENCY_DISABLE_SYNC_CURRENCYLAYER');
678 $this->errors[] = $this->output;
679 return -1;
680 }
681
682 include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
683
684 $provider = getDolGlobalString('MULTICURRENCY_APP_PROVIDER', 'currencylayer');
685 $urlendpoint = $this->urlendpoint;
686
687 dol_syslog("Call url endpoint ".$urlendpoint);
688
689 // Frankfurter is free and needs no API key; currencylayer/apilayer require one.
690 $addheaders = array();
691 if ($provider != 'frankfurter') {
692 $addheaders[] = 'apikey: '.getDolGlobalString('MULTICURRENCY_APP_KEY');
693 }
694
695 $resget = getURLContent($urlendpoint, 'GET', '', 1, $addheaders);
696
697 // Example of result with https://currencylayer.com/live and https://api.apilayer.com/currency_data/live
698 // 'content' => string '{"success":true,"terms":"https:\/\/currencylayer.com\/terms","privacy":"https:\/\/currencylayer.com\/privacy","timestamp":1742562
699 // 251,"source":"USD","quotes":{"USDAED":3.67302,"USDAFN":70.6213,"USDALL":91.042287,"USDAMD":390.984233,"USDANG":1.802039,"USDAOA":913.498241,"USDARS":1
700 // 068.745088,"USDAUD":1.591824,"USDAWG":1.8,"USDAZN":1.699323,"USDBAM":1.80224,"USDBBD":2.018881,"USDBDT":121.488567,"USDBGN":1.802745,"USDBHD":0.376878
701 // ,"USDBIF":2963.403228,"USDBMD":1,"USDBND":1.333573,"USDBOB":6.909262,"USDBRL":5.721'... (length=3337)
702 //
703 // Example of result with https://api.frankfurter.dev/v1/latest (no key, ECB rates, ~30 currencies):
704 // 'content' => string '{"amount":1.0,"base":"USD","date":"2026-09-17","rates":{"AUD":1.4057,"BRL":5.1307,"CAD":1.3995,"EUR":0.871,"GBP":0.74758,...}}'
705 //var_dump($urlendpoint);
706 //var_dump($resget);
707
708 if (empty($resget['content'])) {
709 $this->output = $resget['curl_error_msg'];
710 $this->errors[] = $this->output;
711
712 return -1;
713 }
714
715 $response = json_decode($resget['content']);
716
717 $TRate = null;
718 $error_info = '';
719 $error_info_syslog = '';
720
721 if ($provider == 'frankfurter') {
722 if (!empty($response->rates) && is_object($response->rates)) {
723 // Frankfurter never includes the base currency itself in 'rates', add it back
724 // so recalculRates()'s pivot lookup (USD<localcurrency>) keeps working the same
725 // way it does for currencylayer's response, which does include it.
726 $sourcecode = !empty($response->base) ? $response->base : getDolGlobalString('MULTICURRENCY_APP_SOURCE', 'USD');
727 $TRate = new stdClass();
728 foreach ($response->rates as $code => $rate) {
729 $TRate->{$sourcecode.$code} = $rate;
730 }
731 $TRate->{$sourcecode.$sourcecode} = 1.0;
732 } else {
733 $error_info = !empty($response->message) ? $response->message : (!empty($response->error) ? $response->error : json_encode($response));
734 $error_info_syslog = $error_info;
735 }
736 } else {
737 // currencylayer / apilayer
738 if (!empty($response->success)) {
739 $TRate = $response->quotes;
740 //$timestamp = $response->timestamp;
741 } else {
742 if (isset($response->error->info)) { // @phan-suppress-current-line PhanTypeExpectedObjectPropAccess
743 $error_info_syslog = $response->error->info; // @phan-suppress-current-line PhanTypeExpectedObjectPropAccess
744 $error_info = $error_info_syslog;
745 } else {
746 $error_info_syslog = json_encode($response);
747 $error_info = $resget['content'];
748 }
749 }
750 }
751
752 if ($TRate !== null) {
753 // Recalculate rate and update it (or add it) into database
754 if ($this->recalculRates($TRate) >= 0) {
755 foreach ($TRate as $currency_code => $rate) {
756 $code = substr($currency_code, 3, 3);
757 $obj = new MultiCurrency($db);
758 if ($obj->fetch(0, $code) > 0) {
759 $obj->updateRate($rate);
760 } elseif ($addifnotfound) {
761 $this->addRateFromDolibarr($code, $rate);
762 }
763 }
764 }
765
766 if ($mode == "cron") {
767 return 0;
768 }
769 return 1;
770 } else {
771 dol_syslog("Failed to call endpoint ".$error_info_syslog, LOG_WARNING);
772
773 $this->output = $langs->trans('multicurrency_syncronize_error', $error_info);
774 $this->errors[] = $this->output;
775
776 return -1;
777 }
778 }
779
786 public function checkCodeAlreadyExists($code)
787 {
788 $currencytmp = new MultiCurrency($this->db);
789 if ($currencytmp->fetch(0, $code) > 0) {
790 return true;
791 } else {
792 return false;
793 }
794 }
795}
Class CurrencyRate.
Class to manage Dolibarr database access.
Class Currency.
static getInvoiceRate($fk_facture, $table='facture')
Get current invoite rate.
getRate()
Fetch CurrencyRate object in $this->rate.
static getIdAndTxFromCode($dbs, $code, $date_document=0)
Get id and rate of currency from code.
update(User $user, $notrigger=0)
Update object into database.
syncRates($nu=0, $addifnotfound=0, $mode="")
Sync rates from API.
fetchAllCurrencyRate()
Load all rates in object from the database.
static getAmountConversionFromInvoiceRate($fk_facture, $amount, $way='dolibarr', $table='facture', $invoice_rate=null)
Get the conversion of amount with invoice rate.
checkCodeAlreadyExists($code)
Check in database if the current code already exists.
updateRate($rate)
Add new entry into llx_multicurrency_rate.
static getIdFromCode($dbs, $code)
Get id of currency from code.
__construct(DoliDB $db)
Constructor.
deleteRates()
Delete rates in database.
create(User $user, $notrigger=0)
Create object into database.
addRateFromDolibarr($code, $rate)
Try get label of code in llx_currency then add rate.
recalculRates(&$TRate)
With free account we can't set source to something else than US, to we recalculate all rates to force...
fetch($id, $code=null)
Load object in memory from the database.
addRate($rate)
Add a Rate into database.
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
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...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getDolCurrency()
Return the main currency ('EUR', 'USD', ...)
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1, $timeoutconnect=0, $timeoutresponse=0, $otherCurlOptions=array(), $morelogsuffix='')
Function to get a content from an URL (use proxy if proxy defined).
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140