1<?php 2/* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2005-2021 Laurent Destailleur <eldy@users.sourceforge.net> 4 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com> 5 * Copyright (C) 2011 Herve Prot <herve.prot@symeos.com> 6 * Copyright (C) 2012 Florian Henry <florian.henry@open-concept.pro> 7 * Copyright (C) 2018 Juanjo Menent <jmenent@2byte.es> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 3 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program. If not, see <https://www.gnu.org/licenses/>. 21 */ 22 23/** 24 * \file htdocs/user/group/card.php 25 * \brief Tab of a user group 26 */ 27 28require '../../main.inc.php'; 29require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; 30require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; 31require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; 32require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; 33 34// Defini si peux lire/modifier utilisateurs et permisssions 35$canreadperms = ($user->admin || $user->rights->user->user->lire); 36$caneditperms = ($user->admin || $user->rights->user->user->creer); 37$candisableperms = ($user->admin || $user->rights->user->user->supprimer); 38$feature2 = 'user'; 39 40// Advanced permissions 41if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { 42 $canreadperms = ($user->admin || $user->rights->user->group_advance->read); 43 $caneditperms = ($user->admin || $user->rights->user->group_advance->write); 44 $candisableperms = ($user->admin || $user->rights->user->group_advance->delete); 45 $feature2 = 'group_advance'; 46} 47 48// Load translation files required by page 49$langs->loadLangs(array('users', 'other')); 50 51$id = GETPOST('id', 'int'); 52$action = GETPOST('action', 'aZ09'); 53$cancel = GETPOST('cancel', 'aZ09'); 54$confirm = GETPOST('confirm', 'alpha'); 55$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'groupcard'; // To manage different context of search 56$backtopage = GETPOST('backtopage', 'alpha'); 57 58$userid = GETPOST('user', 'int'); 59 60$object = new Usergroup($db); 61$extrafields = new ExtraFields($db); 62// fetch optionals attributes and labels 63$extrafields->fetch_name_optionals_label($object->table_element); 64 65// Load object 66include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. 67$object->getrights(); 68 69// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array 70$hookmanager->initHooks(array('groupcard', 'globalcard')); 71 72// Security check 73$result = restrictedArea($user, 'user', $id, 'usergroup&usergroup', $feature2); 74 75// Users/Groups management only in master entity if transverse mode 76if (!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE) { 77 accessforbidden(); 78} 79 80 81/** 82 * Actions 83 */ 84 85$parameters = array('id' => $id, 'userid' => $userid, 'caneditperms' => $caneditperms); 86$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 87if ($reshook < 0) { 88 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 89} 90 91if (empty($reshook)) { 92 $backurlforlist = DOL_URL_ROOT.'/user/group/list.php'; 93 94 if (empty($backtopage) || ($cancel && empty($id))) { 95 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { 96 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { 97 $backtopage = $backurlforlist; 98 } else { 99 $backtopage = dol_buildpath('/user/group/card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); 100 } 101 } 102 } 103 104 if ($cancel) { 105 header("Location: ".$backtopage); 106 exit; 107 } 108 109 // Action remove group 110 if ($action == 'confirm_delete' && $confirm == "yes") { 111 if ($caneditperms) { 112 $object->fetch($id); 113 $object->delete($user); 114 header("Location: ".DOL_URL_ROOT."/user/group/list.php?restore_lastsearch_values=1"); 115 exit; 116 } else { 117 $langs->load("errors"); 118 setEventMessages($langs->trans('ErrorForbidden'), null, 'errors'); 119 } 120 } 121 122 // Action add group 123 if ($action == 'add') { 124 if ($caneditperms) { 125 if (!GETPOST("nom", "nohtml")) { 126 setEventMessages($langs->trans("NameNotDefined"), null, 'errors'); 127 $action = "create"; // Go back to create page 128 } else { 129 $object->name = GETPOST("nom", 'nohtml'); 130 $object->note = dol_htmlcleanlastbr(trim(GETPOST("note", 'restricthtml'))); 131 132 // Fill array 'array_options' with data from add form 133 $ret = $extrafields->setOptionalsFromPost(null, $object); 134 if ($ret < 0) { 135 $error++; 136 } 137 138 if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { 139 $object->entity = 0; 140 } else { 141 if ($conf->entity == 1 && $user->admin && !$user->entity) { // Same permissions test than the one used to show the combo of entities into the form 142 $object->entity = GETPOSTISSET("entity") ? GETPOST("entity") : $conf->entity; 143 } else { 144 $object->entity = $conf->entity; 145 } 146 } 147 148 $db->begin(); 149 150 $id = $object->create(); 151 152 if ($id > 0) { 153 $db->commit(); 154 155 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); 156 exit; 157 } else { 158 $db->rollback(); 159 160 $langs->load("errors"); 161 setEventMessages($langs->trans("ErrorGroupAlreadyExists", $object->name), null, 'errors'); 162 $action = "create"; // Go back to create page 163 } 164 } 165 } else { 166 $langs->load("errors"); 167 setEventMessages($langs->trans('ErrorForbidden'), null, 'errors'); 168 } 169 } 170 171 // Add/Remove user into group 172 if ($action == 'adduser' || $action == 'removeuser') { 173 if ($caneditperms) { 174 if ($userid > 0) { 175 $object->fetch($id); 176 $object->oldcopy = clone $object; 177 178 $edituser = new User($db); 179 $edituser->fetch($userid); 180 if ($action == 'adduser') { 181 $result = $edituser->SetInGroup($object->id, $object->entity); 182 } 183 if ($action == 'removeuser') { 184 $result = $edituser->RemoveFromGroup($object->id, $object->entity); 185 } 186 187 if ($result > 0) { 188 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); 189 exit; 190 } else { 191 setEventMessages($edituser->error, $edituser->errors, 'errors'); 192 } 193 } 194 } else { 195 $langs->load("errors"); 196 setEventMessages($langs->trans('ErrorForbidden'), null, 'errors'); 197 } 198 } 199 200 201 if ($action == 'update') { 202 if ($caneditperms) { 203 $db->begin(); 204 205 $object->fetch($id); 206 207 $object->oldcopy = clone $object; 208 209 $object->name = GETPOST("nom", 'nohtml'); 210 $object->note = dol_htmlcleanlastbr(trim(GETPOST("note", 'restricthtml'))); 211 212 // Fill array 'array_options' with data from add form 213 $ret = $extrafields->setOptionalsFromPost(null, $object); 214 if ($ret < 0) { 215 $error++; 216 } 217 218 if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { 219 $object->entity = 0; 220 } else { 221 $object->entity = GETPOST("entity"); 222 } 223 224 $ret = $object->update(); 225 226 if ($ret >= 0 && !count($object->errors)) { 227 setEventMessages($langs->trans("GroupModified"), null, 'mesgs'); 228 $db->commit(); 229 } else { 230 setEventMessages($object->error, $object->errors, 'errors'); 231 $db->rollback(); 232 } 233 } else { 234 $langs->load("errors"); 235 setEventMessages($langs->trans('ErrorForbidden'), null, 'mesgs'); 236 } 237 } 238 239 // Actions to build doc 240 $upload_dir = $conf->usergroup->dir_output; 241 $permissiontoadd = $user->rights->user->user->creer; 242 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; 243} 244 245 246/* 247 * View 248 */ 249 250llxHeader('', $langs->trans("GroupCard")); 251 252$form = new Form($db); 253$fuserstatic = new User($db); 254$form = new Form($db); 255$formfile = new FormFile($db); 256 257if ($action == 'create') { 258 print load_fiche_titre($langs->trans("NewGroup"), '', 'object_group'); 259 260 print dol_set_focus('#nom'); 261 262 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'; 263 print '<input type="hidden" name="token" value="'.newToken().'">'; 264 print '<input type="hidden" name="action" value="add">'; 265 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">'; 266 267 print dol_get_fiche_head('', '', '', 0, ''); 268 269 print '<table class="border centpercent tableforfieldcreate">'; 270 271 // Multicompany 272 if (!empty($conf->multicompany->enabled) && is_object($mc)) { 273 if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) { 274 print "<tr>".'<td class="tdtop">'.$langs->trans("Entity").'</td>'; 275 print "<td>".$mc->select_entities($conf->entity); 276 print "</td></tr>\n"; 277 } else { 278 print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; 279 } 280 } 281 282 // Common attributes 283 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; 284 285 // Other attributes 286 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; 287 288 print "</table>\n"; 289 290 print dol_get_fiche_end(); 291 292 print '<div class="center">'; 293 print '<input class="button" name="add" value="'.$langs->trans("CreateGroup").'" type="submit">'; 294 print ' '; 295 print '<input class="button button-cancel" value="'.$langs->trans("Cancel").'" name="cancel" type="submit">'; 296 print '</div>'; 297 298 print "</form>"; 299} else { 300 /* ************************************************************************** */ 301 /* */ 302 /* Visu et edition */ 303 /* */ 304 /* ************************************************************************** */ 305 if ($id) { 306 $res = $object->fetch_optionals(); 307 308 $head = group_prepare_head($object); 309 $title = $langs->trans("Group"); 310 311 /* 312 * Confirmation suppression 313 */ 314 if ($action == 'delete') { 315 print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("DeleteAGroup"), $langs->trans("ConfirmDeleteGroup", $object->name), "confirm_delete", '', 0, 1); 316 } 317 318 /* 319 * Fiche en mode visu 320 */ 321 322 if ($action != 'edit') { 323 print dol_get_fiche_head($head, 'group', $title, -1, 'group'); 324 325 $linkback = '<a href="'.DOL_URL_ROOT.'/user/group/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; 326 327 dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); 328 329 print '<div class="fichecenter">'; 330 print '<div class="fichehalfleft">'; 331 print '<div class="underbanner clearboth"></div>'; 332 333 print '<table class="border centpercent tableforfield">'; 334 335 // Name (already in dol_banner, we keep it to have the GlobalGroup picto, but we should move it in dol_banner) 336 if (!empty($conf->mutlicompany->enabled)) { 337 print '<tr><td class="titlefield">'.$langs->trans("Name").'</td>'; 338 print '<td class="valeur">'.dol_escape_htmltag($object->name); 339 if (empty($object->entity)) { 340 print img_picto($langs->trans("GlobalGroup"), 'redstar'); 341 } 342 print "</td></tr>\n"; 343 } 344 345 // Multicompany 346 if (!empty($conf->multicompany->enabled) && is_object($mc) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) { 347 $mc->getInfo($object->entity); 348 print "<tr>".'<td class="titlefield">'.$langs->trans("Entity").'</td>'; 349 print '<td class="valeur">'.dol_escape_htmltag($mc->label); 350 print "</td></tr>\n"; 351 } 352 353 unset($object->fields['nom']); // Name already displayed in banner 354 355 // Common attributes 356 $keyforbreak = ''; 357 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; 358 359 // Other attributes 360 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; 361 362 print '</table>'; 363 print '</div>'; 364 print '</div>'; 365 366 print '<div class="clearboth"></div>'; 367 368 print dol_get_fiche_end(); 369 370 371 /* 372 * Action bar 373 */ 374 print '<div class="tabsAction">'; 375 376 $parameters = array(); 377 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook 378 if ($reshook < 0) { 379 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 380 } 381 382 if ($caneditperms) { 383 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'; 384 } 385 386 if ($candisableperms) { 387 print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$object->id.'&token='.newToken().'">'.$langs->trans("DeleteGroup").'</a>'; 388 } 389 390 print "</div>\n"; 391 392 // List users in group 393 394 print load_fiche_titre($langs->trans("ListOfUsersInGroup"), '', 'user'); 395 396 // On selectionne les users qui ne sont pas deja dans le groupe 397 $exclude = array(); 398 399 if (!empty($object->members)) { 400 foreach ($object->members as $useringroup) { 401 $exclude[] = $useringroup->id; 402 } 403 } 404 405 // Other form for add user to group 406 $parameters = array('caneditperms' => $caneditperms, 'exclude' => $exclude); 407 $reshook = $hookmanager->executeHooks('formAddUserToGroup', $parameters, $object, $action); // Note that $action and $object may have been modified by hook 408 print $hookmanager->resPrint; 409 410 if (empty($reshook)) { 411 if ($caneditperms) { 412 print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST">'."\n"; 413 print '<input type="hidden" name="token" value="'.newToken().'">'; 414 print '<input type="hidden" name="action" value="adduser">'; 415 print '<table class="noborder centpercent">'."\n"; 416 print '<tr class="liste_titre"><td class="titlefield liste_titre">'.$langs->trans("NonAffectedUsers").'</td>'."\n"; 417 print '<td class="liste_titre">'; 418 print $form->select_dolusers('', 'user', 1, $exclude, 0, '', '', $object->entity, 0, 0, '', 0, '', 'minwidth200 maxwidth500'); 419 print ' '; 420 print '<input type="hidden" name="entity" value="'.$conf->entity.'">'; 421 print '<input type="submit" class="button buttongen" value="'.$langs->trans("Add").'">'; 422 print '</td></tr>'."\n"; 423 print '</table></form>'."\n"; 424 print '<br>'; 425 } 426 427 /* 428 * Group members 429 */ 430 431 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table 432 print '<table class="noborder centpercent">'; 433 print '<tr class="liste_titre">'; 434 print '<td class="liste_titre">'.$langs->trans("Login").'</td>'; 435 print '<td class="liste_titre">'.$langs->trans("Lastname").'</td>'; 436 print '<td class="liste_titre">'.$langs->trans("Firstname").'</td>'; 437 print '<td class="liste_titre center" width="5">'.$langs->trans("Status").'</td>'; 438 print '<td class="liste_titre right" width="5"> </td>'; 439 print "</tr>\n"; 440 441 if (!empty($object->members)) { 442 foreach ($object->members as $useringroup) { 443 print '<tr class="oddeven">'; 444 print '<td class="tdoverflowmax150">'; 445 print $useringroup->getNomUrl(-1, '', 0, 0, 24, 0, 'login'); 446 if ($useringroup->admin && !$useringroup->entity) { 447 print img_picto($langs->trans("SuperAdministrator"), 'redstar'); 448 } elseif ($useringroup->admin) { 449 print img_picto($langs->trans("Administrator"), 'star'); 450 } 451 print '</td>'; 452 print '<td>'.$useringroup->lastname.'</td>'; 453 print '<td>'.$useringroup->firstname.'</td>'; 454 print '<td class="center">'.$useringroup->getLibStatut(5).'</td>'; 455 print '<td class="right">'; 456 if (!empty($user->admin)) { 457 print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=removeuser&user='.$useringroup->id.'">'; 458 print img_picto($langs->trans("RemoveFromGroup"), 'unlink'); 459 print '</a>'; 460 } else { 461 print "-"; 462 } 463 print "</td></tr>\n"; 464 } 465 } else { 466 print '<tr><td colspan="6" class="opacitymedium">'.$langs->trans("None").'</td></tr>'; 467 } 468 print "</table>"; 469 print '</div>'; 470 } 471 472 print "<br>"; 473 474 print '<div class="fichecenter"><div class="fichehalfleft">'; 475 476 /* 477 * Generated documents 478 */ 479 480 $filename = dol_sanitizeFileName($object->ref); 481 $filedir = $conf->usergroup->dir_output."/".dol_sanitizeFileName($object->ref); 482 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; 483 $genallowed = $user->rights->user->user->creer; 484 $delallowed = $user->rights->user->user->supprimer; 485 486 $somethingshown = $formfile->showdocuments('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); 487 488 // Show links to link elements 489 $linktoelem = $form->showLinkToObjectBlock($object, null, null); 490 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); 491 492 print '</div><div class="fichehalfright"><div class="ficheaddleft">'; 493 494 // List of actions on element 495 /*include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; 496 $formactions = new FormActions($db); 497 $somethingshown = $formactions->showactions($object, 'usergroup', $socid, 1);*/ 498 499 print '</div></div></div>'; 500 } 501 502 /* 503 * Fiche en mode edition 504 */ 505 506 if ($action == 'edit' && $caneditperms) { 507 print '<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="updategroup" enctype="multipart/form-data">'; 508 print '<input type="hidden" name="token" value="'.newToken().'">'; 509 print '<input type="hidden" name="action" value="update">'; 510 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">'; 511 print '<input type="hidden" name="id" value="'.$object->id.'">'; 512 513 print dol_get_fiche_head($head, 'group', $title, 0, 'group'); 514 515 print '<table class="border centpercent tableforfieldedit">'."\n"; 516 517 // Multicompany 518 if (!empty($conf->multicompany->enabled) && is_object($mc)) { 519 if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && !$user->entity) { 520 print "<tr>".'<td class="tdtop">'.$langs->trans("Entity").'</td>'; 521 print "<td>".$mc->select_entities($object->entity); 522 print "</td></tr>\n"; 523 } else { 524 print '<input type="hidden" name="entity" value="'.$conf->entity.'" />'; 525 } 526 } 527 528 // Common attributes 529 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; 530 531 // Other attributes 532 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; 533 534 print '</table>'; 535 536 print dol_get_fiche_end(); 537 538 print '<div class="center"><input type="submit" class="button button-save" name="save" value="'.$langs->trans("Save").'">'; 539 print ' <input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">'; 540 print '</div>'; 541 542 print '</form>'; 543 } 544 } 545} 546 547// End of page 548llxFooter(); 549$db->close(); 550