dolibarr 24.0.0-beta
new.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2001-2002 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2006-2013 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
7 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2018 Alexandre Spangaro <aspangaro@open-dsi.fr>
9 * Copyright (C) 2021 Waël Almoman <info@almoman.com>
10 * Copyright (C) 2022 Udo Tamm <dev@dolibit.de>
11 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
42if (!defined('NOLOGIN')) {
43 define("NOLOGIN", 1); // This means this output page does not require to be logged.
44}
45if (!defined('NOCSRFCHECK')) {
46 define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
47}
48if (!defined('NOBROWSERNOTIF')) {
49 define('NOBROWSERNOTIF', '1');
50}
51
52
53// For MultiCompany module.
54// Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
55// Because 2 entities can have the same ref.
56$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
57define("DOLENTITY", $entity);
58
59
60// Load Dolibarr environment
61require '../../main.inc.php';
70require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
71require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
72require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
73require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
74require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
75require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
76require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
77require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
78
79// Init vars
80$backtopage = GETPOST('backtopage', 'alpha');
81$action = GETPOST('action', 'aZ09');
82
83$errmsg = '';
84$num = 0;
85$error = 0;
86
87// Load translation files
88$langs->loadLangs(array("main", "members", "companies", "install", "other", "errors"));
89
90if (isModEnabled('multicompany')) {
91 force_switch_entity($entity);
92}
93
94// Security check
95if (!isModEnabled('member')) {
96 httponly_accessforbidden('Module Membership not enabled');
97}
98
99if (!getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
100 httponly_accessforbidden("Auto subscription form for public visitors has not been enabled");
101}
102
103// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
104$hookmanager->initHooks(array('publicnewmembercard', 'globalcard'));
105
106$extrafields = new ExtraFields($db);
107
108$object = new Adherent($db);
109
110$user->loadDefaultValues();
111
112$captchaobj = null;
113if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER')) {
114 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
115 $captcha = getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_HANDLER', 'standard');
116 // List of directories where we can find captcha handlers
117 $dirModCaptcha = array_merge(
118 array(
119 'main' => '/core/modules/security/captcha/'
120 ),
121 is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()
122 );
123 $fullpathclassfile = '';
124 foreach ($dirModCaptcha as $dir) {
125 $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2);
126 if ($fullpathclassfile) {
127 break;
128 }
129 }
130 if ($fullpathclassfile) {
131 include_once $fullpathclassfile;
132 // Charging the numbering class
133 $classname = "modCaptcha".ucfirst($captcha);
134 if (class_exists($classname)) {
135 $captchaobj = new $classname($db, $conf, $langs, $user);
136 '@phan-var-force ModeleCaptcha $captchaobj';
138 } else {
139 print 'Error, the captcha handler class '.$classname.' was not found after the include';
140 }
141 } else {
142 print 'Error, the captcha handler '.$captcha.' has no class file found modCaptcha'.ucfirst($captcha);
143 }
144}
145
153function force_switch_entity($newEntity)
154{
155 global $db, $conf;
156
157 if ($newEntity != $conf->entity) {
158 $conf->entity = $newEntity;
159 $conf->setValues($db);
160 }
161}
162
177function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = [], $arrayofcss = [], $ws = '') // @phan-suppress-current-line PhanRedefineFunction
178{
179 global $conf, $langs, $mysoc;
180
181 top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); // Show html headers
182
183 print '<body id="mainbody" class="publicnewmemberform">';
184
185 include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
186 htmlPrintOnlineHeader($mysoc, $langs, 1, getDolGlobalString('MEMBER_PUBLIC_INTERFACE'), 'MEMBER_IMAGE_PUBLIC_REGISTRATION');
187
188 print '<div class="divmainbodylarge">';
189}
190
198function llxFooterVierge() // @phan-suppress-current-line PhanRedefineFunction
199{
200 global $conf, $langs;
201
202 print '</div>';
203
204 printCommonFooter('public');
205
206 if (!empty($conf->use_javascript_ajax)) {
207 print "\n".'<!-- Includes JS Footer of Dolibarr -->'."\n";
208 print '<script src="'.DOL_URL_ROOT.'/core/js/lib_foot.js.php?lang='.$langs->defaultlang.'"></script>'."\n";
209 }
210
211 print "</body>\n";
212 print "</html>\n";
213}
214
215
216//var_dump(GETPOST('firstname')); exit;
217
218/*
219 * Actions
220 */
221
222$parameters = array();
223// Note that $action and $object may have been modified by some hooks
224$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
225if ($reshook < 0) {
226 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
227}
228
229// Verify if we can find member
230
231if (empty($reshook) && getDolGlobalInt("MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATE") && $action == 'add' && !GETPOSTISSET("nofetchmember")) { // Test on permission not required here
232 $memberfound = false;
233
234 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED') && GETPOSTISSET('login')) {
235 // Note that this allow to guess anonymous ID already used. But this is not a problem as it is an anonymous pseudonym.
236 // If we try to new account and option MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATE was off, we also get the same error.
237 $sql = "SELECT rowid as id";
238 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
239 $sql .= " WHERE a.login = '".$db->escape(GETPOST('login'))."'";
240 $sql .= " AND statut = 1";
241 $sql .= " AND entity IN (".getEntity($object->element).")";
242 $resql = $db->query($sql);
243 if ($resql) {
244 if ($db->num_rows($resql) == 1) {
245 $obj = $db->fetch_object($resql);
246 $object->fetch($obj->id);
247 $memberfound = true;
248 }
249 } else {
251 }
252 }
253
254 if (!$memberfound && GETPOST("morphy") == 'mor' && GETPOSTISSET("societe")) {
255 $sql = "SELECT a.rowid as id";
256 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
257 $sql .= " JOIN ".MAIN_DB_PREFIX."societe as s";
258 $sql .= " ON a.fk_soc = s.rowid";
259 $sql .= " WHERE s.nom = '".$db->escape(GETPOST("societe", 'alphanohtml'))."'";
260 $sql .= " AND a.email = '".$db->escape(preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase')))."'";
261 $sql .= " AND a.statut = 1";
262 $sql .= " AND a.entity IN (".getEntity($object->element).")";
263 $resql = $db->query($sql);
264 if ($resql) {
265 if ($db->num_rows($resql) == 1) {
266 $obj = $db->fetch_object($resql);
267 $object->fetch($obj->id);
268 $memberfound = true;
269 }
270 } else {
272 }
273 }
274
275 if (!$memberfound && GETPOST("morphy") == 'phy' && GETPOSTISSET("lastname") && GETPOSTISSET("firstname") && !empty(GETPOST("member_email", 'aZ09arobase'))) {
276 $sql = "SELECT rowid as id";
277 $sql .= " FROM ".MAIN_DB_PREFIX."adherent";
278 $sql .= " WHERE firstname = '".$db->escape(GETPOST("firstname", 'alphanohtml'))."'";
279 $sql .= " AND lastname = '".$db->escape(GETPOST("lastname", 'alphanohtml'))."'";
280 $sql .= " AND email = '".$db->escape(preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase')))."'";
281 $sql .= " AND statut = 1";
282 $sql .= " AND entity IN (".getEntity($object->element).")";
283 $resql = $db->query($sql);
284 if ($resql) {
285 if ($db->num_rows($resql) == 1) {
286 $obj = $db->fetch_object($resql);
287 $object->fetch($obj->id);
288 $memberfound = true;
289 }
290 } else {
292 }
293 }
294
295 if ($memberfound) {
296 $action = 'subscription';
297 }
298}
299
300// Action called when page is submitted
301if (empty($reshook) && $action == 'add') { // Test on permission not required here. This is an anonymous form. Check is done on constant to enable and mitigation.
302 $error = 0;
303 $urlback = '';
304
305 $db->begin();
306
307 $morphy = GETPOST("morphy", 'alphanohtml');
308 $lastname = GETPOST("lastname", 'alphanohtml');
309 $firstname = GETPOST("firstname", 'alphanohtml');
310 $societe = GETPOST("societe", 'alphanohtml');
311 $email = preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase'));
312 $forcecountry = getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE');
313 $country_id = $forcecountry ? (int) getCountry($forcecountry, '3', $db, $langs) : GETPOSTINT('country_id');
314
315 if (!in_array($morphy, array('mor', 'phy'))) {
316 $error++;
317 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('MemberNature'))."<br>\n";
318 }
319
320 // test if login already exists
321 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
322 if (!GETPOST('member_email')) {
323 $error++;
324 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("EMail"))."<br>\n";
325 }
326 if (!GETPOST('login')) {
327 $error++;
328 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login"))."<br>\n";
329 }
330 $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login = '".$db->escape(GETPOST('login'))."'";
331 $result = $db->query($sql);
332 if ($result) {
333 $num = $db->num_rows($result);
334 }
335 if ($num != 0) {
336 $error++;
337 $langs->load("errors");
338 $errmsg .= $langs->trans("ErrorLoginAlreadyExists")."<br>\n";
339 }
340 if (!GETPOSTISSET("pass1") || !GETPOSTISSET("pass2") || GETPOST("pass1", 'none') == '' || GETPOST("pass2", 'none') == '' || GETPOST("pass1", 'none') != GETPOST("pass2", 'none')) {
341 $error++;
342 $langs->load("errors");
343 $errmsg .= $langs->trans("ErrorPasswordsMustMatch")."<br>\n";
344 }
345 }
346 if (GETPOST('typeid') <= 0) {
347 $error++;
348 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"))."<br>\n";
349 }
350
351 if ($morphy && $morphy != 'mor' && empty($lastname)) {
352 $error++;
353 $langs->load("errors");
354 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Lastname"));
355 }
356 if ($morphy && $morphy != 'mor' && (!isset($firstname) || $firstname == '')) {
357 $error++;
358 $langs->load("errors");
359 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Firstname"));
360 }
361 if ($morphy == 'mor' && empty($societe)) {
362 $error++;
363 $langs->load("errors");
364 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Company"));
365 }
366 if (empty($country_id)) {
367 $error++;
368 $langs->load("errors");
369 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Country"));
370 }
371 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && $email && !isValidEmail($email)) {
372 $error++;
373 $langs->load("errors");
374 $errmsg .= $langs->trans("ErrorBadEMail", $email);
375 }
376 $birthday = dol_mktime(GETPOSTINT("birthhour"), GETPOSTINT("birthmin"), GETPOSTINT("birthsec"), GETPOSTINT("birthmonth"), GETPOSTINT("birthday"), GETPOSTINT("birthyear"));
377 if (GETPOST("birthmonth") && empty($birthday)) {
378 $error++;
379 $langs->load("errors");
380 $errmsg .= $langs->trans("ErrorBadDateFormat")."<br>\n";
381 }
382
383 // TODO Add this in a hook
384 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
385 if (GETPOST("morphy") == 'mor' && GETPOSTFLOAT('budget') <= 0) {
386 $error++;
387 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TurnoverOrBudget"))."<br>\n";
388 }
389 }
390
391 // Check Captcha code if is enabled
392 $ok = false;
393 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
394 if (method_exists($captchaobj, 'validateCodeAfterLoginSubmit')) {
395 $ok = $captchaobj->validateCodeAfterLoginSubmit(); // @phan-suppress-current-line PhanUndeclaredMethod
396 } else {
397 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method validateCodeAfterLoginSubmit()';
398 }
399 if (!$ok) {
400 $error++;
401 $langs->load("errors");
402 $errmsg .= $langs->trans("ErrorBadValueForCode")."<br>\n";
403 $action = '';
404 }
405 }
406
407 $public = GETPOSTISSET('public') ? 1 : 0;
408
409 if (!$error) {
410 // E-mail looks OK and login does not exist
411 $adh = new Adherent($db);
412 $adh->statut = -1;
413 $adh->status = -1;
414 $adh->public = $public;
415 $adh->firstname = GETPOST('firstname');
416 $adh->lastname = GETPOST('lastname');
417 $adh->gender = GETPOST('gender');
418 $adh->civility_id = GETPOST('civility_id');
419 $adh->company = GETPOST('societe');
420 $adh->societe = $adh->company;
421 $adh->address = GETPOST('address');
422 $adh->zip = GETPOST('zipcode');
423 $adh->town = GETPOST('town');
424 $adh->email = GETPOST('member_email', 'aZ09arobase');
425 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
426 $adh->login = GETPOST('login');
427 $adh->pass = GETPOST('pass1', 'password');
428 }
429 $adh->photo = GETPOST('photo');
430 $adh->country_id = $country_id;
431 $adh->state_id = GETPOSTINT('state_id');
432 $adh->typeid = getDolGlobalInt("MEMBER_NEWFORM_FORCETYPE", GETPOSTINT('typeid'));
433 $adh->note_private = GETPOST('note_private');
434 $adh->morphy = getDolGlobalString("MEMBER_NEWFORM_FORCEMORPHY", GETPOST('morphy'));
435 $adh->birth = $birthday;
436 $adh->phone = GETPOST('phone');
437 $adh->phone_perso = GETPOST('phone_perso');
438 $adh->phone_mobile = GETPOST('phone_mobile');
439
440 $adh->ip = getUserRemoteIP();
441
442 $nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
443 $now = dol_now();
444 $minmonthpost = dol_time_plus_duree($now, -1, "m");
445 // Calculate nb of post for IP
446 $nb_post_ip = 0;
447 if ($nb_post_max > 0) { // Calculate only if there is a limit to check
448 $sql = "SELECT COUNT(ref) as nb_adh";
449 $sql .= " FROM ".MAIN_DB_PREFIX."adherent";
450 $sql .= " WHERE ip = '".$db->escape($adh->ip)."'";
451 $sql .= " AND datec > '".$db->idate($minmonthpost)."'";
452 $resql = $db->query($sql);
453 if ($resql) {
454 $num = $db->num_rows($resql);
455 $i = 0;
456 while ($i < $num) {
457 $i++;
458 $obj = $db->fetch_object($resql);
459 $nb_post_ip = $obj->nb_adh;
460 }
461 }
462 }
463
464
465 // Fill array 'array_options' with data from add form
466 $extrafields->fetch_name_optionals_label($adh->table_element);
467 $ret = $extrafields->setOptionalsFromPost(null, $adh);
468 if ($ret < 0) {
469 $error++;
470 $errmsg .= $adh->error;
471 }
472
473 if ($nb_post_max > 0 && $nb_post_ip >= $nb_post_max) {
474 $error++;
475 $errmsg .= $langs->trans("AlreadyTooMuchPostOnThisIPAdress");
476 array_push($adh->errors, $langs->trans("AlreadyTooMuchPostOnThisIPAdress"));
477 }
478
479 if (!$error) {
480 $result = $adh->create($user);
481 if ($result > 0) {
482 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
483 $object = $adh;
484
485 $adht = new AdherentType($db);
486 $adht->fetch($object->typeid);
487
488 if ($object->email) {
489 $subject = '';
490 $msg = '';
491
492 // Send subscription email
493 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
494 $formmail = new FormMail($db);
495 // Set output language
496 $outputlangs = new Translate('', $conf);
497 $outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
498 // Load traductions files required by page
499 $outputlangs->loadLangs(array("main", "members"));
500 // Get email content from template
501 $arraydefaultmessage = null;
502 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_AUTOREGISTER');
503
504 if (!empty($labeltouse)) {
505 $arraydefaultmessage = $formmail->getEMailTemplate($db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
506 }
507
508 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
509 $subject = $arraydefaultmessage->topic;
510 $msg = $arraydefaultmessage->content;
511 }
512
513 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
514 complete_substitutions_array($substitutionarray, $outputlangs, $object);
515 $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
516 $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnValid()), $substitutionarray, $outputlangs);
517
518 if ($subjecttosend && $texttosend) {
519 $moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n";
520
521 $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
522 }
523 /*if ($result < 0) {
524 $error++;
525 setEventMessages($object->error, $object->errors, 'errors');
526 }*/
527 }
528
529 // Send email to the foundation to say a new member subscribed with autosubscribe form
530 if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') && getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT') &&
531 getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')) {
532 // Define link to login card
533 $appli = constant('DOL_APPLICATION_TITLE');
534 if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
535 $appli = getDolGlobalString('MAIN_APPLICATION_TITLE');
536 if (preg_match('/\d\.\d/', $appli)) {
537 if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'/', $appli)) {
538 $appli .= " (".DOL_VERSION.")"; // If new title contains a version that is different than core
539 }
540 } else {
541 $appli .= " ".DOL_VERSION;
542 }
543 } else {
544 $appli .= " ".DOL_VERSION;
545 }
546
547 $to = $adh->makeSubstitution(getDolGlobalString('MAIN_INFO_SOCIETE_MAIL'));
548 $from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
549 $mailfile = new CMailFile(
550 '['.$appli.'] ' . getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT'),
551 $to,
552 $from,
553 $adh->makeSubstitution(getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')),
554 array(),
555 array(),
556 array(),
557 "",
558 "",
559 0,
560 -1
561 );
562
563 if (!$mailfile->sendfile()) {
564 dol_syslog($langs->trans("ErrorFailedToSendMail", $from, $to), LOG_ERR);
565 }
566 }
567
568 // Auto-create thirdparty on member creation
569 if (getDolGlobalString('ADHERENT_DEFAULT_CREATE_THIRDPARTY')) {
570 $company = new Societe($db);
571 $result = $company->create_from_member($adh);
572 if ($result < 0) {
573 $error++;
574 $errmsg .= implode('<br>', $company->errors);
575 }
576 }
577
578 if (!empty($backtopage)) {
579 $urlback = $backtopage;
580 } elseif (getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION')) {
581 $urlback = getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION');
582 // TODO Make replacement of __AMOUNT__, etc...
583 } else {
584 $urlback = $_SERVER["PHP_SELF"]."?action=added&token=".newToken();
585 }
586
587 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1') {
588 if (empty($adht->caneditamount)) { // If edition of amount not allowed
589 // TODO Check amount is same than the amount required for the type of member
590 // It is not so important because a test is done on return of payment validation.
591 }
592
593 $minimumamountbytype = $adht->minimumamountbytype(1); // Load the array of minimum amount per type
594 $minimumamount = empty($minimumamountbytype[$adh->typeid]) ? 0 : $minimumamountbytype[$adh->typeid];
595 $amount = price2num(GETPOST('amount', 'alpha'), 'MT');
596 $urlback = getOnlinePaymentUrl(0, 'member', $adh->ref, (float) $amount, '', 0);
597 if ($amount < max(getDolGlobalInt("MEMBER_MIN_AMOUNT"), $minimumamount)) {
598 $error++;
599 $errmsg .= $langs->trans("MinimumAmountShort")." : ".price(max(getDolGlobalInt("MEMBER_MIN_AMOUNT"), $minimumamount), 0, $langs, 1, -1, -1, $conf->currency)."<br>\n";
600 }
601
602 if (GETPOST('member_email')) {
603 $urlback .= '&email='.urlencode(GETPOST('member_email'));
604 }
605 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1' && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != 'all') {
606 $urlback .= '&paymentmethod='.urlencode(getDolGlobalString('MEMBER_NEWFORM_PAYONLINE'));
607 }
608 } else {
609 if (!empty($entity)) {
610 $urlback .= '&entity='.((int) $entity);
611 }
612 }
613 } else {
614 $error++;
615 $errmsg .= implode('<br>', $adh->errors);
616 }
617 }
618 }
619
620 if (!$error) {
621 $db->commit();
622
623 header("Location: ".$urlback);
624 exit;
625 } else {
626 $db->rollback();
627 $action = "create";
628 }
629}
630
631// Action called after a submitted was send and member created successfully
632// If MEMBER_URL_REDIRECT_SUBSCRIPTION is set to an url, we never go here because a redirect was done to this url. Same if we ask to redirect to the payment page.
633// backtopage parameter with an url was set on member submit page, we never go here because a redirect was done to this url.
634
635if (empty($reshook) && $action == 'added') { // Test on permission not required here
636 llxHeaderVierge($langs->trans("NewMemberForm"));
637
638 // If we have not been redirected
639 print '<br><br>';
640 print '<div class="center">';
641 print $langs->trans("NewMemberbyWeb");
642 print '</div>';
643
645 exit;
646}
647
648
649/*
650 * View
651 */
652
653$form = new Form($db);
654$formcompany = new FormCompany($db);
655$adht = new AdherentType($db);
656$extrafields->fetch_name_optionals_label($object->table_element); // fetch optionals attributes and labels
657
658
659llxHeaderVierge($langs->trans("NewSubscription"));
660
661print '<br>';
662print load_fiche_titre(img_picto('', 'member_nocolor', 'class="pictofixedwidth"').' &nbsp; '.$langs->trans("NewSubscription"), '', '', 0, '', 'center');
663
664
665print '<div align="center">';
666print '<div id="divsubscribe">';
667
668print '<div class="center subscriptionformhelptext opacitymedium justify">';
669if (getDolGlobalString('MEMBER_NEWFORM_TEXT')) {
670 print $langs->trans(getDolGlobalString('MEMBER_NEWFORM_TEXT'))."<br>\n";
671} else {
672 print $langs->trans("NewSubscriptionDesc", getDolGlobalString("MAIN_INFO_SOCIETE_MAIL"))."<br>\n";
673}
674print '</div>';
675
676dol_htmloutput_errors($errmsg);
678
679if ($action == "subscription") {
680 $urltocall = DOL_URL_ROOT.'/public/payment/newpayment.php?source=member&ref='.$object->id;
681 print $form->formconfirm($urltocall, $langs->trans("CorrespondingMemberFound"), $langs->trans("CorrespondingMemberFoundQuestion"), "confirm_subscription", '', 'no', 1);
682}
683
684// Print form
685print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="newmember" id="newmember">'."\n";
686print '<input type="hidden" name="token" value="'.newToken().'" />';
687print '<input type="hidden" name="entity" value="'.$entity.'" />';
688print '<input type="hidden" name="page_y" value="" />';
689
690if (getDolGlobalString('MEMBER_SKIP_TABLE') || getDolGlobalString('MEMBER_NEWFORM_FORCETYPE') || in_array($action, array('create', 'subscription'))) {
691 if ($action == 'subscription') {
692 print '<input type="hidden" name="nofetchmember" value="nofetchmember" />';
693 }
694 print '<input type="hidden" name="action" value="add" />';
695 print '<br>';
696
697 //$messagemandatory = '<span class="">'.$langs->trans("FieldsWithAreMandatory", '*').'</span>';
698 //print '<br>'.$messagemandatory.'<br>';
699 //print $langs->trans("FieldsWithIsForPublic",'**').'<br>';
700
701 print dol_get_fiche_head();
702
703 if ($conf->use_javascript_ajax) {
704 print "\n".'<script type="text/javascript">'."\n";
705 print 'jQuery(document).ready(function () {
706 jQuery("#selectcountry_id").change(function() {
707 console.log("We change country, so we reload page");
708 document.newmember.action.value="create";
709 jQuery("#newmember").submit();
710 });
711 function initfieldrequired() {
712 console.log("initfieldrequired");
713 jQuery("#tdcompany").removeClass("fieldrequired");
714 jQuery("#tdlastname").removeClass("fieldrequired");
715 jQuery("#tdfirstname").removeClass("fieldrequired");
716 if (jQuery(\'input[name="morphy"]:checked\').val() == \'mor\') {
717 jQuery("#tdcompany").addClass("fieldrequired");
718 }
719 if (jQuery(\'input[name="morphy"]:checked\').val() == \'phy\') {
720 jQuery("#tdlastname").addClass("fieldrequired");
721 jQuery("#tdfirstname").addClass("fieldrequired");
722 }
723 }
724 jQuery(\'input[name="morphy"]\').change(function() {
725 initfieldrequired();
726 });
727 initfieldrequired();
728 })';
729 print '</script>'."\n";
730 }
731
732 print '<table class="border" summary="form to subscribe" id="tablesubscribe">'."\n";
733
734 // Type
735 if (!getDolGlobalString('MEMBER_NEWFORM_FORCETYPE')) {
736 $typeid = GETPOSTINT("typeid");
737 print '<tr><td class="fieldrequired titlefieldmiddle">'.$langs->trans("MemberType").'</td><td>';
738 $listetype = $adht->liste_array(1);
739 print img_picto('', $adht->picto, 'class="pictofixedwidth"');
740 if (count($listetype)) {
741 print $form->selectarray("typeid", $listetype, (GETPOSTINT('typeid') ? GETPOSTINT('typeid') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', 'minwidth150 maxwidth300 widthcentpercentminusx', 1);
742 } else {
743 print '<span class="error">'.$langs->trans("NoTypeDefinedGoToSetup").'</span>';
744 }
745 print '</td></tr>'."\n";
746 } else {
747 $adht->fetch(getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE'));
748 print '<input type="hidden" id="typeid" name="typeid" value="' . getDolGlobalString('MEMBER_NEWFORM_FORCETYPE').'">';
749 }
750
751 // Moral/Physic attribute
752 $morphys = [
753 "phy" => $langs->trans("Physical"),
754 "mor" => $langs->trans("Moral"),
755 ];
756 $checkednature = GETPOST("morphy", 'alpha');
757 $listetype_natures = $adht->morphyByType(1); // Load the array of morphy per typeof membership
758 $listetype_natures_json = json_encode($listetype_natures);
759
760 if (!getDolGlobalString('MEMBER_NEWFORM_FORCEMORPHY')) {
761 if (empty($checkednature) && !empty($listetype_natures[GETPOSTINT('typeid')])) {
762 $checkednature = $listetype_natures[GETPOSTINT('typeid')];
763 }
764
765 print '<tr><td class="fieldrequired titlefieldmiddle">'.$langs->trans("MemberNature")."</td><td>\n";
766
767 $disabledphy = '';
768 $disabledmor = '';
769 //$disabledphy = ($checkednature == "mor" ? ' disabled="disabled"' : '');
770 //$disabledmor = ($checkednature == "phy" ? ' disabled="disabled"' : '');
771 print '<span id="spannature1" class="nonature-back spannature paddinglarge marginrightonly"><label for="phisicalinput" class="valignmiddle">'.$morphys["phy"].'<input id="phisicalinput" class="flat checkforselect marginleftonly valignmiddle" type="radio" name="morphy" value="phy"'.($checkednature == "phy" ? ' checked="checked"' : '').$disabledphy.'></label></span>';
772 print '<span id="spannature2" class="nonature-back spannature paddinglarge marginrightonly"><label for="moralinput" class="valignmiddle">'.$morphys["mor"].'<input id="moralinput" class="flat checkforselect marginleftonly valignmiddle" type="radio" name="morphy" value="mor"'.($checkednature == "mor" ? ' checked="checked"' : '').$disabledmor.'></label></span>';
773
774 // Add JS to manage the background of nature
775 if ($conf->use_javascript_ajax) {
776 print '<script>
777 var listetype_natures = '.$listetype_natures_json.';
778
779 jQuery(function($) {
780 function refreshNatureCss() {
781 $(".spannature").each(function(index) {
782 let $span = $("#spannature" + (index + 1));
783 let checked = $span.find(".checkforselect").is(":checked");
784
785 if (checked) {
786 if (index === 0) {
787 $span.addClass("member-individual-back").removeClass("nonature-back member-company-back");
788 } else if (index === 1) {
789 $span.addClass("member-company-back").removeClass("nonature-back member-individual-back");
790 }
791 } else {
792 $span.removeClass("member-individual-back member-company-back")
793 .addClass("nonature-back");
794 }
795 });
796 }
797
798 $(".spannature").on("click", function() {
799 console.log("Nature clicked");
800 refreshNatureCss();
801 });
802
803 $("#typeid").on("change", function() {
804 console.log("Type of membership is modified");
805 let morphy = listetype_natures[$(this).val()];
806 console.log("morphy="+morphy);
807
808 let $phyInput = $("#phisicalinput");
809 let $morInput = $("#moralinput");
810 let $tdLast = $("#tdlastname");
811 let $tdFirst = $("#tdfirstname");
812 let $tdCompany = $("#tdcompany");
813 let $span1 = $("#spannature1");
814 let $span2 = $("#spannature2");
815
816 switch (morphy) {
817 case "phy":
818 $phyInput.prop({disabled: false, checked: true});
819 $morInput.prop({disabled: true, checked: false});
820 $span1.addClass("member-individual-back").removeClass("nonature-back");
821 $span2.removeClass("member-company-back").addClass("nonature-back");
822 $("#phisicalinput").prop("checked", true);
823 $tdLast.addClass("fieldrequired");
824 $tdFirst.addClass("fieldrequired");
825 $tdCompany.removeClass("fieldrequired");
826 break;
827
828 case "mor":
829 $phyInput.prop({disabled: true, checked: false});
830 $morInput.prop({disabled: false, checked: true});
831 $span2.addClass("member-company-back").removeClass("nonature-back");
832 $span1.removeClass("member-individual-back").addClass("nonature-back");
833 $("#moralinput").prop("checked", true);
834 $tdCompany.addClass("fieldrequired");
835 $tdLast.removeClass("fieldrequired");
836 $tdFirst.removeClass("fieldrequired");
837 break;
838
839 default:
840 $phyInput.prop({disabled: false});
841 $morInput.prop({disabled: false});';
842 if ($action != "subscription" && !GETPOST('morphy')) {
843 print '
844 $phyInput.prop({checked: false});
845 $morInput.prop({checked: false});
846 $span1.removeClass("member-individual-back").addClass("nonature-back");
847 $span2.removeClass("member-company-back").addClass("nonature-back");';
848 }
849 print'}
850 });
851
852 // Initial state
853 refreshNatureCss();
854 });
855 </script>';
856 }
857 print '</td></tr>'."\n";
858 } else {
859 //print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY];
860 print '<input type="hidden" id="morphy" name="morphy" value="' . getDolGlobalString('MEMBER_NEWFORM_FORCEMORPHY').'">';
861 }
862
863 // Company // TODO : optional hide
864 print '<tr id="trcompany" class="trcompany"><td id="tdcompany" class="titlefieldmiddle paddingrightonly'.($checkednature == "mor" ? ' fieldrequired"' : '').'">'.$langs->trans("Company").'</td><td>';
865 print img_picto('', 'company', 'class="pictofixedwidth paddingright"');
866 print '<input type="text" name="societe" class="minwidth150 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('societe')).'"></td></tr>'."\n";
867
868 // Title
869 if (getDolGlobalString('MEMBER_NEWFORM_ASK_TITLE')) {
870 print '<tr><td>'.$langs->trans('UserTitle').'</td><td>';
871 print $formcompany->select_civility(GETPOST('civility_id'), 'civility_id').'</td></tr>'."\n";
872 }
873
874 // Firstname
875 print '<tr><td id="tdfirstname" class="classfortooltip'.($checkednature == "phy" ? ' fieldrequired"' : '').'">'.$langs->trans("Firstname").'</td><td><input type="text" name="firstname" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('firstname')).'" spellcheck="false"></td></tr>'."\n";
876
877 // Lastname
878 print '<tr><td id="tdlastname" class="classfortooltip'.($checkednature == "phy" ? ' fieldrequired"' : '').'">'.$langs->trans("Lastname").'</td><td><input type="text" name="lastname" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('lastname')).'" spellcheck="false"></td></tr>'."\n";
879
880 // EMail
881 print '<tr><td>'.(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '<span class="fieldrequired">' : '').$langs->trans("EMail").(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '</span>' : '').'</td>';
882 print '<td>'.img_picto('', 'object_email').' <input type="text" name="member_email" class="minwidth150 maxwidth300 widthcentpercentminusx" maxlength="255" value="'.dol_escape_htmltag(GETPOST('member_email', "aZ09arobase")).'" spellcheck="false"></td></tr>'."\n";
883
884 // Login
885 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
886 print '<tr><td><span class="fieldrequired">'.$langs->trans("Login").' / '.$langs->trans("Id").'</span></td><td><input type="text" name="login" maxlength="50" class="minwidth100" value="'.(GETPOSTISSET("login") ? GETPOST("login", 'alphanohtml', 2) : $object->login).'"></td></tr>'."\n";
887 print '<tr><td><span class="fieldrequired">'.$langs->trans("Password").'</span></td><td><input type="password" maxlength="128" name="pass1" class="minwidth100" value="'.dol_escape_htmltag(GETPOST("pass1", "none", 2)).'"></td></tr>'."\n";
888 print '<tr><td><span class="fieldrequired">'.$langs->trans("PasswordRetype").'</span></td><td><input type="password" maxlength="128" name="pass2" class="minwidth100" value="'.dol_escape_htmltag(GETPOST("pass2", "none", 2)).'"></td></tr>'."\n";
889 }
890
891 // Gender
892 print '<tr><td>'.$langs->trans("Gender").'</td>';
893 print '<td>';
894 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
895 print $form->selectarray('gender', $arraygender, GETPOST('gender', 'alphanohtml'), 1, 0, 0, '', 0, 0, 0, '', 'minwidth150 maxwidth300 widthcentpercentminusx', 1);
896 print '</td></tr>';
897
898 // Address
899 print '<tr><td>'.$langs->trans("Address").'</td><td>'."\n";
900 print '<textarea name="address" id="address" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST('address', 'restricthtml'), 0, 1).'</textarea></td></tr>'."\n";
901
902 // Zip / Town
903 print '<tr><td>'.$langs->trans('Zip').' / '.$langs->trans('Town').'</td><td>';
904 print $formcompany->select_ziptown(GETPOST('zipcode'), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 1, '', 'width75');
905 print ' / ';
906 print $formcompany->select_ziptown(GETPOST('town'), 'town', array('zipcode', 'selectcountry_id', 'state_id'), 0, 1);
907 print '</td></tr>';
908
909 $country_id = GETPOSTINT('country_id');
910
911 // Country
912 print '<tr><td class="fieldrequired">'.$langs->trans('Country').'</td><td>';
913 print img_picto('', 'country', 'class="pictofixedwidth paddingright"');
914 if (!$country_id && getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE')) {
915 $country_id = (int) getCountry(getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE'), '3', $db, $langs);
916 }
917 if (!$country_id && !empty($conf->geoipmaxmind->enabled)) {
918 $country_code = dol_user_country();
919 //print $country_code;
920 if ($country_code) {
921 $new_country_id = getCountry($country_code, '3', $db, $langs);
922 //print 'xxx'.$country_code.' - '.$new_country_id;
923 if ($new_country_id) {
924 $country_id = $new_country_id;
925 }
926 }
927 }
928 $country_code = getCountry($country_id, '2', $db, $langs);
929 print $form->select_country($country_id, 'country_id', '', 0, 'minwidth150 maxwidth300 widthcentpercentminusx reposition');
930 print '</td></tr>';
931
932 // State
933 if (!getDolGlobalString('SOCIETE_DISABLE_STATE')) {
934 print '<tr><td>'.$langs->trans('State').'</td><td>';
935 if ($country_code) {
936 print img_picto('', 'state', 'class="pictofixedwidth paddingright"');
937 print $formcompany->select_state(GETPOSTINT("state_id"), $country_code, 'state_id', 'minwidth150 maxwidth300 widthcentpercentminusx');
938 }
939 print '</td></tr>';
940 }
941
942 // Pro phone
943 print '<tr><td>'.$langs->trans("PhonePro").'</td>';
944 print '<td>'.img_picto('', 'object_phoning', 'class="pictofixedwidth"').'<input type="text" name="phone" class="maxwidth300 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('phone')).'"></td></tr>';
945
946 // Personal phone
947 print '<tr><td>'.$langs->trans("PhonePerso").'</td>';
948 print '<td>'.img_picto('', 'object_phoning', 'class="pictofixedwidth"').'<input type="text" name="phone_perso" class="maxwidth300 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('phone_perso')).'"></td></tr>';
949
950 // Mobile phone
951 print '<tr><td>'.$langs->trans("PhoneMobile").'</td>';
952 print '<td>'.img_picto('', 'object_phoning_mobile', 'class="pictofixedwidth"').'<input type="text" name="phone_mobile" class="maxwidth300 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('phone_mobile')).'"></td></tr>';
953
954 // Birthday
955 print '<tr id="trbirth" class="trbirth"><td>'.$langs->trans("DateOfBirth").'</td><td>';
956 print $form->selectDate(!empty($birthday) ? $birthday : "", 'birth', 0, 0, 1, "newmember", 1, 0);
957 print '</td></tr>'."\n";
958
959 // Photo
960 print '<tr><td>'.$langs->trans("URLPhoto").'</td><td><input type="text" name="photo" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('photo')).'"></td></tr>'."\n";
961
962 // Public
963 if (getDolGlobalString('MEMBER_PUBLIC_ENABLED')) {
964 $linkofpubliclist = DOL_MAIN_URL_ROOT.'/public/members/public_list.php'.((isModEnabled('multicompany')) ? '?entity='.$conf->entity : '');
965 $publiclabel = $langs->trans("Public", getDolGlobalString('MAIN_INFO_SOCIETE_NOM'), $linkofpubliclist);
966 print '<tr><td>'.$form->textwithpicto($langs->trans("MembershipPublic"), $publiclabel).'</td><td><input type="checkbox" name="public"></td></tr>'."\n";
967 }
968
969 // Other attributes
970 $parameters['tpl_context'] = 'public'; // define template context to public
971 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
972
973 // Comments
974 print '<tr>';
975 print '<td class="tdtop"></td>';
976 print '<td class="tdtop"><textarea placeholder="'.dolPrintHTML($langs->trans("Comments")).'" name="note_private" id="note_private" wrap="soft" class="quatrevingtpercent" rows="'.ROWS_3.'">'.dol_escape_htmltag(GETPOST('note_private', 'restricthtml'), 0, 1).'</textarea></td>';
977 print '</tr>'."\n";
978
979
980 // Define amount by default to suggest
981 $typeid = getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE', GETPOSTINT('typeid'));
982 $adht = new AdherentType($db);
983 $adht->fetch($typeid);
984 $caneditamount = $adht->caneditamount;
985 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
986 $minimumamountbytype = $adht->minimumamountbytype(1); // Load the array of minimum amount per type
987 foreach ($amountbytype as $k => $v) {
988 $amount = max(0, (float) $v, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"), $minimumamountbytype[$k]);
989 $amountbytype[$k] = $amount;
990 }
991
992 $caneditamountbytype = $adht->caneditamountByType(1); // Load the array of caneditamount per type
993 $amountformuladescriptionbytype = $adht->amountformuladescriptionbytype(1); // Load the array of amount ormula description per type
994
995 // Set amount for the subscription from the type and options:
996 // - First check the amount of the member type.
997 $amount = empty($amountbytype[$typeid]) ? 0 : $amountbytype[$typeid];
998 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
999 if (empty($amount)) {
1000 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
1001 }
1002 // - If a min is set, we take it into account
1003 $minimumamount = empty($minimumamountbytype[$typeid]) ? 0 : $minimumamountbytype[$typeid];
1004 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"), (float) $minimumamount);
1005
1006 // Clean the amount
1007 $amount = price2num($amount);
1008
1009
1010 // Add hook to complete the form
1011 $parameters = array('country_id' => $country_id, 'mode' => 'new');
1012 $reshook = $hookmanager->executeHooks('membershipNewSubscriptionPublicForm', $parameters, $object, $action);
1013 if ($reshook < 0) {
1014 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1015 $error++;
1016 }
1017 // TODO Move this into previous hook
1018 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1019 $s = $langs->trans("AreYouAPreferredPartner", '<a href="https://partners.dolibarr.org" target="_blank">{s1}</a>');
1020 $s = str_replace('{s1}', 'Preferred Partner', $s);
1021 print '<tr id="trbudget" class="trcompany"><td class="paddingrightonly"><label for="pp" class="small">'.$s.'</label></td><td>';
1022 print '<input type="checkbox" name="pp" id="pp" value="1"'.(GETPOST('pp') ? ' checked="checked"' : '').' class="reposition">';
1023 print '</td></tr>';
1024
1025 print '<tr id="trbudget" class="trcompany"><td class="fieldrequired paddingrightonly"><span class="small">'.$langs->trans("TurnoverOrBudget").'</span></td><td>';
1026
1027 $country_code = dol_getIdFromCode($db, $country_id, 'c_country', 'rowid', 'code');
1028 if ($country_code === 'FR' && $checkednature === 'mor' && GETPOST('pp')) {
1029 print '<input type="text" name="budget" id="budget" class="flat turnover right width100" value="'.GETPOST('budget').'" required>';
1030 } else {
1031 $arraybudget = array('50' => '<= 100 000', '100' => '<= 200 000', '200' => '<= 500 000', '300' => '<= 1 500 000', '600' => '<= 3 000 000', '1000' => '<= 5 000 000', '2000' => '5 000 000+');
1032 print $form->selectarray('budget', $arraybudget, GETPOSTINT('budget'), 1, 0, 0, '', 0, 0, 0, '');
1033 }
1034 print ' € or $';
1035
1036 print '<script type="text/javascript">
1037 jQuery(document).ready(function() {
1038 firstload = true;
1039
1040 newamount = initturnover();
1041 jQuery("#amount").val(newamount);
1042
1043 firstload = false;
1044
1045 jQuery("#selectcountry_id").change(function() {
1046 console.log("We change country (code added for association, replace common code), so we reload page");
1047 jQuery("#budget").val(\'\');
1048 jQuery("#amount").val(\'\');
1049 jQuery("#amounthidden").val(\'\');
1050 });
1051 jQuery("#phisicalinput,#moralinput").click(function() {
1052 console.log("We change the nature of membership");
1053 newamount = initturnover();
1054 jQuery("#amount").val(newamount);
1055 });
1056 jQuery("#pp").change(function() {
1057 console.log("We change the preferred partner status");
1058 selectcountry_id = jQuery("#selectcountry_id").val();
1059 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1060 jQuery("#budget").val(\'\');
1061 jQuery("#amount").val(\'\');
1062 jQuery("#amounthidden").val(\'\');
1063 document.newmember.action.value="create";
1064 jQuery("#newmember").submit();
1065 });
1066 jQuery("#budget").change(function() {
1067 console.log("Turnover amount has been modified on change");
1068 newamount = initturnover();
1069 jQuery("#amount").val(newamount);
1070 jQuery("#amounthidden").val(newamount);
1071 });
1072 jQuery("#budget").keyup(function() {
1073 console.log("Turnover amount has been modified on keyup");
1074 newamount = initturnover();
1075 jQuery("#amount").val(newamount);
1076 jQuery("#amounthidden").val(newamount);
1077 });
1078
1079 function initturnover() {
1080 newamount = 0;
1081
1082 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1083 selectcountry_id = jQuery("#selectcountry_id").val();
1084 pp = jQuery("#pp").is(\':checked\') ? true : false;
1085 console.log("Set fields according to nature and other properties");
1086 console.log("morphy="+morphy);
1087 console.log("selectcountry_id="+selectcountry_id);
1088 console.log("pp="+pp);
1089
1090 if (morphy == \'phy\') {
1091 jQuery(".amount").val('.((float) $amount).');
1092 jQuery("#trbirth").show();
1093 jQuery(".trcompany").hide();
1094 jQuery(".trbudget").hide();
1095 newamount = '.((float) $amount).';
1096 } else {
1097 jQuery(".amount").val(\'\');
1098 jQuery("#trbirth").hide();
1099 jQuery(".trcompany").show();
1100 jQuery(".trbudget").show();
1101 jQuery(".hideifautoturnover").hide();
1102 if (firstload) {
1103 jQuery("#budget").val(\'\');
1104 }
1105
1106 if (selectcountry_id == 1) {
1107 if (pp) {
1108 console.log("value selected in input text field is "+jQuery("#budget").val());
1109 newamount = Math.max(Math.round(price2numjs(jQuery("#budget").val()) * 0.005), 50);
1110 console.log("newamount = "+newamount);
1111 } else {
1112 console.log("not a pp");
1113 if (jQuery("#budget").val() > 0) {
1114 console.log("value found in budget is "+jQuery("#budget").val());
1115 newamount = jQuery("#budget").val();
1116 } else {
1117 jQuery("#budget").val(\'\');
1118 newamount = \'\';
1119 }
1120 }
1121 } else {
1122 if (jQuery("#budget").val() > 0) {
1123 newamount = jQuery("#budget").val();
1124 } else {
1125 jQuery("#budget").val(\'\');
1126 newamount = \'\';
1127 }
1128 console.log("newamount="+newamount);
1129 }
1130 }
1131
1132 return newamount;
1133 }
1134 });
1135 </script>';
1136 print '</td></tr>'."\n";
1137 }
1138
1139 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE')) { // Can be 'all', 'paypal', 'paybox', 'stripe'...
1140 print '<tr><td>'.$langs->trans("Subscription");
1141 if (getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO')) {
1142 print '<br>';
1143 print '<a href="' . getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO').'" rel="external" target="_blank" rel="noopener noreferrer">';
1144 print img_picto('', 'url', 'class="pictofixedwidth"').$langs->trans("SeeHere");
1145 print '</a>';
1146 }
1147 print '</td><td class="nowrap">';
1148
1149 $amountformuladescription = $amountformuladescriptionbytype[$typeid];
1150
1151 $showedamount = $amount > 0 ? $amount : 0;
1152 if ($caneditamount === "1") {
1153 print '<input type="text" name="amount" id="amount" class="flat amount right width75" value="'.$showedamount.'">';
1154 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75 hidden" disabled value="'.$showedamount.'">';
1155 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium amountdescription hideifautoturnover small">';
1156 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1157 print ' - ';
1158 if (empty($amountformuladescription)) {
1159 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1160 } else {
1161 print $amountformuladescription;
1162 }
1163 }
1164 if (getDolGlobalInt("MEMBER_MIN_AMOUNT") > 0 || $minimumamount > 0) {
1165 print '</span><br><span id="minimumamount" class="opacitymedium small">'.$langs->trans("MinimumAmountShort").' : '.price(max(getDolGlobalInt("MEMBER_MIN_AMOUNT"), $minimumamount), 0, $langs, 1, -1, -1, $conf->currency);
1166 }
1167 print '</span>';
1168 } else {
1169 print '<input type="text" name="amount" id="amount" class="flat amount width75 right hidden" value="'.$showedamount.'">';
1170 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75" disabled value="'.$showedamount.'">';
1171 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium amountdescription hideifautoturnover hidden small">';
1172 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1173 print ' - ';
1174 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1175 }
1176 print '</span>';
1177 }
1178 print '</td></tr>';
1179 }
1180
1181 // Display Captcha code if is enabled
1182 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
1183 print '<tr><td><label><span class="fieldrequired">'.$langs->trans("SecurityCode").'</span></label></td><td><br>';
1184 if (method_exists($captchaobj, 'getCaptchaCodeForForm')) {
1185 print $captchaobj->getCaptchaCodeForForm(''); // @phan-suppress-current-line PhanUndeclaredMethod
1186 } else {
1187 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method getCaptchaCodeForForm()';
1188 }
1189 print '<br></td></tr>';
1190 }
1191
1192 print "</table>\n";
1193
1194 print dol_get_fiche_end();
1195
1196 // Save / Submit
1197 print '<div class="center">';
1198 print '<input type="submit" value="'.$langs->trans("GetMembershipButtonLabel").'" id="submitsave" class="button">';
1199 if (!empty($backtopage)) {
1200 print ' &nbsp; &nbsp; <input type="submit" value="'.$langs->trans("Cancel").'" id="submitcancel" class="button button-cancel">';
1201 }
1202 print '</div>';
1203
1204 // Add JS to manage the background of amount depending on type
1205 $typeid = getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE', GETPOSTINT('typeid'));
1206 $adht = new AdherentType($db);
1207 $adht->fetch($typeid);
1208 $caneditamountbytype = $adht->caneditamountByType(1); // Load the array of caneditamount per type
1209 $minimumamountbytype = $adht->minimumamountbytype(1); // Load the array of minimum amount per type
1210 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
1211 $amountformuladescriptionbytype = $adht->amountformuladescriptionbytype(1); // Load the array of amount ormula description per type
1212 // Common PHP → JS variables
1213 $caneditamountbytype_json = json_encode($caneditamountbytype);
1214 $minimumamountbytype_json = json_encode($minimumamountbytype);
1215 $amountbytype_json = json_encode($amountbytype);
1216 $amountformuladescriptionbytype_json = json_encode($amountformuladescriptionbytype);
1217 $currencysymbol = $langs->getCurrencySymbol($conf->currency);
1218
1219 if ($conf->use_javascript_ajax) {
1220 print '<script>
1221 // ----- Shared data -----
1222 var amountByType = ' . $amountbytype_json . ';
1223 var canEditAmountByType = ' . $caneditamountbytype_json . ';
1224 var amountFormulaDescriptionByType = ' . $amountformuladescriptionbytype_json . ';
1225 var minimumAmountByType = ' . $minimumamountbytype_json . ';
1226 var memberMinAmount = ' . getDolGlobalInt("MEMBER_MIN_AMOUNT") . ';
1227 var currencySymbol = ' . json_encode($currencysymbol) . ';
1228
1229 // Translations prepared by PHP
1230 var langs = {
1231 AnyAmountWithAdvisedAmount: ' . json_encode($langs->trans("AnyAmountWithAdvisedAmount", "__VAL__")) . ',
1232 AnyAmountWithoutAdvisedAmount: ' . json_encode($langs->trans("AnyAmountWithoutAdvisedAmount")) . ',
1233 MinimumAmountShort: ' . json_encode($langs->trans("MinimumAmountShort", "__VAL__")) . ',
1234 trans: function(key, val) {
1235 if (!this[key]) return key;
1236 return this[key].replace("__VAL__", val || "");
1237 }
1238 };
1239
1240 jQuery(function($) {
1241 // ----- Helpers -----
1242 function getCurrentMin() {
1243 let typeId = $("#typeid").val() || 0;
1244 let minimumAmount = minimumAmountByType[typeId] || 0;
1245 return Math.max(memberMinAmount, minimumAmount);
1246 }
1247
1248 function checkAmount() {
1249 let raw = $("#amount").val() || "";
1250 let val = parseFloat(raw.replace(",", ".")) || 0;
1251 let minimum = getCurrentMin();
1252 if (val < minimum) {
1253 $("#submitsave").prop("disabled", true);
1254 } else {
1255 $("#submitsave").prop("disabled", false);
1256 }
1257 }
1258
1259 function updateAmountAndTexts() {
1260 let typeId = $("#typeid").val();
1261 let amountVal = amountByType[typeId] || 0;
1262 let formattedAmount = parseFloat(amountVal);
1263 let canEdit = canEditAmountByType[typeId] === "1";
1264 let amountFormulaDescription = amountFormulaDescriptionByType[typeId] || "";
1265 let minimumAmount = minimumAmountByType[typeId] || 0;
1266 let minimum = Math.max(memberMinAmount, minimumAmount);
1267
1268 if (canEdit) {
1269 // Editable mode
1270 $("#amount").val(formattedAmount).prop("disabled", false).removeClass("hidden");
1271 $("#amounthidden").addClass("hidden");
1272 $(".hideifautoturnover").removeClass("hidden");
1273
1274 // Description formula or default text
1275 if (amountFormulaDescription.trim() !== "") {
1276 $(".amountdescription").html(" - " + amountFormulaDescription);
1277 } else {
1278 if (amountVal > 0) {
1279 $(".amountdescription").html(" - " + langs.trans("AnyAmountWithAdvisedAmount", formattedAmount + " " + currencySymbol));
1280 } else {
1281 $(".amountdescription").html(" - " + langs.trans("AnyAmountWithoutAdvisedAmount"));
1282 }
1283 }
1284
1285 // Minimum amount label
1286 if (minimum > 0) {
1287 $("#minimumamount")
1288 .html(langs.trans("MinimumAmountShort") + " : " + minimum + " " + currencySymbol)
1289 .removeClass("hidden");
1290 } else {
1291 $("#minimumamount").addClass("hidden");
1292 }
1293 } else {
1294 // Read-only mode
1295 $("#amounthidden").val(formattedAmount).prop("disabled", true).removeClass("hidden");
1296 $("#amount").addClass("hidden");
1297 $(".hideifautoturnover").addClass("hidden");
1298 $("#minimumamount").addClass("hidden");
1299 }
1300
1301 // After updating fields, re‑check the amount validity
1302 checkAmount();
1303 }
1304
1305 // ----- Bind events -----
1306 $("#typeid").on("change", function() {
1307 console.log("Type of membership changed, update amount, description and minimum");
1308 updateAmountAndTexts();
1309 });
1310
1311 $("#amount").on("keyup change", function() {
1312 checkAmount();
1313 });
1314 });
1315 </script>';
1316 }
1317
1318 print "</form>\n";
1319 print "<br>";
1320 print '</div></div>';
1321} else { // Show the table of membership types
1322 // Get units
1323 $measuringUnits = new CUnits($db);
1324 $result = $measuringUnits->fetchAll('', '', 0, 0, array('t.active' => 1));
1325 $units = array();
1326 foreach ($measuringUnits->records as $lines) {
1327 $units[$lines->short_label] = $langs->trans(ucfirst((string) $lines->label));
1328 }
1329
1330 $publiccounters = getDolGlobalString("MEMBER_COUNTERS_ARE_PUBLIC");
1331 $hidevoteallowed = getDolGlobalString("MEMBER_HIDE_VOTE_ALLOWED");
1332
1333 $sql = "SELECT d.rowid, d.libelle as label, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut as status, d.morphy,";
1334 $sql .= " COUNT(a.rowid) AS membercount";
1335 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
1336 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as a";
1337 $sql .= " ON d.rowid = a.fk_adherent_type AND a.statut > 0";
1338 $sql .= " WHERE d.entity IN (".getEntity('member_type').")";
1339 $sql .= " AND d.statut=1";
1340 $sql .= " GROUP BY d.rowid, d.libelle, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut, d.morphy";
1341
1342 $result = $db->query($sql);
1343 if ($result) {
1344 $num = $db->num_rows($result);
1345
1346 print '<br><div class="div-table-responsive">';
1347 print '<table class="tagtable liste">'."\n";
1348 print '<input type="hidden" name="action" value="create">';
1349
1350 print '<tr class="liste_titre">';
1351 print '<th>'.$langs->trans("Label").'</th>';
1352 print '<th class="center">'.$langs->trans("MembershipDuration").'</th>';
1353 print '<th class="center">'.$langs->trans("RecommendedAmount").'</th>';
1354 print '<th class="center">'.$langs->trans("MembersNature").'</th>';
1355 if (empty($hidevoteallowed)) {
1356 print '<th class="center">'.$langs->trans("VoteAllowed").'</th>';
1357 }
1358 if ($publiccounters) {
1359 print '<th class="center">'.$langs->trans("Members").'</th>';
1360 }
1361 print '<th class="center">'.$langs->trans("NewSubscription").'</th>';
1362 print "</tr>\n";
1363
1364 $i = 0;
1365 while ($i < $num) {
1366 $objp = $db->fetch_object($result); // Load the member type and information on it
1367
1368 $caneditamount = $objp->caneditamount;
1369 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
1370 $minimumamountbytype = $adht->minimumamountbytype(1); // Load the array of amount per type
1371
1372 print '<tr class="oddeven">';
1373 // Label
1374 print '<td>'.dolPrintHTML($objp->label).'</td>';
1375 // Duration
1376 print '<td class="center">';
1377 $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration);
1378 print max(1, intval($objp->duration)).' '.$units[$unit];
1379 print '</td>';
1380 // Amount
1381 print '<td class="center"><span class="amount nowrap">';
1382
1383 // Set amount for the subscription from the the type and options:
1384 // - First check the amount of the member type.
1385 $amount = empty($amountbytype[$objp->rowid]) ? 0 : $amountbytype[$objp->rowid];
1386 $minimumamount = empty($minimumamountbytype[$objp->rowid]) ? 0 : $minimumamountbytype[$objp->rowid];
1387 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
1388 if (empty($amount)) {
1389 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
1390 }
1391 // - If a min is set, we take it into account
1392 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"), (float) $minimumamount);
1393
1394 $displayedamount = $amount;
1395
1396 if ($objp->subscription) {
1397 if ($displayedamount > 0 || !$caneditamount) {
1398 print price($displayedamount, 1, $langs, 1, 0, -1, $conf->currency);
1399 }
1400 if ($caneditamount && $displayedamount > 0) {
1401 print $form->textwithpicto('', $langs->transnoentities("CanEditAmountShortForValues"), 1, 'help', '', 0, 3);
1402 } elseif ($caneditamount) {
1403 print $langs->transnoentities("CanEditAmountShort");
1404 }
1405 } else {
1406 print "–"; // No subscription required
1407 }
1408 print '</span></td>';
1409 print '<td class="center">';
1410 if ($objp->morphy == 'phy') {
1411 print $langs->trans("Physical");
1412 } elseif ($objp->morphy == 'mor') {
1413 print $langs->trans("Moral");
1414 } else {
1415 print $langs->trans("MorAndPhy");
1416 }
1417 print '</td>';
1418 if (empty($hidevoteallowed)) {
1419 print '<td class="center">'.yn($objp->vote).'</td>';
1420 }
1421 $membercount = $objp->membercount > 0 ? $objp->membercount : "–";
1422 if ($publiccounters) {
1423 print '<td class="center">'.$membercount.'</td>';
1424 }
1425 print '<td class="center"><button class="button button-save reposition" name="typeid" type="submit" name="submit" value="'.$objp->rowid.'">'.$langs->trans("GetMembershipButtonLabel").'</button></td>';
1426 print "</tr>";
1427 $i++;
1428 }
1429
1430 // If no record found
1431 if ($num == 0) {
1432 $colspan = 8;
1433 print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
1434 }
1435
1436 print "</table>";
1437 print '</div>';
1438
1439 print '</form>';
1440 } else {
1442 }
1443}
1444
1445//htmlPrintOnlineFooter($mysoc, $langs);
1447
1448$db->close();
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class to manage members of a foundation.
Class to manage members type.
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class of dictionary type of thirdparty (used by imports)
Class to manage standard extra fields.
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Class to manage a HTML form to send a unitary email Usage: $formail = new FormMail($db) $formmail->pr...
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
llxHeaderVierge($title, $head="", $disablejs=0, $disablehead=0, $arrayofjs=[], $arrayofcss=[], $ws='')
Show header for new prospect.
Definition new.php:123
llxFooterVierge()
Show footer for new societe.
Definition new.php:144
htmlPrintOnlineHeader($mysoc, $langs, $showlogo=1, $alttext='', $subimageconst='', $altlogo1='', $altlogo2='')
Show the header of a company in HTML public pages.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
global $mysoc
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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...
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='', $useCache=true)
Return an id or code from a code or id.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_user_country()
Return country code for current user.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
printCommonFooter($zone='private')
Print common footer : conf->global->MAIN_HTML_FOOTER js for switch of menu hider js for conf->global-...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dol_htmloutput_events($disabledoutputofmessages=0)
Print formatted messages to output (Used to show messages on html output).
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getUserRemoteIP($trusted=0)
Return the real IP of remote user.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_htmloutput_errors($mesgstring='', $mesgarray=array(), $keepembedded=0)
Print formatted error messages to output (Used to show messages on html output).
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs=array(), $arrayofcss=array(), $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Output html header of a page.
if(getDolGlobalString( 'MAIN_SECURITY_ENABLECAPTCHA_MEMBER')) force_switch_entity($newEntity)
Force switching conf of entity, even if user is connected Fox example when trying to go on public for...
Definition new.php:153
httponly_accessforbidden($message='1', $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.