dolibarr 23.0.3
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-2025 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-2025 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
43if (!defined('NOLOGIN')) {
44 define("NOLOGIN", 1); // This means this output page does not require to be logged.
45}
46if (!defined('NOCSRFCHECK')) {
47 define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
48}
49if (!defined('NOBROWSERNOTIF')) {
50 define('NOBROWSERNOTIF', '1');
51}
52
53
54// For MultiCompany module.
55// Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
56// Because 2 entities can have the same ref.
57$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
58define("DOLENTITY", $entity);
59
60
61// Load Dolibarr environment
62require '../../main.inc.php';
71require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
72require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
73require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
74require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
75require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
76require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
77require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php';
78require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
79
80// Init vars
81$backtopage = GETPOST('backtopage', 'alpha');
82$action = GETPOST('action', 'aZ09');
83
84$errmsg = '';
85$num = 0;
86$error = 0;
87
88// Load translation files
89$langs->loadLangs(array("main", "members", "companies", "install", "other", "errors"));
90
91if (isModEnabled('multicompany')) {
92 force_switch_entity($entity);
93}
94
95// Security check
96if (!isModEnabled('member')) {
97 httponly_accessforbidden('Module Membership not enabled');
98}
99
100if (!getDolGlobalString('MEMBER_ENABLE_PUBLIC')) {
101 httponly_accessforbidden("Auto subscription form for public visitors has not been enabled");
102}
103
104// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
105$hookmanager->initHooks(array('publicnewmembercard', 'globalcard'));
106
107$extrafields = new ExtraFields($db);
108
109$object = new Adherent($db);
110
111$user->loadDefaultValues();
112
113$captchaobj = null;
114if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER')) {
115 require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
116 $captcha = getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_HANDLER', 'standard');
117 // List of directories where we can find captcha handlers
118 $dirModCaptcha = array_merge(
119 array(
120 'main' => '/core/modules/security/captcha/'
121 ),
122 is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()
123 );
124 $fullpathclassfile = '';
125 foreach ($dirModCaptcha as $dir) {
126 $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2);
127 if ($fullpathclassfile) {
128 break;
129 }
130 }
131 if ($fullpathclassfile) {
132 include_once $fullpathclassfile;
133 // Charging the numbering class
134 $classname = "modCaptcha".ucfirst($captcha);
135 if (class_exists($classname)) {
136 $captchaobj = new $classname($db, $conf, $langs, $user);
137 '@phan-var-force ModeleCaptcha $captchaobj';
139 } else {
140 print 'Error, the captcha handler class '.$classname.' was not found after the include';
141 }
142 } else {
143 print 'Error, the captcha handler '.$captcha.' has no class file found modCaptcha'.ucfirst($captcha);
144 }
145}
146
154function force_switch_entity($newEntity)
155{
156 global $db, $conf;
157
158 if ($newEntity != $conf->entity) {
159 $conf->entity = $newEntity;
160 $conf->setValues($db);
161 }
162}
163
177function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = [], $arrayofcss = []) // @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
217/*
218 * Actions
219 */
220
221$parameters = array();
222// Note that $action and $object may have been modified by some hooks
223$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
224if ($reshook < 0) {
225 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
226}
227
228// Verify if we can find member
229
230if (empty($reshook) && getDolGlobalInt("MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATE") && $action == 'add' && !GETPOSTISSET("nofetchmember")) { // Test on permission not required here
231 $memberfound = false;
232
233 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED') && GETPOSTISSET('login')) {
234 // Note that this allow to guess anonymous ID already used. But this is not a problem as it is an anonymous pseudonym.
235 // If we try to new account and option MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATE was off, we also get the same error.
236 $sql = "SELECT rowid as id";
237 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
238 $sql .= " WHERE a.login = '".$db->escape(GETPOST('login'))."'";
239 $sql .= " AND statut = 1";
240 $sql .= " AND entity IN (".getEntity($object->element).")";
241 $resql = $db->query($sql);
242 if ($resql) {
243 if ($db->num_rows($resql) == 1) {
244 $obj = $db->fetch_object($resql);
245 $object->fetch($obj->id);
246 $memberfound = true;
247 }
248 } else {
249 dol_print_error($db);
250 }
251 }
252
253 if (!$memberfound && GETPOST("morphy") == 'mor' && GETPOSTISSET("societe") ) {
254 $sql = "SELECT a.rowid as id";
255 $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
256 $sql .= " JOIN ".MAIN_DB_PREFIX."societe as s";
257 $sql .= " ON a.fk_soc = s.rowid";
258 $sql .= " WHERE s.nom = '".$db->escape(GETPOST("societe", 'alphanohtml'))."'";
259 $sql .= " AND a.email = '".$db->escape(preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase')))."'";
260 $sql .= " AND a.statut = 1";
261 $sql .= " AND a.entity IN (".getEntity($object->element).")";
262 $resql = $db->query($sql);
263 if ($resql) {
264 if ($db->num_rows($resql) == 1) {
265 $obj = $db->fetch_object($resql);
266 $object->fetch($obj->id);
267 $memberfound = true;
268 }
269 } else {
270 dol_print_error($db);
271 }
272 }
273
274 if (!$memberfound && GETPOST("morphy") == 'phy' && GETPOSTISSET("lastname") && GETPOSTISSET("firstname") && !empty(GETPOST("member_email", 'aZ09arobase'))) {
275 $sql = "SELECT rowid as id";
276 $sql .= " FROM ".MAIN_DB_PREFIX."adherent";
277 $sql .= " WHERE firstname = '".$db->escape(GETPOST("firstname", 'alphanohtml'))."'";
278 $sql .= " AND lastname = '".$db->escape(GETPOST("lastname", 'alphanohtml'))."'";
279 $sql .= " AND email = '".$db->escape(preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase')))."'";
280 $sql .= " AND statut = 1";
281 $sql .= " AND entity IN (".getEntity($object->element).")";
282 $resql = $db->query($sql);
283 if ($resql) {
284 if ($db->num_rows($resql) == 1) {
285 $obj = $db->fetch_object($resql);
286 $object->fetch($obj->id);
287 $memberfound = true;
288 }
289 } else {
290 dol_print_error($db);
291 }
292 }
293
294 if ($memberfound) {
295 $action = 'subscription';
296 }
297}
298
299// Action called when page is submitted
300if (empty($reshook) && $action == 'add') { // Test on permission not required here. This is an anonymous form. Check is done on constant to enable and mitigation.
301 $error = 0;
302 $urlback = '';
303
304 $db->begin();
305
306 $morphy = GETPOST("morphy", 'alphanohtml');
307 $lastname = GETPOST("lastname", 'alphanohtml');
308 $firstname = GETPOST("firstname", 'alphanohtml');
309 $societe = GETPOST("societe", 'alphanohtml');
310 $email = preg_replace('/\s+/', '', GETPOST("member_email", 'aZ09arobase'));
311 $country_id = getDolGlobalInt("MEMBER_NEWFORM_FORCECOUNTRYCODE", GETPOSTINT('country_id'));
312
313 if (!in_array($morphy, array('mor', 'phy'))) {
314 $error++;
315 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('MemberNature'))."<br>\n";
316 }
317
318 // test if login already exists
319 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
320 if (!GETPOST('member_email')) {
321 $error++;
322 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("EMail"))."<br>\n";
323 }
324 if (!GETPOST('login')) {
325 $error++;
326 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Login"))."<br>\n";
327 }
328 $sql = "SELECT login FROM ".MAIN_DB_PREFIX."adherent WHERE login = '".$db->escape(GETPOST('login'))."'";
329 $result = $db->query($sql);
330 if ($result) {
331 $num = $db->num_rows($result);
332 }
333 if ($num != 0) {
334 $error++;
335 $langs->load("errors");
336 $errmsg .= $langs->trans("ErrorLoginAlreadyExists")."<br>\n";
337 }
338 if (!GETPOSTISSET("pass1") || !GETPOSTISSET("pass2") || GETPOST("pass1", 'none') == '' || GETPOST("pass2", 'none') == '' || GETPOST("pass1", 'none') != GETPOST("pass2", 'none')) {
339 $error++;
340 $langs->load("errors");
341 $errmsg .= $langs->trans("ErrorPasswordsMustMatch")."<br>\n";
342 }
343 }
344 if (GETPOST('typeid') <= 0) {
345 $error++;
346 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"))."<br>\n";
347 }
348
349 if ($morphy && $morphy != 'mor' && empty($lastname)) {
350 $error++;
351 $langs->load("errors");
352 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Lastname"));
353 }
354 if ($morphy && $morphy != 'mor' && (!isset($firstname) || $firstname == '')) {
355 $error++;
356 $langs->load("errors");
357 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Firstname"));
358 }
359 if ($morphy == 'mor' && empty($societe)) {
360 $error++;
361 $langs->load("errors");
362 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Company"));
363 }
364 if (empty($country_id)) {
365 $error++;
366 $langs->load("errors");
367 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Country"));
368 }
369 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && $email && !isValidEmail($email)) {
370 $error++;
371 $langs->load("errors");
372 $errmsg .= $langs->trans("ErrorBadEMail", $email);
373 }
374 $birthday = dol_mktime(GETPOSTINT("birthhour"), GETPOSTINT("birthmin"), GETPOSTINT("birthsec"), GETPOSTINT("birthmonth"), GETPOSTINT("birthday"), GETPOSTINT("birthyear"));
375 if (GETPOST("birthmonth") && empty($birthday)) {
376 $error++;
377 $langs->load("errors");
378 $errmsg .= $langs->trans("ErrorBadDateFormat")."<br>\n";
379 }
380
381 // TODO Add this in a hook
382 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
383 if (GETPOST("morphy") == 'mor' && GETPOSTFLOAT('budget') <= 0) {
384 $error++;
385 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TurnoverOrBudget"))."<br>\n";
386 }
387 }
388
389 // Check Captcha code if is enabled
390 $ok = false;
391 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
392 if (method_exists($captchaobj, 'validateCodeAfterLoginSubmit')) {
393 $ok = $captchaobj->validateCodeAfterLoginSubmit(); // @phan-suppress-current-line PhanUndeclaredMethod
394 } else {
395 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method validateCodeAfterLoginSubmit()';
396 }
397 if (!$ok) {
398 $error++;
399 $langs->load("errors");
400 $errmsg .= $langs->trans("ErrorBadValueForCode")."<br>\n";
401 $action = '';
402 }
403 }
404
405 $public = GETPOSTISSET('public') ? 1 : 0;
406
407 if (!$error) {
408 // E-mail looks OK and login does not exist
409 $adh = new Adherent($db);
410 $adh->statut = -1;
411 $adh->status = -1;
412 $adh->public = $public;
413 $adh->firstname = GETPOST('firstname');
414 $adh->lastname = GETPOST('lastname');
415 $adh->gender = GETPOST('gender');
416 $adh->civility_id = GETPOST('civility_id');
417 $adh->company = GETPOST('societe');
418 $adh->societe = $adh->company;
419 $adh->address = GETPOST('address');
420 $adh->zip = GETPOST('zipcode');
421 $adh->town = GETPOST('town');
422 $adh->email = GETPOST('member_email', 'aZ09arobase');
423 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
424 $adh->login = GETPOST('login');
425 $adh->pass = GETPOST('pass1', 'password');
426 }
427 $adh->photo = GETPOST('photo');
428 $adh->country_id = getDolGlobalInt("MEMBER_NEWFORM_FORCECOUNTRYCODE", GETPOSTINT('country_id'));
429 $adh->state_id = GETPOSTINT('state_id');
430 $adh->typeid = getDolGlobalInt("MEMBER_NEWFORM_FORCETYPE", GETPOSTINT('typeid'));
431 $adh->note_private = GETPOST('note_private');
432 $adh->morphy = getDolGlobalString("MEMBER_NEWFORM_FORCEMORPHY", GETPOST('morphy'));
433 $adh->birth = $birthday;
434 $adh->phone = GETPOST('phone');
435 $adh->phone_perso = GETPOST('phone_perso');
436 $adh->phone_mobile= GETPOST('phone_mobile');
437
438 $adh->ip = getUserRemoteIP();
439
440 $nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
441 $now = dol_now();
442 $minmonthpost = dol_time_plus_duree($now, -1, "m");
443 // Calculate nb of post for IP
444 $nb_post_ip = 0;
445 if ($nb_post_max > 0) { // Calculate only if there is a limit to check
446 $sql = "SELECT COUNT(ref) as nb_adh";
447 $sql .= " FROM ".MAIN_DB_PREFIX."adherent";
448 $sql .= " WHERE ip = '".$db->escape($adh->ip)."'";
449 $sql .= " AND datec > '".$db->idate($minmonthpost)."'";
450 $resql = $db->query($sql);
451 if ($resql) {
452 $num = $db->num_rows($resql);
453 $i = 0;
454 while ($i < $num) {
455 $i++;
456 $obj = $db->fetch_object($resql);
457 $nb_post_ip = $obj->nb_adh;
458 }
459 }
460 }
461
462
463 // Fill array 'array_options' with data from add form
464 $extrafields->fetch_name_optionals_label($adh->table_element);
465 $ret = $extrafields->setOptionalsFromPost(null, $adh);
466 if ($ret < 0) {
467 $error++;
468 $errmsg .= $adh->error;
469 }
470
471 if ($nb_post_max > 0 && $nb_post_ip >= $nb_post_max) {
472 $error++;
473 $errmsg .= $langs->trans("AlreadyTooMuchPostOnThisIPAdress");
474 array_push($adh->errors, $langs->trans("AlreadyTooMuchPostOnThisIPAdress"));
475 }
476
477 if (!$error) {
478 $result = $adh->create($user);
479 if ($result > 0) {
480 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
481 $object = $adh;
482
483 $adht = new AdherentType($db);
484 $adht->fetch($object->typeid);
485
486 if ($object->email) {
487 $subject = '';
488 $msg = '';
489
490 // Send subscription email
491 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
492 $formmail = new FormMail($db);
493 // Set output language
494 $outputlangs = new Translate('', $conf);
495 $outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
496 // Load traductions files required by page
497 $outputlangs->loadLangs(array("main", "members"));
498 // Get email content from template
499 $arraydefaultmessage = null;
500 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_AUTOREGISTER');
501
502 if (!empty($labeltouse)) {
503 $arraydefaultmessage = $formmail->getEMailTemplate($db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
504 }
505
506 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
507 $subject = $arraydefaultmessage->topic;
508 $msg = $arraydefaultmessage->content;
509 }
510
511 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
512 complete_substitutions_array($substitutionarray, $outputlangs, $object);
513 $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
514 $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnValid()), $substitutionarray, $outputlangs);
515
516 if ($subjecttosend && $texttosend) {
517 $moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n";
518
519 $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
520 }
521 /*if ($result < 0) {
522 $error++;
523 setEventMessages($object->error, $object->errors, 'errors');
524 }*/
525 }
526
527 // Send email to the foundation to say a new member subscribed with autosubscribe form
528 if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') && getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT') &&
529 getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')) {
530 // Define link to login card
531 $appli = constant('DOL_APPLICATION_TITLE');
532 if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
533 $appli = getDolGlobalString('MAIN_APPLICATION_TITLE');
534 if (preg_match('/\d\.\d/', $appli)) {
535 if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'/', $appli)) {
536 $appli .= " (".DOL_VERSION.")"; // If new title contains a version that is different than core
537 }
538 } else {
539 $appli .= " ".DOL_VERSION;
540 }
541 } else {
542 $appli .= " ".DOL_VERSION;
543 }
544
545 $to = $adh->makeSubstitution(getDolGlobalString('MAIN_INFO_SOCIETE_MAIL'));
546 $from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
547 $mailfile = new CMailFile(
548 '['.$appli.'] ' . getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT'),
549 $to,
550 $from,
551 $adh->makeSubstitution(getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')),
552 array(),
553 array(),
554 array(),
555 "",
556 "",
557 0,
558 -1
559 );
560
561 if (!$mailfile->sendfile()) {
562 dol_syslog($langs->trans("ErrorFailedToSendMail", $from, $to), LOG_ERR);
563 }
564 }
565
566 // Auto-create thirdparty on member creation
567 if (getDolGlobalString('ADHERENT_DEFAULT_CREATE_THIRDPARTY')) {
568 $company = new Societe($db);
569 $result = $company->create_from_member($adh);
570 if ($result < 0) {
571 $error++;
572 $errmsg .= implode('<br>', $company->errors);
573 }
574 }
575
576 if (!empty($backtopage)) {
577 $urlback = $backtopage;
578 } elseif (getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION')) {
579 $urlback = getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION');
580 // TODO Make replacement of __AMOUNT__, etc...
581 } else {
582 $urlback = $_SERVER["PHP_SELF"]."?action=added&token=".newToken();
583 }
584
585 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1') {
586 if (empty($adht->caneditamount)) { // If edition of amount not allowed
587 // TODO Check amount is same than the amount required for the type of member or if not defined as the default amount into $conf->global->MEMBER_NEWFORM_AMOUNT
588 // It is not so important because a test is done on return of payment validation.
589 }
590
591 $urlback = getOnlinePaymentUrl(0, 'member', $adh->ref, (float) price2num(GETPOST('amount', 'alpha'), 'MT'), '', 0);
592
593 if (GETPOST('member_email')) {
594 $urlback .= '&email='.urlencode(GETPOST('member_email'));
595 }
596 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1' && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != 'all') {
597 $urlback .= '&paymentmethod='.urlencode(getDolGlobalString('MEMBER_NEWFORM_PAYONLINE'));
598 }
599 } else {
600 if (!empty($entity)) {
601 $urlback .= '&entity='.((int) $entity);
602 }
603 }
604 } else {
605 $error++;
606 $errmsg .= implode('<br>', $adh->errors);
607 }
608 }
609 }
610
611 if (!$error) {
612 $db->commit();
613
614 header("Location: ".$urlback);
615 exit;
616 } else {
617 $db->rollback();
618 $action = "create";
619 }
620}
621
622// Action called after a submitted was send and member created successfully
623// 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.
624// backtopage parameter with an url was set on member submit page, we never go here because a redirect was done to this url.
625
626if (empty($reshook) && $action == 'added') { // Test on permission not required here
627 llxHeaderVierge($langs->trans("NewMemberForm"));
628
629 // If we have not been redirected
630 print '<br><br>';
631 print '<div class="center">';
632 print $langs->trans("NewMemberbyWeb");
633 print '</div>';
634
636 exit;
637}
638
639
640/*
641 * View
642 */
643
644$form = new Form($db);
645$formcompany = new FormCompany($db);
646$adht = new AdherentType($db);
647$extrafields->fetch_name_optionals_label($object->table_element); // fetch optionals attributes and labels
648
649
650llxHeaderVierge($langs->trans("NewSubscription"));
651
652print '<br>';
653print load_fiche_titre(img_picto('', 'member_nocolor', 'class="pictofixedwidth"').' &nbsp; '.$langs->trans("NewSubscription"), '', '', 0, '', 'center');
654
655
656print '<div align="center">';
657print '<div id="divsubscribe">';
658
659print '<div class="center subscriptionformhelptext opacitylow justify small margintoponly"><br>';
660if (getDolGlobalString('MEMBER_NEWFORM_TEXT')) {
661 print $langs->trans(getDolGlobalString('MEMBER_NEWFORM_TEXT'))."<br>\n";
662} else {
663 print $langs->trans("NewSubscriptionDesc", getDolGlobalString("MAIN_INFO_SOCIETE_MAIL"))."<br>\n";
664}
665print '</div>';
666print '<br>';
667
668dol_htmloutput_errors($errmsg);
670
671if ($action == "subscription") {
672 $urltocall = DOL_URL_ROOT.'/public/payment/newpayment.php?source=member&ref='.$object->id;
673 print $form->formconfirm($urltocall, $langs->trans("CorrespondingMemberFound"), $langs->trans("CorrespondingMemberFoundQuestion"), "confirm_subscription", '', 'no', 1);
674}
675
676// Print form
677print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="newmember" id="newmember">'."\n";
678print '<input type="hidden" name="token" value="'.newToken().'" />';
679print '<input type="hidden" name="entity" value="'.$entity.'" />';
680print '<input type="hidden" name="page_y" value="" />';
681
682if (getDolGlobalString('MEMBER_SKIP_TABLE') || getDolGlobalString('MEMBER_NEWFORM_FORCETYPE') || in_array($action, array('create', 'subscription'))) {
683 if ($action == 'subscription') {
684 print '<input type="hidden" name="nofetchmember" value="nofetchmember" />';
685 }
686 print '<input type="hidden" name="action" value="add" />';
687 print '<br>';
688
689 //$messagemandatory = '<span class="">'.$langs->trans("FieldsWithAreMandatory", '*').'</span>';
690 //print '<br>'.$messagemandatory.'<br>';
691 //print $langs->trans("FieldsWithIsForPublic",'**').'<br>';
692
693 print dol_get_fiche_head();
694
695 if ($conf->use_javascript_ajax) {
696 print "\n".'<script type="text/javascript">'."\n";
697 print 'jQuery(document).ready(function () {
698 jQuery("#selectcountry_id").change(function() {
699 console.log("We change country, so we reload page");
700 document.newmember.action.value="create";
701 jQuery("#newmember").submit();
702 });
703 function initfieldrequired() {
704 console.log("initfieldrequired");
705 jQuery("#tdcompany").removeClass("fieldrequired");
706 jQuery("#tdlastname").removeClass("fieldrequired");
707 jQuery("#tdfirstname").removeClass("fieldrequired");
708 if (jQuery(\'input[name="morphy"]:checked\').val() == \'mor\') {
709 jQuery("#tdcompany").addClass("fieldrequired");
710 }
711 if (jQuery(\'input[name="morphy"]:checked\').val() == \'phy\') {
712 jQuery("#tdlastname").addClass("fieldrequired");
713 jQuery("#tdfirstname").addClass("fieldrequired");
714 }
715 }
716 jQuery(\'input[name="morphy"]\').change(function() {
717 initfieldrequired();
718 });
719 initfieldrequired();
720 })';
721 print '</script>'."\n";
722 }
723
724 print '<table class="border" summary="form to subscribe" id="tablesubscribe">'."\n";
725
726 // Type
727 if (!getDolGlobalString('MEMBER_NEWFORM_FORCETYPE')) {
728 $typeid = GETPOSTINT("typeid");
729 print '<tr><td class="fieldrequired titlefieldmiddle">'.$langs->trans("MemberType").'</td><td>';
730 $listetype = $adht->liste_array(1);
731 print img_picto('', $adht->picto, 'class="pictofixedwidth"');
732 if (count($listetype)) {
733 print $form->selectarray("typeid", $listetype, (GETPOSTINT('typeid') ? GETPOSTINT('typeid') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', 'minwidth150 maxwidth300 widthcentpercentminusx', 1);
734 } else {
735 print '<span class="error">'.$langs->trans("NoTypeDefinedGoToSetup").'</span>';
736 }
737 print '</td></tr>'."\n";
738 } else {
739 $adht->fetch(getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE'));
740 print '<input type="hidden" id="typeid" name="typeid" value="' . getDolGlobalString('MEMBER_NEWFORM_FORCETYPE').'">';
741 }
742
743 // Moral/Physic attribute
744 $morphys = [
745 "phy" => $langs->trans("Physical"),
746 "mor" => $langs->trans("Moral"),
747 ];
748 $checkednature = GETPOST("morphy", 'alpha');
749 $listetype_natures = $adht->morphyByType(1); // Load the array of morphy per typeof membership
750 $listetype_natures_json = json_encode($listetype_natures);
751
752 if (!getDolGlobalString('MEMBER_NEWFORM_FORCEMORPHY')) {
753 if (empty($checkednature) && !empty($listetype_natures[GETPOSTINT('typeid')])) {
754 $checkednature = $listetype_natures[GETPOSTINT('typeid')];
755 }
756
757 print '<tr><td class="fieldrequired titlefieldmiddle">'.$langs->trans("MemberNature")."</td><td>\n";
758
759 $disabledphy = '';
760 $disabledmor = '';
761 //$disabledphy = ($checkednature == "mor" ? ' disabled="disabled"' : '');
762 //$disabledmor = ($checkednature == "phy" ? ' disabled="disabled"' : '');
763 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>';
764 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>';
765
766 // Add JS to manage the background of nature
767 if ($conf->use_javascript_ajax) {
768 print '<script>
769 var listetype_natures = '.$listetype_natures_json.';
770
771 jQuery(function($) {
772 function refreshNatureCss() {
773 $(".spannature").each(function(index) {
774 let $span = $("#spannature" + (index + 1));
775 let checked = $span.find(".checkforselect").is(":checked");
776
777 if (checked) {
778 if (index === 0) {
779 $span.addClass("member-individual-back").removeClass("nonature-back member-company-back");
780 } else if (index === 1) {
781 $span.addClass("member-company-back").removeClass("nonature-back member-individual-back");
782 }
783 } else {
784 $span.removeClass("member-individual-back member-company-back")
785 .addClass("nonature-back");
786 }
787 });
788 }
789
790 $(".spannature").on("click", function() {
791 console.log("Nature clicked");
792 refreshNatureCss();
793 });
794
795 $("#typeid").on("change", function() {
796 console.log("Type of membership is modified");
797 let morphy = listetype_natures[$(this).val()];
798 console.log("morphy="+morphy);
799
800 let $phyInput = $("#phisicalinput");
801 let $morInput = $("#moralinput");
802 let $tdLast = $("#tdlastname");
803 let $tdFirst = $("#tdfirstname");
804 let $tdCompany = $("#tdcompany");
805 let $span1 = $("#spannature1");
806 let $span2 = $("#spannature2");
807
808 switch (morphy) {
809 case "phy":
810 /* $phyInput.prop({disabled: false, checked: true});
811 $morInput.prop({disabled: true, checked: false}); */
812 $span1.addClass("member-individual-back").removeClass("nonature-back");
813 $span2.removeClass("member-company-back").addClass("nonature-back");
814 $("#phisicalinput").prop("checked", true);
815 $tdLast.addClass("fieldrequired");
816 $tdFirst.addClass("fieldrequired");
817 $tdCompany.removeClass("fieldrequired");
818 break;
819
820 case "mor":
821 /* $phyInput.prop({disabled: true, checked: false});
822 $morInput.prop({disabled: false, checked: true}); */
823 $span2.addClass("member-company-back").removeClass("nonature-back");
824 $span1.removeClass("member-individual-back").addClass("nonature-back");
825 $("#moralinput").prop("checked", true);
826 $tdCompany.addClass("fieldrequired");
827 $tdLast.removeClass("fieldrequired");
828 $tdFirst.removeClass("fieldrequired");
829 break;
830
831 default:';
832 if ($action != "subscription" && !GETPOST('morphy')) {
833 print '
834 $phyInput.prop({disabled: false, checked: false});
835 $morInput.prop({disabled: false, checked: false});
836 $span1.removeClass("member-individual-back").addClass("nonature-back");
837 $span2.removeClass("member-company-back").addClass("nonature-back");';
838 }
839 print'}
840 });
841
842 // Initial state
843 refreshNatureCss();
844 });
845 </script>';
846 }
847 print '</td></tr>'."\n";
848 } else {
849 //print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY];
850 print '<input type="hidden" id="morphy" name="morphy" value="' . getDolGlobalString('MEMBER_NEWFORM_FORCEMORPHY').'">';
851 }
852
853 // Company // TODO : optional hide
854 print '<tr id="trcompany" class="trcompany"><td id="tdcompany" class="titlefieldmiddle paddingrightonly'.($checkednature == "mor" ? ' fieldrequired"' : '').'">'.$langs->trans("Company").'</td><td>';
855 print img_picto('', 'company', 'class="pictofixedwidth paddingright"');
856 print '<input type="text" name="societe" class="minwidth150 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('societe')).'"></td></tr>'."\n";
857
858 // Title
859 if (getDolGlobalString('MEMBER_NEWFORM_ASK_TITLE')) {
860 print '<tr><td>'.$langs->trans('UserTitle').'</td><td>';
861 print $formcompany->select_civility(GETPOST('civility_id'), 'civility_id').'</td></tr>'."\n";
862 }
863
864 // Firstname
865 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";
866
867 // Lastname
868 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";
869
870 // EMail
871 print '<tr><td>'.(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '<span class="fieldrequired">' : '').$langs->trans("EMail").(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '</span>' : '').'</td>';
872 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";
873
874 // Login
875 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
876 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";
877 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";
878 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";
879 }
880
881 // Gender
882 print '<tr><td>'.$langs->trans("Gender").'</td>';
883 print '<td>';
884 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
885 print $form->selectarray('gender', $arraygender, GETPOST('gender', 'alphanohtml'), 1, 0, 0, '', 0, 0, 0, '', 'minwidth150 maxwidth300 widthcentpercentminusx', 1);
886 print '</td></tr>';
887
888 // Address
889 print '<tr><td>'.$langs->trans("Address").'</td><td>'."\n";
890 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";
891
892 // Zip / Town
893 print '<tr><td>'.$langs->trans('Zip').' / '.$langs->trans('Town').'</td><td>';
894 print $formcompany->select_ziptown(GETPOST('zipcode'), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 1, '', 'width75');
895 print ' / ';
896 print $formcompany->select_ziptown(GETPOST('town'), 'town', array('zipcode', 'selectcountry_id', 'state_id'), 0, 1);
897 print '</td></tr>';
898
899 $country_id = GETPOSTINT('country_id');
900
901 // Country
902 print '<tr><td class="fieldrequired">'.$langs->trans('Country').'</td><td>';
903 print img_picto('', 'country', 'class="pictofixedwidth paddingright"');
904 if (!$country_id && getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE')) {
905 $country_id = getCountry(getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE'), '2', $db, $langs);
906 }
907 if (!$country_id && !empty($conf->geoipmaxmind->enabled)) {
908 $country_code = dol_user_country();
909 //print $country_code;
910 if ($country_code) {
911 $new_country_id = getCountry($country_code, '3', $db, $langs);
912 //print 'xxx'.$country_code.' - '.$new_country_id;
913 if ($new_country_id) {
914 $country_id = $new_country_id;
915 }
916 }
917 }
918 $country_code = getCountry($country_id, '2', $db, $langs);
919 print $form->select_country($country_id, 'country_id', '', 0, 'minwidth150 maxwidth300 widthcentpercentminusx reposition');
920 print '</td></tr>';
921
922 // State
923 if (!getDolGlobalString('SOCIETE_DISABLE_STATE')) {
924 print '<tr><td>'.$langs->trans('State').'</td><td>';
925 if ($country_code) {
926 print img_picto('', 'state', 'class="pictofixedwidth paddingright"');
927 print $formcompany->select_state(GETPOSTINT("state_id"), $country_code, 'state_id', 'minwidth150 maxwidth300 widthcentpercentminusx');
928 }
929 print '</td></tr>';
930 }
931
932 // Pro phone
933 print '<tr><td>'.$langs->trans("PhonePro").'</td>';
934 print '<td>'.img_picto('', 'object_phoning', 'class="pictofixedwidth"').'<input type="text" name="phone" class="maxwidth300 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('phone')).'"></td></tr>';
935
936 // Personal phone
937 print '<tr><td>'.$langs->trans("PhonePerso").'</td>';
938 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>';
939
940 // Mobile phone
941 print '<tr><td>'.$langs->trans("PhoneMobile").'</td>';
942 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>';
943
944 // Birthday
945 print '<tr id="trbirth" class="trbirth"><td>'.$langs->trans("DateOfBirth").'</td><td>';
946 print $form->selectDate(!empty($birthday) ? $birthday : "", 'birth', 0, 0, 1, "newmember", 1, 0);
947 print '</td></tr>'."\n";
948
949 // Photo
950 print '<tr><td>'.$langs->trans("URLPhoto").'</td><td><input type="text" name="photo" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('photo')).'"></td></tr>'."\n";
951
952 // Public
953 if (getDolGlobalString('MEMBER_PUBLIC_ENABLED')) {
954 $linkofpubliclist = DOL_MAIN_URL_ROOT.'/public/members/public_list.php'.((isModEnabled('multicompany')) ? '?entity='.$conf->entity : '');
955 $publiclabel = $langs->trans("Public", getDolGlobalString('MAIN_INFO_SOCIETE_NOM'), $linkofpubliclist);
956 print '<tr><td>'.$form->textwithpicto($langs->trans("MembershipPublic"), $publiclabel).'</td><td><input type="checkbox" name="public"></td></tr>'."\n";
957 }
958
959 // Other attributes
960 $parameters['tpl_context'] = 'public'; // define template context to public
961 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
962
963 // Comments
964 print '<tr>';
965 print '<td class="tdtop"></td>';
966 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>';
967 print '</tr>'."\n";
968
969
970 // Define amount by default to suggest
971 $typeid = getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE', GETPOSTINT('typeid'));
972 $adht = new AdherentType($db);
973 $adht->fetch($typeid);
974 $caneditamount = $adht->caneditamount;
975 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
976 foreach ($amountbytype as $k => $v) {
977 $amount = max(0, (float) $v, (float) getDolGlobalInt("MEMBER_NEWFORM_AMOUNT"));
978 $amountbytype[$k] = $amount;
979 }
980
981 $amountbytype_json = json_encode($amountbytype);
982 $caneditamountbytype = $adht->caneditamountByType(1); // Load the array of caneditamount per type
983 $caneditamountbytype_json = json_encode($caneditamountbytype);
984
985
986 // Set amount for the subscription from the the type and options:
987 // - First check the amount of the member type.
988 $amount = empty($amountbytype[$typeid]) ? 0 : $amountbytype[$typeid];
989 // - If not found, take the default amount only if the user is authorized to edit it
990 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
991 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
992 }
993 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
994 if (empty($amount)) {
995 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
996 }
997 // - If a min is set, we take it into account
998 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"));
999
1000 // Clean the amount
1001 $amount = price2num($amount);
1002
1003
1004
1005 // Add hook to complete the form
1006 $parameters = array('country_id' => $country_id, 'mode' => 'new');
1007 $reshook = $hookmanager->executeHooks('membershipNewSubscriptionPublicForm', $parameters, $object, $action);
1008 if ($reshook < 0) {
1009 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1010 $error++;
1011 }
1012 // TODO Move this into previous hook
1013 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1014 // Do not set a default amount MEMBER_NEWFORM_AMOUNT if you use MEMBER_NEWFORM_DOLIBARRTURNOVER
1015 $s = $langs->trans("AreYouAPreferredPartner", '<a href="https://partners.dolibarr.org" target="_blank">{s1}</a>');
1016 $s = str_replace('{s1}', 'Preferred Partner', $s);
1017 print '<tr id="trbudget" class="trcompany"><td class="paddingrightonly"><label for="pp" class="small">'.$s.'</label></td><td>';
1018 print '<input type="checkbox" name="pp" id="pp" value="1"'.(GETPOST('pp') ? ' checked="checked"' : '').' class="reposition">';
1019 print '</td></tr>';
1020
1021 print '<tr id="trbudget" class="trcompany"><td class="fieldrequired paddingrightonly"><span class="small">'.$langs->trans("TurnoverOrBudget").'</span></td><td>';
1022
1023 $country_code = dol_getIdFromCode($db, $country_id, 'c_country', 'rowid', 'code');
1024 if ($country_code === 'FR' && $checkednature === 'mor' && GETPOST('pp')) {
1025 print '<input type="text" name="budget" id="budget" class="flat turnover right width100" value="'.GETPOST('budget').'" required>';
1026 } else {
1027 $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+');
1028 print $form->selectarray('budget', $arraybudget, GETPOSTINT('budget'), 1, 0, '', 0, 0, 0, '');
1029 }
1030 print ' € or $';
1031
1032 print '<script type="text/javascript">
1033 jQuery(document).ready(function() {
1034 firstload = true;
1035
1036 newamount = initturnover();
1037 jQuery("#amount").val(newamount);
1038
1039 firstload = false;
1040
1041 jQuery("#selectcountry_id").change(function() {
1042 console.log("We change country (code added for association, replace common code), so we reload page");
1043 jQuery("#budget").val(\'\');
1044 jQuery("#amount").val(\'\');
1045 jQuery("#amounthidden").val(\'\');
1046 });
1047 jQuery("#phisicalinput,#moralinput").click(function() {
1048 console.log("We change the nature of membership");
1049 newamount = initturnover();
1050 jQuery("#amount").val(newamount);
1051 });
1052 jQuery("#pp").change(function() {
1053 console.log("We change the preferred partner status");
1054 selectcountry_id = jQuery("#selectcountry_id").val();
1055 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1056 jQuery("#budget").val(\'\');
1057 jQuery("#amount").val(\'\');
1058 jQuery("#amounthidden").val(\'\');
1059 document.newmember.action.value="create";
1060 jQuery("#newmember").submit();
1061 });
1062 jQuery("#budget").change(function() {
1063 console.log("Turnover amount has been modified on change");
1064 newamount = initturnover();
1065 jQuery("#amount").val(newamount);
1066 jQuery("#amounthidden").val(newamount);
1067 });
1068 jQuery("#budget").keyup(function() {
1069 console.log("Turnover amount has been modified on keyup");
1070 newamount = initturnover();
1071 jQuery("#amount").val(newamount);
1072 jQuery("#amounthidden").val(newamount);
1073 });
1074
1075 function initturnover() {
1076 newamount = 0;
1077
1078 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1079 selectcountry_id = jQuery("#selectcountry_id").val();
1080 pp = jQuery("#pp").is(\':checked\') ? true : false;
1081 console.log("Set fields according to nature and other properties");
1082 console.log("morphy="+morphy);
1083 console.log("selectcountry_id="+selectcountry_id);
1084 console.log("pp="+pp);
1085
1086 if (morphy == \'phy\') {
1087 jQuery(".amount").val('.((float) $amount).');
1088 jQuery("#trbirth").show();
1089 jQuery(".trcompany").hide();
1090 jQuery(".trbudget").hide();
1091 newamount = '.((float) $amount).';
1092 } else {
1093 jQuery(".amount").val(\'\');
1094 jQuery("#trbirth").hide();
1095 jQuery(".trcompany").show();
1096 jQuery(".trbudget").show();
1097 jQuery(".hideifautoturnover").hide();
1098 if (firstload) {
1099 jQuery("#budget").val(\'\');
1100 }
1101
1102 if (selectcountry_id == 1) {
1103 if (pp) {
1104 console.log("value selected in input text field is "+jQuery("#budget").val());
1105 newamount = Math.max(Math.round(price2numjs(jQuery("#budget").val()) * 0.005), 50);
1106 console.log("newamount = "+newamount);
1107 } else {
1108 console.log("not a pp");
1109 if (jQuery("#budget").val() > 0) {
1110 console.log("value found in budget is "+jQuery("#budget").val());
1111 newamount = jQuery("#budget").val();
1112 } else {
1113 jQuery("#budget").val(\'\');
1114 newamount = \'\';
1115 }
1116 }
1117 } else {
1118 if (jQuery("#budget").val() > 0) {
1119 newamount = jQuery("#budget").val();
1120 } else {
1121 jQuery("#budget").val(\'\');
1122 newamount = \'\';
1123 }
1124 console.log("newamount="+newamount);
1125 }
1126 }
1127
1128 return newamount;
1129 }
1130 });
1131 </script>';
1132 print '</td></tr>'."\n";
1133 }
1134
1135 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE')) { // Can be 'all', 'paypal', 'paybox', 'stripe'...
1136 print '<tr><td>'.$langs->trans("Subscription");
1137 if (getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO')) {
1138 print '<br>';
1139 print '<a href="' . getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO').'" rel="external" target="_blank" rel="noopener noreferrer">';
1140 print img_picto('', 'url', 'class="pictofixedwidth"').$langs->trans("SeeHere");
1141 print '</a>';
1142 }
1143 print '</td><td class="nowrap">';
1144
1145 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
1146 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1147 }
1148
1149 $showedamount = $amount > 0 ? $amount : 0;
1150 if ($caneditamount === "1") {
1151 print '<input type="text" name="amount" id="amount" class="flat amount right width75" value="'.$showedamount.'">';
1152 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75 hidden" disabled value="'.$showedamount.'">';
1153 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium hideifautoturnover small">';
1154 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1155 print ' - ';
1156 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1157 }
1158 print '</span>';
1159 } else {
1160 print '<input type="text" name="amount" id="amount" class="flat amount width75 right hidden" value="'.$showedamount.'">';
1161 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75" disabled value="'.$showedamount.'">';
1162 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium hideifautoturnover hidden small">';
1163 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1164 print ' - ';
1165 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1166 }
1167 print '</span>';
1168 }
1169 print '</td></tr>';
1170
1171 // Add JS to manage the background of amount depending on type
1172 if ($conf->use_javascript_ajax) {
1173 print "<script>
1174 var amountbytype = $amountbytype_json;
1175 var canEditAmount = $caneditamountbytype_json;
1176 </script>";
1177
1178 print '<script>
1179 jQuery(function($) {
1180 $("#typeid").on("change", function() {
1181 console.log("Type of membership changed, we force amount update");
1182 let typeId = $(this).val();
1183 let amountVal = amountbytype[typeId] || 0;
1184 let formattedAmount = parseFloat(amountVal);
1185
1186 if (canEditAmount[typeId] === "1") {
1187 // Editable mode
1188 $("#amount").val(formattedAmount).prop("disabled", false).removeClass("hidden");
1189 $("#amounthidden").addClass("hidden");
1190 $(".hideifautoturnover").removeClass("hidden");
1191 } else {
1192 // Read-only mode
1193 $("#amounthidden").val(formattedAmount).prop("disabled", true).removeClass("hidden");
1194 $("#amount").addClass("hidden");
1195 $(".hideifautoturnover").addClass("hidden");
1196 }
1197 });
1198
1199 // Trigger it once so the amount matches the initial selection
1200 $("#typeid").trigger("change");
1201 });
1202 </script>';
1203 }
1204 }
1205
1206 // Display Captcha code if is enabled
1207 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
1208 print '<tr><td><label><span class="fieldrequired">'.$langs->trans("SecurityCode").'</span></label></td><td><br>';
1209 if (method_exists($captchaobj, 'getCaptchaCodeForForm')) {
1210 print $captchaobj->getCaptchaCodeForForm(''); // @phan-suppress-current-line PhanUndeclaredMethod
1211 } else {
1212 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method getCaptchaCodeForForm()';
1213 }
1214 print '<br></td></tr>';
1215 }
1216
1217 print "</table>\n";
1218
1219 print dol_get_fiche_end();
1220
1221 // Save / Submit
1222 print '<div class="center">';
1223 print '<input type="submit" value="'.$langs->trans("GetMembershipButtonLabel").'" id="submitsave" class="button">';
1224 if (!empty($backtopage)) {
1225 print ' &nbsp; &nbsp; <input type="submit" value="'.$langs->trans("Cancel").'" id="submitcancel" class="button button-cancel">';
1226 }
1227 print '</div>';
1228
1229
1230 print "</form>\n";
1231 print "<br>";
1232 print '</div></div>';
1233} else { // Show the table of membership types
1234 // Get units
1235 $measuringUnits = new CUnits($db);
1236 $result = $measuringUnits->fetchAll('', '', 0, 0, array('t.active' => 1));
1237 $units = array();
1238 foreach ($measuringUnits->records as $lines) {
1239 $units[$lines->short_label] = $langs->trans(ucfirst((string) $lines->label));
1240 }
1241
1242 $publiccounters = getDolGlobalString("MEMBER_COUNTERS_ARE_PUBLIC");
1243 $hidevoteallowed = getDolGlobalString("MEMBER_HIDE_VOTE_ALLOWED");
1244
1245 $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,";
1246 $sql .= " COUNT(a.rowid) AS membercount";
1247 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
1248 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as a";
1249 $sql .= " ON d.rowid = a.fk_adherent_type AND a.statut > 0";
1250 $sql .= " WHERE d.entity IN (".getEntity('member_type').")";
1251 $sql .= " AND d.statut=1";
1252 $sql .= " GROUP BY d.rowid, d.libelle, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut, d.morphy";
1253
1254 $result = $db->query($sql);
1255 if ($result) {
1256 $num = $db->num_rows($result);
1257
1258 print '<br><div class="div-table-responsive">';
1259 print '<table class="tagtable liste noborder">'."\n";
1260 print '<input type="hidden" name="action" value="create">';
1261
1262 print '<tr class="liste_titre">';
1263 print '<th>'.$langs->trans("Label").'</th>';
1264 print '<th class="center">'.$langs->trans("MembershipDuration").'</th>';
1265 print '<th class="center">'.$langs->trans("Amount").'</th>';
1266 print '<th class="center">'.$langs->trans("MembersNature").'</th>';
1267 if (empty($hidevoteallowed)) {
1268 print '<th class="center">'.$langs->trans("VoteAllowed").'</th>';
1269 }
1270 if ($publiccounters) {
1271 print '<th class="center">'.$langs->trans("Members").'</th>';
1272 }
1273 print '<th class="center">'.$langs->trans("NewSubscription").'</th>';
1274 print "</tr>\n";
1275
1276 $i = 0;
1277 while ($i < $num) {
1278 $objp = $db->fetch_object($result); // Load the member type and information on it
1279
1280 $caneditamount = $objp->caneditamount;
1281 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
1282
1283 print '<tr class="oddeven">';
1284
1285 // Label
1286 print '<td>';
1287 print '<div class="twolinesmax-normallineheight minwidth200onall">';
1288 print dolPrintHTML($objp->label);
1289 print '</div>';
1290 print '</td>';
1291
1292 // Duration
1293 print '<td class="center">';
1294 $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration);
1295 print '<span class="badge badge-primary">';
1296 print max(1, intval($objp->duration)).' '.$units[$unit];
1297 print '</span>';
1298 print '</td>';
1299
1300 // Amount
1301 print '<td class="center"><span class="amount nowrap">';
1302
1303 // Set amount for the subscription from the the type and options:
1304 // - First check the amount of the member type.
1305 $amount = empty($amountbytype[$objp->rowid]) ? 0 : $amountbytype[$objp->rowid];
1306 // - If not found, take the default amount only if the user is authorized to edit it
1307 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
1308 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1309 }
1310 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
1311 if (empty($amount)) {
1312 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
1313 }
1314 // - If a min is set, we take it into account
1315 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"));
1316
1317 $displayedamount = $amount;
1318
1319 if ($objp->subscription) {
1320 if ($displayedamount > 0 || !$caneditamount) {
1321 print price($displayedamount, 1, $langs, 1, 0, -1, $conf->currency);
1322 }
1323 if ($caneditamount && $displayedamount > 0) {
1324 print $form->textwithpicto('', $langs->transnoentities("CanEditAmountShortForValues"), 1, 'help', '', 0, 3);
1325 } elseif ($caneditamount) {
1326 print $langs->transnoentities("CanEditAmountShort");
1327 }
1328 } else {
1329 print "–"; // No subscription required
1330 }
1331 print '</span></td>';
1332
1333 print '<td class="center minwidth100">';
1334 if ($objp->morphy == 'phy') {
1335 print $langs->trans("Physical");
1336 } elseif ($objp->morphy == 'mor') {
1337 print $langs->trans("Moral");
1338 } else {
1339 print $langs->trans("MorAndPhy");
1340 }
1341 print '</td>';
1342
1343 if (empty($hidevoteallowed)) {
1344 print '<td class="center">'.yn($objp->vote).'</td>';
1345 }
1346 $membercount = $objp->membercount > 0 ? $objp->membercount : "–";
1347 if ($publiccounters) {
1348 print '<td class="center">'.$membercount.'</td>';
1349 }
1350 print '<td class="center"><button class="button button-save reposition" name="typeid" type="submit" name="submit" value="'.$objp->rowid.'">'.$langs->trans("GetMembershipButtonLabel").'</button></td>';
1351 print "</tr>";
1352 $i++;
1353 }
1354
1355 // If no record found
1356 if ($num == 0) {
1357 $colspan = 8;
1358 print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
1359 }
1360
1361 print "</table>";
1362 print '</div>';
1363
1364 print '</form>';
1365 } else {
1366 dol_print_error($db);
1367 }
1368}
1369
1370//htmlPrintOnlineFooter($mysoc, $langs);
1372
1373$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 permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
llxHeaderVierge($title, $head="", $disablejs=0, $disablehead=0, $arrayofjs=[], $arrayofcss=[])
Show header for new prospect.
Definition new.php:122
llxFooterVierge()
Show footer for new societe.
Definition new.php:143
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:125
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.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
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.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
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:154
httponly_accessforbidden($message='1', $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.