mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-06 09:38:23 +01:00
# Qual: Fix phan notices Fix phan notices in several classes that have UnknownObjectMethod calls and classes that had notices in relation with these classes
357 lines
8.5 KiB
PHP
357 lines
8.5 KiB
PHP
<?php
|
|
/* Copyright (C) 2021 John BOTELLA <john.botella@atm-consulting.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
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/core/class/validate.class.php
|
|
* \ingroup core
|
|
* \brief File for Utils class
|
|
*/
|
|
|
|
|
|
/**
|
|
* Class toolbox to validate values
|
|
*/
|
|
class Validate
|
|
{
|
|
/**
|
|
* @var DoliDB Database handler (result of a new DoliDB)
|
|
*/
|
|
public $db;
|
|
|
|
/**
|
|
* @var Translate $outputLang
|
|
*/
|
|
public $outputLang;
|
|
|
|
/**
|
|
* @var string Error string
|
|
* @see $errors
|
|
*/
|
|
public $error;
|
|
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
* @param Translate $outputLang Output lang for error
|
|
*/
|
|
public function __construct($db, $outputLang = null)
|
|
{
|
|
global $langs;
|
|
|
|
if (empty($outputLang)) {
|
|
$this->outputLang = $langs;
|
|
} else {
|
|
$this->outputLang = $outputLang;
|
|
}
|
|
|
|
if (!is_object($this->outputLang) || !method_exists($this->outputLang, 'load')) {
|
|
return;
|
|
}
|
|
|
|
$this->outputLang->loadLangs(array('validate', 'errors'));
|
|
|
|
$this->db = $db;
|
|
}
|
|
|
|
/**
|
|
* Use to clear errors msg or other ghost vars
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function clear()
|
|
{
|
|
$this->error = '';
|
|
}
|
|
|
|
/**
|
|
* Use to clear errors msg or other ghost vars
|
|
*
|
|
* @param string $errMsg your error message
|
|
* @return void
|
|
*/
|
|
protected function setError($errMsg)
|
|
{
|
|
$this->error = $errMsg;
|
|
}
|
|
|
|
/**
|
|
* Check for e-mail validity
|
|
*
|
|
* @param string $email e-mail address to validate
|
|
* @param int $maxLength string max length (not used)
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isEmail($email, $maxLength = 0)
|
|
{
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
$this->error = $this->outputLang->trans('RequireValidEmail');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for price validity
|
|
*
|
|
* @param string $price Price to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isPrice($price)
|
|
{
|
|
if (!preg_match('/^[0-9]{1,10}(\.[0-9]{1,9})?$/ui', $price)) {
|
|
$this->error = $this->outputLang->trans('RequireValidValue');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for timestamp validity
|
|
*
|
|
* @param string|int $stamp timestamp to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isTimestamp($stamp)
|
|
{
|
|
if (!is_numeric($stamp) && (int) $stamp == $stamp) {
|
|
$this->error = $this->outputLang->trans('RequireValidDate');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for phone validity
|
|
*
|
|
* @param string $phone Phone string to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isPhone($phone)
|
|
{
|
|
if (!preg_match('/^[+0-9. ()-]*$/ui', $phone)) {
|
|
$this->error = $this->outputLang->trans('RequireValidPhone');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for string max length validity
|
|
*
|
|
* @param string $string to validate
|
|
* @param int $length max length
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isMaxLength($string, $length)
|
|
{
|
|
if (strlen($string) > $length) {
|
|
$this->error = $this->outputLang->trans('RequireMaxLength', $length);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for string not empty
|
|
*
|
|
* @param string $string to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isNotEmptyString($string)
|
|
{
|
|
if (!strlen($string)) {
|
|
$this->error = $this->outputLang->trans('RequireANotEmptyValue');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for string min length validity
|
|
*
|
|
* @param string $string to validate
|
|
* @param int $length max length
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isMinLength($string, $length)
|
|
{
|
|
if (strlen($string) < $length) {
|
|
$this->error = $this->outputLang->trans('RequireMinLength', $length);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check url validity
|
|
*
|
|
* @param string $url to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isUrl($url)
|
|
{
|
|
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
|
$this->error = $this->outputLang->trans('RequireValidUrl');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check Duration validity
|
|
*
|
|
* @param mixed $duration to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isDuration($duration)
|
|
{
|
|
if (!is_int($duration) && $duration >= 0) {
|
|
$this->error = $this->outputLang->trans('RequireValidDuration');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check numeric validity
|
|
*
|
|
* @param mixed $string to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isNumeric($string)
|
|
{
|
|
if (!is_numeric($string)) {
|
|
$this->error = $this->outputLang->trans('RequireValidNumeric');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for boolean validity
|
|
*
|
|
* @param boolean $bool Boolean to validate
|
|
* @return boolean Validity is ok or not
|
|
*/
|
|
public function isBool($bool)
|
|
{
|
|
if (!(is_null($bool) || is_bool($bool) || preg_match('/^[0|1]{1}$/ui', $bool))) {
|
|
$this->error = $this->outputLang->trans('RequireValidBool');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for all values in db
|
|
*
|
|
* @param string[] $values Boolean to validate
|
|
* @param string $table the db table name without $this->db->prefix()
|
|
* @param string $col the target col
|
|
* @return boolean Validity is ok or not
|
|
* @throws Exception
|
|
*/
|
|
public function isInDb($values, $table, $col)
|
|
{
|
|
if (!is_array($values)) {
|
|
$value_arr = array($values);
|
|
} else {
|
|
$value_arr = $values;
|
|
}
|
|
|
|
if (!count($value_arr)) {
|
|
$this->error = $this->outputLang->trans('RequireValue');
|
|
return false;
|
|
}
|
|
|
|
foreach ($value_arr as $val) {
|
|
$sql = "SELECT ".$col." FROM ".$this->db->prefix().$table." WHERE ".$col." = '".$this->db->escape($val)."' LIMIT 1"; // more quick than count(*) to check existing of a row
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
if ($obj) {
|
|
continue;
|
|
}
|
|
}
|
|
// If something was wrong
|
|
$this->error = $this->outputLang->trans('RequireValidExistingElement');
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check for all values in db
|
|
*
|
|
* @param integer $id of element
|
|
* @param string $classname the class name
|
|
* @param string $classpath the class path
|
|
* @return boolean Validity is ok or not
|
|
* @throws Exception
|
|
*/
|
|
public function isFetchable($id, $classname, $classpath)
|
|
{
|
|
if (!empty($classpath)) {
|
|
if (dol_include_once($classpath)) {
|
|
if ($classname && class_exists($classname)) {
|
|
/** @var CommonObject $object */
|
|
$object = new $classname($this->db);
|
|
'@phan-var-force CommonObject|User $object'; // User provided to propose a class with 'fetch'
|
|
|
|
if (!is_callable(array($object, 'fetch')) || !is_callable(array($object, 'isExistingObject'))) {
|
|
$this->error = $this->outputLang->trans('BadSetupOfFieldFetchNotCallable');
|
|
return false;
|
|
}
|
|
|
|
if (!empty($object->table_element) && $object->isExistingObject($object->table_element, $id)) {
|
|
return true;
|
|
} else {
|
|
$this->error = $this->outputLang->trans('RequireValidExistingElement');
|
|
}
|
|
} else {
|
|
$this->error = $this->outputLang->trans('BadSetupOfFieldClassNotFoundForValidation');
|
|
}
|
|
} else {
|
|
$this->error = $this->outputLang->trans('BadSetupOfFieldFileNotFound');
|
|
}
|
|
} else {
|
|
$this->error = $this->outputLang->trans('BadSetupOfField');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check for all values in db for an element
|
|
* @see self::isFetchable()
|
|
*
|
|
* @param integer $id of element
|
|
* @param string $element_type the element type
|
|
* @return boolean Validity is ok or not
|
|
* @throws Exception
|
|
*/
|
|
public function isFetchableElement($id, $element_type)
|
|
{
|
|
// TODO use newObjectByElement() introduce in V20 by PR #30036 for better errors management
|
|
$elementProperty = getElementProperties($element_type);
|
|
return $this->isFetchable($id, $elementProperty['classname'], $elementProperty['classpath'].'/'.$elementProperty['classfile'].'.class.php');
|
|
}
|
|
}
|