dolibarr 23.0.4
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 } elseif (!getDolGlobalString('MEMBER_NEWFORM_FORCETYPE')) {
348 // The type must be one of the active types proposed by the form
349 // (when a type is forced by setup, the type posted is ignored and replaced by the forced one)
350 $tmpadht = new AdherentType($db);
351 if (!array_key_exists(GETPOSTINT('typeid'), $tmpadht->liste_array(1))) {
352 $error++;
353 $errmsg .= $langs->trans("ErrorBadValueForParameter", GETPOSTINT('typeid'), $langs->transnoentitiesnoconv("Type"))."<br>\n";
354 }
355 }
356
357 if ($morphy && $morphy != 'mor' && empty($lastname)) {
358 $error++;
359 $langs->load("errors");
360 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Lastname"));
361 }
362 if ($morphy && $morphy != 'mor' && (!isset($firstname) || $firstname == '')) {
363 $error++;
364 $langs->load("errors");
365 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Firstname"));
366 }
367 if ($morphy == 'mor' && empty($societe)) {
368 $error++;
369 $langs->load("errors");
370 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Company"));
371 }
372 if (empty($country_id)) {
373 $error++;
374 $langs->load("errors");
375 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentities("Country"));
376 }
377 if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && $email && !isValidEmail($email)) {
378 $error++;
379 $langs->load("errors");
380 $errmsg .= $langs->trans("ErrorBadEMail", $email);
381 }
382 $birthday = dol_mktime(GETPOSTINT("birthhour"), GETPOSTINT("birthmin"), GETPOSTINT("birthsec"), GETPOSTINT("birthmonth"), GETPOSTINT("birthday"), GETPOSTINT("birthyear"));
383 if (GETPOST("birthmonth") && empty($birthday)) {
384 $error++;
385 $langs->load("errors");
386 $errmsg .= $langs->trans("ErrorBadDateFormat")."<br>\n";
387 }
388
389 // TODO Add this in a hook
390 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
391 if (GETPOST("morphy") == 'mor' && GETPOSTFLOAT('budget') <= 0) {
392 $error++;
393 $errmsg .= $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("TurnoverOrBudget"))."<br>\n";
394 }
395 }
396
397 // Check Captcha code if is enabled
398 $ok = false;
399 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
400 if (method_exists($captchaobj, 'validateCodeAfterLoginSubmit')) {
401 $ok = $captchaobj->validateCodeAfterLoginSubmit(); // @phan-suppress-current-line PhanUndeclaredMethod
402 } else {
403 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method validateCodeAfterLoginSubmit()';
404 }
405 if (!$ok) {
406 $error++;
407 $langs->load("errors");
408 $errmsg .= $langs->trans("ErrorBadValueForCode")."<br>\n";
409 $action = '';
410 }
411 }
412
413 $public = GETPOSTISSET('public') ? 1 : 0;
414
415 if (!$error) {
416 // E-mail looks OK and login does not exist
417 $adh = new Adherent($db);
418 $adh->statut = -1;
419 $adh->status = -1;
420 $adh->public = $public;
421 $adh->firstname = GETPOST('firstname');
422 $adh->lastname = GETPOST('lastname');
423 $adh->gender = GETPOST('gender');
424 $adh->civility_id = GETPOST('civility_id');
425 $adh->company = GETPOST('societe');
426 $adh->societe = $adh->company;
427 $adh->address = GETPOST('address');
428 $adh->zip = GETPOST('zipcode');
429 $adh->town = GETPOST('town');
430 $adh->email = GETPOST('member_email', 'aZ09arobase');
431 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
432 $adh->login = GETPOST('login');
433 $adh->pass = GETPOST('pass1', 'password');
434 }
435 $adh->photo = GETPOST('photo');
436 $adh->country_id = getDolGlobalInt("MEMBER_NEWFORM_FORCECOUNTRYCODE", GETPOSTINT('country_id'));
437 $adh->state_id = GETPOSTINT('state_id');
438 $adh->typeid = getDolGlobalInt("MEMBER_NEWFORM_FORCETYPE", GETPOSTINT('typeid'));
439 $adh->note_private = GETPOST('note_private');
440 $adh->morphy = getDolGlobalString("MEMBER_NEWFORM_FORCEMORPHY", GETPOST('morphy'));
441 $adh->birth = $birthday;
442 $adh->phone = GETPOST('phone');
443 $adh->phone_perso = GETPOST('phone_perso');
444 $adh->phone_mobile= GETPOST('phone_mobile');
445
446 $adh->ip = getUserRemoteIP();
447
448 $nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
449 $now = dol_now();
450 $minmonthpost = dol_time_plus_duree($now, -1, "m");
451 // Calculate nb of post for IP
452 $nb_post_ip = 0;
453 if ($nb_post_max > 0) { // Calculate only if there is a limit to check
454 $sql = "SELECT COUNT(ref) as nb_adh";
455 $sql .= " FROM ".MAIN_DB_PREFIX."adherent";
456 $sql .= " WHERE ip = '".$db->escape($adh->ip)."'";
457 $sql .= " AND datec > '".$db->idate($minmonthpost)."'";
458 $resql = $db->query($sql);
459 if ($resql) {
460 $num = $db->num_rows($resql);
461 $i = 0;
462 while ($i < $num) {
463 $i++;
464 $obj = $db->fetch_object($resql);
465 $nb_post_ip = $obj->nb_adh;
466 }
467 }
468 }
469
470
471 // Fill array 'array_options' with data from add form
472 $extrafields->fetch_name_optionals_label($adh->table_element);
473 $ret = $extrafields->setOptionalsFromPost(null, $adh);
474 if ($ret < 0) {
475 $error++;
476 $errmsg .= $adh->error;
477 }
478
479 if ($nb_post_max > 0 && $nb_post_ip >= $nb_post_max) {
480 $error++;
481 $errmsg .= $langs->trans("AlreadyTooMuchPostOnThisIPAdress");
482 array_push($adh->errors, $langs->trans("AlreadyTooMuchPostOnThisIPAdress"));
483 }
484
485 if (!$error) {
486 $result = $adh->create($user);
487 if ($result > 0) {
488 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
489 $object = $adh;
490
491 $adht = new AdherentType($db);
492 $adht->fetch($object->typeid);
493
494 if ($object->email) {
495 $subject = '';
496 $msg = '';
497
498 // Send subscription email
499 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
500 $formmail = new FormMail($db);
501 // Set output language
502 $outputlangs = new Translate('', $conf);
503 $outputlangs->setDefaultLang(!empty($object->default_lang) ? $object->default_lang : (empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang));
504 // Load traductions files required by page
505 $outputlangs->loadLangs(array("main", "members"));
506 // Get email content from template
507 $arraydefaultmessage = null;
508 $labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_AUTOREGISTER');
509
510 if (!empty($labeltouse)) {
511 $arraydefaultmessage = $formmail->getEMailTemplate($db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
512 }
513
514 if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
515 $subject = $arraydefaultmessage->topic;
516 $msg = $arraydefaultmessage->content;
517 }
518
519 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
520 complete_substitutions_array($substitutionarray, $outputlangs, $object);
521 $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
522 $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnValid()), $substitutionarray, $outputlangs);
523
524 if ($subjecttosend && $texttosend) {
525 $moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n";
526
527 $result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
528 }
529 /*if ($result < 0) {
530 $error++;
531 setEventMessages($object->error, $object->errors, 'errors');
532 }*/
533 }
534
535 // Send email to the foundation to say a new member subscribed with autosubscribe form
536 if (getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') && getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT') &&
537 getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')) {
538 // Define link to login card
539 $appli = constant('DOL_APPLICATION_TITLE');
540 if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
541 $appli = getDolGlobalString('MAIN_APPLICATION_TITLE');
542 if (preg_match('/\d\.\d/', $appli)) {
543 if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'/', $appli)) {
544 $appli .= " (".DOL_VERSION.")"; // If new title contains a version that is different than core
545 }
546 } else {
547 $appli .= " ".DOL_VERSION;
548 }
549 } else {
550 $appli .= " ".DOL_VERSION;
551 }
552
553 $to = $adh->makeSubstitution(getDolGlobalString('MAIN_INFO_SOCIETE_MAIL'));
554 $from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
555 $mailfile = new CMailFile(
556 '['.$appli.'] ' . getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT'),
557 $to,
558 $from,
559 $adh->makeSubstitution(getDolGlobalString('ADHERENT_AUTOREGISTER_NOTIF_MAIL')),
560 array(),
561 array(),
562 array(),
563 "",
564 "",
565 0,
566 -1
567 );
568
569 if (!$mailfile->sendfile()) {
570 dol_syslog($langs->trans("ErrorFailedToSendMail", $from, $to), LOG_ERR);
571 }
572 }
573
574 // Auto-create thirdparty on member creation
575 if (getDolGlobalString('ADHERENT_DEFAULT_CREATE_THIRDPARTY')) {
576 $company = new Societe($db);
577 $result = $company->create_from_member($adh);
578 if ($result < 0) {
579 $error++;
580 $errmsg .= implode('<br>', $company->errors);
581 }
582 }
583
584 if (!empty($backtopage)) {
585 $urlback = $backtopage;
586 } elseif (getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION')) {
587 $urlback = getDolGlobalString('MEMBER_URL_REDIRECT_SUBSCRIPTION');
588 // TODO Make replacement of __AMOUNT__, etc...
589 } else {
590 $urlback = $_SERVER["PHP_SELF"]."?action=added&token=".newToken();
591 }
592
593 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1') {
594 if (empty($adht->caneditamount)) { // If edition of amount not allowed
595 // 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
596 // It is not so important because a test is done on return of payment validation.
597 }
598
599 $urlback = getOnlinePaymentUrl(0, 'member', $adh->ref, (float) price2num(GETPOST('amount', 'alpha'), 'MT'), '', 0);
600
601 if (GETPOST('member_email')) {
602 $urlback .= '&email='.urlencode(GETPOST('member_email'));
603 }
604 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != '-1' && getDolGlobalString('MEMBER_NEWFORM_PAYONLINE') != 'all') {
605 $urlback .= '&paymentmethod='.urlencode(getDolGlobalString('MEMBER_NEWFORM_PAYONLINE'));
606 }
607 } else {
608 if (!empty($entity)) {
609 $urlback .= '&entity='.((int) $entity);
610 }
611 }
612 } else {
613 $error++;
614 $errmsg .= implode('<br>', $adh->errors);
615 }
616 }
617 }
618
619 if (!$error) {
620 $db->commit();
621
622 header("Location: ".$urlback);
623 exit;
624 } else {
625 $db->rollback();
626 $action = "create";
627 }
628}
629
630// Action called after a submitted was send and member created successfully
631// 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.
632// backtopage parameter with an url was set on member submit page, we never go here because a redirect was done to this url.
633
634if (empty($reshook) && $action == 'added') { // Test on permission not required here
635 llxHeaderVierge($langs->trans("NewMemberForm"));
636
637 // If we have not been redirected
638 print '<br><br>';
639 print '<div class="center">';
640 print $langs->trans("NewMemberbyWeb");
641 print '</div>';
642
644 exit;
645}
646
647
648/*
649 * View
650 */
651
652$form = new Form($db);
653$formcompany = new FormCompany($db);
654$adht = new AdherentType($db);
655$extrafields->fetch_name_optionals_label($object->table_element); // fetch optionals attributes and labels
656
657
658llxHeaderVierge($langs->trans("NewSubscription"));
659
660print '<br>';
661print load_fiche_titre(img_picto('', 'member_nocolor', 'class="pictofixedwidth"').' &nbsp; '.$langs->trans("NewSubscription"), '', '', 0, '', 'center');
662
663
664print '<div align="center">';
665print '<div id="divsubscribe">';
666
667print '<div class="center subscriptionformhelptext opacitylow justify small margintoponly"><br>';
668if (getDolGlobalString('MEMBER_NEWFORM_TEXT')) {
669 print $langs->trans(getDolGlobalString('MEMBER_NEWFORM_TEXT'))."<br>\n";
670} else {
671 print $langs->trans("NewSubscriptionDesc", getDolGlobalString("MAIN_INFO_SOCIETE_MAIL"))."<br>\n";
672}
673print '</div>';
674print '<br>';
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 if ($action != "subscription" && !GETPOST('morphy')) {
841 print '
842 $phyInput.prop({disabled: false, checked: false});
843 $morInput.prop({disabled: false, checked: false});
844 $span1.removeClass("member-individual-back").addClass("nonature-back");
845 $span2.removeClass("member-company-back").addClass("nonature-back");';
846 }
847 print'}
848 });
849
850 // Initial state
851 refreshNatureCss();
852 });
853 </script>';
854 }
855 print '</td></tr>'."\n";
856 } else {
857 //print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY];
858 print '<input type="hidden" id="morphy" name="morphy" value="' . getDolGlobalString('MEMBER_NEWFORM_FORCEMORPHY').'">';
859 }
860
861 // Company // TODO : optional hide
862 print '<tr id="trcompany" class="trcompany"><td id="tdcompany" class="titlefieldmiddle paddingrightonly'.($checkednature == "mor" ? ' fieldrequired"' : '').'">'.$langs->trans("Company").'</td><td>';
863 print img_picto('', 'company', 'class="pictofixedwidth paddingright"');
864 print '<input type="text" name="societe" class="minwidth150 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('societe')).'"></td></tr>'."\n";
865
866 // Title
867 if (getDolGlobalString('MEMBER_NEWFORM_ASK_TITLE')) {
868 print '<tr><td>'.$langs->trans('UserTitle').'</td><td>';
869 print $formcompany->select_civility(GETPOST('civility_id'), 'civility_id').'</td></tr>'."\n";
870 }
871
872 // Firstname
873 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";
874
875 // Lastname
876 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";
877
878 // EMail
879 print '<tr><td>'.(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '<span class="fieldrequired">' : '').$langs->trans("EMail").(getDolGlobalString('ADHERENT_MAIL_REQUIRED') ? '</span>' : '').'</td>';
880 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";
881
882 // Login
883 if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
884 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";
885 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";
886 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";
887 }
888
889 // Gender
890 print '<tr><td>'.$langs->trans("Gender").'</td>';
891 print '<td>';
892 $arraygender = array('man' => $langs->trans("Genderman"), 'woman' => $langs->trans("Genderwoman"), 'other' => $langs->trans("Genderother"));
893 print $form->selectarray('gender', $arraygender, GETPOST('gender', 'alphanohtml'), 1, 0, 0, '', 0, 0, 0, '', 'minwidth150 maxwidth300 widthcentpercentminusx', 1);
894 print '</td></tr>';
895
896 // Address
897 print '<tr><td>'.$langs->trans("Address").'</td><td>'."\n";
898 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";
899
900 // Zip / Town
901 print '<tr><td>'.$langs->trans('Zip').' / '.$langs->trans('Town').'</td><td>';
902 print $formcompany->select_ziptown(GETPOST('zipcode'), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 1, '', 'width75');
903 print ' / ';
904 print $formcompany->select_ziptown(GETPOST('town'), 'town', array('zipcode', 'selectcountry_id', 'state_id'), 0, 1);
905 print '</td></tr>';
906
907 $country_id = GETPOSTINT('country_id');
908
909 // Country
910 print '<tr><td class="fieldrequired">'.$langs->trans('Country').'</td><td>';
911 print img_picto('', 'country', 'class="pictofixedwidth paddingright"');
912 if (!$country_id && getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE')) {
913 $country_id = getCountry(getDolGlobalString('MEMBER_NEWFORM_FORCECOUNTRYCODE'), '2', $db, $langs);
914 }
915 if (!$country_id && !empty($conf->geoipmaxmind->enabled)) {
916 $country_code = dol_user_country();
917 //print $country_code;
918 if ($country_code) {
919 $new_country_id = getCountry($country_code, '3', $db, $langs);
920 //print 'xxx'.$country_code.' - '.$new_country_id;
921 if ($new_country_id) {
922 $country_id = $new_country_id;
923 }
924 }
925 }
926 $country_code = getCountry($country_id, '2', $db, $langs);
927 print $form->select_country($country_id, 'country_id', '', 0, 'minwidth150 maxwidth300 widthcentpercentminusx reposition');
928 print '</td></tr>';
929
930 // State
931 if (!getDolGlobalString('SOCIETE_DISABLE_STATE')) {
932 print '<tr><td>'.$langs->trans('State').'</td><td>';
933 if ($country_code) {
934 print img_picto('', 'state', 'class="pictofixedwidth paddingright"');
935 print $formcompany->select_state(GETPOSTINT("state_id"), $country_code, 'state_id', 'minwidth150 maxwidth300 widthcentpercentminusx');
936 }
937 print '</td></tr>';
938 }
939
940 // Pro phone
941 print '<tr><td>'.$langs->trans("PhonePro").'</td>';
942 print '<td>'.img_picto('', 'object_phoning', 'class="pictofixedwidth"').'<input type="text" name="phone" class="maxwidth300 widthcentpercentminusx" value="'.dol_escape_htmltag(GETPOST('phone')).'"></td></tr>';
943
944 // Personal phone
945 print '<tr><td>'.$langs->trans("PhonePerso").'</td>';
946 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>';
947
948 // Mobile phone
949 print '<tr><td>'.$langs->trans("PhoneMobile").'</td>';
950 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>';
951
952 // Birthday
953 print '<tr id="trbirth" class="trbirth"><td>'.$langs->trans("DateOfBirth").'</td><td>';
954 print $form->selectDate(!empty($birthday) ? $birthday : "", 'birth', 0, 0, 1, "newmember", 1, 0);
955 print '</td></tr>'."\n";
956
957 // Photo
958 print '<tr><td>'.$langs->trans("URLPhoto").'</td><td><input type="text" name="photo" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('photo')).'"></td></tr>'."\n";
959
960 // Public
961 if (getDolGlobalString('MEMBER_PUBLIC_ENABLED')) {
962 $linkofpubliclist = DOL_MAIN_URL_ROOT.'/public/members/public_list.php'.((isModEnabled('multicompany')) ? '?entity='.$conf->entity : '');
963 $publiclabel = $langs->trans("Public", getDolGlobalString('MAIN_INFO_SOCIETE_NOM'), $linkofpubliclist);
964 print '<tr><td>'.$form->textwithpicto($langs->trans("MembershipPublic"), $publiclabel).'</td><td><input type="checkbox" name="public"></td></tr>'."\n";
965 }
966
967 // Other attributes
968 $parameters['tpl_context'] = 'public'; // define template context to public
969 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
970
971 // Comments
972 print '<tr>';
973 print '<td class="tdtop"></td>';
974 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>';
975 print '</tr>'."\n";
976
977
978 // Define amount by default to suggest
979 $typeid = getDolGlobalInt('MEMBER_NEWFORM_FORCETYPE', GETPOSTINT('typeid'));
980 $adht = new AdherentType($db);
981 $adht->fetch($typeid);
982 $caneditamount = $adht->caneditamount;
983 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
984 foreach ($amountbytype as $k => $v) {
985 $amount = max(0, (float) $v, (float) getDolGlobalInt("MEMBER_NEWFORM_AMOUNT"));
986 $amountbytype[$k] = $amount;
987 }
988
989 $amountbytype_json = json_encode($amountbytype);
990 $caneditamountbytype = $adht->caneditamountByType(1); // Load the array of caneditamount per type
991 $caneditamountbytype_json = json_encode($caneditamountbytype);
992
993
994 // Set amount for the subscription from the the type and options:
995 // - First check the amount of the member type.
996 $amount = empty($amountbytype[$typeid]) ? 0 : $amountbytype[$typeid];
997 // - If not found, take the default amount only if the user is authorized to edit it
998 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
999 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1000 }
1001 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
1002 if (empty($amount)) {
1003 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
1004 }
1005 // - If a min is set, we take it into account
1006 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"));
1007
1008 // Clean the amount
1009 $amount = price2num($amount);
1010
1011
1012
1013 // Add hook to complete the form
1014 $parameters = array('country_id' => $country_id, 'mode' => 'new');
1015 $reshook = $hookmanager->executeHooks('membershipNewSubscriptionPublicForm', $parameters, $object, $action);
1016 if ($reshook < 0) {
1017 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1018 $error++;
1019 }
1020 // TODO Move this into previous hook
1021 if (getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1022 // Do not set a default amount MEMBER_NEWFORM_AMOUNT if you use MEMBER_NEWFORM_DOLIBARRTURNOVER
1023 $s = $langs->trans("AreYouAPreferredPartner", '<a href="https://partners.dolibarr.org" target="_blank">{s1}</a>');
1024 $s = str_replace('{s1}', 'Preferred Partner', $s);
1025 print '<tr id="trbudget" class="trcompany"><td class="paddingrightonly"><label for="pp" class="small">'.$s.'</label></td><td>';
1026 print '<input type="checkbox" name="pp" id="pp" value="1"'.(GETPOST('pp') ? ' checked="checked"' : '').' class="reposition">';
1027 print '</td></tr>';
1028
1029 print '<tr id="trbudget" class="trcompany"><td class="fieldrequired paddingrightonly"><span class="small">'.$langs->trans("TurnoverOrBudget").'</span></td><td>';
1030
1031 $country_code = dol_getIdFromCode($db, $country_id, 'c_country', 'rowid', 'code');
1032 if ($country_code === 'FR' && $checkednature === 'mor' && GETPOST('pp')) {
1033 print '<input type="text" name="budget" id="budget" class="flat turnover right width100" value="'.GETPOST('budget').'" required>';
1034 } else {
1035 $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+');
1036 print $form->selectarray('budget', $arraybudget, GETPOSTINT('budget'), 1, 0, '', 0, 0, 0, '');
1037 }
1038 print ' € or $';
1039
1040 print '<script type="text/javascript">
1041 jQuery(document).ready(function() {
1042 firstload = true;
1043
1044 newamount = initturnover();
1045 jQuery("#amount").val(newamount);
1046
1047 firstload = false;
1048
1049 jQuery("#selectcountry_id").change(function() {
1050 console.log("We change country (code added for association, replace common code), so we reload page");
1051 jQuery("#budget").val(\'\');
1052 jQuery("#amount").val(\'\');
1053 jQuery("#amounthidden").val(\'\');
1054 });
1055 jQuery("#phisicalinput,#moralinput").click(function() {
1056 console.log("We change the nature of membership");
1057 newamount = initturnover();
1058 jQuery("#amount").val(newamount);
1059 });
1060 jQuery("#pp").change(function() {
1061 console.log("We change the preferred partner status");
1062 selectcountry_id = jQuery("#selectcountry_id").val();
1063 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1064 jQuery("#budget").val(\'\');
1065 jQuery("#amount").val(\'\');
1066 jQuery("#amounthidden").val(\'\');
1067 document.newmember.action.value="create";
1068 jQuery("#newmember").submit();
1069 });
1070 jQuery("#budget").change(function() {
1071 console.log("Turnover amount has been modified on change");
1072 newamount = initturnover();
1073 jQuery("#amount").val(newamount);
1074 jQuery("#amounthidden").val(newamount);
1075 });
1076 jQuery("#budget").keyup(function() {
1077 console.log("Turnover amount has been modified on keyup");
1078 newamount = initturnover();
1079 jQuery("#amount").val(newamount);
1080 jQuery("#amounthidden").val(newamount);
1081 });
1082
1083 function initturnover() {
1084 newamount = 0;
1085
1086 morphy = jQuery("#moralinput").is(\':checked\') ? \'mor\' : \'phy\';
1087 selectcountry_id = jQuery("#selectcountry_id").val();
1088 pp = jQuery("#pp").is(\':checked\') ? true : false;
1089 console.log("Set fields according to nature and other properties");
1090 console.log("morphy="+morphy);
1091 console.log("selectcountry_id="+selectcountry_id);
1092 console.log("pp="+pp);
1093
1094 if (morphy == \'phy\') {
1095 jQuery(".amount").val('.((float) $amount).');
1096 jQuery("#trbirth").show();
1097 jQuery(".trcompany").hide();
1098 jQuery(".trbudget").hide();
1099 newamount = '.((float) $amount).';
1100 } else {
1101 jQuery(".amount").val(\'\');
1102 jQuery("#trbirth").hide();
1103 jQuery(".trcompany").show();
1104 jQuery(".trbudget").show();
1105 jQuery(".hideifautoturnover").hide();
1106 if (firstload) {
1107 jQuery("#budget").val(\'\');
1108 }
1109
1110 if (selectcountry_id == 1) {
1111 if (pp) {
1112 console.log("value selected in input text field is "+jQuery("#budget").val());
1113 newamount = Math.max(Math.round(price2numjs(jQuery("#budget").val()) * 0.005), 50);
1114 console.log("newamount = "+newamount);
1115 } else {
1116 console.log("not a pp");
1117 if (jQuery("#budget").val() > 0) {
1118 console.log("value found in budget is "+jQuery("#budget").val());
1119 newamount = jQuery("#budget").val();
1120 } else {
1121 jQuery("#budget").val(\'\');
1122 newamount = \'\';
1123 }
1124 }
1125 } else {
1126 if (jQuery("#budget").val() > 0) {
1127 newamount = jQuery("#budget").val();
1128 } else {
1129 jQuery("#budget").val(\'\');
1130 newamount = \'\';
1131 }
1132 console.log("newamount="+newamount);
1133 }
1134 }
1135
1136 return newamount;
1137 }
1138 });
1139 </script>';
1140 print '</td></tr>'."\n";
1141 }
1142
1143 if (getDolGlobalString('MEMBER_NEWFORM_PAYONLINE')) { // Can be 'all', 'paypal', 'paybox', 'stripe'...
1144 print '<tr><td>'.$langs->trans("Subscription");
1145 if (getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO')) {
1146 print '<br>';
1147 print '<a href="' . getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO').'" rel="external" target="_blank" rel="noopener noreferrer">';
1148 print img_picto('', 'url', 'class="pictofixedwidth"').$langs->trans("SeeHere");
1149 print '</a>';
1150 }
1151 print '</td><td class="nowrap">';
1152
1153 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
1154 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1155 }
1156
1157 $showedamount = $amount > 0 ? $amount : 0;
1158 if ($caneditamount === "1") {
1159 print '<input type="text" name="amount" id="amount" class="flat amount right width75" value="'.$showedamount.'">';
1160 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75 hidden" disabled value="'.$showedamount.'">';
1161 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium hideifautoturnover small">';
1162 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1163 print ' - ';
1164 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1165 }
1166 print '</span>';
1167 } else {
1168 print '<input type="text" name="amount" id="amount" class="flat amount width75 right hidden" value="'.$showedamount.'">';
1169 print '<input type="text" name="amount" id="amounthidden" class="flat amount width75" disabled value="'.$showedamount.'">';
1170 print ' '.$langs->getCurrencySymbol($conf->currency).'<span class="opacitymedium hideifautoturnover hidden small">';
1171 if (!getDolGlobalString('MEMBER_NEWFORM_DOLIBARRTURNOVER')) {
1172 print ' - ';
1173 print $amount > 0 ? $langs->trans("AnyAmountWithAdvisedAmount", price($amount, 0, $langs, 1, -1, -1, $conf->currency)) : $langs->trans("AnyAmountWithoutAdvisedAmount");
1174 }
1175 print '</span>';
1176 }
1177 print '</td></tr>';
1178
1179 // Add JS to manage the background of amount depending on type
1180 if ($conf->use_javascript_ajax) {
1181 print "<script>
1182 var amountbytype = $amountbytype_json;
1183 var canEditAmount = $caneditamountbytype_json;
1184 </script>";
1185
1186 print '<script>
1187 jQuery(function($) {
1188 $("#typeid").on("change", function() {
1189 console.log("Type of membership changed, we force amount update");
1190 let typeId = $(this).val();
1191 let amountVal = amountbytype[typeId] || 0;
1192 let formattedAmount = parseFloat(amountVal);
1193
1194 if (canEditAmount[typeId] === "1") {
1195 // Editable mode
1196 $("#amount").val(formattedAmount).prop("disabled", false).removeClass("hidden");
1197 $("#amounthidden").addClass("hidden");
1198 $(".hideifautoturnover").removeClass("hidden");
1199 } else {
1200 // Read-only mode
1201 $("#amounthidden").val(formattedAmount).prop("disabled", true).removeClass("hidden");
1202 $("#amount").addClass("hidden");
1203 $(".hideifautoturnover").addClass("hidden");
1204 }
1205 });
1206
1207 // Trigger it once so the amount matches the initial selection
1208 $("#typeid").trigger("change");
1209 });
1210 </script>';
1211 }
1212 }
1213
1214 // Display Captcha code if is enabled
1215 if (getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_MEMBER') && is_object($captchaobj)) {
1216 print '<tr><td><label><span class="fieldrequired">'.$langs->trans("SecurityCode").'</span></label></td><td><br>';
1217 if (method_exists($captchaobj, 'getCaptchaCodeForForm')) {
1218 print $captchaobj->getCaptchaCodeForForm(''); // @phan-suppress-current-line PhanUndeclaredMethod
1219 } else {
1220 print 'Error, the captcha handler '.get_class($captchaobj).' does not have any method getCaptchaCodeForForm()';
1221 }
1222 print '<br></td></tr>';
1223 }
1224
1225 print "</table>\n";
1226
1227 print dol_get_fiche_end();
1228
1229 // Save / Submit
1230 print '<div class="center">';
1231 print '<input type="submit" value="'.$langs->trans("GetMembershipButtonLabel").'" id="submitsave" class="button">';
1232 if (!empty($backtopage)) {
1233 print ' &nbsp; &nbsp; <input type="submit" value="'.$langs->trans("Cancel").'" id="submitcancel" class="button button-cancel">';
1234 }
1235 print '</div>';
1236
1237
1238 print "</form>\n";
1239 print "<br>";
1240 print '</div></div>';
1241} else { // Show the table of membership types
1242 // Get units
1243 $measuringUnits = new CUnits($db);
1244 $result = $measuringUnits->fetchAll('', '', 0, 0, array('t.active' => 1));
1245 $units = array();
1246 foreach ($measuringUnits->records as $lines) {
1247 $units[$lines->short_label] = $langs->trans(ucfirst((string) $lines->label));
1248 }
1249
1250 $publiccounters = getDolGlobalString("MEMBER_COUNTERS_ARE_PUBLIC");
1251 $hidevoteallowed = getDolGlobalString("MEMBER_HIDE_VOTE_ALLOWED");
1252
1253 $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,";
1254 $sql .= " COUNT(a.rowid) AS membercount";
1255 $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d";
1256 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as a";
1257 $sql .= " ON d.rowid = a.fk_adherent_type AND a.statut > 0";
1258 $sql .= " WHERE d.entity IN (".getEntity('member_type').")";
1259 $sql .= " AND d.statut=1";
1260 $sql .= " GROUP BY d.rowid, d.libelle, d.subscription, d.amount, d.caneditamount, d.vote, d.note, d.duration, d.statut, d.morphy";
1261
1262 $result = $db->query($sql);
1263 if ($result) {
1264 $num = $db->num_rows($result);
1265
1266 print '<br><div class="div-table-responsive">';
1267 print '<table class="tagtable liste noborder">'."\n";
1268 print '<input type="hidden" name="action" value="create">';
1269
1270 print '<tr class="liste_titre">';
1271 print '<th>'.$langs->trans("Label").'</th>';
1272 print '<th class="center">'.$langs->trans("MembershipDuration").'</th>';
1273 print '<th class="center">'.$langs->trans("Amount").'</th>';
1274 print '<th class="center">'.$langs->trans("MembersNature").'</th>';
1275 if (empty($hidevoteallowed)) {
1276 print '<th class="center">'.$langs->trans("VoteAllowed").'</th>';
1277 }
1278 if ($publiccounters) {
1279 print '<th class="center">'.$langs->trans("Members").'</th>';
1280 }
1281 print '<th class="center">'.$langs->trans("NewSubscription").'</th>';
1282 print "</tr>\n";
1283
1284 $i = 0;
1285 while ($i < $num) {
1286 $objp = $db->fetch_object($result); // Load the member type and information on it
1287
1288 $caneditamount = $objp->caneditamount;
1289 $amountbytype = $adht->amountByType(1); // Load the array of amount per type
1290
1291 print '<tr class="oddeven">';
1292
1293 // Label
1294 print '<td>';
1295 print '<div class="twolinesmax-normallineheight minwidth200onall">';
1296 print dolPrintHTML($objp->label);
1297 print '</div>';
1298 print '</td>';
1299
1300 // Duration
1301 print '<td class="center">';
1302 $unit = preg_replace("/[^a-zA-Z]+/", "", $objp->duration);
1303 print '<span class="badge badge-primary">';
1304 print max(1, intval($objp->duration)).' '.$units[$unit];
1305 print '</span>';
1306 print '</td>';
1307
1308 // Amount
1309 print '<td class="center"><span class="amount nowrap">';
1310
1311 // Set amount for the subscription from the the type and options:
1312 // - First check the amount of the member type.
1313 $amount = empty($amountbytype[$objp->rowid]) ? 0 : $amountbytype[$objp->rowid];
1314 // - If not found, take the default amount only if the user is authorized to edit it
1315 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
1316 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1317 }
1318 // - If not set, we accept to have amount defined as parameter (for backward compatibility).
1319 if (empty($amount)) {
1320 $amount = (GETPOST('amount') ? price2num(GETPOST('amount', 'alpha'), 'MT', 2) : '');
1321 }
1322 // - If a min is set, we take it into account
1323 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"));
1324
1325 $displayedamount = $amount;
1326
1327 if ($objp->subscription) {
1328 if ($displayedamount > 0 || !$caneditamount) {
1329 print price($displayedamount, 1, $langs, 1, 0, -1, $conf->currency);
1330 }
1331 if ($caneditamount && $displayedamount > 0) {
1332 print $form->textwithpicto('', $langs->transnoentities("CanEditAmountShortForValues"), 1, 'help', '', 0, 3);
1333 } elseif ($caneditamount) {
1334 print $langs->transnoentities("CanEditAmountShort");
1335 }
1336 } else {
1337 print "–"; // No subscription required
1338 }
1339 print '</span></td>';
1340
1341 print '<td class="center minwidth100">';
1342 if ($objp->morphy == 'phy') {
1343 print $langs->trans("Physical");
1344 } elseif ($objp->morphy == 'mor') {
1345 print $langs->trans("Moral");
1346 } else {
1347 print $langs->trans("MorAndPhy");
1348 }
1349 print '</td>';
1350
1351 if (empty($hidevoteallowed)) {
1352 print '<td class="center">'.yn($objp->vote).'</td>';
1353 }
1354 $membercount = $objp->membercount > 0 ? $objp->membercount : "–";
1355 if ($publiccounters) {
1356 print '<td class="center">'.$membercount.'</td>';
1357 }
1358 print '<td class="center"><button class="button button-save reposition" name="typeid" type="submit" name="submit" value="'.$objp->rowid.'">'.$langs->trans("GetMembershipButtonLabel").'</button></td>';
1359 print "</tr>";
1360 $i++;
1361 }
1362
1363 // If no record found
1364 if ($num == 0) {
1365 $colspan = 8;
1366 print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
1367 }
1368
1369 print "</table>";
1370 print '</div>';
1371
1372 print '</form>';
1373 } else {
1374 dol_print_error($db);
1375 }
1376}
1377
1378//htmlPrintOnlineFooter($mysoc, $langs);
1380
1381$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, $tz='')
Add a delay to a date.
Definition date.lib.php:128
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.