7 * @link http://www.open-emr.org
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @author Rod Roark <rod@sunsetsystems.com>
10 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 require_once("../globals.php");
15 require_once("$srcdir/calendar.inc.php");
16 require_once("$srcdir/options.inc.php");
18 use OpenEMR\Common\Acl\AclExtended
;
19 use OpenEMR\Common\Acl\AclMain
;
20 use OpenEMR\Common\Csrf\CsrfUtils
;
21 use OpenEMR\Common\Twig\TwigContainer
;
22 use OpenEMR\Core\Header
;
23 use OpenEMR\Events\User\UserEditRenderEvent
;
24 use OpenEMR\Menu\MainMenuRole
;
25 use OpenEMR\Menu\PatientMenuRole
;
26 use OpenEMR\Services\FacilityService
;
27 use OpenEMR\Services\UserService
;
29 $facilityService = new FacilityService();
31 if (!AclMain
::aclCheckCore('admin', 'users')) {
32 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Add User")]);
42 <?php Header
::setupHeader(['common','opener', 'erx']); ?
>
44 <script src
="checkpwd_validation.js"></script
>
46 <!-- validation library
-->
47 <!--//Not lbf forms use the new validation, please make sure you have the corresponding values in the list Page validation-->
48 <?php
$use_validate_js = 1;?
>
49 <?php
require_once($GLOBALS['srcdir'] . "/validation/validation_script.js.php"); ?
>
51 //Gets validation rules from Page Validation list.
52 //Note that for technical reasons, we are bypassing the standard validateUsingPageRules() call.
53 $collectthis = collectValidationPageRules("/interface/usergroup/usergroup_admin_add.php");
54 if (empty($collectthis)) {
55 $collectthis = "undefined";
57 $collectthis = json_sanitize($collectthis["new_user"]["rules"]);
63 * validation on the form with new client side validation (using validate.js).
64 * this enable to add new rules for this form in the pageValidation list.
66 var collectvalidation
= <?php
echo $collectthis; ?
>;
68 function trimAll(sString
)
70 while (sString
.substring(0,1) == ' ')
72 sString
= sString
.substring(1, sString
.length
);
74 while (sString
.substring(sString
.length
-1, sString
.length
) == ' ')
76 sString
= sString
.substring(0,sString
.length
-1);
81 function submitform() {
83 var valid
= submitme(1, undefined
, 'new_user', collectvalidation
);
88 //Checking if secure password is enabled or disabled.
89 //If it is enabled and entered password is a weak password, alert the user to enter strong password.
90 if(document
.new_user
.secure_pwd
.value
== 1){
91 var password
= trim(document
.new_user
.stiltskin
.value
);
93 var pwdresult
= passwordvalidate(password
);
96 <?php
echo xlj('The password must be at least eight characters, and should'); ?
> +
98 <?php
echo xlj('contain at least three of the four following items:'); ?
> +
100 <?php
echo xlj('A number'); ?
> +
102 <?php
echo xlj('A lowercase letter'); ?
> +
104 <?php
echo xlj('An uppercase letter'); ?
> +
106 <?php
echo xlj('A special character'); ?
> +
109 <?php
echo xlj('not a letter or number'); ?
> +
112 <?php
echo xlj('For example:'); ?
> +
118 } //secure_pwd if ends here
120 // Valiate Google email (if provided)
121 if(document
.new_user
.google_signin_email
.value
!= "" && !isValidEmail(document
.new_user
.google_signin_email
.value
)) {
122 alert(<?php
echo xlj('Google email provided is invalid/not properly formatted (e.g. first.last@gmail.com)') ?
>);
126 <?php
if ($GLOBALS['erx_enable']) { ?
>
129 for(i
=0;i
<f
.length
;i++
){
130 if(f
[i
].type
=='text' && f
[i
].value
)
132 if(f
[i
].name
== 'rumple')
134 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,35);
135 alertMsg +
= checkUsername(f
[i
].name
,f
[i
].value
);
137 else if(f
[i
].name
== 'fname' || f
[i
].name
== 'mname' || f
[i
].name
== 'lname')
139 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,35);
140 alertMsg +
= checkUsername(f
[i
].name
,f
[i
].value
);
142 else if(f
[i
].name
== 'federaltaxid')
144 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,10);
145 alertMsg +
= checkFederalEin(f
[i
].name
,f
[i
].value
);
147 else if(f
[i
].name
== 'state_license_number')
149 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,10);
150 alertMsg +
= checkStateLicenseNumber(f
[i
].name
,f
[i
].value
);
152 else if(f
[i
].name
== 'npi')
154 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,35);
155 alertMsg +
= checkTaxNpiDea(f
[i
].name
,f
[i
].value
);
157 else if(f
[i
].name
== 'federaldrugid')
159 alertMsg +
= checkLength(f
[i
].name
,f
[i
].value
,30);
160 alertMsg +
= checkAlphaNumeric(f
[i
].name
,f
[i
].value
);
169 <?php
} // End erx_enable only include block?>
171 let post_url
= $
("#new_user").attr("action");
172 let request_method
= $
("#new_user").attr("method");
173 let form_data
= $
("#new_user").serialize();
177 type
: request_method
,
179 }).done(function (r
) {
183 dlgclose('reload', false);
189 function authorized_clicked() {
190 var f
= document
.forms
[0];
191 f
.calendar
.disabled
= !f
.authorized
.checked
;
192 f
.calendar
.checked
= f
.authorized
.checked
;
197 .physician_type_class
{
198 width
: 120px
!important
;
201 width
: 120px
!important
;
205 <body
class="body_top">
207 <div
class="container">
210 <span
class="title"><?php
echo xlt('Add User'); ?
></span
> 
;</td
>
212 <a
class="btn btn-secondary btn-save" name
='form_save' id
='form_save' href
='#' onclick
="return submitform()">
213 <span
><?php
echo xlt('Save'); ?
></span
></a
>
214 <a
class="btn btn-link btn-cancel" id
='cancel' href
='#'>
215 <span
><?php
echo xlt('Cancel');?
></span
>
224 <form name
='new_user' id
="new_user" method
='post' action
="usergroup_admin.php">
225 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
227 <input type
='hidden' name
='mode' value
='new_user'>
228 <input type
='hidden' name
='secure_pwd' value
="<?php echo attr($GLOBALS['secure_password']); ?>">
230 <span
class="font-weight-bold"> 
;</span
>
231 <table
class="border-0" cellpadding
='0' cellspacing
='0' style
="width:600px;">
235 // TODO: we eventually want to move to a responsive layout and not use tables here. So we are going to give
236 // module writers the ability to inject divs, tables, or whatever inside the cell instead of having them
237 // generate additional rows / table columns which locks us into that format.
238 $preRenderEvent = new UserEditRenderEvent('usergroup_admin_add');
239 $GLOBALS['kernel']->getEventDispatcher()->dispatch($preRenderEvent, UserEditRenderEvent
::EVENT_USER_EDIT_RENDER_BEFORE
);
244 <td style
="width:150px;"><span
class="text"><?php
echo xlt('Username'); ?
>: </span
></td
><td style
="width:220px;"><input type
="text" name
="rumple" style
="width:120px;" class="form-control"><span
class="mandatory"></span
></td
>
245 <?php
if (empty($GLOBALS['gbl_ldap_enabled']) ||
empty($GLOBALS['gbl_ldap_exclusions'])) { ?
>
246 <td style
="width:150px;">
247 <span
class="text"><?php
echo xlt('Password'); ?
>:</span
>
249 <td style
="width:150px;">
250 <input type
="password" style
="width:120px;" name
="stiltskin" id
="stiltskin" class="form-control" onkeyup
="checkPasswordStrength(this);">
251 <span
class="mandatory"></span
>
252 <!-- Password Strength Meter
-->
253 <div id
="password_strength_meter" class="progress mt-2">
254 <div
class="progress-bar" role
="progressbar" style
="width: 0%;" aria
-valuenow
="0" aria
-valuemin
="0" aria
-valuemax
="100"></div
>
256 <div id
="password_strength_text"></div
>
259 <td
><input type
="hidden" value
="124" name
="stiltskin" /></td
>
263 <td style
="width:150px;"></td
><td style
="width:220px;"></td
>
264 <td style
="width:200px;"><span
class='text'><?php
echo xlt('Your Password'); ?
>: </span
></td
>
265 <td
class='text' style
="width:280px;"><input type
='password' name
=adminPass style
="width:120px;" value
="" autocomplete
='off' class="form-control"><font
class="mandatory"></font
></td
>
269 <td
><span
class="text"<?php
echo ($GLOBALS['disable_non_default_groups']) ?
" style='display: none'" : ""; ?
>><?php
echo xlt('Groupname'); ?
>: </span
></td
>
271 <select name
="groupname" class="form-control"<?php
echo ($GLOBALS['disable_non_default_groups']) ?
" style='display:none'" : ""; ?
>>
273 $res = sqlStatement("select distinct name from `groups`");
275 for ($iter = 0; $row = sqlFetchArray($res); $iter++
) {
276 $result2[$iter] = $row;
279 foreach ($result2 as $iter) {
280 print "<option value='" . attr($iter["name"]) . "'>" . text($iter["name"]) . "</option>\n";
284 <td colspan
="2"><span
class="text"><?php
echo xlt('Provider'); ?
>: </span
>
285 <input type
='checkbox' name
='authorized' value
='1' onclick
='authorized_clicked()' />
286 <span
class='text'><?php
echo xlt('Calendar'); ?
>:
287 <input type
='checkbox' name
='calendar' disabled
/></span
>
288 <span
class=text
><?php
echo xlt('Portal'); ?
>:
289 <input type
="checkbox" name
="portal_user" /></span
>
293 <td
><span
class="text"><?php
echo xlt('First Name'); ?
>: </span
></td
><td
><input type
="text" name
='fname' id
='fname' style
="width:120px;" class="form-control"><span
class="mandatory"></span
></td
>
294 <td
><span
class="text"><?php
echo xlt('Middle Name'); ?
>: </span
></td
><td
><input type
="text" name
='mname' style
="width:120px;" class="form-control"></td
>
297 <td
><span
class="text"><?php
echo xlt('Last Name'); ?
>: </span
></td
><td
><input type
="text" name
='lname' id
='lname' style
="width:120px;" class="form-control"><span
class="mandatory"></span
></td
>
298 <td
><span
class=text
><?php
echo xlt('Suffix'); ?
>: </span
></td
><td
><input type
="text" name
=suffix id
=suffix style
="width:150px;" class="form-control"></td
>
301 <td
><span
class=text
><?php
echo xlt('Valedictory'); ?
>: </span
></td
><td
><input type
="text" name
=valedictory id
=valedictory style
="width:150px;" class="form-control"></td
>
302 <td
><span
class="text"><?php
echo xlt('Default Facility'); ?
>: </span
></td
>
304 <select style
="width:120px;" name
=facility_id
class="form-control">
306 $fres = $facilityService->getAllServiceLocations();
308 for ($iter = 0; $iter < sizeof($fres); $iter++
) {
309 $result[$iter] = $fres[$iter];
312 foreach ($result as $iter) {
314 <option value
="<?php echo attr($iter['id']); ?>"><?php
echo text($iter['name']); ?
></option
>
322 <td
><span
class="text"><?php
echo xlt('Federal Tax ID'); ?
>: </span
></td
><td
><input type
="text" name
='federaltaxid' style
="width:120px;" class="form-control"></td
>
323 <td
><span
class="text"><?php
echo xlt('DEA number'); ?
>: </span
></td
><td
><input type
="text" name
='federaldrugid' style
="width:120px;" class="form-control"></td
>
326 <td
><span
class="text"><?php
echo xlt('UPIN'); ?
>: </span
></td
><td
><input type
="text" name
="upin" style
="width:120px;" class="form-control"></td
>
327 <td
class='text'><?php
echo xlt('See Authorizations'); ?
>: </td
>
328 <td
><select name
="see_auth" style
="width:120px;" class="form-control">
330 foreach (array(1 => xl('None{{Authorization}}'), 2 => xl('Only Mine'), 3 => xl('All')) as $key => $value) {
331 echo " <option value='" . attr($key) . "'";
332 echo ">" . text($value) . "</option>\n";
338 <td
><span
class="text"><?php
echo xlt('NPI'); ?
>: </span
></td
><td
><input type
="text" name
="npi" style
="width:120px;" class="form-control"></td
>
339 <td
><span
class="text"><?php
echo xlt('Job Description'); ?
>: </span
></td
><td
><input type
="text" name
="specialty" style
="width:120px;" class="form-control"></td
>
344 <span
class="text"><?php
echo xlt('Provider Type'); ?
>: </span
>
347 <?php
echo generate_select_list("physician_type", "physician_type", '', '', xl('Select Type'), 'physician_type_class', '', '', ''); ?
>
352 <span
class="text"><?php
echo xlt('Main Menu Role'); ?
>: </span
>
356 $menuMain = new MainMenuRole($GLOBALS['kernel']->getEventDispatcher());
357 echo $menuMain->displayMenuRoleSelector();
361 <span
class="text"><?php
echo xlt('Patient Menu Role'); ?
>: </span
>
365 $menuPatient = new PatientMenuRole();
366 echo $menuPatient->displayMenuRoleSelector();
372 <td
><span
class="text"><?php
echo xlt('Taxonomy'); ?
>: </span
></td
>
373 <td
><input type
="text" name
="taxonomy" style
="width:120px;" class="form-control" value
="207Q00000X"></td
>
374 <td
><span
class="text"><?php
echo xlt('Supervisor'); ?
>: </span
></td
>
376 <select name
="supervisor_id" style
="width:150px;" class="form-control">
377 <option value
=""><?php
echo xlt("Select Supervisor") ?
></option
>
379 $userService = new UserService();
380 $users = $userService->getActiveUsers();
381 foreach ($users as $activeUser) {
382 $p_id = (int)$activeUser['id'];
383 if ($activeUser['authorized'] != 1) {
386 echo "<option value='" . attr($p_id) . "'";
387 if ((int)($iter["supervisor_id"] ??
null) === $p_id) {
390 echo ">" . text($activeUser['lname']) . ' ' .
391 text($activeUser['fname']) . ' ' . text($activeUser['mname']) . "</option>\n";
397 <td
><span
class="text"><?php
echo xlt('State License Number'); ?
>: </span
></td
>
398 <td
><input type
="text" name
="state_license_number" style
="width:120px;" class="form-control"></td
>
399 <td
class='text'><?php
echo xlt('NewCrop eRX Role'); ?
>:</td
>
401 <?php
echo generate_select_list("erxrole", "newcrop_erx_role", '', '', '--Select Role--', '', '', '', array('style' => 'width:120px')); ?
>
405 <td
><span
class="text"><?php
echo xlt('Weno Provider ID'); ?
>: </span
></td
><td
><input type
="text" name
="erxprid" style
="width:120px;" class="form-control" value
="<?php echo attr($iter["weno_prov_id
"] ?? ''); ?>"></td
>
406 <td
><span
class="text"><?php
echo xlt('Google Email for Login'); ?
>: </span
></td
><td
><input type
="text" name
="google_signin_email" style
="width:150px;" class="form-control" value
="<?php echo attr($iter["google_signin_email
"] ?? ''); ?>"></td
>
408 <?php
if ($GLOBALS['inhouse_pharmacy']) { ?
>
410 <td
class="text"><?php
echo xlt('Default Warehouse'); ?
>: </td
>
413 echo generate_select_list(
421 <td
class="text"><?php
echo xlt('Invoice Refno Pool'); ?
>: </td
>
424 echo generate_select_list(
428 xl('Invoice reference number pool, if used')
435 <!-- facility
and warehouse restrictions
, optional
-->
436 <?php
if (!empty($GLOBALS['gbl_fac_warehouse_restrictions']) ||
!empty($GLOBALS['restrict_user_facility'])) { ?
>
437 <tr title
="<?php echo xla('If nothing is selected here then all are permitted.'); ?>">
438 <td
class="text"><?php
echo !empty($GLOBALS['gbl_fac_warehouse_restrictions']) ?
439 xlt('Facility and warehouse permissions') : xlt('Facility permissions'); ?
>:</td
>
441 <select name
="schedule_facility[]" multiple style
="width:490px;">
443 $user_id = 0; // in user_admin.php this is intval($_GET["id"]).
444 $userFacilities = getUserFacilities($user_id, 'id', $GLOBALS['gbl_fac_warehouse_restrictions']);
446 foreach ($userFacilities as $uf) {
449 $fres = sqlStatement("select * from facility order by name");
451 while ($frow = sqlFetchArray($fres)) {
452 // Get the warehouses that are linked to this user and facility.
453 $whids = getUserFacWH($user_id, $frow['id']); // from calendar.inc.php
454 // Generate an option for just the facility with no warehouse restriction.
456 if (empty($whids) && in_array($frow['id'], $ufid)) {
459 echo " value='" . attr($frow['id']) . "'>" . text($frow['name']) . "</option>\n";
460 // Then generate an option for each of the facility's warehouses.
461 // Does not apply if the site does not use warehouse restrictions.
462 if (!empty($GLOBALS['gbl_fac_warehouse_restrictions'])) {
463 $lres = sqlStatement(
464 "SELECT option_id, title FROM list_options WHERE " .
465 "list_id = ? AND option_value = ? ORDER BY seq, title",
466 array('warehouse', $frow['id'])
468 while ($lrow = sqlFetchArray($lres)) {
470 if (in_array($lrow['option_id'], $whids)) {
473 echo " value='" . attr($frow['id']) . "/" . attr($lrow['option_id']) . "'> " .
474 text(xl_list_label($lrow['title'])) . "</option>\n";
486 <td
class='text'><?php
echo xlt('Access Control'); ?
>:</td
>
487 <td
><select name
="access_group[]" multiple style
="width:120px;" class="form-control">
489 // List the access control groups
490 $is_super_user = AclMain
::aclCheckCore('admin', 'super');
491 $list_acl_groups = AclExtended
::aclGetGroupTitleList($is_super_user ?
true : false);
492 $default_acl_group = 'Administrators';
493 foreach ($list_acl_groups as $value) {
494 if ($is_super_user && $default_acl_group == $value) {
495 // Modified 6-2009 by BM - Translate group name if applicable
496 echo " <option value='" . attr($value) . "' selected>" . text(xl_gacl_group($value)) . "</option>\n";
498 // Modified 6-2009 by BM - Translate group name if applicable
499 echo " <option value='" . attr($value) . "'>" . text(xl_gacl_group($value)) . "</option>\n";
504 <td
><span
class="text"><?php
echo xlt('Additional Info'); ?
>: </span
></td
>
505 <td
><textarea name
=info style
="width:120px;" cols
='27' rows
='4' wrap
='auto' class="form-control"></textarea
></td
>
509 <td
><span
class=text
><?php
echo xlt('Default Billing Facility'); ?
>: </span
></td
>
510 <td
><select name
="billing_facility_id" style
="width:150px;" class="form-control">
512 $fres = $facilityService->getAllBillingLocations();
515 for ($iter2 = 0; $iter2 < sizeof($fres); $iter2++
) {
516 $billResults[$iter2] = $fres[$iter2];
519 foreach ($billResults as $iter2) {
521 <option value
="<?php echo attr($iter2['id']); ?>"><?php
echo text($iter2['name']); ?
></option
>
533 // TODO: we eventually want to move to a responsive layout and not use tables here. So we are going to give
534 // module writers the ability to inject divs, tables, or whatever inside the cell instead of having them
535 // generate additional rows / table columns which locks us into that format.
536 $preRenderEvent = new UserEditRenderEvent('usergroup_admin_add.php');
537 $GLOBALS['kernel']->getEventDispatcher()->dispatch($preRenderEvent, UserEditRenderEvent
::EVENT_USER_EDIT_RENDER_AFTER
);
541 <tr height
="25"><td colspan
="4"> 
;</td
></tr
>
546 <input type
="hidden" name
="newauthPass">
552 <tr
<?php
echo ($GLOBALS['disable_non_default_groups']) ?
" style='display:none'" : ""; ?
>>
555 <form name
='new_group' method
='post' action
="usergroup_admin.php"
556 onsubmit
='return top.restoreSession()'>
557 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
559 <input type
='hidden' name
='mode' value
='new_group' />
560 <span
class="bold"><?php
echo xlt('New Group'); ?
>:</span
>
563 <span
class="text"><?php
echo xlt('Groupname'); ?
>: </span
><input type
="text" name
='groupname' size
='10'>
565 <span
class="text"><?php
echo xlt('Initial User'); ?
>: </span
>
566 <select name
='rumple'>
568 $res = sqlStatement("select distinct username from users where username != ''");
569 for ($iter = 0; $row = sqlFetchArray($res); $iter++
) {
570 $result[$iter] = $row;
573 foreach ($result as $iter) {
574 print "<option value='" . attr($iter["username"]) . "'>" . text($iter["username"]) . "</option>\n";
579 <input type
="submit" value
="<?php echo xla('Save'); ?>" />
584 <tr
<?php
echo ($GLOBALS['disable_non_default_groups']) ?
" style='display:none'" : ""; ?
>>
587 <form name
='new_group' method
='post' action
="usergroup_admin.php"
588 onsubmit
='return top.restoreSession()'>
589 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
590 <input type
='hidden' name
='mode' value
='new_group' />
591 <span
class="bold"><?php
echo xlt('Add User To Group'); ?
>:</span
>
595 <?php
echo xlt('User'); ?
>
597 <select name
='rumple'>
599 $res = sqlStatement("select distinct username from users where username != ''");
600 for ($iter = 0; $row = sqlFetchArray($res); $iter++
) {
601 $result3[$iter] = $row;
604 foreach ($result3 as $iter) {
605 print "<option value='" . attr($iter["username"]) . "'>" . text($iter["username"]) . "</option>\n";
610 <span
class="text"><?php
echo xlt('Groupname'); ?
>: </span
>
611 <select name
='groupname'>
613 $res = sqlStatement("select distinct name from `groups`");
615 for ($iter = 0; $row = sqlFetchArray($res); $iter++
) {
616 $result2[$iter] = $row;
619 foreach ($result2 as $iter) {
620 print "<option value='" . attr($iter["name"]) . "'>" . text($iter["name"]) . "</option>\n";
625 <input type
="submit" value
="<?php echo xla('Add User To Group'); ?>" />
633 if (empty($GLOBALS['disable_non_default_groups'])) {
634 $res = sqlStatement("select * from `groups` order by name");
635 for ($iter = 0; $row = sqlFetchArray($res); $iter++
) {
636 $result5[$iter] = $row;
639 foreach ($result5 as $iter) {
640 $grouplist[$iter["name"]] .= $iter["user"] .
641 "(<a class='link_submit' href='usergroup_admin.php?mode=delete_group&id=" .
642 attr_url($iter["id"]) . "&csrf_token_form=" . attr_url(CsrfUtils
::collectCsrfToken()) . "' onclick='top.restoreSession()'>" . xlt("Remove") . "</a>), ";
645 foreach ($grouplist as $groupname => $list) {
646 print "<span class='font-weight-bold'>" . text($groupname) . "</span><br />\n<span class='text'>" .
647 text(substr($list, 0, strlen($list) - 2)) . "</span><br />\n";
654 if ($alertmsg = trim($alertmsg)) {
655 echo "alert('" . js_escape($alertmsg) . "');\n";
659 $
("#cancel").click(function() {