dolibarr/htdocs/admin/mails_templates.php
MDW f551727df9
Qual/Sec: Use db->sanitize instead of db->escape when not quoted, fix some quoting (#39286)
* FIX phpstan: Societe::$client (int<0,3>) does not accept -1 (#39244)

Societe::$client is annotated @var int<0,3> (domain 0=no customer,
1=customer, 2=prospect, 3=both) in societe.class.php, but the create
form in societe/card.php pre-set it to -1 as a transient "nothing
pre-selected" placeholder, tripping PHPStan level 10 on develop.

The value is never persisted (save paths compute 0..3) and the only
reader, the switch() building the form, treats -1 and 0 identically via
its default case. Use 0 (the property's own default) so the assignment
matches the declared type. No behavior change.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* Qual: Fix entity handling in bonprelevement.class.php

The variable name 'entities' was changed to 'entity' to better reflect the singular nature of the value being retrieved.
It was also casted to an int instead of using an unquoted db->escape.

* Qual: Improve SQL query construction in company.lib.php

By escaping the concatenated string, injection verification does not identify a false positive.

* Qual: Avoid void positive, sanitize instead of escape

* Qual: Avoid false positive, sanitize instead of escape

* Sec: Fix potential injection with cast to int (timespent_duration)

* Qual: Avoid false positive, sanitize instead of escape

* Qual: Avoid false positive, sanitize instead of escape

* fix: Replace escape() with sanitize() in SQL queries

# FIX: Replace escape() with sanitize() in SQL queries

- Replace escape() with sanitize() in SQL queries to ensure proper SQL injection protection
- Update SQL queries in multiple files to use sanitize() instead of escape()
- Ensure consistent use of sanitize() across the codebase for better security

* fix(sql): Replace escape with sanitize in SQL queries

# FIX: Replace escape with sanitize in SQL queries

- Replace `escape` with `sanitize` in SQL queries to ensure proper SQL injection prevention

* Qual: Improve field escaping/quoting

# Qual: Qual: Improve field escaping/quoting

---------

Co-authored-by: Jam Balaya <jambalaya.pyoncafe@outlook.jp>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 13:00:33 +02:00

1647 lines
61 KiB
PHP

<?php
/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2016 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2011-2018 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2011 Remy Younes <ryounes@gmail.com>
* Copyright (C) 2012-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@ltairis.fr>
* Copyright (C) 2011-2016 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2015-2024 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2025 Vincent Maury <vmaury@timgroup.fr>
* Copyright (C) 2025 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
*
* 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
* (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
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/admin/mails_templates.php
* \ingroup core
* \brief Page to administer emails templates
*/
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/cemailtemplate.class.php';
// Load translation files required by the page
$langsArray = array("errors", "admin", "mails", "languages");
if (isModEnabled('member')) {
$langsArray[] = 'members';
}
if (isModEnabled('eventorganization')) {
$langsArray[] = 'eventorganization';
}
$langs->loadLangs($langsArray);
$toselect = GETPOST('toselect', 'array:int');
$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
$massaction = GETPOST('massaction', 'alpha');
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
$mode = GETPOST('mode', 'aZ09');
$optioncss = GETPOST('optioncss', 'alpha');
$backtopage = GETPOST('backtopage');
$contextpage = GETPOST('contextpage', 'aZ09');
$rowid = (GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('rowid'));
$search_label = GETPOST('search_label', 'alphanohtml'); // Must allow value like 'Abc Def' or '(MyTemplateName)'
$search_type_template = GETPOST('search_type_template', 'alpha');
$search_lang = GETPOST('search_lang', 'alpha');
$search_fk_user = GETPOST('search_fk_user', 'intcomma');
$search_topic = GETPOST('search_topic', 'alpha');
$search_module = GETPOST('search_module', 'alpha');
$acts = array();
$actl = array();
$acts[0] = "activate";
$acts[1] = "disable";
$actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
$actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
if (empty($page) || $page == -1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (empty($sortfield)) {
$sortfield = 'type_template,lang,position,label';
}
if (empty($sortorder)) {
$sortorder = 'ASC';
}
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('emailtemplates'));
$object = new CEmailTemplate($db);
// Definition of array of fields for columns from ->fields
$tableprefix = 't';
$arrayfields = array();
foreach ($object->fields as $key => $val) {
// If $val['visible']==0, then we never show the field
if (!empty($val['visible'])) {
$visible = (int) dol_eval((string) $val['visible'], 1);
$arrayfields[$tableprefix.'.'.$key] = array(
'label' => $val['label'],
'checked' => (($visible < 0) ? '0' : '1'),
'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
'position' => $val['position'],
'help' => isset($val['help']) ? $val['help'] : ''
);
}
}
// Security
if (!empty($user->socid)) {
accessforbidden();
}
$permissiontoadd = 1;
$permissiontoedit = ($user->admin ? 1 : 0);
$permissiontodelete = ($user->admin ? 1 : 0);
$tmpmailtemplate = new CEmailTemplate($db);
if ($rowid > 0) {
$result = $tmpmailtemplate->fetch($rowid);
if ($tmpmailtemplate->fk_user == $user->id) {
$permissiontoedit = 1;
$permissiontodelete = 1;
}
}
// Old way to define field.
// Name of SQL tables of dictionaries
$tabname = array();
$tabname[25] = MAIN_DB_PREFIX."c_email_templates";
// Nom des champs en resultat de select pour affichage du dictionnaire
// Names of fields in select results for dictionary display (AI translated)
$tabfield = array();
$tabfield[25] = "label,lang,type_template,fk_user,position,module,topic,joinfiles,defaultfortype,content";
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$tabfield[25] .= ',content_lines';
}
// Nom des champs d'edition pour modification d'un enregistrement
// Names of edit fields for modifying a record (AI translated)
$tabfieldvalue = array();
$tabfieldvalue[25] = "label,lang,type_template,fk_user,private,position,topic,email_from,joinfiles,defaultfortype,content";
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$tabfieldvalue[25] .= ',content_lines';
}
// Nom des champs dans la table pour insertion d'un enregistrement
// Field names in the table for inserting a record (AI translated)
$tabfieldinsert = array();
$tabfieldinsert[25] = "label,lang,type_template,fk_user,private,position,topic,email_from,joinfiles,defaultfortype,content,datec";
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$tabfieldinsert[25] .= ',content_lines';
}
$tabfieldinsert[25] .= ',entity'; // Must be at end because not into other arrays
// List of help for fields
// Set MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES to allow edit of template for lines
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
if (!getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$targetobject = fetchObjectByElement(0, $tmpmailtemplate->type_template);
$tmp = FormMail::getAvailableSubstitKey('formemail', $targetobject);
$tmp['__(AnyTranslationKey)__'] = 'Translation';
$helpsubstit = $langs->trans("AvailableVariables").':<br>';
$helpsubstitforlines = $langs->trans("AvailableVariables").':<br>';
foreach ($tmp as $key => $val) {
$helpsubstit .= $key.' -> '.$val.'<br>';
$helpsubstitforlines .= $key.' -> '.$val.'<br>';
}
} else {
$targetobject = fetchObjectByElement(0, $tmpmailtemplate->type_template);
$tmp = FormMail::getAvailableSubstitKey('formemailwithlines', $targetobject);
$tmp['__(AnyTranslationKey)__'] = 'Translation';
$helpsubstit = $langs->trans("AvailableVariables").':<br>';
$helpsubstitforlines = $langs->trans("AvailableVariables").':<br>';
foreach ($tmp as $key => $val) {
$helpsubstit .= $key.' -> '.$val.'<br>';
}
$tmp = FormMail::getAvailableSubstitKey('formemailforlines');
foreach ($tmp as $key => $val) {
$helpsubstitforlines .= $key.' -> '.$val.'<br>';
}
}
$tabhelp = array();
$tabhelp[25] = array(
'label' => $langs->trans('EnterAnyCode'),
'type_template' => $langs->trans("TemplateForElement"),
'private' => $langs->trans("TemplateIsVisibleByOwnerOnly"),
'position' => $langs->trans("PositionIntoComboList"),
'topic' => '<span class="small">'.$helpsubstit.'</span>',
'email_from' => $langs->trans('ForceEmailFrom'),
'joinfiles' => $langs->trans('AttachMainDocByDefault'),
'defaultfortype' => $langs->trans("DefaultForTypeDesc"),
'content' => '<span class="small">'.$helpsubstit.'</span>',
'content_lines' => '<span class="small">'.$helpsubstitforlines.'</span>'
);
// We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']"
$elementList = array();
// Add all and none after the sort
$elementList['all'] = '-- '.dol_escape_htmltag($langs->trans("All")).' --';
$elementList['none'] = '-- '.dol_escape_htmltag($langs->trans("None")).' --';
$elementList['user'] = img_picto('', 'user', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToUser'));
if (isModEnabled('member') && $user->hasRight('adherent', 'lire')) {
$elementList['member'] = img_picto('', 'object_member', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToMember'));
}
if (isModEnabled('recruitment') && $user->hasRight('recruitment', 'recruitmentjobposition', 'read')) {
$elementList['recruitmentcandidature_send'] = img_picto('', 'recruitmentcandidature', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('RecruitmentCandidatures'));
}
if (isModEnabled('expensereport') && $user->hasRight('expensereport', 'lire')) {
$elementList['expensereport_send'] = img_picto('', 'trip', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendExpenseReport'));
}
if (isModEnabled('holiday') && $user->hasRight('holiday', 'read')) {
$elementList['holiday'] = img_picto('', 'holiday', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendLeaves'));
}
if (isModEnabled("societe") && $user->hasRight('societe', 'lire')) {
$elementList['thirdparty'] = img_picto('', 'company', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToThirdparty'));
}
if (isModEnabled("societe") && $user->hasRight('societe', 'contact', 'lire')) {
$elementList['contact'] = img_picto('', 'contact', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToContact'));
}
if (isModEnabled('project')) {
$elementList['project'] = img_picto('', 'project', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToProject'));
}
if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
$elementList['propal_send'] = img_picto('', 'propal', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendProposal'));
}
if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
$elementList['order_send'] = img_picto('', 'order', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendOrder'));
}
if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
$elementList['facture_send'] = img_picto('', 'bill', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendInvoice'));
}
if (isModEnabled("shipping")) {
$elementList['shipping_send'] = img_picto('', 'dolly', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendShipment'));
$elementList['delivery_send'] = img_picto('', 'dolly', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendDelivery'));
}
if (isModEnabled("reception")) {
$elementList['reception_send'] = img_picto('', 'dollyrevert', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendReception'));
}
if (isModEnabled('intervention')) {
$elementList['fichinter_send'] = img_picto('', 'intervention', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendIntervention'));
}
if (isModEnabled('supplier_proposal')) {
$elementList['supplier_proposal_send'] = img_picto('', 'propal', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierRequestForQuotation'));
}
if (isModEnabled("supplier_order") && ($user->hasRight('fournisseur', 'commande', 'lire') || $user->hasRight('supplier_order', 'read'))) {
$elementList['order_supplier_send'] = img_picto('', 'order', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierOrder'));
}
if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'lire') || $user->hasRight('supplier_invoice', 'read'))) {
$elementList['invoice_supplier_send'] = img_picto('', 'bill', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendSupplierInvoice'));
}
if (isModEnabled("supplier_invoice") && ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "write"))) {
$elementList['supplier_payment_send'] = img_picto('', 'bill', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('SuppliersPayment'));
}
if (isModEnabled('contract') && $user->hasRight('contrat', 'lire')) {
$elementList['contract'] = img_picto('', 'contract', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendContract'));
}
if (isModEnabled('ticket') && $user->hasRight('ticket', 'read')) {
$elementList['ticket_send'] = img_picto('', 'ticket', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToTicket'));
}
if (isModEnabled('agenda')) {
$elementList['actioncomm_send'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventPush'));
}
if (isModEnabled('eventorganization') && $user->hasRight('project', 'read')) {
$elementList['conferenceorbooth'] = img_picto('', 'action', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToSendEventOrganization'));
}
if (isModEnabled('partnership') && $user->hasRight('partnership', 'read')) {
$elementList['partnership_send'] = img_picto('', 'partnership', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('MailToPartnership'));
}
if (isModEnabled('product') && $user->hasRight('produit', 'lire')) {
$elementList['product_send'] = img_picto('', 'product', 'class="pictofixedwidth"').dol_escape_htmltag($langs->trans('Product'));
}
if (isModEnabled('stocktransfer')) {
$elementList['stocktransfer_send'] = '<span class="fas fa-box-open em080 valignmiddle pictomodule paddingrightonly" style="color: #a69944;"></span>'.dol_escape_htmltag($langs->trans('MailToSendStockTransfer'));
}
$parameters = array('elementList' => $elementList);
$reshook = $hookmanager->executeHooks('emailElementlist', $parameters); // Note that $action and $object may have been modified by some hooks
if ($reshook == 0) {
foreach ($hookmanager->resArray as $item => $value) {
$elementList[$item] = $value;
}
}
$error = 0;
$acceptlocallinktomedia = (acceptLocalLinktoMedia() > 0 ? 1 : 0);
/*
* Actions
*/
if (GETPOST('cancel', 'alpha') || GETPOST('actioncancel', 'alpha')) {
$action = 'list';
$massaction = '';
if (!empty($backtopage)) {
header("Location: ".$backtopage);
exit(1);
}
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
$massaction = '';
}
$parameters = array();
$object = null;
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
// Selection of new fields
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
// All tests are required to be compatible with all browsers
$search_label = '';
$search_type_template = '';
$search_lang = '';
$search_fk_user = '';
$search_topic = '';
$search_module = '';
$toselect = array();
$search_array_options = array();
}
// Actions add or modify an email template
if ((GETPOST('actionadd', 'alpha') && $permissiontoadd) || (GETPOST('actionmodify', 'alpha') && $permissiontoedit)) {
$listfield = explode(',', str_replace(' ', '', $tabfield[25]));
$listfieldinsert = explode(',', $tabfieldinsert[25]);
$listfieldmodify = explode(',', $tabfieldvalue[25]);
$listfieldvalue = explode(',', $tabfieldvalue[25]);
// Check that all fields are filled
$ok = 1;
foreach ($listfield as $f => $value) {
// Not mandatory fields
if (in_array($value, ['joinfiles', 'defaultfortype', 'content', 'content_lines', 'module', 'tms', 'datec'])) {
continue;
}
// Rename some POST variables into a generic name
if (GETPOST('actionmodify', 'alpha') && $value == 'topic') {
$_POST['topic'] = GETPOST('topic-'.$rowid);
}
if ((!GETPOSTISSET($value) || GETPOST($value) == '' || GETPOST($value) == '-1') && $value != 'lang' && $value != 'fk_user' && $value != 'position') {
$ok = 0;
$fieldnamekey = $listfield[$f];
// We take translate key of field
if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) {
$fieldnamekey = 'Code';
}
if ($fieldnamekey == 'code') {
$fieldnamekey = 'Code';
}
if ($fieldnamekey == 'note') {
$fieldnamekey = 'Note';
}
if ($fieldnamekey == 'type_template') {
$fieldnamekey = 'TypeOfTemplate';
}
if ($fieldnamekey == 'fk_user') {
$fieldnamekey = 'Owner';
}
if ($fieldnamekey == 'private') {
$fieldnamekey = 'Private';
}
if ($fieldnamekey == 'position') {
$fieldnamekey = 'Position';
}
if ($fieldnamekey == 'topic') {
$fieldnamekey = 'Topic';
}
setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
$action = 'create';
}
}
// If previous test is ok action is add, we add the line
if ($ok && GETPOST('actionadd')) {
// Add new entry
$sql = "INSERT INTO ".$db->sanitize($tabname[25])." (";
// List of fields
$sql .= $tabfieldinsert[25];
$sql .= ", active, enabled)";
$sql .= " VALUES(";
// List of values
$i = 0;
$now = dol_now();
foreach ($listfieldinsert as $f => $value) {
$keycode = isset($listfieldvalue[$i]) ? $listfieldvalue[$i] : "";
if ($value == 'lang') {
$keycode = 'langcode';
}
if (empty($keycode)) {
$keycode = $value;
}
// Clean input variables
if ($value == 'entity') {
$_POST[$keycode] = $conf->entity;
}
if ($value == 'fk_user' && !($_POST[$keycode] > 0)) {
$_POST[$keycode] = '';
}
if ($value == 'private' && !is_numeric($_POST[$keycode])) {
$_POST[$keycode] = '0';
}
if ($value == 'position' && !is_numeric($_POST[$keycode])) {
$_POST[$keycode] = '1';
}
if ($value == 'defaultfortype' && !is_numeric($_POST[$keycode])) {
$_POST[$keycode] = '0';
}
//var_dump($keycode.' '.$value);
if ($i) {
$sql .= ", ";
}
if ($keycode == 'datec') {
$sql .= "'".$db->idate($now)."'";
} elseif (GETPOST($keycode) == '' && $keycode != 'langcode') {
$sql .= "null"; // langcode must be '' if not defined so the unique key that include lang will work
} elseif (GETPOST($keycode) == '0' && $keycode == 'langcode') {
$sql .= "''"; // langcode must be '' if not defined so the unique key that include lang will work
} elseif ($keycode == 'fk_user') {
if (!$user->admin) { // A non admin user can only edit its own template
$sql .= " ".((int) $user->id);
} else {
$sql .= " ".(GETPOSTINT($keycode));
}
} elseif ($keycode == 'content') {
$sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'";
} elseif (in_array($keycode, array('joinfiles', 'defaultfortype', 'private', 'position', 'entity'))) {
$sql .= GETPOSTINT($keycode);
} else {
$sql .= "'".$db->escape(GETPOST($keycode, 'alphanohtml'))."'";
}
$i++;
}
$sql .= ", 1, 1)";
dol_syslog("actionadd", LOG_DEBUG);
$result = $db->query($sql);
if ($result) { // Add is ok
setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
$_POST = array('id' => 25); // Clean $_POST array, we keep only id
if (!empty($backtopage)) {
header("Location: ".$backtopage);
exit(1);
}
} else {
if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
} else {
dol_print_error($db);
}
$action = 'create';
}
}
// We modify the line
if ($ok && GETPOST('actionmodify')) {
$rowidcol = "rowid";
if (GETPOSTINT('fk_user') <= 0 && GETPOST('private')) {
setEventMessages($langs->trans("AnOwnerMustBeSetIfEmailTemplateIsPrivate"), null, 'errors');
$error++;
$action = 'edit';
}
if (!$error) {
// Modify entry
$sql = "UPDATE ".$db->sanitize($tabname[25])." SET ";
// Modify value of fields
$i = 0;
foreach ($listfieldmodify as $field) {
if ($field == 'entity') {
// entity not present on listfieldmodify array
$keycode = $field;
$_POST[$keycode] = $conf->entity;
} else {
$keycode = $listfieldvalue[$i];
}
if ($field == 'lang') {
$keycode = 'langcode';
}
if (empty($keycode)) {
$keycode = $field;
}
// Rename some POST variables into a generic name
if ($field == 'topic') {
$_POST['topic'] = GETPOST('topic-'.$rowid);
}
if ($field == 'joinfiles') {
$_POST['joinfiles'] = GETPOST('joinfiles-'.$rowid);
}
if ($field == 'content') {
$_POST['content'] = GETPOST('content-'.$rowid, 'restricthtml');
}
if ($field == 'content_lines') {
$_POST['content_lines'] = GETPOST('content_lines-'.$rowid, 'restricthtml');
}
if ($field == 'email_from') {
$_POST['email_from'] = GETPOST('email_from-'.$rowid, 'restricthtml');
}
if ($i) {
$sql .= ", ";
}
$sql .= $field." = ";
if ((GETPOST($keycode) == '' && in_array($keycode, array('langcode'))) || (!in_array($keycode, array('langcode', 'position', 'private', 'defaultfortype')) && !GETPOST($keycode))) {
$sql .= "null"; // langcode,... must be '' if not defined so the unique key that include lang will work
} elseif ($keycode == 'langcode' && (GETPOST($keycode) == '0' || GETPOST($keycode) == '-1')) {
$sql .= "''"; // langcode must be '' if not defined so the unique key that include lang will work
} elseif ($keycode == 'fk_user') {
if (!$user->admin) { // A non admin user can only edit its own template
$sql .= ((int) $user->id);
} else {
$sql .= (GETPOSTINT($keycode) > 0 ? GETPOSTINT($keycode) : "null");
}
} elseif ($keycode == 'content') {
$sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'";
} elseif ($keycode == 'position') {
$sql .= (GETPOSTINT($keycode) > 0 ? GETPOSTINT($keycode) : 1);
} elseif (in_array($keycode, array('joinfiles', 'defaultfortype', 'private'))) {
$sql .= GETPOSTINT($keycode);
} else {
$sql .= "'".$db->escape(GETPOST($keycode, 'alphanohtml'))."'";
}
$i++;
}
$sql .= " WHERE ".$db->sanitize($rowidcol)." = ".((int) $rowid);
if (!$user->admin) { // A non admin user can only edit its own template
$sql .= " AND fk_user = ".((int) $user->id);
}
dol_syslog("actionmodify", LOG_DEBUG);
//print $sql; exit;
$resql = $db->query($sql);
if (!$resql) {
$error++;
setEventMessages($db->error(), null, 'errors');
$action = 'edit';
}
}
if (!$error) {
setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
}
}
}
if ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) { // delete
$rowidcol = "rowid";
$sql = "DELETE from ".$db->sanitize($tabname[25])." WHERE rowid = ".((int) $rowid);
if (!$user->admin) { // A non admin user can only edit its own template
$sql .= " AND fk_user = ".((int) $user->id);
}
dol_syslog("delete", LOG_DEBUG);
$result = $db->query($sql);
if (!$result) {
if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
} else {
dol_print_error($db);
}
}
}
// activate
if ($action == $acts[0] && $permissiontoedit) {
$rowidcol = "rowid";
$sql = "UPDATE ".$db->sanitize($tabname[25])." SET active = 1 WHERE rowid = ".((int) $rowid);
$result = $db->query($sql);
if (!$result) {
dol_print_error($db);
}
}
// disable
if ($action == $acts[1] && $permissiontoedit) {
$rowidcol = "rowid";
$sql = "UPDATE ".$db->sanitize($tabname[25])." SET active = 0 WHERE rowid = ".((int) $rowid);
$result = $db->query($sql);
if (!$result) {
dol_print_error($db);
}
}
}
/*
* View
*/
$form = new Form($db);
$formadmin = new FormAdmin($db);
$now = dol_now();
//$help_url = "EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject";
$help_url = '';
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
$title = $langs->trans("EMailsSetup");
} else {
$title = $langs->trans("EMailTemplates");
}
$morejs = array();
$morecss = array();
$sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, email_from, joinfiles, defaultfortype,";
$sql .= " content_lines, content, enabled, active, tms, datec";
$sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates";
$sql .= " WHERE entity IN (".getEntity('email_template').")";
if (!$user->admin) {
$sql .= " AND (private = 0 OR (private = 1 AND fk_user = ".((int) $user->id)."))"; // Show only public and private to me
$sql .= " AND (active = 1 OR fk_user = ".((int) $user->id).")"; // Show only active or owned by me
}
if (!getDolGlobalInt('MAIN_MULTILANGS')) {
$sql .= " AND (lang = '".$db->escape($langs->defaultlang)."' OR lang IS NULL OR lang = '')";
}
if ($search_label) {
$sql .= natural_search('label', $search_label);
}
if ($search_type_template != '' && $search_type_template != '-1') {
$sql .= natural_search('type_template', $search_type_template);
}
if ($search_lang) {
$sql .= natural_search('lang', $search_lang);
}
if ($search_fk_user != '' && $search_fk_user != '-1') {
$sql .= natural_search('fk_user', $search_fk_user, 2);
}
if ($search_module) {
$sql .= natural_search('module', $search_module);
}
// Exclude disabled modules
$listofmodules = implode(",", array_keys($conf->modules));
$sql .= "AND (".natural_search('module', $listofmodules, 3, 1)." OR module IS NULL)";
if ($search_topic) {
$sql .= natural_search('topic', $search_topic);
}
// If sort order is "country", we use country_code instead
if ($sortfield == 'country') {
$sortfield = 'country_code';
}
$sql .= $db->order($sortfield, $sortorder);
//print $sql;
// Output page
// --------------------------------------------------------------------
llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'mod-admin page-mails_templates');
$arrayofselected = is_array($toselect) ? $toselect : array();
$param = '';
if (!empty($mode)) {
$param .= '&mode='.urlencode($mode);
}
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.((int) $limit);
}
if (!empty($search) && is_array($search)) {
foreach ($search as $key => $val) {
if (is_array($search[$key]) && count($search[$key])) {
foreach ($search[$key] as $skey) {
if ($skey != '') {
$param .= '&search_'.$key.'[]='.urlencode($skey);
}
}
} elseif ($search[$key] != '') {
$param .= '&search_'.$key.'='.urlencode($search[$key]);
}
}
}
if ($optioncss != '') {
$param .= '&optioncss='.urlencode($optioncss);
}
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
// Add $param from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
$param .= $hookmanager->resPrint;
$titlepicto = 'title_setup';
$url = DOL_URL_ROOT.'/admin/mails_templates.php?action=create';
$newcardbutton = '';
$newcardbutton .= dolGetButtonTitle($langs->trans('NewEMailTemplate'), '', 'fa fa-plus-circle', $url, '', (int) $permissiontoadd);
$param = '';
if ($search_label) {
$param .= '&search_label='.urlencode($search_label);
}
if (!empty($search_lang) && $search_lang != '-1') {
$param .= '&search_lang='.urlencode($search_lang);
}
if ($search_type_template != '-1') {
$param .= '&search_type_template='.urlencode($search_type_template);
}
if ($search_fk_user > 0) {
$param .= '&search_fk_user='.urlencode($search_fk_user);
}
if ($search_module) {
$param .= '&search_module='.urlencode($search_module);
}
if ($search_topic) {
$param .= '&search_topic='.urlencode($search_topic);
}
$paramwithsearch = $param;
if ($sortorder) {
$paramwithsearch .= '&sortorder='.urlencode($sortorder);
}
if ($sortfield) {
$paramwithsearch .= '&sortfield='.urlencode($sortfield);
}
if ($limit) {
$paramwithsearch .= '&limit='.((int) $limit);
}
if (GETPOST('from', 'alpha')) {
$paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha'));
}
$massactionbutton = '';
// List of available record in database
dol_syslog("htdocs/admin/mails_templates.php", LOG_DEBUG);
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$nbtotalofrecords = $db->num_rows($resql);
$sql .= $db->plimit($limit + 1, $offset);
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
if ($action != 'create') {
print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" id="list_of_c_email_templates">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from', 'alpha')).'">';
}
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
print load_fiche_titre($title, '', $titlepicto);
} else {
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'tools', 0, $newcardbutton, '', $limit, 'limit', 0, 1);
}
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
$head = email_admin_prepare_head();
print dol_get_fiche_head($head, 'templates', '', -1);
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
print load_fiche_titre('', $newcardbutton, '');
}
}
// Confirm deletion of record
if ($action == 'delete') {
print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.((int) $rowid), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
}
$fieldlist = explode(',', $tabfield[25]);
if ($action == 'create') {
// If data was already input, we define them in obj to populate input fields.
$obj = new stdClass();
$obj->label = GETPOST('label');
$obj->lang = GETPOST('lang');
$obj->type_template = GETPOST('type_template');
$obj->fk_user = GETPOSTINT('fk_user');
$obj->private = GETPOSTINT('private');
$obj->position = GETPOST('position');
$obj->topic = GETPOST('topic');
$obj->joinfiles = GETPOST('joinfiles');
$obj->defaultfortype = GETPOST('defaultfortype') ? 1 : 0;
$obj->content = GETPOST('content', 'restricthtml');
// Form to add a new line
print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST" id="create_c_email_template">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from', 'alpha')).'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent" id="table_create_c_email_template">';
// Line to enter new values (title)
print '<tr class="liste_titre">';
foreach ($fieldlist as $field => $value) {
// Determine the field name based on the possible names
// in the data dictionaries.
$valuetoshow = ucfirst($fieldlist[$field]); // Par default
$valuetoshow = $langs->trans($valuetoshow); // try to translate
$css = "left";
if ($fieldlist[$field] == 'module') {
$valuetoshow = '&nbsp;';
}
if ($fieldlist[$field] == 'fk_user') {
$valuetoshow = $langs->trans("Owner");
}
if ($fieldlist[$field] == 'lang') {
$valuetoshow = (!getDolGlobalInt('MAIN_MULTILANGS') ? '&nbsp;' : $langs->trans("Language"));
}
if ($fieldlist[$field] == 'type') {
$valuetoshow = $langs->trans("Type");
}
if ($fieldlist[$field] == 'position') {
$css = 'center';
}
if ($fieldlist[$field] == 'code') {
$valuetoshow = $langs->trans("Code");
}
if ($fieldlist[$field] == 'label') {
$valuetoshow = $langs->trans("Label");
}
if ($fieldlist[$field] == 'type_template') {
$valuetoshow = $langs->trans("TypeOfTemplate");
$css = "center";
}
if (in_array($fieldlist[$field], array('private', 'private', 'defaultfortype'))) {
$css = 'center';
}
if ($fieldlist[$field] == 'topic') {
$valuetoshow = '';
}
if ($fieldlist[$field] == 'joinfiles') {
$valuetoshow = '';
}
if ($fieldlist[$field] == 'content') {
$valuetoshow = '';
}
if ($fieldlist[$field] == 'content_lines') {
$valuetoshow = '';
}
if ($valuetoshow != '') {
print '<th class="'.$css.'">';
if (!empty($tabhelp[25][$value]) && preg_match('/^http(s*):/i', $tabhelp[25][$value])) {
print '<a href="'.$tabhelp[25][$value].'" target="_blank" rel="noopener noreferrer">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>';
} elseif (!empty($tabhelp[25][$value])) {
if (in_array($value, array('topic'))) {
print $form->textwithpicto($valuetoshow, $tabhelp[25][$value], 1, 'help', '', 0, 2, $value); // Tooltip on click
} else {
print $form->textwithpicto($valuetoshow, $tabhelp[25][$value], 1, 'help', '', 0, 2); // Tooltip on hover
}
} else {
print $valuetoshow;
}
print '</th>';
}
}
print '<th>';
print '</th>';
print '</tr>';
$tmpaction = 'create';
$parameters = array(
'fieldlist' => $fieldlist,
'tabname' => $tabname[25]
);
$reshook = $hookmanager->executeHooks('createEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
$error = $hookmanager->error;
$errors = $hookmanager->errors;
// Line to enter new values (input fields)
print '<tr class="oddeven">';
if (empty($reshook)) {
if ($action == 'edit') {
fieldList($fieldlist, $obj, $tabname[25], 'hide');
} else {
fieldList($fieldlist, $obj, $tabname[25], 'add');
}
}
// Action column
print '<td class="right">';
print '</td>';
print "</tr>";
print '<tr class="oddeven nodrag nodrop nohover"><td colspan="9" style="padding-left: 20px; padding-right: 20px;">';
// Show fields for topic, join files and body
$fieldsforcontent = array('topic', 'email_from', 'joinfiles', 'content');
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$fieldsforcontent = array('topic', 'email_from', 'joinfiles', 'content', 'content_lines');
}
foreach ($fieldsforcontent as $tmpfieldlist) {
print '<div class="inline-block lineformailtemplatefield paddingtop paddingbottom centpercent">';
// Topic of email
if ($tmpfieldlist == 'topic') {
print '<span class="bold minwidth150 inline-block">'.$form->textwithpicto($langs->trans("Topic"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</span>';
}
if ($tmpfieldlist == 'email_from') {
print '<span class="minwidth150 inline-block">'.$form->textwithpicto($langs->trans("MailFrom"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</span>';
}
if ($tmpfieldlist == 'joinfiles') {
print '<span class="minwidth150 inline-block">'.$form->textwithpicto($langs->trans("FilesAttachedToEmail"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</span>';
}
if ($tmpfieldlist == 'content') {
print '<span class="minwidth150 inline-block margintoponly">'.$form->textwithpicto($langs->trans("Content"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</span><br>';
}
if ($tmpfieldlist == 'content_lines') {
print '<span class="minwidth150 inline-block">'.$form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</span><br>';
}
// Input field
if ($tmpfieldlist == 'topic') {
print '<input type="text" class="flat minwidth500" name="'.$tmpfieldlist.'" value="'.(!empty($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : '').'">';
} elseif ($tmpfieldlist == 'email_from') {
print '<input type="text" class="flat minwidth500" name="'.$tmpfieldlist.'" value="'.(!empty($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : '').'" spellcheck="false">';
} elseif ($tmpfieldlist == 'joinfiles') {
print $form->selectyesno($tmpfieldlist, (isset($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : '0'), 1, false, 0, 1);
} else {
$okforextended = true;
if (!getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
$okforextended = false;
}
$doleditor = new DolEditor($tmpfieldlist, (!empty($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : ''), '', 400, 'dolibarr_mailings', 'In', false, $acceptlocallinktomedia, $okforextended, ROWS_6, '90%');
print $doleditor->Create(1);
}
print '</div>';
print '<br>';
}
print '</tr>';
print '</table>';
if ($action != 'edit') {
print '<center>';
print '<input type="submit" class="button button-add" name="actionadd" value="'.$langs->trans("Add").'"> ';
print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</center>';
}
print '</div>';
print '</form>';
print '<br><br><br>';
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent" id="table_list_of_c_email_templates">';
$i = 0;
// There is several pages
/*
if ($num > $limit) {
print '<tr class="none"><td class="right" colspan="'.(3 + count($fieldlist)).'">';
print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $limit ? 1 : 0), '<li class="pagination"><span>'.$langs->trans("Page").' '.($page + 1).'</span></li>');
print '</td></tr>';
}
*/
// Title line with search boxes
print '<tr class="liste_titre" id="Title line with search boxes">';
// Action column
if ($conf->main_checkbox_left_column) {
print '<td class="liste_titre center" width="64">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
}
foreach ($fieldlist as $field => $value) {
if ($value == 'module') {
print '<td class="liste_titre"><input type="text" name="search_module" class="maxwidth75" value="'.dol_escape_htmltag($search_module).'" spellcheck="false"></td>';
} elseif ($value == 'label') {
print '<td class="liste_titre"><input type="text" name="search_label" class="maxwidth75" value="'.dol_escape_htmltag($search_label).'" spellcheck="false"></td>';
} elseif ($value == 'lang') {
print '<td class="liste_titre">';
print $formadmin->select_language($search_lang, 'search_lang', 0, array(), 1, 0, 0, 'maxwidth100');
print '</td>';
} elseif ($value == 'fk_user') {
print '<td class="liste_titre">';
print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), array(), '0', 0, 0, '', 0, '', 'maxwidth100', 1);
print '</td>';
} elseif ($value == 'topic') {
print '<td class="liste_titre"><input type="text" class="maxwidth150" name="search_topic" value="'.dol_escape_htmltag($search_topic).'" spellcheck="false"></td>';
} elseif ($value == 'type_template') {
print '<td class="liste_titre center">';
// @phan-suppress-next-line PhanPluginSuspiciousParamOrder
print $form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100 maxwidth125', 1, '', 0, 1);
print '</td>';
} elseif (!in_array($value, array('content', 'content_lines'))) {
print '<td class="liste_titre"></td>';
}
}
/*if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) {
print '<td class="liste_titre"></td>';
}*/
// Status
print '<td></td>';
// Have to expand the id="Title line with search boxes" with 2 extra fields because the line below id="Title of lines" are 2 fields longer
if (!empty($arrayfields['t.tms']['checked'])) {
print '<td></td>'; // tms / Modif. date
}
if (!empty($arrayfields['t.datec']['checked'])) {
print '<td></td>'; // datec / Date creation
}
// Action column
if (!$conf->main_checkbox_left_column) {
print '<td class="liste_titre center" width="64">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
}
print '</tr>';
// Title of lines
print '<tr class="liste_titre" id="Title of lines">';
// Action column
if ($conf->main_checkbox_left_column) {
print getTitleFieldOfList('');
}
array_push($fieldlist, "tms", "datec");
foreach ($fieldlist as $field => $value) {
$showfield = 1; // By default
$css = "left";
$sortable = 1;
$valuetoshow = '';
$forcenowrap = 1;
/*
$tmparray=getLabelOfField($fieldlist[$field]);
$showfield=$tmp['showfield'];
$valuetoshow=$tmp['valuetoshow'];
$css=$tmp['align'];
$sortable=$tmp['sortable'];
*/
$valuetoshow = ucfirst($fieldlist[$field]); // By default
$valuetoshow = $langs->trans($valuetoshow); // try to translate
if ($fieldlist[$field] == 'module') {
$css = 'tdoverflowmax100';
}
if ($fieldlist[$field] == 'fk_user') {
$valuetoshow = $langs->trans("Owner");
}
if ($fieldlist[$field] == 'lang') {
$valuetoshow = $langs->trans("Language");
}
if ($fieldlist[$field] == 'type') {
$valuetoshow = $langs->trans("Type");
}
if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') {
$valuetoshow = $langs->trans("Label");
}
if ($fieldlist[$field] == 'type_template') {
$css = 'center';
$valuetoshow = $langs->trans("TypeOfTemplate");
}
if ($fieldlist[$field] == 'private') {
$css = 'center';
}
if ($fieldlist[$field] == 'position') {
$css = 'center';
}
if ($fieldlist[$field] == 'tms') {
$valuetoshow = 'Modif. date';
}
if ($fieldlist[$field] == 'datec') {
$valuetoshow = 'Date creation';
}
if ($fieldlist[$field] == 'joinfiles') {
$valuetoshow = $langs->trans("FilesAttachedToEmail");
$css = 'center';
$forcenowrap = 0;
}
if ($fieldlist[$field] == 'content') {
$valuetoshow = $langs->trans("Content");
$showfield = 0;
}
if ($fieldlist[$field] == 'content_lines') {
$valuetoshow = $langs->trans("ContentForLines");
$showfield = 0;
}
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
$showfield = 0;
}
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
$showfield = 0;
}
// Show fields
if ($showfield) {
if (!empty($tabhelp[25][$value])) {
if (in_array($value, array('topic'))) {
$valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[25][$value], 1, 'help', '', 0, 2, 'tooltip'.$value, $forcenowrap); // Tooltip on click
} else {
$valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[25][$value], 1, 'help', '', 0, 2, '', $forcenowrap); // Tooltip on hover
}
}
$sortfieldtouse = ($sortable ? $fieldlist[$field] : '');
if ($sortfieldtouse == 'type_template') {
$sortfieldtouse .= ',lang,position,label';
}
print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], $sortfieldtouse, ($page ? 'page='.$page.'&' : ''), $paramwithsearch, '', $sortfield, $sortorder, $css.' ');
}
}
print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $paramwithsearch, '', $sortfield, $sortorder, 'center ');
// Action column
if (!$conf->main_checkbox_left_column) {
print getTitleFieldOfList('');
}
print '</tr>';
$nbqualified = 0;
if ($num) {
// Lines with values
while ($i < $num) {
$obj = $db->fetch_object($resql);
if ($obj) {
if (($action == 'edit' || $action == 'preview') && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) {
// TODO Move this 2 lines into a popup
print '<tr class="nohover oddeven noborderbottom" id="rowid-'.$obj->rowid.'" name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'">';
$tmpaction = 'edit';
if ($action == 'edit') {
// do not show tms and datec
$fieldlist = explode(',', $tabfield[25]);
$parameters = array('fieldlist' => $fieldlist, 'tabname' => $tabname[25]);
} else {
$parameters = array('fieldlist' => $fieldlist, 'tabname' => $tabname[25]);
}
$reshook = $hookmanager->executeHooks('editEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
$error = $hookmanager->error;
$errors = $hookmanager->errors;
$colspan = 0;
// Action column
if ($conf->main_checkbox_left_column) {
print '<td class="center">';
print '</td>';
$colspan++;
}
// Show main fields
if (empty($reshook)) {
$colspan += fieldList($fieldlist, $obj, $tabname[25], $action);
}
// Action column
if (!$conf->main_checkbox_left_column) {
print '<td class="center">';
print '</td>';
$colspan++;
}
print "</tr>\n";
print '<tr class="oddeven nohover" id="tr-aaa-'.$rowid.'">';
if ($conf->main_checkbox_left_column) {
print '<td class="center"></td>';
}
print '<td colspan="'.($colspan - 1).'" class="" style="padding-left: 20px; padding-right: 20px;">';
$fieldsforcontent = array('topic', 'email_from','joinfiles', 'content');
if (getDolGlobalString('MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES')) {
$fieldsforcontent[] = 'content_lines';
}
$parameters = array('fieldsforcontent' => &$fieldsforcontent, 'tabname' => $tabname[25]);
$hookmanager->executeHooks('editEmailTemplateFieldsForContent', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
print '<div class="lineformailtemplatefield centpercent">';
foreach ($fieldsforcontent as $tmpfieldlist) {
$showfield = 1;
$css = "left";
$valuetoshow = $obj->$tmpfieldlist;
$class = 'tddict';
// Show value for field
if ($showfield) {
print '<div class="inline-block lineformailtemplatefield paddingtop paddingbottom centpercent">';
// Show line for topic, joinfiles and content
if ($tmpfieldlist == 'topic') {
print '<div class="minwidth150 inline-block bold">'.$form->textwithpicto($langs->trans("Topic"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</div> ';
print '<input type="text" class="flat minwidth500" name="'.$tmpfieldlist.'-'.$rowid.'" value="'.(!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : '').'"'.($action != 'edit' ? ' disabled' : '').'>';
print '<br>'."\n";
}
if ($tmpfieldlist == 'email_from') {
print '<div class="minwidth150 inline-block">'.$form->textwithpicto($langs->trans("MailFrom"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</div> ';
print '<input type="text" class="flat minwidth500" name="'.$tmpfieldlist.'-'.$rowid.'" value="'.(!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : '').'"'.($action != 'edit' ? ' disabled' : '').' spellcheck="false">';
print '<br>'."\n";
}
if ($tmpfieldlist == 'joinfiles') {
print '<div class="minwidth150 inline-block">'.$form->textwithpicto($langs->trans("FilesAttachedToEmail"), $tabhelp[25][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'</div> ';
print $form->selectyesno($tmpfieldlist.'-'.$rowid, (isset($obj->$tmpfieldlist) ? $obj->$tmpfieldlist : '0'), 1, ($action != 'edit'), 0, 1);
print '<br>'."\n";
}
if ($tmpfieldlist == 'content') {
print $form->textwithpicto($langs->trans("Content"), $tabhelp[25][$tmpfieldlist], 1, 'help', 'margintoponly', 0, 2, $tmpfieldlist).'<br>';
$okforextended = true;
if (!getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
$okforextended = false;
}
$doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 450, 'dolibarr_mailings', 'In', false, $acceptlocallinktomedia, $okforextended, ROWS_6, '80%', ($action != 'edit' ? 1 : 0));
print $doleditor->Create(1);
}
if ($tmpfieldlist == 'content_lines') {
print '<br>'."\n";
print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[25][$tmpfieldlist], 1, 'help', 'margintoponly', 0, 2, $tmpfieldlist).'<br>';
$okforextended = true;
if (!getDolGlobalString('FCKEDITOR_ENABLE_MAIL')) {
$okforextended = false;
}
$doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', false, $acceptlocallinktomedia, $okforextended, ROWS_6, '80%');
print $doleditor->Create(1);
}
print '</div>';
}
}
print '</div>';
print '<center><input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
if ($action == 'edit') {
print '<input type="submit" class="button buttongen button-save" name="actionmodify" value="'.$langs->trans("Save").'">';
}
print '<input type="submit" class="button buttongen button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</center>';
print '</td>';
if (!$conf->main_checkbox_left_column) {
print '<td class="center"></td>';
}
print '</tr>';
$nbqualified++;
} else {
// If template is for a module, check module is enabled.
if ($obj->module) {
$tempmodulekey = $obj->module;
if (empty($conf->$tempmodulekey) || !isModEnabled($tempmodulekey)) {
$i++;
continue;
}
}
$keyforobj = 'type_template';
if (!in_array($obj->$keyforobj, array_keys($elementList))) {
$i++;
continue; // It means this is a type of template not into elementList (may be because enabled condition of this type is false because module is not enabled)
}
// Test on 'enabled'
if (! (int) dol_eval((string) $obj->enabled, 1, 1, '1')) {
$i++;
continue; // Email template not qualified
}
$nbqualified++;
// Can an entry be erased or disabled ?
$iserasable = 1;
$canbedisabled = 1;
$canbemodified = 1; // true by default
if (!$user->admin && $obj->fk_user != $user->id) {
$iserasable = 0;
$canbedisabled = 0;
$canbemodified = 0;
}
$url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).(!empty($obj->code) ? '&code='.urlencode($obj->code) : '');
if ($param) {
$url .= '&'.$param;
}
print '<tr class="oddeven" id="rowid-'.$obj->rowid.'">';
// Action column - Modify link / Delete link
if ($conf->main_checkbox_left_column) {
print '<td class="center nowraponall" width="64">';
if ($canbemodified) {
print '<a class="reposition editfielda" href="'.$url.'&action=edit&token='.newToken().'">'.img_edit().'</a>';
} else {
print '<a class="reposition editfielda" href="'.$url.'&action=preview&token='.newToken().'">'.img_view().'</a>';
}
if ($iserasable) {
print '<a class="reposition marginleftonly" href="'.$url.'&action=delete&token='.newToken().$param.'">'.img_delete().'</a>';
}
print '</td>';
}
$tmpaction = 'view';
$parameters = array('fieldlist' => $fieldlist, 'tabname' => $tabname[25]);
$reshook = $hookmanager->executeHooks('viewEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
$error = $hookmanager->error;
$errors = $hookmanager->errors;
if (empty($reshook)) {
foreach ($fieldlist as $field => $value) {
if (in_array($fieldlist[$field], array('content', 'content_lines'))) {
continue;
}
$showfield = 1;
$css = "";
$class = "tddict";
$title = '';
$tmpvar = $fieldlist[$field];
$valuetoshow = $obj->$tmpvar;
if ($value == 'label' || $value == 'topic') {
if ($langs->trans($valuetoshow) != $valuetoshow) {
$valuetoshow = $langs->trans($valuetoshow);
}
$valuetoshow = dol_escape_htmltag($valuetoshow);
}
if ($value == 'label') {
$class .= ' tdoverflowmax200';
}
if ($value == 'topic') {
$class .= ' tdoverflowmax200 small';
}
if ($value == 'type_template') {
$valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow;
$css = "center tdoverflowmax150";
}
if ($value == 'lang' && $valuetoshow) {
$valuetoshow = $valuetoshow.' - '.$langs->trans("Language_".$valuetoshow);
$class .= ' tdoverflowmax100';
}
if ($value == 'fk_user') {
if ($valuetoshow > 0) {
$fuser = new User($db);
$fuser->fetch($valuetoshow);
$valuetoshow = $fuser->getNomUrl(-1);
if ($obj->private) {
$valuetoshow = img_picto($langs->transnoentitiesnoconv("Private"), 'lock', 'class="pictofixedwidth"').$valuetoshow;
}
$class .= ' tdoverflowmax100';
}
}
if ($value == 'private') {
$css = "center";
if ($valuetoshow) {
$valuetoshow = yn($valuetoshow);
} else {
$valuetoshow = '';
}
}
if ($value == 'position') {
$css = "center";
}
if (in_array($value, array('joinfiles', 'defaultfortype'))) {
$css = "center";
if ($valuetoshow) {
//$valuetoshow = yn(1);
$valuetoshow = '<input type="checkbox" checked="checked" disabled>';
} else {
$valuetoshow = '';
}
}
if ($css) {
$class .= ' '.$css;
}
if ($value == 'tms' && empty($arrayfields['t'.$value]['checked'])) {
$showfield = 0;
}
if ($value == 'datec' && empty($arrayfields['t.'.$value]['checked'])) {
$showfield = 0;
}
// Show value for field
if ($showfield) {
print '<!-- '.$fieldlist[$field].' -->';
print '<td class="'.$class.'"';
if (in_array($value, array('code', 'label', 'topic'))) {
print ' title="'.dol_escape_htmltag($valuetoshow).'"';
}
print '>';
print $valuetoshow;
print '</td>';
}
}
}
// Status / Active
print '<td class="center nowrap">';
if ($canbedisabled) {
print '<a class="reposition" href="'.$url.'&action='.$acts[$obj->active].'&token='.newToken().'">'.$actl[$obj->active].'</a>';
} else {
print '<span class="opacitymedium">'.$actl[$obj->active].'</span>';
}
print "</td>";
// Action column - Modify link / Delete link
if (!$conf->main_checkbox_left_column) {
print '<td class="center nowraponall" width="64">';
if ($canbemodified) {
print '<a class="reposition editfielda" href="'.$url.'&action=edit&token='.newToken().'">'.img_edit().'</a>';
}
if ($iserasable) {
print '<a class="reposition marginleftonly" href="'.$url.'&action=delete&token='.newToken().'">'.img_delete().'</a>';
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
}
print '</td>';
}
print "</tr>\n";
}
}
$i++;
}
}
// If no record found
if ($nbqualified == 0) {
$colspan = 12;
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
}
print '</table>';
print '</div>';
if ($action != 'create') {
print '</form>';
}
if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) {
print dol_get_fiche_end();
}
// End of page
llxFooter();
$db->close();
/**
* Show fields in insert/edit mode
*
* @param array<int|string,null|int|float|string> $fieldlist Array of fields and their values
* @param ?Object $obj If we show a particular record, obj is filled with record fields
* @param string $tabname Name of SQL table
* @param string $context 'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'preview'=show in readonly the template, 'hide'=Output field for the "add form" but we don't want it to be rendered
* @return int Number of fields printed
*/
function fieldList($fieldlist, $obj = null, $tabname = '', $context = '')
{
global $langs, $user, $db;
global $form;
global $elementList;
$formadmin = new FormAdmin($db);
$nboffieldsprinted = 0;
foreach ($fieldlist as $value) {
//print $value;
if ($value == 'module') {
print '<td></td>';
$nboffieldsprinted++;
} elseif ($value == 'fk_user') {
print '<td>';
if ($user->admin && $context != 'preview') {
print $form->select_dolusers(GETPOSTISSET('fk_user') ? GETPOSTINT('fk_user') : (empty($obj->$value) ? '' : $obj->$value), 'fk_user', $langs->trans("Owner"), array(), 0, ($user->admin ? '' : 'hierarchyme'), array(), '0', 0, 0, '', 0, '', 'minwidth75 maxwidth100');
} else {
if ($context == 'add') { // I am not admin and we show the add form
print $user->getNomUrl(-1); // Me
$forcedvalue = $user->id;
} else {
if ($obj && !empty($obj->$value) && $obj->$value > 0) {
$fuser = new User($db);
$fuser->fetch($obj->$value);
print $fuser->getNomUrl(-1);
$forcedvalue = $fuser->id;
} else {
$forcedvalue = $obj->$value;
}
}
$keyname = $value;
print '<input type="hidden" value="'.$forcedvalue.'" name="'.$keyname.'">';
}
print '</td>';
$nboffieldsprinted++;
} elseif ($value == 'lang') {
print '<td>';
if (getDolGlobalInt('MAIN_MULTILANGS') && $context != 'preview') {
$selectedlang = GETPOSTISSET('langcode') ? GETPOST('langcode', 'aZ09') : $langs->defaultlang;
if ($context == 'edit') {
$selectedlang = $obj->lang;
}
print $formadmin->select_language($selectedlang, 'langcode', 0, array(), $langs->trans("Language"), 0, 0, 'maxwidth100');
} else {
if (!empty($obj->lang)) {
print $obj->lang.' - '.$langs->trans('Language_'.$obj->lang);
}
$keyname = $value;
if ($keyname == 'lang') {
$keyname = 'langcode'; // Avoid conflict with lang param
}
print '<input type="hidden" value="'.(empty($obj->lang) ? '' : $obj->lang).'" name="'.$keyname.'">';
}
print '</td>';
$nboffieldsprinted++;
} elseif ($value == 'type_template') {
// Le type de template
print '<td class="center">';
if (($context == 'edit' && !empty($obj->type_template) && !in_array($obj->type_template, array_keys($elementList))) || $context == 'preview') {
// Current template type is an unknown type, so we must keep it as it is.
print '<input type="hidden" name="type_template" value="'.$obj->type_template.'">';
print $obj->type_template;
} else {
print $form->selectarray('type_template', $elementList, (!empty($obj->type_template) ? $obj->type_template : ''), 1, 0, 0, '', 0, 0, 0, '', 'minwidth75 maxwidth125', 1, '', 0, 1);
}
print '</td>';
$nboffieldsprinted++;
} elseif ($context == 'add' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) {
//print '<td></td>';
} elseif ($context == 'edit' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) {
print '<td></td>';
$nboffieldsprinted++;
} elseif ($context == 'preview' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) {
print '<td></td>';
$nboffieldsprinted++;
} elseif ($context == 'hide' && in_array($value, array('topic', 'joinfiles', 'content', 'content_lines'))) {
//print '<td></td>';
} else {
$size = '';
$class = '';
$classtd = '';
if ($value == 'code') {
$class = 'maxwidth100';
}
if ($value == 'label') {
$class = 'maxwidth200';
}
if ($value == 'private') {
$class = 'maxwidth50';
$classtd = 'center';
}
if ($value == 'position') {
$class = 'maxwidth50 center';
$classtd = 'center';
}
if ($value == 'topic') {
$class = 'quatrevingtpercent';
}
if ($value == 'defaultfortype') {
$class = 'width25 center';
$classtd = 'center';
}
print '<td'.($classtd ? ' class="'.$classtd.'"' : '').'>';
if (in_array($value, array('defaultfortype', 'private')) && $context != 'preview') {
if (empty($user->admin)) {
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->selectyesno($value, GETPOSTISSET($value) ? GETPOSTINT($value) : (($context != 'add' && isset($obj->$value)) ? $obj->$value : '1'), 1, false, 0, 1);
} else {
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->selectyesno($value, (isset($obj->$value) ? $obj->$value : ''), 1, false, 0, 1);
}
} else {
print '<input type="text" '.$size.'class="flat'.($class ? ' '.$class : '').'" value="'.(isset($obj->$value) ? $obj->$value : '').'" name="'. $value .'"'.($context == 'preview' ? ' disabled' : '').' spellcheck="false">';
}
print '</td>';
$nboffieldsprinted++;
}
}
return $nboffieldsprinted;
}