5 * Functions wrapping php-GACL's functionality, to create a generic OpenEMR access control system.
7 * LICENSE: This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see
17 * http://www.gnu.org/licenses/licenses.html#GPL .
20 * @license http://www.gnu.org/licenses/licenses.html#GPL GNU GPL V3+
21 * @author Brady Miller <brady.g.miller@gmail.com>
22 * @author Rod Roark <rod@sunsetsystems.com>
23 * @link http://www.open-emr.org
26 // php-GACL access controls are included in OpenEMR. The below
27 // function will automatically create the path where gacl.class.php
28 // can be found. Note that this path can be manually set below
29 // for users who are using an external version of php-GACL.
30 // Also note that php-GACL access controls can be turned off
33 $phpgacl_location = dirname(__FILE__).'/../gacl';
35 // If using an external version of phpGACL, then uncomment the following
36 // line and manually place the path below. IN THIS CASE YOU MUST ALSO
37 // COMMENT OUT ABOVE $phpgacl_location ASSIGNMENT ABOVE, OR BACKUPS WILL
38 // NOT RESTORE PROPERLY!
40 //$phpgacl_location = "/var/www/gacl";
42 // If you want to turn off php-GACL, then uncomment the following line.
43 // IN THIS CASE YOU MUST ALSO COMMENT OUT ABOVE $phpgacl_location ASSIGNMENT(S)
44 // ABOVE, OR BACKUPS WILL NOT RESTORE PROPERLY!
46 //unset($phpgacl_location);
49 // The following Access Control Objects (ACO) are currently supported.
50 // These are the "things to be protected":
52 // Section "admin" (Administration):
53 // super Superuser - can delete patients, encounters, issues
54 // calendar Calendar Settings
55 // database Database Reporting
56 // forms Forms Administration
57 // practice Practice Settings
58 // superbill Superbill Codes Administration
59 // users Users/Groups/Logs Administration
60 // batchcom Batch Communication Tool
61 // language Language Interface Tool
62 // drugs Pharmacy Dispensary
63 // acl ACL Administration
65 // Section "acct" (Accounting):
66 // bill Billing (write optional)
67 // disc Allowed to discount prices (in Fee Sheet or Checkout form)
69 // rep Financial Reporting - my encounters
70 // rep_a Financial Reporting - anything
72 // Section "patients" (Patient Information):
73 // appt Appointments (write,wsome optional)
74 // demo Demographics (write,addonly optional)
75 // med Medical Records and History (write,addonly optional)
76 // trans Transactions, e.g. referrals (write optional)
77 // docs Documents (write,addonly optional)
78 // notes Patient Notes (write,addonly optional)
79 // sign Sign Lab Results (write,addonly optional)
80 // reminder Patient Reminders (write,addonly optional)
81 // alert Clinical Reminders/Alerts (write,addonly optional)
82 // disclosure Disclosures (write,addonly optional)
83 // rx Prescriptions (write,addonly optional)
84 // amendment Amendments (write,addonly optional)
85 // lab Lab Results (write,addonly optional)
87 // Section "encounters" (Encounter Information):
88 // auth Authorize - my encounters
89 // auth_a Authorize - any encounters
90 // coding Coding - my encounters (write,wsome optional)
91 // coding_a Coding - any encounters (write,wsome optional)
92 // notes Notes - my encounters (write,addonly optional)
93 // notes_a Notes - any encounters (write,addonly optional)
94 // date_a Fix encounter dates - any encounters
95 // relaxed Less-private information (write,addonly optional)
96 // (e.g. the Sports Fitness encounter form)
98 // Section "squads" applies to sports team use only:
99 // acos in this section define the user-specified list of squads
101 // Section "sensitivities" (Sensitivities):
105 // Section "lists" (Lists):
106 // default Default List (write,addonly optional)
107 // state State List (write,addonly optional)
108 // country Country List (write,addonly optional)
109 // language Language List (write,addonly optional)
110 // ethrace Ethnicity-Race List (write,addonly optional)
112 // Section "placeholder" (Placeholder):
113 // filler Placeholder (Maintains empty ACLs)
115 // Section "nationnotes" (Nation Notes):
116 // nn_configure Nation Notes
118 // Section "patientportal" (Patient Portal):
119 // portal Patient Portal
120 // Section "menus" (Menus):
123 if (isset ($phpgacl_location)) {
124 $GLOBALS['phpgacl_location_global'] = $phpgacl_location;
125 require_once("$phpgacl_location/gacl.class.php");
126 $gacl_object = new gacl();
127 //DO NOT CHANGE BELOW VARIABLE
128 $section_aro_value = 'users';
129 $GLOBALS['section_aro_value_global'] = $section_aro_value;
133 * Check if a user has a given type or types of access to an access control object.
135 * Globals that can use are:
136 * $GLOBALS['phpgacl_location_global']
137 * $GLOBALS['section_aro_value_global']
139 * This function will check for access to the given ACO.
140 * view - The user may view but not add or modify entries
141 * write - The user may add or modify the ACO
142 * wsome - The user has limited add/modify access to the ACO
143 * addonly - The user may view and add but not modify entries
145 * @param string $section Category of ACO
146 * @param string $value Subcategory of ACO
147 * @param string $user Optional user being checked for access.
148 * @param string|array $return_value Type or types of access being requested.
149 * @return bool|array FALSE if access is denied, TRUE if allowed. An
150 * array() of bools is returned if $return_value is an
151 * array, representing results for each type of access
154 function acl_check($section, $value, $user = '', $return_value = '') {
155 if (! $user) $user = $_SESSION['authUser'];
157 // Superuser always gets access to everything.
158 if (($section != 'admin' || $value != 'super') && acl_check('admin', 'super', $user)) {
162 if ($GLOBALS['phpgacl_location_global']) {
163 // This will return all pertinent ACL's (including return_values and whether allow/deny)
164 // Walk through them to assess for access
165 $gacl_object = new gacl();
166 $acl_results = $gacl_object->acl_query($section, $value, $GLOBALS['section_aro_value_global'], $user,NULL,NULL,NULL,NULL,NULL,TRUE);
167 if (empty($acl_results)) {
168 return FALSE; //deny access
170 $access=FALSE; //flag
172 foreach ($acl_results as $acl_result) {
173 if (empty($acl_result['acl_id'])) return FALSE; //deny access, since this happens if no pertinent ACL's are returned
174 if (is_array($return_value)) {
175 foreach ($return_value as $single_return_value) {
176 if (empty($single_return_value)) {
177 // deal with case if not looking for specific return value
178 if ($acl_result['allow']) {
185 else { //!empty($single_return_value)
186 // deal with case if looking for specific return value
187 if ($acl_result['return_value'] == $single_return_value) {
188 if ($acl_result['allow']) {
198 else { // $return_value is not an array (either empty or with one value)
199 if (empty($return_value)) {
200 // deal with case if not looking for specific return value
201 if ($acl_result['allow']) {
208 else { //!empty($return_value)
209 // deal with case if looking for specific return value
210 if ($acl_result['return_value'] == $return_value) {
211 if ($acl_result['allow']) {
222 // Now decide whether user has access
223 // (Note a denial takes precedence)
224 if (!$deny && $access) return TRUE;
228 // If no phpgacl, then apply the old static rules whereby "authorized"
229 // users (providers) can do anything, and other users can do most things.
230 // If you want custom access control but don't want to mess with phpGACL,
231 // then you could customize the code below instead.
233 if ($user == 'admin') return 'write';
234 if ($section == 'admin' && $value == 'super') return 0;
235 if ($_SESSION['userauthorized']) return 'write';
237 if ($section == 'patients') {
238 if ($value == 'med') return 1;
241 else if ($section == 'encounters') {
242 if (strpos($value, 'coding' ) === 0) return 'write';
243 if (strpos($value, 'notes' ) === 0) return 'write';
244 if ($value == 'relaxed') return 'write';
246 else if ($section != 'admin') {
253 // Get the ACO name/value pairs for a designated section. Each value
254 // is an array (section_value, value, order_value, name, hidden).
256 function acl_get_section_acos($section) {
257 global $phpgacl_location;
258 if ($phpgacl_location) {
259 include_once("$phpgacl_location/gacl_api.class.php");
260 $gacl = new gacl_api();
261 $arr1 = $gacl->get_objects($section, 1, 'ACO');
263 if (!empty($arr1[$section])) {
264 foreach ($arr1[$section] as $value) {
265 $odata = $gacl->get_object_data($gacl->get_object_id($section, $value, 'ACO'), 'ACO');
266 $arr[$value] = $odata[0];
274 // Sort squads by their order value. Used only by acl_get_squads().
275 function _acl_squad_compare($a, $b) {
276 if ($a[2] == $b[2]) {
277 // If order value is the same, sort by squad name.
278 if ($a[3] == $b[3]) return 0;
279 return ($a[3] < $b[3]) ? -1 : 1;
281 return ($a[2] < $b[2]) ? -1 : 1;
284 // Return an array keyed on squad ACO names.
285 // This is only applicable for sports team use.
287 function acl_get_squads() {
288 $squads = acl_get_section_acos('squads');
289 uasort($squads, "_acl_squad_compare");
293 // Return an array keyed on encounter sensitivity level ACO names.
294 // Sensitivities are useful when some encounter notes are not
295 // medically sensitive (e.g. a physical fitness test), and/or if
296 // some will be "for doctor's eyes only" (e.g. STD treatment).
298 // When a non-blank sensitivity value exists in the new encounter
299 // form, it names an additional ACO required for access to all forms
300 // in the encounter. If you want some encounters to be non-sensitive,
301 // then you also need some default nonblank sensitivity for normal
302 // encounters, as well as greater encounter notes permissions for
303 // those allowed to view non-sensitive encounters.
305 function acl_get_sensitivities() {
306 return acl_get_section_acos('sensitivities');
310 // Returns true if aco exist
311 // Returns false if aco doesn't exist
312 // $section_name = name of section (string)
313 // $aco_name = name of aco (string)
315 function aco_exist($section_name, $aco_name) {
316 global $phpgacl_location;
317 if (isset ($phpgacl_location)) {
318 include_once("$phpgacl_location/gacl_api.class.php");
319 $gacl = new gacl_api();
320 $aco_id = $gacl->get_object_id($section_name, $aco_name, 'ACO');
329 // Returns a sorted array of all available Group Titles.
331 function acl_get_group_title_list() {
332 global $phpgacl_location;
333 if (isset ($phpgacl_location)) {
334 include_once("$phpgacl_location/gacl_api.class.php");
335 $gacl = new gacl_api();
336 $parent_id = $gacl->get_root_group_id();
337 $arr_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
338 $arr_group_titles = array();
339 foreach ($arr_group_ids as $value) {
340 $arr_group_data = $gacl->get_group_data($value, 'ARO');
341 $arr_group_titles[$value] = $arr_group_data[3];
343 sort($arr_group_titles);
344 return $arr_group_titles;
350 // Returns a sorted array of group Titles that a user belongs to.
351 // Returns 0 if does not belong to any group yet.
352 // $user_name = Username, which is login name.
354 function acl_get_group_titles($user_name) {
355 global $phpgacl_location, $section_aro_value;
356 if (isset ($phpgacl_location)) {
357 include_once("$phpgacl_location/gacl_api.class.php");
358 $gacl = new gacl_api();
359 $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
361 $arr_group_id = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
363 foreach ($arr_group_id as $key => $value) {
364 $arr_group_data = $gacl->get_group_data($value, 'ARO');
365 $arr_group_titles[$key] = $arr_group_data[3];
367 sort($arr_group_titles);
368 return $arr_group_titles;
376 // This will place the user aro object into selected group(s)
377 // It uses the set_user_aro() function
378 // $username = username (string)
379 // $group = title of group(s) (string or array)
381 function add_user_aros($username, $group) {
382 $current_user_groups = acl_get_group_titles($username);
383 if (!$current_user_groups) {
384 $current_user_groups = array();
386 if (is_array($group)){
387 foreach ($group as $value) {
388 if (!in_array($value, $current_user_groups)) {
389 array_push($current_user_groups, $value);
394 if (!in_array($group, $current_user_groups)) {
395 array_push($current_user_groups, $group);
398 $user_data = sqlFetchArray(sqlStatement("select * from users where username='" .
400 set_user_aro($current_user_groups, $username, $user_data["fname"],
401 $user_data["mname"], $user_data["lname"]);
406 // This will remove the user aro object from the selected group(s)
407 // It uses the set_user_aro() function
408 // $username = username (string)
409 // $group = title of group(s) (string or array)
411 function remove_user_aros($username, $group) {
412 $current_user_groups = acl_get_group_titles($username);
413 $new_user_groups = array();
414 if (is_array($group)){
415 foreach ($current_user_groups as $value) {
416 if (!in_array($value, $group)) {
417 array_push($new_user_groups, $value);
422 foreach ($current_user_groups as $value) {
423 if ($value != $group) {
424 array_push($new_user_groups, $value);
428 $user_data = sqlFetchArray(sqlStatement("select * from users where username='" .
430 set_user_aro($new_user_groups, $username, $user_data["fname"],
431 $user_data["mname"], $user_data["lname"]);
436 // This will either create or edit a user aro object, and then place it
437 // in the requested groups. It will not allow removal of the 'admin'
438 // user or gacl_protected users from the 'admin' group.
439 // $arr_group_titles = titles of the groups that user will be added to.
440 // $user_name = username, which is login name.
441 // $first_name = first name
442 // $middle_name = middle name
443 // $last_name = last name
445 function set_user_aro($arr_group_titles, $user_name, $first_name, $middle_name, $last_name) {
446 global $phpgacl_location, $section_aro_value;
448 if (isset ($phpgacl_location)) {
449 include_once("$phpgacl_location/gacl_api.class.php");
450 $gacl = new gacl_api();
452 //see if this user is gacl protected (ie. do not allow
453 //removal from the Administrators group)
454 require_once(dirname(__FILE__).'/user.inc');
455 require_once(dirname(__FILE__).'/calendar.inc');
456 $userNametoID = getIDfromUser($user_name);
457 if (checkUserSetting("gacl_protect","1",$userNametoID) || $user_name == "admin") {
458 $gacl_protect = true;
461 $gacl_protect = false;
464 //get array of all available group ID numbers
465 $parent_id = $gacl->get_root_group_id();
466 $arr_all_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
468 //Cycle through ID array to find and process each selected group
469 //Create a counter since processing of first hit is unique
471 foreach ($arr_all_group_ids as $value) {
472 $arr_group_data = $gacl->get_group_data($value, 'ARO');
473 if ((empty($arr_group_titles)) ||
474 (in_array($arr_group_data[3], $arr_group_titles))) {
475 //We have a hit, so need to add group and increment counter
476 // because processing of first hit is unique
477 //This will also deal with an empty $arr_group_titles array
478 // removing user from all groups unless 'admin'
479 $counter = $counter + 1;
480 //create user full name field
482 $full_name = $first_name . " " . $middle_name . " " . $last_name;
486 $full_name = $first_name . " " . $last_name;
489 $full_name = $first_name;
493 //If this is not the first group to be added, then will skip below
494 // and will be added. If this is the first group, then need to
495 // go thru several steps before adding the group.
497 //get ID of user ARO object, if it exist
498 $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
500 //user ARO object already exist, so will edit it
501 $gacl->edit_object($user_aro_id, $section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
503 //remove all current user ARO object group associations
504 $arr_remove_group_ids = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
505 foreach ($arr_remove_group_ids as $value2) {
506 $gacl->del_group_object($value2, $section_aro_value, $user_name, 'ARO');
510 //user ARO object does not exist, so will create it
511 $gacl->add_object($section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
515 //place the user ARO object in the selected group (if group(s) is selected)
516 if (!empty($arr_group_titles)) {
517 $gacl->add_group_object($value, $section_aro_value, $user_name, 'ARO');
521 //Below will not allow 'admin' or gacl_protected user to be removed from 'admin' group
525 $admin_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
526 $arr_admin = $gacl->get_object_groups($admin_id, 'ARO', 'NO_RECURSE');
527 foreach ($arr_admin as $value3) {
528 $arr_admin_data = $gacl->get_group_data($value3, 'ARO');
529 if (strcmp($arr_admin_data[2], 'admin') == 0) {
533 if (!$boolean_admin) {
534 foreach ($arr_all_group_ids as $value4) {
535 $arr_temp = $gacl->get_group_data($value4, 'ARO');
536 if ($arr_temp[2] == 'admin') {
537 $gacl->add_group_object($value4, $section_aro_value, $user_name, 'ARO');
543 //if array of groups was empty, then we are done, and can break from loop
544 if (empty($arr_group_titles)) break;
552 // Returns true if acl exist
553 // Returns false if acl doesn't exist
554 // EITHER $title or $name is required(send FALSE in variable
555 // not being used). If both are sent, then only $title will be
557 // $return_value is required
558 // $title = title of acl (string)
559 // $name = name of acl (string)
560 // $return_value = return value of acl (string)
562 function acl_exist($title, $name, $return_value) {
563 global $phpgacl_location;
564 if (isset ($phpgacl_location)) {
565 include_once("$phpgacl_location/gacl_api.class.php");
566 $gacl = new gacl_api();
568 $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
571 $group_id = $gacl->get_group_id($name, NULL, 'ARO');
573 $group_data = $gacl->get_group_data($group_id, 'ARO');
574 $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $group_data[3], FALSE, FALSE, FALSE, $return_value);
581 $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
593 // This will add a new acl and group(if group doesn't yet exist)
594 // with one aco in it.
595 // $acl_title = title of acl (string)
596 // $acl_name = name of acl (string)
597 // $return_value = return value of acl (string)
598 // $note = description of acl (array)
600 function acl_add($acl_title, $acl_name, $return_value, $note) {
601 global $phpgacl_location;
602 if (isset ($phpgacl_location)) {
603 include_once("$phpgacl_location/gacl_api.class.php");
604 $gacl = new gacl_api();
605 $group_id = $gacl->get_group_id($acl_name, $acl_title, 'ARO');
607 //group already exist, so just create acl
608 $gacl->add_acl(array("placeholder"=>array("filler")),
609 NULL, array($group_id), NULL, NULL, 1, 1, $return_value, $note);
612 //create group, then create acl
613 $parent_id = $gacl->get_root_group_id();
614 $aro_id = $gacl->add_group($acl_name, $acl_title, $parent_id, 'ARO');
615 $gacl->add_acl(array("placeholder"=>array("filler")),
616 NULL, array($aro_id), NULL, NULL, 1, 1, $return_value, $note);
624 // This will remove acl. It will also remove group(if the group
625 // is no longer associated with any acl's).
626 // $acl_title = title of acl (string)
627 // $acl_name = name of acl (string)
628 // $return_value = return value of acl (string)
629 // $note = description of acl (array)
631 function acl_remove($acl_title, $return_value) {
632 global $phpgacl_location;
633 if (isset ($phpgacl_location)) {
634 include_once("$phpgacl_location/gacl_api.class.php");
635 $gacl = new gacl_api();
636 //First, delete the acl
637 $acl_id=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
638 $gacl->del_acl($acl_id[0]);
639 //Then, remove the group(if no more acl's are remaining)
640 $acl_search=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, FALSE);
641 if (empty($acl_search)){
642 $group_id=$gacl-> get_group_id(NULL, $acl_title, 'ARO');
643 $gacl->del_group($group_id, TRUE, 'ARO');
651 // This will place the aco(s) into the selected acl
652 // $acl_title = title of acl (string)
653 // $return_value = return value of acl (string)
654 // $aco_id = id of aco (array)
656 function acl_add_acos($acl_title, $return_value, $aco_id) {
657 global $phpgacl_location;
658 if (isset ($phpgacl_location)) {
659 include_once("$phpgacl_location/gacl_api.class.php");
660 $gacl = new gacl_api();
661 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
662 foreach ($aco_id as $value) {
663 $aco_data = $gacl->get_object_data($value, 'ACO');
664 $aco_section = $aco_data[0][0];
665 $aco_name = $aco_data[0][1];
666 $gacl->append_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
674 // This will remove the aco(s) from the selected acl
675 // Note if all aco's are removed, then will place the filler-placeholder
676 // into the acl to avoid complete removal of the acl.
677 // $acl_title = title of acl (string)
678 // $return_value = return value of acl (string)
679 // $aco_id = id of aco (array)
681 function acl_remove_acos($acl_title, $return_value, $aco_id) {
682 global $phpgacl_location;
683 if (isset ($phpgacl_location)) {
684 include_once("$phpgacl_location/gacl_api.class.php");
685 $gacl = new gacl_api();
686 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
688 // Check to see if removing all acos. If removing all acos then will
689 // ensure the filler-placeholder aco in acl to avoid complete
690 // removal of the acl.
691 if (count($aco_id) == acl_count_acos($acl_title, $return_value)) {
692 //1-get the filler-placeholder aco id
693 $filler_aco_id = $gacl->get_object_id('placeholder','filler','ACO');
694 //2-add filler-placeholder aco
695 acl_add_acos($acl_title, $return_value, array($filler_aco_id));
696 //3-ensure filler-placeholder aco is not to be deleted
697 $safeListaco = remove_element($_POST["selection"],$filler_aco_id);
698 //4-prepare to safely delete the acos
699 $aco_id = $safeListaco;
702 foreach ($aco_id as $value) {
703 $aco_data = $gacl->get_object_data($value, 'ACO');
704 $aco_section = $aco_data[0][0];
705 $aco_name = $aco_data[0][1];
706 $gacl->shift_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
714 // This will return the number of aco objects
715 // in a specified acl.
716 // $acl_title = title of acl (string)
717 // $return_value = return value of acl (string)
719 function acl_count_acos($acl_title, $return_value) {
720 global $phpgacl_location;
721 if (isset ($phpgacl_location)) {
722 include_once("$phpgacl_location/gacl_api.class.php");
723 $gacl = new gacl_api();
724 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
725 $acl_data = $gacl->get_acl($acl_id[0]);
727 foreach ($acl_data['aco'] as $key => $value) {
728 $aco_count = $aco_count + count($acl_data['aco'][$key]);
736 // Function to remove an element from an array
738 function remove_element($arr, $val){
740 foreach ($arr as $value){
741 if ($value != $val) {
742 array_push($arr2,$value);
750 * Same Functionality in the Zend Module
751 * for ACL Check in Zend
752 * Path openemr/interface/modules/zend_modules/module/Application/src/Application/Model/ApplicationTable
753 * Function Name zAclCheck
755 * @param String $user_id Auth user Id
756 * $param String $section_identifier ACL Section id
759 function zh_acl_check($user_id,$section_identifier){
760 $sql_user_acl = " SELECT
761 COUNT(allowed) AS count
763 module_acl_user_settings AS usr_settings
764 LEFT JOIN module_acl_sections AS acl_sections
765 ON usr_settings.section_id = acl_sections.`section_id`
767 acl_sections.section_identifier = ? AND usr_settings.user_id = ? AND usr_settings.allowed = ?";
768 $sql_user_group = " SELECT
772 LEFT JOIN `gacl_groups_aro_map` AS gamp
773 ON garo.id = gamp.aro_id
774 LEFT JOIN `gacl_aro_groups` AS gagp
775 ON gagp.id = gamp.group_id
776 RIGHT JOIN `users_secure` usr
777 ON usr. username = garo.value
779 garo.section_value = ? AND usr. id = ?";
780 $res_groups = sqlStatement($sql_user_group,array('users',$user_id));
782 // Prepare the group queries with the placemakers and binding array for the IN part
783 $groups_sql_param = array();
784 $groupPlacemakers = "";
786 while($row = sqlFetchArray($res_groups)){
787 array_push($groups_sql_param,$row['group_id']);
789 $groupPlacemakers = "?";
793 $groupPlacemakers .= ",?";
796 $sql_group_acl_base = " SELECT
797 COUNT(allowed) AS count
799 module_acl_group_settings AS group_settings
800 LEFT JOIN module_acl_sections AS acl_sections
801 ON group_settings.section_id = acl_sections.section_id
803 group_settings.group_id IN (".$groupPlacemakers.") AND acl_sections.`section_identifier` = ? ";
804 $sql_group_acl_denied = $sql_group_acl_base . " AND group_settings.allowed = '0'";
805 $sql_group_acl_allowed = $sql_group_acl_base . " AND group_settings.allowed = '1'";
807 // Complete the group queries sql binding array
808 array_push($groups_sql_param, $section_identifier);
810 $count_user_denied = 0;
811 $count_user_allowed = 0;
812 $count_group_denied = 0;
813 $count_group_allowed = 0;
815 $res_user_denied = sqlQuery($sql_user_acl,array($section_identifier,$user_id,0));
816 $count_user_denied = $res_user_denied['count'];
818 $res_user_allowed = sqlQuery($sql_user_acl,array($section_identifier,$user_id,1));
819 $count_user_allowed = $res_user_allowed['count'];
821 $res_group_denied = sqlQuery($sql_group_acl_denied, $groups_sql_param);
822 $count_group_denied = $res_group_denied['count'];
824 $res_group_allowed = sqlQuery($sql_group_acl_allowed, $groups_sql_param);
825 $count_group_allowed = $res_group_allowed['count'];
827 if($count_user_denied > 0)
829 elseif($count_user_allowed > 0)
831 elseif($count_group_denied > 0)
833 elseif($count_group_allowed > 0)
839 // This generates an HTML options list for all ACOs.
840 // The caller inserts this between <select> and </select> tags.
842 function gen_aco_html_options($default='') {
843 global $phpgacl_location;
844 require_once("$phpgacl_location/gacl_api.class.php");
846 $gacl = new gacl_api();
847 // collect and sort all aco objects
848 $list_aco_objects = $gacl->get_objects(NULL, 0, 'ACO');
849 ksort($list_aco_objects);
850 foreach ($list_aco_objects as $seckey => $dummy) {
851 if (empty($dummy)) continue;
852 asort($list_aco_objects[$seckey]);
853 $aco_section_data = $gacl->get_section_data($seckey, 'ACO');
854 $aco_section_title = $aco_section_data[3];
855 $s .= "<optgroup label='" . xla($aco_section_title) . "'>\n";
856 foreach($list_aco_objects[$seckey] as $acokey) {
857 $aco_id = $gacl->get_object_id($seckey, $acokey,'ACO');
858 $aco_data = $gacl->get_object_data($aco_id, 'ACO');
859 $aco_title = $aco_data[0][3];
860 $optkey = "$seckey|$acokey";
861 $s .= "<option value='" . attr($optkey) . "'";
862 if ($optkey == $default) $s .= ' selected';
863 $s .= ">" . xlt($aco_title) . "</option>";
870 // Permissions check for an ACO in "section|aco" format.
871 // Note $return_value may be an array of return values.
873 function acl_check_aco_spec($aco_spec, $user='', $return_value='') {
874 if (empty($aco_spec)) return true;
875 $tmp = explode('|', $aco_spec);
876 if (!is_array($return_value)) $return_value = array($return_value);
877 foreach ($return_value as $rv) {
878 if (acl_check($tmp[0], $tmp[1], $user, $rv)) return true;
883 // Permissions check for a specified encounter form type.
884 // Note $return_value may be an array of return values.
886 function acl_check_form($formdir, $user='', $return_value='') {
887 require_once(dirname(__FILE__) . '/registry.inc');
888 $tmp = getRegistryEntryByDirectory($formdir, 'aco_spec');
889 return acl_check_aco_spec($tmp['aco_spec'], $user, $return_value);
892 // Permissions check for a specified issue type.
893 // Note $return_value may be an array of return values.
895 function acl_check_issue($type, $user='', $return_value='') {
896 require_once(dirname(__FILE__) . '/lists.inc');
898 if (empty($ISSUE_TYPES[$type][5])) return true;
899 return acl_check_aco_spec($ISSUE_TYPES[$type][5], $user, $return_value);
902 // Permissions check for a specified document category name.
903 // Note $return_value may be an array of return values.
905 function acl_check_cat_name($catname, $user='', $return_value='') {
906 $tmp = sqlQuery("SELECT aco_spec FROM categories WHERE name = ? ORDER BY id LIMIT 1",
908 if (empty($tmp['aco_spec'])) return true;
909 return acl_check_aco_spec($tmp['aco_spec'], $user, $return_value);