remove embedded phpmyadmin package
[openemr.git] / library / acl.inc
blob66155970f8ad53d74d225433bdfaac9dd7d86be7
1 <?php
2 /**
3  * library/acl.inc
4  *
5  * Functions wrapping php-GACL's functionality, to create a generic OpenEMR access control system.
6  *
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 .
18  *
19  * @package OpenEMR
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
24  */
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
31 // below.
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":
51   //
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
64   //
65   // Section "acct" (Accounting):
66   //   bill        Billing (write optional)
67   //   disc        Allowed to discount prices (in Fee Sheet or Checkout form)
68   //   eob         EOB Data Entry
69   //   rep         Financial Reporting - my encounters
70   //   rep_a       Financial Reporting - anything
71   //
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)
86   //
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)
97   //
98   // Section "squads" applies to sports team use only:
99   //   acos in this section define the user-specified list of squads
100   //
101   // Section "sensitivities" (Sensitivities):
102   //   normal     Normal
103   //   high       High
104   //
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)
111   //
112   // Section "placeholder" (Placeholder):
113   //   filler     Placeholder (Maintains empty ACLs)
114   //
115   // Section "nationnotes" (Nation Notes):
116   //   nn_configure     Nation Notes
117   //
118   // Section "patientportal" (Patient Portal):
119   //   portal     Patient Portal
120   // Section "menus" (Menus):
121   //   modle      Module
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;
130   }
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
152  *                     requested.
153  */
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)) {
159       return TRUE;
160     }
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
169       }
170       $access=FALSE; //flag
171       $deny=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']) {
179                 $access=TRUE;
180               }
181               else {
182                 $deny=TRUE;
183               }
184             }
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']) {
189                   $access=TRUE;
190                 }
191                 else{
192                   $deny=TRUE;
193                 }
194               }
195             }
196           }
197         }
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']) {
202               $access=TRUE;
203             }
204             else {
205               $deny=TRUE;
206             }
207           }
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']) {
212                 $access=TRUE;
213               }
214               else{
215                 $deny=TRUE;
216               }
217             }
218           }
219         }
220       }
222       // Now decide whether user has access
223       // (Note a denial takes precedence)
224       if (!$deny && $access) return TRUE;
225       return FALSE;
226     }
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;
239       return 'write';
240     }
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';
245     }
246     else if ($section != 'admin') {
247       return 'write';
248     }
250     return 0;
251   }
253   // Get the ACO name/value pairs for a designated section.  Each value
254   // is an array (section_value, value, order_value, name, hidden).
255   //
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');
262       $arr = array();
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];
267         }
268       }
269       return $arr;
270     }
271     return 0;
272   }
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;
280     }
281     return ($a[2] < $b[2]) ? -1 : 1;
282   }
284   // Return an array keyed on squad ACO names.
285   // This is only applicable for sports team use.
286   //
287   function acl_get_squads() {
288     $squads = acl_get_section_acos('squads');
289     uasort($squads, "_acl_squad_compare");
290     return $squads;
291   }
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).
297   //
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.
304   //
305   function acl_get_sensitivities() {
306     return acl_get_section_acos('sensitivities');
307   }
309   //
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)
314   //
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');
321     if ($aco_id) {
322      return true;
323     }
324    }
325    return false;
326   }
328   //
329   // Returns a sorted array of all available Group Titles.
330   //
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];
342       }
343       sort($arr_group_titles);
344       return $arr_group_titles;
345     }
346     return 0;
347   }
349   //
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.
353   //
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');
360       if ($user_aro_id) {
361         $arr_group_id = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
362         if ($arr_group_id) {
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];
366           }
367         sort($arr_group_titles);
368         return $arr_group_titles;
369         }
370       }
371     }
372     return 0;
373   }
375   //
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)
380   //
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();
385    }
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);
390        }
391     }
392    }
393    else {
394     if (!in_array($group, $current_user_groups)) {
395      array_push($current_user_groups, $group);
396     }
397    }
398    $user_data = sqlFetchArray(sqlStatement("select * from users where username='" .
399     $username . "'"));
400    set_user_aro($current_user_groups, $username, $user_data["fname"],
401     $user_data["mname"], $user_data["lname"]);
402    return;
403   }
405   //
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)
410   //
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);
418      }
419     }
420    }
421    else {
422     foreach ($current_user_groups as $value) {
423      if ($value != $group) {
424       array_push($new_user_groups, $value);
425      }
426     }
427    }
428    $user_data = sqlFetchArray(sqlStatement("select * from users where username='" .
429     $username . "'"));
430    set_user_aro($new_user_groups, $username, $user_data["fname"],
431     $user_data["mname"], $user_data["lname"]);
432    return;
433   }
435   //
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
444   //
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;
459       }
460       else {
461         $gacl_protect = false;
462       }
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
470       $counter = 0;
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
481           if ($middle_name) {
482             $full_name = $first_name . " " . $middle_name . " " .  $last_name;
483           }
484           else {
485             if ($last_name) {
486               $full_name = $first_name . " " . $last_name;
487             }
488             else {
489               $full_name = $first_name;
490             }
491           }
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.
496           if ($counter == 1) {
497             //get ID of user ARO object, if it exist
498             $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
499             if ($user_aro_id) {
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');
507               }
508             }
509             else {
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');
512             }
513           }
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');
518           }
520           //
521           //Below will not allow 'admin' or gacl_protected user to be removed from 'admin' group
522           //
523           if ($gacl_protect) {
524             $boolean_admin=0;
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) {
530                 $boolean_admin=1;
531               }
532             }
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');
538                 }
539               }
540             }
541           }
542         }
543         //if array of groups was empty, then we are done, and can break from loop
544         if (empty($arr_group_titles)) break;
545       }
546       return true;
547     }
548    return false;
549   }
551   //
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
556   //  used.
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)
561   //
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();
567     if (!$name) {
568      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
569     }
570     else if (!$title) {
571      $group_id = $gacl->get_group_id($name, NULL, 'ARO');
572      if ($group_id) {
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);
575      }
576      else {
577      return false;
578      }
579     }
580     else {
581      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
582     }
583     if (!empty($acl)) {
584      return true;
585     }
586     else {
587      return false;
588     }
589    }
590   }
592   //
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)
599   //
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');
606     if ($group_id) {
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);
610     }
611     else {
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);
617     }
618     return;
619    }
620    return 0;
621   }
623   //
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)
630   //
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');
644     }
645     return;
646    }
647    return 0;
648   }
650   //
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)
655   //
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)));
667     }
668     return;
669    }
670    return 0;
671   }
673   //
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)
680   //
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;
700     }
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)));
707      }
708     return;
709    }
710    return 0;
711   }
713   //
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)
718   //
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]);
726     $aco_count = 0;
727     foreach ($acl_data['aco'] as $key => $value) {
728      $aco_count = $aco_count + count($acl_data['aco'][$key]);
729     }
730     return $aco_count;
731    }
732    return 0;
733   }
735   //
736   // Function to remove an element from an array
737   //
738   function remove_element($arr, $val){
739    $arr2 = array();
740    foreach ($arr as $value){
741     if ($value != $val) {
742      array_push($arr2,$value);
743     }
744    }
745    return $arr2;
746   }
747   /**
748   * Checks ACL
749   *
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
754   *
755   * @param String $user_id Auth user Id
756   * $param String $section_identifier ACL Section id
757   * @return boolean
758   */
759   function zh_acl_check($user_id,$section_identifier){
760     $sql_user_acl = " SELECT
761                         COUNT(allowed) AS count
762                       FROM
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`
766                       WHERE
767                           acl_sections.section_identifier = ? AND usr_settings.user_id = ? AND usr_settings.allowed = ?";
768     $sql_user_group = " SELECT
769                           gagp.id AS group_id
770                         FROM
771                           gacl_aro AS garo
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
778                         WHERE
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 = "";
785     $firstFlag = TRUE;
786     while($row = sqlFetchArray($res_groups)){
787       array_push($groups_sql_param,$row['group_id']);
788       if ($firstFlag) {
789         $groupPlacemakers = "?";
790         $firstFlag = FALSE;
791       }
792       else {
793         $groupPlacemakers .= ",?";
794       }
795     }
796     $sql_group_acl_base  = " SELECT
797                         COUNT(allowed) AS count
798                       FROM
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
802                       WHERE
803                         group_settings.group_id IN (".$groupPlacemakers.") AND acl_sections.`section_identifier` = ? ";
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);
809       
810         $count_group_allowed    = 0;
811         $count_user_allowed     = 0;
812       
813         $res_user_allowed       = sqlQuery($sql_user_acl,array($section_identifier,$user_id,1));
814         $count_user_allowed     = $res_user_allowed['count'];
816         $res_group_allowed      = sqlQuery($sql_group_acl_allowed, $groups_sql_param);
817         $count_group_allowed    = $res_group_allowed['count'];
819         if($count_user_allowed > 0)
820             return true;
821         elseif($count_group_allowed > 0)
822             return true;
823         else
824             return false;
825     }
827   // This generates an HTML options list for all ACOs.
828   // The caller inserts this between <select> and </select> tags.
829   //
830   function gen_aco_html_options($default='') {
831     global $phpgacl_location;
832     require_once("$phpgacl_location/gacl_api.class.php");
833     $s = '';
834     $gacl = new gacl_api();
835     // collect and sort all aco objects
836     $list_aco_objects = $gacl->get_objects(NULL, 0, 'ACO');
837     ksort($list_aco_objects);
838     foreach ($list_aco_objects as $seckey => $dummy) {
839       if (empty($dummy)) continue;
840       asort($list_aco_objects[$seckey]);
841       $aco_section_data = $gacl->get_section_data($seckey, 'ACO');
842       $aco_section_title = $aco_section_data[3];
843       $s .= "<optgroup label='" . xla($aco_section_title) . "'>\n";
844       foreach($list_aco_objects[$seckey] as $acokey) {
845         $aco_id = $gacl->get_object_id($seckey, $acokey,'ACO');
846         $aco_data = $gacl->get_object_data($aco_id, 'ACO');
847         $aco_title = $aco_data[0][3];
848         $optkey = "$seckey|$acokey";
849         $s .= "<option value='" . attr($optkey) . "'";
850         if ($optkey == $default) $s .= ' selected';
851         $s .= ">" . xlt($aco_title) . "</option>";
852       }
853       $s .= "</optgroup>";
854     }
855     return $s;
856   }
858   // Permissions check for an ACO in "section|aco" format.
859   // Note $return_value may be an array of return values.
860   //
861   function acl_check_aco_spec($aco_spec, $user='', $return_value='') {
862     if (empty($aco_spec)) return true;
863     $tmp = explode('|', $aco_spec);
864     if (!is_array($return_value)) $return_value = array($return_value);
865     foreach ($return_value as $rv) {
866       if (acl_check($tmp[0], $tmp[1], $user, $rv)) return true;
867     }
868     return false;
869   }
871   // Permissions check for a specified encounter form type.
872   // Note $return_value may be an array of return values.
873   //
874   function acl_check_form($formdir, $user='', $return_value='') {
875     require_once(dirname(__FILE__) . '/registry.inc');
876     $tmp = getRegistryEntryByDirectory($formdir, 'aco_spec');
877     return acl_check_aco_spec($tmp['aco_spec'], $user, $return_value);
878   }
880   // Permissions check for a specified issue type.
881   // Note $return_value may be an array of return values.
882   //
883   function acl_check_issue($type, $user='', $return_value='') {
884     require_once(dirname(__FILE__) . '/lists.inc');
885     global $ISSUE_TYPES;
886     if (empty($ISSUE_TYPES[$type][5])) return true;
887     return acl_check_aco_spec($ISSUE_TYPES[$type][5], $user, $return_value);
888   }
890   // Permissions check for a specified document category name.
891   // Note $return_value may be an array of return values.
892   //
893   function acl_check_cat_name($catname, $user='', $return_value='') {
894     $tmp = sqlQuery("SELECT aco_spec FROM categories WHERE name = ? ORDER BY id LIMIT 1",
895       array($catname));
896     if (empty($tmp['aco_spec'])) return true;
897     return acl_check_aco_spec($tmp['aco_spec'], $user, $return_value);
898   }