Fix & enable PhanPluginUnknownClosureParamType

# Fix & enable PhanPluginUnknownClosureParamType

Typing of anonymous functions to fix this notice.
Optimised some minor things.
This commit is contained in:
MDW 2024-03-14 21:59:15 +01:00
parent 5006fed84b
commit a408288ba1
No known key found for this signature in database
15 changed files with 355 additions and 223 deletions

View File

@ -453,7 +453,7 @@ return [
'PhanTypeInvalidDimOffset',
// 'PhanPluginNoCommentOnProtectedProperty',
// 'PhanPluginDescriptionlessCommentOnPublicMethod',
'PhanPluginUnknownClosureParamType',
// 'PhanPluginUnknownClosureParamType',
'PhanPluginUnknownClosureReturnType',
// 'PhanPluginNoCommentOnProtectedMethod',
// 'PhanTypeArraySuspicious',

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2005-2009 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -308,21 +309,37 @@ print '</tr>';
// sort list
if ($sortfield == "name" && $sortorder == "asc") {
usort($moduleList, function (stdClass $a, stdClass $b) {
return strcasecmp($a->name, $b->name);
});
usort(
$moduleList,
/** @return bool */
function (stdClass $a, stdClass $b) {
return strcasecmp($a->name, $b->name);
}
);
} elseif ($sortfield == "name" && $sortorder == "desc") {
usort($moduleList, function (stdClass $a, stdClass $b) {
return strcasecmp($b->name, $a->name);
});
usort(
$moduleList,
/** @return bool */
static function (stdClass $a, stdClass $b) {
return strcasecmp($b->name, $a->name);
}
);
} elseif ($sortfield == "version" && $sortorder == "asc") {
usort($moduleList, function (stdClass $a, stdClass $b) {
return strcasecmp($a->version, $b->version);
});
usort(
$moduleList,
/** @return bool */
static function (stdClass $a, stdClass $b) {
return strcasecmp($a->version, $b->version);
}
);
} elseif ($sortfield == "version" && $sortorder == "desc") {
usort($moduleList, function (stdClass $a, stdClass $b) {
return strcasecmp($b->version, $a->version);
});
usort(
$moduleList,
/** @return bool */
static function (stdClass $a, stdClass $b) {
return strcasecmp($b->version, $a->version);
}
);
} elseif ($sortfield == "id" && $sortorder == "asc") {
usort($moduleList, "compareIdAsc");
} elseif ($sortfield == "id" && $sortorder == "desc") {

View File

@ -3,6 +3,7 @@
* Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2005-2021 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -60,96 +61,96 @@ clearstatcache();
$workflowcodes = array(
// Automatic creation
'WORKFLOW_PROPAL_AUTOCREATE_ORDER'=>array(
'family'=>'create',
'position'=>10,
'enabled'=>(isModEnabled("propal") && isModEnabled('order')),
'picto'=>'order'
'WORKFLOW_PROPAL_AUTOCREATE_ORDER' => array(
'family' => 'create',
'position' => 10,
'enabled' => (isModEnabled("propal") && isModEnabled('order')),
'picto' => 'order'
),
'WORKFLOW_ORDER_AUTOCREATE_INVOICE'=>array(
'family'=>'create',
'position'=>20,
'enabled'=>(isModEnabled('order') && isModEnabled('invoice')),
'picto'=>'bill'
'WORKFLOW_ORDER_AUTOCREATE_INVOICE' => array(
'family' => 'create',
'position' => 20,
'enabled' => (isModEnabled('order') && isModEnabled('invoice')),
'picto' => 'bill'
),
'WORKFLOW_TICKET_CREATE_INTERVENTION' => array(
'family'=>'create',
'position'=>25,
'enabled'=>(isModEnabled('ticket') && isModEnabled('intervention')),
'picto'=>'ticket'
'family' => 'create',
'position' => 25,
'enabled' => (isModEnabled('ticket') && isModEnabled('intervention')),
'picto' => 'ticket'
),
'separator1'=>array('family'=>'separator', 'position'=>25, 'title'=>'', 'enabled'=>((isModEnabled("propal") && isModEnabled('order')) || (isModEnabled('order') && isModEnabled('invoice')) || (isModEnabled('ticket') && isModEnabled('intervention')))),
'separator1' => array('family' => 'separator', 'position' => 25, 'title' => '', 'enabled' => ((isModEnabled("propal") && isModEnabled('order')) || (isModEnabled('order') && isModEnabled('invoice')) || (isModEnabled('ticket') && isModEnabled('intervention')))),
// Automatic classification of proposal
'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL'=>array(
'family'=>'classify_proposal',
'position'=>30,
'enabled'=>(isModEnabled("propal") && isModEnabled('order')),
'picto'=>'propal',
'warning'=>''
'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL' => array(
'family' => 'classify_proposal',
'position' => 30,
'enabled' => (isModEnabled("propal") && isModEnabled('order')),
'picto' => 'propal',
'warning' => ''
),
'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL'=>array(
'family'=>'classify_proposal',
'position'=>31,
'enabled'=>(isModEnabled("propal") && isModEnabled('invoice')),
'picto'=>'propal',
'warning'=>''
'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL' => array(
'family' => 'classify_proposal',
'position' => 31,
'enabled' => (isModEnabled("propal") && isModEnabled('invoice')),
'picto' => 'propal',
'warning' => ''
),
// Automatic classification of order
'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array( // when shipping validated
'family'=>'classify_order',
'position'=>40,
'enabled'=>(isModEnabled("shipping") && isModEnabled('order')),
'picto'=>'order'
'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING' => array( // when shipping validated
'family' => 'classify_order',
'position' => 40,
'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
'picto' => 'order'
),
'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED'=>array( // when shipping closed
'family'=>'classify_order',
'position'=>41,
'enabled'=>(isModEnabled("shipping") && isModEnabled('order')),
'picto'=>'order'
'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED' => array( // when shipping closed
'family' => 'classify_order',
'position' => 41,
'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
'picto' => 'order'
),
'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array(
'family'=>'classify_order',
'position'=>42,
'enabled'=>(isModEnabled('invoice') && isModEnabled('order')),
'picto'=>'order',
'warning'=>''
'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER' => array(
'family' => 'classify_order',
'position' => 42,
'enabled' => (isModEnabled('invoice') && isModEnabled('order')),
'picto' => 'order',
'warning' => ''
), // For this option, if module invoice is disabled, it does not exists, so "Classify billed" for order must be done manually from order card.
// Automatic classification supplier proposal
'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL'=>array(
'family'=>'classify_supplier_proposal',
'position'=>60,
'enabled'=>(isModEnabled('supplier_proposal') && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
'picto'=>'supplier_proposal',
'warning'=>''
'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL' => array(
'family' => 'classify_supplier_proposal',
'position' => 60,
'enabled' => (isModEnabled('supplier_proposal') && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
'picto' => 'supplier_proposal',
'warning' => ''
),
// Automatic classification supplier order
'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION'=>array(
'family'=>'classify_supplier_order',
'position'=>63,
'enabled'=>(getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
'picto'=>'supplier_order',
'warning'=>''
'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION' => array(
'family' => 'classify_supplier_order',
'position' => 63,
'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
'picto' => 'supplier_order',
'warning' => ''
),
'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED'=>array(
'family'=>'classify_supplier_order',
'position'=>64,
'enabled'=>(getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
'picto'=>'supplier_order',
'warning'=>''
'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED' => array(
'family' => 'classify_supplier_order',
'position' => 64,
'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
'picto' => 'supplier_order',
'warning' => ''
),
'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array(
'family'=>'classify_supplier_order',
'position'=>65,
'enabled'=>(isModEnabled("supplier_order") || isModEnabled("supplier_invoice")),
'picto'=>'supplier_order',
'warning'=>''
'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER' => array(
'family' => 'classify_supplier_order',
'position' => 65,
'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")),
'picto' => 'supplier_order',
'warning' => ''
),
// Automatic classification shipping
@ -188,7 +189,7 @@ $workflowcodes = array(
),
'separator2'=>array('family'=>'separator', 'position'=>400, 'enabled' => (isModEnabled('ticket') && isModEnabled('contract'))),
'separator2' => array('family' => 'separator', 'position' => 400, 'enabled' => (isModEnabled('ticket') && isModEnabled('contract'))),
// Automatic link ticket -> contract
'WORKFLOW_TICKET_LINK_CONTRACT' => array(
@ -212,9 +213,16 @@ if (!empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['w
}
// remove not available workflows (based on activated modules and global defined keys)
$workflowcodes = array_filter($workflowcodes, function ($var) {
return $var['enabled'];
});
$workflowcodes = array_filter(
$workflowcodes,
/**
* @param array{enabled:int<0,1>} $var
* @return int<0,1>
*/
static function ($var) {
return $var['enabled'];
}
);

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2023 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,11 +20,16 @@
// Create the autoloader for Luracast
require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/AutoLoader.php';
call_user_func(function () {
$loader = Luracast\Restler\AutoLoader::instance();
spl_autoload_register($loader);
return $loader;
});
call_user_func(
/**
* @return Luracast\Restler\AutoLoader
*/
static function () {
$loader = Luracast\Restler\AutoLoader::instance();
spl_autoload_register($loader);
return $loader;
}
);
require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/iAuthenticate.php';
require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/iUseAuthentication.php';

View File

@ -3,6 +3,7 @@
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2017 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2021 Alexis LAURIER <contact@alexislaurier.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -91,11 +92,16 @@ if (!$res) {
require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/AutoLoader.php';
call_user_func(function () {
$loader = Luracast\Restler\AutoLoader::instance();
spl_autoload_register($loader);
return $loader;
});
call_user_func(
/**
* @return Luracast\Restler\AutoLoader
*/
static function () {
$loader = Luracast\Restler\AutoLoader::instance();
spl_autoload_register($loader);
return $loader;
}
);
require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php';

View File

@ -7,6 +7,7 @@
* Copyright (C) 2016-2023 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1491,9 +1492,17 @@ abstract class CommonDocGenerator
if (!empty($fields)) {
// Sort extrafields by rank
uasort($fields, function ($a, $b) {
return ($a->rank > $b->rank) ? 1 : -1;
});
uasort(
$fields,
/**
* @param stdClass $a
* @param stdClass $b
* @return int<-1,1>
*/
static function ($a, $b) {
return ($a->rank > $b->rank) ? 1 : -1;
}
);
// define some HTML content with style
$html .= !empty($params['style']) ? '<style>'.$params['style'].'</style>' : '';

View File

@ -7929,9 +7929,17 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
// We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step (preg_replace).
// No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are
// using a non coventionnel way to be encoded, to not have them sanitized just after)
$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', function ($m) {
return realCharForNumericEntities($m);
}, $out);
$out = preg_replace_callback(
'/&#(x?[0-9][0-9a-f]+;?)/i',
/**
* @param string $m
* @return string
*/
static function ($m) {
return realCharForNumericEntities($m);
},
$out
);
// Now we remove all remaining HTML entities starting with a number. We don't want such entities.

View File

@ -1,5 +1,6 @@
<?php
/* Copyright (C) 2009-2010 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1210,9 +1211,16 @@ function updateDictionaryInFile($module, $file, $dicts)
$dicData .= "\t\t\t'$key'=>";
if ($key === 'tabcond') {
$conditions = array_map(function ($val) use ($module) {
return ($val === true || $val === false) ? "isModEnabled('$module')" : $val;
}, $value);
$conditions = array_map(
/**
* @param bool|int|string $val
* @return string|int
*/
function ($val) use ($module) {
return is_bool($val) ? "isModEnabled('$module')" : $val;
},
$value
);
$dicData .= "array(" . implode(",", $conditions) . ")";
} elseif ($key === 'tabhelp') {
$helpItems = array();
@ -1222,9 +1230,19 @@ function updateDictionaryInFile($module, $file, $dicts)
$dicData .= "array(" . implode(",", $helpItems) . ")";
} else {
if (is_array($value)) {
$dicData .= "array(" . implode(",", array_map(function ($val) {
return "'$val'";
}, $value)) . ")";
$dicData .= "array(" . implode(
",",
array_map(
/**
* @param string $val
* @return string
*/
static function ($val) {
return "'$val'";
},
$value
)
) . ")";
} else {
$dicData .= "'$value'";
}

View File

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2018 Destailleur Laurent <eldy@users.sourceforge.net>
* Copyright (C) 2019 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -92,69 +93,76 @@ $tmpDir = $conf->dav->multidir_output[$entity]; // We need root dir, not a dir t
// Authentication callback function
$authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function ($username, $password) {
global $user, $conf;
global $dolibarr_main_authentication, $dolibarr_auto_user;
$authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(
/**
* @param string $username Username to validate as a login
* @param string $password Password to validate for $username
* @return true True if login ok, false if not
*/
static function ($username, $password) {
global $user, $conf;
global $dolibarr_main_authentication, $dolibarr_auto_user;
if (empty($user->login)) {
dol_syslog("Failed to authenticate to DAV, login is not provided", LOG_WARNING);
return false;
}
if ($user->socid > 0) {
dol_syslog("Failed to authenticate to DAV, user is an external user", LOG_WARNING);
return false;
}
if ($user->login != $username) {
dol_syslog("Failed to authenticate to DAV, login does not match the login of loaded user", LOG_WARNING);
return false;
}
// Authentication mode
if (empty($dolibarr_main_authentication)) {
$dolibarr_main_authentication = 'dolibarr';
}
// Authentication mode: forceuser
if ($dolibarr_main_authentication == 'forceuser') {
if (empty($dolibarr_auto_user)) {
$dolibarr_auto_user = 'auto';
}
if ($dolibarr_auto_user != $username) {
dol_syslog("Warning: your instance is set to use the automatic forced login '".$dolibarr_auto_user."' that is not the requested login. DAV usage is forbidden in this mode.");
if (empty($user->login)) {
dol_syslog("Failed to authenticate to DAV, login is not provided", LOG_WARNING);
return false;
}
if ($user->socid > 0) {
dol_syslog("Failed to authenticate to DAV, user is an external user", LOG_WARNING);
return false;
}
if ($user->login != $username) {
dol_syslog("Failed to authenticate to DAV, login does not match the login of loaded user", LOG_WARNING);
return false;
}
// Authentication mode
if (empty($dolibarr_main_authentication)) {
$dolibarr_main_authentication = 'dolibarr';
}
// Authentication mode: forceuser
if ($dolibarr_main_authentication == 'forceuser') {
if (empty($dolibarr_auto_user)) {
$dolibarr_auto_user = 'auto';
}
if ($dolibarr_auto_user != $username) {
dol_syslog("Warning: your instance is set to use the automatic forced login '".$dolibarr_auto_user."' that is not the requested login. DAV usage is forbidden in this mode.");
return false;
}
}
$authmode = explode(',', $dolibarr_main_authentication);
$entity = (GETPOSTINT('entity') ? GETPOSTINT('entity') : (!empty($conf->entity) ? $conf->entity : 1));
if (checkLoginPassEntity($username, $password, $entity, $authmode, 'dav') != $username) {
return false;
}
// Check if user status is enabled
if ($user->statut != $user::STATUS_ENABLED) {
// Status is disabled
dol_syslog("The user has been disabled.");
return false;
}
// Check if session was unvalidated by a password change
if (($user->flagdelsessionsbefore && !empty($_SESSION["dol_logindate"]) && $user->flagdelsessionsbefore > $_SESSION["dol_logindate"])) {
// Session is no more valid
dol_syslog("The user has a date for session invalidation = ".$user->flagdelsessionsbefore." and a session date = ".$_SESSION["dol_logindate"].". We must invalidate its sessions.");
return false;
}
// Check date validity
if ($user->isNotIntoValidityDateRange()) {
// User validity dates are no more valid
dol_syslog("The user login has a validity between [".$user->datestartvalidity." and ".$user->dateendvalidity."], current date is ".dol_now());
return false;
}
return true;
}
$authmode = explode(',', $dolibarr_main_authentication);
$entity = (GETPOSTINT('entity') ? GETPOSTINT('entity') : (!empty($conf->entity) ? $conf->entity : 1));
if (checkLoginPassEntity($username, $password, $entity, $authmode, 'dav') != $username) {
return false;
}
// Check if user status is enabled
if ($user->statut != $user::STATUS_ENABLED) {
// Status is disabled
dol_syslog("The user has been disabled.");
return false;
}
// Check if session was unvalidated by a password change
if (($user->flagdelsessionsbefore && !empty($_SESSION["dol_logindate"]) && $user->flagdelsessionsbefore > $_SESSION["dol_logindate"])) {
// Session is no more valid
dol_syslog("The user has a date for session invalidation = ".$user->flagdelsessionsbefore." and a session date = ".$_SESSION["dol_logindate"].". We must invalidate its sessions.");
return false;
}
// Check date validity
if ($user->isNotIntoValidityDateRange()) {
// User validity dates are no more valid
dol_syslog("The user login has a validity between [".$user->datestartvalidity." and ".$user->dateendvalidity."], current date is ".dol_now());
return false;
}
return true;
});
);
$authBackend->setRealm(constant('DOL_APPLICATION_TITLE').' - WebDAV');
@ -211,7 +219,7 @@ if (isset($baseUri)) {
if ((!getDolGlobalString('DAV_ALLOW_PUBLIC_DIR')
|| !preg_match('/'.preg_quote(DOL_URL_ROOT.'/dav/fileserver.php/public', '/').'/', $_SERVER["PHP_SELF"]))
&& !preg_match('/^sabreAction=asset&assetName=[a-zA-Z0-9%\-\/]+\.(png|css|woff|ico|ttf)$/', $_SERVER["QUERY_STRING"]) // URL for Sabre browser resources
) {
) {
//var_dump($_SERVER["QUERY_STRING"]);exit;
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
}

View File

@ -76,18 +76,26 @@ class PhpCollector extends DataCollector implements Renderable
/**
* Returns a list of messages ordered by their timestamp.
*
* @return array A list of messages ordered by time.
* @return array<array{time:int}> A list of messages ordered by time.
*/
public function getMessages()
{
$messages = $this->messages;
usort($messages, function ($itemA, $itemB) {
if ($itemA['time'] === $itemB['time']) {
return 0;
usort(
$messages,
/**
* @param array{time:int} $itemA Message A information
* @param array{time:int} $itemB Message B information
* @return int<-1,1> -1 if Item A before Item B, 0 if same, 1 if later.
*/
static function ($itemA, $itemB) {
if ($itemA['time'] === $itemB['time']) {
return 0;
}
return $itemA['time'] < $itemB['time'] ? -1 : 1;
}
return $itemA['time'] < $itemB['time'] ? -1 : 1;
});
);
return $messages;
}

View File

@ -1,35 +1,43 @@
<?php
/* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*/
/**
* Simple autoloader, so we don't need Composer just for this.
*/
spl_autoload_register(function ($class) {
if (preg_match('/^DebugBar/', $class)) {
$file = DOL_DOCUMENT_ROOT.'/includes/maximebf/debugbar/src/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
//var_dump($class.' - '.file_exists($file).' - '.$file);
if (file_exists($file)) {
require_once $file;
return true;
spl_autoload_register(
/**
* @param string $class Class to load
* @return true If class could be loaded
*/
static function ($class) {
if (preg_match('/^DebugBar/', $class)) {
$file = DOL_DOCUMENT_ROOT.'/includes/maximebf/debugbar/src/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
//var_dump($class.' - '.file_exists($file).' - '.$file);
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
}
return false;
}
if (preg_match('/^'.preg_quote('Psr\Log', '/').'/', $class)) {
$file = DOL_DOCUMENT_ROOT.'/includes/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
//var_dump($class.' - '.file_exists($file).' - '.$file);
if (file_exists($file)) {
require_once $file;
return true;
if (preg_match('/^'.preg_quote('Psr\Log', '/').'/', $class)) {
$file = DOL_DOCUMENT_ROOT.'/includes/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
//var_dump($class.' - '.file_exists($file).' - '.$file);
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
}
return false;
}
if (preg_match('/^'.preg_quote('Symfony\Component\VarDumper', '/').'/', $class)) {
$class = preg_replace('/'.preg_quote('Symfony\Component\VarDumper', '/').'/', '', $class);
$file = DOL_DOCUMENT_ROOT.'/includes/symfony/var-dumper/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
if (file_exists($file)) {
require_once $file;
return true;
if (preg_match('/^'.preg_quote('Symfony\Component\VarDumper', '/').'/', $class)) {
$class = preg_replace('/'.preg_quote('Symfony\Component\VarDumper', '/').'/', '', $class);
$file = DOL_DOCUMENT_ROOT.'/includes/symfony/var-dumper/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
}
return false;
return true;
}
return true;
});
);

View File

@ -7,6 +7,7 @@
* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2021 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -140,24 +141,39 @@ if (php_sapi_name() === "cli" && (float) PHP_VERSION > 7.0) {
case 'config':
$conffile = $arg;
$conffiletoshow = $arg;
break;
break;
case 'h':
case 'help':
usage($argv[0], "Usage:");
exit(0);
exit(0);
}
}
// Parse the arguments to find the options.
$args_options = array_filter(array_slice($argv, 0, $rest_index), function ($arg) {
return strlen($arg) >= 2 && $arg[0] == '-';
});
$parsed_options = array_map(function ($arg) {
if (strlen($arg) > 1) {
return "--" . $arg;
$args_options = array_filter(
array_slice($argv, 0, $rest_index),
/**
* @param string $arg
* @return bool
*/
static function ($arg) {
return strlen($arg) >= 2 && $arg[0] == '-';
}
return "-" . $arg;
}, array_keys($opts));
);
$parsed_options = array_map(
/**
* Previx option with '-' for single characters and -- for more than single characters
* @param string $arg
* @return straing
*/
static function ($arg) {
if (strlen($arg) > 1) {
return "--" . $arg;
}
return "-" . $arg;
},
array_keys($opts)
);
// Find options (dash-prefixed) that were not parsed.
$unknown_options = array_diff($args_options, $parsed_options);
@ -301,7 +317,7 @@ if (constant('DOL_DATA_ROOT') === null) {
$lockfile = '../../documents/install.lock';
$upgradeunlockfile = '../../documents/upgrade.unlock';
}
$islocked=false;
$islocked = false;
if (@file_exists($lockfile) || @file_exists($lockfile2)) {
if (!defined('ALLOWED_IF_UPGRADE_UNLOCK_FOUND') || (! @file_exists($upgradeunlockfile) && ! @file_exists($upgradeunlockfile2))) {
// If this is a dangerous install page (ALLOWED_IF_UPGRADE_UNLOCK_FOUND not defined) or

View File

@ -101,10 +101,18 @@ function testSqlAndScriptInject($val, $type)
$oldval = $val;
$val = html_entity_decode($val, ENT_QUOTES | ENT_HTML5); // Decode '&colon;', '&apos;', '&Tab;', '&NewLine', ...
// Sometimes we have entities without the ; at end so html_entity_decode does not work but entities is still interpreted by browser.
$val = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', function ($m) {
// Decode '&#110;', ...
return realCharForNumericEntities($m);
}, $val);
$val = preg_replace_callback(
'/&#(x?[0-9][0-9a-f]+;?)/i',
/**
* @param string $m
* @return string
*/
static function ($m) {
// Decode '&#110;', ...
return realCharForNumericEntities($m);
},
$val
);
// We clean html comments because some hacks try to obfuscate evil strings by inserting HTML comments. Example: on<!-- -->error=alert(1)
$val = preg_replace('/<!--[^>]*-->/', '', $val);

View File

@ -525,7 +525,12 @@ class Task extends CommonObjectLine
$project->getLinesArray(null); // this method does not return <= 0 if fails
$projectCompleted = array_reduce(
$project->lines,
function ($allTasksCompleted, $task) {
/**
* @param bool $allTasksCompleted
* @param Task $task
* @return bool
*/
static function ($allTasksCompleted, $task) {
return $allTasksCompleted && $task->progress >= 100;
},
1

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2022 Open-Dsi <support@open-dsi.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -292,13 +293,13 @@ class ProductCombination
global $conf;
$sql = "SELECT pac.rowid, pac.fk_product_parent, pac.fk_product_child, pac.variation_price, pac.variation_price_percentage, pac.variation_ref_ext, pac.variation_weight";
$sql.= " FROM ".MAIN_DB_PREFIX."product_attribute_combination AS pac";
$sql .= " FROM ".MAIN_DB_PREFIX."product_attribute_combination AS pac";
if ($sort_by_ref) {
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product AS p ON p.rowid = pac.fk_product_child";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product AS p ON p.rowid = pac.fk_product_child";
}
$sql.= " WHERE pac.fk_product_parent = ".((int) $fk_product_parent)." AND pac.entity IN (".getEntity('product').")";
$sql .= " WHERE pac.fk_product_parent = ".((int) $fk_product_parent)." AND pac.entity IN (".getEntity('product').")";
if ($sort_by_ref) {
$sql.= $this->db->order('p.ref', 'ASC');
$sql .= $this->db->order('p.ref', 'ASC');
}
$query = $this->db->query($sql);
@ -614,7 +615,7 @@ class ProductCombination
* Retrieves the combination that matches the given features.
*
* @param int $prodid Id of parent product
* @param array $features Format: [$attr] => $attr_val
* @param array<string,string> $features Format: [$attr] => $attr_val
* @return false|ProductCombination False if not found
*/
public function fetchByProductCombination2ValuePairs($prodid, array $features)
@ -626,9 +627,15 @@ class ProductCombination
$prodcomb2val = new ProductCombination2ValuePair($this->db);
$prodcomb = new ProductCombination($this->db);
$features = array_filter($features, function ($v) {
return !empty($v);
});
$features = array_filter(
$features,
/**
* @param mixed $v Feature information of a product.
*/
static function ($v) {
return !empty($v);
}
);
foreach ($features as $attr => $attr_val) {
$actual_comp[$attr] = $attr_val;
@ -729,7 +736,7 @@ class ProductCombination
$this->db->begin();
$price_impact = array(1=>0); // init level price impact
$price_impact = array(1 => 0); // init level price impact
$forced_refvar = trim($forced_refvar);