dolibarr 25.0.0-alpha
fraise.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
28include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
29include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
30
31
36{
37 public $name = 'FundationMembers'; // Identifiant du module mailing
38 // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found
39 public $desc = 'Foundation members with emails';
40
44 public $require_admin = 0;
45
49 public $require_module = array('adherent');
50
54 public $enabled = 'isModEnabled("member")';
55
59 public $picto = 'user';
60
61
67 public function __construct($db)
68 {
69 $this->db = $db;
70 }
71
72
81 public function getSqlArrayForStats()
82 {
83 global $langs;
84
85 $langs->load("members");
86
87 // Array for requests for statistics board
88 $statssql = array();
89
90 $statssql[0] = "SELECT '".$this->db->escape($langs->trans("FundationMembers"))."' as label, count(*) as nb";
91 $statssql[0] .= " FROM ".MAIN_DB_PREFIX."adherent where statut = 1 and entity IN (".getEntity('member').")";
92
93 return $statssql;
94 }
95
96
105 public function getNbOfRecipients($sql = '')
106 {
107 global $conf;
108 $sql = "SELECT count(distinct(a.email)) as nb";
109 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
110 $sql .= " WHERE (a.email IS NOT NULL AND a.email != '') AND a.entity IN (".getEntity('member').")";
111 if (empty($this->evenunsubscribe)) {
112 $sql .= " AND NOT EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = a.email and mu.entity = ".((int) $conf->entity).")";
113 }
114
115 // La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients
116 return parent::getNbOfRecipients($sql);
117 }
118
119
125 public function formFilter()
126 {
127 global $conf, $langs;
128
129 // Load translation files required by the page
130 $langs->loadLangs(array("members", "companies", "categories"));
131
132 $form = new Form($this->db);
133
134 $s = '';
135
136 // Status
137 $s .= '<select id="filter_fraise" name="filter" class="flat">';
138 $s .= '<option value="-1">'.$langs->trans("Status").'</option>';
139 $s .= '<option value="draft">'.$langs->trans("MemberStatusDraft").'</option>';
140 $s .= '<option value="1a">'.$langs->trans("MemberStatusActiveShort").' ('.$langs->trans("MemberStatusPaidShort").')</option>';
141 $s .= '<option value="1b">'.$langs->trans("MemberStatusActiveShort").' ('.$langs->trans("MemberStatusActiveLateShort").')</option>';
142 $s .= '<option value="0">'.$langs->trans("MemberStatusResiliatedShort").'</option>';
143 $s .= '</select> ';
144 $s .= ajax_combobox("filter_fraise");
145
146 $s .= '<select id="filter_type_fraise" name="filter_type" class="flat">';
147 $sql = "SELECT rowid, libelle as label, statut";
148 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type";
149 $sql .= " WHERE entity IN (".getEntity('member_type').")";
150 $sql .= " ORDER BY rowid";
151 $resql = $this->db->query($sql);
152 if ($resql) {
153 $num = $this->db->num_rows($resql);
154
155 $s .= '<option value="-1">'.$langs->trans("Type").'</option>';
156 if (!$num) {
157 $s .= '<option value="0" disabled="disabled">'.$langs->trans("NoCategoriesDefined").'</option>';
158 }
159
160 $i = 0;
161 while ($i < $num) {
162 $obj = $this->db->fetch_object($resql);
163
164 $s .= '<option value="'.$obj->rowid.'">'.dol_trunc($obj->label, 38, 'middle');
165 $s .= '</option>';
166 $i++;
167 }
168 $s .= ajax_combobox("filter_type");
169 } else {
170 dol_print_error($this->db);
171 }
172
173 $s .= '</select>';
174 $s .= ajax_combobox("filter_type_fraise");
175
176 $s .= ' ';
177
178 $s .= '<select id="filter_category_fraise" name="filter_category" class="flat">';
179
180 // Show categories
181 $sql = "SELECT rowid, label, type, visible";
182 $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
183 $sql .= " WHERE type = 3"; // We keep only categories for members
184 // $sql.= " AND visible > 0"; // We ignore the property visible because member's categories does not use this property (only products categories use it).
185 $sql .= " AND entity = ".((int) $conf->entity);
186 $sql .= " ORDER BY label";
187
188 //print $sql;
189 $resql = $this->db->query($sql);
190 if ($resql) {
191 $num = $this->db->num_rows($resql);
192
193 $s .= '<option value="-1">'.$langs->trans("Category").'</option>';
194 if (!$num) {
195 $s .= '<option value="0" disabled>'.$langs->trans("NoCategoriesDefined").'</option>';
196 }
197
198 $i = 0;
199 while ($i < $num) {
200 $obj = $this->db->fetch_object($resql);
201
202 $s .= '<option value="'.$obj->rowid.'">'.dol_trunc($obj->label, 38, 'middle');
203 $s .= '</option>';
204 $i++;
205 }
206 $s .= ajax_combobox("filter_category_fraise");
207 } else {
208 dol_print_error($this->db);
209 }
210
211 $s .= '</select>';
212
213
214 $s .= '<br><span class="opacitymedium">';
215 $s .= $langs->trans("DateEndSubscription").': &nbsp;';
216 $s .= $langs->trans("After").' > </span>'.$form->selectDate(-1, 'subscriptionafter', 0, 0, 1, 'fraise', 1, 0, 0);
217 $s .= ' &nbsp; ';
218 $s .= '<span class="opacitymedium">'.$langs->trans("Before").' < </span>'.$form->selectDate(-1, 'subscriptionbefore', 0, 0, 1, 'fraise', 1, 0, 0);
219
220 return $s;
221 }
222
223
230 public function url($id)
231 {
232 return '<a href="'.DOL_URL_ROOT.'/adherents/card.php?rowid='.$id.'">'.img_object('', "user").'</a>';
233 }
234
235
236 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
243 public function add_to_target($mailing_id)
244 {
245 // phpcs:enable
246 global $conf, $langs;
247
248 // Load translation files required by the page
249 $langs->loadLangs(array("members", "companies"));
250
251 $cibles = array();
252 $now = dol_now();
253
254 $dateendsubscriptionafter = dol_mktime(GETPOSTINT('subscriptionafterhour'), GETPOSTINT('subscriptionaftermin'), GETPOSTINT('subscriptionaftersec'), GETPOSTINT('subscriptionaftermonth'), GETPOSTINT('subscriptionafterday'), GETPOSTINT('subscriptionafteryear'));
255 $dateendsubscriptionbefore = dol_mktime(GETPOSTINT('subscriptionbeforehour'), GETPOSTINT('subscriptionbeforemin'), GETPOSTINT('subscriptionbeforesec'), GETPOSTINT('subscriptionbeforemonth'), GETPOSTINT('subscriptionbeforeday'), GETPOSTINT('subscriptionbeforeyear'));
256
257 // La requete doit retourner: id, email, fk_contact, name, firstname
258 $sql = "SELECT a.rowid as id, a.email as email, null as fk_contact, ";
259 $sql .= " a.lastname, a.firstname,";
260 $sql .= " a.datefin, a.civility as civility_id, a.login, a.societe"; // Other fields
261 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
262 if (GETPOSTINT('filter_category') > 0) {
263 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."categorie_member as cm ON cm.fk_member = a.rowid";
264 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = cm.fk_categorie AND c.rowid = ".(GETPOSTINT('filter_category'));
265 }
266 $sql .= " , ".MAIN_DB_PREFIX."adherent_type as ta";
267 $sql .= " WHERE a.entity IN (".getEntity('member').") AND a.email <> ''"; // Note that null != '' is false
268 $sql .= " AND a.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
269 // Filter on status
270 if (GETPOST("filter", 'aZ09') == 'draft') {
271 $sql .= " AND a.statut = -1";
272 } elseif (GETPOST("filter", 'aZ09') == '1a') {
273 $sql .= " AND a.statut=1 AND (a.datefin >= '".$this->db->idate($now)."' OR ta.subscription = 0)";
274 } elseif (GETPOST("filter", 'aZ09') == '1b') {
275 $sql .= " AND a.statut=1 AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND ta.subscription = 1)";
276 } elseif (GETPOST("filter", 'aZ09') === '0') {
277 $sql .= " AND a.statut=0";
278 }
279 // Filter on date
280 if ($dateendsubscriptionafter > 0) {
281 $sql .= " AND datefin > '".$this->db->idate($dateendsubscriptionafter)."'";
282 }
283 if ($dateendsubscriptionbefore > 0) {
284 $sql .= " AND datefin < '".$this->db->idate($dateendsubscriptionbefore)."'";
285 }
286 $sql .= " AND a.fk_adherent_type = ta.rowid";
287 // Filter on type
288 if (GETPOSTINT('filter_type') > 0) {
289 $sql .= " AND ta.rowid = ".(GETPOSTINT('filter_type'));
290 }
291 if (empty($this->evenunsubscribe)) {
292 $sql .= " AND NOT EXISTS (SELECT rowid FROM ".MAIN_DB_PREFIX."mailing_unsubscribe as mu WHERE mu.email = a.email and mu.entity = ".((int) $conf->entity).")";
293 }
294 $sql .= " ORDER BY a.email";
295 //print $sql;
296
297 // Add targets into table
298 dol_syslog(get_class($this)."::add_to_target", LOG_DEBUG);
299 $result = $this->db->query($sql);
300 if ($result) {
301 $num = $this->db->num_rows($result);
302 $i = 0;
303 $j = 0;
304
305 dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
306
307 $old = '';
308 while ($i < $num) {
309 $obj = $this->db->fetch_object($result);
310 if ($old != $obj->email) {
311 $cibles[$j] = array(
312 'email' => $obj->email,
313 'fk_contact' => (int) $obj->fk_contact,
314 'lastname' => $obj->lastname,
315 'firstname' => $obj->firstname,
316 'other' =>
317 ($langs->transnoentities("Login").'='.$obj->login).';'.
318 ($langs->transnoentities("UserTitle").'='.($obj->civility_id ? $langs->transnoentities("Civility".$obj->civility_id) : '')).';'.
319 ($langs->transnoentities("DateEnd").'='.dol_print_date($this->db->jdate($obj->datefin), 'day')).';'.
320 ($langs->transnoentities("Company").'='.$obj->societe),
321 'source_url' => $this->url($obj->id),
322 'source_id' => (int) $obj->id,
323 'source_type' => 'member'
324 );
325 $old = $obj->email;
326 $j++;
327 }
328
329 $i++;
330 }
331 } else {
332 dol_syslog($this->db->error());
333 $this->error = $this->db->error();
334 return -1;
335 }
336
337 return parent::addTargetsToDatabase($mailing_id, $cibles);
338 }
339}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
Class to manage generation of HTML components Only common components must be here.
Parent class of emailing target selectors modules.
Class to generate targets according to the Fraise rule.
url($id)
Provides the URL to the card of the source information of the recipient for the mailing.
add_to_target($mailing_id)
Adds recipients to the targets table.
getSqlArrayForStats()
In the main mailing area, there is a box with statistics.
formFilter()
Displays the filter form that appears on the mailing recipient selection page.
__construct($db)
Constructor.
getNbOfRecipients($sql='')
Returns the number of distinct emails returned by your selector.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '...' if string larger than length.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.