';
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index aa2ee4b3e6a..c81ccb769ab 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -1279,7 +1279,7 @@ class FormMail extends Form
*
* @param DoliDB $dbs Database handler
* @param string $type_template Get message for model/type=$type_template, type='all' also included.
- * @param User $user Get template public or limited to this user
+ * @param User $user Get templates public + limited to this user
* @param Translate $outputlangs Output lang object
* @param int $id Id of template to get, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found)
* @param int $active 1=Only active template, 0=Only disabled, -1=All
diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php
index 9c8928de718..430c3a708d2 100644
--- a/htdocs/core/class/html.formprojet.class.php
+++ b/htdocs/core/class/html.formprojet.class.php
@@ -66,14 +66,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for JSON mode
- * @param string $filterkey Key to filter
+ * @param string $filterkey Key to filter on ref or title
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param string $morecss More css
* @param int $htmlid Html id to use instead of htmlname
+ * @param string $morefilter More filters (Must be a sql sanitized string)
* @return string Return html content
*/
- public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '')
+ public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '', $morefilter = '')
{
// phpcs:enable
global $langs, $conf, $form;
@@ -96,16 +97,14 @@ class FormProjets
$selected_input_value = $project->ref;
}
$urloption = 'socid='.((int) $socid).'&htmlname='.urlencode($htmlname).'&discardclosed='.((int) $discard_closed);
-
+ if ($morefilter == 'usage_organize_event=1') {
+ $urloption .= '&usage_organize_event=1';
+ }
$out .= '';
- $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array(
- // 'update' => array(
- // 'projectid' => 'id'
- // )
- ));
+ $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array());
} else {
- $out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss);
+ $out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss, $morefilter);
}
if ($discard_closed > 0) {
if (!empty($form)) {
@@ -135,14 +134,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for array return (to be used by json_encode for example)
- * @param string $filterkey Key to filter
+ * @param string $filterkey Key to filter on title or ref
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param int $htmlid Html id to use instead of htmlname
* @param string $morecss More CSS
+ * @param string $morefilter More filters (Must be a sql sanitized string)
* @return int Nb of project if OK, <0 if KO
*/
- public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500')
+ public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500', $morefilter = '')
{
// phpcs:enable
global $user, $conf, $langs;
@@ -187,6 +187,9 @@ class FormProjets
if (!empty($filterkey)) {
$sql .= natural_search(array('p.title', 'p.ref'), $filterkey);
}
+ if ($morefilter) {
+ $sql .= ' AND ('.$this->db->sanitize($morefilter, 0, 1).')';
+ }
$sql .= " ORDER BY p.ref ASC";
$resql = $this->db->query($sql);
diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php
index 2d2ea33a6c5..16b2fd956fe 100644
--- a/htdocs/core/db/DoliDB.class.php
+++ b/htdocs/core/db/DoliDB.class.php
@@ -136,15 +136,12 @@ abstract class DoliDB implements Database
*
* @param string $stringtosanitize String to escape
* @param int $allowsimplequote 1=Allow simple quotes in string. When string is used as a list of SQL string ('aa', 'bb', ...)
+ * @param string $allowsequals 1=Allow equals sign
* @return string String escaped
*/
- public function sanitize($stringtosanitize, $allowsimplequote = 0)
+ public function sanitize($stringtosanitize, $allowsimplequote = 0, $allowsequals = 0)
{
- if ($allowsimplequote) {
- return preg_replace('/[^a-z0-9_\-\.,\']/i', '', $stringtosanitize);
- } else {
- return preg_replace('/[^a-z0-9_\-\.,]/i', '', $stringtosanitize);
- }
+ return preg_replace('/[^a-z0-9_\-\.,'.($allowsequals ? '=' : '').($allowsimplequote ? "\'" : '').']/i', '', $stringtosanitize);
}
/**
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 74e3afaa141..b5450f7317f 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -1813,7 +1813,7 @@ function dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $di
* @param array $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped.
* @param string $active Active tab name (document', 'info', 'ldap', ....)
* @param string $title Title
- * @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no seaparation under tab (to start a tab just after)
+ * @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no sepaaration under tab (to start a tab just after), -3=Add tab header but no footer separation
* @param string $picto Add a picto on tab title
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
@@ -8858,7 +8858,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
$forbiddenphpstrings = array('$$');
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST'));
- $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", 'verifCond');
+ $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", "verifCond", "base64_decode");
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func"));
diff --git a/htdocs/core/modules/mailings/eventorganization.modules.php b/htdocs/core/modules/mailings/eventorganization.modules.php
new file mode 100644
index 00000000000..84c27c5f673
--- /dev/null
+++ b/htdocs/core/modules/mailings/eventorganization.modules.php
@@ -0,0 +1,212 @@
+
+ * Copyright (C) 2005-2010 Laurent Destailleur
+ * Copyright (C) 2005-2009 Regis Houssin
+ *
+ * This file is an example to follow to add your own email selector inside
+ * the Dolibarr email tool.
+ * Follow instructions given in README file to know what to change to build
+ * your own emailing list selector.
+ * Code that need to be changed in this file are marked by "CHANGE THIS" tag.
+ */
+
+/**
+ * \file htdocs/core/modules/mailings/eventorganization.modules.php
+ * \ingroup mailing
+ * \brief Example file to provide a list of recipients for mailing module
+ */
+
+
+// Load Dolibarr Environment
+include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
+
+
+/**
+ * Class to manage a list of personalised recipients for mailing feature
+ */
+class mailing_eventorganization extends MailingTargets
+{
+ // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found
+ public $name = 'AttendeesOfOrganizedEvent';
+ public $desc = "Attendees of an organized event";
+
+ public $require_admin = 0;
+
+ public $require_module = array(); // This module allows to select by categories must be also enabled if category module is not activated
+
+ /**
+ * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
+ */
+ public $picto = 'conferenceorbooth';
+
+ /**
+ * @var DoliDB Database handler.
+ */
+ public $db;
+
+ public $enabled = 'isModEnabled("eventorganization")';
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf, $langs;
+ $langs->load('companies');
+
+ $this->db = $db;
+ }
+
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * This is the main function that returns the array of emails
+ *
+ * @param int $mailing_id Id of mailing. No need to use it.
+ * @return int <0 if error, number of emails added if ok
+ */
+ public function add_to_target($mailing_id)
+ {
+ // phpcs:enable
+ global $conf, $langs;
+
+ $cibles = array();
+ $addDescription = '';
+
+ $sql = "SELECT p.ref, p.entity, e.rowid as id, e.fk_project, e.email as email, e.email_company as company_name, e.firstname as firstname, e.lastname as lastname,";
+ $sql .= " 'eventorganizationattendee' as source";
+ $sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e,";
+ $sql .= " ".MAIN_DB_PREFIX."projet as p";
+ $sql .= " WHERE e.email <> ''";
+ $sql .= " AND e.fk_project = p.rowid";
+ $sql .= " AND p.entity IN (".getEntity('project').")";
+ $sql .= " AND e.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
+ $sql .= " AND e.fk_project = ".((int) GETPOST('filter_eventorganization', 'int'));
+ $sql .= " ORDER BY e.email";
+
+ // Stock recipients emails into targets table
+ $result = $this->db->query($sql);
+ if ($result) {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+ $j = 0;
+
+ dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
+
+ $old = '';
+ while ($i < $num) {
+ $obj = $this->db->fetch_object($result);
+ if ($old <> $obj->email) {
+ $otherTxt = ($obj->ref ? $langs->transnoentities("Project").'='.$obj->ref : '');
+ if (strlen($addDescription) > 0 && strlen($otherTxt) > 0) {
+ $otherTxt .= ";";
+ }
+ $otherTxt .= $addDescription;
+ $cibles[$j] = array(
+ 'email' => $obj->email,
+ 'fk_project' => $obj->fk_project,
+ 'lastname' => $obj->lastname,
+ 'firstname' => $obj->firstname,
+ 'other' => $otherTxt,
+ 'source_url' => $this->url($obj->id, $obj->source),
+ 'source_id' => $obj->id,
+ 'source_type' => $obj->source
+ );
+ $old = $obj->email;
+ $j++;
+ }
+
+ $i++;
+ }
+ } else {
+ dol_syslog($this->db->error());
+ $this->error = $this->db->error();
+ return -1;
+ }
+
+ return parent::addTargetsToDatabase($mailing_id, $cibles);
+ }
+
+
+ /**
+ * On the main mailing area, there is a box with statistics.
+ * If you want to add a line in this report you must provide an
+ * array of SQL request that returns two field:
+ * One called "label", One called "nb".
+ *
+ * @return array Array with SQL requests
+ */
+ public function getSqlArrayForStats()
+ {
+ // CHANGE THIS: Optionnal
+
+ //var $statssql=array();
+ //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL";
+ return array();
+ }
+
+
+ /**
+ * Return here number of distinct emails returned by your selector.
+ * For example if this selector is used to extract 500 different
+ * emails from a text file, this function must return 500.
+ *
+ * @param string $sql Requete sql de comptage
+ * @return int|string Nb of recipient, or <0 if error, or '' if NA
+ */
+ public function getNbOfRecipients($sql = '')
+ {
+ global $conf;
+
+ $sql = "SELECT COUNT(DISTINCT(e.email)) as nb";
+ $sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e, ";
+ $sql .= " ".MAIN_DB_PREFIX."projet as p";
+ $sql .= " WHERE e.email <> ''";
+ $sql .= " AND e.fk_project = p.rowid";
+ $sql .= " AND p.entity IN (".getEntity('project').")";
+
+ //print $sql;
+
+ // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients
+ return parent::getNbOfRecipients($sql);
+ }
+
+ /**
+ * This is to add a form filter to provide variant of selector
+ * If used, the HTML select must be called "filter"
+ *
+ * @return string A html select zone
+ */
+ public function formFilter()
+ {
+ global $conf, $langs;
+
+ $langs->load("companies");
+
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+ $formproject = new FormProjets($this->db);
+ $s .= $formproject->select_projects(-1, 0, "filter_eventorganization", 0, 0, 1, 1, 0, 0, 0, '', 1, 0, '', '', 'usage_organize_event=1');
+
+ return $s;
+ }
+
+
+ /**
+ * Can include an URL link on each record provided by selector shown on target page.
+ *
+ * @param int $id ID
+ * @param string $sourcetype Source type
+ * @return string Url link
+ */
+ public function url($id, $sourcetype = 'thirdparty')
+ {
+ if ($sourcetype == 'project') {
+ return ''.img_object('', "eventorganization").'';
+ }
+
+ return '';
+ }
+}
diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
index 9083b643900..1f8f3f82f7c 100644
--- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
+++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
@@ -219,6 +219,7 @@ class mailing_thirdparties_services_expired extends MailingTargets
$s = '