sendrecurringinvoicebymail/fiche-rec-tab1.php
Chl f94ba084a3 Disable Dolibarr filter on email addresses and subject
'was wondering if the filter change of Dolibarr 13 might have affected
something else and, well, yes...

So, following e1ac0a6d69, we also disable the
filter for the email addresses, else we get something like
"Webmaster <webmaster@bugness.org>" becoming "Webmaster".
2024-08-25 15:10:07 +02:00

346 lines
17 KiB
PHP

<?php
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2021 Chl <chl-dev@bugness.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
// Initially copied from modulebuilder/template/myobject_card.php
// Load Dolibarr environment
$res=0;
// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
// Try main.inc.php using relative path
if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
if (! $res) die("Include of main fails");
// Load needed classes/lib
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture-rec.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
require_once 'class/sribmcustommailinfo.class.php';
// Get parameters
$id = GETPOST('id', 'int');
$output = '';
// Check security (take care of everything, even page layout, if something goes wrong)
restrictedArea($user, 'facture', $id, 'facture_rec');
// Load translation files required by the page
$langs->loadLangs(array('bills', 'compta', 'other', 'mails', 'products', 'companies', 'sendrecurringinvoicebymail@sendrecurringinvoicebymail'));
// Wrap everything in a do-while(false) as a try-catch mecanisme
// in order to print llxFooter whatever happens.
do {
/**
* Part 0 : Preparations
*/
// Load necessary data
$mailObject = new SRIBMCustomMailInfo($db);
$form = new Form($db);
if ($mailObject->fetch(null, $id, true) <= 0) {
// Note : this should only happen when facture-rec doesn't exist or some database error.
// If sribmcustommailinfo doesn't exist in database, we should still get a instance of the template.
setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
break;
}
// List of senders (user, company, robot, ...)
$listFrom = array();
$listFrom['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
$listFrom['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
if (!empty($user->email)) {
$listFrom['user'] = $user->getFullName($langs) . ' <' . $user->email . '>';
}
// If the address in the SRIBM object is not the same as the user (basically,
// the user has changed its email address or the address has been set by another
// user), we add an 'old' = 'no modification' option.
if ($mailObject->id
&& $mailObject->fromtype == 'user'
&& isset($listFrom['user'])
&& $listFrom['user'] != $mailObject->frommail
) {
$listFrom['old'] = $mailObject->frommail;
}
// List of contacts of the third party
$listContacts = $mailObject->fac_rec_object->thirdparty->thirdparty_and_contact_email_array(1);
// Substitution array/string
$helpforsubstitution = $langs->trans('AvailableVariables').' :<br>'."\n";
$tmparray = getCommonSubstitutionArray($langs, 0, null, $mailObject->fac_rec_object);
complete_substitutions_array($tmparray, $langs);
foreach($tmparray as $key => $val) {
$helpforsubstitution .= $key . ' -> ' . $langs->trans(dol_string_nohtmltag($val)) . '<br>';
}
/**
* Part 1 : Treatment of form submission
*/
// If the mail form has been submitted, check and record the data
if (GETPOST('save')) {
do {
// Validate input data
if (! array_key_exists(GETPOST('fromtype'), $listFrom)) {
setEventMessages('Unexpected from value', null, 'errors');
break;
}
if (GETPOST('sendto_socpeople', 'array') != array_intersect(GETPOST('sendto_socpeople', 'array'), array_keys($listContacts))) {
setEventMessages("Unexpected contact value in 'to'", null, 'errors');
break;
}
if (GETPOST('sendcc_socpeople', 'array') != array_intersect(GETPOST('sendcc_socpeople', 'array'), array_keys($listContacts))) {
setEventMessages("Unexpected contact value in 'cc'", null, 'errors');
break;
}
// Validate some non-breaking stuff after feeding
if (empty(GETPOST('sendto_free', 'none')) && empty(GETPOST('sendto_socpeople', 'array'))) {
// Kinda weird behaviour from CMailFile but better alert the user beforehand
// FIXME: check if there is a workaround ?
setEventMessages("In some configuration, CMailFile doesn't allow empty 'to' recipient. You should set at least one.", null, 'warnings');
//break;
}
if (! strlen(GETPOST('subject', 'none'))) {
// Kinda weird behaviour from CMailFile but better alert the user beforehand
// FIXME: check if there is a workaround ?
setEventMessages("In some configuration, CMailFile doesn't allow empty subject. You should set one.", null, 'warnings');
//break;
}
if (! in_array(GETPOST('body_ishtml', 'int'), array('-1', '0', '1'), true)) {
setEventMessages("Unexpected body_ishtml value", null, 'errors');
break;
}
// Feed the input data to the model
$mailObject->active = GETPOST('active', 'int') ? 1 : 0;
$mailObject->addmaindocfile = GETPOST('addmaindocfile', 'int') ? 1 : 0;
$mailObject->fromtype = GETPOST('fromtype', 'alpha');
$mailObject->frommail = $listFrom[$mailObject->fromtype];
$mailObject->sendto_free = GETPOST('sendto_free', 'none');
$mailObject->sendto_thirdparty = in_array('thirdparty', GETPOST('sendto_socpeople', 'array'));
$mailObject->sendcc_free = GETPOST('sendcc_free', 'none');
$mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array'));
$mailObject->subject = GETPOST('subject', 'none');
$mailObject->body = GETPOST('body', 'none');
$mailObject->body_ishtml = (int)GETPOST('body_ishtml', 'int');
// Save into database
if ($mailObject->id) {
if ($mailObject->update($user) != 1) {
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
break;
}
} else {
$mailObject->fk_facture_rec = $mailObject->fac_rec_object->id;
if ($mailObject->create($user) < 0) {
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
break;
}
}
// Update the linked contacts
$data = array_merge(
array_map(
function ($id) { return array('id' => $id, 'sendtype' => 'to'); },
array_filter(GETPOST('sendto_socpeople', 'array'), 'is_numeric')
),
array_map(
function ($id) { return array('id' => $id, 'sendtype' => 'cc'); },
array_filter(GETPOST('sendcc_socpeople', 'array'), 'is_numeric')
)
);
if ($mailObject->updateLinkSocPeople($data) != 1) {
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
break;
}
// Everything seems ok
setEventMessages($langs->trans("CorrectlyUpdated"), null, 'mesgs');
// ... + redirect to cleanly reload all data and avoid some F5 misbehaviour
header("Location: fiche-rec-tab1.php?id=" . (int) $id, true, 302);
return;
} while(false);
} else if (GETPOST('reset') && $mailObject->id) {
if ($mailObject->delete() == 1) {
// Success message...
setEventMessages($langs->trans("ResetDone"), null, 'mesgs');
// ... + redirect to cleanly reload all data
header("Location: fiche-rec-tab1.php?id=" . (int) $id, true, 302);
return;
} else {
setEventMessages($langs->trans("ErrorSQL") . " : " . $mailObject->error , null, 'errors');
}
}
// Prepare the pre-selected id for To/Cc select inputs
$preselected = array(
'to' => array(),
'cc' => array(),
);
if (GETPOSTISSET('sendto_socpeople') || GETPOSTISSET('sendcc_socpeople')) {
// Retrieve data from last form submission
$preselected['to'] = GETPOST('sendto_socpeople');
$preselected['cc'] = GETPOST('sendcc_socpeople');
} else {
// Retrieve data from model
foreach ($mailObject->linkToSocPeoples as $contact) {
$preselected[$contact->pivot->sendtype][] = $contact->id;
}
// add the third-party's email in case sendXX_thirdparty is true
if ($mailObject->sendto_thirdparty) {
$preselected['to'][] = 'thirdparty';
}
if ($mailObject->sendcc_thirdparty) {
$preselected['cc'][] = 'thirdparty';
}
}
/**
* Part 2 : Display
*/
// Same tabs than the main page
$head=invoice_rec_prepare_head($mailObject->fac_rec_object);
$output .= dol_get_fiche_head($head, 'sendrecurringinvoicebymail', $langs->trans("RepeatableInvoice"), -1, 'bill'); // Add a div
$output .= '<div class="inline-block floatleft valignmiddle refid refidpadding">' . $mailObject->fac_rec_object->ref . "</div>\n";
$output .= '<div class="refidno">' . $langs->trans('ThirdParty') . ' : ' . $mailObject->fac_rec_object->thirdparty->getNomUrl(1) . "</div>\n";
$output .= "</div><!-- Closing div class='tabBar' -->\n\n";
$output .= '<div class="titre inline-block">' . $langs->trans("Options") . "</div>\n";
$output .= '<form id="sribmform" name="sribmform" method="POST" action="#sribmform">';
if (function_exists('newToken')) {
$output .= '<input type="hidden" name="token" value="'.newToken().'">'; // CSRF protection
} else {
// Used before Dolibar 13
$output .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; // CSRF protection
}
$output .= '<table class="liste" summary="mail options"><tbody>';
$output .= '<tr class="oddeven">';
$output .= ' <td><label for="active">' . $langs->trans('OptionEnable') . "</label></td>\n";
$output .= ' <td><input type="checkbox" id="active" name="active" value="1"' . ((empty($_POST) && $mailObject->active || GETPOSTISSET('active')) ? ' checked="checked"' : '') . " /></td>\n";
$output .= "</tr>\n";
$output .= "</tbody></table>\n";
// Little explanations
$output .= '<div class="titre inline-block" style="margin-top: 1.5em;">' . $langs->trans("CustomizationTitle") . "</div>\n";
// TODO: translation
$output .= "<p>" . $langs->trans('CustomizationIntro', $langs->trans('Reset')) . "<br />\n";
$output .= $langs->trans('CustomizationLinkToGlobalTemplate', DOL_URL_ROOT . '/admin/mails_templates.php?search_label=sendrecurring', DOL_URL_ROOT . '/admin/mails.php') . "</p>\n\n";
$output .= '<table class="tableforemailform boxtablenotop" width="100%">';
$output .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
$defaultFrom = 'robot';
if (isset($listFrom['old'])) {
$defaultFrom = 'old';
} elseif ($mailObject->id) {
$defaultFrom = $mailObject->fromtype;
}
$output .= $form->selectarray('fromtype', $listFrom, GETPOST('fromtype', 'alpha') ? GETPOST('fromtype', 'alpha') : $defaultFrom);
$output .= "</td></tr>\n";
// Recipient(s)
$output .= '<tr><td class="minwidth200 fieldrequired">';
$output .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
$output .= "</td>\n<td>";
$output .= '<input class="minwidth200" id="sendto_free" name="sendto_free" value="'.(GETPOST("sendto_free", "alpha") ? GETPOST("sendto_free", "alpha") : htmlentities($mailObject->sendto_free)) . '" />';
$output .= " " . $langs->trans("and") . "/" . $langs->trans("or") . " ";
$output .= $form->multiselectarray('sendto_socpeople', $listContacts, $preselected['to']);
$output .= "</td></tr>\n";
// CC
$output .= '<tr><td class="minwidth200">';
$output .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
$output .= "</td>\n<td>";
$output .= '<input class="minwidth200" id="sendto_free" name="sendcc_free" value="'.(GETPOST("sendcc_free", "alpha") ? GETPOST("sendcc_free", "alpha") : htmlentities($mailObject->sendcc_free)) . '" />';
$output .= " " . $langs->trans("and") . "/" . $langs->trans("or") . " ";
$output .= $form->multiselectarray('sendcc_socpeople', $listContacts, $preselected['cc']);
$output .= "</td></tr>\n";
// Subject
$output .= '<tr><td class="minwidth200 fieldrequired">';
$output .= $form->textwithpicto($langs->trans("MailTopic"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
$output .= "</td>\n<td>";
$output .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. (GETPOST('subject', 'alpha') ? GETPOST('subject', 'alpha') : htmlentities($mailObject->subject)) . '" />';
$output .= "</td></tr>\n";
// addmaindocfile
$output .= '<tr><td>' . $langs->trans('MailFile') . "</td>\n";
$tmp_addmaindocfile = $mailObject->addmaindocfile;
if (! empty($_POST)) {
$tmp_addmaindocfile = GETPOSTISSET('addmaindocfile') ? 1 : 0;
}
$output .= '<td><input type="checkbox" name="addmaindocfile" value="1"' . ($tmp_addmaindocfile ? ' checked="checked"' : '') . ' /> ' . $langs->trans("JoinMainDoc") . "</td>\n";
// body
$output .= '<tr><td class="minwidth200" valign="top">';
$output .= $form->textwithpicto($langs->trans("MailText"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
$output .= "</td>\n<td>";
/*
// doleditor does some weird stuff, adding <br> and newlines, I'll get more into it when I have time.
// fallback to simple <textarea> for the time being.
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('body_plaintext', (GETPOST('body_plaintext', 'alpha') ? GETPOST('body_plaintext', 'alpha') : $mailObject->body_plaintext), '', 280);
$output .= $doleditor->Create(1);
*/
$output .= '<textarea id="body" name="body" rows="14" cols="80" class="flat">';
$output .= htmlentities(GETPOST('body', 'alpha') ? GETPOST('body', 'alpha') : $mailObject->body);
$output .= "</textarea>\n";
$output .= "</td></tr>\n";
// body_ishtml
$output .= '<tr><td>' . $langs->trans('MailBodyFormat') . "</td>\n";
$tmp_ishtml = (int)(GETPOSTISSET('body_ishtml') ? GETPOST('body_ishtml', 'int') : $mailObject->body_ishtml);
// selectarray() does funny things with -1 key, so we build it manually.
//$output .= $form->selectarray('body_ishtml', $listBodyIsHtml, $mailObject->body_ishtml);
$output .= '<td><select name="body_ishtml">';
foreach (array(-1 => 'MailBodyFormatAutoDetect', 0 => 'MailBodyFormatPlainText', 1 => 'MailBodyFormatHtml') as $key => $item) {
$output .= '<option value="' . $key . '"';
$output .= ($key === $tmp_ishtml) ? ' selected="selected"' : '';
$output .= '>' . $langs->trans($item) . "</option>\n";
}
$output .= "</select>\n</td>\n";
$output .= "</table>\n";
$output .= '<br><div class="center">';
$output .= '<input class="button" type="submit" id="save" name="save" value="'.$langs->trans("Save").'" />';
$output .= '<input class="button warning" type="submit" id="reset" name="reset" value="'.$langs->trans("Reset").'"';
$output .= ($mailObject->id ? '' : ' title="' . $langs->trans('ResetTooltipNoCustomisationToReset') . '" disabled="disabled"') . ' />';
$output .= "</div>\n";
} while (false);
// Print everything
llxHeader('', $langs->trans('RepeatableInvoice') . ' - ' . $langs->trans('SendingByMail'), '');
print $output;
llxFooter();