From 0043e39f3069c33e220bfa11c6f07b87166d963a Mon Sep 17 00:00:00 2001 From: Chl Date: Tue, 10 Aug 2021 19:54:05 +0200 Subject: [PATCH 01/19] readme: more helpful download links + typos & format --- README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 39a3144..ed44b61 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Features -(en) This module send the invoice generated with recurring invoices by email to the client. +(en) This module sends by email the invoice generated with recurring invoices via scheduled jobs. (fr) Ce module envoie par mail les factures générées automatiquement par les travaux planifiés et les factures modèles. @@ -30,11 +30,18 @@ Other modules are available on `Setup` > `Modules/Applications` and finally the `Deploy/install external app/module` tab +and upload the module_sendrecurringinvoicebymail-x.y.z.zip file (you can get it from the +[original forge](https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail/releases) +or [Github](https://github.com/bugness-chl/sendrecurringinvoicebymail/releases)). + +Next, on the `Modules/Applications` page, activate the newly available sendrecurringinvoicebymail module, +and probably the Scheduled jobs (alias cron or modCron) integrated module too. -Note: If this screen tell you there is no custom directory, check your setup is correct: +#### Troubleshooting + +Note: If the module screen tells you there is no custom directory, check that your setup is correct: - In your Dolibarr installation directory, edit the ```htdocs/conf/conf.php``` file and check that following lines are not commented: @@ -68,9 +75,7 @@ cd ....../custom git clone git@github.com:bugness-chl/sendrecurringinvoicebymail.git sendrecurringinvoicebymail ``` -### Final steps - -From your browser: +Then, from your browser: - Log into Dolibarr as a super-administrator - Go to "Setup" -> "Modules" @@ -94,7 +99,7 @@ GPLv3 or (at your option) any later version. See file COPYING for more information. -#### Documentation +### Documentation All texts and readmes. From 1e694ef51d3864d799d7ae442064243811a7cf12 Mon Sep 17 00:00:00 2001 From: Chl Date: Sat, 27 Nov 2021 23:47:52 +0100 Subject: [PATCH 02/19] [DB upgrade] Adding a field to select the mail's body format Technical reminder about the DB upgrade : There doesn't seem to be an easy and reusable way to give CMail both parts of an text+html email, so we rework the database schema to have a simple 'body' field with a 'body_ishtml' switch, following CMail interface. Enhancement from issue #1 --- ...tions_sendrecurringinvoicebymail.class.php | 5 ++-- class/sribmcustommailinfo.class.php | 20 +++++++------- .../modsendrecurringinvoicebymail.class.php | 2 +- fiche-rec-tab1.php | 26 ++++++++++++++++--- langs/en_US/sendrecurringinvoicebymail.lang | 6 +++++ langs/fr_FR/sendrecurringinvoicebymail.lang | 9 +++++++ sql/update_0.3.1-0.3.2.sql | 21 +++++++++++++++ 7 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 sql/update_0.3.1-0.3.2.sql diff --git a/class/actions_sendrecurringinvoicebymail.class.php b/class/actions_sendrecurringinvoicebymail.class.php index 2f0c15c..ccc9813 100644 --- a/class/actions_sendrecurringinvoicebymail.class.php +++ b/class/actions_sendrecurringinvoicebymail.class.php @@ -115,7 +115,8 @@ class Actionssendrecurringinvoicebymail 'errorsTo' => $conf->global->MAIN_MAIL_ERRORS_TO, 'replyTo' => $conf->global->MAIN_MAIL_ERRORS_TO, 'subject' => $mailObject->subject, - 'message' => $mailObject->body_plaintext, + 'message' => $mailObject->body, + 'ishtml' => $mailObject->body_ishtml, ); // Check that we have a recipient, to avoid some frequent error... @@ -154,7 +155,7 @@ class Actionssendrecurringinvoicebymail $mail_data['cc'], // CC $mail_data['bcc'], // BCC 0, //deliveryreceipt - 0, //msgishtml + $mail_data['ishtml'], //msgishtml $mail_data['errorsTo'], '', // css '', // trackid diff --git a/class/sribmcustommailinfo.class.php b/class/sribmcustommailinfo.class.php index 6559134..7f68e19 100644 --- a/class/sribmcustommailinfo.class.php +++ b/class/sribmcustommailinfo.class.php @@ -109,12 +109,12 @@ class SRIBMCustomMailInfo extends CommonObject /** * @var string */ - public $body_plaintext; + public $body; /** - * @var string (not used at the moment) + * @var int 0: plain text, 1: html, -1: auto (see CMailFile and dol_ishtml()) */ - public $body_html; + public $body_ishtml = 0; // End of database fields @@ -228,7 +228,7 @@ class SRIBMCustomMailInfo extends CommonObject $sql .= " SET "; $sql .= " fk_facture_rec = " . (int)$this->fk_facture_rec; $sql .= ", active = " . (int)$this->active; - $sql .= ", addmaindocfile = '" . (int)$this->addmaindocfile . "'"; + $sql .= ", addmaindocfile = " . (int)$this->addmaindocfile; $sql .= ", fromtype = '" . $this->db->escape($this->fromtype) . "'"; $sql .= ", frommail = '" . $this->db->escape($this->frommail) . "'"; $sql .= ", sendto_thirdparty = " . (int)$this->db->escape($this->sendto_thirdparty); @@ -238,8 +238,8 @@ class SRIBMCustomMailInfo extends CommonObject $sql .= ", sendbcc_thirdparty = " . (int)$this->db->escape($this->sendbcc_thirdparty); $sql .= ", sendbcc_free = '" . $this->db->escape($this->sendbcc_free) . "'"; $sql .= ", subject = '" . $this->db->escape($this->subject) . "'"; - $sql .= ", body_plaintext = '" . $this->db->escape($this->body_plaintext) . "'"; - $sql .= ", body_html = '" . $this->db->escape($this->body_html) . "'"; + $sql .= ", body = '" . $this->db->escape($this->body) . "'"; + $sql .= ", body_ishtml = " . (int)$this->body_ishtml; $sql .= " WHERE rowid = " . (int)$this->id; $result = $this->db->query($sql); @@ -281,7 +281,7 @@ class SRIBMCustomMailInfo extends CommonObject { global $conf; - $sql = "SELECT rowid, fk_facture_rec, active, addmaindocfile, fromtype, frommail, sendto_thirdparty, sendto_free, sendcc_thirdparty, sendcc_free, sendbcc_thirdparty, sendbcc_free, subject, body_plaintext, body_html"; + $sql = "SELECT rowid, fk_facture_rec, active, addmaindocfile, fromtype, frommail, sendto_thirdparty, sendto_free, sendcc_thirdparty, sendcc_free, sendbcc_thirdparty, sendbcc_free, subject, body, body_ishtml"; $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; $sql .= " WHERE " . (isset($ref) ? 'fk_facture_rec = ' . (int)$ref : "rowid = " . (int)$rowid); @@ -309,8 +309,8 @@ class SRIBMCustomMailInfo extends CommonObject $this->sendbcc_thirdparty = $obj->sendbcc_thirdparty; $this->sendbcc_free = $obj->sendbcc_free; $this->subject = $obj->subject; - $this->body_plaintext = $obj->body_plaintext; - $this->body_html = $obj->body_html; + $this->body = $obj->body; + $this->body_ishtml = $obj->body_ishtml; $ref = $obj->fk_facture_rec; } elseif (!$fill_defaults_from_template) { $this->error = "SRIBMCustomMailInfo not found (id: " . var_export($rowid, true) . ", ref: " . var_export($ref, true); @@ -366,7 +366,7 @@ class SRIBMCustomMailInfo extends CommonObject } $this->subject = $template->topic; - $this->body_plaintext = $template->content; + $this->body = $template->content; $this->addmaindocfile = $template->joinfiles; } diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index 0ce3334..3369880 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -357,7 +357,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->db->query("INSERT INTO " . MAIN_DB_PREFIX . "sribm_custom_mail_info (fk_facture_rec, fromtype, frommail) VALUES (" . (int)$row->rid . ", 'robot', '" . $this->db->escape($conf->global->MAIN_MAIL_EMAIL_FROM) . "')"); $sid = $this->db->last_insert_id(MAIN_DB_PREFIX . 'sribm_custom_mail_info'); } - foreach (array('subject' => 'subject', 'body' => 'body_plaintext', 'sendto' => 'sendto_free') as $key => $item) { + foreach (array('subject' => 'subject', 'body' => 'body', 'sendto' => 'sendto_free') as $key => $item) { if (! empty($mail_data[$key])) { // We loop on each field. // Not optimized, I know. diff --git a/fiche-rec-tab1.php b/fiche-rec-tab1.php index b787ffd..f78fb3e 100644 --- a/fiche-rec-tab1.php +++ b/fiche-rec-tab1.php @@ -132,6 +132,10 @@ do { 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; @@ -147,7 +151,8 @@ do { $mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array')); $mailObject->subject = GETPOST('subject', 'alpha'); - $mailObject->body_plaintext = GETPOST('body_plaintext', 'alpha'); + $mailObject->body = GETPOST('body', 'alpha'); + $mailObject->body_ishtml = (int)GETPOST('body_ishtml', 'int'); // Save into database if ($mailObject->id) { @@ -295,7 +300,7 @@ do { $output .= ' ' . $langs->trans("JoinMainDoc") . "\n"; - // body_plaintext + // body $output .= ''; $output .= $form->textwithpicto($langs->trans("MailText"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody'); $output .= "\n"; @@ -306,11 +311,24 @@ do { $doleditor = new DolEditor('body_plaintext', (GETPOST('body_plaintext', 'alpha') ? GETPOST('body_plaintext', 'alpha') : $mailObject->body_plaintext), '', 280); $output .= $doleditor->Create(1); */ - $output .= '\n"; $output .= "\n"; + // body_ishtml + $output .= '' . $langs->trans('MailBodyFormat') . "\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 .= '\n\n"; + $output .= "\n"; $output .= '
'; diff --git a/langs/en_US/sendrecurringinvoicebymail.lang b/langs/en_US/sendrecurringinvoicebymail.lang index 92ea605..2e0ef64 100644 --- a/langs/en_US/sendrecurringinvoicebymail.lang +++ b/langs/en_US/sendrecurringinvoicebymail.lang @@ -41,10 +41,16 @@ About = About sendrecurringinvoicebymailAbout = About sendrecurringinvoicebymail sendrecurringinvoicebymailAboutPage = sendrecurringinvoicebymail about page +# # Tab title on the fiche-rec page +# CustomizationTitle = Customization CustomizationIntro = Below, you can override the global email template for this particular recurring invoice. To remove all customization, click on the %s button. CustomizationLinkToGlobalTemplate = As a note, the global email template can be configured here, and the default sender address can be configured there. +MailBodyFormat = Message format +MailBodyFormatAutoDetect = Auto-detect +MailBodyFormatPlainText = Plain text +MailBodyFormatHtml = HTML OptionEnable = Send mail when generating via cron (cf. module "Scheduled Jobs") Reset = Reset ResetDone = Reset done : customization deleted diff --git a/langs/fr_FR/sendrecurringinvoicebymail.lang b/langs/fr_FR/sendrecurringinvoicebymail.lang index 47a29da..787adbf 100644 --- a/langs/fr_FR/sendrecurringinvoicebymail.lang +++ b/langs/fr_FR/sendrecurringinvoicebymail.lang @@ -29,6 +29,11 @@ sendrecurringinvoicebymailSetup = Configuration du module sendrecurringinvoiceby Settings = Réglages sendrecurringinvoicebymailSetupPage = Page de configuration du module sendrecurringinvoicebymail + + + + + # # Page À propos # @@ -42,6 +47,10 @@ sendrecurringinvoicebymailAboutPage = Page à propos de sendrecurringinvoicebyma CustomizationTitle = Personnalisation CustomizationIntro = Ci-dessous, vous pouvez personnaliser les emails pour cette facture-modèle. Pour annuler toute personnalisation, cliquez sur le bouton '%s'. CustomizationLinkToGlobalTemplate = Pour mémoire, le template global est configurable par ici, et l'adresse de l'émetteur par défaut est configurable par là. +MailBodyFormat = Format du message +MailBodyFormatAutoDetect = Auto-detect +MailBodyFormatPlainText = Texte pur +MailBodyFormatHtml = HTML OptionEnable = Envoyer par email lors d'une génération automatique via le module "Travaux planifiés" Reset = Réinitialiser ResetDone = Réinitialisation effectuée : personnalisation supprimée. diff --git a/sql/update_0.3.1-0.3.2.sql b/sql/update_0.3.1-0.3.2.sql new file mode 100644 index 0000000..388337c --- /dev/null +++ b/sql/update_0.3.1-0.3.2.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Chl +-- +-- 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/. + + +-- We designed the schema too quickly : CMailFile doesn't let us manage +-- independently the text and html parts. All we can do is set the mode. +ALTER TABLE llx_sribm_custom_mail_info CHANGE COLUMN body_plaintext body mediumtext; +ALTER TABLE llx_sribm_custom_mail_info DROP COLUMN body_html; +ALTER TABLE llx_sribm_custom_mail_info ADD COLUMN body_ishtml smallint DEFAULT 0 NOT NULL; From 4c49334c315fb51896d7ebf79433fd51d0da689b Mon Sep 17 00:00:00 2001 From: Chl Date: Sun, 28 Nov 2021 00:59:18 +0100 Subject: [PATCH 03/19] optimization: Don't load the facture-rec twice --- fiche-rec-tab1.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/fiche-rec-tab1.php b/fiche-rec-tab1.php index f78fb3e..4d55f06 100644 --- a/fiche-rec-tab1.php +++ b/fiche-rec-tab1.php @@ -56,18 +56,14 @@ do { */ // Load necessary data - $object = new FactureRec($db); $mailObject = new SRIBMCustomMailInfo($db); $form = new Form($db); - if ($object->fetch($id) <= 0 or !$object->id) - { + 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; } - if ($mailObject->fetch(null, $object->id, true) <= 0) { - setEventMessages("Weird stuff, shouldn't happen : " . $mailObject->error); - break; - } // List of senders (user, company, robot, ...) $listFrom = array(); @@ -92,7 +88,7 @@ do { // Substitution array/string $helpforsubstitution = $langs->trans('AvailableVariables').' :
'."\n"; - $tmparray = getCommonSubstitutionArray($langs, 0, null, $object); + $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)) . '
'; @@ -161,7 +157,7 @@ do { break; } } else { - $mailObject->fk_facture_rec = $object->id; + $mailObject->fk_facture_rec = $mailObject->fac_rec_object->id; if ($mailObject->create($user) < 0) { setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors'); break; @@ -230,7 +226,7 @@ do { */ // Same tabs than the main page - $head=invoice_rec_prepare_head($object); + $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 .= '
' . $mailObject->fac_rec_object->ref . "
\n"; $output .= '
' . $langs->trans('ThirdParty') . ' : ' . $mailObject->fac_rec_object->thirdparty->getNomUrl(1) . "
\n"; From faa9dcaa6cfdd593c6f96aa9a3338cba3085c3df Mon Sep 17 00:00:00 2001 From: Chl Date: Sun, 28 Nov 2021 01:00:40 +0100 Subject: [PATCH 04/19] Allow sending emails even when the invoice is a draft --- class/actions_sendrecurringinvoicebymail.class.php | 6 +++--- class/sribmcustommailinfo.class.php | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/class/actions_sendrecurringinvoicebymail.class.php b/class/actions_sendrecurringinvoicebymail.class.php index ccc9813..0209d6b 100644 --- a/class/actions_sendrecurringinvoicebymail.class.php +++ b/class/actions_sendrecurringinvoicebymail.class.php @@ -90,9 +90,9 @@ class Actionssendrecurringinvoicebymail return -1; } - // We only send the mail when the invoice is not a draft - // and the sending is enabled for the template. - if ($object->brouillon || !$mailObject->active) { + // Abort sending when inactive + // (draft invoice or explictly disabled) + if (!$mailObject->active) { return 0; } diff --git a/class/sribmcustommailinfo.class.php b/class/sribmcustommailinfo.class.php index 7f68e19..1a1a21e 100644 --- a/class/sribmcustommailinfo.class.php +++ b/class/sribmcustommailinfo.class.php @@ -368,6 +368,9 @@ class SRIBMCustomMailInfo extends CommonObject $this->subject = $template->topic; $this->body = $template->content; $this->addmaindocfile = $template->joinfiles; + // By default, we don't send emails when the generated invoice is + // still a draft. + $this->active = $this->fac_rec_object->auto_validate; } return 1; From 224e82f9fa907671bf717035ff59153b4011f9df Mon Sep 17 00:00:00 2001 From: Chl Date: Wed, 1 Dec 2021 00:17:33 +0100 Subject: [PATCH 05/19] Default choice for body format (auto/txt/html) in module's setup Enhancement for issue #1 --- admin/setup.php | 176 ++++++++++++++++++ class/sribmcustommailinfo.class.php | 4 + .../modsendrecurringinvoicebymail.class.php | 11 +- langs/en_US/sendrecurringinvoicebymail.lang | 6 +- langs/fr_FR/sendrecurringinvoicebymail.lang | 6 +- 5 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 admin/setup.php diff --git a/admin/setup.php b/admin/setup.php new file mode 100644 index 0000000..81b5097 --- /dev/null +++ b/admin/setup.php @@ -0,0 +1,176 @@ + + * Copyright (C) 2021 Chl + * + * 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 . + */ + +/** + * \file sendrecurringinvoicebymail/admin/setup.php + * \ingroup sendrecurringinvoicebymail + * \brief SRIBM setup page. + */ + +// 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) die("Include of main fails"); + +global $langs, $user; + +// Libraries +require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php"; +//require_once '../lib/mymodule.lib.php'; +//require_once "../class/myclass.class.php"; + +// Translations +$langs->loadLangs(array("admin", "sendrecurringinvoicebymail@sendrecurringinvoicebymail")); + +// Access control +if (! $user->admin) accessforbidden(); + +// Parameters +$action = GETPOST('action', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$arrayofparameters=array( + //'SENDRECURRINGINVOICEBYMAIL_MYPARAM2'=>array('css'=>'minwidth500','enabled'=>1) + 'SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT' => array( + 'css' => 'minwidth200', + 'selectvalues' => array( + -1 => 'MailBodyFormatAutoDetect', + 0 => 'MailBodyFormatPlainText', + 1 => 'MailBodyFormatHtml', + ), + ), +); + + + +/* + * Actions + */ + +if ((float) DOL_VERSION >= 6) +{ + include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +} + + + +/* + * View + */ + +$page_name = "sendrecurringinvoicebymailSetup"; +llxHeader('', $langs->trans($page_name)); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_mymodule@mymodule'); + +// Configuration header +//$head = mymoduleAdminPrepareHead(); +$head = array(); +dol_fiche_head($head, 'settings', '', -1, "sendrecurringinvoicebymail@sendrecurringinvoicebymail"); + +// Setup page goes here +echo ''.$langs->trans("sendrecurringinvoicebymailSetupPage").'

'; + + +if ($action == 'edit') +{ + print '
'; + print ''; + print ''; + + print ''; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print '\n"; + print '\n"; + } + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print "'; + if (isset($val['selectvalues'])) { + // Select input + print '\n"; + } else { + // Simple input + print ''; + } + print "
'; + + print '
'; + print ''; + print '
'; + + print '
'; + print '
'; +} +else +{ + if (! empty($arrayofparameters)) + { + print ''; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print '' . $conf->global->$key . '
'; + + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; + } + else + { + print '
'.$langs->trans("NothingToSetup"); + } +} + + +// Page end +dol_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/class/sribmcustommailinfo.class.php b/class/sribmcustommailinfo.class.php index 1a1a21e..a611e5c 100644 --- a/class/sribmcustommailinfo.class.php +++ b/class/sribmcustommailinfo.class.php @@ -368,9 +368,13 @@ class SRIBMCustomMailInfo extends CommonObject $this->subject = $template->topic; $this->body = $template->content; $this->addmaindocfile = $template->joinfiles; + // By default, we don't send emails when the generated invoice is // still a draft. $this->active = $this->fac_rec_object->auto_validate; + + // Retrieve the default body format from config. + $this->body_ishtml = $conf->global->SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT; } return 1; diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index 3369880..2bc42c6 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -103,7 +103,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->dirs = array("/sendrecurringinvoicebymail/temp"); // Config pages. Put here list of php page, stored into sendrecurringinvoicebymail/admin directory, to use to setup module. - //$this->config_page_url = array("setup.php@sendrecurringinvoicebymail"); + $this->config_page_url = array("setup.php@sendrecurringinvoicebymail"); // Dependencies $this->hidden = false; // A condition to hide module @@ -124,6 +124,15 @@ class modsendrecurringinvoicebymail extends DolibarrModules // 1=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) // ); $this->const = array( + 0 => array( + 'SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT', // key + 'chaine', // always 'chaine' ? + '0', // value + 'default format for mail body : -1 for auto-detect, 0 for plain text, 1 for HTML.', // desc + 1, // visible + 'current', // current or allentities + 0, // deleteonunactive + ), //1=>array('SENDRECURRINGINVOICEBYMAIL_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1) ); diff --git a/langs/en_US/sendrecurringinvoicebymail.lang b/langs/en_US/sendrecurringinvoicebymail.lang index 2e0ef64..86f7180 100644 --- a/langs/en_US/sendrecurringinvoicebymail.lang +++ b/langs/en_US/sendrecurringinvoicebymail.lang @@ -28,10 +28,8 @@ ModulesendrecurringinvoicebymailDesc = Send FactureRec generated invoices by mai sendrecurringinvoicebymailSetup = sendrecurringinvoicebymail setup Settings = Settings sendrecurringinvoicebymailSetupPage = sendrecurringinvoicebymail setup page -SENDRECURRINGINVOICEBYMAIL_MYPARAM1 = My param 1 -SENDRECURRINGINVOICEBYMAIL_MYPARAM1Tooltip = My param 1 tooltip -SENDRECURRINGINVOICEBYMAIL_MYPARAM2=My param 2 -SENDRECURRINGINVOICEBYMAIL_MYPARAM2Tooltip=My param 2 tooltip +SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Default mail body's format +SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1 for auto-detect, 0 for plaintext, 1 for HTML # diff --git a/langs/fr_FR/sendrecurringinvoicebymail.lang b/langs/fr_FR/sendrecurringinvoicebymail.lang index 787adbf..c7475ca 100644 --- a/langs/fr_FR/sendrecurringinvoicebymail.lang +++ b/langs/fr_FR/sendrecurringinvoicebymail.lang @@ -28,10 +28,8 @@ ModulesendrecurringinvoicebymailDesc = Envoi par mail des factures générées p sendrecurringinvoicebymailSetup = Configuration du module sendrecurringinvoicebymail Settings = Réglages sendrecurringinvoicebymailSetupPage = Page de configuration du module sendrecurringinvoicebymail - - - - +SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Format par défaut du corps du mail +SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1: auto-détection, 0: texte pur, 1: HTML # From 904554a0e1091bdb8e85edf6c026af820fc4c4fa Mon Sep 17 00:00:00 2001 From: Chl Date: Sat, 4 Dec 2021 02:37:38 +0100 Subject: [PATCH 06/19] Add a notice if the module cron is disabled --- admin/setup.php | 5 +++++ langs/en_US/sendrecurringinvoicebymail.lang | 1 + langs/fr_FR/sendrecurringinvoicebymail.lang | 1 + 3 files changed, 7 insertions(+) diff --git a/admin/setup.php b/admin/setup.php index 81b5097..42c53fe 100644 --- a/admin/setup.php +++ b/admin/setup.php @@ -166,6 +166,11 @@ else { print '
'.$langs->trans("NothingToSetup"); } + + // Display a notice if the 'cron' module is not enabled + if (! in_array('cron', $conf->modules, true)) { + print '

' . $langs->trans('NoticeCronIsDisabled') . "

\n"; + } } diff --git a/langs/en_US/sendrecurringinvoicebymail.lang b/langs/en_US/sendrecurringinvoicebymail.lang index 86f7180..dc9d28f 100644 --- a/langs/en_US/sendrecurringinvoicebymail.lang +++ b/langs/en_US/sendrecurringinvoicebymail.lang @@ -28,6 +28,7 @@ ModulesendrecurringinvoicebymailDesc = Send FactureRec generated invoices by mai sendrecurringinvoicebymailSetup = sendrecurringinvoicebymail setup Settings = Settings sendrecurringinvoicebymailSetupPage = sendrecurringinvoicebymail setup page +NoticeCronIsDisabled = Notice: the cron / Scheduled Jobs module seems disabled. Unless you know what you are doing, invoices won't be generated and emails won't be sent. SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Default mail body's format SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1 for auto-detect, 0 for plaintext, 1 for HTML diff --git a/langs/fr_FR/sendrecurringinvoicebymail.lang b/langs/fr_FR/sendrecurringinvoicebymail.lang index c7475ca..cdd1af6 100644 --- a/langs/fr_FR/sendrecurringinvoicebymail.lang +++ b/langs/fr_FR/sendrecurringinvoicebymail.lang @@ -28,6 +28,7 @@ ModulesendrecurringinvoicebymailDesc = Envoi par mail des factures générées p sendrecurringinvoicebymailSetup = Configuration du module sendrecurringinvoicebymail Settings = Réglages sendrecurringinvoicebymailSetupPage = Page de configuration du module sendrecurringinvoicebymail +NoticeCronIsDisabled = Notice : le module cron / Travaux Planifiés semble désactivé. Sauf cas particulier, les factures ne seront pas générées et les mails ne seront pas envoyés. SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Format par défaut du corps du mail SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1: auto-détection, 0: texte pur, 1: HTML From faa3ff6a02d7ce966bb6ea99203492a8076284f6 Mon Sep 17 00:00:00 2001 From: Chl Date: Wed, 1 Dec 2021 00:27:33 +0100 Subject: [PATCH 07/19] Preparing 0.3.2 release --- ChangeLog.md | 13 ++++++++++++- .../modules/modsendrecurringinvoicebymail.class.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index b32a51e..be22db7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,15 @@ -# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR DOLIBARR ERP CRM +# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR [DOLIBARR ERP CRM](https://www.dolibarr.org) + + +## 0.3.2 + +Note: This release includes a DB schema modification. Reactivate the module to trigger it. + +Enhancements: + +* Mails can now be sent in HTML (via global module configuration and via the customzation tab). +* Mails can now be sent even when the invoice is a draft. + ## 0.3.1 diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index 2bc42c6..b1153c4 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '0.3.1'; + $this->version = '0.3.2'; //Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From 97f6eb9ff16b18c33d42b31b886d675f1cbb926c Mon Sep 17 00:00:00 2001 From: Chl Date: Sun, 5 Dec 2021 18:19:29 +0100 Subject: [PATCH 08/19] a little chauvinism :) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed44b61..6cde6c6 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Note: If the module screen tells you there is no custom directory, check that yo ```sh cd ....../custom -git clone git@github.com:bugness-chl/sendrecurringinvoicebymail.git sendrecurringinvoicebymail +git clone https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail.git sendrecurringinvoicebymail ``` Then, from your browser: From 704fd77e8249bb21e6641008c6356acc83ad58bd Mon Sep 17 00:00:00 2001 From: Chl Date: Tue, 11 Jan 2022 18:11:12 +0100 Subject: [PATCH 09/19] Little rewrite on why there is no dedicated scheduled job --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cde6c6..0ac0b28 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ To edit the default global mail template, go to Home > Setup > Emails > Email te To edit the default sender address, go to Home > Setup > Emails, and edit the `Sender email for automatic emails` field. -This module is triggered by the cron (Scheduled jobs module) and will not send emails when manually generating an invoice. +This module hooks himself on the end of the `Recurring invoices` job from the Scheduled jobs (aka. `cron`) module. It will only be triggered via this Scheduled job and will not send mail when manually generating an invoice from a recurring invoice template. ## Requirements From cdde859aeaa662ddc99e44004302ca4e93d58ae8 Mon Sep 17 00:00:00 2001 From: Chl Date: Mon, 5 Jun 2023 12:39:50 +0200 Subject: [PATCH 10/19] Correct the module's family CRM -> Financial, with the invoice module. --- core/modules/modsendrecurringinvoicebymail.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index b1153c4..f26bf39 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -52,7 +52,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...' // It is used to group modules by family in module setup page - $this->family = "crm"; + $this->family = "financial"; // Module position in the family on 2 digits ('01', '10', '20', ...) $this->module_position = '90'; // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this) From d3bac76b2ee415fd4da59d1e869b46fd9b48f0f6 Mon Sep 17 00:00:00 2001 From: Chl Date: Sun, 17 Dec 2023 00:22:21 +0100 Subject: [PATCH 11/19] CSRF-protect the form + update the version Fix #8 --- core/modules/modsendrecurringinvoicebymail.class.php | 2 +- fiche-rec-tab1.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index f26bf39..f2a029d 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '0.3.2'; + $this->version = '0.3.3'; //Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; diff --git a/fiche-rec-tab1.php b/fiche-rec-tab1.php index 4d55f06..604ec6e 100644 --- a/fiche-rec-tab1.php +++ b/fiche-rec-tab1.php @@ -234,6 +234,12 @@ do { $output .= '
' . $langs->trans("Options") . "
\n"; $output .= '
'; + if (function_exists('newToken')) { + $output .= ''; // CSRF protection + } else { + // Used before Dolibar 13 + $output .= ''; // CSRF protection + } $output .= ''; $output .= ''; $output .= ' \n"; From a7532db483aa9c63cdc19018004c33b05dd39a67 Mon Sep 17 00:00:00 2001 From: Chl Date: Wed, 13 Mar 2024 01:05:50 +0100 Subject: [PATCH 12/19] Execute the hook only for customer invoices With the introduction of supplier invoice templates in Dolibarr 16, with the same hook but different table, this module tried to load the customer invoice having the same id than the supplier invoice template being treated. This could result in severe information disclosure. Fixes gh-10 --- ChangeLog.md | 10 ++++++++++ class/actions_sendrecurringinvoicebymail.class.php | 8 ++++++++ core/modules/modsendrecurringinvoicebymail.class.php | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index be22db7..8834495 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,15 @@ # CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR [DOLIBARR ERP CRM](https://www.dolibarr.org) +## 0.3.4 + +Fix: the hook was also triggered by supplier invoices. +Thanks to jpardenoy for the report and the fix. + + +## 0.3.3 + +Fix: adds CSRF protection. + ## 0.3.2 diff --git a/class/actions_sendrecurringinvoicebymail.class.php b/class/actions_sendrecurringinvoicebymail.class.php index 0209d6b..fcae1d4 100644 --- a/class/actions_sendrecurringinvoicebymail.class.php +++ b/class/actions_sendrecurringinvoicebymail.class.php @@ -84,6 +84,14 @@ class Actionssendrecurringinvoicebymail $error = 0; // Error counter $facturerec = $parameters['facturerec']; + // Since Dolibarr 16, this hook is also used for the FactureFournisseurRec class. + if (! $facturerec instanceof FactureRec) { + return 0; + } + + // Load our own object, linked to this facture + // (if it doesn't exist in database, fetch(,,true) will fill the object + // from the global mail template) $mailObject = new SRIBMCustomMailInfo($this->db); if ($mailObject->fetch(null, $facturerec->id, true) != 1) { dol_syslog("Error loading SRIBMCustomMailInfo for facture rec " . (isset($facturerec->id) ? $facturerec->id : "(facturerec->id not set ??)")); diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index f2a029d..b3517b4 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '0.3.3'; + $this->version = '0.3.4'; //Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From 0b08f125c9e7ee24a0118c8940288e9f305aa343 Mon Sep 17 00:00:00 2001 From: Chl Date: Wed, 13 Mar 2024 18:49:51 +0100 Subject: [PATCH 13/19] readme: specify 'customer invoice' Following the arrival of supplier invoice templates in Dolibarr 16, it's better to specify than this module only manage customer invoices. Adding the management of supplier invoice seems possible but I don't really see a use case at the moment. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ac0b28..2f736af 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ## Features -(en) This module sends by email the invoice generated with recurring invoices via scheduled jobs. +(en) This module sends by email the customer invoice generated with a recurring invoice template via scheduled jobs. -(fr) Ce module envoie par mail les factures générées automatiquement par les travaux planifiés et les factures modèles. +(fr) Ce module envoie par mail les factures clientes générées automatiquement par les travaux planifiés et les factures modèles. You can customize the mail globally or by recurring invoice. From 44c54ab3f7802eac028b4897802f135b4b576af7 Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 15 Mar 2024 01:22:09 +0100 Subject: [PATCH 14/19] $conf->global->MAIN_MAIL_ERRORS_TO is not always set --- class/actions_sendrecurringinvoicebymail.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/class/actions_sendrecurringinvoicebymail.class.php b/class/actions_sendrecurringinvoicebymail.class.php index fcae1d4..ceb5417 100644 --- a/class/actions_sendrecurringinvoicebymail.class.php +++ b/class/actions_sendrecurringinvoicebymail.class.php @@ -120,8 +120,8 @@ class Actionssendrecurringinvoicebymail 'to' => implode(', ', $mailObject->compileEmails('to', true)), 'cc' => implode(', ', $mailObject->compileEmails('cc', true)), 'bcc' => implode(', ', $mailObject->compileEmails('bcc', true)), - 'errorsTo' => $conf->global->MAIN_MAIL_ERRORS_TO, - 'replyTo' => $conf->global->MAIN_MAIL_ERRORS_TO, + 'errorsTo' => (isset($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : ''), + 'replyTo' => (isset($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : ''), 'subject' => $mailObject->subject, 'message' => $mailObject->body, 'ishtml' => $mailObject->body_ishtml, From e1ac0a6d69f0d5913bf74c8bdbebfff0bbecd72a Mon Sep 17 00:00:00 2001 From: Chl Date: Sat, 17 Aug 2024 21:27:57 +0200 Subject: [PATCH 15/19] Fix GH-11: HTML silently removed with Dolibarr 13+ The behaviour of GETPOST(..., 'alpha') changed with Dolibarr 13, copying 'alphanohtml'. Unfortunately, there is no retro-compatible option. Thus the 'none' filter seems the better call since there doesn't seem to have any big attack involving emails' body (except HTML+JS...) For the next big version, maybe use the 'restricthtml' filter, but it only appeared in Dolibarr 12. --- fiche-rec-tab1.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fiche-rec-tab1.php b/fiche-rec-tab1.php index 604ec6e..4efce12 100644 --- a/fiche-rec-tab1.php +++ b/fiche-rec-tab1.php @@ -146,8 +146,8 @@ do { $mailObject->sendcc_free = GETPOST('sendcc_free', 'alpha'); $mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array')); - $mailObject->subject = GETPOST('subject', 'alpha'); - $mailObject->body = GETPOST('body', 'alpha'); + $mailObject->subject = GETPOST('subject', 'none'); + $mailObject->body = GETPOST('body', 'none'); $mailObject->body_ishtml = (int)GETPOST('body_ishtml', 'int'); // Save into database From ab5a9c28613b294f5a0485b841dc921c11328ec2 Mon Sep 17 00:00:00 2001 From: Chl Date: Sat, 17 Aug 2024 21:36:25 +0200 Subject: [PATCH 16/19] Preparing 0.3.5 release --- ChangeLog.md | 8 ++++++++ core/modules/modsendrecurringinvoicebymail.class.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 8834495..521c60f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,13 @@ # CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR [DOLIBARR ERP CRM](https://www.dolibarr.org) +## 0.3.5 + +Fix: + +* HTML formating was silently removed when used on Dolibarr v.13+ (GH-11) +* `$conf->global->MAIN_MAIL_ERRORS_TO` might not always be set (cause not found) + + ## 0.3.4 Fix: the hook was also triggered by supplier invoices. diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index b3517b4..d296454 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '0.3.4'; + $this->version = '0.3.5'; //Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From f94ba084a3e616b21ca39909bc3be2ae8f8509a7 Mon Sep 17 00:00:00 2001 From: Chl Date: Mon, 19 Aug 2024 23:39:29 +0200 Subject: [PATCH 17/19] 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 e1ac0a6d69f0d5913bf74c8bdbebfff0bbecd72a, we also disable the filter for the email addresses, else we get something like "Webmaster " becoming "Webmaster". --- fiche-rec-tab1.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fiche-rec-tab1.php b/fiche-rec-tab1.php index 4efce12..69fcb98 100644 --- a/fiche-rec-tab1.php +++ b/fiche-rec-tab1.php @@ -103,7 +103,7 @@ do { if (GETPOST('save')) { do { // Validate input data - if (! array_key_exists(GETPOST('fromtype', 'alpha'), $listFrom)) { + if (! array_key_exists(GETPOST('fromtype'), $listFrom)) { setEventMessages('Unexpected from value', null, 'errors'); break; } @@ -116,13 +116,13 @@ do { break; } // Validate some non-breaking stuff after feeding - if (empty(GETPOST('sendto_free', 'alpha')) && empty(GETPOST('sendto_socpeople', 'array'))) { + 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', 'alpha'))) { + 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'); @@ -140,10 +140,10 @@ do { $mailObject->fromtype = GETPOST('fromtype', 'alpha'); $mailObject->frommail = $listFrom[$mailObject->fromtype]; - $mailObject->sendto_free = GETPOST('sendto_free', 'alpha'); + $mailObject->sendto_free = GETPOST('sendto_free', 'none'); $mailObject->sendto_thirdparty = in_array('thirdparty', GETPOST('sendto_socpeople', 'array')); - $mailObject->sendcc_free = GETPOST('sendcc_free', 'alpha'); + $mailObject->sendcc_free = GETPOST('sendcc_free', 'none'); $mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array')); $mailObject->subject = GETPOST('subject', 'none'); From 26d25135d65d05bc5d99bba557c7841be3c8d222 Mon Sep 17 00:00:00 2001 From: Chl Date: Tue, 27 Aug 2024 01:43:39 +0200 Subject: [PATCH 18/19] Add workflow for generating zip file --- .../workflows/generate-release-zipfile.yml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .forgejo/workflows/generate-release-zipfile.yml diff --git a/.forgejo/workflows/generate-release-zipfile.yml b/.forgejo/workflows/generate-release-zipfile.yml new file mode 100644 index 0000000..43b7ab2 --- /dev/null +++ b/.forgejo/workflows/generate-release-zipfile.yml @@ -0,0 +1,74 @@ +# Creates a module_sendrecurringinvoicebymail-X.Y.Z.zip file when pushing a tag +# +# This job is mainly useless (Forgejo already creates a usable .zip archive, +# minus the name) and serves more as a warmup for a decent CI/CD tryout. + +on: + push: + tags: + # For the time being, we only trigger on the tags clearly matching a + # '1.2.3' version pattern. + - '[0-9]+.[0-9]+.[0-9]+' + +env: + MYFILENAME: "module_sendrecurringinvoicebymail-${{ github.ref_name }}" + +jobs: + GenerateReleaseZipfile: + runs-on: docker + container: + image: code.bugness.org/chl/alpine-wget-git-zip:latest + steps: + - name: Download the automatic repository archive + run: | + # In case the repository is private, we build an authenticated URL + # with our action token. + MY_GITHUB_AUTHENTICATED_URL="$( echo "$GITHUB_SERVER_URL" | sed "s#^\(https\?://\)#\1$GITHUB_TOKEN\@#" )" + wget -O "$MYFILENAME.zip" "$MY_GITHUB_AUTHENTICATED_URL"/"$GITHUB_REPOSITORY"/archive/"$GITHUB_REF_NAME".zip + + - name: A bit of useless cleanup + run: | + #apk add zip + # On Forgejo, GITHUB_REPOSITORY="owner/repo" (and we just want the 'repo' part) + MY_REPOSITORY="$( echo "$GITHUB_REPOSITORY" | sed 's/.*\///' )" + zip -d "$MYFILENAME.zip" \ + "$MY_REPOSITORY/.editorconfig" \ + "$MY_REPOSITORY/.gitattributes" \ + "$MY_REPOSITORY/.gitignore" \ + "$MY_REPOSITORY/.tx*" + + - name: Upload artifact (using v4) + run: | + set -ex + + # The busybox version of wget does not offer --method=PUT as of 2024-08-26 + #apk add wget + + # We extract the Actions.Results:22:33 from ACTIONS_RUNTIME_TOKEN + # (base64 -d doesn't like when the '==' padding is missing, so 2>/dev/null and relying on the piping to forget about non-zero return code...) + read WORKFLOW_RUN_BACKEND_ID WORKFLOW_JOB_RUN_BACKEND_ID </dev/null | sed 's/.*Actions.Results:\([^:]\+\):\([^:" ]\+\).*/\1 \2/' ) + EOF + + # Get the upload URL + # note: we use the name without .zip, it seems to be added automatically. + RESPONSE="$( wget -O - \ + --header 'Content-Type:application/json' \ + --header "Authorization: Bearer $GITHUB_TOKEN" \ + --post-data "$( printf '{"version":4, "name":"%s", "workflow_run_backend_id":"%s", "workflow_job_run_backend_id":"%s"}' "$MYFILENAME" "$WORKFLOW_RUN_BACKEND_ID" "$WORKFLOW_JOB_RUN_BACKEND_ID" )" \ + "$GITHUB_SERVER_URL"/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact + )" + # We get a JSON with an signedUploadUrl similar to : + # https://entrepot.xlii.si/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=yWWEI8tIIECp8D7E5TVh4_6G2pZxWaVdQcSYaCsx5s0=&expires=2024-08-26+07%3A20%3A49.886890537+%2B0200+CEST&artifactName=mymodule-1.2.3.zip&taskID=63 + SIGNED_UPLOAD_URL="$( echo "$RESPONSE" | sed -n 's/.*"signedUploadUrl" *: *"\([^"]\+\)".*/\1/p' )" + + # Upload our file + # (note: adding '&comp=block' at the end of the URL) + wget --method PUT --body-file "$MYFILENAME.zip" "$SIGNED_UPLOAD_URL&comp=block" + + # Finalize the artifact + wget -O - \ + --header 'Content-Type:application/json' \ + --header "Authorization: Bearer $GITHUB_TOKEN" \ + --post-data "$( printf '{"hash":"sha256:%s", "name":"%s", "size":"%d", "workflow_run_backend_id":"%s", "workflow_job_run_backend_id":"%s"}' "$( sha256sum $MYFILENAME.zip | sed 's/[[:space:]]\+.*//' )" "$MYFILENAME" "$( stat -c %s $MYFILENAME.zip )" "$WORKFLOW_RUN_BACKEND_ID" "$WORKFLOW_JOB_RUN_BACKEND_ID" )" \ + "$GITHUB_SERVER_URL"/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact From c26013ea03f4935ddc303fba776689f81e7e8c2c Mon Sep 17 00:00:00 2001 From: Chl Date: Tue, 27 Aug 2024 01:46:31 +0200 Subject: [PATCH 19/19] Preparing 0.3.6 release --- ChangeLog.md | 5 +++++ core/modules/modsendrecurringinvoicebymail.class.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 521c60f..cdf58df 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,10 @@ # CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR [DOLIBARR ERP CRM](https://www.dolibarr.org) +## 0.3.6 + +Fix: freeform email addresses being "html-filtered" `Postmaster ` → `Postmaster` + + ## 0.3.5 Fix: diff --git a/core/modules/modsendrecurringinvoicebymail.class.php b/core/modules/modsendrecurringinvoicebymail.class.php index d296454..4a2cc1f 100644 --- a/core/modules/modsendrecurringinvoicebymail.class.php +++ b/core/modules/modsendrecurringinvoicebymail.class.php @@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules $this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = '0.3.5'; + $this->version = '0.3.6'; //Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt';