dolibarr 20.0.0
context.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2023-2024 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26require_once __DIR__ . '/controller.class.php';
27require_once __DIR__ . '/webPortalTheme.class.php';
28
33{
39 private static $_instance = null;
40
44 public $db;
45
49 public $title;
50
54 public $desc;
55
59 public $meta_title;
60
64 public $meta_desc;
65
70 public $appliName;
71
75 public $controller;
76
80 public $controller_found = false;
81
85 private $controllers = array();
86
90 public $controllerInstance;
91
96 public $error;
97
101 public $errors = array();
102
106 public $action;
107
108 public $tplDir;
109 public $tplPath;
110 public $topMenu;
111
112 public $rootUrl;
113
114 public $menu_active = array();
115
116 public $eventMessages = array();
117
118 public $tokenKey = 'token';
119
124 public $object;
125
129 public $logged_user = null;
130
134 public $logged_thirdparty = null;
135
139 public $logged_member = null;
140
144 public $logged_partnership = null;
145
146
150 public $theme;
151
152
158 private function __construct()
159 {
160 global $conf, $db;
161
162 $this->db = $db;
163
164 $this->tplDir = __DIR__ . '/../';
165
166 $this->getControllerUrl();
167
168 $this->topMenu = new stdClass();
169
170 $this->tplPath = realpath(__DIR__ . '/../../public/webportal/tpl');
171
172 $this->controller = GETPOST('controller', 'aZ09'); // for security, limited to 'aZ09'
173 $this->action = GETPOST('action', 'aZ09');// for security, limited to 'aZ09'
174
175 if (empty($this->controller)) {
176 $this->controller = 'default';
177 }
178
179 $this->appliName = getDolGlobalString('WEBPORTAL_TITLE', getDolGlobalString('MAIN_INFO_SOCIETE_NOM'));
180
181 //$this->generateNewToken();
182
183 $this->initController();
184
185 // Init de l'url de base
186 $this->rootUrl = self::getRootConfigUrl();
187
188
189 $this->theme = new WebPortalTheme();
190 }
191
197 public static function getInstance()
198 {
199 if (is_null(self::$_instance)) {
200 self::$_instance = new Context();
201 }
202
203 return self::$_instance;
204 }
205
211 public function initController()
212 {
213 global $db;
214
215 $defaultControllersPath = __DIR__ . '/../controllers/';
216
217 // define controllers definition
218 $this->addControllerDefinition('login', $defaultControllersPath . 'login.controller.class.php', 'LoginController');
219 $this->addControllerDefinition('default', $defaultControllersPath . 'default.controller.class.php', 'DefaultController');
220 $this->addControllerDefinition('document', $defaultControllersPath . 'document.controller.class.php', 'DocumentController');
221 $this->addControllerDefinition('propallist', $defaultControllersPath . 'propallist.controller.class.php', 'PropalListController');
222 $this->addControllerDefinition('orderlist', $defaultControllersPath . 'orderlist.controller.class.php', 'OrderListController');
223 $this->addControllerDefinition('invoicelist', $defaultControllersPath . 'invoicelist.controller.class.php', 'InvoiceListController');
224 $this->addControllerDefinition('membercard', $defaultControllersPath . 'membercard.controller.class.php', 'MemberCardController');
225 $this->addControllerDefinition('partnershipcard', $defaultControllersPath . 'partnershipcard.controller.class.php', 'PartnershipCardController');
226
227 // call triggers
228 //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
229 //$interface=new Interfaces($db);
230 //$interface->run_triggers('WebPortalInitController', $this, $logged_user, $langs, $conf);
231
232 // search for controller
233 $this->controllerInstance = new Controller();
234 if (isset($this->controllers[$this->controller]) && file_exists($this->controllers[$this->controller]->path)) {
235 require_once $this->controllers[$this->controller]->path;
236
237 if (class_exists($this->controllers[$this->controller]->class)) {
238 $this->controllerInstance = new $this->controllers[$this->controller]->class();
239 $this->setControllerFound();
240 }
241 }
242 }
243
252 public function addControllerDefinition($controller, $path, $className)
253 {
254 $fileName = basename($path);
255 $needle = '.controller.class.php';
256 $length = strlen($needle);
257 $isControllerFile = $length > 0 ? substr($fileName, -$length) === $needle : true;
258 if (!$isControllerFile) {
259 $this->setError('Error: controller definition ' . $fileName);
260 return false;
261 }
262
263 $this->controllers[$controller] = new stdClass();
264 $this->controllers[$controller]->path = $path;
265 $this->controllers[$controller]->class = $className;
266
267 return true;
268 }
269
275 public function setControllerFound()
276 {
277 $this->controller_found = true;
278 }
279
285 public static function getRootConfigUrl()
286 {
287 global $conf;
288
289 // Init de l'url de base
290 if (getDolGlobalString('WEBPORTAL_ROOT_URL')) {
291 $rootUrl = getDolGlobalString('WEBPORTAL_ROOT_URL');
292 if (substr($rootUrl, -1) !== '/') {
293 $rootUrl .= '/';
294 }
295 } else {
296 $rootUrl = dol_buildpath('/public/webportal/', 2);
297 }
298
299 return $rootUrl;
300 }
301
311 public function getRootUrl($controller = '', $moreParams = '', $addToken = true)
312 {
313 return self::getControllerUrl($controller, $moreParams, $addToken);
314 }
315
324 public function getControllerUrl($controller = '', $moreParams = '', $addToken = true)
325 {
326 // TODO : addToken parameter on auto to detect (create or edit) action and add token on url
327 $url = $this->rootUrl;
328
329 if (empty($controller)) {
330 // because can be called without params to get only rootUrl
331 return $url;
332 }
333
334 $Tparams = array();
335
336 $Tparams['controller'] = $controller;
337
338 if (!empty($addToken)) {
339 $Tparams[$this->tokenKey] = $this->newToken();
340 }
341
342 return self::getPublicControllerUrl($controller, $moreParams, $Tparams);
343 }
344
355 public static function getPublicControllerUrl($controller = '', $moreParams = '', $Tparams = array())
356 {
357 $url = self::getRootConfigUrl();
358
359 if (empty($controller)) {
360 // because can be called without params to get only rootUrl
361 return $url;
362 }
363
364 $Tparams['controller'] = $controller;
365
366 // if $moreParams is an array
367 if (!empty($moreParams) && is_array($moreParams)) {
368 if (isset($moreParams['controller'])) {
369 unset($moreParams['controller']);
370 }
371 if (!empty($moreParams)) {
372 foreach ($moreParams as $paramKey => $paramVal) {
373 $Tparams[$paramKey] = $paramVal;
374 }
375 }
376 }
377
378 if (!empty($Tparams)) {
379 $TCompiledAttr = array();
380 foreach ($Tparams as $key => $value) {
381 $TCompiledAttr[] = $key . '=' . $value;
382 }
383 $url .= '?' . implode("&", $TCompiledAttr);
384 }
385
386 // if $moreParams is a string
387 if (!empty($moreParams) && !is_array($moreParams)) {
388 if (empty($Tparams)) {
389 if ($moreParams[0] !== '?') {
390 $url .= '?';
391 }
392 if ($moreParams[0] === '&') {
393 $moreParams = substr($moreParams, 1);
394 }
395 }
396 $url .= $moreParams;
397 }
398
399 return $url;
400 }
401
409 public static function urlOrigin($withRequestUri = true, $use_forwarded_host = false)
410 {
411 $s = $_SERVER;
412
413 $ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on');
414 $sp = strtolower($s['SERVER_PROTOCOL']);
415 $protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
416 $port = $s['SERVER_PORT'];
417 $port = ((!$ssl && $port == '80') || ($ssl && $port == '443')) ? '' : ':' . $port;
418 $host = ($use_forwarded_host && isset($s['HTTP_X_FORWARDED_HOST'])) ? $s['HTTP_X_FORWARDED_HOST'] : (isset($s['HTTP_HOST']) ? $s['HTTP_HOST'] : null);
419 $host = isset($host) ? $host : $s['SERVER_NAME'] . $port;
420
421 $url = $protocol . '://' . $host;
422
423 if ($withRequestUri) {
424 $url .= $s['REQUEST_URI'];
425 }
426
427 return $url;
428 }
429
435 public function userIsLog()
436 {
437 if (!empty($_SESSION["webportal_logged_thirdparty_account_id"])) {
438 return true;
439 } else {
440 return false;
441 }
442 }
443
450 public function menuIsActive($menuName)
451 {
452 return in_array($menuName, $this->menu_active);
453 }
454
461 public function setError($errors)
462 {
463 if (!is_array($errors)) {
464 $errors = array($errors);
465 }
466 if (!isset($_SESSION['webportal_errors'])) {
467 $_SESSION['webportal_errors'] = array();
468 }
469 foreach ($errors as $msg) {
470 if (!in_array($msg, $_SESSION['webportal_errors'])) {
471 $_SESSION['webportal_errors'][] = $msg;
472 }
473 }
474 }
475
481 public function getErrors()
482 {
483 if (!empty($_SESSION['webportal_errors'])) {
484 $this->errors = array_values($_SESSION['webportal_errors']);
485 return count($this->errors);
486 }
487
488 return 0;
489 }
490
496 public function clearErrors()
497 {
498 unset($_SESSION['webportal_errors']);
499 $this->errors = array();
500 }
501
510 public function setEventMessage($mesgs, $style = 'mesgs')
511 {
512 $TAcceptedStyle = array('mesgs', 'warnings', 'errors');
513
514 if (!in_array($style, $TAcceptedStyle)) {
515 $style = 'mesgs';
516 }
517
518 if (!is_array($mesgs)) {
519 $mesgs = array($mesgs);
520 }
521 if (!isset($_SESSION['webportal_events'])) {
522 $_SESSION['webportal_events'] = array(
523 'mesgs' => array(), 'warnings' => array(), 'errors' => array()
524 );
525 }
526
527 foreach ($mesgs as $msg) {
528 if (!in_array($msg, $_SESSION['webportal_events'][$style])) {
529 $_SESSION['webportal_events'][$style][] = $msg;
530 }
531 }
532 }
533
543 public function setEventMessages($mesg, $mesgs, $style = 'mesgs')
544 {
545 if (empty($mesg) && empty($mesgs)) {
546 dol_syslog(__METHOD__ . ' Try to add a message in stack, but value to add is empty message', LOG_WARNING);
547 } else {
548 if (!in_array((string) $style, array('mesgs', 'warnings', 'errors'))) {
549 dol_print_error('', 'Bad parameter style=' . $style . ' for setEventMessages');
550 }
551 if (empty($mesgs)) {
552 $this->setEventMessage($mesg, $style);
553 } else {
554 if (!empty($mesg) && !in_array($mesg, $mesgs)) {
555 $this->setEventMessage($mesg, $style); // Add message string if not already into array
556 }
557 $this->setEventMessage($mesgs, $style);
558 }
559 }
560 }
561
567 public function loadEventMessages()
568 {
569 if (!empty($_SESSION['webportal_events'])) {
570 $this->eventMessages = $_SESSION['webportal_events'];
571 return 1;
572 }
573
574 return 0;
575 }
576
582 public function clearEventMessages()
583 {
584 unset($_SESSION['webportal_events']);
585 $this->eventMessages = array();
586 }
587
595 public function newToken()
596 {
597 return newToken();
598 }
599
605 protected function generateNewToken()
606 {
607 $currentToken = $this->newToken();
608 // Creation of a token against CSRF vulnerabilities
609 if (!defined('NOTOKENRENEWAL') || empty($currentToken)) {
610 // Rolling token at each call ($_SESSION['token'] contains token of previous page)
611 if (isset($_SESSION['newtoken'])) {
612 $_SESSION['token'] = $_SESSION['newtoken'];
613 }
614
615 // Save what will be next token. Into forms, we will add param $context->newToken();
616 $token = dol_hash(uniqid((string) mt_rand(), true)); // Generate
617 $_SESSION['newtoken'] = $token;
618
619 return $token;
620 } else {
621 return $this->newToken();
622 }
623 }
624
630 public function getUrlToken()
631 {
632 $token = $this->newToken();
633 if ($token) {
634 return '&' . $this->tokenKey . '=' . $this->newToken();
635 }
636
637 return null;
638 }
639
645 public function getFormToken()
646 {
647 $token = $this->newToken();
648 if ($token) {
649 return '<input type="hidden" name="' . $this->tokenKey . '" value="' . $this->newToken() . '" />';
650 }
651
652 return null;
653 }
654
662 public function getThirdPartyAccountFromLogin($login, $pass)
663 {
664 $id = 0;
665
666 $sql = "SELECT sa.rowid as id, sa.pass_crypted";
667 $sql .= " FROM " . $this->db->prefix() . "societe_account as sa";
668 $sql .= " WHERE BINARY sa.login = '" . $this->db->escape($login) . "'"; // case sensitive
669 //$sql .= " AND BINARY sa.pass_crypted = '" . $this->db->escape($pass) . "'"; // case sensitive
670 $sql .= " AND sa.site = 'dolibarr_portal'";
671 $sql .= " AND sa.status = 1";
672 $sql .= " AND sa.entity IN (" . getEntity('societe') . ")";
673
674 dol_syslog(__METHOD__ . ' Try to find the third-party account id for login"' . $login . '" and site="dolibarr_portal"', LOG_DEBUG);
675 $result = $this->db->query($sql);
676 if ($result) {
677 if ($this->db->num_rows($result) == 1) {
678 $passok = false;
679 $obj = $this->db->fetch_object($result);
680 if ($obj) {
681 $passcrypted = $obj->pass_crypted;
682
683 // Check crypted password
684 $cryptType = '';
685 if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) {
686 $cryptType = getDolGlobalString('DATABASE_PWD_ENCRYPTED');
687 }
688
689 // By default, we use default setup for encryption rule
690 if (!in_array($cryptType, array('auto'))) {
691 $cryptType = 'auto';
692 }
693
694 // Check crypted password according to crypt algorithm
695 if ($cryptType == 'auto') {
696 if ($passcrypted && dol_verifyHash($pass, $passcrypted, '0')) {
697 $passok = true;
698 }
699 }
700
701 // Password ok ?
702 if ($passok) {
703 $id = $obj->id;
704 } else {
705 dol_syslog(__METHOD__ .' Authentication KO bad password for ' . $login . ', cryptType=' . $cryptType, LOG_NOTICE);
706 sleep(1); // Brut force protection. Must be same delay when login is not valid
707 return -3;
708 }
709 }
710 } else {
711 dol_syslog(__METHOD__ . ' Many third-party account found for login"' . $login . '" and site="dolibarr_portal"', LOG_ERR);
712 return -2;
713 }
714 } else {
715 $this->error = $this->db->lasterror();
716 return -1;
717 }
718
719 return $id;
720 }
721}
Class Context.
static urlOrigin($withRequestUri=true, $use_forwarded_host=false)
Url origin.
generateNewToken()
Generate new token.
menuIsActive($menuName)
Is menu enabled ?
getErrors()
Get errors.
static getInstance()
Singleton method to create one instance of this object.
$object
Current object of page.
clearEventMessages()
Clear event messages.
getFormToken()
Get token input for form.
newToken()
Return the value of token currently saved into session with name 'newToken'.
setError($errors)
Set errors.
userIsLog()
Check if user is logged.
getUrlToken()
Get token url.
addControllerDefinition($controller, $path, $className)
Add controller definition.
initController()
Init controller.
getRootUrl($controller='', $moreParams='', $addToken=true)
Get root url.
static getPublicControllerUrl($controller='', $moreParams='', $Tparams=array())
Generate public controller URL Used for external link (like email or web page) so remove token and co...
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
getThirdPartyAccountFromLogin($login, $pass)
Try to find the third-party account id from.
setControllerFound()
Set controller found.
getControllerUrl($controller='', $moreParams='', $addToken=true)
Get controller url according to context.
static getRootConfigUrl()
Get WebPortal root url.
$appliName
The application name.
setEventMessage($mesgs, $style='mesgs')
Set event messages in dol_events session object.
__construct()
Constructor.
loadEventMessages()
Load event messages.
clearErrors()
Clear errors.
Class to manage pages.
Class WebPortalTheme.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.