diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 7084e2a9564db..39d81c209a01f 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -301,7 +301,7 @@ return [ 'htdocs/core/class/notify.class.php' => ['PhanUndeclaredProperty'], 'htdocs/core/class/openid.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType'], 'htdocs/core/class/reddithandler.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownArrayPropertyType'], - 'htdocs/core/class/smtps.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType', 'PhanPluginUnknownPropertyType', 'PhanTypeMismatchDimFetch'], + 'htdocs/core/class/smtps.class.php' => ['PhanTypeConversionFromArray'], 'htdocs/core/class/socialnetworkmanager.class.php' => ['PhanPluginUnknownArrayMethodParamType'], 'htdocs/core/class/stats.class.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchDimFetch'], 'htdocs/core/class/timespent.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'], diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index bda4da73c57ed..7740ed0066fbe 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -48,7 +48,7 @@ class SMTPs { /** - * Host Name or IP of SMTP Server to use + * @var string Host Name or IP of SMTP Server to use */ private $_smtpsHost = 'localhost'; @@ -61,82 +61,84 @@ class SMTPs private $_smtpsPort = 25; /** - * Secure SMTP Server access ID + * @var ?string Secure SMTP Server access ID * This can be defined via a INI file or via a setter method */ private $_smtpsID = null; /** - * Secure SMTP Server access Password + * @var ?string Secure SMTP Server access Password * This can be defined via a INI file or via a setter method */ private $_smtpsPW = null; /** - * Token in case we use OAUTH2 + * @var ?string Token in case we use OAUTH2 */ private $_smtpsToken = null; /** - * Who sent the Message + * @var ?array{org:string,real?:string,addr:string,user:string,host:string} Who sends the Message * This can be defined via a INI file or via a setter method */ private $_msgFrom = null; /** - * Where are replies and errors to be sent to + * @var ?array Where are replies and errors to be sent to * This can be defined via a INI file or via a setter method */ private $_msgReplyTo = null; /** - * List of In-Reply-To + * @var ?string List of In-Reply-To */ private $_msgInReplyTo = null; /** - * List of Msg-Id + * @var ?string[] List of Msg-Id */ private $_msgReferences = null; /** - * Who will the Message be sent to; TO, CC, BCC + * @var array>> Who will the Message be sent to; TO, CC, BCC * Multi-diminsional array containing addresses the message will * be sent TO, CC or BCC */ private $_msgRecipients = null; /** - * Message Subject + * @var ?string Message Subject */ private $_msgSubject = null; /** * Message Content * - * @var array{html?:array{mimeType:string,data:string,dataText:string,md5?:string},plain?:array{mimeType:string,data:string,dataText:string,md5?:string},image:array,attachment:array} $msgContent Array of messages + * @var array{}|array{html?:array{mimeType:string,data:string,dataText:string,md5?:string},plain?:array{mimeType:string,data:string,dataText:string,md5?:string},image:array,attachment:array} Array of messages */ private $_msgContent = array(); /** - * Custom X-Headers + * @var string[] Custom X-Headers */ - private $_msgXheader = null; + private $_msgXheader = array(); /** + * @var string * Character set - * Defaulted to 'iso-8859-1' + * Defaults to 'iso-8859-1' */ private $_smtpsCharSet = 'iso-8859-1'; /** + * @var int * Message Sensitivity * Defaults to ZERO - None */ private $_msgSensitivity = 0; /** - * Message Sensitivity + * @var string[] Message Sensitivity */ private $_arySensitivity = array(false, 'Personal', @@ -144,13 +146,13 @@ class SMTPs 'Company Confidential'); /** - * Message Sensitivity + * @var int Message Sensitivity * Defaults to 3 - Normal */ private $_msgPriority = 3; /** - * Message Priority + * @var string[] Message Priority */ private $_aryPriority = array('Bulk', 'Highest', @@ -160,13 +162,13 @@ class SMTPs 'Lowest'); /** - * Content-Transfer-Encoding + * @var 0|string Content-Transfer-Encoding * Defaulted to 0 - 7bit */ private $_smtpsTransEncodeType = 0; /** - * Content-Transfer-Encoding + * @var string[] Content-Transfer-Encoding */ private $_smtpsTransEncodeTypes = array('7bit', // Simple 7-bit ASCII '8bit', // 8-bit coding with line termination characters @@ -177,27 +179,29 @@ class SMTPs 'uuencode'); // UUENCODE encoding /** + * @var string * Content-Transfer-Encoding * Defaulted to '7bit' */ private $_smtpsTransEncode = '7bit'; /** - * Boundary String for MIME separation + * @var ?string Boundary String for MIME separation */ private $_smtpsBoundary = null; /** - * Related Boundary + * @var ?string Related Boundary */ private $_smtpsRelatedBoundary = null; /** - * Alternative Boundary + * @var ?string Alternative Boundary */ private $_smtpsAlternativeBoundary = null; /** + * @var int * Determines the method inwhich the message are to be sent. * - 'sockets' [0] - connect via network to SMTP server - default * - 'pipe [1] - use UNIX path to EXE @@ -207,43 +211,49 @@ class SMTPs private $_transportType = 0; /** - * If '$_transportType' is set to '1', then this variable is used + * @var string If '$_transportType' is set to '1', then this variable is used * to define the UNIX file system path to the sendmail executable */ private $_mailPath = '/usr/lib/sendmail'; // @phpstan-ignore-line /** - * Sets the SMTP server timeout in seconds. + * @var int Sets the SMTP server timeout in seconds. */ private $_smtpTimeout = 10; /** - * Determines whether to calculate message MD5 checksum. + * @var bool Determines whether to calculate message MD5 checksum. */ private $_smtpMD5 = false; /** - * Class error codes and messages + * @var array Class error codes and messages */ - private $_smtpsErrors = null; + private $_smtpsErrors = array(); /** - * Defines log level + * @var int<0,3> Defines log level * 0 - no logging * 1 - connectivity logging * 2 - message generation logging - * 3 - detail logging + * 3 - detailed logging */ private $_log_level = 0; // @phpstan-ignore-line /** - * Place Class in" debug" mode + * @var bool Place Class in" debug" mode */ private $_debug = false; // @CHANGE LDR + /** + * @var string + */ public $log = ''; + /** + * @var string + */ public $lastretval = ''; /** @@ -261,20 +271,32 @@ class SMTPs */ public $errstr; - private $_errorsTo = ''; + /** + * @var array + */ + private $_errorsTo = array(); + /** + * @var int + */ private $_deliveryReceipt = 0; + /** + * @var string + */ private $_trackId = ''; + /** + * @var string + */ private $_moreinheader = ''; /** - * An array of options for stream_context_create() + * @var array> An array of options for stream_context_create() */ private $_options = array(); /** * Set delivery receipt * - * @param array $_options An array of options for stream_context_create() + * @param array> $_options An array of options for stream_context_create() * @return void */ public function setOptions($_options = array()) @@ -361,14 +383,14 @@ public function setErrorsTo($_strErrorsTo) /** * Get errors to * - * @param boolean $_part Variant - * @return string Errors to + * @param true|string $_part Variant + * @return string|array Errors to */ public function getErrorsTo($_part = true) { $_retValue = ''; - if ($_part === true) { + if ($_part === true || !array_key_exists($_part, $this->_errorsTo)) { $_retValue = $this->_errorsTo; } else { $_retValue = $this->_errorsTo[$_part]; @@ -512,7 +534,7 @@ private function _server_authenticate() } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 1) { // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from. // So if the from to is 'aaa ', we will keep 'ccc.com' - $hosth = $this->getFrom('addr'); + $hosth = (string) $this->getFrom('addr'); $hosth = preg_replace('/^.*.*$/', '', $hosth); $hosth = preg_replace('/.*@/', '', $hosth); @@ -577,7 +599,7 @@ private function _server_authenticate() C: QUIT S: 221 Bye */ - if (!$_retVal = $this->socket_send_str('STARTTLS', 220)) { + if (!$_retVal = $this->socket_send_str('STARTTLS', '220')) { $this->_setErr(131, 'STARTTLS connection is not supported.'); return $_retVal; } @@ -641,10 +663,10 @@ private function _server_authenticate() $this->_setErr(130, 'Error when asking for AUTH LOGIN'); } else { // User name will not return any error, server will take anything we give it. - $this->socket_send_str(base64_encode($this->_smtpsID), '334'); + $this->socket_send_str(base64_encode((string) $this->_smtpsID), '334'); // The error here just means the ID/password combo doesn't work. // There is no method to determine which is the problem, ID or password - $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235'); + $_retVal = $this->socket_send_str(base64_encode((string) $this->_smtpsPW), '235'); } break; } @@ -699,7 +721,7 @@ public function sendMsg() } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 1) { // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from. // So if the from to is 'aaa ', we will keep 'ccc.com' - $hosth = $this->getFrom('addr'); + $hosth = (string) $this->getFrom('addr'); $hosth = preg_replace('/^.*.*$/', '', $hosth); $hosth = preg_replace('/.*@/', '', $hosth); @@ -1102,14 +1124,14 @@ public function setFrom($_strFrom) /** * Retrieves the Address from which mail will be sent * - * @param boolean $_part To "strip" 'Real name' from address - * @return string Address from which mail will be sent + * @param true|string $_part To "strip" 'Real name' from address + * @return null|string|array{org:string,real?:string,addr:string,user:string,host:string} Address from which mail will be sent */ public function getFrom($_part = true) { $_retValue = ''; - if ($_part === true) { + if ($_part === true || $this->_msgFrom === null) { $_retValue = $this->_msgFrom; } else { $_retValue = $this->_msgFrom[$_part]; @@ -1134,8 +1156,8 @@ public function setReplyTo($_strReplyTo) /** * Retrieves the Address from which mail will be the reply-to * - * @param boolean $_part To "strip" 'Real name' from address - * @return string Address from which mail will be the reply-to + * @param true|string $_part To "strip" 'Real name' from address + * @return null|array|string Reply-To Address to use */ public function getReplyTo($_part = true) { @@ -1178,7 +1200,7 @@ public function getInReplyTo() /** * Set References in the list of Msg-Id * - * @param string $_strReferences List of Msg-Id + * @param string[] $_strReferences List of Msg-Id * @return void */ public function setReferences($_strReferences) @@ -1191,7 +1213,7 @@ public function setReferences($_strReferences) /** * Retrieves the References from which mail will be the reply-to * - * @return string List of Msg-Id + * @return ?string[] List of Msg-Id */ public function getReferences() { @@ -1318,11 +1340,11 @@ private function _strip_email($_strAddr) // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Returns an array of bares addresses for use with 'RCPT TO:' + * Returns an array of bare addresses for use with 'RCPT TO:' * This is a "build as you go" method. Each time this method is called * the underlying array is destroyed and reconstructed. * - * @return array Returns an array of bares addresses + * @return string[] Returns an array of bare addresses */ public function get_RCPT_list() { @@ -1926,7 +1948,7 @@ public function setXheader($strXdata) /** * Retrieves the Message X-Header Content * - * @return array $_msgContent Message X-Header Content + * @return string[] $_msgContent Message X-Header Content */ public function getXheader() { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 0db3ae9a88a49..6f87c5244eb63 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -54,8 +54,8 @@ parameters: - '#(?:Comparison operation "(?:<(?:" between (?:0(?:(?:\|1)? and 0)|int<(?:0, max>(?:(?:\|false)? and 0)|1, max> and 1)|null and 0)|=" between int<2, max> and 1)|>(?:" between (?:(?:-1|0) and 0|0(?: and 1(?:000)?|\|1\|2\|3 and 999)|1 and 1)))) is always false#' - '#(?:Comparison operation ">=" between 0 and 8) is always false#' - - "#(?:Comparison operation .<. between '' and 0 is always) true#" - '#(?:Comparison operation "(?:<(?:" between (?:(?:..|-1) and 0|0 and 4)|=" between (?:0 and 0|int<100, 999> and 999))|>(?:" between (?:1(?:(?:\|2)? and 0)|int<(?:1, max> and 0|2, max> and 1))|=" between (?:\S+ and 0|int<(?:0, max> and 0|1, max> and 1))))) is always true#' + - '#(?:Comparison operation ">=") between int<2, 4> and 1 is always true\.#' - '#(?:Else branch is unreachable because (?:(?:previous|ternary operator) condition)) is always true#' - '#(?:(?:Elsei|I)f condition|Left side of (?:&&|\|\|)|Negated boolean expression|R(?:esult of (?:&&|\|\|)|ight side of (?:&&|\|\|))|Ternary operator condition) is always true#' - '#is_object\(\) with mixed will always evaluate to false#' @@ -73,24 +73,26 @@ parameters: - '#.*phan-var#' - '#(?:(?:s(?:(?:et_error_handl|pl_autoload_regist)er)|array_filter)) expects \(callable#' - '# (vatrate|DolEditor constructor) expects bool, int#' - - '# SMTPs::(getFrom|getErrorsTo|getReplyTo)\(\) expects bool, string given.#' - '# getLocalTaxesFromRate expects int\|string#' - - '#::(options)\(\) expects int\|string#' + - '#(?:mysqli::options\(\)) expects int\|string#' - '# print_barre_liste expects int\|null#' - '#(?:colorAdjustBrightness|imap_(?:(?:fetch)?body|fetchstructure)) expects int, string#' - - '#(sendTicketMessageByEmail|addItemsFact|update_price|recur|addDepreciationLine|addline|generate|update|getSelectConditionsPaiements|select_state|listBoxes|literalBarcodeType)\(\) expects int, string#' + - '#(?:(?:(?:BonPrelevement::generat|CommonObject::update_pric)e|Form(?:::getSelectConditionsPaiements|Company::select_state)|In(?:foBox::listBoxes|tracommReport::addItemsFact)|Menubase::recur|Ticket::sendTicketMessageByEmail|mod_barcode_(?:(?:product|thirdparty)_standard::literalBarcodeType))\(\)) expects int, string given\.#' - '#on array{url: mixed} in empty\(\) does not exist.#' - '#EvalMath::trigger\(\) expects string, int given#' - '# Diff::generatePartialDiff\(\) expects array#' - '# EmailCollector::getpart\(\) expects string#' - '#(?:convertSecondToTime) expects int, float\|string given#' - - '#(?:Comm(?:(?:ande::updateline|on(?:Invoice::getLibStatut|StickerGenerator::(?:Set_Char_Size|_Croix|convertMetric)))\(\))|Facture(?:(?:::update|FournisseurRec::add)line\(\))|(?:Holiday::addLogCP|Loan::getLibStatut|SupplierProposal::updateline)\(\)|c(?:alcul_price_total|onvert(?:DurationtoHour|SecondToTime))|dol_(?:substr|time_plus_duree)|pdf_(?:azur::_tableau_(?:(?:info|tot)\(\))|ban(?:::_tableau\(\)|k)|c(?:anelle::_tableau_(?:(?:tot|versements)\(\))|ornas::_tableau_(?:(?:info|tot)\(\))|rabe::_tableau_(?:(?:info|tot|versements)\(\))|yan::draw(?:(?:Info|Total)Table\(\)))|e(?:agle(?:(?:::_tableau_tot|_proforma::drawTotalTable)\(\))|instein::_tableau_(?:(?:info|tot)\(\))|ratosthene::draw(?:(?:Info|Total)Table\(\))|spadon::_tableau_tot\(\))|muscadet::_tableau_(?:(?:info|tot)\(\))|octopus::(?:_table(?:(?:FirstPage|au)\(\))|draw(?:(?:Info|Total)Table\(\)))|page(?:foot|head)|(?:rouget::_tableau_tot|s(?:epamandate::_tableau(?:_info)?|ponge::draw(?:(?:Info|Total)Table)|quille::_tableau_tot|t(?:andard_(?:e(?:(?:valuation|xpensereport)::_tableau|xpensereport::tablePayments)|(?:myobjec|supplierpaymen)t::_tableau|supplierpayment::_tableau_cheque)|orm::_tableau_info|rato::tabSignature))|t(?:cpdflabel::writeBarcode|yphon::_tableau_info)|vinci::_tableau_info)\(\)|w(?:atermark|rite(?:LinkedObjects|linedesc))|zenith::_tableau_tot\(\))|usleep) expects int, float given\.#' + - '#(?:Comm(?:(?:ande::updateline|on(?:Invoice::getLibStatut|StickerGenerator::(?:Set_Char_Size|_Croix|convertMetric)))\(\))|Facture(?:(?:::update|FournisseurRec::add)line\(\))|(?:Holiday::addLogCP|Loan::getLibStatut|SupplierProposal::updateline)\(\)|c(?:alcul_price_total|onvert(?:DurationtoHour|SecondToTime))|dol_time_plus_duree|pdf_(?:azur::_tableau_(?:(?:info|tot)\(\))|ban(?:::_tableau\(\)|k)|c(?:anelle::_tableau_(?:(?:tot|versements)\(\))|ornas::_tableau_(?:(?:info|tot)\(\))|rabe::_tableau_(?:(?:info|tot|versements)\(\))|yan::draw(?:(?:Info|Total)Table\(\)))|e(?:agle(?:(?:::_tableau_tot|_proforma::drawTotalTable)\(\))|instein::_tableau_(?:(?:info|tot)\(\))|ratosthene::draw(?:(?:Info|Total)Table\(\))|spadon::_tableau_tot\(\))|muscadet::_tableau_(?:(?:info|tot)\(\))|octopus::(?:_table(?:(?:FirstPage|au)\(\))|draw(?:(?:Info|Total)Table\(\)))|page(?:foot|head)|(?:rouget::_tableau_tot|s(?:epamandate::_tableau(?:_info)?|ponge::draw(?:(?:Info|Total)Table)|quille::_tableau_tot|t(?:andard_(?:e(?:(?:valuation|xpensereport)::_tableau|xpensereport::tablePayments)|(?:myobjec|supplierpaymen)t::_tableau|supplierpayment::_tableau_cheque)|orm::_tableau_info|rato::tabSignature))|t(?:cpdflabel::writeBarcode|yphon::_tableau_info)|vinci::_tableau_info)\(\)|w(?:atermark|rite(?:LinkedObjects|linedesc))|zenith::_tableau_tot\(\))|usleep) expects int, float given\.#' + - '#::saveboxorder\(\) expects int, array#' - - '# (fetchObjectByElement|print_actions_filter|dol_mktime|dol_remove_file_process) expects int, array\|string given.#' + - '#(?:dol_(?:mktime|remove_file_process)|fetchObjectByElement|print_actions_filter) expects int, array\|string given\.#' + - '# (CSMSFile) constructor expects int, array\|string given.#' - '#(?:ProductFournisseur::logPrice\(\)) expects float\|null#' - '#(?:(?:Asset::addDepreciationL|Facture(?:(?:(?:Fournisseur)?::add|Fournisseur::update)l))ine\(\)|calcul_price_total|dol_convertToWord|(?:loanCalcMonthlyPaymen|print_paypal_redirec)t) expects float, string given.#' - - '#(?:(?:EvalMath::trigger|F(?:acture(?:(?:Fournisseur)?Rec::addline)|ichinterRec::addLineRec)|SMTPs::socket_send_str)\(\)|dolMd2Html|setEventMessages) expects string\|null#' + - '#EvalMath::trigger\(\) expects string\|null,#' + - '#(?:F(?:acture(?:(?:Fournisseur)?Rec::addline\(\))|ichinterRec::addLineRec\(\))|dolMd2Html|setEventMessages) expects string\|null,#' - '# (envoi_mail|sendEmailTo) expects string, \(float\|int\) given.#' - '#::printStdColumnContent\(\) expects string, float(\|(int|array)(\<.*\>)?)* given.#' - '#::HTML2OpenIDServer\(\) expects string, array given.#'