2002-04-30 10:44:42 +00:00
< ? php
2011-12-28 11:48:18 +00:00
/**
2019-03-06 19:29:58 +00:00
* Copyright ( C ) Dan Potter
* Copyright ( C ) Eric Seigne
2024-04-03 12:46:46 +00:00
* Copyright ( C ) 2000 - 2005 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
* Copyright ( C ) 2003 Jean - Louis Bergamo < jlb @ j1b . org >
* Copyright ( C ) 2004 - 2015 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2005 - 2012 Regis Houssin < regis . houssin @ inodbox . com >
FIX: Resolve possibly-undefined-variable cases flagged by PHPStan (#39523)
* FIX: Resolve possibly-undefined-variable cases flagged by PHPStan
Fixes several cases of the variable.undefined PHPStan rule instead of
just excluding them via the baseline: a wrong variable used to build a
delete link (dir_add_card.php), an uninitialized $result across a
try/catch (CMailFile), missing GETPOST reads ($mode, $fk_project/$date
reset via unset() creating cross-branch ambiguity), a missing $r
contract check (commonfieldsinimport.inc.php), missing @var/global
annotations for $conf/$langs/$bc, dead extrafields-display code
guarded by the wrong condition (expedition/card.php), and an
undefined $soc passed to formAddObjectLine() where objects have no
buyer thirdparty (replaced with null). Corresponding entries removed
from dev/build/phpstan/phpstan-baseline.neon.
* FIX: Resolve more possibly-undefined-variable cases flagged by PHPStan
Second batch of variable.undefined fixes removed from the baseline:
- Complex conditional flows PHPStan can't prove exhaustive (Stripe key
selection in commoninvoice.class.php, a situation-invoice loop var in
pdf_sponge.modules.php, a product loop var in stock/movement_list.php)
fixed by adding a definite initialization before the ambiguous branch.
- A commented-out $linkback assignment restored in
expensereport/payment/info.php.
- Missing GETPOST reads added (holiday/list.php update-date filters,
product/stock/info.php $action/$socid, projet/comment.php $mode).
- A dead-code $mesg call to dol_htmloutput_mesg() removed from
admin_hrm.php (messages are already shown via setEventMessages()).
- Redundant isset() checks removed in product/reassort.php and
reassortlot.php where $type is unconditionally set earlier in the
same file, so the isset()-false branch was unreachable dead code.
- $user documented as always available in public/bookcal/index.php
(NOREQUIREUSER is not defined on that page).
- A genuinely missing $tmpcode initialization fixed in
attendee_new.php, suggestbooth.php and suggestconference.php: when
an existing thirdparty is reused (or SOCIETE_CODECLIENT_ADDON has no
auto-numbering), $tmpcode was never set before being assigned to
code_client/code_fournisseur.
* add phan fix
* add phan fix
* fix
* fix
* fix
2026-08-15 16:33:12 +00:00
* Copyright ( C ) 2019 - 2026 Frédéric France < frederic . france @ free . fr >
2026-02-12 15:29:11 +00:00
* Copyright ( C ) 2024 - 2026 MDW < mdeweerd @ users . noreply . github . com >
2025-10-08 18:24:56 +00:00
* Copyright ( C ) 2025 Joachim Kueter < git - jk @ bloxera . com >
2005-06-25 13:02:39 +00:00
*
* 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
2013-01-16 14:36:08 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2005-06-25 13:02:39 +00:00
* ( at your option ) 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
2019-09-23 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2005-06-25 13:02:39 +00:00
*
* Lots of code inspired from Dan Potter ' s CMailFile class
*/
/**
2011-10-24 07:29:17 +00:00
* \file htdocs / core / class / CMailFile . class . php
2010-08-28 10:55:11 +00:00
* \brief File of class to send emails ( with attachments or not )
2008-11-15 00:52:42 +00:00
*/
2004-07-15 22:17:39 +00:00
2022-08-01 09:31:32 +00:00
use OAuth\Common\Storage\DoliStorage ;
2022-08-11 08:03:44 +00:00
use OAuth\Common\Consumer\Credentials ;
2023-03-13 09:30:37 +00:00
2005-06-25 13:02:39 +00:00
/**
2012-02-01 15:00:22 +00:00
* Class to send emails ( with attachments or not )
2020-08-31 15:00:43 +00:00
* Usage : $mailfile = new CMailFile ( $subject , $sendto , $replyto , $message , $filepath , $mimetype , $filename , $cc , $ccc , $deliveryreceipt , $msgishtml , $errors_to , $css , $trackid , $moreinheader , $sendcontext , $replyto );
2012-02-01 15:00:22 +00:00
* $mailfile -> sendfile ();
2008-11-15 00:52:42 +00:00
*/
2004-07-15 22:17:39 +00:00
class CMailFile
2003-07-07 10:04:20 +00:00
{
2024-08-01 09:09:26 +00:00
/** @var string Context of mail ('standard', 'emailing', 'ticket', 'password') */
2017-04-17 23:39:06 +00:00
public $sendcontext ;
2024-08-01 09:09:26 +00:00
/** @var string Send mode of mail ('mail', 'smtps', 'swiftmailer', ...) */
2017-04-17 23:39:06 +00:00
public $sendmode ;
2024-08-01 09:09:26 +00:00
/**
* @ var mixed
* @ deprecated Seems unused , update if used
*/
2017-04-17 23:39:06 +00:00
public $sendsetup ;
2017-08-24 00:02:00 +00:00
2021-01-16 13:12:09 +00:00
/**
* @ var string Subject of email
*/
public $subject ;
2024-08-01 09:09:26 +00:00
/** @var string From: Label and EMail of sender (must include '<>'). For example '<myemail@example.com>' or 'John Doe <myemail@example.com>' or '<myemail+trackingid@example.com>'). Note that with gmail smtps, value here is forced by google to account (but not the reply-to). */
/**
* @ var string Sender email
* Sender : Who sends the email ( " Sender " has sent emails on behalf of " From " ) .
* Use it when the " From " is an email of a domain that is a SPF protected domain , and the sending smtp server is not this domain . In such case , add Sender field with an email of the protected domain .
*/
public $addr_from ;
2017-04-17 23:39:06 +00:00
// Return-Path: Email where to send bounds.
2024-08-01 09:09:26 +00:00
/** @var string Reply-To: Email where to send replies from mailer software (mailer use From if reply-to not defined, Gmail use gmail account if reply-to not defined) */
public $reply_to ;
/** @var string Errors-To: Email where to send errors. */
public $errors_to ;
/** @var string Comma separates list of destination emails */
2020-09-07 08:18:17 +00:00
public $addr_to ;
2024-08-01 09:09:26 +00:00
/** @var string Comma separates list of cc emails */
2020-09-07 08:18:17 +00:00
public $addr_cc ;
2024-08-01 09:09:26 +00:00
/** @var string Comma separates list of bcc emails */
2020-09-07 08:18:17 +00:00
public $addr_bcc ;
2024-08-01 09:09:26 +00:00
/** @var string Tracking code */
2020-09-07 08:18:17 +00:00
public $trackid ;
2008-11-15 00:52:42 +00:00
2024-08-01 09:09:26 +00:00
/** @var string Mixed Boundary */
2020-09-07 08:18:17 +00:00
public $mixed_boundary ;
2024-08-01 09:09:26 +00:00
/** @var string Related Boundary */
2020-09-07 08:18:17 +00:00
public $related_boundary ;
2024-08-01 09:09:26 +00:00
/** @var string Alternative Boundary */
2020-09-07 08:18:17 +00:00
public $alternative_boundary ;
2024-08-01 09:09:26 +00:00
/** @var int<0,1> When 1, request delivery receipt */
2020-09-07 08:18:17 +00:00
public $deliveryreceipt ;
2008-11-15 00:52:42 +00:00
2024-08-01 09:09:26 +00:00
/** @var ?int<1,1> When 1, there is at least one file */
2020-12-01 10:35:30 +00:00
public $atleastonefile ;
2025-03-15 15:34:35 +00:00
/** @var string Message to send */
2023-02-16 20:48:55 +00:00
public $msg ;
2025-03-15 15:34:35 +00:00
/** @var string End of line sequence */
2020-09-07 08:18:17 +00:00
public $eol ;
2025-03-15 15:34:35 +00:00
/** @var string End of line sequence (header ?) */
2020-09-07 08:18:17 +00:00
public $eol2 ;
2018-09-20 15:46:39 +00:00
/**
* @ var string Error code ( or message )
*/
2019-11-13 17:32:11 +00:00
public $error = '' ;
2008-11-15 00:52:42 +00:00
2022-08-10 11:38:18 +00:00
/**
* @ var string [] Array of Error code ( or message )
*/
public $errors = array ();
2022-08-10 08:59:57 +00:00
/**
2024-03-15 18:39:08 +00:00
* @ var SMTPS ( if this method is used )
2022-08-10 08:59:57 +00:00
*/
2024-03-15 18:39:08 +00:00
public $smtps ;
2022-08-10 08:59:57 +00:00
/**
2024-03-15 18:39:08 +00:00
* @ var Swift_Mailer ( if the method is used )
2022-08-10 08:59:57 +00:00
*/
public $mailer ;
2024-03-15 18:39:08 +00:00
/**
* @ var Swift_SmtpTransport
*/
public $transport ;
2022-08-10 11:38:18 +00:00
/**
* @ var Swift_Plugins_Loggers_ArrayLogger
*/
public $logger ;
2018-11-19 22:38:07 +00:00
/**
2024-08-01 09:09:26 +00:00
* @ var string | array < string , string > CSS
2018-11-19 22:38:07 +00:00
*/
public $css ;
2024-08-01 09:09:26 +00:00
/** @var ?string Defined css style for body background */
2020-09-07 08:18:17 +00:00
public $styleCSS ;
2024-08-01 09:09:26 +00:00
/** @var ?string Defined background directly in body tag */
2020-09-07 08:18:17 +00:00
public $bodyCSS ;
2009-05-24 20:01:25 +00:00
2024-03-15 18:39:08 +00:00
/**
* @ var string Message - ID of the email to send ( generated )
*/
2020-09-07 08:18:17 +00:00
public $msgid ;
2024-04-01 17:11:08 +00:00
/**
* @ var string Value to use in In - reply - to when email is set as an answer of another email ( The Msg - Id of received email )
*/
public $in_reply_to ;
/**
* @ var string References to add to the email to send ( generated from the email we answer )
*/
public $references ;
2024-08-01 09:09:26 +00:00
/**
* @ var string Headers
*/
2020-09-07 08:18:17 +00:00
public $headers ;
2024-04-01 17:11:08 +00:00
2024-08-01 09:09:26 +00:00
/**
2025-09-19 21:38:52 +00:00
* @ var string | Swift_Message Message
2024-08-01 09:09:26 +00:00
*/
2020-09-07 08:18:17 +00:00
public $message ;
2024-03-15 18:39:08 +00:00
2020-09-07 08:18:17 +00:00
/**
2024-08-01 09:09:26 +00:00
* @ var ? string [] fullfilenames list ( full path of filename on file system )
2019-09-17 08:15:55 +00:00
*/
public $filename_list = array ();
/**
2024-08-01 09:09:26 +00:00
* @ var ? string [] mimetypes of files list ( List of MIME type of attached files )
2019-09-17 08:15:55 +00:00
*/
public $mimetype_list = array ();
/**
2024-08-01 09:09:26 +00:00
* @ var ? string [] filenames list ( List of attached file name in message )
2019-09-17 08:15:55 +00:00
*/
public $mimefilename_list = array ();
2022-10-23 15:14:23 +00:00
/**
2024-08-01 09:09:26 +00:00
* @ var ? string [] filenames cid
2022-10-23 15:14:23 +00:00
*/
public $cid_list = array ();
2015-05-05 02:10:42 +00:00
2024-08-01 09:09:26 +00:00
/** @var string HTML content */
2020-09-07 08:18:17 +00:00
public $html ;
2024-08-01 09:09:26 +00:00
/** @var int<0,1> */
2023-02-22 20:38:26 +00:00
public $msgishtml ;
2024-08-01 09:09:26 +00:00
/** @var string */
2020-09-07 08:18:17 +00:00
public $image_boundary ;
2024-08-01 09:09:26 +00:00
/** @var int<0,1> */
2020-09-07 08:18:17 +00:00
public $atleastoneimage = 0 ; // at least one image file with file=xxx.ext into content (TODO Debug this. How can this case be tested. Remove if not used).
2024-08-01 09:09:26 +00:00
/** @var array<array{type:string,fullpath:string,content_type?:string,name:string,cid:string}> */
2020-09-07 08:18:17 +00:00
public $html_images = array ();
2024-08-01 09:09:26 +00:00
/** @var array<array{name:string,fullpath:string,content_type:string,cid:string,image_encoded:string}> */
2020-09-07 08:18:17 +00:00
public $images_encoded = array ();
2026-04-21 00:28:35 +00:00
/** @var array<string,string> Filename extension to MIME mapping */
2020-09-07 08:18:17 +00:00
public $image_types = array (
'gif' => 'image/gif' ,
2018-01-21 14:55:56 +00:00
'jpg' => 'image/jpeg' ,
'jpeg' => 'image/jpeg' ,
'jpe' => 'image/jpeg' ,
'bmp' => 'image/bmp' ,
'png' => 'image/png' ,
'tif' => 'image/tiff' ,
2020-09-07 08:18:17 +00:00
'tiff' => 'image/tiff' ,
2025-04-16 15:32:59 +00:00
'webp' => 'image/webp' ,
2020-09-07 08:18:17 +00:00
);
2009-02-09 00:04:34 +00:00
2008-11-15 00:52:42 +00:00
/**
2011-07-04 09:36:29 +00:00
* CMailFile
2011-07-20 11:07:12 +00:00
*
2025-07-21 21:20:08 +00:00
* @ param string $subject Topic / Subject of mail
* @ param string $to Recipients emails ( RFC 2822 : " Name firstname <email>[, ...] " or " email[, ...] " or " <email>[, ...] " ) . Note : the keyword '__SUPERVISOREMAIL__' is not allowed here and must be replaced by caller .
* @ param string $from Sender email ( RFC 2822 : " Name firstname <email>[, ...] " or " email[, ...] " or " <email>[, ...] " )
* @ param string $msg Message
* @ param ? string [] $filename_list List of files to attach ( full path of filename on file system )
* @ param ? string [] $mimetype_list List of MIME type of attached files
* @ param ? string [] $mimefilename_list List of attached file name in message
* @ param string $addr_cc Email cc ( Example : 'abc@def.com, ghk@lmn.com' )
* @ param string $addr_bcc Email bcc ( Note : This is autocompleted with MAIN_MAIL_AUTOCOPY_TO if defined )
* @ param int < 0 , 1 > $deliveryreceipt Ask a delivery receipt
* @ param int <- 1 , 1 > $msgishtml 1 = String IS already html , 0 = String IS NOT html , - 1 = Unknown make autodetection ( with fast mode , not reliable )
* @ param string $errors_to Email for errors - to
* @ param string | array < string , string > $css Css option ( should be array , legacy : empty string if none )
* @ param string $trackid Tracking string ( contains type and id of related element )
* @ param string $moreinheader More in header . $moreinheader must contains the " \r \n " at end of each line
* @ param string $sendcontext 'standard' , 'emailing' , 'ticket' , 'password' , ... ( used to define which sending mode and parameters to use )
* @ param string $replyto Reply - to email ( will be set to the same value than From by default if not provided )
* @ param string $upload_dir_tmp Temporary directory ( used to convert images embedded as img src = data : image )
* @ param string $in_reply_to Message - ID of the message we reply to
* @ param string $references String with list of Message - ID of the thread ( '<123> <456> ...' )
2008-11-15 00:52:42 +00:00
*/
2024-04-01 17:11:08 +00:00
public function __construct ( $subject , $to , $from , $msg , $filename_list = array (), $mimetype_list = array (), $mimefilename_list = array (), $addr_cc = " " , $addr_bcc = " " , $deliveryreceipt = 0 , $msgishtml = 0 , $errors_to = '' , $css = '' , $trackid = '' , $moreinheader = '' , $sendcontext = 'standard' , $replyto = '' , $upload_dir_tmp = '' , $in_reply_to = '' , $references = '' )
2008-11-15 00:52:42 +00:00
{
2022-03-17 11:39:39 +00:00
global $conf , $dolibarr_main_data_root , $user ;
2009-05-16 18:11:38 +00:00
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: charset= " . $conf -> file -> character_set_client . " from= $from , to= $to , addr_cc= $addr_cc , addr_bcc= $addr_bcc , errors_to= $errors_to , replyto= $replyto trackid= $trackid sendcontext= $sendcontext " );
dol_syslog ( " CMailFile::CMailFile: subject= " . $subject . " , deliveryreceipt= " . $deliveryreceipt . " , msgishtml= " . $msgishtml , LOG_DEBUG );
2023-02-16 20:44:38 +00:00
2020-02-06 11:58:02 +00:00
// Clean values of $mimefilename_list
if ( is_array ( $mimefilename_list )) {
2020-04-10 08:59:32 +00:00
foreach ( $mimefilename_list as $key => $val ) {
2020-02-06 11:58:02 +00:00
$mimefilename_list [ $key ] = dol_string_unaccent ( $mimefilename_list [ $key ]);
}
}
2022-10-23 15:14:23 +00:00
$cid_list = array ();
2017-04-17 23:39:06 +00:00
$this -> sendcontext = $sendcontext ;
2017-08-24 00:02:00 +00:00
2024-08-01 09:35:42 +00:00
// Define this->sendmode ('mail', 'smtps', 'swiftmailer', ...) according to $sendcontext ('standard', 'emailing', 'ticket', 'passwordreset')
2017-04-17 23:39:06 +00:00
$this -> sendmode = '' ;
2020-09-02 13:33:18 +00:00
if ( ! empty ( $this -> sendcontext )) {
$smtpContextKey = strtoupper ( $this -> sendcontext );
2022-08-31 12:02:09 +00:00
$smtpContextSendMode = getDolGlobalString ( 'MAIN_MAIL_SENDMODE_' . $smtpContextKey );
2020-09-02 13:33:18 +00:00
if ( ! empty ( $smtpContextSendMode ) && $smtpContextSendMode != 'default' ) {
$this -> sendmode = $smtpContextSendMode ;
}
2017-08-24 00:02:00 +00:00
}
2021-01-16 13:12:09 +00:00
if ( empty ( $this -> sendmode )) {
2024-03-13 17:39:51 +00:00
$this -> sendmode = getDolGlobalString ( 'MAIN_MAIL_SENDMODE' , 'mail' );
2021-01-16 13:12:09 +00:00
}
2017-04-17 23:39:06 +00:00
2024-01-19 13:05:42 +00:00
// Add a Feedback-ID. Must be used for stats on spam report only.
if ( $trackid ) {
//Examples:
// LinkedIn – Feedback-ID: accept_invite_04:linkedin
// Twitter – Feedback-ID: 0040162518f58f41d1f0:15491f3b2ee48656f8e7fb2fac:none:twitterESP
// Amazon.com : Feedback-ID: 1.eu-west-1.kjoQSiqb8G+7lWWiDVsxjM2m0ynYd4I6yEFlfoox6aY=:AmazonSES
$moreinheader .= " Feedback-ID: " . $trackid . ':' . dol_getprefix ( 'email' ) . " :dolib \r \n " ;
}
2012-11-13 16:25:47 +00:00
// We define end of line (RFC 821).
2019-11-13 17:32:11 +00:00
$this -> eol = " \r \n " ;
2013-03-13 18:14:49 +00:00
// We define end of line for header fields (RFC 822bis section 2.3 says header must contains \r\n).
2019-11-13 17:32:11 +00:00
$this -> eol2 = " \r \n " ;
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_FIX_FOR_BUGGED_MTA' )) {
2019-11-13 17:32:11 +00:00
$this -> eol = " \n " ;
$this -> eol2 = " \n " ;
2019-01-27 10:55:16 +00:00
$moreinheader = str_replace ( " \r \n " , " \n " , $moreinheader );
2012-11-13 16:25:47 +00:00
}
2009-05-17 22:54:12 +00:00
2011-03-25 18:12:58 +00:00
// On defini mixed_boundary
2019-11-13 17:32:11 +00:00
$this -> mixed_boundary = " multipart_x. " . time () . " .x_boundary " ;
2009-05-17 10:27:13 +00:00
// On defini related_boundary
2024-09-05 14:05:37 +00:00
$this -> related_boundary = 'mul_' . dol_hash ( uniqid ( " dolibarr2 " ), '3' ); // Force md5 hash (does not contain special chars)
2009-05-17 10:27:13 +00:00
// On defini alternative_boundary
2024-09-05 14:05:37 +00:00
$this -> alternative_boundary = 'mul_' . dol_hash ( uniqid ( " dolibarr3 " ), '3' ); // Force md5 hash (does not contain special chars)
2009-05-13 19:10:06 +00:00
2021-01-16 13:12:09 +00:00
if ( empty ( $subject )) {
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: Try to send an email with empty subject " );
2019-11-13 17:32:11 +00:00
$this -> error = 'ErrorSubjectIsRequired' ;
2017-04-17 23:39:06 +00:00
return ;
2016-06-24 13:36:20 +00:00
}
2021-01-16 13:12:09 +00:00
if ( empty ( $msg )) {
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: Try to send an email with empty body " );
2020-09-07 08:18:17 +00:00
$msg = '.' ; // Avoid empty message (with empty message content, you will see a multipart structure)
2017-08-24 00:02:00 +00:00
}
2016-06-24 13:36:20 +00:00
2008-07-16 23:37:34 +00:00
// Detect if message is HTML (use fast method)
2021-01-16 13:12:09 +00:00
if ( $msgishtml == - 1 ) {
2007-10-04 19:59:21 +00:00
$this -> msgishtml = 0 ;
2021-01-16 13:12:09 +00:00
if ( dol_textishtml ( $msg )) {
$this -> msgishtml = 1 ;
}
2020-05-21 13:05:19 +00:00
} else {
2007-10-04 19:59:21 +00:00
$this -> msgishtml = $msgishtml ;
}
2006-08-06 18:34:37 +00:00
2017-08-27 22:06:19 +00:00
global $dolibarr_main_url_root ;
// Define $urlwithroot
2019-11-13 17:32:11 +00:00
$urlwithouturlroot = preg_replace ( '/' . preg_quote ( DOL_URL_ROOT , '/' ) . '$/i' , '' , trim ( $dolibarr_main_url_root ));
$urlwithroot = $urlwithouturlroot . DOL_URL_ROOT ; // This is to use external domain name found into config file
2017-08-27 22:06:19 +00:00
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
// Replace relative /viewimage to absolute path
2020-02-09 14:51:43 +00:00
$msg = preg_replace ( '/src="' . preg_quote ( DOL_URL_ROOT , '/' ) . '\/viewimage\.php/ims' , 'src="' . $urlwithroot . '/viewimage.php' , $msg , - 1 );
2017-08-27 22:06:19 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML' )) {
2021-01-16 13:12:09 +00:00
$this -> msgishtml = 1 ; // To force to send everything with content type html.
}
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: msgishtml= " . $this -> msgishtml , LOG_DEBUG );
2017-01-11 15:47:17 +00:00
2009-05-11 17:13:56 +00:00
// Detect images
2021-01-16 13:12:09 +00:00
if ( $this -> msgishtml ) {
2009-05-11 17:13:56 +00:00
$this -> html = $msg ;
2011-11-16 22:58:25 +00:00
2020-12-07 14:36:37 +00:00
$findimg = 0 ;
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS' )) { // Off by default
2022-10-23 15:14:23 +00:00
// Search into the body for <img tags of links in medias files to replace them with an embedded file
// Note because media links are public, this should be useless, except avoid blocking images with email browser.
2024-01-13 18:48:20 +00:00
// This converts an embed file with src="/viewimage.php?modulepart... into a cid link
2023-02-25 03:05:18 +00:00
// TODO Exclude viewimage used for the read tracker ?
2025-08-07 14:17:11 +00:00
$dolibarr_main_data_root_images = $dolibarr_main_data_root ;
2025-08-24 20:05:46 +00:00
if (( int ) $conf -> entity !== 1 ) {
2026-02-12 15:29:11 +00:00
$dolibarr_main_data_root_images .= '/' . $conf -> entity . '/' ;
2025-08-07 12:42:20 +00:00
}
$findimg = $this -> findHtmlImages ( $dolibarr_main_data_root_images . '/medias' );
2024-03-11 20:39:04 +00:00
if ( $findimg < 0 ) {
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: Error on findHtmlImages " );
2024-04-03 12:46:46 +00:00
$this -> error = 'ErrorInAddAttachmentsImageBaseOnMedia' ;
2023-12-13 10:31:42 +00:00
return ;
}
2017-04-17 23:39:06 +00:00
}
2023-02-25 03:05:18 +00:00
2025-10-07 11:37:47 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_ADD_INLINE_IMAGES_IF_DATA' )) { // On by default because Gmail does not support src="data:image..."
2022-10-23 15:14:23 +00:00
// Search into the body for <img src="data:image/ext;base64,..." to replace them with an embedded file
2025-10-07 11:37:47 +00:00
// This convert an embedded file with src="data:image... into a cid link + attached file.
// It modifies ->html and complete ->html_images
2023-12-13 10:31:42 +00:00
$resultImageData = $this -> findHtmlImagesIsSrcData ( $upload_dir_tmp );
2024-03-11 20:39:04 +00:00
if ( $resultImageData < 0 ) {
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: Error on findHtmlImagesInSrcData code= " . $resultImageData . " upload_dir_tmp= " . $upload_dir_tmp );
2024-04-03 12:46:46 +00:00
$this -> error = 'ErrorInAddAttachmentsImageBaseIsSrcData' ;
2023-12-13 10:31:42 +00:00
return ;
}
$findimg += $resultImageData ;
2022-10-23 15:14:23 +00:00
}
2017-04-17 23:39:06 +00:00
2022-10-23 15:14:23 +00:00
// Set atleastoneimage if there is at least one embedded file (into ->html_images)
2022-11-21 17:30:17 +00:00
if ( $findimg > 0 ) {
2021-01-16 13:12:09 +00:00
foreach ( $this -> html_images as $i => $val ) {
if ( $this -> html_images [ $i ]) {
2019-11-13 17:32:11 +00:00
$this -> atleastoneimage = 1 ;
2022-10-23 15:14:23 +00:00
if ( $this -> html_images [ $i ][ 'type' ] == 'cidfromdata' ) {
2023-02-23 17:29:58 +00:00
if ( ! in_array ( $this -> html_images [ $i ][ 'fullpath' ], $filename_list )) {
2024-05-17 01:48:55 +00:00
// If this file path is not already into the $filename_list, we append it at end of array
2023-02-23 17:29:58 +00:00
$posindice = count ( $filename_list );
$filename_list [ $posindice ] = $this -> html_images [ $i ][ 'fullpath' ];
$mimetype_list [ $posindice ] = $this -> html_images [ $i ][ 'content_type' ];
$mimefilename_list [ $posindice ] = $this -> html_images [ $i ][ 'name' ];
} else {
$posindice = array_search ( $this -> html_images [ $i ][ 'fullpath' ], $filename_list );
}
// We complete the array of cid_list
2022-10-23 15:14:23 +00:00
$cid_list [ $posindice ] = $this -> html_images [ $i ][ 'cid' ];
}
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: html_images[ $i ]['name']= " . $this -> html_images [ $i ][ 'name' ], LOG_DEBUG );
2009-05-11 17:13:56 +00:00
}
}
}
}
2023-02-23 17:29:58 +00:00
//var_dump($filename_list);
//var_dump($cid_list);exit;
2009-05-11 17:13:56 +00:00
2022-10-23 15:14:23 +00:00
// Set atleastoneimage if there is at least one file (into $filename_list array)
2021-01-16 13:12:09 +00:00
if ( is_array ( $filename_list )) {
foreach ( $filename_list as $i => $val ) {
if ( $filename_list [ $i ]) {
2019-11-13 17:32:11 +00:00
$this -> atleastonefile = 1 ;
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: filename_list[ $i ]= " . $filename_list [ $i ] . " , mimetype_list[ $i ]= " . $mimetype_list [ $i ] . " mimefilename_list[ $i ]= " . $mimefilename_list [ $i ] . " cid_list[ $i ]= " . ( empty ( $cid_list [ $i ]) ? '' : $cid_list [ $i ]), LOG_DEBUG );
2018-06-01 15:20:49 +00:00
}
2009-02-09 00:04:34 +00:00
}
2006-08-06 18:34:37 +00:00
}
2004-07-16 06:41:58 +00:00
2022-03-17 11:39:39 +00:00
// Add auto copy to if not already in $to (Note: Adding bcc for specific modules are also done from pages)
// For example MAIN_MAIL_AUTOCOPY_TO can be 'email@example.com, __USER_EMAIL__, ...'
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_AUTOCOPY_TO' )) {
2023-12-13 14:20:53 +00:00
$listofemailstoadd = explode ( ',' , getDolGlobalString ( 'MAIN_MAIL_AUTOCOPY_TO' ));
2022-03-17 11:39:39 +00:00
foreach ( $listofemailstoadd as $key => $val ) {
$emailtoadd = $listofemailstoadd [ $key ];
if ( trim ( $emailtoadd ) == '__USER_EMAIL__' ) {
if ( ! empty ( $user ) && ! empty ( $user -> email )) {
$emailtoadd = $user -> email ;
} else {
$emailtoadd = '' ;
}
}
if ( $emailtoadd && preg_match ( '/' . preg_quote ( $emailtoadd , '/' ) . '/i' , $to )) {
$emailtoadd = '' ; // Email already in the "To"
}
if ( $emailtoadd ) {
$listofemailstoadd [ $key ] = $emailtoadd ;
} else {
unset ( $listofemailstoadd [ $key ]);
}
}
if ( ! empty ( $listofemailstoadd )) {
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 20:46:12 +00:00
$addr_bcc .= ( $addr_bcc ? ', ' : '' ) . implode ( ', ' , $listofemailstoadd );
2022-03-17 11:39:39 +00:00
}
2020-12-08 07:49:06 +00:00
}
2024-02-01 14:32:11 +00:00
// Verify if $to, $addr_cc and addr_bcc have unwanted addresses
if ( getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO' )) {
2025-04-05 17:09:40 +00:00
// Parse to, cc and bcc to remove MAIN_MAIL_FORCE_NOT_SENDING_TO
$listofemailstonotsendto = explode ( ',' , getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO' ));
2024-02-01 14:32:11 +00:00
//Verify for $to
2024-02-09 15:54:28 +00:00
$replaceto = false ;
2024-02-01 14:32:11 +00:00
$tabto = explode ( " , " , $to );
foreach ( $tabto as $key => $addrto ) {
2024-04-22 13:20:25 +00:00
$addrto = array_keys ( $this -> getArrayAddress ( $addrto ));
if ( in_array ( $addrto [ 0 ], $listofemailstonotsendto )) {
2024-02-01 14:32:11 +00:00
unset ( $tabto [ $key ]);
2024-02-09 15:54:28 +00:00
$replaceto = true ;
2024-02-01 14:32:11 +00:00
}
}
2024-02-09 15:54:28 +00:00
if ( $replaceto && getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' )) {
2024-02-01 14:32:11 +00:00
$tabto [] = getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' );
}
$to = implode ( ',' , $tabto );
//Verify for $addr_cc
2024-02-09 15:54:28 +00:00
$replacecc = false ;
2024-02-01 14:32:11 +00:00
$tabcc = explode ( ',' , $addr_cc );
foreach ( $tabcc as $key => $cc ) {
2024-04-22 13:20:25 +00:00
$cc = array_keys ( $this -> getArrayAddress ( $cc ));
if ( in_array ( $cc [ 0 ], $listofemailstonotsendto )) {
2024-02-01 14:32:11 +00:00
unset ( $tabcc [ $key ]);
2024-02-09 15:54:28 +00:00
$replacecc = true ;
2024-02-01 14:32:11 +00:00
}
}
2024-02-09 15:54:28 +00:00
if ( $replacecc && getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' )) {
$tabcc [] = getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' );
2024-02-01 14:32:11 +00:00
}
$addr_cc = implode ( ',' , $tabcc );
//Verify for $addr_bcc
2024-03-11 20:39:04 +00:00
$replacebcc = false ;
2024-02-01 14:32:11 +00:00
$tabbcc = explode ( ',' , $addr_bcc );
foreach ( $tabbcc as $key => $bcc ) {
2024-04-22 13:20:25 +00:00
$bcc = array_keys ( $this -> getArrayAddress ( $bcc ));
if ( in_array ( $bcc [ 0 ], $listofemailstonotsendto )) {
2024-02-01 14:32:11 +00:00
unset ( $tabbcc [ $key ]);
2024-02-09 15:54:28 +00:00
$replacebcc = true ;
2024-02-01 14:32:11 +00:00
}
}
2024-02-09 15:54:28 +00:00
if ( $replacebcc && getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' )) {
2024-02-01 14:32:11 +00:00
$tabbcc [] = getDolGlobalString ( 'MAIN_MAIL_FORCE_NOT_SENDING_TO_REPLACE' );
}
$addr_bcc = implode ( ',' , $tabbcc );
}
2024-02-01 12:12:21 +00:00
// We always use a replyto
if ( empty ( $replyto )) {
$replyto = dol_sanitizeEmail ( $from );
}
// We can force the from
if ( getDolGlobalString ( 'MAIN_MAIL_FORCE_FROM' )) {
$from = getDolGlobalString ( 'MAIN_MAIL_FORCE_FROM' );
}
2022-02-28 13:10:35 +00:00
$this -> subject = $subject ;
2022-11-28 14:37:38 +00:00
$this -> addr_to = dol_sanitizeEmail ( $to );
$this -> addr_from = dol_sanitizeEmail ( $from );
2022-02-28 13:10:35 +00:00
$this -> msg = $msg ;
2022-11-28 14:37:38 +00:00
$this -> addr_cc = dol_sanitizeEmail ( $addr_cc );
$this -> addr_bcc = dol_sanitizeEmail ( $addr_bcc );
2022-02-28 13:10:35 +00:00
$this -> deliveryreceipt = $deliveryreceipt ;
2022-11-28 15:57:06 +00:00
$this -> reply_to = dol_sanitizeEmail ( $replyto );
$this -> errors_to = dol_sanitizeEmail ( $errors_to );
2020-08-06 14:28:17 +00:00
$this -> trackid = $trackid ;
2024-04-01 17:11:08 +00:00
$this -> in_reply_to = $in_reply_to ;
$this -> references = $references ;
2022-10-23 15:14:23 +00:00
// Set arrays with attached files info
2022-02-28 13:10:35 +00:00
$this -> filename_list = $filename_list ;
$this -> mimetype_list = $mimetype_list ;
$this -> mimefilename_list = $mimefilename_list ;
2022-10-23 15:14:23 +00:00
$this -> cid_list = $cid_list ;
2020-08-06 14:28:17 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_FORCE_SENDTO' )) {
2024-02-01 12:12:21 +00:00
$this -> addr_to = dol_sanitizeEmail ( getDolGlobalString ( 'MAIN_MAIL_FORCE_SENDTO' ));
2020-08-06 14:28:17 +00:00
$this -> addr_cc = '' ;
$this -> addr_bcc = '' ;
}
2020-10-31 13:32:18 +00:00
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED' ;
2020-09-08 12:48:50 +00:00
if ( ! empty ( $this -> sendcontext )) {
$smtpContextKey = strtoupper ( $this -> sendcontext );
2022-08-31 12:02:09 +00:00
$smtpContextSendMode = getDolGlobalString ( 'MAIN_MAIL_SENDMODE_' . $smtpContextKey );
2020-09-08 12:48:50 +00:00
if ( ! empty ( $smtpContextSendMode ) && $smtpContextSendMode != 'default' ) {
2020-10-31 13:32:18 +00:00
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED_' . $smtpContextKey ;
2020-09-08 12:48:50 +00:00
}
}
2026-01-10 16:28:44 +00:00
dol_syslog ( " CMailFile::CMailFile: sendmode= " . $this -> sendmode . " addr_bcc= $addr_bcc , replyto= $replyto " , LOG_DEBUG );
2023-02-15 21:10:03 +00:00
2024-01-13 18:48:20 +00:00
// We set all data according to chose sending method.
2019-11-14 09:01:05 +00:00
// We also set a value for ->msgid
2021-01-16 13:12:09 +00:00
if ( $this -> sendmode == 'mail' ) {
2009-02-09 00:04:34 +00:00
// Use mail php function (default PHP method)
// ------------------------------------------
$smtp_headers = " " ;
$mime_headers = " " ;
$text_body = " " ;
2011-03-25 18:12:58 +00:00
$files_encoded = " " ;
2009-02-09 00:04:34 +00:00
2025-01-16 11:52:03 +00:00
// Define smtp_headers (this also set SMTP headers from ->in_reply_to and ->references and set the property ->msgid)
2009-02-09 00:04:34 +00:00
$smtp_headers = $this -> write_smtpheaders ();
2021-01-16 13:12:09 +00:00
if ( ! empty ( $moreinheader )) {
$smtp_headers .= $moreinheader ; // $moreinheader contains the \r\n
}
2017-01-11 15:47:17 +00:00
2009-05-17 22:54:12 +00:00
// Define mime_headers
2012-02-10 12:28:53 +00:00
$mime_headers = $this -> write_mimeheaders ( $filename_list , $mimefilename_list );
2009-05-13 14:49:30 +00:00
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> html )) {
if ( ! empty ( $css )) {
2009-11-18 12:31:55 +00:00
$this -> css = $css ;
2019-11-13 17:32:11 +00:00
$this -> buildCSS (); // Build a css style (mode = all) into this->styleCSS and this->bodyCSS
2009-11-18 12:31:55 +00:00
}
2010-01-12 23:03:34 +00:00
2009-11-18 12:31:55 +00:00
$msg = $this -> html ;
}
2006-10-31 23:10:46 +00:00
2009-05-17 22:54:12 +00:00
// Define body in text_body
2009-05-13 19:10:06 +00:00
$text_body = $this -> write_body ( $msg );
2009-05-17 22:54:12 +00:00
// Add attachments to text_encoded
2025-03-15 15:34:35 +00:00
if ( ! empty ( $this -> atleastonefile ) && $filename_list !== null && $mimetype_list !== null && $mimefilename_list !== null ) {
2022-10-23 15:14:23 +00:00
$files_encoded = $this -> write_files ( $filename_list , $mimetype_list , $mimefilename_list , $cid_list );
2009-02-09 00:04:34 +00:00
}
2008-11-15 00:52:42 +00:00
2012-02-01 19:44:06 +00:00
// We now define $this->headers and $this->message
2019-11-13 17:32:11 +00:00
$this -> headers = $smtp_headers . $mime_headers ;
2024-01-13 18:48:20 +00:00
// Clean the header to avoid that it terminates with a CR character.
2019-06-29 14:29:32 +00:00
// This avoid also empty lines at end that can be interpreted as mail injection by email servers.
2019-01-27 10:55:16 +00:00
$this -> headers = preg_replace ( " /([ \r \n ]+) $ /i " , " " , $this -> headers );
2012-02-01 19:44:06 +00:00
2017-10-16 12:31:28 +00:00
//$this->message = $this->eol.'This is a message with multiple parts in MIME format.'.$this->eol;
$this -> message = 'This is a message with multiple parts in MIME format.' . $this -> eol ;
2019-11-13 17:32:11 +00:00
$this -> message .= $text_body . $files_encoded ;
$this -> message .= " -- " . $this -> mixed_boundary . " -- " . $this -> eol ;
2021-01-16 13:12:09 +00:00
} elseif ( $this -> sendmode == 'smtps' ) {
2009-02-09 00:04:34 +00:00
// Use SMTPS library
// ------------------------------------------
2024-01-19 13:05:42 +00:00
$host = dol_getprefix ( 'email' );
2009-02-09 00:04:34 +00:00
2012-08-22 21:11:24 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/class/smtps.class.php' ;
2009-02-09 00:04:34 +00:00
$smtps = new SMTPs ();
2009-05-08 01:11:04 +00:00
$smtps -> setCharSet ( $conf -> file -> character_set_client );
2009-05-13 14:49:30 +00:00
2020-02-06 11:58:02 +00:00
// Encode subject if required.
2020-08-06 14:54:49 +00:00
$subjecttouse = $this -> subject ;
2020-04-10 08:59:32 +00:00
if ( ! ascii_check ( $subjecttouse )) {
2020-02-06 11:58:02 +00:00
$subjecttouse = $this -> encodetorfc2822 ( $subjecttouse );
}
$smtps -> setSubject ( $subjecttouse );
2020-08-07 15:06:57 +00:00
$smtps -> setTO ( $this -> getValidAddress ( $this -> addr_to , 0 , 1 ));
2020-08-07 15:06:12 +00:00
$smtps -> setFrom ( $this -> getValidAddress ( $this -> addr_from , 0 , 1 ));
2020-08-31 15:07:13 +00:00
$smtps -> setReplyTo ( $this -> getValidAddress ( $this -> reply_to , 0 , 1 ));
2017-01-11 15:47:17 +00:00
2024-04-01 17:11:08 +00:00
$smtps -> setTrackId ( $this -> trackid );
if ( ! empty ( $this -> in_reply_to )) {
$smtps -> setInReplyTo ( $this -> in_reply_to );
}
if ( ! empty ( $this -> references )) {
$smtps -> setReferences ( $this -> references );
}
2024-01-19 13:05:42 +00:00
2021-01-16 13:12:09 +00:00
if ( ! empty ( $moreinheader )) {
$smtps -> setMoreInHeader ( $moreinheader );
}
2017-01-12 10:06:24 +00:00
2024-04-01 17:11:08 +00:00
//X-Dolibarr-TRACKID, In-Reply-To, References and $moreinheader will be added to header inside the smtps->getHeader
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> html )) {
if ( ! empty ( $css )) {
2009-05-19 15:40:25 +00:00
$this -> css = $css ;
2013-03-15 17:27:48 +00:00
$this -> buildCSS ();
2009-05-19 15:40:25 +00:00
}
2009-05-13 14:49:30 +00:00
$msg = $this -> html ;
2024-03-19 09:31:39 +00:00
$msg = $this -> checkIfHTML ( $msg ); // This add a header and a body including custom CSS to the HTML content
2009-05-13 14:49:30 +00:00
}
2024-10-18 23:26:02 +00:00
if ( $msg === '.' ) {
$msg = " \n . \n " ;
}
2020-02-09 14:51:43 +00:00
// Replace . alone on a new line with .. to avoid to have SMTP interpret this as end of message
$msg = preg_replace ( '/(\r|\n)\.(\r|\n)/ims' , '\1..\2' , $msg );
2021-01-16 13:12:09 +00:00
if ( $this -> msgishtml ) {
$smtps -> setBodyContent ( $msg , 'html' );
} else {
$smtps -> setBodyContent ( $msg , 'plain' );
}
2009-02-09 00:04:34 +00:00
2025-10-07 11:37:47 +00:00
if ( ! empty ( $this -> atleastoneimage )) {
2021-01-16 13:12:09 +00:00
foreach ( $this -> images_encoded as $img ) {
2019-01-27 10:55:16 +00:00
$smtps -> setImageInline ( $img [ 'image_encoded' ], $img [ 'name' ], $img [ 'content_type' ], $img [ 'cid' ]);
2009-05-11 17:13:56 +00:00
}
}
2009-05-13 14:49:30 +00:00
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> atleastonefile )) {
foreach ( $filename_list as $i => $val ) {
2019-11-13 17:32:11 +00:00
$content = file_get_contents ( $filename_list [ $i ]);
2025-10-08 18:24:56 +00:00
if ( empty ( $cid_list [ $i ])) {
$smtps -> setAttachment ( $content , $mimefilename_list [ $i ], $mimetype_list [ $i ], ( empty ( $cid_list [ $i ]) ? '' : $cid_list [ $i ]));
}
2009-02-09 00:04:34 +00:00
}
}
2020-08-06 14:28:17 +00:00
$smtps -> setCC ( $this -> addr_cc );
$smtps -> setBCC ( $this -> addr_bcc );
$smtps -> setErrorsTo ( $this -> errors_to );
$smtps -> setDeliveryReceipt ( $this -> deliveryreceipt );
2025-03-26 04:06:41 +00:00
$options = array ();
2024-04-13 11:22:10 +00:00
if ( getDolGlobalString ( $keyforsslseflsigned )) {
2025-03-26 04:06:41 +00:00
$options = array ( 'ssl' => array ( 'verify_peer' => false , 'verify_peer_name' => false , 'allow_self_signed' => true ));
}
if ( getDolGlobalString ( 'SMTPS_CAPTURE_PEER_CERT' )) {
$options = array_merge ( $options , array ( 'ssl' => array ( 'capture_peer_cert' => true , 'capture_peer_cert_chain' => true )));
// Adding this will allow the code to retrieve information about the TLS certificate by doing
// $cert = stream_context_get_params($this->socket)['options']['ssl']['peer_certificate'];
// echo "Server Certificate Information:\n";
// echo "Subject: " . openssl_x509_parse($cert)['subject']['CN'] . "\n";
// echo "Issuer: " . openssl_x509_parse($cert)['issuer']['CN'] . "\n";
// echo "Valid From: " . date('Y-m-d H:i:s', openssl_x509_parse($cert)['validFrom_time_t']) . "\n";
// echo "Valid To: " . date('Y-m-d H:i:s', openssl_x509_parse($cert)['validTo_time_t']) . "\n";
}
if ( getDolGlobalString ( 'SMTPS_FORCE_IP_V4' )) {
$options = array_merge ( $options , array ( 'socket' => [ 'bindto' => '0.0.0.0:0' ])); // Forces IPv4 (IPv6 would be '::0')
}
if ( ! empty ( $options )) {
$smtps -> setOptions ( $options );
2021-01-16 13:12:09 +00:00
}
2009-02-09 00:04:34 +00:00
2025-07-17 23:33:24 +00:00
$this -> msgid = uniqid ( '' , true ) . '.SMTPs-dolibarr-' . $this -> trackid . '@' . $host ;
2019-11-14 09:01:05 +00:00
2025-07-21 23:23:28 +00:00
$smtps -> setMessageID ( $this -> msgid );
2019-11-13 17:32:11 +00:00
$this -> smtps = $smtps ;
2020-08-07 09:59:55 +00:00
} elseif ( $this -> sendmode == 'swiftmailer' ) {
2017-04-17 23:39:06 +00:00
// Use Swift Mailer library
2024-01-19 13:05:42 +00:00
// ------------------------------------------
2020-09-07 08:18:17 +00:00
$host = dol_getprefix ( 'email' );
require_once DOL_DOCUMENT_ROOT . '/includes/swiftmailer/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php' ;
// egulias autoloader lib
require_once DOL_DOCUMENT_ROOT . '/includes/swiftmailer/autoload.php' ;
require_once DOL_DOCUMENT_ROOT . '/includes/swiftmailer/lib/swift_required.php' ;
// Create the message
//$this->message = Swift_Message::newInstance();
$this -> message = new Swift_Message ();
//$this->message = new Swift_SignedMessage();
// Adding a trackid header to a message
$headers = $this -> message -> getHeaders ();
2024-03-15 18:39:08 +00:00
2020-09-07 08:18:17 +00:00
$headers -> addTextHeader ( 'X-Dolibarr-TRACKID' , $this -> trackid . '@' . $host );
2025-07-17 23:33:24 +00:00
$this -> msgid = uniqid ( '' , true ) . '.swiftmailer-dolibarr-' . $this -> trackid . '@' . $host ;
2020-09-07 08:18:17 +00:00
$headerID = $this -> msgid ;
$msgid = $headers -> get ( 'Message-ID' );
2024-08-01 09:09:26 +00:00
if ( $msgid instanceof Swift_Mime_Headers_IdentificationHeader ) {
$msgid -> setId ( $headerID );
}
2024-03-15 18:39:08 +00:00
2024-04-01 17:11:08 +00:00
// Add 'In-Reply-To:' header
if ( ! empty ( $this -> in_reply_to )) {
$headers -> addIdHeader ( 'In-Reply-To' , $this -> in_reply_to );
}
2024-03-15 18:39:08 +00:00
// Add 'References:' header
2024-04-01 17:11:08 +00:00
if ( ! empty ( $this -> references )) {
$headers -> addIdHeader ( 'References' , $this -> references );
}
2024-01-19 13:05:42 +00:00
if ( ! empty ( $moreinheader )) {
$moreinheaderarray = preg_split ( '/[\r\n]+/' , $moreinheader );
foreach ( $moreinheaderarray as $moreinheaderval ) {
$moreinheadervaltmp = explode ( ':' , $moreinheaderval , 2 );
if ( ! empty ( $moreinheadervaltmp [ 0 ]) && ! empty ( $moreinheadervaltmp [ 1 ])) {
$headers -> addTextHeader ( $moreinheadervaltmp [ 0 ], $moreinheadervaltmp [ 1 ]);
}
}
}
2020-09-07 08:18:17 +00:00
// Give the message a subject
try {
2023-05-13 06:58:52 +00:00
$this -> message -> setSubject ( $this -> subject );
2020-09-07 08:18:17 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
// Set the From address with an associative array
2025-09-19 21:38:52 +00:00
// $this->message->setFrom(array('john@doe.com' => 'John Doe'));
2020-09-08 19:27:28 +00:00
if ( ! empty ( $this -> addr_from )) {
2020-09-07 08:18:17 +00:00
try {
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_FORCE_DISABLE_MAIL_SPOOFING' )) {
2020-07-06 10:00:14 +00:00
// Prevent email spoofing for smtp server with a strict configuration
$regexp = '/([a-z0-9_\.\-\+])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,4})+/i' ; // This regular expression extracts all emails from a string
2022-10-23 15:14:23 +00:00
$adressEmailFrom = array ();
2020-07-06 10:00:14 +00:00
$emailMatchs = preg_match_all ( $regexp , $from , $adressEmailFrom );
$adressEmailFrom = reset ( $adressEmailFrom );
2025-09-19 21:38:52 +00:00
if ( $emailMatchs !== false && filter_var ( getDolGlobalString ( 'MAIN_MAIL_SMTPS_ID' ), FILTER_VALIDATE_EMAIL ) && getDolGlobalString ( 'MAIN_MAIL_SMTPS_ID' ) !== $adressEmailFrom [ 0 ]) {
2025-09-18 14:26:38 +00:00
$this -> message -> setFrom ( getDolGlobalString ( 'MAIN_MAIL_SMTPS_ID' ));
2020-07-06 10:01:00 +00:00
} else {
2022-08-04 07:24:57 +00:00
$this -> message -> setFrom ( $this -> getArrayAddress ( $this -> addr_from ));
2020-07-06 10:00:14 +00:00
}
} else {
2022-08-04 07:24:57 +00:00
$this -> message -> setFrom ( $this -> getArrayAddress ( $this -> addr_from ));
2020-07-01 14:55:23 +00:00
}
2020-09-07 08:18:17 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
}
// Set the To addresses with an associative array
2020-09-08 19:27:28 +00:00
if ( ! empty ( $this -> addr_to )) {
2020-09-07 08:18:17 +00:00
try {
2022-08-04 07:24:57 +00:00
$this -> message -> setTo ( $this -> getArrayAddress ( $this -> addr_to ));
2020-09-07 08:18:17 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
}
2020-09-08 19:27:28 +00:00
if ( ! empty ( $this -> reply_to )) {
2020-09-07 08:18:17 +00:00
try {
2022-08-04 07:24:57 +00:00
$this -> message -> SetReplyTo ( $this -> getArrayAddress ( $this -> reply_to ));
2020-09-07 08:18:17 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
}
2023-05-13 06:58:52 +00:00
if ( ! empty ( $this -> errors_to )) {
try {
2024-07-25 15:55:52 +00:00
$headers -> addMailboxHeader ( 'Errors-To' , $this -> getArrayAddress ( $this -> errors_to ));
2023-05-13 06:58:52 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
}
2020-09-07 08:18:17 +00:00
try {
2022-08-04 07:24:57 +00:00
$this -> message -> setCharSet ( $conf -> file -> character_set_client );
2020-09-07 08:18:17 +00:00
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
if ( ! empty ( $this -> html )) {
2019-03-02 13:32:52 +00:00
if ( ! empty ( $css )) {
2017-04-17 23:39:06 +00:00
$this -> css = $css ;
$this -> buildCSS ();
}
$msg = $this -> html ;
2024-03-19 09:31:39 +00:00
$msg = $this -> checkIfHTML ( $msg ); // This add a header and a body including custom CSS to the HTML content
2017-04-17 23:39:06 +00:00
}
2021-01-16 13:12:09 +00:00
if ( $this -> atleastoneimage ) {
2024-06-08 10:00:23 +00:00
foreach ( $this -> html_images as $img ) {
// $img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid']
$attachment = Swift_Image :: fromPath ( $img [ 'fullpath' ]);
// embed image
$imgcid = $this -> message -> embed ( $attachment );
// replace cid by the one created by swiftmail in html message
$msg = str_replace ( " cid: " . $img [ 'cid' ], $imgcid , $msg );
}
2021-01-16 13:12:09 +00:00
foreach ( $this -> images_encoded as $img ) {
2017-04-17 23:39:06 +00:00
//$img['fullpath'],$img['image_encoded'],$img['name'],$img['content_type'],$img['cid']
2019-09-06 08:36:49 +00:00
$attachment = Swift_Image :: fromPath ( $img [ 'fullpath' ]);
2017-04-17 23:39:06 +00:00
// embed image
$imgcid = $this -> message -> embed ( $attachment );
// replace cid by the one created by swiftmail in html message
$msg = str_replace ( " cid: " . $img [ 'cid' ], $imgcid , $msg );
}
}
if ( $this -> msgishtml ) {
2019-01-27 10:55:16 +00:00
$this -> message -> setBody ( $msg , 'text/html' );
2017-04-17 23:39:06 +00:00
// And optionally an alternative body
2018-01-21 14:55:56 +00:00
$this -> message -> addPart ( html_entity_decode ( strip_tags ( $msg )), 'text/plain' );
2017-04-17 23:39:06 +00:00
} else {
2019-01-27 10:55:16 +00:00
$this -> message -> setBody ( $msg , 'text/plain' );
2017-04-17 23:39:06 +00:00
// And optionally an alternative body
2019-12-22 08:13:34 +00:00
$this -> message -> addPart ( dol_nl2br ( $msg ), 'text/html' );
2017-04-17 23:39:06 +00:00
}
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> atleastonefile )) {
foreach ( $filename_list as $i => $val ) {
2017-04-17 23:39:06 +00:00
//$this->message->attach(Swift_Attachment::fromPath($filename_list[$i],$mimetype_list[$i]));
2019-01-27 10:55:16 +00:00
$attachment = Swift_Attachment :: fromPath ( $filename_list [ $i ], $mimetype_list [ $i ]);
2020-09-01 13:36:35 +00:00
if ( ! empty ( $mimefilename_list [ $i ])) {
$attachment -> setFilename ( $mimefilename_list [ $i ]);
}
2017-04-17 23:39:06 +00:00
$this -> message -> attach ( $attachment );
}
}
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> addr_cc )) {
2022-08-02 09:01:09 +00:00
try {
$this -> message -> setCc ( $this -> getArrayAddress ( $this -> addr_cc ));
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
2021-01-16 13:12:09 +00:00
}
if ( ! empty ( $this -> addr_bcc )) {
2022-08-02 09:01:09 +00:00
try {
$this -> message -> setBcc ( $this -> getArrayAddress ( $this -> addr_bcc ));
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
2021-01-16 13:12:09 +00:00
}
if ( isset ( $this -> deliveryreceipt ) && $this -> deliveryreceipt == 1 ) {
2022-08-04 07:24:57 +00:00
try {
$this -> message -> setReadReceiptTo ( $this -> getArrayAddress ( $this -> addr_from ));
} catch ( Exception $e ) {
$this -> errors [] = $e -> getMessage ();
}
2021-01-16 13:12:09 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2009-02-09 00:04:34 +00:00
// Send mail method not correctly defined
// --------------------------------------
2017-04-17 23:39:06 +00:00
$this -> error = 'Bad value for sendmode' ;
2008-11-15 00:52:42 +00:00
}
}
/**
2018-02-03 16:32:38 +00:00
* Send mail that was prepared by constructor .
2010-01-12 23:03:34 +00:00
*
2024-03-15 16:24:15 +00:00
* @ return bool True if mail sent , false otherwise . Negative int if error in hook . String if incorrect send mode .
*
* @ phan - suppress PhanTypeMismatchReturnNullable False positif by phan for unclear reason .
2008-11-15 00:52:42 +00:00
*/
2019-02-25 21:27:04 +00:00
public function sendfile ()
2007-06-07 21:24:01 +00:00
{
2023-03-26 15:59:28 +00:00
global $conf , $db , $langs , $hookmanager ;
2008-11-15 00:52:42 +00:00
2019-11-13 17:32:11 +00:00
$errorlevel = error_reporting ();
2018-01-21 14:55:56 +00:00
//error_reporting($errorlevel ^ E_WARNING); // Desactive warnings
2006-08-06 18:34:37 +00:00
2019-11-13 17:32:11 +00:00
$res = false ;
2008-11-15 00:52:42 +00:00
2023-11-27 10:24:19 +00:00
if ( ! getDolGlobalString ( 'MAIN_DISABLE_ALL_MAILS' )) {
2023-03-26 15:59:28 +00:00
if ( ! is_object ( $hookmanager )) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php' ;
$hookmanager = new HookManager ( $db );
}
2018-02-03 16:32:38 +00:00
$hookmanager -> initHooks ( array ( 'mail' ));
2021-03-01 19:37:16 +00:00
$parameters = array ();
$action = '' ;
2018-02-03 16:32:38 +00:00
$reshook = $hookmanager -> executeHooks ( 'sendMail' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
2021-01-16 13:12:09 +00:00
if ( $reshook < 0 ) {
2019-11-13 17:32:11 +00:00
$this -> error = " Error in hook maildao sendMail " . $reshook ;
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2017-04-17 23:39:06 +00:00
2024-03-12 14:13:54 +00:00
return false ;
2017-04-17 23:39:06 +00:00
}
2021-01-16 13:12:09 +00:00
if ( $reshook == 1 ) { // Hook replace standard code
2024-08-15 13:17:39 +00:00
dol_syslog ( " A hook has replaced code to send email " , LOG_DEBUG );
2018-02-03 16:32:38 +00:00
return true ;
}
2017-04-17 23:39:06 +00:00
2019-05-21 19:16:06 +00:00
$sendingmode = $this -> sendmode ;
2023-11-27 10:24:19 +00:00
if ( $this -> sendcontext == 'emailing' && getDolGlobalString ( 'MAILING_NO_USING_PHPMAIL' ) && $sendingmode == 'mail' ) {
2020-09-07 08:18:17 +00:00
// List of sending methods
$listofmethods = array ();
$listofmethods [ 'mail' ] = 'PHP mail function' ;
//$listofmethods['simplemail']='Simplemail class';
$listofmethods [ 'smtps' ] = 'SMTP/SMTPS socket library' ;
// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
// You ensure that every user is using its own SMTP server when using the mass emailing module.
$linktoadminemailbefore = '<a href="' . DOL_URL_ROOT . '/admin/mails.php">' ;
$linktoadminemailend = '</a>' ;
$this -> error = $langs -> trans ( " MailSendSetupIs " , $listofmethods [ $sendingmode ]);
$this -> errors [] = $langs -> trans ( " MailSendSetupIs " , $listofmethods [ $sendingmode ]);
$this -> error .= '<br>' . $langs -> trans ( " MailSendSetupIs2 " , $linktoadminemailbefore , $linktoadminemailend , $langs -> transnoentitiesnoconv ( " MAIN_MAIL_SENDMODE " ), $listofmethods [ 'smtps' ]);
$this -> errors [] = $langs -> trans ( " MailSendSetupIs2 " , $linktoadminemailbefore , $linktoadminemailend , $langs -> transnoentitiesnoconv ( " MAIN_MAIL_SENDMODE " ), $listofmethods [ 'smtps' ]);
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS' )) {
2024-01-05 03:18:53 +00:00
$this -> error .= '<br>' . $langs -> trans ( " MailSendSetupIs3 " , getDolGlobalString ( 'MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS' ));
$this -> errors [] = $langs -> trans ( " MailSendSetupIs3 " , getDolGlobalString ( 'MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS' ));
2020-09-07 08:18:17 +00:00
}
2023-03-23 10:14:22 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_WARNING );
2020-09-07 08:18:17 +00:00
return false ;
2019-05-21 19:16:06 +00:00
}
2017-04-17 23:39:06 +00:00
// Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
2023-11-27 10:24:19 +00:00
if ( ! getDolGlobalString ( 'MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL' )) {
2021-01-16 13:12:09 +00:00
$conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL = 10 ;
}
2017-04-17 23:39:06 +00:00
$tmparray1 = explode ( ',' , $this -> addr_to );
2021-01-16 13:12:09 +00:00
if ( count ( $tmparray1 ) > $conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL ) {
2017-04-17 23:39:06 +00:00
$this -> error = 'Too much recipients in to:' ;
2019-11-13 17:32:11 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_WARNING );
2017-04-17 23:39:06 +00:00
return false ;
}
2023-11-27 10:24:19 +00:00
if ( ! getDolGlobalString ( 'MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL' )) {
2021-01-16 13:12:09 +00:00
$conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL = 10 ;
}
2017-04-17 23:39:06 +00:00
$tmparray2 = explode ( ',' , $this -> addr_cc );
2021-01-16 13:12:09 +00:00
if ( count ( $tmparray2 ) > $conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL ) {
2017-04-17 23:39:06 +00:00
$this -> error = 'Too much recipients in cc:' ;
2019-11-13 17:32:11 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_WARNING );
2017-04-17 23:39:06 +00:00
return false ;
}
2023-11-27 10:24:19 +00:00
if ( ! getDolGlobalString ( 'MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL' )) {
2021-01-16 13:12:09 +00:00
$conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL = 10 ;
}
2017-04-17 23:39:06 +00:00
$tmparray3 = explode ( ',' , $this -> addr_bcc );
2021-01-16 13:12:09 +00:00
if ( count ( $tmparray3 ) > $conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL ) {
2017-04-17 23:39:06 +00:00
$this -> error = 'Too much recipients in bcc:' ;
2019-11-13 17:32:11 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_WARNING );
2017-04-17 23:39:06 +00:00
return false ;
}
2023-11-27 10:24:19 +00:00
if ( ! getDolGlobalString ( 'MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL' )) {
2021-01-16 13:12:09 +00:00
$conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL = 10 ;
}
if (( count ( $tmparray1 ) + count ( $tmparray2 ) + count ( $tmparray3 )) > $conf -> global -> MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL ) {
2017-04-17 23:39:06 +00:00
$this -> error = 'Too much recipients in to:, cc:, bcc:' ;
2019-11-13 17:32:11 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_WARNING );
2017-04-17 23:39:06 +00:00
return false ;
}
2017-01-11 15:47:17 +00:00
2019-11-13 17:32:11 +00:00
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER' ;
2025-09-12 13:12:55 +00:00
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT' ;
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID' ;
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW' ;
2022-08-26 13:21:35 +00:00
$keyforsmtpauthtype = 'MAIN_MAIL_SMTPS_AUTH_TYPE' ;
$keyforsmtpoauthservice = 'MAIN_MAIL_SMTPS_OAUTH_SERVICE' ;
2025-09-12 13:12:55 +00:00
$keyfortls = 'MAIN_MAIL_EMAIL_TLS' ;
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS' ;
2020-10-31 13:32:18 +00:00
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED' ;
2020-09-02 13:33:18 +00:00
if ( ! empty ( $this -> sendcontext )) {
$smtpContextKey = strtoupper ( $this -> sendcontext );
2022-08-31 12:02:09 +00:00
$smtpContextSendMode = getDolGlobalString ( 'MAIN_MAIL_SENDMODE_' . $smtpContextKey );
2020-09-02 13:33:18 +00:00
if ( ! empty ( $smtpContextSendMode ) && $smtpContextSendMode != 'default' ) {
2020-10-31 13:32:18 +00:00
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER_' . $smtpContextKey ;
2025-09-12 13:12:55 +00:00
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT_' . $smtpContextKey ;
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID_' . $smtpContextKey ;
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW_' . $smtpContextKey ;
2022-08-26 13:21:35 +00:00
$keyforsmtpauthtype = 'MAIN_MAIL_SMTPS_AUTH_TYPE_' . $smtpContextKey ;
$keyforsmtpoauthservice = 'MAIN_MAIL_SMTPS_OAUTH_SERVICE_' . $smtpContextKey ;
2025-09-12 13:12:55 +00:00
$keyfortls = 'MAIN_MAIL_EMAIL_TLS_' . $smtpContextKey ;
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS_' . $smtpContextKey ;
2020-10-31 13:32:18 +00:00
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED_' . $smtpContextKey ;
2020-09-02 13:33:18 +00:00
}
2017-08-24 00:02:00 +00:00
}
2024-01-13 18:48:20 +00:00
// Action according to chose sending method
2021-01-16 13:12:09 +00:00
if ( $this -> sendmode == 'mail' ) {
2009-02-09 00:04:34 +00:00
// Use mail php function (default PHP method)
// ------------------------------------------
2024-09-23 11:54:48 +00:00
dol_syslog ( " CMailFile::sendfile addr_to= " . $this -> addr_to . " , subject= " . $this -> subject , LOG_NOTICE );
2023-03-23 09:54:25 +00:00
//dol_syslog("CMailFile::sendfile header=\n".$this->headers, LOG_DEBUG);
2009-02-20 22:53:15 +00:00
//dol_syslog("CMailFile::sendfile message=\n".$message);
2009-02-09 00:04:34 +00:00
2009-05-17 22:54:12 +00:00
// If Windows, sendmail_from must be defined
2021-01-16 13:12:09 +00:00
if ( isset ( $_SERVER [ " WINDIR " ])) {
if ( empty ( $this -> addr_from )) {
$this -> addr_from = 'robot@example.com' ;
}
2019-01-27 10:55:16 +00:00
@ ini_set ( 'sendmail_from' , $this -> getValidAddress ( $this -> addr_from , 2 ));
2009-02-09 00:04:34 +00:00
}
2017-08-24 00:02:00 +00:00
// Force parameters
2023-12-23 19:00:57 +00:00
//dol_syslog("CMailFile::sendfile conf->global->".$keyforsmtpserver."=".getDolGlobalString($keyforsmtpserver)." cpnf->global->".$keyforsmtpport."=".$conf->global->$keyforsmtpport, LOG_DEBUG);
if ( getDolGlobalString ( $keyforsmtpserver )) {
ini_set ( 'SMTP' , getDolGlobalString ( $keyforsmtpserver ));
2021-01-16 13:12:09 +00:00
}
2023-12-23 19:00:57 +00:00
if ( getDolGlobalString ( $keyforsmtpport )) {
ini_set ( 'smtp_port' , getDolGlobalString ( $keyforsmtpport ));
2021-01-16 13:12:09 +00:00
}
2009-02-09 00:04:34 +00:00
2019-11-13 17:32:11 +00:00
$res = true ;
2021-01-16 13:12:09 +00:00
if ( $res && ! $this -> subject ) {
2019-11-13 17:32:11 +00:00
$this -> error = " Failed to send mail with php mail to HOST= " . ini_get ( 'SMTP' ) . " , PORT= " . ini_get ( 'smtp_port' ) . " <br>Subject is empty " ;
2018-02-28 18:09:05 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2018-02-28 18:09:05 +00:00
}
2019-11-13 17:32:11 +00:00
$dest = $this -> getValidAddress ( $this -> addr_to , 2 );
2021-01-16 13:12:09 +00:00
if ( $res && ! $dest ) {
2019-11-13 17:32:11 +00:00
$this -> error = " Failed to send mail with php mail to HOST= " . ini_get ( 'SMTP' ) . " , PORT= " . ini_get ( 'smtp_port' ) . " <br>Recipient address ' $dest ' invalid " ;
2011-11-01 12:22:39 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2009-02-09 00:04:34 +00:00
}
2018-02-28 18:09:05 +00:00
2021-01-16 13:12:09 +00:00
if ( $res ) {
2019-11-13 17:32:11 +00:00
$additionnalparam = '' ; // By default
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_ALLOW_SENDMAIL_F' )) {
2024-02-06 16:46:12 +00:00
// When using the phpmail function, the mail command may force the from to the user of the login, for example: linuxuser@myserver.mydomain.com
// You can try to set this option to have the command use the From. if it does not work, you can also try the MAIN_MAIL_SENDMAIL_FORCE_BA.
// So forcing using the option -f of sendmail is possible if constant MAIN_MAIL_ALLOW_SENDMAIL_F is defined.
2016-12-25 23:00:28 +00:00
// Having this variable defined may create problems with some sendmail (option -f refused)
// Having this variable not defined may create problems with some other sendmail (option -f required)
2023-11-27 10:24:19 +00:00
$additionnalparam .= ( $additionnalparam ? ' ' : '' ) . ( getDolGlobalString ( 'MAIN_MAIL_ERRORS_TO' ) ? '-f' . $this -> getValidAddress ( $conf -> global -> MAIN_MAIL_ERRORS_TO , 2 ) : ( $this -> addr_from != '' ? '-f' . $this -> getValidAddress ( $this -> addr_from , 2 ) : '' ));
2009-02-09 00:04:34 +00:00
}
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_SENDMAIL_FORCE_BA' )) { // To force usage of -ba option. This option tells sendmail to read From: or Sender: to setup sender
2019-11-13 17:32:11 +00:00
$additionnalparam .= ( $additionnalparam ? ' ' : '' ) . '-ba' ;
2017-04-17 23:39:06 +00:00
}
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_SENDMAIL_FORCE_ADDPARAM' )) {
2024-01-13 18:48:20 +00:00
$additionnalparam .= ( $additionnalparam ? ' ' : '' ) . '-U ' . $additionnalparam ; // Use -U to add additional params
2021-01-16 13:12:09 +00:00
}
2017-04-17 23:39:06 +00:00
2020-12-13 17:32:55 +00:00
$linuxlike = 1 ;
2021-01-16 13:12:09 +00:00
if ( preg_match ( '/^win/i' , PHP_OS )) {
$linuxlike = 0 ;
}
if ( preg_match ( '/^mac/i' , PHP_OS )) {
$linuxlike = 0 ;
}
2020-12-13 17:32:55 +00:00
dol_syslog ( " CMailFile::sendfile: mail start " . ( $linuxlike ? '' : " HOST= " . ini_get ( 'SMTP' ) . " , PORT= " . ini_get ( 'smtp_port' )) . " , additionnal_parameters= " . $additionnalparam , LOG_DEBUG );
2017-04-17 23:39:06 +00:00
2019-11-13 17:32:11 +00:00
$this -> message = stripslashes ( $this -> message );
2009-05-13 19:10:06 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2021-01-16 13:12:09 +00:00
$this -> dump_mail ();
}
2009-05-13 19:10:06 +00:00
2020-02-06 11:58:02 +00:00
// Encode subject if required.
$subjecttouse = $this -> subject ;
2020-04-10 08:59:32 +00:00
if ( ! ascii_check ( $subjecttouse )) {
2020-02-06 11:58:02 +00:00
$subjecttouse = $this -> encodetorfc2822 ( $subjecttouse );
}
2021-01-16 13:12:09 +00:00
if ( ! empty ( $additionnalparam )) {
$res = mail ( $dest , $subjecttouse , $this -> message , $this -> headers , $additionnalparam );
} else {
$res = mail ( $dest , $subjecttouse , $this -> message , $this -> headers );
}
2009-05-24 20:01:25 +00:00
2021-01-16 13:12:09 +00:00
if ( ! $res ) {
2018-06-29 16:23:59 +00:00
$langs -> load ( " errors " );
2019-11-13 17:32:11 +00:00
$this -> error = " Failed to send mail with php mail " ;
2020-12-13 17:32:55 +00:00
if ( ! $linuxlike ) {
2019-11-13 17:32:11 +00:00
$this -> error .= " to HOST= " . ini_get ( 'SMTP' ) . " , PORT= " . ini_get ( 'smtp_port' ); // This values are value used only for non linuxlike systems
2015-06-26 11:18:40 +00:00
}
2019-11-13 17:32:11 +00:00
$this -> error .= " .<br> " ;
$this -> error .= $langs -> trans ( " ErrorPhpMailDelivery " );
2011-11-01 12:22:39 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2023-03-02 09:38:45 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2023-03-30 12:48:04 +00:00
$this -> save_dump_mail_in_err ( 'Mail with topic ' . $this -> subject );
2023-03-02 09:38:45 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2009-05-24 20:01:25 +00:00
dol_syslog ( " CMailFile::sendfile: mail end success " , LOG_DEBUG );
2009-05-17 22:54:12 +00:00
}
2009-05-24 20:01:25 +00:00
}
2021-01-16 13:12:09 +00:00
if ( isset ( $_SERVER [ " WINDIR " ])) {
2009-05-24 20:01:25 +00:00
@ ini_restore ( 'sendmail_from' );
}
2017-08-24 00:02:00 +00:00
// Restore parameters
2023-12-23 19:00:57 +00:00
if ( getDolGlobalString ( $keyforsmtpserver )) {
2021-01-16 13:12:09 +00:00
ini_restore ( 'SMTP' );
}
2023-12-23 19:00:57 +00:00
if ( getDolGlobalString ( $keyforsmtpport )) {
2021-01-16 13:12:09 +00:00
ini_restore ( 'smtp_port' );
}
} elseif ( $this -> sendmode == 'smtps' ) {
if ( ! is_object ( $this -> smtps )) {
2023-08-29 20:13:38 +00:00
$this -> error = " Failed to send mail with smtps lib<br>Constructor of object CMailFile was not initialized without errors. " ;
2018-06-18 23:15:37 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
return false ;
}
2009-02-09 00:04:34 +00:00
// Use SMTPS library
// ------------------------------------------
2019-11-13 17:32:11 +00:00
$this -> smtps -> setTransportType ( 0 ); // Only this method is coded in SMTPs library
2009-02-09 00:04:34 +00:00
2017-04-11 08:57:17 +00:00
// Clean parameters
2021-01-16 13:12:09 +00:00
if ( empty ( $conf -> global -> $keyforsmtpserver )) {
$conf -> global -> $keyforsmtpserver = ini_get ( 'SMTP' );
}
if ( empty ( $conf -> global -> $keyforsmtpport )) {
$conf -> global -> $keyforsmtpport = ini_get ( 'smtp_port' );
}
2017-04-17 23:39:06 +00:00
2009-11-01 14:16:30 +00:00
// If we use SSL/TLS
2023-08-29 20:13:38 +00:00
$server = getDolGlobalString ( $keyforsmtpserver );
2019-11-13 17:32:11 +00:00
$secure = '' ;
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyfortls ) && function_exists ( 'openssl_open' )) {
2021-01-16 13:12:09 +00:00
$secure = 'ssl' ;
}
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforstarttls ) && function_exists ( 'openssl_open' )) {
2021-01-16 13:12:09 +00:00
$secure = 'tls' ;
}
2019-11-13 17:32:11 +00:00
$server = ( $secure ? $secure . '://' : '' ) . $server ;
2017-08-24 00:02:00 +00:00
2023-08-29 20:13:38 +00:00
$port = getDolGlobalInt ( $keyforsmtpport );
2017-04-17 23:39:06 +00:00
2009-11-01 14:16:30 +00:00
$this -> smtps -> setHost ( $server );
2017-04-11 08:57:17 +00:00
$this -> smtps -> setPort ( $port ); // 25, 465...;
2009-02-09 00:04:34 +00:00
2021-03-01 19:37:16 +00:00
$loginid = '' ;
$loginpass = '' ;
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforsmtpid )) {
2024-01-05 03:18:53 +00:00
$loginid = getDolGlobalString ( $keyforsmtpid );
2017-04-17 23:39:06 +00:00
$this -> smtps -> setID ( $loginid );
2017-04-11 08:57:17 +00:00
}
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforsmtppw )) {
2024-01-05 03:18:53 +00:00
$loginpass = getDolGlobalString ( $keyforsmtppw );
2017-04-17 23:39:06 +00:00
$this -> smtps -> setPW ( $loginpass );
2017-04-11 08:57:17 +00:00
}
2008-08-20 09:25:41 +00:00
2022-08-10 07:54:14 +00:00
if ( getDolGlobalString ( $keyforsmtpauthtype ) === " XOAUTH2 " ) {
2022-08-01 09:31:32 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/oauth.lib.php' ; // define $supportedoauth2array
2023-03-02 09:38:45 +00:00
2023-11-27 17:45:08 +00:00
$supportedoauth2array = getSupportedOauth2Array ();
$keyforsupportedoauth2array = getDolGlobalString ( $keyforsmtpoauthservice );
2022-08-01 09:31:32 +00:00
if ( preg_match ( '/^.*-/' , $keyforsupportedoauth2array )) {
$keyforprovider = preg_replace ( '/^.*-/' , '' , $keyforsupportedoauth2array );
} else {
$keyforprovider = '' ;
}
$keyforsupportedoauth2array = preg_replace ( '/-.*$/' , '' , $keyforsupportedoauth2array );
$keyforsupportedoauth2array = 'OAUTH_' . $keyforsupportedoauth2array . '_NAME' ;
2023-08-29 20:13:38 +00:00
if ( ! empty ( $supportedoauth2array )) {
2024-10-02 19:23:06 +00:00
$nameofservice = ucfirst ( strtolower ( empty ( $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) ? 'Unknown' : $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]));
$nameofservice .= ( $keyforprovider ? '-' . $keyforprovider : '' );
$OAUTH_SERVICENAME = $nameofservice ;
2022-09-10 11:58:19 +00:00
} else {
$OAUTH_SERVICENAME = 'Unknown' ;
}
2022-08-01 09:31:32 +00:00
2024-10-02 23:06:44 +00:00
$keyforparamtenant = 'OAUTH_' . strtoupper ( empty ( $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) ? 'Unknown' : $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) . ( $keyforprovider ? '-' . $keyforprovider : '' ) . '_TENANT' ;
2022-08-01 09:31:32 +00:00
require_once DOL_DOCUMENT_ROOT . '/includes/OAuth/bootstrap.php' ;
2024-10-02 23:06:44 +00:00
$storage = new DoliStorage ( $db , $conf , $keyforprovider , getDolGlobalString ( $keyforparamtenant ));
2022-08-01 09:31:32 +00:00
try {
2022-08-12 09:00:02 +00:00
$tokenobj = $storage -> retrieveAccessToken ( $OAUTH_SERVICENAME );
2024-08-01 09:55:49 +00:00
2022-08-12 09:42:23 +00:00
$expire = false ;
2022-08-12 09:00:02 +00:00
// Is token expired or will token expire in the next 30 seconds
if ( is_object ( $tokenobj )) {
$expire = ( $tokenobj -> getEndOfLife () !== - 9002 && $tokenobj -> getEndOfLife () !== - 9001 && time () > ( $tokenobj -> getEndOfLife () - 30 ));
}
// Token expired so we refresh it
if ( is_object ( $tokenobj ) && $expire ) {
$credentials = new Credentials (
2024-08-01 09:35:42 +00:00
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_ID' ),
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_SECRET' ),
2024-08-13 16:36:33 +00:00
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_URLCALLBACK' )
2022-08-12 09:00:02 +00:00
);
$serviceFactory = new \OAuth\ServiceFactory ();
2026-06-08 23:18:41 +00:00
$httpClient = new \OAuth\Common\Http\Client\CurlClient ();
$serviceFactory -> setHttpClient ( $httpClient );
2022-08-12 09:00:02 +00:00
$oauthname = explode ( '-' , $OAUTH_SERVICENAME );
2026-01-24 19:13:06 +00:00
// Recreate the service with its configured scopes.
// This matters for some providers (Microsoft v2 token endpoint) where scope may be required on refresh.
$oauthScopes = array ();
$oauthScopesStr = getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_SCOPE' );
if ( ! empty ( $oauthScopesStr )) {
$oauthScopes = preg_split ( '/\s*,\s*/' , $oauthScopesStr );
if ( ! is_array ( $oauthScopes )) {
$oauthScopes = array ();
}
}
2022-08-12 09:00:02 +00:00
// ex service is Google-Emails we need only the first part Google
2026-01-24 19:13:06 +00:00
$apiService = $serviceFactory -> createService ( $oauthname [ 0 ], $credentials , $storage , $oauthScopes );
2024-08-01 15:05:29 +00:00
2026-01-24 19:13:06 +00:00
// Some providers (like Google) return a refresh token only once.
// If the refreshed token does not contain one, keep the previous refresh token.
2022-08-12 09:00:02 +00:00
$refreshtoken = $tokenobj -> getRefreshToken ();
2024-08-01 12:02:36 +00:00
if ( $apiService instanceof OAuth\OAuth2\Service\AbstractService || $apiService instanceof OAuth\OAuth1\Service\AbstractService ) {
2024-08-19 00:05:27 +00:00
// ServiceInterface does not provide refreshAccessToken, AbstractService does
2024-08-01 09:09:26 +00:00
$tokenobj = $apiService -> refreshAccessToken ( $tokenobj );
2026-01-24 19:13:06 +00:00
if ( empty ( $tokenobj -> getRefreshToken ())) {
$tokenobj -> setRefreshToken ( $refreshtoken );
}
2024-08-01 09:09:26 +00:00
$storage -> storeAccessToken ( $OAUTH_SERVICENAME , $tokenobj );
}
2024-08-01 09:55:49 +00:00
$tokenobj = $storage -> retrieveAccessToken ( $OAUTH_SERVICENAME );
2022-08-12 09:00:02 +00:00
}
2022-08-01 09:31:32 +00:00
if ( is_object ( $tokenobj )) {
$this -> smtps -> setToken ( $tokenobj -> getAccessToken ());
} else {
$this -> error = " Token not found " ;
}
} catch ( Exception $e ) {
// Return an error if token not found
$this -> error = $e -> getMessage ();
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
}
}
2019-11-13 17:32:11 +00:00
$res = true ;
$from = $this -> smtps -> getFrom ( 'org' );
2021-01-16 13:12:09 +00:00
if ( $res && ! $from ) {
2023-10-15 13:32:35 +00:00
$this -> error = " Failed to send mail with smtps lib to HOST= " . $server . " , PORT= " . getDolGlobalString ( $keyforsmtpport ) . " - Sender address ' $from ' invalid " ;
2011-01-14 01:11:02 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2011-01-14 01:11:02 +00:00
}
2019-11-13 17:32:11 +00:00
$dest = $this -> smtps -> getTo ();
2021-01-16 13:12:09 +00:00
if ( $res && ! $dest ) {
2023-10-15 13:32:35 +00:00
$this -> error = " Failed to send mail with smtps lib to HOST= " . $server . " , PORT= " . getDolGlobalString ( $keyforsmtpport ) . " - Recipient address ' $dest ' invalid " ;
2009-05-24 21:30:37 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2007-06-07 21:24:01 +00:00
}
2011-07-02 16:48:31 +00:00
2021-01-16 13:12:09 +00:00
if ( $res ) {
2024-09-23 11:54:48 +00:00
dol_syslog ( " CMailFile::sendfile: sendMsg, HOST= " . $server . " , PORT= " . getDolGlobalString ( $keyforsmtpport ), LOG_NOTICE );
2023-02-16 01:59:29 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2021-01-16 13:12:09 +00:00
$this -> smtps -> setDebug ( true );
}
2017-08-24 00:02:00 +00:00
2019-11-13 17:32:11 +00:00
$result = $this -> smtps -> sendMsg ();
2009-02-09 00:04:34 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2025-04-22 14:57:49 +00:00
$this -> dump_mail (); // Create file dolibarr_mail.log or dolibarr_mail.log.vXXX if option for archive is on
2021-01-16 13:12:09 +00:00
}
2009-02-09 00:04:34 +00:00
2023-05-31 11:14:03 +00:00
$smtperrorcode = 0 ;
2023-03-24 12:27:04 +00:00
if ( ! $result ) {
$smtperrorcode = $this -> smtps -> lastretval ; // SMTP error code
dol_syslog ( " CMailFile::sendfile: mail SMTP error code " . $smtperrorcode , LOG_WARNING );
if ( $smtperrorcode == '421' ) { // Try later
// TODO Add a delay and try again
/*
dol_syslog ( " CMailFile::sendfile: Try later error, so we wait and we retry " );
sleep ( 2 );
$result = $this -> smtps -> sendMsg ();
2025-01-05 17:34:01 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2023-03-24 12:27:04 +00:00
$this -> dump_mail ();
}
*/
}
2025-04-22 14:57:49 +00:00
} else {
dol_syslog ( " CMailFile::sendfile: mail SMTP sendMsg is success " , LOG_DEBUG );
2023-03-24 12:27:04 +00:00
}
$result = $this -> smtps -> getErrors (); // applicative error code (not SMTP error code)
2025-04-22 14:57:49 +00:00
2021-01-16 13:12:09 +00:00
if ( empty ( $this -> error ) && empty ( $result )) {
2018-10-29 02:25:21 +00:00
dol_syslog ( " CMailFile::sendfile: mail end success " , LOG_DEBUG );
2024-05-30 11:37:17 +00:00
$res = true ;
2020-05-21 13:05:19 +00:00
} else {
2021-01-16 13:12:09 +00:00
if ( empty ( $this -> error )) {
$this -> error = $result ;
}
2023-10-15 13:32:35 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error with smtps lib to HOST= " . $server . " , PORT= " . getDolGlobalString ( $keyforsmtpport ) . " - " . $this -> error , LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2023-03-02 09:38:45 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2025-06-08 11:23:46 +00:00
$this -> save_dump_mail_in_err ( 'Mail smtp error ' . $smtperrorcode . ' with topic ' . $this -> subject . ' - ' . $this -> error );
2023-03-02 09:38:45 +00:00
}
2010-05-12 13:14:26 +00:00
}
2010-04-13 20:58:36 +00:00
}
2021-01-16 13:12:09 +00:00
} elseif ( $this -> sendmode == 'swiftmailer' ) {
2020-09-07 08:18:17 +00:00
// Use Swift Mailer library
// ------------------------------------------
require_once DOL_DOCUMENT_ROOT . '/includes/swiftmailer/lib/swift_required.php' ;
2017-04-17 23:39:06 +00:00
2017-08-24 00:02:00 +00:00
// Clean parameters
2021-01-16 13:12:09 +00:00
if ( empty ( $conf -> global -> $keyforsmtpserver )) {
$conf -> global -> $keyforsmtpserver = ini_get ( 'SMTP' );
}
if ( empty ( $conf -> global -> $keyforsmtpport )) {
$conf -> global -> $keyforsmtpport = ini_get ( 'smtp_port' );
}
2017-04-17 23:39:06 +00:00
// If we use SSL/TLS
2023-12-23 19:00:57 +00:00
$server = getDolGlobalString ( $keyforsmtpserver );
2018-01-21 14:55:56 +00:00
$secure = '' ;
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyfortls ) && function_exists ( 'openssl_open' )) {
2021-01-16 13:12:09 +00:00
$secure = 'ssl' ;
}
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforstarttls ) && function_exists ( 'openssl_open' )) {
2021-01-16 13:12:09 +00:00
$secure = 'tls' ;
}
2017-04-17 23:39:06 +00:00
2024-08-01 08:52:53 +00:00
$this -> transport = new Swift_SmtpTransport ( $server , getDolGlobalInt ( $keyforsmtpport ), $secure );
2017-04-17 23:39:06 +00:00
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforsmtpid )) {
2024-10-02 19:23:06 +00:00
$this -> transport -> setUsername ( getDolGlobalString ( $keyforsmtpid ));
2021-01-16 13:12:09 +00:00
}
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyforsmtppw ) && getDolGlobalString ( $keyforsmtpauthtype ) != " XOAUTH2 " ) {
2024-10-02 19:23:06 +00:00
$this -> transport -> setPassword ( getDolGlobalString ( $keyforsmtppw ));
2021-01-16 13:12:09 +00:00
}
2022-08-10 07:54:14 +00:00
if ( getDolGlobalString ( $keyforsmtpauthtype ) === " XOAUTH2 " ) {
2026-02-24 16:48:29 +00:00
$this -> transport -> setAuthMode ( 'XOAUTH2' );
2023-11-27 17:45:08 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/oauth.lib.php' ;
$supportedoauth2array = getSupportedOauth2Array ();
2023-03-02 09:38:45 +00:00
2022-08-10 07:54:14 +00:00
$keyforsupportedoauth2array = getDolGlobalString ( $keyforsmtpoauthservice );
if ( preg_match ( '/^.*-/' , $keyforsupportedoauth2array )) {
$keyforprovider = preg_replace ( '/^.*-/' , '' , $keyforsupportedoauth2array );
} else {
$keyforprovider = '' ;
}
$keyforsupportedoauth2array = preg_replace ( '/-.*$/' , '' , $keyforsupportedoauth2array );
$keyforsupportedoauth2array = 'OAUTH_' . $keyforsupportedoauth2array . '_NAME' ;
2024-10-02 19:23:06 +00:00
if ( ! empty ( $supportedoauth2array )) {
$nameofservice = ucfirst ( strtolower ( empty ( $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) ? 'Unknown' : $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]));
$nameofservice .= ( $keyforprovider ? '-' . $keyforprovider : '' );
$OAUTH_SERVICENAME = $nameofservice ;
} else {
$OAUTH_SERVICENAME = 'Unknown' ;
2023-11-22 08:27:12 +00:00
}
2022-08-10 07:54:14 +00:00
2024-10-02 23:06:44 +00:00
$keyforparamtenant = 'OAUTH_' . strtoupper ( empty ( $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) ? 'Unknown' : $supportedoauth2array [ $keyforsupportedoauth2array ][ 'callbackfile' ]) . ( $keyforprovider ? '-' . $keyforprovider : '' ) . '_TENANT' ;
2022-08-10 07:54:14 +00:00
require_once DOL_DOCUMENT_ROOT . '/includes/OAuth/bootstrap.php' ;
2024-10-02 23:06:44 +00:00
$storage = new DoliStorage ( $db , $conf , $keyforprovider , getDolGlobalString ( $keyforparamtenant ));
2022-08-11 08:03:44 +00:00
2022-08-10 07:54:14 +00:00
try {
2022-08-11 08:16:20 +00:00
$tokenobj = $storage -> retrieveAccessToken ( $OAUTH_SERVICENAME );
2024-08-01 09:55:49 +00:00
2022-08-11 08:03:44 +00:00
$expire = false ;
// Is token expired or will token expire in the next 30 seconds
if ( is_object ( $tokenobj )) {
$expire = ( $tokenobj -> getEndOfLife () !== - 9002 && $tokenobj -> getEndOfLife () !== - 9001 && time () > ( $tokenobj -> getEndOfLife () - 30 ));
}
// Token expired so we refresh it
2022-08-11 08:16:20 +00:00
if ( is_object ( $tokenobj ) && $expire ) {
$credentials = new Credentials (
2024-08-01 09:35:42 +00:00
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_ID' ),
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_SECRET' ),
2024-08-13 16:36:33 +00:00
getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_URLCALLBACK' )
2022-08-11 08:16:20 +00:00
);
$serviceFactory = new \OAuth\ServiceFactory ();
2026-06-08 23:18:41 +00:00
$httpClient = new \OAuth\Common\Http\Client\CurlClient ();
$serviceFactory -> setHttpClient ( $httpClient );
2022-08-11 08:16:20 +00:00
$oauthname = explode ( '-' , $OAUTH_SERVICENAME );
2026-01-24 19:13:06 +00:00
// Recreate the service with its configured scopes.
// This matters for some providers (Microsoft v2 token endpoint) where scope may be required on refresh.
$oauthScopes = array ();
$oauthScopesStr = getDolGlobalString ( 'OAUTH_' . getDolGlobalString ( $keyforsmtpoauthservice ) . '_SCOPE' );
if ( ! empty ( $oauthScopesStr )) {
$oauthScopes = preg_split ( '/\s*,\s*/' , $oauthScopesStr );
if ( ! is_array ( $oauthScopes )) {
$oauthScopes = array ();
}
}
2022-08-11 08:16:20 +00:00
// ex service is Google-Emails we need only the first part Google
2026-01-24 19:13:06 +00:00
$apiService = $serviceFactory -> createService ( $oauthname [ 0 ], $credentials , $storage , $oauthScopes );
2022-08-11 08:16:20 +00:00
$refreshtoken = $tokenobj -> getRefreshToken ();
2024-08-01 09:55:49 +00:00
2024-08-01 12:02:36 +00:00
if ( $apiService instanceof OAuth\OAuth2\Service\AbstractService || $apiService instanceof OAuth\OAuth1\Service\AbstractService ) {
2024-08-19 00:05:27 +00:00
// ServiceInterface does not provide refreshAccessToken, AbstractService does
2024-08-01 09:09:26 +00:00
$tokenobj = $apiService -> refreshAccessToken ( $tokenobj );
2026-01-24 19:13:06 +00:00
if ( empty ( $tokenobj -> getRefreshToken ())) {
$tokenobj -> setRefreshToken ( $refreshtoken );
}
2024-08-01 09:09:26 +00:00
$storage -> storeAccessToken ( $OAUTH_SERVICENAME , $tokenobj );
2024-08-01 12:02:36 +00:00
$tokenobj = $storage -> retrieveAccessToken ( $OAUTH_SERVICENAME );
2024-08-01 09:09:26 +00:00
}
2022-08-11 08:03:44 +00:00
}
2024-08-01 09:55:49 +00:00
2022-08-10 07:54:14 +00:00
if ( is_object ( $tokenobj )) {
$this -> transport -> setAuthMode ( 'XOAUTH2' );
$this -> transport -> setPassword ( $tokenobj -> getAccessToken ());
} else {
$this -> errors [] = " Token not found " ;
2026-02-24 16:48:29 +00:00
dol_syslog ( " CMailFile::sendfile: OAuth2 token object is not valid " , LOG_ERR );
2022-08-10 07:54:14 +00:00
}
} catch ( Exception $e ) {
// Return an error if token not found
$this -> errors [] = $e -> getMessage ();
2022-08-10 14:29:37 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . $e -> getMessage (), LOG_ERR );
2022-08-10 07:54:14 +00:00
}
}
2023-12-26 20:59:08 +00:00
if ( getDolGlobalString ( $keyforsslseflsigned )) {
2021-01-16 13:12:09 +00:00
$this -> transport -> setStreamOptions ( array ( 'ssl' => array ( 'allow_self_signed' => true , 'verify_peer' => false )));
}
2017-04-17 23:39:06 +00:00
//$smtps->_msgReplyTo = 'reply@web.com';
2020-04-08 14:03:41 +00:00
// Switch content encoding to base64 - avoid the doubledot issue with quoted-printable
2020-09-07 08:18:17 +00:00
$contentEncoderBase64 = new Swift_Mime_ContentEncoder_Base64ContentEncoder ();
$this -> message -> setEncoder ( $contentEncoderBase64 );
2020-04-08 14:09:04 +00:00
2017-04-17 23:39:06 +00:00
// Create the Mailer using your created Transport
2018-01-21 14:55:56 +00:00
$this -> mailer = new Swift_Mailer ( $this -> transport );
2017-04-17 23:39:06 +00:00
2020-09-07 08:18:17 +00:00
// DKIM SIGN
2023-12-26 20:59:08 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_EMAIL_DKIM_ENABLED' )) {
2024-01-05 03:18:53 +00:00
$privateKey = getDolGlobalString ( 'MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY' );
$domainName = getDolGlobalString ( 'MAIN_MAIL_EMAIL_DKIM_DOMAIN' );
$selector = getDolGlobalString ( 'MAIN_MAIL_EMAIL_DKIM_SELECTOR' );
2020-09-07 08:18:17 +00:00
$signer = new Swift_Signers_DKIMSigner ( $privateKey , $domainName , $selector );
$this -> message -> attachSigner ( $signer -> ignoreHeader ( 'Return-Path' ));
}
2018-01-25 21:03:51 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2017-04-17 23:39:06 +00:00
// To use the ArrayLogger
$this -> logger = new Swift_Plugins_Loggers_ArrayLogger ();
// Or to use the Echo Logger
//$this->logger = new Swift_Plugins_Loggers_EchoLogger();
$this -> mailer -> registerPlugin ( new Swift_Plugins_LoggerPlugin ( $this -> logger ));
}
2023-02-16 01:59:29 +00:00
2024-09-23 11:54:48 +00:00
dol_syslog ( " CMailFile::sendfile: mailer->send, HOST= " . $server . " , PORT= " . getDolGlobalString ( $keyforsmtpport ), LOG_NOTICE );
2023-02-16 01:59:29 +00:00
2017-04-17 23:39:06 +00:00
// send mail
2023-02-16 01:59:29 +00:00
$failedRecipients = array ();
FIX: Resolve possibly-undefined-variable cases flagged by PHPStan (#39523)
* FIX: Resolve possibly-undefined-variable cases flagged by PHPStan
Fixes several cases of the variable.undefined PHPStan rule instead of
just excluding them via the baseline: a wrong variable used to build a
delete link (dir_add_card.php), an uninitialized $result across a
try/catch (CMailFile), missing GETPOST reads ($mode, $fk_project/$date
reset via unset() creating cross-branch ambiguity), a missing $r
contract check (commonfieldsinimport.inc.php), missing @var/global
annotations for $conf/$langs/$bc, dead extrafields-display code
guarded by the wrong condition (expedition/card.php), and an
undefined $soc passed to formAddObjectLine() where objects have no
buyer thirdparty (replaced with null). Corresponding entries removed
from dev/build/phpstan/phpstan-baseline.neon.
* FIX: Resolve more possibly-undefined-variable cases flagged by PHPStan
Second batch of variable.undefined fixes removed from the baseline:
- Complex conditional flows PHPStan can't prove exhaustive (Stripe key
selection in commoninvoice.class.php, a situation-invoice loop var in
pdf_sponge.modules.php, a product loop var in stock/movement_list.php)
fixed by adding a definite initialization before the ambiguous branch.
- A commented-out $linkback assignment restored in
expensereport/payment/info.php.
- Missing GETPOST reads added (holiday/list.php update-date filters,
product/stock/info.php $action/$socid, projet/comment.php $mode).
- A dead-code $mesg call to dol_htmloutput_mesg() removed from
admin_hrm.php (messages are already shown via setEventMessages()).
- Redundant isset() checks removed in product/reassort.php and
reassortlot.php where $type is unconditionally set earlier in the
same file, so the isset()-false branch was unreachable dead code.
- $user documented as always available in public/bookcal/index.php
(NOREQUIREUSER is not defined on that page).
- A genuinely missing $tmpcode initialization fixed in
attendee_new.php, suggestbooth.php and suggestconference.php: when
an existing thirdparty is reused (or SOCIETE_CODECLIENT_ADDON has no
auto-numbering), $tmpcode was never set before being assigned to
code_client/code_fournisseur.
* add phan fix
* add phan fix
* fix
* fix
* fix
2026-08-15 16:33:12 +00:00
$result = false ;
2017-04-17 23:39:06 +00:00
try {
2021-05-18 15:57:23 +00:00
$result = $this -> mailer -> send ( $this -> message , $failedRecipients );
2017-04-17 23:39:06 +00:00
} catch ( Exception $e ) {
2022-08-10 08:09:52 +00:00
$this -> errors [] = $e -> getMessage ();
2017-04-17 23:39:06 +00:00
}
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2021-01-16 13:12:09 +00:00
$this -> dump_mail ();
}
2017-04-17 23:39:06 +00:00
$res = true ;
2022-08-10 08:09:52 +00:00
if ( ! empty ( $this -> error ) || ! empty ( $this -> errors ) || ! $result ) {
2021-05-18 15:57:23 +00:00
if ( ! empty ( $failedRecipients )) {
2024-09-23 19:57:16 +00:00
$this -> error = 'Transport failed for the following addresses: "' . implode ( '", "' , $failedRecipients ) . '".' ;
2024-09-20 15:46:52 +00:00
$this -> errors [] = $this -> error ;
2021-05-18 15:57:23 +00:00
}
2024-09-25 20:17:40 +00:00
dol_syslog ( " CMailFile::sendfile: mail end error= " . implode ( ' ' , $this -> errors ), LOG_ERR );
2019-11-13 17:32:11 +00:00
$res = false ;
2023-03-02 09:38:45 +00:00
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG' )) {
2023-03-30 12:48:04 +00:00
$this -> save_dump_mail_in_err ( 'Mail with topic ' . $this -> subject );
2023-03-02 09:38:45 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2018-10-29 02:25:21 +00:00
dol_syslog ( " CMailFile::sendfile: mail end success " , LOG_DEBUG );
}
2020-05-21 13:05:19 +00:00
} else {
2009-02-09 00:04:34 +00:00
// Send mail method not correctly defined
// --------------------------------------
2024-03-12 14:13:54 +00:00
$this -> error = 'Bad value for sendmode' ;
2024-03-12 15:18:44 +00:00
return false ;
2007-06-06 15:38:33 +00:00
}
2007-11-28 22:53:21 +00:00
2023-02-23 17:29:58 +00:00
// Now we delete image files that were created dynamically to manage data inline files
2024-08-01 09:09:26 +00:00
/* Note : dol_delete call was disabled , so code commented to not trigger empty if body
2023-02-23 17:29:58 +00:00
foreach ( $this -> html_images as $val ) {
if ( ! empty ( $val [ 'type' ]) && $val [ 'type' ] == 'cidfromdata' ) {
//dol_delete($val['fullpath']);
}
}
2024-08-01 09:09:26 +00:00
*/
2023-02-23 17:29:58 +00:00
2022-12-20 16:38:01 +00:00
$parameters = array ( 'sent' => $res );
2021-03-01 19:37:16 +00:00
$action = '' ;
2018-02-03 16:32:38 +00:00
$reshook = $hookmanager -> executeHooks ( 'sendMailAfter' , $parameters , $this , $action ); // Note that $action and $object may have been modified by some hooks
2021-01-16 13:12:09 +00:00
if ( $reshook < 0 ) {
2019-11-13 17:32:11 +00:00
$this -> error = " Error in hook maildao sendMailAfter " . $reshook ;
dol_syslog ( " CMailFile::sendfile: mail end error= " . $this -> error , LOG_ERR );
2018-02-03 16:32:38 +00:00
2024-03-12 14:13:54 +00:00
return false ;
2018-02-03 16:32:38 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2019-11-13 17:32:11 +00:00
$this -> error = 'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS' ;
2010-07-14 23:12:49 +00:00
dol_syslog ( " CMailFile::sendfile: " . $this -> error , LOG_WARNING );
2006-04-01 01:10:38 +00:00
}
2005-06-25 13:02:39 +00:00
2026-01-21 11:29:49 +00:00
error_reporting ( $errorlevel ); // Reactive original error level
2007-06-07 21:24:01 +00:00
return $res ;
}
2005-06-25 13:02:39 +00:00
2015-04-06 10:25:30 +00:00
/**
2015-04-06 18:02:29 +00:00
* Encode subject according to RFC 2822 - http :// en . wikipedia . org / wiki / MIME #Encoded-Word
2015-05-05 02:10:42 +00:00
*
2015-04-06 18:02:29 +00:00
* @ param string $stringtoencode String to encode
* @ return string string encoded
2015-04-06 10:25:30 +00:00
*/
2019-02-25 21:27:04 +00:00
public static function encodetorfc2822 ( $stringtoencode )
2009-05-13 14:49:30 +00:00
{
global $conf ;
return '=?' . $conf -> file -> character_set_client . '?B?' . base64_encode ( $stringtoencode ) . '?=' ;
}
2009-02-09 00:04:34 +00:00
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2009-02-09 00:04:34 +00:00
/**
2011-07-20 11:07:12 +00:00
* Read a file on disk and return encoded content for emails ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2011-12-01 22:36:00 +00:00
* @ param string $sourcefile Path to file to encode
2024-08-14 17:21:10 +00:00
* @ return int <- 1 , - 1 >| string Return integer < 0 if KO , encoded string if OK
2009-02-09 00:04:34 +00:00
*/
2019-02-25 21:27:04 +00:00
private function _encode_file ( $sourcefile )
2009-02-09 00:04:34 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2019-11-13 17:32:11 +00:00
$newsourcefile = dol_osencode ( $sourcefile );
2009-10-14 16:13:20 +00:00
2021-01-04 23:11:19 +00:00
if ( is_readable ( $newsourcefile )) {
2019-11-13 17:32:11 +00:00
$contents = file_get_contents ( $newsourcefile ); // Need PHP 4.3
$encoded = chunk_split ( base64_encode ( $contents ), 76 , $this -> eol ); // 76 max is defined into http://tools.ietf.org/html/rfc2047
2009-02-09 00:04:34 +00:00
return $encoded ;
2020-05-21 13:05:19 +00:00
} else {
2023-05-13 14:39:42 +00:00
$this -> error = " Error in _encode_file() method: Can't read file ' " . $sourcefile . " ' " ;
dol_syslog ( " CMailFile::_encode_file: " . $this -> error , LOG_ERR );
2009-02-09 00:04:34 +00:00
return - 1 ;
}
}
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-11-15 00:52:42 +00:00
/**
2010-10-09 23:17:41 +00:00
* Write content of a SMTP request into a dump file ( mode = all )
* Used for debugging .
2013-03-13 18:14:49 +00:00
* Note that to see full SMTP protocol , you can use tcpdump - w / tmp / smtp - s 2000 port 25 "
2011-12-01 22:36:00 +00:00
*
* @ return void
2008-11-15 00:52:42 +00:00
*/
2019-02-25 21:27:04 +00:00
public function dump_mail ()
2008-11-15 00:52:42 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2024-01-19 13:05:42 +00:00
global $dolibarr_main_data_root ;
2009-02-09 00:04:34 +00:00
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 20:46:12 +00:00
if ( @ is_writable ( $dolibarr_main_data_root )) { // Avoid fatal error on fopen with open_basedir
2019-11-13 17:32:11 +00:00
$outputfile = $dolibarr_main_data_root . " /dolibarr_mail.log " ;
2023-03-02 09:38:45 +00:00
$fp = fopen ( $outputfile , " w " ); // overwrite
2009-02-09 00:04:34 +00:00
2025-02-16 21:45:14 +00:00
if ( $fp ) {
if ( $this -> sendmode == 'mail' ) {
fwrite ( $fp , $this -> headers );
fwrite ( $fp , $this -> eol ); // This eol is added by the mail function, so we add it in log
fwrite ( $fp , $this -> message );
} elseif ( $this -> sendmode == 'smtps' ) {
fwrite ( $fp , $this -> smtps -> log ); // this->smtps->log is filled only if MAIN_MAIL_DEBUG was set to on
} elseif ( $this -> sendmode == 'swiftmailer' ) {
fwrite ( $fp , " smtpheader= \n " . $this -> message -> getHeaders () -> toString () . " \n " );
fwrite ( $fp , $this -> logger -> dump ()); // this->logger is filled only if MAIN_MAIL_DEBUG was set to on
}
2009-02-09 00:04:34 +00:00
2025-02-16 21:45:14 +00:00
fclose ( $fp );
dolChmod ( $outputfile );
2023-10-09 07:13:27 +00:00
2025-02-16 21:45:14 +00:00
// Move dolibarr_mail.log into a dolibarr_mail.log.v123456789
if ( getDolGlobalInt ( 'MAIN_MAIL_DEBUG_LOG_WITH_DATE' )) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
archiveOrBackupFile ( $outputfile , getDolGlobalInt ( 'MAIN_MAIL_DEBUG_LOG_WITH_DATE' ));
}
2023-10-09 07:13:27 +00:00
}
2008-11-15 00:52:42 +00:00
}
}
2023-03-02 09:38:45 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Save content if mail is in error
* Used for debugging .
*
2023-03-30 12:48:04 +00:00
* @ param string $message Add also a message
2023-03-02 09:38:45 +00:00
* @ return void
*/
2023-03-30 12:48:04 +00:00
public function save_dump_mail_in_err ( $message = '' )
2023-03-02 09:38:45 +00:00
{
global $dolibarr_main_data_root ;
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 20:46:12 +00:00
if ( @ is_writable ( $dolibarr_main_data_root )) { // Avoid fatal error on fopen with open_basedir
2023-03-30 20:25:29 +00:00
$srcfile = $dolibarr_main_data_root . " /dolibarr_mail.log " ;
// Add message to dolibarr_mail.log. We do not use dol_syslog() on purpose,
// to be sure to write into dolibarr_mail.log
2023-03-30 12:48:04 +00:00
if ( $message ) {
2023-03-30 20:25:29 +00:00
// Test constant SYSLOG_FILE_NO_ERROR (should stay a constant defined with define('SYSLOG_FILE_NO_ERROR',1);
if ( defined ( 'SYSLOG_FILE_NO_ERROR' )) {
$filefd = @ fopen ( $srcfile , 'a+' );
} else {
$filefd = fopen ( $srcfile , 'a+' );
}
if ( $filefd ) {
fwrite ( $filefd , $message . " \n " );
fclose ( $filefd );
dolChmod ( $srcfile );
}
2023-03-30 12:48:04 +00:00
}
// Move dolibarr_mail.log into a dolibarr_mail.err or dolibarr_mail.date.err
2023-03-24 12:27:04 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_DEBUG_ERR_WITH_DATE' )) {
$destfile = $dolibarr_main_data_root . " /dolibarr_mail. " . dol_print_date ( dol_now (), 'dayhourlog' , 'gmt' ) . " .err " ;
} else {
$destfile = $dolibarr_main_data_root . " /dolibarr_mail.err " ;
}
2023-03-02 09:38:45 +00:00
2023-03-22 20:24:53 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2024-09-05 14:05:37 +00:00
dol_move ( $srcfile , $destfile , '0' , 1 , 0 , 0 );
2023-03-02 09:38:45 +00:00
}
}
2017-04-17 23:39:06 +00:00
/**
2024-01-13 18:48:20 +00:00
* Correct an incomplete html string
2017-04-17 23:39:06 +00:00
*
* @ param string $msg String
* @ return string Completed string
*/
2019-02-25 21:27:04 +00:00
public function checkIfHTML ( $msg )
2017-04-17 23:39:06 +00:00
{
2021-01-04 23:11:19 +00:00
if ( ! preg_match ( '/^[\s\t]*<html/i' , $msg )) {
2017-04-17 23:39:06 +00:00
$out = " <html><head><title></title> " ;
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> styleCSS )) {
$out .= $this -> styleCSS ;
}
2019-11-13 17:32:11 +00:00
$out .= " </head><body " ;
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> bodyCSS )) {
$out .= $this -> bodyCSS ;
}
2019-11-13 17:32:11 +00:00
$out .= " > " ;
$out .= $msg ;
$out .= " </body></html> " ;
2020-05-21 13:05:19 +00:00
} else {
2017-04-17 23:39:06 +00:00
$out = $msg ;
}
return $out ;
}
/**
* Build a css style ( mode = all ) into this -> styleCSS and this -> bodyCSS
*
2023-04-30 01:10:20 +00:00
* @ return void
2017-04-17 23:39:06 +00:00
*/
2019-02-25 21:27:04 +00:00
public function buildCSS ()
2017-04-17 23:39:06 +00:00
{
2021-01-04 23:11:19 +00:00
if ( ! empty ( $this -> css )) {
2017-04-17 23:39:06 +00:00
// Style CSS
$this -> styleCSS = '<style type="text/css">' ;
2019-11-13 17:32:11 +00:00
$this -> styleCSS .= 'body {' ;
2017-04-17 23:39:06 +00:00
2021-01-04 23:11:19 +00:00
if ( $this -> css [ 'bgcolor' ]) {
2019-11-13 17:32:11 +00:00
$this -> styleCSS .= ' background-color: ' . $this -> css [ 'bgcolor' ] . ';' ;
$this -> bodyCSS .= ' bgcolor="' . $this -> css [ 'bgcolor' ] . '"' ;
2017-04-17 23:39:06 +00:00
}
2021-01-04 23:11:19 +00:00
if ( $this -> css [ 'bgimage' ]) {
2017-04-17 23:39:06 +00:00
// TODO recuperer cid
2019-11-13 17:32:11 +00:00
$this -> styleCSS .= ' background-image: url("cid:' . $this -> css [ 'bgimage_cid' ] . '");' ;
2017-04-17 23:39:06 +00:00
}
2019-11-13 17:32:11 +00:00
$this -> styleCSS .= '}' ;
$this -> styleCSS .= '</style>' ;
2017-04-17 23:39:06 +00:00
}
}
2010-10-09 23:17:41 +00:00
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-11-15 00:52:42 +00:00
/**
2010-10-09 23:17:41 +00:00
* Create SMTP headers ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2015-04-06 10:25:30 +00:00
* @ return string headers
2008-11-15 00:52:42 +00:00
*/
2019-02-25 21:27:04 +00:00
public function write_smtpheaders ()
2008-11-15 00:52:42 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2007-05-25 20:02:23 +00:00
$out = " " ;
2016-12-15 11:11:39 +00:00
$host = dol_getprefix ( 'email' );
2012-02-01 21:39:17 +00:00
2006-08-06 18:34:37 +00:00
// Sender
2012-02-10 12:28:53 +00:00
//$out.= "Sender: ".getValidAddress($this->addr_from,2)).$this->eol2;
2019-11-13 17:32:11 +00:00
$out .= " From: " . $this -> getValidAddress ( $this -> addr_from , 3 , 1 ) . $this -> eol2 ;
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_SENDMAIL_FORCE_BA' )) {
2019-11-13 17:32:11 +00:00
$out .= " To: " . $this -> getValidAddress ( $this -> addr_to , 0 , 1 ) . $this -> eol2 ;
2012-11-13 16:25:47 +00:00
}
2024-11-08 16:11:02 +00:00
if ( ! getDolGlobalString ( 'MAIN_MAIL_NO_RETURN_PATH_FOR_MODE_MAIL' )) {
// Return-Path is important because it is used by SPF. Some command line MTA overwrites the Return-Path, even if already in the
// SMTP header, with a value guessed by command line tool. See option MAIN_MAIL_ALLOW_SENDMAIL_F to provide email to the command line tool.
// Return-Path is used for bounced emails. If not set (most cases), the From is used.
$out .= " Return-Path: " . $this -> getValidAddress ( $this -> addr_from , 1 , 1 ) . $this -> eol2 ;
}
2021-01-16 13:12:09 +00:00
if ( isset ( $this -> reply_to ) && $this -> reply_to ) {
$out .= " Reply-To: " . $this -> getValidAddress ( $this -> reply_to , 2 ) . $this -> eol2 ;
}
if ( isset ( $this -> errors_to ) && $this -> errors_to ) {
$out .= " Errors-To: " . $this -> getValidAddress ( $this -> errors_to , 2 ) . $this -> eol2 ;
}
2006-08-06 18:34:37 +00:00
// Receiver
2021-01-16 13:12:09 +00:00
if ( isset ( $this -> addr_cc ) && $this -> addr_cc ) {
$out .= " Cc: " . $this -> getValidAddress ( $this -> addr_cc , 2 ) . $this -> eol2 ;
}
if ( isset ( $this -> addr_bcc ) && $this -> addr_bcc ) {
$out .= " Bcc: " . $this -> getValidAddress ( $this -> addr_bcc , 2 ) . $this -> eol2 ; // TODO Question: bcc must not be into header, only into SMTP command "RCPT TO". Does php mail support this ?
}
2008-11-15 00:52:42 +00:00
2012-02-04 12:39:21 +00:00
// Delivery receipt
2021-01-16 13:12:09 +00:00
if ( isset ( $this -> deliveryreceipt ) && $this -> deliveryreceipt == 1 ) {
$out .= " Disposition-Notification-To: " . $this -> getValidAddress ( $this -> addr_from , 2 ) . $this -> eol2 ;
}
2008-11-15 00:52:42 +00:00
2012-02-08 11:55:25 +00:00
//$out.= "X-Priority: 3".$this->eol2;
2019-11-13 17:32:11 +00:00
$out .= 'Date: ' . date ( " r " ) . $this -> eol2 ;
2015-05-05 02:10:42 +00:00
$trackid = $this -> trackid ;
2021-01-16 13:12:09 +00:00
if ( $trackid ) {
2025-07-17 23:33:24 +00:00
$this -> msgid = uniqid ( '' , true ) . '.phpmail-dolibarr-' . $trackid . '@' . $host ;
2019-11-14 09:01:05 +00:00
$out .= 'Message-ID: <' . $this -> msgid . " > " . $this -> eol2 ; // Uppercase seems replaced by phpmail
2019-11-13 17:32:11 +00:00
$out .= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host . $this -> eol2 ;
2020-05-21 13:05:19 +00:00
} else {
2025-07-17 23:33:24 +00:00
$this -> msgid = uniqid ( '' , true ) . '.phpmail@' . $host ;
2019-11-14 09:01:05 +00:00
$out .= 'Message-ID: <' . $this -> msgid . " > " . $this -> eol2 ;
2015-05-05 02:10:42 +00:00
}
2012-02-01 21:39:17 +00:00
2024-04-01 17:11:08 +00:00
// Add 'In-Reply-To:' header with the Message-Id we answer
if ( ! empty ( $this -> in_reply_to )) {
$out .= 'In-Reply-To: <' . $this -> in_reply_to . '>' . $this -> eol2 ;
}
// Add 'References:' header with list of all Message-ID in thread history
if ( ! empty ( $this -> references )) {
$out .= 'References: ' . $this -> references . $this -> eol2 ;
}
2021-01-16 13:12:09 +00:00
if ( ! empty ( $_SERVER [ 'REMOTE_ADDR' ])) {
$out .= " X-RemoteAddr: " . $_SERVER [ 'REMOTE_ADDR' ] . $this -> eol2 ;
}
2019-11-13 17:32:11 +00:00
$out .= " X-Mailer: Dolibarr version " . DOL_VERSION . " (using php mail) " . $this -> eol2 ;
$out .= " Mime-Version: 1.0 " . $this -> eol2 ;
2006-08-06 18:34:37 +00:00
2012-02-05 00:11:20 +00:00
//$out.= "From: ".$this->getValidAddress($this->addr_from,3,1).$this->eol;
2012-02-04 12:39:21 +00:00
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: multipart/mixed; " . $this -> eol2 . " boundary= \" " . $this -> mixed_boundary . " \" " . $this -> eol2 ;
2025-08-13 17:51:27 +00:00
if ( ! getDolGlobalString ( " MAIN_EMAIL_DISABLE_ADD_CONTENT_ENCODING_8BIT " )) {
$out .= " Content-Transfer-Encoding: 8bit " . $this -> eol2 ; // TODO Seems to be ignored. Header is 7bit once received.
}
2017-04-17 23:39:06 +00:00
2024-09-23 11:54:48 +00:00
dol_syslog ( " CMailFile::write_smtpheaders smtp_header= \n " . $out , LOG_DEBUG );
2008-11-15 00:52:42 +00:00
return $out ;
}
2006-08-06 18:34:37 +00:00
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-11-15 00:52:42 +00:00
/**
2011-07-20 11:07:12 +00:00
* Create header MIME ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2025-03-15 15:34:35 +00:00
* @ param ? string [] $filename_list Array of filenames
* @ param ? string [] $mimefilename_list Array of mime types
2015-04-06 10:25:30 +00:00
* @ return string mime headers
2008-11-15 00:52:42 +00:00
*/
2019-02-25 21:27:04 +00:00
public function write_mimeheaders ( $filename_list , $mimefilename_list )
2008-11-15 00:52:42 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2008-11-15 00:52:42 +00:00
$out = " " ;
2009-05-13 14:49:30 +00:00
2025-03-15 15:34:35 +00:00
if ( is_array ( $filename_list ) && is_array ( $mimefilename_list )) {
2019-11-13 17:32:11 +00:00
$filename_list_size = count ( $filename_list );
2021-01-16 13:12:09 +00:00
for ( $i = 0 ; $i < $filename_list_size ; $i ++ ) {
if ( $filename_list [ $i ]) {
if ( $mimefilename_list [ $i ]) {
$filename_list [ $i ] = $mimefilename_list [ $i ];
}
2019-11-13 17:32:11 +00:00
$out .= " X-attachments: $filename_list[$i] " . $this -> eol2 ;
2006-08-06 18:34:37 +00:00
}
2008-11-15 00:52:42 +00:00
}
}
2009-05-13 14:49:30 +00:00
2009-02-20 22:53:15 +00:00
dol_syslog ( " CMailFile::write_mimeheaders mime_header= \n " . $out , LOG_DEBUG );
2008-11-15 00:52:42 +00:00
return $out ;
}
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-11-15 00:52:42 +00:00
/**
2011-07-20 11:07:12 +00:00
* Return email content ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2011-12-07 16:28:11 +00:00
* @ param string $msgtext Message string
* @ return string String content
2008-11-15 00:52:42 +00:00
*/
2019-02-25 21:27:04 +00:00
public function write_body ( $msgtext )
2008-11-15 00:52:42 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2008-11-15 00:52:42 +00:00
global $conf ;
2019-11-13 17:32:11 +00:00
$out = '' ;
2011-07-02 16:48:31 +00:00
2019-11-13 17:32:11 +00:00
$out .= " -- " . $this -> mixed_boundary . $this -> eol ;
2012-06-17 16:40:45 +00:00
2021-01-16 13:12:09 +00:00
if ( $this -> atleastoneimage ) {
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: multipart/alternative; " . $this -> eol . " boundary= \" " . $this -> alternative_boundary . " \" " . $this -> eol ;
$out .= $this -> eol ;
$out .= " -- " . $this -> alternative_boundary . $this -> eol ;
2009-05-13 14:49:30 +00:00
}
2011-07-02 16:48:31 +00:00
2009-05-13 19:10:06 +00:00
// Make RFC821 Compliant, replace bare linefeeds
2019-11-13 17:32:11 +00:00
$strContent = preg_replace ( " /(?<! \r ) \n /si " , " \r \n " , $msgtext ); // PCRE modifier /s means new lines are common chars
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_FIX_FOR_BUGGED_MTA' )) {
2019-11-13 17:32:11 +00:00
$strContent = preg_replace ( " / \r \n /si " , " \n " , $strContent ); // PCRE modifier /s means new lines are common chars
2012-11-13 16:25:47 +00:00
}
2013-03-13 18:14:49 +00:00
2017-04-04 23:01:43 +00:00
$strContentAltText = '' ;
2021-01-16 13:12:09 +00:00
if ( $this -> msgishtml ) {
2019-11-05 23:27:36 +00:00
// Similar code to forge a text from html is also in smtps.class.php
2019-11-05 23:51:26 +00:00
$strContentAltText = preg_replace ( " /<br \ s*[^>]*>/ " , " " , $strContent );
2022-10-23 15:14:23 +00:00
// TODO We could replace <img ...> with [Filename.ext] like Gmail do.
$strContentAltText = html_entity_decode ( strip_tags ( $strContentAltText )); // Remove any HTML tags
2023-11-27 10:24:19 +00:00
$strContentAltText = trim ( wordwrap ( $strContentAltText , 75 , ! getDolGlobalString ( 'MAIN_FIX_FOR_BUGGED_MTA' ) ? " \r \n " : " \n " ));
2017-04-17 23:39:06 +00:00
// Check if html header already in message, if not complete the message
2024-03-19 09:31:39 +00:00
$strContent = $this -> checkIfHTML ( $strContent ); // This add a header and a body including custom CSS to the HTML content
2017-04-04 23:01:43 +00:00
}
2016-12-19 00:04:17 +00:00
// Make RFC2045 Compliant, split lines
2017-04-17 23:39:06 +00:00
//$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
2017-10-16 12:31:28 +00:00
// TODO Encode main content into base64 and use the chunk_split, or quoted-printable
2023-11-27 10:24:19 +00:00
$strContent = rtrim ( wordwrap ( $strContent , 75 , ! getDolGlobalString ( 'MAIN_FIX_FOR_BUGGED_MTA' ) ? " \r \n " : " \n " )); // TODO Using this method creates unexpected line break on text/plain content.
2009-05-13 19:10:06 +00:00
2021-01-16 13:12:09 +00:00
if ( $this -> msgishtml ) {
if ( $this -> atleastoneimage ) {
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: text/plain; charset= " . $conf -> file -> character_set_client . $this -> eol ;
2017-10-16 12:31:28 +00:00
//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
2019-11-13 17:32:11 +00:00
$out .= $this -> eol . ( $strContentAltText ? $strContentAltText : strip_tags ( $strContent )) . $this -> eol ; // Add plain text message
$out .= " -- " . $this -> alternative_boundary . $this -> eol ;
$out .= " Content-Type: multipart/related; " . $this -> eol . " boundary= \" " . $this -> related_boundary . " \" " . $this -> eol ;
$out .= $this -> eol ;
$out .= " -- " . $this -> related_boundary . $this -> eol ;
2011-06-20 21:18:06 +00:00
}
2017-08-24 00:02:00 +00:00
2023-11-27 10:24:19 +00:00
if ( ! $this -> atleastoneimage && $strContentAltText && getDolGlobalString ( 'MAIN_MAIL_USE_MULTI_PART' )) { // Add plain text message part before html part
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: multipart/alternative; " . $this -> eol . " boundary= \" " . $this -> alternative_boundary . " \" " . $this -> eol ;
$out .= $this -> eol ;
$out .= " -- " . $this -> alternative_boundary . $this -> eol ;
$out .= " Content-Type: text/plain; charset= " . $conf -> file -> character_set_client . $this -> eol ;
2017-10-16 12:31:28 +00:00
//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
2019-11-13 17:32:11 +00:00
$out .= $this -> eol . $strContentAltText . $this -> eol ;
$out .= " -- " . $this -> alternative_boundary . $this -> eol ;
2017-04-04 23:01:43 +00:00
}
2017-08-24 00:02:00 +00:00
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: text/html; charset= " . $conf -> file -> character_set_client . $this -> eol ;
2017-10-16 12:31:28 +00:00
//$out.= "Content-Transfer-Encoding: 7bit".$this->eol; // TODO Use base64
2019-11-13 17:32:11 +00:00
$out .= $this -> eol . $strContent . $this -> eol ;
2017-04-17 23:39:06 +00:00
2023-11-27 10:24:19 +00:00
if ( ! $this -> atleastoneimage && $strContentAltText && getDolGlobalString ( 'MAIN_MAIL_USE_MULTI_PART' )) { // Add plain text message part after html part
2019-11-13 17:32:11 +00:00
$out .= " -- " . $this -> alternative_boundary . " -- " . $this -> eol ;
2017-04-04 23:01:43 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2019-11-13 17:32:11 +00:00
$out .= " Content-Type: text/plain; charset= " . $conf -> file -> character_set_client . $this -> eol ;
2017-10-16 12:31:28 +00:00
//$out.= "Content-Transfer-Encoding: 7bit".$this->eol;
2019-11-13 17:32:11 +00:00
$out .= $this -> eol . $strContent . $this -> eol ;
2011-06-20 21:18:06 +00:00
}
2011-07-02 16:48:31 +00:00
2019-11-13 17:32:11 +00:00
$out .= $this -> eol ;
2009-05-13 19:10:06 +00:00
2017-04-04 23:01:43 +00:00
// Encode images
2021-01-16 13:12:09 +00:00
if ( $this -> atleastoneimage ) {
2017-04-17 23:39:06 +00:00
$out .= $this -> write_images ( $this -> images_encoded );
// always end related and end alternative after inline images
2019-11-13 17:32:11 +00:00
$out .= " -- " . $this -> related_boundary . " -- " . $this -> eol ;
$out .= $this -> eol . " -- " . $this -> alternative_boundary . " -- " . $this -> eol ;
2017-04-17 23:39:06 +00:00
$out .= $this -> eol ;
2017-04-04 23:01:43 +00:00
}
2017-04-17 23:39:06 +00:00
2008-11-15 00:52:42 +00:00
return $out ;
}
2009-05-13 14:49:30 +00:00
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2008-11-15 00:52:42 +00:00
/**
2011-07-20 11:07:12 +00:00
* Attach file to email ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2024-08-01 09:09:26 +00:00
* @ param string [] $filename_list Tableau
* @ param string [] $mimetype_list Tableau
* @ param string [] $mimefilename_list Tableau
2024-08-14 17:21:10 +00:00
* @ param ? string [] $cidlist Array of CID if file must be completed with CID code
* @ return string | int <- 1 , - 1 > String with files encoded or - 1 when error
2008-11-15 00:52:42 +00:00
*/
2022-10-23 15:14:23 +00:00
private function write_files ( $filename_list , $mimetype_list , $mimefilename_list , $cidlist )
2008-11-15 00:52:42 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2008-11-15 00:52:42 +00:00
$out = '' ;
2019-11-13 17:32:11 +00:00
$filename_list_size = count ( $filename_list );
2021-01-16 13:12:09 +00:00
for ( $i = 0 ; $i < $filename_list_size ; $i ++ ) {
if ( $filename_list [ $i ]) {
2024-01-28 08:32:53 +00:00
dol_syslog ( " CMailFile::write_files: i= $i " . $filename_list [ $i ]);
2008-11-15 00:52:42 +00:00
$encoded = $this -> _encode_file ( $filename_list [ $i ]);
2024-01-28 08:32:53 +00:00
if ( $encoded !== - 1 ) {
2021-01-16 13:12:09 +00:00
if ( $mimefilename_list [ $i ]) {
$filename_list [ $i ] = $mimefilename_list [ $i ];
}
2019-11-13 17:32:11 +00:00
if ( ! $mimetype_list [ $i ]) {
2017-04-17 23:39:06 +00:00
$mimetype_list [ $i ] = " application/octet-stream " ;
}
2008-11-15 00:52:42 +00:00
2025-10-08 18:24:56 +00:00
// Skip files that have a CID (they will be added as inline images instead)
2025-10-08 18:38:23 +00:00
// @phpstan-ignore-next-line
2025-10-08 18:24:56 +00:00
if ( ! empty ( $cidlist ) && is_array ( $cidlist ) && isset ( $cidlist [ $i ]) && $cidlist [ $i ] !== null && $cidlist [ $i ] !== '' ) {
continue ; // Skip this file as it will be processed as inline image
}
2019-11-13 17:32:11 +00:00
$out .= " -- " . $this -> mixed_boundary . $this -> eol ;
2025-10-08 18:24:56 +00:00
2019-11-13 17:32:11 +00:00
$out .= " Content-Disposition: attachment; filename= \" " . $filename_list [ $i ] . " \" " . $this -> eol ;
$out .= " Content-Type: " . $mimetype_list [ $i ] . " ; name= \" " . $filename_list [ $i ] . " \" " . $this -> eol ;
$out .= " Content-Transfer-Encoding: base64 " . $this -> eol ;
$out .= " Content-Description: " . $filename_list [ $i ] . $this -> eol ;
$out .= $this -> eol ;
$out .= $encoded ;
$out .= $this -> eol ;
2009-05-11 17:13:56 +00:00
//$out.= $this->eol;
2020-05-21 13:05:19 +00:00
} else {
2008-11-15 00:52:42 +00:00
return $encoded ;
}
2006-08-06 18:34:37 +00:00
}
2008-11-15 00:52:42 +00:00
}
2005-06-25 13:02:39 +00:00
2009-05-13 19:10:06 +00:00
return $out ;
}
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2009-05-13 19:10:06 +00:00
/**
2011-07-20 11:07:12 +00:00
* Attach an image to email ( mode = 'mail' )
2010-01-12 23:03:34 +00:00
*
2024-08-01 09:09:26 +00:00
* @ param array < array { name : string , fullpath : string , content_type : string , cid : string , image_encoded : string } > $images_list Array of array image
2026-01-21 11:29:49 +00:00
* @ return string String with encoded images
2009-05-13 19:10:06 +00:00
*/
2019-02-25 21:27:04 +00:00
public function write_images ( $images_list )
2009-05-13 19:10:06 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2009-05-13 19:10:06 +00:00
$out = '' ;
2021-01-16 13:12:09 +00:00
if ( is_array ( $images_list )) {
foreach ( $images_list as $img ) {
2018-11-19 22:43:58 +00:00
dol_syslog ( " CMailFile::write_images: " . $img [ " name " ]);
2009-05-13 19:10:06 +00:00
2019-11-13 17:32:11 +00:00
$out .= " -- " . $this -> related_boundary . $this -> eol ; // always related for an inline image
$out .= " Content-Type: " . $img [ " content_type " ] . " ; name= \" " . $img [ " name " ] . " \" " . $this -> eol ;
$out .= " Content-Transfer-Encoding: base64 " . $this -> eol ;
$out .= " Content-Disposition: inline; filename= \" " . $img [ " name " ] . " \" " . $this -> eol ;
$out .= " Content-ID: < " . $img [ " cid " ] . " > " . $this -> eol ;
$out .= $this -> eol ;
$out .= $img [ " image_encoded " ];
$out .= $this -> eol ;
2009-05-13 19:10:06 +00:00
}
}
2009-05-11 17:13:56 +00:00
2008-11-15 00:52:42 +00:00
return $out ;
}
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2009-11-01 14:16:30 +00:00
/**
* Try to create a socket connection
2011-07-20 11:07:12 +00:00
*
2026-06-02 13:18:57 +00:00
* @ param string $host Add ssl :// for SSL / TLS .
* @ param int $port Example : 25 , 465
* @ return int | array < string , int | string > Socket id if OK , = 0 if KO
2009-11-01 14:16:30 +00:00
*/
2019-02-25 21:27:04 +00:00
public function check_server_port ( $host , $port )
2008-04-16 23:11:45 +00:00
{
2026-06-02 13:18:57 +00:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/geturl.lib.php' ;
2017-08-24 00:02:00 +00:00
2026-06-02 13:18:57 +00:00
// phpcs:enable
2019-11-13 17:32:11 +00:00
$_retVal = 0 ;
$timeout = 5 ; // Timeout in seconds
2008-04-16 23:11:45 +00:00
2026-06-02 13:18:57 +00:00
// Parse $newUrl
$newUrlArray = parse_url ( $host );
$hosttocheck = $newUrlArray [ 'host' ] ? : $newUrlArray [ 'path' ];
$hosttocheck = str_replace ( array ( '[' , ']' ), '' , $hosttocheck ); // Remove brackets of IPv6
// Deny some reserved host names
if ( in_array ( $hosttocheck , array ( 'metadata.google.internal' ))) {
$info = array ();
$info [ 'http_code' ] = 400 ;
$info [ 'content' ] = 'Error bad hostname ' . $hosttocheck . ' (Used by Google metadata). This value for hostname is not allowed.' ;
return $info ;
}
// Clean host name $hosttocheck to convert it into an IP $iptocheck
if ( in_array ( $hosttocheck , array ( 'localhost' , 'localhost.domain' ))) {
$iptocheck = '127.0.0.1' ;
} elseif ( in_array ( $hosttocheck , array ( 'ip6-localhost' , 'ip6-loopback' ))) {
$iptocheck = '::1' ;
} else {
// Resolve $hosttocheck to get the IP $iptocheck
$iptocheck = resolveDns ( $hosttocheck );
}
// Check $iptocheck is an IP (v4 or v6), if not clear value.
if ( ! filter_var ( $iptocheck , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 )) { // This is not an IP, we clean data
$iptocheck = '0' ; // will disabled check on IP
}
if ( $iptocheck && ! in_array ( $iptocheck , array ( '127.0.0.1' , '::1' ))) {
$localurl = 0 ;
$tmpresult = isIPAllowed ( $iptocheck , $localurl );
if ( $tmpresult ) {
$info = array ();
$info [ 'http_code' ] = 400 ;
$info [ 'content' ] = $tmpresult ;
return $info ;
}
}
2021-01-16 13:12:09 +00:00
if ( function_exists ( 'fsockopen' )) {
2019-11-13 17:32:11 +00:00
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER' ;
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT' ;
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID' ;
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW' ;
2022-08-31 12:02:09 +00:00
$keyforsmtpauthtype = 'MAIN_MAIL_SMTPS_AUTH_TYPE' ;
$keyforsmtpoauthservice = 'MAIN_MAIL_SMTPS_OAUTH_SERVICE' ;
2019-11-13 17:32:11 +00:00
$keyfortls = 'MAIN_MAIL_EMAIL_TLS' ;
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS' ;
2022-08-31 12:02:09 +00:00
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED' ;
if ( ! empty ( $this -> sendcontext )) {
$smtpContextKey = strtoupper ( $this -> sendcontext );
$smtpContextSendMode = getDolGlobalString ( 'MAIN_MAIL_SENDMODE_' . $smtpContextKey );
if ( ! empty ( $smtpContextSendMode ) && $smtpContextSendMode != 'default' ) {
$keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER_' . $smtpContextKey ;
$keyforsmtpport = 'MAIN_MAIL_SMTP_PORT_' . $smtpContextKey ;
$keyforsmtpid = 'MAIN_MAIL_SMTPS_ID_' . $smtpContextKey ;
$keyforsmtppw = 'MAIN_MAIL_SMTPS_PW_' . $smtpContextKey ;
$keyforsmtpauthtype = 'MAIN_MAIL_SMTPS_AUTH_TYPE_' . $smtpContextKey ;
$keyforsmtpoauthservice = 'MAIN_MAIL_SMTPS_OAUTH_SERVICE_' . $smtpContextKey ;
$keyfortls = 'MAIN_MAIL_EMAIL_TLS_' . $smtpContextKey ;
$keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS_' . $smtpContextKey ;
$keyforsslseflsigned = 'MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED_' . $smtpContextKey ;
}
2017-08-24 00:02:00 +00:00
}
2017-04-17 23:39:06 +00:00
// If we use SSL/TLS
2024-07-03 18:05:29 +00:00
if ( getDolGlobalString ( $keyfortls ) && function_exists ( 'openssl_open' )) {
2021-01-16 13:12:09 +00:00
$host = 'ssl://' . $host ;
}
2017-04-17 23:39:06 +00:00
// tls smtp start with no encryption
2025-01-05 17:34:01 +00:00
//if (getDolGlobalString('MAIN_MAIL_EMAIL_STARTTLS') && function_exists('openssl_open')) $host='tls://'.$host;
2016-04-17 22:47:08 +00:00
2023-07-27 13:51:32 +00:00
dol_syslog ( " Try socket connection to host= " . $host . " port= " . $port . " timeout= " . $timeout );
2008-04-16 23:11:45 +00:00
//See if we can connect to the SMTP server
2023-12-04 11:04:36 +00:00
$errno = 0 ;
$errstr = '' ;
2020-09-07 08:18:17 +00:00
if ( $socket = @ fsockopen (
2021-01-16 13:12:09 +00:00
$host , // Host to test, IP or domain. Add ssl:// for SSL/TLS.
$port , // which Port number to use
$errno , // actual system level error
$errstr , // and any text that goes with the error
$timeout // timeout for reading/writing data over the socket
2019-02-10 09:45:49 +00:00
)) {
2008-04-16 23:11:45 +00:00
// Windows still does not have support for this timeout function
2021-01-16 13:12:09 +00:00
if ( function_exists ( 'stream_set_timeout' )) {
stream_set_timeout ( $socket , $timeout , 0 );
}
2009-10-28 20:37:06 +00:00
dol_syslog ( " Now we wait for answer 220 " );
2008-04-16 23:11:45 +00:00
// Check response from Server
2021-01-16 13:12:09 +00:00
if ( $_retVal = $this -> server_parse ( $socket , " 220 " )) {
$_retVal = $socket ;
2024-12-06 14:33:29 +00:00
} else {
$this -> error = ( $this -> error ? $this -> error . " - " : " " ) . " Succeed in opening socket but answer 220 not received " ;
2021-01-16 13:12:09 +00:00
}
2020-05-21 13:05:19 +00:00
} else {
2023-12-07 02:37:05 +00:00
$this -> error = utf8_check ( 'Error ' . $errno . ' - ' . $errstr ) ? 'Error ' . $errno . ' - ' . $errstr : mb_convert_encoding ( 'Error ' . $errno . ' - ' . $errstr , 'UTF-8' , 'ISO-8859-1' );
2008-04-16 23:11:45 +00:00
}
}
2024-12-06 14:33:29 +00:00
2026-06-02 13:39:56 +00:00
sleep ( 1 );
2026-06-02 13:39:09 +00:00
2008-04-16 23:11:45 +00:00
return $_retVal ;
}
2020-09-07 08:18:17 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2010-07-21 17:39:17 +00:00
/**
2011-07-20 11:07:12 +00:00
* This function has been modified as provided by SirSir to allow multiline responses when
2010-07-21 17:39:17 +00:00
* using SMTP Extensions .
2011-07-20 11:07:12 +00:00
*
2019-04-04 16:33:12 +00:00
* @ param resource $socket Socket
* @ param string $response Response string
* @ return boolean true if success
2010-07-21 17:39:17 +00:00
*/
2019-02-25 21:27:04 +00:00
public function server_parse ( $socket , $response )
2008-04-16 23:11:45 +00:00
{
2020-09-07 08:18:17 +00:00
// phpcs:enable
2019-11-13 17:32:11 +00:00
$_retVal = true ; // Indicates if Object was created or not
2008-04-16 23:11:45 +00:00
$server_response = '' ;
2021-01-16 13:12:09 +00:00
while ( substr ( $server_response , 3 , 1 ) != ' ' ) {
if ( ! ( $server_response = fgets ( $socket , 256 ))) {
2019-11-13 17:32:11 +00:00
$this -> error = " Couldn't get mail server response codes " ;
2016-10-01 14:41:12 +00:00
return false ;
2008-04-16 23:11:45 +00:00
}
}
2021-01-16 13:12:09 +00:00
if ( ! ( substr ( $server_response , 0 , 3 ) == $response )) {
2019-11-13 17:32:11 +00:00
$this -> error = " Ran into problems sending Mail. \r \n Response: $server_response " ;
2008-04-16 23:11:45 +00:00
$_retVal = false ;
}
return $_retVal ;
2008-11-15 00:52:42 +00:00
}
2009-05-13 14:49:30 +00:00
2009-05-11 17:13:56 +00:00
/**
2023-02-23 17:29:58 +00:00
* Search images into html message and init array this -> images_encoded if found
2026-01-10 16:28:44 +00:00
* This is called in the CMailFile constructor but only if MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS is set ( Off by default )
2010-01-12 23:03:34 +00:00
*
2024-01-13 18:48:20 +00:00
* @ param string $images_dir Path to store physical images files . For example $dolibarr_main_data_root . '/medias'
2011-12-07 16:28:11 +00:00
* @ return int > 0 if OK , < 0 if KO
2009-05-11 17:13:56 +00:00
*/
2022-10-23 15:14:23 +00:00
private function findHtmlImages ( $images_dir )
2009-05-13 14:49:30 +00:00
{
2022-10-23 15:14:23 +00:00
// Build the array of image extensions
2009-05-13 14:49:30 +00:00
$extensions = array_keys ( $this -> image_types );
2025-10-07 10:45:33 +00:00
// We search (into mail body this->html), if we find some strings like "... .imgext" or '... .imgext' to detect strings like "...file=xxx.img"
// For example to detect:
2022-10-23 15:14:23 +00:00
// <img alt="" src="/viewimage.php?modulepart=medias&entity=1&file=image/picture.jpg" style="height:356px; width:1040px" />
2018-10-19 13:02:54 +00:00
$matches = array ();
2019-11-13 17:32:11 +00:00
preg_match_all ( '/(?:"|\')([^"\']+\.(' . implode ( '|' , $extensions ) . '))(?:"|\')/Ui' , $this -> html , $matches ); // If "xxx.ext" or 'xxx.ext' found
2009-05-13 14:49:30 +00:00
2024-01-04 10:47:43 +00:00
if ( ! empty ( $matches ) && ! empty ( $matches [ 1 ])) {
2019-11-13 17:32:11 +00:00
$i = 0 ;
2022-10-23 15:14:23 +00:00
// We are interested in $matches[1] only (the second set of parenthesis into regex)
2021-01-16 13:12:09 +00:00
foreach ( $matches [ 1 ] as $full ) {
2026-03-20 15:22:57 +00:00
$full = urldecode ( $full );
2022-10-23 15:14:23 +00:00
$regs = array ();
2026-03-20 15:22:57 +00:00
if ( preg_match ( '/file=([A-Za-z0-9_\-\/ ]+[\.]?[A-Za-z0-9]+)?$/i' , $full , $regs )) { // If xxx is 'file=aaa'
2009-11-18 14:19:03 +00:00
$img = $regs [ 1 ];
2010-01-12 23:03:34 +00:00
2021-01-16 13:12:09 +00:00
if ( file_exists ( $images_dir . '/' . $img )) {
2009-11-18 14:19:03 +00:00
// Image path in src
2019-01-27 10:55:16 +00:00
$src = preg_quote ( $full , '/' );
2009-11-18 14:19:03 +00:00
// Image full path
$this -> html_images [ $i ][ " fullpath " ] = $images_dir . '/' . $img ;
// Image name
$this -> html_images [ $i ][ " name " ] = $img ;
// Content type
2022-10-23 15:14:23 +00:00
$regext = array ();
if ( preg_match ( '/^.+\.(\w{3,4})$/' , $img , $regext )) {
$ext = strtolower ( $regext [ 1 ]);
2013-09-11 13:17:31 +00:00
$this -> html_images [ $i ][ " content_type " ] = $this -> image_types [ $ext ];
2013-09-11 12:48:02 +00:00
}
2009-11-18 14:19:03 +00:00
// cid
2023-05-11 00:04:25 +00:00
$this -> html_images [ $i ][ " cid " ] = dol_hash ( $this -> html_images [ $i ][ " fullpath " ], 'md5' ); // Force md5 hash (does not contain special chars)
2022-10-23 15:14:23 +00:00
// type
$this -> html_images [ $i ][ " type " ] = 'cidfromurl' ;
2009-11-18 14:19:03 +00:00
$this -> html = preg_replace ( " /src= \" $src\ " | src = '$src' / i " , " src = \ " cid: " . $this -> html_images [ $i ][ " cid " ] . " \" " , $this -> html );
}
$i ++ ;
2009-05-13 14:49:30 +00:00
}
}
2021-01-16 13:12:09 +00:00
if ( ! empty ( $this -> html_images )) {
2009-05-18 07:30:53 +00:00
$inline = array ();
2019-11-13 17:32:11 +00:00
$i = 0 ;
2009-05-13 14:49:30 +00:00
2021-01-16 13:12:09 +00:00
foreach ( $this -> html_images as $img ) {
2009-05-18 07:30:53 +00:00
$fullpath = $images_dir . '/' . $img [ " name " ];
2009-05-24 20:01:25 +00:00
2025-10-07 10:45:33 +00:00
// If referenced image is found on disk (src link), it may show up as attachments, so we remove it by storing it into images_encoded
2021-01-16 13:12:09 +00:00
if ( ! in_array ( $fullpath , $inline )) {
2009-05-18 07:30:53 +00:00
// Read image file
2021-01-16 13:12:09 +00:00
if ( $image = file_get_contents ( $fullpath )) {
2009-05-18 07:30:53 +00:00
// On garde que le nom de l'image
2022-10-23 15:14:23 +00:00
$regs = array ();
2019-01-27 10:55:16 +00:00
preg_match ( '/([A-Za-z0-9_-]+[\.]?[A-Za-z0-9]+)?$/i' , $img [ " name " ], $regs );
2009-05-18 07:30:53 +00:00
$imgName = $regs [ 1 ];
$this -> images_encoded [ $i ][ 'name' ] = $imgName ;
2016-04-17 08:28:21 +00:00
$this -> images_encoded [ $i ][ 'fullpath' ] = $fullpath ;
2009-05-18 07:30:53 +00:00
$this -> images_encoded [ $i ][ 'content_type' ] = $img [ " content_type " ];
$this -> images_encoded [ $i ][ 'cid' ] = $img [ " cid " ];
// Encodage de l'image
$this -> images_encoded [ $i ][ " image_encoded " ] = chunk_split ( base64_encode ( $image ), 68 , $this -> eol );
$inline [] = $fullpath ;
}
2009-05-13 14:49:30 +00:00
}
$i ++ ;
}
2020-05-21 13:05:19 +00:00
} else {
2009-05-13 14:49:30 +00:00
return - 1 ;
}
return 1 ;
2020-05-21 13:05:19 +00:00
} else {
2009-05-13 14:49:30 +00:00
return 0 ;
}
}
2009-05-17 22:54:12 +00:00
2022-10-23 15:14:23 +00:00
/**
2025-10-07 10:45:33 +00:00
* Search images with src = " data:image... " format into html message .
* If we find some , we create them on disk .
2026-01-10 16:28:44 +00:00
* This is called in the CMailFile constructor .
2022-10-23 15:14:23 +00:00
*
2024-01-13 18:48:20 +00:00
* @ param string $images_dir Location of where to store physically images files . For example $dolibarr_main_data_root . '/medias'
2022-10-23 15:14:23 +00:00
* @ return int > 0 if OK , < 0 if KO
*/
private function findHtmlImagesIsSrcData ( $images_dir )
{
global $conf ;
2024-03-19 09:51:42 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
2022-10-23 15:14:23 +00:00
// Build the array of image extensions
$extensions = array_keys ( $this -> image_types );
2024-03-18 19:02:08 +00:00
if ( empty ( $images_dir )) {
2024-03-19 08:19:59 +00:00
//$images_dir = $conf->admin->dir_output.'/temp/'.uniqid('cmailfile');
$images_dir = $conf -> admin -> dir_output . '/temp/cmailfile' ;
2024-03-18 19:02:08 +00:00
}
2022-10-23 15:14:23 +00:00
if ( $images_dir && ! dol_is_dir ( $images_dir )) {
dol_mkdir ( $images_dir , DOL_DATA_ROOT );
}
// Uncomment this for debug
/*
global $dolibarr_main_data_root ;
$outputfile = $dolibarr_main_data_root . " /dolibarr_mail.log " ;
2022-10-28 02:20:54 +00:00
$fp = fopen ( $outputfile , " w+ " );
2022-10-23 15:14:23 +00:00
fwrite ( $fp , $this -> html );
fclose ( $fp );
*/
// We search (into mail body this->html), if we find some strings like "... file=xxx.img"
// For example when:
2023-12-13 10:31:42 +00:00
// <img alt="" src="/src="data:image....;base64,...." />
2022-10-23 15:14:23 +00:00
$matches = array ();
preg_match_all ( '/src="data:image\/(' . implode ( '|' , $extensions ) . ');base64,([^"]+)"/Ui' , $this -> html , $matches ); // If "xxx.ext" or 'xxx.ext' found
2022-10-23 20:32:52 +00:00
if ( ! empty ( $matches ) && ! empty ( $matches [ 1 ])) {
2022-10-23 15:14:23 +00:00
if ( empty ( $images_dir )) {
2024-01-13 18:48:20 +00:00
// No temp directory provided, so we are not able to support conversion of data:image into physical images.
2024-03-18 18:27:52 +00:00
$this -> errors [] = 'NoTempDirProvidedInCMailConstructorSoCantConvertDataImgOnDisk' ;
2022-10-23 15:14:23 +00:00
return - 1 ;
}
2023-12-02 14:53:22 +00:00
$i = count ( $this -> html_images );
2022-10-23 15:14:23 +00:00
foreach ( $matches [ 1 ] as $key => $ext ) {
// We save the image to send in disk
$filecontent = $matches [ 2 ][ $key ];
2023-02-25 03:05:18 +00:00
$cid = 'cid000' . dol_hash ( $filecontent , 'md5' ); // The id must not change if image is same
2022-10-23 15:14:23 +00:00
$destfiletmp = $images_dir . '/' . $cid . '.' . $ext ;
2023-02-25 03:05:18 +00:00
if ( ! dol_is_file ( $destfiletmp )) { // If file does not exist yet (this is the case for the first email sent with a data:image inside)
dol_syslog ( " write the cid file " . $destfiletmp );
$fhandle = @ fopen ( $destfiletmp , 'w' );
if ( $fhandle ) {
$nbofbyteswrote = fwrite ( $fhandle , base64_decode ( $filecontent ));
fclose ( $fhandle );
2023-02-25 03:10:25 +00:00
dolChmod ( $destfiletmp );
2023-02-25 03:05:18 +00:00
} else {
$this -> errors [] = " Failed to open file ' " . $destfiletmp . " ' for write " ;
2024-03-18 18:27:52 +00:00
return - 2 ;
2023-02-25 03:05:18 +00:00
}
2022-10-23 15:14:23 +00:00
}
if ( file_exists ( $destfiletmp )) {
// Image full path
$this -> html_images [ $i ][ " fullpath " ] = $destfiletmp ;
// Image name
$this -> html_images [ $i ][ " name " ] = basename ( $destfiletmp );
// Content type
$this -> html_images [ $i ][ " content_type " ] = $this -> image_types [ strtolower ( $ext )];
// cid
$this -> html_images [ $i ][ " cid " ] = $cid ;
// type
$this -> html_images [ $i ][ " type " ] = 'cidfromdata' ;
2022-10-28 02:20:54 +00:00
$this -> html = str_replace ( 'src="data:image/' . $ext . ';base64,' . $filecontent . '"' , 'src="cid:' . $this -> html_images [ $i ][ " cid " ] . '"' , $this -> html );
2022-10-23 15:14:23 +00:00
}
$i ++ ;
}
2025-10-08 18:24:56 +00:00
// Also add cidfromdata images to images_encoded array so they are sent as inline images
foreach ( $this -> html_images as $img ) {
if ( $img [ 'type' ] == 'cidfromdata' ) {
$image_content = file_get_contents ( $img [ 'fullpath' ]);
if ( $image_content !== false ) {
$idx = count ( $this -> images_encoded );
$this -> images_encoded [ $idx ][ 'name' ] = $img [ 'name' ];
$this -> images_encoded [ $idx ][ 'fullpath' ] = $img [ 'fullpath' ];
$this -> images_encoded [ $idx ][ 'content_type' ] = $img [ 'content_type' ];
$this -> images_encoded [ $idx ][ 'cid' ] = $img [ 'cid' ];
$this -> images_encoded [ $idx ][ 'type' ] = 'cidfromdata' ;
$this -> images_encoded [ $idx ][ 'image_encoded' ] = chunk_split ( base64_encode ( $image_content ), 68 , $this -> eol );
}
}
}
2022-10-23 15:14:23 +00:00
return 1 ;
} else {
return 0 ;
}
}
2009-05-17 22:54:12 +00:00
/**
2015-03-19 10:47:30 +00:00
* Return a formatted address string for SMTP protocol
2011-07-20 11:07:12 +00:00
*
2016-10-24 00:02:30 +00:00
* @ param string $address Example : 'John Doe <john@doe.com>, Alan Smith <alan@smith.com>' or 'john@doe.com, alan@smith.com'
2025-08-21 21:13:00 +00:00
* @ param int $format Set to 0 = auto , 1 = emails with <> , 2 = emails without <> , 3 = auto + label between " " , 4 label or email , 5 mailto link
* @ param int $encode Set to 0 = No encode name , 1 = Encode name to RFC2822
* @ param int $maxnumberofemail Set to 0 = No limit . Otherwise , maximum number of emails returned ( $address may contains several email separated with ',' ) . Add '...' if there is more .
2016-10-24 00:02:30 +00:00
* @ return string If format 0 : '<john@doe.com>' or 'John Doe <john@doe.com>' or '=?UTF-8?B?Sm9obiBEb2U=?= <john@doe.com>'
* If format 1 : '<john@doe.com>'
* If format 2 : 'john@doe.com'
* If format 3 : '<john@doe.com>' or '"John Doe" <john@doe.com>' or '"=?UTF-8?B?Sm9obiBEb2U=?=" <john@doe.com>'
* If format 4 : 'John Doe' or 'john@doe.com' if no label exists
2020-09-07 08:18:17 +00:00
* If format 5 : < a href = " mailto:john@doe.com " > John Doe </ a > or < a href = " mailto:john@doe.com " > john @ doe . com </ a > if no label exists
* @ see getArrayAddress ()
2009-05-17 22:54:12 +00:00
*/
2019-02-25 21:27:04 +00:00
public static function getValidAddress ( $address , $format , $encode = 0 , $maxnumberofemail = 0 )
2009-05-17 22:54:12 +00:00
{
2019-11-13 17:32:11 +00:00
$ret = '' ;
2004-12-28 18:34:56 +00:00
2024-02-18 22:00:01 +00:00
$arrayaddress = ( ! empty ( $address ) ? explode ( ',' , $address ) : array ());
2008-11-15 00:52:42 +00:00
2026-02-12 15:29:11 +00:00
// Loop over every component of the address
2019-11-13 17:32:11 +00:00
$i = 0 ;
2021-01-16 13:12:09 +00:00
foreach ( $arrayaddress as $val ) {
2020-09-28 18:47:36 +00:00
$regs = array ();
2021-01-16 13:12:09 +00:00
if ( preg_match ( '/^(.*)<(.*)>$/i' , trim ( $val ), $regs )) {
2009-05-17 22:54:12 +00:00
$name = trim ( $regs [ 1 ]);
$email = trim ( $regs [ 2 ]);
2020-05-21 13:05:19 +00:00
} else {
2009-05-17 22:54:12 +00:00
$name = '' ;
$email = trim ( $val );
2007-04-01 02:56:53 +00:00
}
2009-05-17 22:54:12 +00:00
2021-01-16 13:12:09 +00:00
if ( $email ) {
2017-04-17 23:39:06 +00:00
$i ++ ;
2017-08-24 00:02:00 +00:00
2019-11-13 17:32:11 +00:00
$newemail = '' ;
2020-09-07 08:18:17 +00:00
if ( $format == 5 ) {
$newemail = $name ? $name : $email ;
$newemail = '<a href="mailto:' . $email . '">' . $newemail . '</a>' ;
}
2021-01-16 13:12:09 +00:00
if ( $format == 4 ) {
2019-11-13 17:32:11 +00:00
$newemail = $name ? $name : $email ;
2016-10-24 00:02:30 +00:00
}
2021-01-16 13:12:09 +00:00
if ( $format == 2 ) {
2019-11-13 17:32:11 +00:00
$newemail = $email ;
2009-05-17 22:54:12 +00:00
}
2021-01-16 13:12:09 +00:00
if ( $format == 1 || $format == 3 ) {
2019-11-13 17:32:11 +00:00
$newemail = '<' . $email . '>' ;
2009-05-17 22:54:12 +00:00
}
2021-01-16 13:12:09 +00:00
if ( $format == 0 || $format == 3 ) {
2023-11-27 10:24:19 +00:00
if ( getDolGlobalString ( 'MAIN_MAIL_NO_FULL_EMAIL' )) {
2021-01-16 13:12:09 +00:00
$newemail = '<' . $email . '>' ;
} elseif ( ! $name ) {
$newemail = '<' . $email . '>' ;
} else {
2023-12-04 11:04:36 +00:00
$newemail = ( $format == 3 ? '"' : '' ) . ( $encode ? self :: encodetorfc2822 ( $name ) : $name ) . ( $format == 3 ? '"' : '' ) . ' <' . $email . '>' ;
2024-11-08 15:58:25 +00:00
//$newemail = (($format == 3 && !$encode) ? '"' : '').($encode ? self::encodetorfc2822($name) : $name).(($format == 3 && !$encode) ? '"' : '').' <'.$email.'>';
2021-01-16 13:12:09 +00:00
}
2009-05-17 22:54:12 +00:00
}
2007-04-01 02:56:53 +00:00
2019-11-13 17:32:11 +00:00
$ret = ( $ret ? $ret . ',' : '' ) . $newemail ;
2017-04-17 23:39:06 +00:00
2016-10-24 00:02:30 +00:00
// Stop if we have too much records
2021-01-16 13:12:09 +00:00
if ( $maxnumberofemail && $i >= $maxnumberofemail ) {
if ( count ( $arrayaddress ) > $maxnumberofemail ) {
$ret .= '...' ;
}
2017-04-17 23:39:06 +00:00
break ;
2016-10-24 00:02:30 +00:00
}
2009-05-17 22:54:12 +00:00
}
2006-08-06 18:34:37 +00:00
}
2008-11-15 00:52:42 +00:00
2009-05-17 22:54:12 +00:00
return $ret ;
}
2016-04-16 16:15:03 +00:00
2017-04-17 23:39:06 +00:00
/**
* Return a formatted array of address string for SMTP protocol
*
2024-08-01 09:09:26 +00:00
* @ param string $address Example : 'John Doe <john@doe.com>, Alan Smith <alan@smith.com>' or 'john@doe.com, alan@smith.com'
* @ return array < string , ? string > array ( email => name )
2019-12-13 14:52:08 +00:00
* @ see getValidAddress ()
2017-04-17 23:39:06 +00:00
*/
2021-07-29 08:51:51 +00:00
public static function getArrayAddress ( $address )
2017-04-17 23:39:06 +00:00
{
2019-11-13 17:32:11 +00:00
$ret = array ();
2017-04-17 23:39:06 +00:00
2019-11-13 17:32:11 +00:00
$arrayaddress = explode ( ',' , $address );
2017-04-17 23:39:06 +00:00
2026-02-12 15:29:11 +00:00
// Loop over every component of the address
2021-01-16 13:12:09 +00:00
foreach ( $arrayaddress as $val ) {
2024-04-22 13:06:41 +00:00
$regs = array ();
2021-01-16 13:12:09 +00:00
if ( preg_match ( '/^(.*)<(.*)>$/i' , trim ( $val ), $regs )) {
2017-04-17 23:39:06 +00:00
$name = trim ( $regs [ 1 ]);
$email = trim ( $regs [ 2 ]);
2020-05-21 13:05:19 +00:00
} else {
2017-04-17 23:39:06 +00:00
$name = null ;
$email = trim ( $val );
}
2024-04-22 13:06:41 +00:00
$ret [ $email ] = getDolGlobalString ( 'MAIN_MAIL_NO_FULL_EMAIL' ) ? null : $name ;
2017-04-17 23:39:06 +00:00
}
return $ret ;
}
2002-04-30 10:44:42 +00:00
}