dolibarr/htdocs/core/class/html.formmail.class.php

2296 lines
91 KiB
PHP
Raw Normal View History

2012-08-22 21:27:53 +00:00
<?php
2023-01-26 09:46:59 +00:00
/* Copyright (C) 2005-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015-2017 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2015-2017 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
2023-01-26 09:46:59 +00:00
* Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2023 Anthony Berton <anthony.berton@bb2a.fr>
Qual: Fix phan notices (#37837) * Qual: Ignore PhanUndeclaredProperty for specific lines * Fix: Update payment mode reference in PDF generation # Fix: Update payment mode reference in PDF generation The payment mode reference in the PDF generation was incorrectly using `type_payment_code`, an unknown property in Salary. It has been updated to use `type_code` as used elsewhere for the same purpose. * Qual: Typing of several DDLUpdateField field_desc items made optional # Qual: Typing of several DDLUpdateField field_desc items made optional Not all fields are required for updateing the DB typing, and ExtraFields was not providing all of them. * Qual: Update typing for phan notices # Qual: Update typing for phan notices Fix typing mismatches * Qual: Fix extrafields typing in objectline_create.tpl.php # Qual: Fix extrafields typing in objectline_create.tpl.php - Update typing for phan * Qual: Fix typing for Phan & re-use encrypted password when requested # Qual: Fix typing for Phan & re-use encrypted password when requested - Added a cast to string for the crypted password to hint phan that it returns the string version (not the array) - Added a check to ensure the password is not already crypted before generating a new password. - Updated the type hints for parameters `$changelater`, `$notrigger`, `$nosyncmember`, and `$passwordalreadycrypted` to include the range of possible values. - Updated the return type hint for the `setPassword` method to include the range of possible error values. * Qual: Fix file argument to showPreview() calls # Qual: Fix file argument to showPreview() calls Fix argument type mismatches by adjusting '$file' arguments in showPreview calls. * Qual: Update login_c type to string # Qual: Update login_c type to string login_c is username from db. * Qual: Update type hints in treeview.lib.php # Qual: Update type hints in treeview.lib.php Update type hints for static analysis. * Qual: Add null check for objecttmp in selectForFormsList # Qual: Add null check for objecttmp in selectForFormsList Add null check for objecttmp before calling selectForFormsList to ensure static analysis * Qual: Fix phan through null check on object argument # Qual: Fix phan through null check on object argument - Do null check to avoid null parameter (fix phan); - Set more specific type for argument. * Qual: Change type hint of $remise_percent parameter to float # Qual: Change type hint of $remise_percent parameter to float DB type is float, so correct arg type to fix phan notice. * Qual: Ignore some phan notices The descriptions for the linkedObjectsFullLoaded and oldcopy properties have been updated to avoid modification by code formatting tools * Qual: Update phan baseline * Qual: Cast remise_percent to float to match typing requirements * Qual: Cast label to string to help static analysis * Qual: Update date_cancel property type and assignment To fix phan notices: - The date_cancel property type was changed from 'int|string' to 'int|""' to match return type from jdate(). - Additionally, the assignment of date_cancel was updated to use dol_now() instead of $this->db->idate(dol_now()). * Qual: Provide the expected user_id instead of the User object Changed the user fetch logic from using `user_author` to `user_creation_id` * Qual: Correct bool argument from 0 to false ($fill) * Qual/Fix: Correct date converted to dol_print_date * Qual: Fix argument type for addline() * Qual: Update Phan baseline.txt
2026-04-13 10:50:23 +00:00
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
2023-01-26 09:46:59 +00:00
*
2010-05-03 08:43:32 +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
* the Free Software Foundation; either version 3 of the License, or
2010-05-03 08:43:32 +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/>.
2010-05-03 08:43:32 +00:00
*/
/**
2010-06-07 23:52:43 +00:00
* \file htdocs/core/class/html.formmail.class.php
2010-11-22 09:18:53 +00:00
* \ingroup core
2025-10-22 16:12:10 +00:00
* \brief File of class to generate HTML form to send email of unitary email.
2010-05-03 08:43:32 +00:00
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
2025-10-22 16:12:10 +00:00
require_once DOL_DOCUMENT_ROOT.'/core/class/cemailtemplate.class.php'; // So the class ModelMail that was defined into this file in old version is still available when including this file
2010-05-03 08:43:32 +00:00
2012-01-27 14:17:36 +00:00
/**
2026-01-26 15:19:45 +00:00
* Class to manage a HTML form to send a unitary email
2012-01-27 14:17:36 +00:00
* Usage: $formail = new FormMail($db)
2026-01-26 15:19:45 +00:00
* $formmail->proprietes=1 or string or array of values
* $formmail->show_form() show the form
2010-05-03 08:43:32 +00:00
*/
2015-04-18 09:06:53 +00:00
class FormMail extends Form
2010-05-03 08:43:32 +00:00
{
2018-08-22 09:06:34 +00:00
/**
* @var DoliDB Database handler.
*/
public $db;
/**
* @var int 1 = Include HTML form tag and show submit button
* 0 = Do not include form tag and submit button
* -1 = Do not include form tag but include submit button
*/
2019-10-27 17:08:21 +00:00
public $withform;
2011-06-29 10:23:32 +00:00
/**
* @var string name from
*/
2018-08-29 10:35:56 +00:00
public $fromname;
2019-10-27 17:08:21 +00:00
/**
* @var string email from
*/
2018-08-29 10:35:56 +00:00
public $frommail;
2018-10-16 20:27:34 +00:00
/**
* @var string user, company, robot
*/
public $fromtype;
/**
* @var int from ID
*/
public $fromid;
/**
* @var int Add also the robot email as possible senders
*/
public $fromalsorobot;
/**
* @var string thirdparty etc
*/
public $totype;
/**
* @var int ID
*/
public $toid;
/**
2022-08-02 18:22:10 +00:00
* @var string Reply-to name
*/
public $replytoname;
/**
* @var string Reply-to email
*/
2018-08-29 10:35:56 +00:00
public $replytomail;
2019-10-27 17:08:21 +00:00
/**
2022-08-02 18:22:10 +00:00
* @var string To name
*/
2018-08-29 10:35:56 +00:00
public $toname;
2019-10-27 17:08:21 +00:00
/**
2022-08-02 18:22:10 +00:00
* @var string To email
*/
2018-08-29 10:35:56 +00:00
public $tomail;
2019-10-27 17:08:21 +00:00
/**
2022-08-02 18:22:10 +00:00
* @var string Track id
*/
2018-08-29 10:35:56 +00:00
public $trackid;
2022-08-02 18:22:10 +00:00
/**
* @var string If you know a MSGID of an email and want to send the email in reply to it. Will be added into header as In-Reply-To: <...>
*/
public $inreplyto;
/**
* @var int<0,1>
*/
public $withsubstit; // Show substitution array
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withfrom;
/**
* @var int<0,1>|string[]
*/
public $withto; // Show recipient emails
/**
* @var int<0,1>
*/
2022-06-12 09:17:11 +00:00
public $withreplyto;
2018-08-29 10:35:56 +00:00
2021-01-04 22:41:20 +00:00
/**
* @var int<0,1>|string 0 = Do not Show free text for recipient emails
2021-01-04 22:41:20 +00:00
* 1 = Show free text for recipient emails
* or a free email
*/
public $withtofree;
/**
* @var int<0,1>|string[]
*/
2018-08-29 10:35:56 +00:00
public $withtocc;
/**
* @var int<0,1>|string|string[] When 1|'1', enable BCC field, when not 0, use as default BCC email
*/
2018-08-29 10:35:56 +00:00
public $withtoccc;
/**
* @var int<0,1>|string
*/
2018-08-29 10:35:56 +00:00
public $withtopic;
/**
* @var int<0,1>
*/
2023-09-02 08:14:25 +00:00
public $witherrorsto;
2021-01-02 08:47:29 +00:00
/**
* @var int<0,2>|string 0=No attaches files, 1=Show attached files, 2=Can add new attached files, 'text'=Show attached files and the text
2021-01-02 08:47:29 +00:00
*/
public $withfile;
2024-02-18 20:15:26 +00:00
/**
2024-10-14 21:38:14 +00:00
* @var string Use case string to a button "Fill with layout" for this use case. Example 'wesitepage', 'emailing', 'email', ...
2024-02-18 20:15:26 +00:00
*/
public $withlayout;
/**
* @var string 'text' or 'html' to add a button "Fill with AI generation"
2024-02-18 20:15:26 +00:00
*/
public $withaiprompt;
2021-01-02 08:47:29 +00:00
/**
* @var int<-1,1> 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
2021-01-02 08:47:29 +00:00
*/
public $withmaindocfile;
/**
* @var int<0,1>|string
*/
2018-08-29 10:35:56 +00:00
public $withbody;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withfromreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withreplytoreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withtoreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withtoccreadonly;
/**
* @var int<0,1>
*/
2023-09-02 08:14:25 +00:00
public $witherrorstoreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withtocccreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withtopicreadonly;
/**
* @var int<0,1>
*/
2023-09-02 08:14:25 +00:00
public $withbodyreadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withfilereadonly;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withdeliveryreceipt;
/**
* @var int<0,1>
*/
2018-08-29 10:35:56 +00:00
public $withcancel;
/**
* @var int<0,1>
*/
2023-09-02 08:14:25 +00:00
public $withdeliveryreceiptreadonly;
/**
* @var int<-1,1>
*/
2018-08-29 10:35:56 +00:00
public $withfckeditor;
2023-09-02 08:14:25 +00:00
/**
* @var string ckeditortoolbar
*/
public $ckeditortoolbar;
/**
* @var array<string,string>
*/
public $substit = array();
/**
* @var array<int,array<string,string>>
*/
public $substit_lines = array();
2024-03-16 01:09:21 +00:00
/**
* @var array{}|array{models:string,langsmodels?:string,fileinit?:string[],returnurl:string}
2024-03-16 01:09:21 +00:00
*/
public $param = array();
/**
* @var string[]
*/
public $withtouser = array();
/**
* @var string[]
*/
public $withtoccuser = array();
2018-03-21 10:48:30 +00:00
/**
* @var CEmailTemplate[]
*/
public $lines_model;
/**
* @var int<-1,1> -1 suggests the checkbox 'one email per recipient' not checked, 0 = no suggestion, 1 = suggest and checked
*/
2021-10-21 16:15:15 +00:00
public $withoptiononeemailperrecipient;
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
2019-02-27 19:45:07 +00:00
public function __construct($db)
{
$this->db = $db;
$this->withform = 1;
$this->withfrom = 1;
$this->withto = 1;
$this->withtofree = 1;
$this->withtocc = 1;
$this->withtoccc = '0';
$this->witherrorsto = 0;
$this->withtopic = 1;
$this->withfile = 0; // 1=Add section "Attached files". 2=Can add files.
$this->withmaindocfile = 0; // 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
$this->withbody = 1;
$this->withfromreadonly = 1;
$this->withreplytoreadonly = 1;
$this->withtoreadonly = 0;
$this->withtoccreadonly = 0;
$this->withtocccreadonly = 0;
$this->witherrorstoreadonly = 0;
$this->withtopicreadonly = 0;
$this->withfilereadonly = 0;
$this->withbodyreadonly = 0;
$this->withdeliveryreceiptreadonly = 0;
$this->withfckeditor = -1; // -1 = Auto
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Clear list of attached files in send mail form (also stored in session)
*
* @return void
*/
2019-02-27 19:45:07 +00:00
public function clear_attached_files()
{
// phpcs:enable
global $conf, $user;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
// Set tmp user directory
$vardir = $conf->user->dir_output."/".$user->id;
$upload_dir = $vardir.'/temp/'; // TODO Add $keytoavoidconflict in upload_dir path
2021-01-02 08:47:29 +00:00
if (is_dir($upload_dir)) {
dol_delete_dir_recursive($upload_dir);
}
$keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
unset($_SESSION["listofpaths".$keytoavoidconflict]);
unset($_SESSION["listofnames".$keytoavoidconflict]);
unset($_SESSION["listofmimes".$keytoavoidconflict]);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Add a file into the list of attached files (stored in SECTION array)
*
* @param string $path Full absolute path on filesystem of file, including file name
* @param string $file Only filename (can be basename($path))
* @param string $type Mime type (can be dol_mimetype($file))
* @return void
*/
2019-02-27 19:45:07 +00:00
public function add_attached_files($path, $file = '', $type = '')
{
// phpcs:enable
$listofpaths = array();
$listofnames = array();
$listofmimes = array();
2021-01-02 08:47:29 +00:00
if (empty($file)) {
$file = basename($path);
}
if (empty($type)) {
$type = dol_mimetype($file);
}
$keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
2021-01-02 08:47:29 +00:00
if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
$listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
$listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
$listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
}
if (!in_array($file, $listofnames)) {
$listofpaths[] = $path;
$listofnames[] = $file;
$listofmimes[] = $type;
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
$_SESSION["listofpaths".$keytoavoidconflict] = implode(';', $listofpaths);
$_SESSION["listofnames".$keytoavoidconflict] = implode(';', $listofnames);
$_SESSION["listofmimes".$keytoavoidconflict] = implode(';', $listofmimes);
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Remove a file from the list of attached files (stored in SECTION array)
*
* @param int $keytodelete Key index in file array (0, 1, 2, ...)
* @return void
*/
2019-02-27 19:45:07 +00:00
public function remove_attached_files($keytodelete)
{
// phpcs:enable
$listofpaths = array();
$listofnames = array();
$listofmimes = array();
$keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
2021-01-02 08:47:29 +00:00
if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
$listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
$listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
$listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
}
if ($keytodelete >= 0) {
unset($listofpaths[$keytodelete]);
unset($listofnames[$keytodelete]);
unset($listofmimes[$keytodelete]);
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
$_SESSION["listofpaths".$keytoavoidconflict] = implode(';', $listofpaths);
$_SESSION["listofnames".$keytoavoidconflict] = implode(';', $listofnames);
$_SESSION["listofmimes".$keytoavoidconflict] = implode(';', $listofmimes);
//var_dump($_SESSION['listofpaths']);
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Return list of attached files (stored in SECTION array)
*
* @return array{paths:string[],names:string[],mimes:string[]}
*/
2019-02-27 19:45:07 +00:00
public function get_attached_files()
{
// phpcs:enable
$listofpaths = array();
$listofnames = array();
$listofmimes = array();
$keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
2021-01-02 08:47:29 +00:00
if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
$listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
$listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
$listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
}
2024-03-12 23:29:33 +00:00
return array('paths' => $listofpaths, 'names' => $listofnames, 'mimes' => $listofmimes);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Show the form to input an email
* this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
* this->withmaindocfile
*
* @param string $addfileaction Name of action when posting file attachments
* @param string $removefileaction Name of action when removing file attachments
* @return void
2020-10-17 10:59:22 +00:00
* @deprecated
*/
2019-02-27 19:45:07 +00:00
public function show_form($addfileaction = 'addfile', $removefileaction = 'removefile')
{
// phpcs:enable
print $this->get_form($addfileaction, $removefileaction);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Get the form to input an email
* this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
* this->param: Contains more parameters like email templates info
* this->withfckeditor: 1=We use an advanced editor, so we switch content into HTML
*
* @param string $addfileaction Name of action when posting file attachments
* @param string $removefileaction Name of action when removing file attachments
* @return string Form to show
*/
2019-02-27 19:45:07 +00:00
public function get_form($addfileaction = 'addfile', $removefileaction = 'removefile')
{
// phpcs:enable
global $conf, $langs, $user, $hookmanager, $form;
2021-01-04 22:41:20 +00:00
if (!is_object($form)) {
$form = new Form($this->db);
}
2025-04-17 01:56:54 +00:00
// Required to show editor assistants
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
$formfile = new FormFile($this->db);
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formai.class.php';
$formai = new FormAI($this->db);
2018-09-11 08:36:39 +00:00
// Load translation files required by the page
2022-01-21 12:44:40 +00:00
$langs->loadLangs(array('other', 'mails', 'members'));
2021-02-28 11:47:24 +00:00
// Clear temp files. Must be done before call of triggers, at beginning (mode = init), or when we select a new template
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
$this->clear_attached_files();
}
// Call hook getFormMail
$hookmanager->initHooks(array('formmail'));
$parameters = array(
'addfileaction' => $addfileaction,
2024-03-12 23:29:33 +00:00
'removefileaction' => $removefileaction,
'trackid' => $this->trackid
);
$reshook = $hookmanager->executeHooks('getFormMail', $parameters, $this);
2021-01-04 22:41:20 +00:00
if (!empty($reshook)) {
return $hookmanager->resPrint;
2020-05-21 13:05:19 +00:00
} else {
$out = '';
$disablebademails = 1;
2018-08-22 11:37:18 +00:00
// Define output language
$outputlangs = $langs;
$newlang = '';
2022-09-24 12:43:29 +00:00
if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($this->param['langsmodels'])) {
2021-01-12 22:46:29 +00:00
$newlang = $this->param['langsmodels'];
}
2021-01-04 22:41:20 +00:00
if (!empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
$outputlangs->load('other');
}
// Get message template for $this->param["models"] into c_email_templates
$arraydefaultmessage = -1;
2021-01-04 22:41:20 +00:00
if ($this->param['models'] != 'none') {
$model_id = 0;
2021-01-04 22:41:20 +00:00
if (array_key_exists('models_id', $this->param)) {
$model_id = $this->param["models_id"];
}
2023-04-25 19:30:00 +00:00
$arraydefaultmessage = $this->getEMailTemplate($this->db, $this->param["models"], $user, $outputlangs, $model_id, 1, '', ($model_id > 0 ? -1 : 1)); // If $model_id is empty, preselect the first one
}
// Define list of attached files
$listofpaths = array();
$listofnames = array();
$listofmimes = array();
2025-01-27 09:15:56 +00:00
$keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined
2025-01-24 15:52:50 +00:00
if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) {
2025-01-27 09:15:56 +00:00
if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) {
foreach ($this->param['fileinit'] as $path) {
if (!empty($path)) {
$this->add_attached_files($path);
}
}
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
if (!empty($_SESSION["listofpaths".$keytoavoidconflict])) {
$listofpaths = explode(';', $_SESSION["listofpaths".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofnames".$keytoavoidconflict])) {
$listofnames = explode(';', $_SESSION["listofnames".$keytoavoidconflict]);
}
if (!empty($_SESSION["listofmimes".$keytoavoidconflict])) {
$listofmimes = explode(';', $_SESSION["listofmimes".$keytoavoidconflict]);
}
2025-01-27 09:15:56 +00:00
$out .= "\n".'<!-- Begin form mail type='.$this->param["models"].' --><div id="mailformdiv"></div>'."\n";
if ($this->withform == 1) {
$out .= '<form method="POST" name="mailform" id="mailform" enctype="multipart/form-data" action="'.$this->param["returnurl"].'#formmail">'."\n";
2017-11-25 16:21:53 +00:00
2025-01-27 09:15:56 +00:00
$out .= '<a id="formmail" name="formmail"></a>';
$out .= '<input style="display:none" type="submit" id="sendmailhidden" name="sendmail">';
$out .= '<input type="hidden" name="token" value="'.newToken().'" />';
2026-01-10 11:47:13 +00:00
$out .= '<input type="hidden" name="page_y" value="" />';
2025-01-27 09:15:56 +00:00
$out .= '<input type="hidden" name="trackid" value="'.$this->trackid.'" />';
$out .= '<input type="hidden" name="inreplyto" value="'.$this->inreplyto.'" />';
}
if (!empty($this->withfrom)) {
if (!empty($this->withfromreadonly)) {
$out .= '<input type="hidden" id="fromname" name="fromname" value="'.$this->fromname.'" />';
$out .= '<input type="hidden" id="frommail" name="frommail" value="'.$this->frommail.'" />';
}
2025-01-27 09:15:56 +00:00
}
foreach ($this->param as $key => $value) {
if (is_array($value)) {
$out .= "<!-- param key=".$key." is array, we do not output input field for it -->\n";
} else {
$out .= '<input type="hidden" id="'.$key.'" name="'.$key.'" value="'.$value.'" />'."\n";
}
2025-01-27 09:15:56 +00:00
}
$modelmail_array = array();
$break = '';
2025-01-27 09:15:56 +00:00
if ($this->param['models'] != 'none') {
$result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
if ($result < 0) {
setEventMessages($this->error, $this->errors, 'errors');
2025-01-24 15:55:13 +00:00
}
2020-10-17 10:59:22 +00:00
2025-01-27 09:15:56 +00:00
foreach ($this->lines_model as $line) {
$reg = array();
if (preg_match('/\((.*)\)/', $line->label, $reg)) {
$labeltouse = $langs->trans($reg[1]); // langs->trans when label is __(xxx)__
} else {
$labeltouse = $line->label;
2021-01-12 22:46:29 +00:00
}
2025-01-24 15:55:13 +00:00
if ($break != $line->lang) {
// New break for a new language, we add the break
$s = $line->lang;
$shtml = '----- '.$langs->trans("Language_".$line->lang).' -----';
$modelmail_array['separator_'.$line->lang] = array('label' => $s, 'data-html' => $shtml, 'disabled' => 'disabled');
}
2025-01-27 09:15:56 +00:00
// We escape the $labeltouse to store it into $modelmail_array.
$s = dol_escape_htmltag($labeltouse);
$shtml = dol_escape_htmltag($labeltouse);
2025-01-27 09:15:56 +00:00
if ($line->lang) {
$shtml = picto_from_langcode($line->lang).'</span> '.$shtml;
2025-01-27 09:15:56 +00:00
}
if ($line->private) {
$shtml .= ' - <span class="opacitymedium small">'.dol_escape_htmltag($langs->trans("Private")).'</span>';
2021-01-12 22:46:29 +00:00
}
$modelmail_array[$line->id] = array('label' => $s, 'data-html' => $shtml);
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// Zone to select email template
if (count($modelmail_array) > 0) {
$model_mail_selected_id = GETPOSTISSET('modelmailselected') ? GETPOSTINT('modelmailselected') : ($arraydefaultmessage->id > 0 ? $arraydefaultmessage->id : 0);
2021-02-02 09:34:33 +00:00
2025-01-27 09:15:56 +00:00
// If list of template is filled
$out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
$out .= $this->selectarray('modelmailselected', $modelmail_array, $model_mail_selected_id, $langs->trans('SelectMailModel'), 0, 0, '', 0, 0, 0, '', 'minwidth150', 1, '', 0, 1);
2025-01-27 09:15:56 +00:00
if ($user->admin) {
$out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
}
// Language selector for predefined message templates (only when multilang is enabled)
if (getDolGlobalInt('MAIN_MULTILANGS')) {
// This feature is in conflict with the existing one where all templates are show with the language in a flag so user
// can choose the template in the correct language.To avoid duplicate and conflict selection, we currently enable this on a hidden constant.
// A solution to be compatible would be to wait the user has selected the template, and the combo to select language is shown if no language is forced for the template.
if (getDolGlobalInt('MAIN_MULTILANGS_ASK_LANG_IN_SEPARATE_COMBO')) {
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
$formadmin = new FormAdmin($this->db);
$currentlang = (is_object($outputlangs) ? $outputlangs->defaultlang : $langs->defaultlang);
$out .= ' &nbsp; ';
$out .= $formadmin->select_language($currentlang, 'lang_id', 0, array(), 1, 0, 0, 'maxwidth150');
}
}
2025-01-27 09:15:56 +00:00
$out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" id="modelselected">';
$out .= ' &nbsp; ';
$out .= '</div>';
} elseif (!empty($this->param['models']) && in_array($this->param['models'], array(
'propal_send', 'order_send', 'facture_send',
'shipping_send', 'reception_send', 'fichinter_send', 'supplier_proposal_send', 'order_supplier_send',
'invoice_supplier_send', 'supplier_payment_send', 'thirdparty', 'contract', 'user', 'recruitmentcandidature_send', 'product_send', 'all'
2025-01-27 09:15:56 +00:00
))) {
// If list of template is empty
$out .= '<div class="center" style="padding: 0px 0 12px 0">'."\n";
$out .= '<span class="opacitymedium">'.$langs->trans('SelectMailModel').':</span> ';
$out .= '<select name="modelmailselected" disabled="disabled"><option value="none">'.$langs->trans("NoTemplateDefined").'</option></select>'; // Do not put 'disabled' on 'option' tag, it is already on 'select' and it makes chrome crazy.
if ($user->admin) {
$out .= info_admin($langs->trans("YouCanChangeValuesForThisListFrom", $langs->transnoentitiesnoconv('Setup').' - '.$langs->transnoentitiesnoconv('EMails')), 1);
2021-01-12 22:46:29 +00:00
}
2025-01-27 09:15:56 +00:00
$out .= ' &nbsp; ';
$out .= '<input type="submit" class="button reposition smallpaddingimp" value="'.$langs->trans('Apply').'" name="modelselected" disabled="disabled" id="modelselected">';
$out .= ' &nbsp; ';
$out .= '</div>';
} else {
$out .= '<!-- No template available for $this->param["models"] = '.$this->param['models'].' -->';
}
2025-01-27 09:15:56 +00:00
$out .= '<table class="tableforemailform boxtablenotop centpercent">'."\n";
2025-01-27 09:15:56 +00:00
// Substitution array/string
$helpforsubstitution = '';
if (is_array($this->substit) && count($this->substit)) {
$helpforsubstitution .= $langs->trans('AvailableVariables').' :<br><br><span class="small">'."\n";
foreach ($this->substit as $key => $val) {
// Do not show deprecated variables into the tooltip help of substitution variables
if (in_array($key, array('__NEWREF__', '__REFCLIENT__', '__REFSUPPLIER__', '__SUPPLIER_ORDER_DATE_DELIVERY__', '__SUPPLIER_ORDER_DELAY_DELIVERY__'))) {
continue;
}
Qual: Fix phan notices (#37837) * Qual: Ignore PhanUndeclaredProperty for specific lines * Fix: Update payment mode reference in PDF generation # Fix: Update payment mode reference in PDF generation The payment mode reference in the PDF generation was incorrectly using `type_payment_code`, an unknown property in Salary. It has been updated to use `type_code` as used elsewhere for the same purpose. * Qual: Typing of several DDLUpdateField field_desc items made optional # Qual: Typing of several DDLUpdateField field_desc items made optional Not all fields are required for updateing the DB typing, and ExtraFields was not providing all of them. * Qual: Update typing for phan notices # Qual: Update typing for phan notices Fix typing mismatches * Qual: Fix extrafields typing in objectline_create.tpl.php # Qual: Fix extrafields typing in objectline_create.tpl.php - Update typing for phan * Qual: Fix typing for Phan & re-use encrypted password when requested # Qual: Fix typing for Phan & re-use encrypted password when requested - Added a cast to string for the crypted password to hint phan that it returns the string version (not the array) - Added a check to ensure the password is not already crypted before generating a new password. - Updated the type hints for parameters `$changelater`, `$notrigger`, `$nosyncmember`, and `$passwordalreadycrypted` to include the range of possible values. - Updated the return type hint for the `setPassword` method to include the range of possible error values. * Qual: Fix file argument to showPreview() calls # Qual: Fix file argument to showPreview() calls Fix argument type mismatches by adjusting '$file' arguments in showPreview calls. * Qual: Update login_c type to string # Qual: Update login_c type to string login_c is username from db. * Qual: Update type hints in treeview.lib.php # Qual: Update type hints in treeview.lib.php Update type hints for static analysis. * Qual: Add null check for objecttmp in selectForFormsList # Qual: Add null check for objecttmp in selectForFormsList Add null check for objecttmp before calling selectForFormsList to ensure static analysis * Qual: Fix phan through null check on object argument # Qual: Fix phan through null check on object argument - Do null check to avoid null parameter (fix phan); - Set more specific type for argument. * Qual: Change type hint of $remise_percent parameter to float # Qual: Change type hint of $remise_percent parameter to float DB type is float, so correct arg type to fix phan notice. * Qual: Ignore some phan notices The descriptions for the linkedObjectsFullLoaded and oldcopy properties have been updated to avoid modification by code formatting tools * Qual: Update phan baseline * Qual: Cast remise_percent to float to match typing requirements * Qual: Cast label to string to help static analysis * Qual: Update date_cancel property type and assignment To fix phan notices: - The date_cancel property type was changed from 'int|string' to 'int|""' to match return type from jdate(). - Additionally, the assignment of date_cancel was updated to use dol_now() instead of $this->db->idate(dol_now()). * Qual: Provide the expected user_id instead of the User object Changed the user fetch logic from using `user_author` to `user_creation_id` * Qual: Correct bool argument from 0 to false ($fill) * Qual/Fix: Correct date converted to dol_print_date * Qual: Fix argument type for addline() * Qual: Update Phan baseline.txt
2026-04-13 10:50:23 +00:00
if (is_array($val)) {
$val = implode(', ', $val);
} // key __MULTICURRENCY_CODE__ is an array and crashes dolGetFirstLineOfText function which accept only text
2025-12-06 04:06:24 +00:00
$helpforsubstitution .= $key.' -> '.$langs->trans(dol_string_nohtmltag(dolGetFirstLineOfText((string) $val))).'<br>';
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
$helpforsubstitution .= '</span>';
}
2025-01-24 15:55:13 +00:00
2025-01-27 09:15:56 +00:00
/*
if (!empty($this->withsubstit)) { // Unset or set ->withsubstit=0 to disable this.
$out .= '<tr><td colspan="2" class="right">';
if (is_numeric($this->withsubstit)) {
$out .= $form->textwithpicto($langs->trans("EMailTestSubstitutionReplacedByGenericValues"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // Old usage
} else {
$out .= $form->textwithpicto($langs->trans('AvailableVariables'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltip'); // New usage
}
$out .= "</td></tr>\n";
}*/
// From
if (!empty($this->withfrom)) {
if (!empty($this->withfromreadonly)) {
$out .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
// $this->fromtype is the default value to use to select sender
if (!($this->fromtype === 'user' && $this->fromid > 0)
&& !($this->fromtype === 'company')
&& !($this->fromtype === 'robot')
&& !preg_match('/user_aliases/', $this->fromtype)
&& !preg_match('/global_aliases/', $this->fromtype)
&& !preg_match('/senderprofile/', $this->fromtype)
) {
// Use this->fromname and this->frommail or error if not defined
$out .= $this->fromname;
if ($this->frommail) {
$out .= ' &lt;'.$this->frommail.'&gt;';
2020-05-21 13:05:19 +00:00
} else {
2025-01-27 09:15:56 +00:00
if ($this->fromtype) {
$langs->load('errors');
2025-01-27 09:15:56 +00:00
$out .= '<span class="warning"> &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt; </span>';
}
2025-01-27 09:15:56 +00:00
}
} else {
$liste = array();
2025-01-27 09:15:56 +00:00
// Add user email
if (empty($user->email)) {
$langs->load('errors');
$s = $user->getFullName($langs).' &lt;'.$langs->trans('ErrorNoMailDefinedForThisUser').'&gt;';
} else {
$s = $user->getFullName($langs).' &lt;'.$user->email.'&gt;';
}
$liste['user'] = array('label' => $s, 'data-html' => $s);
2025-01-27 09:15:56 +00:00
// Add also company main email
if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
2025-11-09 11:43:04 +00:00
$s = getDolGlobalString('MAIN_INFO_SOCIETE_NOM', getDolGlobalString('MAIN_INFO_SOCIETE_EMAIL')).' &lt;' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'&gt;';
2025-01-27 09:15:56 +00:00
$liste['company'] = array('label' => $s, 'data-html' => $s);
}
2025-01-27 09:15:56 +00:00
// Add also email aliases if there is some
$listaliases = array(
'global_aliases' => getDolGlobalString('MAIN_INFO_SOCIETE_MAIL_ALIASES'),
);
if (!empty($arraydefaultmessage->email_from) && !empty($arraydefaultmessage->id)) {
2025-01-27 09:15:56 +00:00
$templatemailfrom = ' &lt;'.$arraydefaultmessage->email_from.'&gt;';
$liste['from_template_'.((int) $arraydefaultmessage->id)] = array('label' => $templatemailfrom, 'data-html' => $templatemailfrom);
2025-01-27 09:15:56 +00:00
}
// Also add robot email
if (!empty($this->fromalsorobot)) {
if (getDolGlobalString('MAIN_MAIL_EMAIL_FROM') && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) {
$s = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
if ($this->frommail) {
$s .= ' &lt;' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM').'&gt;';
}
2025-01-27 09:15:56 +00:00
$liste['main_from'] = array('label' => $s, 'data-html' => $s);
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// Add also email aliases from the c_email_senderprofile table
$sql = "SELECT rowid, label, email FROM ".$this->db->prefix()."c_email_senderprofile";
2025-10-02 13:36:47 +00:00
$sql .= " WHERE active = 1 AND (private = 0 OR private = ".((int) $user->id).") AND entity IN (".getEntity('c_email_senderprofile').")";
2025-01-27 09:15:56 +00:00
$sql .= " ORDER BY position";
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
$i = 0;
while ($i < $num) {
$obj = $this->db->fetch_object($resql);
if ($obj) {
$listaliases['senderprofile_'.$obj->rowid] = $obj->label.' <'.$obj->email.'>';
}
2025-01-27 09:15:56 +00:00
$i++;
}
2025-01-27 09:15:56 +00:00
} else {
dol_print_error($this->db);
}
2025-01-27 09:15:56 +00:00
foreach ($listaliases as $typealias => $listalias) {
$posalias = 0;
$listaliasarray = explode(',', $listalias);
foreach ($listaliasarray as $listaliasval) {
$posalias++;
$listaliasval = trim($listaliasval);
if ($listaliasval) {
$listaliasval = preg_replace('/</', '&lt;', $listaliasval);
$listaliasval = preg_replace('/>/', '&gt;', $listaliasval);
if (!preg_match('/&lt;/', $listaliasval)) {
$listaliasval = '&lt;'.$listaliasval.'&gt;';
2021-01-12 22:46:29 +00:00
}
2025-01-27 09:15:56 +00:00
$liste[$typealias.'_'.$posalias] = array('label' => $listaliasval, 'data-html' => $listaliasval);
}
}
2025-01-27 09:15:56 +00:00
}
2017-12-10 01:01:36 +00:00
2025-01-27 09:15:56 +00:00
// Using ajaxcombo here make the '<email>' no more visible on list because <emailofuser> is not a valid html tag,
// so we transform before each record into $liste to be printable with ajaxcombo by replacing <> into ()
// $liste['senderprofile_0_0'] = array('label'=>'rrr', 'data-html'=>'rrr &lt;aaaa&gt;');
foreach ($liste as $key => $val) {
if (!empty($liste[$key]['data-html'])) {
$liste[$key]['data-html'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $liste[$key]['data-html']);
$liste[$key]['data-html'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $liste[$key]['data-html']);
}
}
$out .= ' '.$form->selectarray('fromtype', $liste, (empty($arraydefaultmessage->email_from) || empty($arraydefaultmessage->id)) ? $this->fromtype : 'from_template_'.((int) $arraydefaultmessage->id), 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails);
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
$out .= "</td></tr>\n";
} else {
$out .= '<tr><td class="fieldrequired width200">'.$langs->trans("MailFrom")."</td><td>";
$out .= $langs->trans("Name").':<input type="text" id="fromname" name="fromname" class="maxwidth200onsmartphone" value="'.$this->fromname.'" />';
$out .= '&nbsp; &nbsp; ';
$out .= $langs->trans("EMail").':&lt;<input type="text" id="frommail" name="frommail" class="maxwidth200onsmartphone" value="'.$this->frommail.'" />&gt;';
$out .= "</td></tr>\n";
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// To
if (!empty($this->withto) || is_array($this->withto)) {
$out .= $this->getHtmlForTo();
}
2018-03-21 10:48:30 +00:00
2025-01-27 09:15:56 +00:00
// To User
if (!empty($this->withtouser) && is_array($this->withtouser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
$out .= '<tr><td>';
$out .= $langs->trans("MailToUsers");
$out .= '</td><td>';
// multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
$tmparray = $this->withtouser;
foreach ($tmparray as $key => $val) {
$tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true);
}
$withtoselected = GETPOST("receiveruser", 'array'); // Array of selected value
if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
$withtoselected = array_keys($tmparray);
2018-03-21 10:48:30 +00:00
}
2025-01-27 09:15:56 +00:00
$out .= $form->multiselectarray("receiveruser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, "");
$out .= "</td></tr>\n";
}
2018-03-21 10:48:30 +00:00
2025-01-27 09:15:56 +00:00
// With option for one email per recipient
if (!empty($this->withoptiononeemailperrecipient)) {
if (abs($this->withoptiononeemailperrecipient) == 1) {
$out .= '<tr><td class="minwidth200">';
$out .= $langs->trans("GroupEmails");
$out .= '</td><td>';
$out .= ' <input type="checkbox" id="oneemailperrecipient" value="1" name="oneemailperrecipient"'.($this->withoptiononeemailperrecipient > 0 ? ' checked="checked"' : '').'> ';
$out .= '<label for="oneemailperrecipient">';
$out .= $form->textwithpicto($langs->trans("OneEmailPerRecipient"), $langs->trans("WarningIfYouCheckOneRecipientPerEmail"), 1, 'help');
$out .= '</label>';
//$out .= '<span class="hideonsmartphone opacitymedium">';
//$out .= ' - ';
//$out .= $langs->trans("WarningIfYouCheckOneRecipientPerEmail");
//$out .= '</span>';
if (getDolGlobalString('MASS_ACTION_EMAIL_ON_DIFFERENT_THIRPARTIES_ADD_CUSTOM_EMAIL')) {
if (!empty($this->withto) && !is_array($this->withto)) {
2026-02-03 16:57:18 +00:00
$out .= ' <span class="opacitymedium">'.$langs->trans("or").'</span> <input type="email" name="emailto" value="">';
2023-06-13 17:35:18 +00:00
}
}
2025-01-27 09:15:56 +00:00
$out .= '</td></tr>';
} else {
$out .= '<tr><td><input type="hidden" name="oneemailperrecipient" value="1"></td><td></td></tr>';
2022-01-21 12:44:40 +00:00
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// CC
if (!empty($this->withtocc) || is_array($this->withtocc)) {
$out .= $this->getHtmlForCc();
}
2025-01-27 09:15:56 +00:00
// To User cc
if (!empty($this->withtoccuser) && is_array($this->withtoccuser) && getDolGlobalString('MAIN_MAIL_ENABLED_USER_DEST_SELECT')) {
$out .= '<tr><td>';
$out .= $langs->trans("MailToCCUsers");
$out .= '</td><td>';
2018-03-21 10:48:30 +00:00
2025-01-27 09:15:56 +00:00
// multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
$tmparray = $this->withtoccuser;
foreach ($tmparray as $key => $val) {
$tmparray[$key] = dol_htmlentities($tmparray[$key], 0, 'UTF-8', true);
2018-03-21 10:48:30 +00:00
}
2025-01-27 09:15:56 +00:00
$withtoselected = GETPOST("receiverccuser", 'array'); // Array of selected value
if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
$withtoselected = array_keys($tmparray);
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
$out .= $form->multiselectarray("receiverccuser", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, "");
$out .= "</td></tr>\n";
}
2025-01-27 09:15:56 +00:00
// CCC
if (!empty($this->withtoccc) || is_array($this->withtoccc)) {
$out .= $this->getHtmlForWithCcc();
}
2025-01-27 09:15:56 +00:00
// Replyto
if (!empty($this->withreplyto)) {
if ($this->withreplytoreadonly) {
$out .= '<input type="hidden" id="replyname" name="replyname" value="'.$this->replytoname.'" />';
$out .= '<input type="hidden" id="replymail" name="replymail" value="'.$this->replytomail.'" />';
$out .= "<tr><td>".$langs->trans("MailReply")."</td><td>".$this->replytoname.($this->replytomail ? (" &lt;".$this->replytomail."&gt;") : "");
$out .= "</td></tr>\n";
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// Errorsto
if (!empty($this->witherrorsto)) {
$out .= $this->getHtmlForWithErrorsTo();
}
2025-01-27 09:15:56 +00:00
// Ask delivery receipt
if (!empty($this->withdeliveryreceipt) && getDolGlobalInt('MAIN_EMAIL_SUPPORT_ACK')) {
$out .= $this->getHtmlForDeliveryreceipt();
}
2025-01-27 09:15:56 +00:00
// Topic
if (!empty($this->withtopic)) {
$out .= $this->getHtmlForTopic($arraydefaultmessage, $helpforsubstitution);
}
2025-01-27 09:15:56 +00:00
// Attached files
if (!empty($this->withfile)) {
$out .= '<tr>';
$out .= '<td class="tdtop">'.$langs->trans("MailFile").'</td>';
2025-01-27 09:15:56 +00:00
$out .= '<td>';
if ($this->withmaindocfile) {
// withmaindocfile is set to 1 or -1 to show the checkbox (-1 = checked or 1 = not checked)
if (GETPOSTISSET('sendmail')) {
$this->withmaindocfile = (GETPOST('addmaindocfile', 'alpha') ? -1 : 1);
} elseif (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
// If a template was selected, we use setup of template to define if join file checkbox is selected or not.
$this->withmaindocfile = ($arraydefaultmessage->joinfiles ? -1 : 1);
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
if (!empty($this->withmaindocfile)) {
if ($this->withmaindocfile == 1) {
$out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" />';
} elseif ($this->withmaindocfile == -1) {
$out .= '<input type="checkbox" id="addmaindocfile" name="addmaindocfile" value="1" checked="checked" />';
}
if (getDolGlobalString('MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND')) {
$out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDocOrLastGenerated").'.</label><br>';
} else {
$out .= ' <label for="addmaindocfile">'.$langs->trans("JoinMainDoc").'.</label><br>';
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
if (is_numeric($this->withfile)) {
// TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript
$out .= '<input type="hidden" class="removedfilehidden" name="removedfile" value="">'."\n";
$out .= '<script nonce="'.getNonce().'" type="text/javascript">';
$out .= 'jQuery(document).ready(function () {';
$out .= ' jQuery(".removedfile").click(function() {';
$out .= ' jQuery(".removedfilehidden").val(jQuery(this).val());';
$out .= ' });';
$out .= '})';
$out .= '</script>'."\n";
if (count($listofpaths)) {
foreach ($listofpaths as $key => $val) {
$relativepathtofile = substr($val, (strlen(DOL_DATA_ROOT) - strlen($val)));
$entity = (isset($this->param['object_entity']) ? $this->param['object_entity'] : $conf->entity);
if ($entity > 1) {
$relativepathtofile = str_replace('/'.$entity.'/', '/', $relativepathtofile);
}
// Try to extract data from full path
$formfile_params = array();
preg_match('#^(/)(\w+)(/)(.+)$#', $relativepathtofile, $formfile_params);
2025-01-27 09:15:56 +00:00
$out .= '<div id="attachfile_'.$key.'">';
// Preview of attachment
$out .= img_mime($listofnames[$key]).$listofnames[$key];
Qual: Fix phan notices (#37837) * Qual: Ignore PhanUndeclaredProperty for specific lines * Fix: Update payment mode reference in PDF generation # Fix: Update payment mode reference in PDF generation The payment mode reference in the PDF generation was incorrectly using `type_payment_code`, an unknown property in Salary. It has been updated to use `type_code` as used elsewhere for the same purpose. * Qual: Typing of several DDLUpdateField field_desc items made optional # Qual: Typing of several DDLUpdateField field_desc items made optional Not all fields are required for updateing the DB typing, and ExtraFields was not providing all of them. * Qual: Update typing for phan notices # Qual: Update typing for phan notices Fix typing mismatches * Qual: Fix extrafields typing in objectline_create.tpl.php # Qual: Fix extrafields typing in objectline_create.tpl.php - Update typing for phan * Qual: Fix typing for Phan & re-use encrypted password when requested # Qual: Fix typing for Phan & re-use encrypted password when requested - Added a cast to string for the crypted password to hint phan that it returns the string version (not the array) - Added a check to ensure the password is not already crypted before generating a new password. - Updated the type hints for parameters `$changelater`, `$notrigger`, `$nosyncmember`, and `$passwordalreadycrypted` to include the range of possible values. - Updated the return type hint for the `setPassword` method to include the range of possible error values. * Qual: Fix file argument to showPreview() calls # Qual: Fix file argument to showPreview() calls Fix argument type mismatches by adjusting '$file' arguments in showPreview calls. * Qual: Update login_c type to string # Qual: Update login_c type to string login_c is username from db. * Qual: Update type hints in treeview.lib.php # Qual: Update type hints in treeview.lib.php Update type hints for static analysis. * Qual: Add null check for objecttmp in selectForFormsList # Qual: Add null check for objecttmp in selectForFormsList Add null check for objecttmp before calling selectForFormsList to ensure static analysis * Qual: Fix phan through null check on object argument # Qual: Fix phan through null check on object argument - Do null check to avoid null parameter (fix phan); - Set more specific type for argument. * Qual: Change type hint of $remise_percent parameter to float # Qual: Change type hint of $remise_percent parameter to float DB type is float, so correct arg type to fix phan notice. * Qual: Ignore some phan notices The descriptions for the linkedObjectsFullLoaded and oldcopy properties have been updated to avoid modification by code formatting tools * Qual: Update phan baseline * Qual: Cast remise_percent to float to match typing requirements * Qual: Cast label to string to help static analysis * Qual: Update date_cancel property type and assignment To fix phan notices: - The date_cancel property type was changed from 'int|string' to 'int|""' to match return type from jdate(). - Additionally, the assignment of date_cancel was updated to use dol_now() instead of $this->db->idate(dol_now()). * Qual: Provide the expected user_id instead of the User object Changed the user fetch logic from using `user_author` to `user_creation_id` * Qual: Correct bool argument from 0 to false ($fill) * Qual/Fix: Correct date converted to dol_print_date * Qual: Fix argument type for addline() * Qual: Update Phan baseline.txt
2026-04-13 10:50:23 +00:00
$out .= ' '.$formfile->showPreview(array('fullname' => $val,'name' => basename($val)), $formfile_params[2], $formfile_params[4], 0, ($entity == 1 ? '' : 'entity='.((int) $entity)));
2025-01-27 09:15:56 +00:00
if (!$this->withfilereadonly) {
$out .= ' <input type="image" style="border: 0px;" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/delete.png" value="'.($key + 1).'" class="removedfile input-nobottom" id="removedfile_'.$key.'" name="removedfile_'.$key.'" />';
//$out.= ' <a href="'.$_SERVER["PHP_SELF"].'?removedfile='.($key+1).'&id=removedfile_'.$key.'">'.img_delete($langs->trans("Remove"), 'id="removedfile_'.$key.'" name="removedfile_'.$key.'"', 'removedfile input-nobottom').'</a>';
}
2025-01-27 09:15:56 +00:00
$out .= '<br></div>';
}
} /*elseif (empty($this->withmaindocfile)) {
2022-09-19 19:02:06 +00:00
//$out .= '<span class="opacitymedium">'.$langs->trans("NoAttachedFiles").'</span><br>';
}*/
2025-01-27 09:15:56 +00:00
if ($this->withfile == 2) {
$maxfilesizearray = getMaxFileSizeArray();
$maxmin = $maxfilesizearray['maxmin'];
if ($maxmin > 0) {
$out .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
2021-01-12 22:46:29 +00:00
}
2025-01-27 09:15:56 +00:00
// Can add other files
if (!getDolGlobalString('FROM_MAIL_DONT_USE_INPUT_FILE_MULTIPLE')) {
$out .= '<input type="file" class="flat" id="addedfile" name="addedfile[]" value="'.$langs->trans("Upload").'" multiple />';
} else {
$out .= '<input type="file" class="flat" id="addedfile" name="addedfile" value="'.$langs->trans("Upload").'" />';
}
$out .= ' ';
$out .= '<input type="submit" class="button smallpaddingimp" id="'.$addfileaction.'" name="'.$addfileaction.'" value="'.$langs->trans("MailingAddFile").'" />';
}
2025-01-27 09:15:56 +00:00
} else {
$out .= $this->withfile;
}
2025-01-27 09:15:56 +00:00
$out .= "</td></tr>\n";
}
// Message (+ Links to choose layout or ai prompt)
if (!empty($this->withbody)) {
$defaultmessage = GETPOST('message', 'restricthtml');
if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
if ($arraydefaultmessage && $arraydefaultmessage->content) {
2025-04-16 19:08:11 +00:00
$defaultmessage = (string) $arraydefaultmessage->content;
2025-01-27 09:15:56 +00:00
} elseif (!is_numeric($this->withbody)) {
$defaultmessage = $this->withbody;
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
// Complete substitution array with the url to make online payment
$paymenturl = '';
// Set the online payment url link into __ONLINE_PAYMENT_URL__ key
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
$validpaymentmethod = getValidOnlinePaymentMethods('');
2025-01-24 15:55:13 +00:00
2025-01-27 09:15:56 +00:00
if (empty($this->substit['__REF__'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
$paymenturl = '';
} else {
$langs->loadLangs(array('paypal', 'other'));
$typeforonlinepayment = 'free';
if ($this->param["models"] == 'order' || $this->param["models"] == 'order_send') {
$typeforonlinepayment = 'order'; // TODO use detection on something else than template
2021-01-04 22:41:20 +00:00
}
2025-01-27 09:15:56 +00:00
if ($this->param["models"] == 'invoice' || $this->param["models"] == 'facture_send') {
$typeforonlinepayment = 'invoice'; // TODO use detection on something else than template
}
if ($this->param["models"] == 'member') {
$typeforonlinepayment = 'member'; // TODO use detection on something else than template
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
$url = getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
$paymenturl = $url;
}
2013-01-24 16:29:11 +00:00
2025-01-27 09:15:56 +00:00
if (count($validpaymentmethod) > 0 && $paymenturl) {
$langs->load('other');
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = str_replace('\n', "\n", $langs->transnoentities("PredefinedMailContentLink", $paymenturl));
$this->substit['__ONLINE_PAYMENT_URL__'] = $paymenturl;
} elseif (count($validpaymentmethod) > 0) {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '__ONLINE_PAYMENT_TEXT_AND_URL__';
$this->substit['__ONLINE_PAYMENT_URL__'] = '__ONLINE_PAYMENT_URL__';
} else {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = '';
$this->substit['__ONLINE_PAYMENT_URL__'] = '';
}
2020-08-23 20:11:16 +00:00
2025-01-27 09:15:56 +00:00
$this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'] = '';
// Generate the string with the template for lines repeated and filled for each line
$lines = '';
$defaultlines = $arraydefaultmessage->content_lines;
if (isset($defaultlines)) {
foreach ($this->substit_lines as $lineid => $substit_line) {
Fix #34540 use template language for __(TranslationKey)__ substitution (#38546) `make_substitutions()` resolves `__(TranslationKey)__` tokens via the third $outputlangs argument, falling back to the global $langs (the operator's language) when nothing is passed in. The mail-template helpers in `html.formmail.class.php` already build the recipient language at line 509-518 from `this->param['langsmodels']` (or from the template's own `lang` column in `llx_c_email_templates`), but the three call sites that turn the template body and subject into the final preview dropped the argument: - line 1041, when rebuilding repeated `__LINES__` from the template `content_lines` - line 1086, when substituting the template body for the form preview - line 1478, when substituting the topic in `getHtmlForTopic()` So a translation key set up in two languages was always resolved with the operator's locale, never the recipient's, even when the operator picked the French template for a French customer (or when the template carried an explicit `lang` column). The PDF flow was already correct because it routes its substitutions through the already-localised `$outputlangs` of the document generator. Pass $outputlangs at the two existing sites in the main render path, and compute it from the template's `lang` column in the helper `getHtmlForTopic()` so the subject and the body are localised together. Templates with no explicit `lang` still resolve via the operator's language, preserving the prior behaviour for that case. Signed-off-by: Dolicraft <contact@dolicraft.com> Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-06-01 21:39:08 +00:00
$lines .= make_substitutions($defaultlines, $substit_line, $outputlangs)."\n";
}
2025-01-27 09:15:56 +00:00
}
$this->substit['__LINES__'] = $lines;
2013-01-24 16:29:11 +00:00
2025-01-27 09:15:56 +00:00
$defaultmessage = str_replace('\n', "\n", $defaultmessage);
2025-01-27 09:15:56 +00:00
// Deal with format differences between message and some substitution variables (text / HTML)
$atleastonecomponentishtml = 0;
if (strpos($defaultmessage, '__USER_SIGNATURE__') !== false && dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
$atleastonecomponentishtml++;
}
if (strpos($defaultmessage, '__SENDEREMAIL_SIGNATURE__') !== false && dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
$atleastonecomponentishtml++;
}
if (strpos($defaultmessage, '__ONLINE_PAYMENT_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
$atleastonecomponentishtml++;
}
if (strpos($defaultmessage, '__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__') !== false && dol_textishtml($this->substit['__ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__'])) {
$atleastonecomponentishtml++;
}
if (dol_textishtml($defaultmessage)) {
$atleastonecomponentishtml++;
}
if ($atleastonecomponentishtml) {
if (!dol_textishtml($this->substit['__USER_SIGNATURE__'])) {
$this->substit['__USER_SIGNATURE__'] = dol_nl2br($this->substit['__USER_SIGNATURE__']);
}
2025-01-27 09:15:56 +00:00
if (!dol_textishtml($this->substit['__SENDEREMAIL_SIGNATURE__'])) {
$this->substit['__SENDEREMAIL_SIGNATURE__'] = dol_nl2br($this->substit['__SENDEREMAIL_SIGNATURE__']);
2025-01-24 15:55:13 +00:00
}
if (!dol_textishtml($this->substit['__LINES__'])) {
$this->substit['__LINES__'] = dol_nl2br($this->substit['__LINES__']);
}
2025-01-27 09:15:56 +00:00
if (!dol_textishtml($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'])) {
$this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__'] = dol_nl2br($this->substit['__ONLINE_PAYMENT_TEXT_AND_URL__']);
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
if (!dol_textishtml($defaultmessage)) {
$defaultmessage = dol_nl2br($defaultmessage);
}
2025-01-27 09:15:56 +00:00
}
2025-01-27 09:15:56 +00:00
if (GETPOSTISSET("message") && !GETPOST('modelselected')) {
$defaultmessage = GETPOST("message", "restricthtml");
} else {
Fix #34540 use template language for __(TranslationKey)__ substitution (#38546) `make_substitutions()` resolves `__(TranslationKey)__` tokens via the third $outputlangs argument, falling back to the global $langs (the operator's language) when nothing is passed in. The mail-template helpers in `html.formmail.class.php` already build the recipient language at line 509-518 from `this->param['langsmodels']` (or from the template's own `lang` column in `llx_c_email_templates`), but the three call sites that turn the template body and subject into the final preview dropped the argument: - line 1041, when rebuilding repeated `__LINES__` from the template `content_lines` - line 1086, when substituting the template body for the form preview - line 1478, when substituting the topic in `getHtmlForTopic()` So a translation key set up in two languages was always resolved with the operator's locale, never the recipient's, even when the operator picked the French template for a French customer (or when the template carried an explicit `lang` column). The PDF flow was already correct because it routes its substitutions through the already-localised `$outputlangs` of the document generator. Pass $outputlangs at the two existing sites in the main render path, and compute it from the template's `lang` column in the helper `getHtmlForTopic()` so the subject and the body are localised together. Templates with no explicit `lang` still resolve via the operator's language, preserving the prior behaviour for that case. Signed-off-by: Dolicraft <contact@dolicraft.com> Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-06-01 21:39:08 +00:00
// Pass $outputlangs so __(TranslationKey)__ in the template body is resolved
// in the language of the selected email template, not the operator's language
// (see issue #34540).
$defaultmessage = make_substitutions($defaultmessage, $this->substit, $outputlangs);
2025-01-27 09:15:56 +00:00
// Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
$defaultmessage = preg_replace("/^(<br>)+/", "", $defaultmessage);
$defaultmessage = preg_replace("/^\n+/", "", $defaultmessage);
}
2013-01-24 16:29:11 +00:00
$out .= '<!-- Message line from get_form -->';
2025-01-27 09:15:56 +00:00
$out .= '<tr>';
$out .= '<td class="tdtop">';
$out .= $form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
$out .= '</td>';
$out .= '<td class="tdtop">';
$formmail = $this;
$showlinktolayout = ($formmail->withfckeditor && getDolGlobalInt('MAIN_EMAIL_USE_LAYOUT')) ? $formmail->withlayout : '';
$showlinktolayoutlabel = $langs->trans("FillMessageWithALayout");
$showlinktoai = ($formmail->withaiprompt && isModEnabled('ai')) ? 'textgenerationemail' : '';
$showlinktoailabel = $langs->trans("AIEnhancements");
2025-01-27 09:15:56 +00:00
$formatforouput = '';
$htmlname = 'message';
$formai->substit = $this->substit;
$formai->substit_lines = $this->substit_lines;
2025-01-27 09:15:56 +00:00
// Fill $out
$db = $this->db;
2025-01-27 09:15:56 +00:00
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
$out .= '</td>';
$out .= '</tr>';
$out .= '<tr>';
$out .= '<td colspan="2">';
if ($this->withbodyreadonly) {
$out .= nl2br($defaultmessage);
$out .= '<input type="hidden" id="message" name="message" disabled value="'.$defaultmessage.'" />';
} else {
if (!isset($this->ckeditortoolbar)) {
$this->ckeditortoolbar = 'dolibarr_mailings';
}
2025-01-27 09:15:56 +00:00
// Editor wysiwyg
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
if ($this->withfckeditor == -1) {
if (getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
$this->withfckeditor = 1;
} else {
$this->withfckeditor = 0;
2025-01-24 15:55:13 +00:00
}
}
2025-01-27 09:15:56 +00:00
$uselocalbrowser = getDolGlobalBool('FCKEDITOR_ENABLE_IMAGE_UPLOAD');
// $uselocalbrowser = true;
$doleditor = new DolEditor('message', $defaultmessage, '', 280, $this->ckeditortoolbar, 'In', true, $uselocalbrowser, $this->withfckeditor, 8, '95%');
2025-01-27 09:15:56 +00:00
$out .= $doleditor->Create(1);
}
2025-01-27 09:15:56 +00:00
$out .= "</td></tr>\n";
}
2013-01-24 16:29:11 +00:00
2025-01-27 09:15:56 +00:00
$out .= '</table>'."\n";
2016-06-10 16:41:18 +00:00
2025-01-27 09:15:56 +00:00
if ($this->withform == 1 || $this->withform == -1) {
$out .= '<div class="center">';
$out .= '<input type="submit" class="button button-add" id="sendmail" name="sendmail" value="'.$langs->trans("SendMail").'"';
// Add a javascript test to avoid to forget to submit file before sending email
if ($this->withfile == 2 && $conf->use_javascript_ajax) {
$out .= ' onClick="if (document.mailform.addedfile.value != \'\') { alert(\''.dol_escape_js($langs->trans("FileWasNotUploaded")).'\'); return false; } else { return true; }"';
}
2025-01-27 09:15:56 +00:00
$out .= ' />';
if ($this->withcancel) {
$out .= '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'" />';
2025-01-24 15:55:13 +00:00
}
2025-01-27 09:15:56 +00:00
$out .= '</div>'."\n";
}
2025-01-27 09:15:56 +00:00
if ($this->withform == 1) {
$out .= '</form>'."\n";
}
// Disable enter key if option MAIN_MAILFORM_DISABLE_ENTERKEY is set
if (getDolGlobalString('MAIN_MAILFORM_DISABLE_ENTERKEY')) {
$out .= '<script nonce="'.getNonce().'" type="text/javascript">';
$out .= 'jQuery(document).ready(function () {';
$out .= ' $(document).on("keypress", \'#mailform\', function (e) { /* Note this is called at every key pressed ! */
var code = e.keyCode || e.which;
if (code == 13) {
2020-03-06 10:02:40 +00:00
console.log("Enter was intercepted and blocked");
e.preventDefault();
return false;
}
});';
2025-01-27 09:15:56 +00:00
$out .= ' })';
$out .= '</script>';
}
2025-01-27 09:15:56 +00:00
$out .= "<!-- End form mail -->\n";
2013-01-24 16:29:11 +00:00
2025-01-27 09:15:56 +00:00
return $out;
}
}
2025-01-27 09:15:56 +00:00
2021-03-15 19:17:01 +00:00
/**
* get html For To
*
* @return string html
*/
public function getHtmlForTo()
{
global $langs, $form;
$out = '<tr><td class="fieldrequired">';
if ($this->withtofree) {
$out .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
} else {
$out .= $langs->trans("MailTo");
}
$out .= '</td><td>';
if ($this->withtoreadonly) {
if (!empty($this->toname) && !empty($this->tomail)) {
$out .= '<input type="hidden" id="toname" name="toname" value="'.$this->toname.'" />';
$out .= '<input type="hidden" id="tomail" name="tomail" value="'.$this->tomail.'" />';
if ($this->totype == 'thirdparty') {
$soc = new Societe($this->db);
$soc->fetch($this->toid);
$out .= $soc->getNomUrl(1);
} elseif ($this->totype == 'contact') {
$contact = new Contact($this->db);
$contact->fetch($this->toid);
$out .= $contact->getNomUrl(1);
} else {
$out .= $this->toname;
}
$out .= ' &lt;'.$this->tomail.'&gt;';
if ($this->withtofree) {
2025-09-11 14:43:59 +00:00
$out .= '<br>'.$langs->trans("and").' <input class="minwidth200" id="sendto" name="sendto" spellcheck="false" value="'.(!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "").'" />';
2021-03-15 19:17:01 +00:00
}
} else {
// Note withto may be a text like 'AllRecipientSelected'
$out .= (!is_array($this->withto) && !is_numeric($this->withto)) ? $this->withto : "";
}
} else {
// The free input of email
if (!empty($this->withtofree)) {
2025-09-11 14:43:59 +00:00
$out .= '<input class="minwidth200" id="sendto" name="sendto" spellcheck="false" value="'.(($this->withtofree && !is_numeric($this->withtofree)) ? $this->withtofree : (!is_array($this->withto) && !is_numeric($this->withto) ? (GETPOSTISSET("sendto") ? GETPOST("sendto") : $this->withto) : "")).'" />';
2021-03-15 19:17:01 +00:00
}
// The select combo
if (!empty($this->withto) && is_array($this->withto)) {
if (!empty($this->withtofree)) {
2026-02-03 16:57:18 +00:00
$out .= ' <span class="opacitymedium">'.$langs->trans("and")."/".$langs->trans("or")."</span> ";
2021-03-15 19:17:01 +00:00
}
2021-03-15 19:17:01 +00:00
$tmparray = $this->withto;
foreach ($tmparray as $key => $val) {
if (is_array($val)) {
$label = $val['label'];
} else {
$label = $val;
}
$tmparray[$key] = array();
$tmparray[$key]['id'] = $key;
$tmparray[$key]['label'] = $label;
$tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
// multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
2024-03-12 23:29:33 +00:00
$tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
$tmparray[$key]['labelhtml'] = $label;
$tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
$tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
2021-03-15 19:17:01 +00:00
}
2023-02-01 00:04:29 +00:00
$withtoselected = GETPOST("receiver", 'array'); // Array of selected value
if (!getDolGlobalInt('MAIN_MAIL_NO_WITH_TO_SELECTED')) {
if (empty($withtoselected) && count($tmparray) == 1 && GETPOST('action', 'aZ09') == 'presend') {
$withtoselected = array_keys($tmparray);
}
2021-03-15 19:17:01 +00:00
}
2022-08-29 17:40:47 +00:00
$out .= $form->multiselectarray("receiver", $tmparray, $withtoselected, 0, 0, 'inline-block minwidth500', 0, 0);
2021-03-15 19:17:01 +00:00
}
}
$out .= "</td></tr>\n";
return $out;
}
/**
* get html For CC
*
* @return string html
*/
public function getHtmlForCc()
{
global $langs, $form;
$out = '<tr><td>';
$out .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
$out .= '</td><td>';
if ($this->withtoccreadonly) {
$out .= (!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : "";
} else {
$out .= '<input class="minwidth200" id="sendtocc" name="sendtocc" value="'.(GETPOST("sendtocc", "alpha") ? GETPOST("sendtocc", "alpha") : ((!is_array($this->withtocc) && !is_numeric($this->withtocc)) ? $this->withtocc : '')).'" />';
if (!empty($this->withtocc) && is_array($this->withtocc)) {
2026-02-03 16:57:18 +00:00
$out .= ' <span class="opacitymedium">'.$langs->trans("and")."/".$langs->trans("or")."</span> ";
2021-03-15 19:17:01 +00:00
$tmparray = $this->withtocc;
foreach ($tmparray as $key => $val) {
if (is_array($val)) {
$label = $val['label'];
} else {
$label = $val;
}
$tmparray[$key] = array();
$tmparray[$key]['id'] = $key;
$tmparray[$key]['label'] = $label;
$tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
// multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
2024-03-12 23:29:33 +00:00
$tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
$tmparray[$key]['labelhtml'] = $label;
$tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
$tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
2021-03-15 19:17:01 +00:00
}
2021-03-15 19:17:01 +00:00
$withtoccselected = GETPOST("receivercc", 'array'); // Array of selected value
$out .= $form->multiselectarray("receivercc", $tmparray, $withtoccselected, 0, 0, 'inline-block minwidth500', 0, 0);
2021-03-15 19:17:01 +00:00
}
}
$out .= "</td></tr>\n";
return $out;
}
/**
* get html For WithCCC
* This information is show when MAIN_EMAIL_USECCC is set.
*
* @return string html
*/
public function getHtmlForWithCcc()
{
global $langs, $form;
2024-01-17 18:52:17 +00:00
$out = '<tr><td>';
$out .= $form->textwithpicto($langs->trans("MailCCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
$out .= '</td><td>';
if (!empty($this->withtocccreadonly)) {
$out .= (!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : "";
} else {
2020-09-29 19:28:07 +00:00
$out .= '<input class="minwidth200" id="sendtoccc" name="sendtoccc" value="'.(GETPOSTISSET("sendtoccc") ? GETPOST("sendtoccc", "alpha") : ((!is_array($this->withtoccc) && !is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />';
if (!empty($this->withtoccc) && is_array($this->withtoccc)) {
2026-02-03 16:57:18 +00:00
$out .= ' <span class="opacitymedium">'.$langs->trans("and")."/".$langs->trans("or")."</span> ";
$tmparray = $this->withtoccc;
foreach ($tmparray as $key => $val) {
if (is_array($val)) {
$label = $val['label'];
} else {
$label = $val;
}
$tmparray[$key] = array();
$tmparray[$key]['id'] = $key;
$tmparray[$key]['label'] = $label;
$tmparray[$key]['label'] = str_replace(array('<', '>'), array('(', ')'), $tmparray[$key]['label']);
// multiselect array convert html entities into options tags, even if we don't want this, so we encode them a second time
2024-03-12 23:29:33 +00:00
$tmparray[$key]['label'] = dol_htmlentities($tmparray[$key]['label'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', true);
$tmparray[$key]['labelhtml'] = $label;
$tmparray[$key]['labelhtml'] = str_replace(array('&lt;', '<', '&gt;', '>'), array('__LTCHAR__', '__LTCHAR__', '__GTCHAR__', '__GTCHAR__'), $tmparray[$key]['labelhtml']);
$tmparray[$key]['labelhtml'] = str_replace(array('__LTCHAR__', '__GTCHAR__'), array('<span class="opacitymedium">(', ')</span>'), $tmparray[$key]['labelhtml']);
}
2020-09-29 19:28:07 +00:00
$withtocccselected = GETPOST("receiverccc", 'array'); // Array of selected value
$out .= $form->multiselectarray("receiverccc", $tmparray, $withtocccselected, 0, 0, 'inline-block minwidth500', 0, 0);
}
}
$showinfobcc = '';
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROPOSAL_TO');
2021-01-02 15:58:05 +00:00
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_ORDER_TO');
2021-01-02 15:58:05 +00:00
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_INVOICE_TO');
2021-01-02 15:58:05 +00:00
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO');
2021-01-02 15:58:05 +00:00
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO');
2021-01-02 15:58:05 +00:00
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO') && !empty($this->param['models']) && $this->param['models'] == 'invoice_supplier_send') {
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO');
2021-01-02 15:58:05 +00:00
}
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO') && !empty($this->param['models']) && $this->param['models'] == 'project') { // don't know why there is not '_send' at end of this models name.
2024-01-05 03:18:53 +00:00
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_PROJECT_TO');
2021-01-02 15:58:05 +00:00
}
2024-01-17 18:52:17 +00:00
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO') && !empty($this->param['models']) && $this->param['models'] == 'shipping_send') {
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_SHIPMENT_TO');
}
if (getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO') && !empty($this->param['models']) && $this->param['models'] == 'reception_send') {
$showinfobcc = getDolGlobalString('MAIN_MAIL_AUTOCOPY_RECEPTION_TO');
2021-01-02 15:58:05 +00:00
}
if ($showinfobcc) {
$out .= ' + '.$showinfobcc;
}
$out .= "</td></tr>\n";
return $out;
}
/**
* get Html For WithErrorsTo
*
* @return string html
*/
public function getHtmlForWithErrorsTo()
{
global $langs;
//if (! $this->errorstomail) $this->errorstomail=$this->frommail;
2022-08-10 12:42:07 +00:00
$errorstomail = getDolGlobalString('MAIN_MAIL_ERRORS_TO', (!empty($this->errorstomail) ? $this->errorstomail : ''));
if ($this->witherrorstoreadonly) {
$out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
$out .= '<input type="hidden" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
$out .= $errorstomail;
$out .= "</td></tr>\n";
} else {
$out = '<tr><td>'.$langs->trans("MailErrorsTo").'</td><td>';
$out .= '<input class="minwidth200" id="errorstomail" name="errorstomail" value="'.$errorstomail.'" />';
$out .= "</td></tr>\n";
}
return $out;
}
/**
2021-01-16 13:12:09 +00:00
* get Html For Asking for Delivery Receipt
*
* @return string html
*/
public function getHtmlForDeliveryreceipt()
{
global $langs;
$out = '<tr><td><label for="deliveryreceipt">'.$langs->trans("DeliveryReceipt").'</label></td><td>';
if (!empty($this->withdeliveryreceiptreadonly)) {
$out .= yn($this->withdeliveryreceipt);
} else {
$defaultvaluefordeliveryreceipt = 0;
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_PROPAL') && !empty($this->param['models']) && $this->param['models'] == 'propal_send') {
2021-01-12 22:46:29 +00:00
$defaultvaluefordeliveryreceipt = 1;
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_PROPOSAL') && !empty($this->param['models']) && $this->param['models'] == 'supplier_proposal_send') {
2021-01-12 22:46:29 +00:00
$defaultvaluefordeliveryreceipt = 1;
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_send') {
2021-01-12 22:46:29 +00:00
$defaultvaluefordeliveryreceipt = 1;
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_INVOICE') && !empty($this->param['models']) && $this->param['models'] == 'facture_send') {
2021-01-12 22:46:29 +00:00
$defaultvaluefordeliveryreceipt = 1;
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MAIL_FORCE_DELIVERY_RECEIPT_SUPPLIER_ORDER') && !empty($this->param['models']) && $this->param['models'] == 'order_supplier_send') {
$defaultvaluefordeliveryreceipt = 1;
}
//$out .= $form->selectyesno('deliveryreceipt', (GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt), 1);
$out .= '<input type="checkbox" id="deliveryreceipt" name="deliveryreceipt" value="1"'.((GETPOSTISSET("deliveryreceipt") ? GETPOST("deliveryreceipt") : $defaultvaluefordeliveryreceipt) ? ' checked="checked"' : '').'>';
}
$out .= "</td></tr>\n";
return $out;
}
/**
* Return Html section for the Topic of message
*
2025-10-22 20:31:51 +00:00
* @param CEmailTemplate $arraydefaultmessage Array with message template content
* @param string $helpforsubstitution Help string for substitution
* @return string Text for topic
*/
public function getHtmlForTopic($arraydefaultmessage, $helpforsubstitution)
{
Fix #34540 use template language for __(TranslationKey)__ substitution (#38546) `make_substitutions()` resolves `__(TranslationKey)__` tokens via the third $outputlangs argument, falling back to the global $langs (the operator's language) when nothing is passed in. The mail-template helpers in `html.formmail.class.php` already build the recipient language at line 509-518 from `this->param['langsmodels']` (or from the template's own `lang` column in `llx_c_email_templates`), but the three call sites that turn the template body and subject into the final preview dropped the argument: - line 1041, when rebuilding repeated `__LINES__` from the template `content_lines` - line 1086, when substituting the template body for the form preview - line 1478, when substituting the topic in `getHtmlForTopic()` So a translation key set up in two languages was always resolved with the operator's locale, never the recipient's, even when the operator picked the French template for a French customer (or when the template carried an explicit `lang` column). The PDF flow was already correct because it routes its substitutions through the already-localised `$outputlangs` of the document generator. Pass $outputlangs at the two existing sites in the main render path, and compute it from the template's `lang` column in the helper `getHtmlForTopic()` so the subject and the body are localised together. Templates with no explicit `lang` still resolve via the operator's language, preserving the prior behaviour for that case. Signed-off-by: Dolicraft <contact@dolicraft.com> Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-06-01 21:39:08 +00:00
global $conf, $langs, $form;
2020-09-17 23:29:17 +00:00
$defaulttopic = GETPOST('subject', 'restricthtml');
2022-01-21 12:44:40 +00:00
if (!GETPOST('modelselected', 'alpha') || GETPOST('modelmailselected') != '-1') {
if ($arraydefaultmessage && $arraydefaultmessage->topic) {
$defaulttopic = $arraydefaultmessage->topic;
} elseif (!is_numeric($this->withtopic)) {
$defaulttopic = $this->withtopic;
}
}
Fix #34540 use template language for __(TranslationKey)__ substitution (#38546) `make_substitutions()` resolves `__(TranslationKey)__` tokens via the third $outputlangs argument, falling back to the global $langs (the operator's language) when nothing is passed in. The mail-template helpers in `html.formmail.class.php` already build the recipient language at line 509-518 from `this->param['langsmodels']` (or from the template's own `lang` column in `llx_c_email_templates`), but the three call sites that turn the template body and subject into the final preview dropped the argument: - line 1041, when rebuilding repeated `__LINES__` from the template `content_lines` - line 1086, when substituting the template body for the form preview - line 1478, when substituting the topic in `getHtmlForTopic()` So a translation key set up in two languages was always resolved with the operator's locale, never the recipient's, even when the operator picked the French template for a French customer (or when the template carried an explicit `lang` column). The PDF flow was already correct because it routes its substitutions through the already-localised `$outputlangs` of the document generator. Pass $outputlangs at the two existing sites in the main render path, and compute it from the template's `lang` column in the helper `getHtmlForTopic()` so the subject and the body are localised together. Templates with no explicit `lang` still resolve via the operator's language, preserving the prior behaviour for that case. Signed-off-by: Dolicraft <contact@dolicraft.com> Co-authored-by: Dolicraft <contact@dolicraft.com>
2026-06-01 21:39:08 +00:00
// Resolve __(TranslationKey)__ in the language of the selected template
// (see issue #34540). Falls back to the caller's language when the template
// has no explicit language pinned.
$outputlangs = $langs;
if (is_object($arraydefaultmessage) && !empty($arraydefaultmessage->lang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($arraydefaultmessage->lang);
$outputlangs->load('other');
}
$defaulttopic = make_substitutions($defaulttopic, $this->substit, $outputlangs);
$out = '<tr>';
$out .= '<td class="fieldrequired">';
2026-01-10 12:18:27 +00:00
$out .= $form->textwithpicto($langs->trans('MailTopicShort'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
$out .= '</td>';
$out .= '<td>';
if ($this->withtopicreadonly) {
$out .= $defaulttopic;
2026-04-24 11:10:42 +00:00
$out .= '<input type="hidden" class="quatrevingtpercent" id="subject" name="subject" value="'.$defaulttopic.'" spellcheck="false">';
} else {
2026-04-24 11:10:42 +00:00
$out .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'.((GETPOSTISSET("subject") && !GETPOST('modelselected')) ? GETPOST("subject") : ($defaulttopic ? $defaulttopic : '')).'" spellcheck="false">';
}
$out .= "</td></tr>\n";
return $out;
}
/**
2024-02-18 20:15:26 +00:00
* Return HTML code for selection of email layout
2024-03-24 04:23:06 +00:00
*
2025-04-17 01:56:54 +00:00
* @param string $htmlContent HTML name of WYSIWYG field to fill once layout has been chosen
2024-10-14 21:38:14 +00:00
* @param string $showlinktolayout Show link to layout
* @return string HTML for model email boxes
* @see getContentPageTemplate()
*/
2025-06-02 14:59:46 +00:00
public function getEmailLayoutSelector($htmlContent = 'message', $showlinktolayout = 'email')
{
2025-06-02 18:51:21 +00:00
global $conf, $db, $websitepage, $langs;
2024-08-15 16:32:55 +00:00
2024-02-19 09:16:50 +00:00
require_once DOL_DOCUMENT_ROOT.'/core/lib/emaillayout.lib.php';
2024-08-15 16:32:55 +00:00
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2025-06-02 18:51:21 +00:00
require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
2025-02-16 21:45:14 +00:00
$out = '<div id="template-selector" class="template-selector email-layout-container hidden" style="display:none;">';
2026-04-24 11:24:10 +00:00
$out .= '<div>';
2024-10-14 21:38:14 +00:00
// Define list of email layouts to use
$layouts = array(
2025-10-06 00:50:07 +00:00
'none' => 'None',
2024-01-30 14:37:52 +00:00
);
2025-10-06 00:50:07 +00:00
// Add layouts found on disk in install/doctemplates/maillayout directory
2024-08-15 16:32:55 +00:00
$arrayoflayoutemplates = dol_dir_list(DOL_DOCUMENT_ROOT.'/install/doctemplates/maillayout/', 'files', 0, '\.html$');
foreach ($arrayoflayoutemplates as $layouttemplatefile) {
$layoutname = preg_replace('/\.html$/i', '', $layouttemplatefile['name']);
2024-10-14 21:38:14 +00:00
// Exclude some layouts for some use cases
2025-06-02 15:07:25 +00:00
if ($layoutname == 'news' && (!in_array($showlinktolayout, array('emailing', 'websitepage')) || !isModEnabled('website'))) {
2024-10-14 21:38:14 +00:00
continue;
}
2025-10-06 00:50:07 +00:00
if ($layoutname == 'product' && (!in_array($showlinktolayout, array('emailing', 'websitepage')) || (!isModEnabled('product') && !isModEnabled('service')))) {
2024-10-14 21:38:14 +00:00
continue;
}
$layouts[$layoutname] = ucfirst($layoutname);
2024-08-15 16:32:55 +00:00
}
2024-06-15 23:33:35 +00:00
//}
2024-08-15 16:32:55 +00:00
// TODO Add a hook to allow to complete the list
2024-10-14 21:38:14 +00:00
foreach ($layouts as $layout => $templateFunction) {
$contentHtml = getHtmlOfLayout($layout);
2024-02-18 20:15:26 +00:00
2024-10-14 21:38:14 +00:00
$out .= '<div class="template-option" data-template="'.$layout.'" data-content="'.htmlentities($contentHtml).'">';
$out .= '<img class="maillayout" alt="'.$layout.'" src="'.DOL_URL_ROOT.'/theme/common/maillayout/'.$layout.'.png" />';
2024-08-15 16:32:55 +00:00
$out .= '<span class="template-option-text">'.$langs->trans($templateFunction).'</span>';
$out .= '</div>';
}
$out .= '</div>';
2024-02-18 20:15:26 +00:00
// Prepare the array for multiselect
2025-04-17 01:56:54 +00:00
// Fetch blogs
$blogArray = array();
2025-06-02 18:51:21 +00:00
if (isModEnabled('website')) {
$websitepage = new WebsitePage($this->db);
$arrayofblogs = $websitepage->fetchAll('', 'ASC,DESC', 'fk_website,date_creation', 0, 0, array('type_container' => 'blogpost'));
if (empty($conf->cache['websiteurl'])) {
$conf->cache['websiteurl'] = array();
}
if (!empty($arrayofblogs)) {
foreach ($arrayofblogs as $blog) {
if (!isset($conf->cache['websiteurl'][$blog->id])) {
$tmpwebsite = new Website($db);
$tmpwebsite->fetch($blog->fk_website);
$conf->cache['websiteurl'][$blog->fk_website] = (empty($tmpwebsite->virtualhost) ? $tmpwebsite->ref : $tmpwebsite->virtualhost);
}
$labelwebsite = $conf->cache['websiteurl'][$blog->fk_website];
//$blog->fk_website
$blogArray[$blog->id] = array(
'id' => $blog->id,
'label' => '['.$labelwebsite.' '.$blog->type_container.' '.$blog->id.'] '.dol_trunc($blog->title, 40),
2025-06-04 08:59:27 +00:00
'labelhtml' => '<span class="opacitymedium">['.$labelwebsite.' '.$blog->type_container.' '.$blog->id.']</span> '.dol_trunc($blog->title, 40),
2025-06-02 18:51:21 +00:00
);
}
}
}
// Fetch Product / Services
2026-01-10 11:47:13 +00:00
/* to use with multiselectarray but consume too much memory so replaced
if (in_array('product', array_keys($layouts))) {
$productArray = array();
if (isModEnabled('product') || isModEnabled('service')) {
include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
$form = new Form($this->db);
$arrayofproduct = $form->select_produits_list(0, 'product-select', '', 0, 0, '', 1, 2, 1);
if (!empty($arrayofproduct)) {
foreach ($arrayofproduct as $product) {
$productArray[$product["key"]] = array(
'id' => $product["key"],
'label' => $product["value"].' - '.dol_trunc($product["label2"], 40),
'labelhtml' => $product["value"].' - '.dol_trunc($product["label2"], 40),
);
}
}
}
}
2026-01-10 11:47:13 +00:00
*/
// Use the multiselect array function to create the dropdown
2026-01-10 11:47:13 +00:00
if (in_array('news', array_keys($layouts)) && (isModEnabled('product') || isModEnabled('service'))) {
2026-04-24 12:15:34 +00:00
$out .= '<div id="post-dropdown-container" class="email-layout-container hidden" style="margin-top: 8px; display:none;">';
2026-01-10 11:47:13 +00:00
$out .= '<label for="blogpost-select">Select Posts: </label>';
$out .= '<!-- select component for selection of blog posts -->'."\n";
// TODO WARNING: multiselectarray is ok only for very small list
$out .= self::multiselectarray('blogpost-select', $blogArray, array(), 0, 0, 'minwidth200 select-template');
$out .= ' <input type="submit" class="smallpaddingimp button reposition" name="submit" id="post-submit" value="'.dolPrintHTMLForAttribute($langs->trans("Select")).'">';
$out .= '</div>';
}
if (in_array('product', array_keys($layouts)) && (isModEnabled('product') || isModEnabled('service'))) {
2025-10-06 09:29:03 +00:00
include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
2025-10-06 00:50:07 +00:00
$form = new Form($this->db);
2026-04-24 12:15:34 +00:00
$out .= '<div id="product-dropdown-container" class="email-layout-container hidden" style="margin-top: 8px; display:none;">';
2025-10-06 00:50:07 +00:00
$out .= '<label for="product-select">'.img_picto('', 'product', 'class="pictofixedwidth"').$langs->trans("Product").' : </label>';
$out .= '<!-- select component for selection of product -->'."\n";
2026-01-10 11:47:13 +00:00
$out .= $form->select_produits(0, 'product-select', '', 0, 0, -1, 2, '', 0, array(), 0, '1', 0, 'inline-block valignmiddle', 0, '', null, 1);
// TODO multiselectarray is ok only for very small list but is ok for multiselect. We need a multiselect ok with ajax for long list
//$out .= self::multiselectarray('product-select', $productArray, array(), 0, 0, 'minwidth200 select-template');
$out .= ' <input type="submit" class="smallpaddingimp button reposition" name="submit" id="product-submit" value="'.dolPrintHTMLForAttribute($langs->trans("Select")).'">';
2025-10-06 00:50:07 +00:00
$out .= '</div>';
}
2026-04-24 11:24:10 +00:00
$out .= '</div>';
2025-04-17 01:56:54 +00:00
$out .= '<!-- Js code to manage choice of an email layout -->'."\n";
2024-03-24 04:23:06 +00:00
$out .= '<script type="text/javascript">
2025-04-16 22:56:22 +00:00
$(document).ready(function() {
$(".template-option").click(function() {
var template = $(this).data("template");
var subject = jQuery("#subject").val();
var fromtype = jQuery("#fromtype").val();
var sendto = jQuery("#sendto").val();
var sendtocc = jQuery("#sendtocc").val();
var sendtoccc = jQuery("#sendtoccc").val();
2025-01-23 00:29:29 +00:00
console.log("We choose a layout for email template=" + template + ", subject="+subject);
2025-01-27 09:19:22 +00:00
$(".template-option").removeClass("selected");
$(this).addClass("selected");
$(".select-template").val("").trigger("change");
if (template === "news") {
$("#post-dropdown-container").show();
2025-10-06 00:50:07 +00:00
$("#product-dropdown-container").hide();
console.log("Displaying dropdown for news selection");
2025-10-06 00:50:07 +00:00
} else if (template === "product") {
$("#product-dropdown-container").show();
$("#post-dropdown-container").hide();
console.log("Displaying dropdown for product selection");
} else {
$("#post-dropdown-container").hide();
2025-10-06 00:50:07 +00:00
$("#product-dropdown-container").hide();
}
2024-02-18 20:15:26 +00:00
var csrfToken = "' .newToken().'";
$.ajax({
type: "POST",
url: "'.DOL_URL_ROOT.'/core/ajax/mailtemplate.php",
data: {
token: csrfToken,
template: template,
subject: subject,
fromtype: fromtype,
sendto: sendto,
sendtocc: sendtocc,
sendtoccc: sendtoccc,
selectedPosts: "[]"
},
success: function(response) {
jQuery("#'.$htmlContent.'").val(response);
var editorInstance = CKEDITOR.instances["'.$htmlContent.'"];
if (editorInstance) {
editorInstance.setData(response);
2024-01-30 14:37:52 +00:00
}
},
error: function(xhr, status, error) {
console.error("An error occurred: " + xhr.responseText);
}
});
});
$("#blogpost-select").change(function() {
var selectedIds = $(this).val();
var contentHtml = $(".template-option.selected").data("content");
updateSelectedPostsContent(contentHtml, selectedIds);
});
$("#product-select").change(function() {
var selectedIds = $(this).val();
var contentHtml = $(".template-option.selected").data("content");
updateSelectedPostsContent(contentHtml, selectedIds);
});
function updateSelectedPostsContent(contentHtml, selectedIds) {
var csrfToken = "' .newToken().'";
template = $(".template-option.selected").data("template");
var subject = $("#subject").val();
$.ajax({
type: "POST",
url: "'.dol_buildpath('/core/ajax/mailtemplate.php', 1).'",
data: {
token: csrfToken,
template: template,
subject: subject,
selectedPosts: JSON.stringify(selectedIds)
},
success: function(response) {
jQuery("#'.$htmlContent.'").val(response);
var editorInstance = CKEDITOR.instances["'.$htmlContent.'"];
if (editorInstance) {
editorInstance.setData(response);
}
},
error: function(xhr, status, error) {
console.error("An error occurred: " + xhr.responseText);
}
});
}
});
</script>';
2024-02-18 20:15:26 +00:00
return $out;
}
2024-01-17 16:53:35 +00:00
/**
2019-02-27 19:45:07 +00:00
* Return templates of email with type = $type_template or type = 'all'.
* This search into table c_email_templates. Used by the get_form function.
*
2022-03-07 18:37:53 +00:00
* @param DoliDB $dbs Database handler
2019-02-27 19:45:07 +00:00
* @param string $type_template Get message for model/type=$type_template, type='all' also included.
2022-11-23 17:49:59 +00:00
* @param User $user Get templates public + limited to this user
2019-02-27 19:45:07 +00:00
* @param Translate $outputlangs Output lang object
* @param int $id Id of template to get, or
* -1 for first found with position 0, or
* 0 for first found whatever is position (priority order depends on lang provided or not) or
* -2 for exact match with label (no answer if not found)
2019-02-27 19:45:07 +00:00
* @param int $active 1=Only active template, 0=Only disabled, -1=All
* @param string $label Label of template to get
* @param int $defaultfortype 1=Only default templates, 0=Only not default, -1=All
2025-10-22 18:06:24 +00:00
* @return ModelMail|CEmailTemplate|int<-1,-1> One instance of CEmailTemplate or < 0 if error
*/
public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '', $defaultfortype = -1)
{
global $conf;
2019-02-27 19:45:07 +00:00
if ($id == -2 && empty($label)) {
$this->error = 'LabelIsMandatoryWhenIdIs-2or-3';
2018-03-16 18:03:16 +00:00
return -1;
}
if ($type_template === 'societe') {
$type_template = 'thirdparty';
}
2025-10-22 18:06:24 +00:00
$ret = new CEmailTemplate($dbs);
$languagetosearch = (is_object($outputlangs) ? $outputlangs->defaultlang : '');
// Define $languagetosearchmain to fall back on main language (for example to get 'es_ES' for 'es_MX')
$tmparray = explode('_', $languagetosearch);
$languagetosearchmain = $tmparray[0].'_'.strtoupper($tmparray[0]);
2021-01-02 15:58:05 +00:00
if ($languagetosearchmain == $languagetosearch) {
$languagetosearchmain = '';
}
2024-07-22 19:49:47 +00:00
$sql = "SELECT rowid, entity, module, label, type_template, topic, email_from, joinfiles, content, content_lines, lang, email_from, email_to, email_tocc, email_tobcc";
2022-03-07 18:37:53 +00:00
$sql .= " FROM ".$dbs->prefix().'c_email_templates';
$sql .= " WHERE (type_template = '".$dbs->escape($type_template)."' OR type_template = '".$dbs->escape($type_template)."_send' OR type_template = 'all')";
$sql .= " AND entity IN (".getEntity('c_email_templates').")";
$sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned
2021-01-12 22:46:29 +00:00
if ($active >= 0) {
2021-06-09 13:36:47 +00:00
$sql .= " AND active = ".((int) $active);
2021-01-12 22:46:29 +00:00
}
if ($defaultfortype >= 0) {
$sql .= " AND defaultfortype = ".((int) $defaultfortype);
}
2021-01-12 22:46:29 +00:00
if ($label) {
2022-03-07 18:37:53 +00:00
$sql .= " AND label = '".$dbs->escape($label)."'";
2021-01-12 22:46:29 +00:00
}
if (!($id > 0) && $languagetosearch) {
2022-03-07 18:37:53 +00:00
$sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')";
2021-01-12 22:46:29 +00:00
}
if ($id > 0) {
2023-03-26 16:48:29 +00:00
$sql .= " AND rowid = ".(int) $id;
2021-01-12 22:46:29 +00:00
}
if ($id == -1) {
2023-03-26 16:48:29 +00:00
$sql .= " AND position = 0";
2021-01-12 22:46:29 +00:00
}
2024-07-22 19:49:47 +00:00
$sql .= " AND entity IN(".getEntity('c_email_templates', 1).")";
2021-01-02 15:58:05 +00:00
if ($languagetosearch) {
2022-03-07 18:37:53 +00:00
$sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or ''
2021-01-02 15:58:05 +00:00
} else {
2022-03-07 18:37:53 +00:00
$sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined
2021-01-02 15:58:05 +00:00
}
2022-03-07 18:37:53 +00:00
//$sql .= $dbs->plimit(1);
//print $sql;
2022-03-07 18:37:53 +00:00
$resql = $dbs->query($sql);
2021-02-28 23:19:52 +00:00
if (!$resql) {
2022-03-07 18:37:53 +00:00
dol_print_error($dbs);
2021-02-28 11:47:24 +00:00
return -1;
}
// Get first found
while (1) {
2022-03-07 18:37:53 +00:00
$obj = $dbs->fetch_object($resql);
if ($obj) {
2021-02-28 11:47:24 +00:00
// If template is for a module, check module is enabled; if not, take next template
if ($obj->module) {
$tempmodulekey = $obj->module;
2023-06-12 18:43:28 +00:00
if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
2021-02-28 11:47:24 +00:00
continue;
}
}
// If a record was found
2025-04-16 19:08:11 +00:00
$ret->id = (int) $obj->rowid;
$ret->module = (string) $obj->module;
$ret->label = (string) $obj->label;
$ret->lang = $obj->lang;
$ret->topic = $obj->topic;
2025-04-16 19:08:11 +00:00
$ret->content = (string) $obj->content;
$ret->content_lines = (string) $obj->content_lines;
$ret->joinfiles = $obj->joinfiles;
2025-04-16 19:08:11 +00:00
$ret->email_from = (string) $obj->email_from;
$ret->email_tocc = (string) $obj->email_tocc;
$ret->email_tobcc = (string) $obj->email_tobcc;
2021-02-28 11:47:24 +00:00
break;
2021-01-12 22:46:29 +00:00
} else {
2021-02-28 11:47:24 +00:00
// If no record found
if ($id == -2) {
// Not found with the provided label
return -1;
} else {
// If there is no template at all
$defaultmessage = '';
2021-02-28 11:47:24 +00:00
if ($type_template == 'body') {
// Special case to use this->withbody as content
2025-04-16 19:08:11 +00:00
$defaultmessage = (string) $this->withbody;
} elseif ($type_template == 'facture_send' || $type_template == 'facture' || $type_template == 'facture_relance') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendInvoice");
} elseif ($type_template == 'propal_send' || $type_template == 'propal') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendProposal");
} elseif ($type_template == 'supplier_proposal_send' || $type_template == 'supplier_proposal') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierProposal");
} elseif ($type_template == 'order_send' || $type_template == 'order') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendOrder");
} elseif ($type_template == 'order_supplier_send' || $type_template == 'order_supplier') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierOrder");
} elseif ($type_template == 'invoice_supplier_send' || $type_template == 'invoice_supplier') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendSupplierInvoice");
} elseif ($type_template == 'shipping_send' || $type_template == 'shipping') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendShipping");
} elseif ($type_template == 'reception_send' || $type_template == 'reception') {
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendReception");
} elseif ($type_template == 'fichinter_send' || $type_template == 'fichinter') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendFichInter");
} elseif ($type_template == 'actioncomm_send' || $type_template == 'actioncomm') {
2021-02-28 11:47:24 +00:00
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentSendActionComm");
} elseif (!empty($type_template)) {
$defaultmessage = $outputlangs->transnoentities("PredefinedMailContentGeneric");
}
2021-02-28 11:47:24 +00:00
$ret->label = 'default';
$ret->lang = $outputlangs->defaultlang;
$ret->topic = '';
$ret->joinfiles = 1;
$ret->content = $defaultmessage;
$ret->content_lines = '';
break;
}
}
}
2021-02-28 11:47:24 +00:00
2022-03-07 18:37:53 +00:00
$dbs->free($resql);
2021-02-28 11:47:24 +00:00
return $ret;
}
2015-04-18 09:06:53 +00:00
/**
* Find if template exists
* Search into table c_email_templates
*
* @param string $type_template Get message for key module
2021-01-02 15:58:05 +00:00
* @param User $user Use template public or limited to this user
2015-04-18 09:06:53 +00:00
* @param Translate $outputlangs Output lang object
2023-12-06 14:46:39 +00:00
* @return int Return integer <0 if KO,
2015-04-18 09:06:53 +00:00
*/
public function isEMailTemplate($type_template, $user, $outputlangs)
{
$sql = "SELECT label, topic, content, lang";
2022-01-27 09:19:35 +00:00
$sql .= " FROM ".$this->db->prefix().'c_email_templates';
$sql .= " WHERE type_template='".$this->db->escape($type_template)."'";
$sql .= " AND entity IN (".getEntity('c_email_templates').")";
$sql .= " AND (fk_user is NULL or fk_user = 0 or fk_user = ".((int) $user->id).")";
2021-01-02 15:58:05 +00:00
if (is_object($outputlangs)) {
$sql .= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')";
}
$sql .= $this->db->order("lang,label", "ASC");
2015-04-18 09:06:53 +00:00
//print $sql;
2015-04-18 09:06:53 +00:00
$resql = $this->db->query($sql);
2021-01-02 15:58:05 +00:00
if ($resql) {
$num = $this->db->num_rows($resql);
2015-04-18 09:06:53 +00:00
$this->db->free($resql);
return $num;
2020-05-21 13:05:19 +00:00
} else {
$this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
2015-04-18 09:06:53 +00:00
return -1;
}
}
2015-04-18 09:06:53 +00:00
/**
Qual: Fix PhanPluginUnknownObjectMethodCall ("part 1") (#30563) * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add typing hint to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add typing hint in phan config to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjectBlock * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjectBlock * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjects * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Fix: MemberNumRefNumbers getExample does not take any arguments Found thanks to adding the typing for phan! * Qual: Correct forced type for $module * Qual: Ignore phan false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Ignore false positive * Qual: phan/Ignore false positive, replace depr.prop with method * Qual: Fix typing for count by adding is_array check * Qual: replace depr.prop `nom` with method * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Fix depr.prop with getter and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: Improve typing for mymodule template * Make info method arguments match calls * Make PrintingDriver abstract class because we added abstract methods * Add phpdoc typing for phan * Update getExample function signature for compatibility * Update getExample function signature for compatibility * Update getExample function signature for compatibility * Update header wit correct information * Update getExample method signature * Update getExample method signature * Correct reference to class in comment * Force php phan typing for numbering modules * Correct $_GLOBALS to $GLOBALS * Add phpdoc to indicat type of properties * Correct default to null * Improve getNextValue typehint * Improve getNextValue typehint * Qual: Improve ModeleNumRefTakepos typing * Qual: Improve ModeleNumRefRecruitmentJobPosition typing * Fix default for $langs * Do not use non-existing ModeleNumRefTakepos::nom * Allow getNextValue argument to be null * Correct $_GLOBAL into $GLOBALS * Improve typing for ldap functions * Allow null for outputlangs argument * Improve typing for printOriginLine * Improve typing for linkedObject access * Fix PhanTypeMismatchArgumentNullableInternal and optimize * Fix PhanPossiblyUndeclaredVariable by setting default value * Ignore PhanPluginDuplicateExpressionAssignmentOperation - needs PHP7.4 * getToolTip does not accept null, changed to '' * Improve getNextValue typing * Change PrintingDriver back to normal class (instantiated) And add errors for functions that should be overloaded * Adjust pringOriginLine typing to match parent * Fix phpdoc for getNextValue * Fix phan typing * Add/Improve phpdoc typing hints * Qual: Adjustments to match typing * Update typing for unit, use GETPOSTINT * ModeleNumRefTask needs Project * Fix several notices appearing after update from develop * Index for choices is int, use GETPOSTINT * Qual: Ignore empty foreach * Force BOMLine on object line * phan typing to indicate that linked objects are BOM * Type the correct variable name (phan) * Add typing for $langs * Type to CommonNumRefGenerator (no class for availabilities) * Resolve several phan notices after update from dev branch * Extra typing fixes * Move common attributes to parent class (phan) * Add typing to Calendar class * Improve typing hints * Add typing to pdf_eagle_proforma * Qual: Add typing for token in generic_oauthcallback.php * Add typing for objMod * Correct getNextValue function signature (phpstan) * Fix typing (phpstan) * Update version declarations (fix phpstan) * Fix phpstan typing issues * Adjust typing (phpstan) * Qual: Update baseline & conf to detect 25% of PhanPluginUnknownObjectMethodCall
2024-08-17 17:32:52 +00:00
* Find if template exists and are available for current user, then set them into $this->lines_model.
* Search in table c_email_templates
2015-04-18 09:06:53 +00:00
*
Qual: Fix PhanPluginUnknownObjectMethodCall ("part 1") (#30563) * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add typing hint to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add typing hint in phan config to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint to fix phan notice. * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjectBlock * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjectBlock * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for linkedObjects * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) # Qual: Fix PhanPluginUnknownObjectMethodCall (add typing hints) Add/improve typing hint for PhanPluginUnknownObjectMethodCall * Fix: MemberNumRefNumbers getExample does not take any arguments Found thanks to adding the typing for phan! * Qual: Correct forced type for $module * Qual: Ignore phan false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Ignore false positive * Qual: phan/Ignore false positive, replace depr.prop with method * Qual: Fix typing for count by adding is_array check * Qual: replace depr.prop `nom` with method * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Fix depr.prop with getter and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: phan/Correct module type and ignore false positive * Qual: Improve typing for mymodule template * Make info method arguments match calls * Make PrintingDriver abstract class because we added abstract methods * Add phpdoc typing for phan * Update getExample function signature for compatibility * Update getExample function signature for compatibility * Update getExample function signature for compatibility * Update header wit correct information * Update getExample method signature * Update getExample method signature * Correct reference to class in comment * Force php phan typing for numbering modules * Correct $_GLOBALS to $GLOBALS * Add phpdoc to indicat type of properties * Correct default to null * Improve getNextValue typehint * Improve getNextValue typehint * Qual: Improve ModeleNumRefTakepos typing * Qual: Improve ModeleNumRefRecruitmentJobPosition typing * Fix default for $langs * Do not use non-existing ModeleNumRefTakepos::nom * Allow getNextValue argument to be null * Correct $_GLOBAL into $GLOBALS * Improve typing for ldap functions * Allow null for outputlangs argument * Improve typing for printOriginLine * Improve typing for linkedObject access * Fix PhanTypeMismatchArgumentNullableInternal and optimize * Fix PhanPossiblyUndeclaredVariable by setting default value * Ignore PhanPluginDuplicateExpressionAssignmentOperation - needs PHP7.4 * getToolTip does not accept null, changed to '' * Improve getNextValue typing * Change PrintingDriver back to normal class (instantiated) And add errors for functions that should be overloaded * Adjust pringOriginLine typing to match parent * Fix phpdoc for getNextValue * Fix phan typing * Add/Improve phpdoc typing hints * Qual: Adjustments to match typing * Update typing for unit, use GETPOSTINT * ModeleNumRefTask needs Project * Fix several notices appearing after update from develop * Index for choices is int, use GETPOSTINT * Qual: Ignore empty foreach * Force BOMLine on object line * phan typing to indicate that linked objects are BOM * Type the correct variable name (phan) * Add typing for $langs * Type to CommonNumRefGenerator (no class for availabilities) * Resolve several phan notices after update from dev branch * Extra typing fixes * Move common attributes to parent class (phan) * Add typing to Calendar class * Improve typing hints * Add typing to pdf_eagle_proforma * Qual: Add typing for token in generic_oauthcallback.php * Add typing for objMod * Correct getNextValue function signature (phpstan) * Fix typing (phpstan) * Update version declarations (fix phpstan) * Fix phpstan typing issues * Adjust typing (phpstan) * Qual: Update baseline & conf to detect 25% of PhanPluginUnknownObjectMethodCall
2024-08-17 17:32:52 +00:00
* @param string $type_template Get message for key module
* @param User $user Use template public or limited to this user
* @param ?Translate $outputlangs Output lang object
* @param int<-1,1> $active 1=Only active template, 0=Only disabled, -1=All
* @return int<-1,max> Return integer <0 if KO, nb of records found if OK
2015-04-18 09:06:53 +00:00
*/
public function fetchAllEMailTemplate($type_template, $user, $outputlangs, $active = 1)
2015-04-18 09:06:53 +00:00
{
2024-07-23 07:25:23 +00:00
global $db, $conf;
2021-02-28 11:47:24 +00:00
$sql = "SELECT rowid, module, label, topic, content, content_lines, lang, fk_user, private, position";
2022-01-27 09:19:35 +00:00
$sql .= " FROM ".$this->db->prefix().'c_email_templates';
$sql .= " WHERE type_template IN ('".$this->db->escape($type_template)."', 'all')";
$sql .= " AND entity IN (".getEntity('c_email_templates').")";
$sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // See all public templates or templates I own.
2021-01-02 15:58:05 +00:00
if ($active >= 0) {
2021-06-09 13:36:47 +00:00
$sql .= " AND active = ".((int) $active);
2021-01-02 15:58:05 +00:00
}
2020-09-19 19:19:04 +00:00
//if (is_object($outputlangs)) $sql.= " AND (lang = '".$this->db->escape($outputlangs->defaultlang)."' OR lang IS NULL OR lang = '')"; // Return all languages
$sql .= $this->db->order("lang,position,label", "ASC");
2015-04-18 09:06:53 +00:00
//print $sql;
2015-04-18 09:06:53 +00:00
$resql = $this->db->query($sql);
2021-01-02 15:58:05 +00:00
if ($resql) {
$num = $this->db->num_rows($resql);
$this->lines_model = array();
2021-01-02 15:58:05 +00:00
while ($obj = $this->db->fetch_object($resql)) {
2021-02-28 11:47:24 +00:00
// If template is for a module, check module is enabled.
if ($obj->module) {
$tempmodulekey = $obj->module;
2023-06-12 18:43:28 +00:00
if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
2021-02-28 11:47:24 +00:00
continue;
}
}
2025-10-22 18:06:24 +00:00
$line = new CEmailTemplate($db);
2025-04-16 19:08:11 +00:00
$line->id = (int) $obj->rowid;
$line->label = (string) $obj->label;
$line->lang = $obj->lang;
$line->fk_user = $obj->fk_user;
$line->private = $obj->private;
$line->position = $obj->position;
$line->topic = $obj->topic;
$line->content = $obj->content;
$line->content_lines = $obj->content_lines;
$this->lines_model[] = $line;
2015-04-18 09:06:53 +00:00
}
$this->db->free($resql);
return $num;
2020-05-21 13:05:19 +00:00
} else {
$this->error = get_class($this).' '.__METHOD__.' ERROR:'.$this->db->lasterror();
2015-04-18 09:06:53 +00:00
return -1;
}
}
/**
* Normalize a text for equality checks.
* @param string $value Raw text to normalize.
* @return string
*/
private static function normalizeTextForComparison($value)
{
$value = dol_string_nohtmltag((string) $value);
$value = preg_replace('/\s+/', ' ', $value);
return trim((string) $value);
}
/**
* Return language prefix from a language code.
* @param string $langcode Full language code (for example fr_FR).
* @return string
*/
private static function getLangPrefix($langcode)
{
$langcode = trim((string) $langcode);
if ($langcode === '') {
return '';
}
$prefix = preg_replace('/[_-].*$/', '', $langcode);
$prefix = strtolower((string) $prefix);
return preg_replace('/[^a-z]/', '', $prefix);
}
/**
* Pick best translated label/description from product multilangs.
*
* @param array<string,array{label?:string,description?:string,note?:string,other?:string}>|null $multilangs Product multilang rows indexed by language code.
* @param string $langcode Preferred language code.
* @return array{label:string,description:string}
*/
private static function getBestProductTranslation($multilangs, $langcode)
{
$langcode = trim((string) $langcode);
if ($langcode === '' || !is_array($multilangs) || empty($multilangs)) {
return array('label' => '', 'description' => '');
}
$prefix = self::getLangPrefix($langcode);
$candidates = array($langcode);
if ($prefix !== '' && $prefix !== $langcode) {
$candidates[] = $prefix;
}
foreach ($candidates as $candidate) {
if (empty($multilangs[$candidate]) || !is_array($multilangs[$candidate])) {
continue;
}
$label = trim((string) (isset($multilangs[$candidate]['label']) ? $multilangs[$candidate]['label'] : ''));
$description = trim((string) (isset($multilangs[$candidate]['description']) ? $multilangs[$candidate]['description'] : ''));
if ($label !== '' || $description !== '') {
return array('label' => $label, 'description' => $description);
}
}
if ($prefix !== '') {
foreach ($multilangs as $code => $row) {
if (!is_array($row)) {
continue;
}
if (!(strpos($code, $prefix.'_') === 0 || strpos($code, $prefix.'-') === 0)) {
continue;
}
$label = trim((string) (isset($row['label']) ? $row['label'] : ''));
$description = trim((string) (isset($row['description']) ? $row['description'] : ''));
if ($label !== '' || $description !== '') {
return array('label' => $label, 'description' => $description);
}
}
}
return array('label' => '', 'description' => '');
}
/**
* Set ->substit (and ->substit_line) array from object. This is call when suggesting the email template into forms before sending email.
* @param CommonObject $object Object to use
* @param Translate $outputlangs Object lang
* @return void
* @see getCommonSubstitutionArray()
*/
2019-02-27 19:45:07 +00:00
public function setSubstitFromObject($object, $outputlangs)
{
global $extrafields;
$parameters = array();
$tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
complete_substitutions_array($tmparray, $outputlangs, null, $parameters);
$this->substit = $tmparray;
$targetLang = '';
if (is_object($outputlangs) && !empty($outputlangs->defaultlang)) {
$targetLang = trim((string) $outputlangs->defaultlang);
}
// Fill substit_lines with each object lines content
2021-01-02 15:58:05 +00:00
if (is_array($object->lines)) {
foreach ($object->lines as $line) {
$substit_line = array(
'__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '',
'__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '',
'__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '',
'__LABEL__' => isset($line->label) ? $line->label : '',
'__DESCRIPTION__' => isset($line->desc) ? $line->desc : '',
'__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', false, $outputlangs),
'__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', false, $outputlangs),
'__QUANTITY__' => $line->qty,
'__SUBPRICE__' => price($line->subprice),
'__AMOUNT__' => price($line->total_ttc),
2018-04-11 15:14:34 +00:00
'__AMOUNT_EXCL_TAX__' => price($line->total_ht)
);
// Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__
2021-01-02 15:58:05 +00:00
if (!empty($line->fk_product)) {
2021-01-16 13:12:09 +00:00
if (!is_object($extrafields)) {
$extrafields = new ExtraFields($this->db);
}
$product = new Product($this->db);
$product->fetch($line->fk_product, '', '', '1');
2018-02-21 13:48:25 +00:00
$product->fetch_optionals();
if (getDolGlobalInt('MAIN_MULTILANGS') && $targetLang !== '' && !empty($product->multilangs) && is_array($product->multilangs)) {
$translated = self::getBestProductTranslation($product->multilangs, $targetLang);
$translatedLabel = trim((string) (isset($translated['label']) ? $translated['label'] : ''));
$translatedDescription = trim((string) (isset($translated['description']) ? $translated['description'] : ''));
$currentLabelNorm = self::normalizeTextForComparison($substit_line['__PRODUCT_LABEL__']);
$currentProductDescriptionNorm = self::normalizeTextForComparison($substit_line['__PRODUCT_DESCRIPTION__']);
$currentLineDescriptionNorm = self::normalizeTextForComparison($substit_line['__DESCRIPTION__']);
$productLabelNorm = self::normalizeTextForComparison($product->label);
$productDescriptionNorm = self::normalizeTextForComparison($product->description);
if ($translatedLabel !== '' && ($currentLabelNorm === '' || $currentLabelNorm === $productLabelNorm)) {
$substit_line['__PRODUCT_LABEL__'] = $translatedLabel;
}
if ($translatedDescription !== '' && ($currentProductDescriptionNorm === '' || $currentProductDescriptionNorm === $productDescriptionNorm)) {
$substit_line['__PRODUCT_DESCRIPTION__'] = $translatedDescription;
}
if ($translatedDescription !== '' && ($currentLineDescriptionNorm === '' || $currentLineDescriptionNorm === $productDescriptionNorm || $currentLineDescriptionNorm === $currentProductDescriptionNorm)) {
$substit_line['__DESCRIPTION__'] = $translatedDescription;
}
}
$extrafields->fetch_name_optionals_label($product->table_element, true);
2022-06-09 13:13:29 +00:00
if (!empty($extrafields->attributes[$product->table_element]['label']) && is_array($extrafields->attributes[$product->table_element]['label']) && count($extrafields->attributes[$product->table_element]['label']) > 0) {
2018-04-13 14:18:33 +00:00
foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) {
2022-07-04 13:50:41 +00:00
$substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = isset($product->array_options['options_'.$key]) ? $product->array_options['options_'.$key] : '';
2018-04-13 14:18:33 +00:00
}
}
}
2024-10-13 23:15:54 +00:00
2024-10-13 23:21:40 +00:00
$this->substit_lines[$line->id] = $substit_line; // @phan-suppress-current-line PhanTypeMismatchProperty
}
}
}
/**
2017-09-16 07:15:10 +00:00
* Get list of substitution keys available for emails. This is used for tooltips help.
* This include the complete_substitutions_array.
* @param string $mode 'formemail', 'formemailwithlines', 'formemailforlines', 'emailing', ...
* @param ?Object $object Object if applicable
* @return array<string,string> Array of substitution values for emails.
*/
2019-02-27 19:45:07 +00:00
public static function getAvailableSubstitKey($mode = 'formemail', $object = null)
{
global $langs;
$tmparray = array();
2021-01-02 15:58:05 +00:00
if ($mode == 'formemail' || $mode == 'formemailwithlines' || $mode == 'formemailforlines') {
2024-03-12 23:29:33 +00:00
$parameters = array('mode' => $mode);
2026-03-30 09:07:47 +00:00
$tmparray = getCommonSubstitutionArray($langs, 2, null, $object); // Note: On email template creation, this may be null because it is related to all type of objects
complete_substitutions_array($tmparray, $langs, null, $parameters);
2021-01-02 15:58:05 +00:00
if ($mode == 'formwithlines') {
$tmparray['__LINES__'] = '__LINES__'; // Will be set by the get_form function
}
2021-01-02 15:58:05 +00:00
if ($mode == 'formforlines') {
$tmparray['__QUANTITY__'] = '__QUANTITY__'; // Will be set by the get_form function
}
}
2021-01-02 15:58:05 +00:00
if ($mode == 'emailing') {
2024-03-12 23:29:33 +00:00
$parameters = array('mode' => $mode);
2026-03-30 09:07:47 +00:00
$tmparray = getCommonSubstitutionArray($langs, 2, array('object', 'objectamount'), $object); // Note: On email template creation, this may be null because it is related to all type of objects
complete_substitutions_array($tmparray, $langs, null, $parameters);
// For mass emailing, we have different keys specific to the data into tagerts list
$tmparray['__ID__'] = 'IdRecord';
$tmparray['__EMAIL__'] = 'EMailRecipient';
$tmparray['__LASTNAME__'] = 'Lastname';
$tmparray['__FIRSTNAME__'] = 'Firstname';
$tmparray['__MAILTOEMAIL__'] = 'TagMailtoEmail';
$tmparray['__OTHER1__'] = 'Other1';
$tmparray['__OTHER2__'] = 'Other2';
$tmparray['__OTHER3__'] = 'Other3';
$tmparray['__OTHER4__'] = 'Other4';
$tmparray['__OTHER5__'] = 'Other5';
2025-06-02 19:10:45 +00:00
$tmparray['__THIRDPARTY_CUSTOMER_CODE__'] = 'CustomerCode'; // If source is a thirdparty
2024-02-07 11:28:35 +00:00
$tmparray['__CHECK_READ__'] = $langs->trans('TagCheckMail');
$tmparray['__UNSUBSCRIBE__'] = $langs->trans('TagUnsubscribe');
$tmparray['__UNSUBSCRIBE_URL__'] = $langs->trans('TagUnsubscribe').' (URL)';
$onlinepaymentenabled = 0;
2022-09-25 19:58:40 +00:00
if (isModEnabled('paypal')) {
2021-01-16 13:12:09 +00:00
$onlinepaymentenabled++;
}
2022-09-25 19:58:40 +00:00
if (isModEnabled('stripe')) {
2021-01-16 13:12:09 +00:00
$onlinepaymentenabled++;
}
2023-11-27 10:24:19 +00:00
if ($onlinepaymentenabled && getDolGlobalString('PAYMENT_SECURITY_TOKEN')) {
2024-01-05 03:18:53 +00:00
$tmparray['__SECUREKEYPAYMENT__'] = getDolGlobalString('PAYMENT_SECURITY_TOKEN');
if (isModEnabled('member')) {
$tmparray['__SECUREKEYPAYMENT_MEMBER__'] = 'SecureKeyPAYMENTUniquePerMember';
}
if (isModEnabled('don')) {
$tmparray['__SECUREKEYPAYMENT_DONATION__'] = 'SecureKeyPAYMENTUniquePerDonation';
}
if (isModEnabled('invoice')) {
$tmparray['__SECUREKEYPAYMENT_INVOICE__'] = 'SecureKeyPAYMENTUniquePerInvoice';
}
if (isModEnabled('order')) {
$tmparray['__SECUREKEYPAYMENT_ORDER__'] = 'SecureKeyPAYMENTUniquePerOrder';
}
if (isModEnabled('contract')) {
$tmparray['__SECUREKEYPAYMENT_CONTRACTLINE__'] = 'SecureKeyPAYMENTUniquePerContractLine';
}
2021-05-03 23:53:46 +00:00
//Online payment link
if (isModEnabled('member')) {
$tmparray['__ONLINEPAYMENTLINK_MEMBER__'] = 'OnlinePaymentLinkUniquePerMember';
}
if (isModEnabled('don')) {
$tmparray['__ONLINEPAYMENTLINK_DONATION__'] = 'OnlinePaymentLinkUniquePerDonation';
}
if (isModEnabled('invoice')) {
$tmparray['__ONLINEPAYMENTLINK_INVOICE__'] = 'OnlinePaymentLinkUniquePerInvoice';
}
if (isModEnabled('order')) {
$tmparray['__ONLINEPAYMENTLINK_ORDER__'] = 'OnlinePaymentLinkUniquePerOrder';
}
if (isModEnabled('contract')) {
$tmparray['__ONLINEPAYMENTLINK_CONTRACTLINE__'] = 'OnlinePaymentLinkUniquePerContractLine';
}
2020-05-21 13:05:19 +00:00
} else {
/* No need to show into tooltip help, option is not enabled
$vars['__SECUREKEYPAYMENT__']='';
$vars['__SECUREKEYPAYMENT_MEMBER__']='';
$vars['__SECUREKEYPAYMENT_INVOICE__']='';
$vars['__SECUREKEYPAYMENT_ORDER__']='';
$vars['__SECUREKEYPAYMENT_CONTRACTLINE__']='';
*/
}
2023-11-27 10:24:19 +00:00
if (getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
2024-02-07 11:28:35 +00:00
$tmparray['__PUBLICLINK_NEWMEMBERFORM__'] = 'BlankSubscriptionForm';
2021-05-07 15:14:33 +00:00
}
}
2021-01-02 15:58:05 +00:00
foreach ($tmparray as $key => $val) {
2021-01-16 13:12:09 +00:00
if (empty($val)) {
$tmparray[$key] = $key;
}
}
return $tmparray;
}
2015-04-18 09:06:53 +00:00
}