added ending dates of service
[openemr.git] / library / acl.inc
blobf65c83eddb1bc8baa5bf138e8d2e73df0fec5831
1 <?php
2   // If you have installed phpGACL (http://phpgacl.sourceforge.net/)
3   // and have configured it for your site, then uncomment the following
4   // statement and change it to point to the location where
5   // gacl.class.php is intalled.
6   //
7   // $phpgacl_location = "/var/www/gacl";
9   // The following Access Control Objects (ACO) are currently supported.
10   // These are the "things to be protected":
11   //
12   // Section "admin" (Administration):
13   //   super       Superuser - can delete patients, encounters, issues
14   //   calendar    Calendar Settings
15   //   database    Database Reporting
16   //   forms       Forms Administration
17   //   practice    Practice Settings
18   //   superbill   Superbill Codes Administration
19   //   users       Users/Groups/Logs Administration
20   //   batchcom    Batch Communication Tool
21   //   language    Language Interface Tool
22   //   drugs       Pharmacy Dispensary
23   //   acl         ACL Administration
24   //
25   // Section "acct" (Accounting):
26   //   bill        Billing (write optional)
27   //   disc        Allowed to discount prices (in Fee Sheet or Checkout form)
28   //   eob         EOB Data Entry
29   //   rep         Financial Reporting - my encounters
30   //   rep_a       Financial Reporting - anything
31   //
32   // Section "patients" (Patient Information):
33   //   appt        Appointments (write optional)
34   //   demo        Demographics (write,addonly optional)
35   //   med         Medical Records and History (write,addonly optional)
36   //   trans       Transactions, e.g. referrals (write optional)
37   //   docs        Documents (write,addonly optional)
38   //   notes       Patient Notes (write,addonly optional)
39   //
40   // Section "encounters" (Encounter Information):
41   //   auth        Authorize - my encounters
42   //   auth_a      Authorize - any encounters
43   //   coding      Coding - my encounters (write,wsome optional)
44   //   coding_a    Coding - any encounters (write,wsome optional)
45   //   notes       Notes - my encounters (write,addonly optional)
46   //   notes_a     Notes - any encounters (write,addonly optional)
47   //   date_a      Fix encounter dates - any encounters
48   //   relaxed     Less-private information (write,addonly optional)
49   //               (e.g. the Sports Fitness encounter form)
50   //
51   // Section "squads" applies to sports team use only:
52   //   acos in this section define the user-specified list of squads
53   //
54   // Section "sensitivities" (Sensitivities):
55   //   normal     Normal
56   //   high       High
58   if (isset ($phpgacl_location)) {
59     include_once("$phpgacl_location/gacl.class.php");
60     $gacl_object = new gacl();
61     //DO NOT CHANGE BELOW VARIABLE
62     $section_aro_value = 'users';
63   }
65   // acl_check should return 0 if access is denied.  Otherwise it may
66   // return anything that evaluates to true.  In addition if any of the
67   // following types of access are applicable, then the corresponding value
68   // must be returned if and only if such access is granted (ony one may
69   // be specified):
70   //
71   // * write   - the user may add or modify the ACO
72   // * wsome   - the user has limited add/modify access to the ACO
73   // * addonly - the user may view and add but not modify entries
74   //
75   function acl_check($section, $value, $user = '') {
76     global $gacl_object, $phpgacl_location, $section_aro_value;
77     if (! $user) $user = $_SESSION['authUser'];
79     if ($phpgacl_location) {
80       return $gacl_object->acl_check($section, $value, $section_aro_value, $user);
81     }
83     // If no phpgacl, then apply the old static rules whereby "authorized"
84     // users (providers) can do anything, and other users can do most things.
85     // If you want custom access control but don't want to mess with phpGACL,
86     // then you could customize the code below instead.
88     if ($section == 'admin' && $value == 'super') return 0;
90     if ($_SESSION['userauthorized']) return 'write';
92     if ($section == 'patients') {
93       if ($value == 'med') return 1;
94       return 'write';
95     }
96     else if ($section == 'encounters') {
97       if (strpos($value, 'coding' ) === 0) return 'write';
98       if (strpos($value, 'notes'  ) === 0) return 'write';
99       if ($value == 'relaxed') return 'write';
100     }
101     else if ($section != 'admin') {
102       return 'write';
103     }
105     return 0;
106   }
108   // Get the ACO name/value pairs for a designated section.  Each value
109   // is an array (section_value, value, order_value, name, hidden).
110   //
111   function acl_get_section_acos($section) {
112     global $phpgacl_location;
113     if ($phpgacl_location) {
114       include_once("$phpgacl_location/gacl_api.class.php");
115       $gacl = new gacl_api();
116       $arr1 = $gacl->get_objects($section, 1, 'ACO');
117       $arr = array();
118       if (!empty($arr1[$section])) {
119         foreach ($arr1[$section] as $value) {
120           $odata = $gacl->get_object_data($gacl->get_object_id($section, $value, 'ACO'), 'ACO');
121           $arr[$value] = $odata[0];
122         }
123       }
124       return $arr;
125     }
126     return 0;
127   }
129   // Return an array keyed on squad ACO names.
130   // This is only applicable for sports team use.
131   //
132   function acl_get_squads() {
133     return acl_get_section_acos('squads');
134   }
136   // Return an array keyed on encounter sensitivity level ACO names.
137   // Sensitivities are useful when some encounter notes are not
138   // medically sensitive (e.g. a physical fitness test), and/or if
139   // some will be "for doctor's eyes only" (e.g. STD treatment).
140   //
141   // When a non-blank sensitivity value exists in the new encounter
142   // form, it names an additional ACO required for access to all forms
143   // in the encounter.  If you want some encounters to be non-sensitive,
144   // then you also need some default nonblank sensitivity for normal
145   // encounters, as well as greater encounter notes permissions for
146   // those allowed to view non-sensitive encounters.
147   //
148   function acl_get_sensitivities() {
149     return acl_get_section_acos('sensitivities');
150   }
152   //
153   // Returns a sorted array of all available Group Titles.
154   //
155   function acl_get_group_title_list() {
156     global $phpgacl_location;
157     if (isset ($phpgacl_location)) {
158       include_once("$phpgacl_location/gacl_api.class.php");
159       $gacl = new gacl_api();
160       $parent_id = $gacl->get_root_group_id();
161       $arr_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
162       $arr_group_titles = array();
163       foreach ($arr_group_ids as $value) {
164         $arr_group_data = $gacl->get_group_data($value, 'ARO');
165         $arr_group_titles[$value] = $arr_group_data[3];
166       }
167       sort($arr_group_titles);
168       return $arr_group_titles;
169     }
170     return 0;
171   }
173   //
174   // Returns a sorted array of group Titles that a user belongs to.
175   // Returns 0 if does not belong to any group yet.
176   //   $user_name = Username, which is login name.
177   //
178   function acl_get_group_titles($user_name) {
179     global $phpgacl_location, $section_aro_value;
180     if (isset ($phpgacl_location)) {
181       include_once("$phpgacl_location/gacl_api.class.php");
182       $gacl = new gacl_api();
183       $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
184       if ($user_aro_id) {
185         $arr_group_id = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
186         if ($arr_group_id) {
187           foreach ($arr_group_id as $key => $value) {
188             $arr_group_data = $gacl->get_group_data($value, 'ARO');
189             $arr_group_titles[$key] =  $arr_group_data[3];
190           }
191         sort($arr_group_titles);
192         return $arr_group_titles;
193         }
194       }
195     }
196     return 0;
197   }
199   //
200   // This will place the user aro object into selected group(s)
201   // It uses the set_user_aro() function
202   //   $username = username (string)
203   //   $group = title of group(s) (string or array)
204   //
205   function add_user_aros($username, $group) {
206    $current_user_groups = acl_get_group_titles($username);
207    if (!$current_user_groups) {
208     $current_user_groups = array();
209    }
210    if (is_array($group)){
211     foreach ($group as $value) {
212        if (!in_array($value, $current_user_groups)) { 
213         array_push($current_user_groups, $value);
214        }
215     }
216    }
217    else {   
218     if (!in_array($group, $current_user_groups)) {
219      array_push($current_user_groups, $group);
220     }
221    }    
222    $user_data = mysql_fetch_array(sqlStatement("select * from users where username='" .
223     $username . "'"));
224    set_user_aro($current_user_groups, $username, $user_data["fname"],
225     $user_data["mname"], $user_data["lname"]);
226    return;
227   }
229   //
230   // This will remove the user aro object from the selected group(s)
231   // It uses the set_user_aro() function
232   //   $username = username (string)
233   //   $group = title of group(s) (string or array)
234   //
235   function remove_user_aros($username, $group) {
236    $current_user_groups = acl_get_group_titles($username);
237    $new_user_groups = array();
238    if (is_array($group)){
239     foreach ($current_user_groups as $value) {    
240      if (!in_array($value, $group)) {
241       array_push($new_user_groups, $value);
242      }
243     }    
244    }
245    else {   
246     foreach ($current_user_groups as $value) {     
247      if ($value != $group) {
248       array_push($new_user_groups, $value);
249      }
250     }
251    }
252    $user_data = mysql_fetch_array(sqlStatement("select * from users where username='" .
253     $username . "'"));
254    set_user_aro($new_user_groups, $username, $user_data["fname"],
255     $user_data["mname"], $user_data["lname"]);
256    return;
257   }
259   //
260   // This will either create or edit a user aro object, and then place it
261   // in the requested groups. It will not allow removal of the 'admin'
262   // user from the 'admin' group.
263   //   $arr_group_titles = titles of the groups that user will be added to.
264   //   $user_name = username, which is login name.
265   //   $first_name = first name
266   //   $middle_name = middle name
267   //   $last_name = last name
268   //
269   function set_user_aro($arr_group_titles, $user_name, $first_name, $middle_name, $last_name) {
270     global $phpgacl_location, $section_aro_value;
272     if (isset ($phpgacl_location)) {
273       include_once("$phpgacl_location/gacl_api.class.php");
274       $gacl = new gacl_api();
276       //get array of all available group ID numbers
277       $parent_id = $gacl->get_root_group_id();
278       $arr_all_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
280       //Cycle through ID array to find and process each selected group
281       //Create a counter since processing of first hit is unique
282       $counter = 0;
283       foreach ($arr_all_group_ids as $value) {
284         $arr_group_data = $gacl->get_group_data($value, 'ARO');
285         if (in_array($arr_group_data[3], $arr_group_titles)) {
286           //We have a hit, so need to add group and increment counter
287           //  because processing of first hit is unique
288           $counter = $counter + 1;
289           //create user full name field
290           if ($middle_name) {
291             $full_name = $first_name . " " . $middle_name . " " .  $last_name;
292           }
293           else {
294             $full_name = $first_name . " " . $last_name;
295           }
297           //If this is not the first group to be added, then will skip below
298           // and will be added. If this is the first group, then need to
299           // go thru several steps before adding the group.
300           if ($counter == 1) {
301             //get ID of user ARO object, if it exist
302             $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
303             if ($user_aro_id) {
304               //user ARO object already exist, so will edit it
305               $gacl->edit_object($user_aro_id, $section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
307               //remove all current user ARO object group associations
308               $arr_remove_group_ids = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
309               foreach ($arr_remove_group_ids as $value2) {
310                 $gacl->del_group_object($value2, $section_aro_value, $user_name, 'ARO');
311               }
312             }
313             else {
314               //user ARO object does not exist, so will create it
315               $gacl->add_object($section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
316             }
317           }
319           //place the user ARO object in the selected group
320           $gacl->add_group_object($value, $section_aro_value, $user_name, 'ARO');
322           //
323           //Below will not allow 'admin' user to be removed from 'admin' group
324           //
325           if ($user_name == 'admin') {
326             $boolean_admin=0;
327             $admin_id = $gacl->get_object_id($section_aro_value, 'admin', 'ARO');
328             $arr_admin = $gacl->get_object_groups($admin_id, 'ARO', 'NO_RECURSE');
329             foreach ($arr_admin as $value3) {
330               $arr_admin_data = $gacl->get_group_data($value3, 'ARO');
331               if (strcmp($arr_admin_data[2], 'admin') == 0) {
332                 $boolean_admin=1;
333               }
334             }
335             if (!$boolean_admin) {
336               foreach ($arr_all_group_ids as $value4) {
337                 $arr_temp = $gacl->get_group_data($value4, 'ARO');
338                 if ($arr_temp[2] == 'admin') {
339                   $gacl->add_group_object($value4, $section_aro_value, 'admin', 'ARO');
340                 }
341               }
342             }
343           }
344         }
345       }
346     }
347    return;
348   }
350   //
351   // Returns true if acl exist
352   // Returns false if acl doesn't exist
353   //  EITHER $title or $name is required(send FALSE in variable
354   //  not being used). If both are sent, then only $title will be
355   //  used.
356   //  $return_value is required
357   //    $title = title of acl (string)
358   //    $name = name of acl (string)
359   //    $return_value = return value of acl (string)
360   //
361   function acl_exist($title, $name, $return_value) {
362    global $phpgacl_location;
363    if (isset ($phpgacl_location)) {
364     include_once("$phpgacl_location/gacl_api.class.php");
365     $gacl = new gacl_api();
366     if (!$name) {
367      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
368     }
369     else if (!$title) {
370      $group_id = $gacl->get_group_id($name, NULL, 'ARO');
371      if ($group_id) {
372       $group_data = $gacl->get_group_data($group_id, 'ARO');
373       $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $group_data[3], FALSE, FALSE, FALSE, $return_value);
374      }
375      else {
376      return false;
377      }
378     }
379     else {
380      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
381     }
382     if (!empty($acl)) {
383      return true;
384     }
385     else {
386      return false;
387     }
388    }
389   }
391   //
392   // This will add a new acl and group(if group doesn't yet exist)
393   // with one aco in it.
394   //   $acl_title = title of acl (string)
395   //   $acl_name = name of acl (string)
396   //   $return_value = return value of acl (string)
397   //   $note = description of acl (array)
398   //
399   function acl_add($acl_title, $acl_name, $return_value, $note) {
400    global $phpgacl_location;
401    if (isset ($phpgacl_location)) {
402     include_once("$phpgacl_location/gacl_api.class.php");
403     $gacl = new gacl_api();
404     $group_id = $gacl->get_group_id($acl_name, $acl_title, 'ARO');
405     if ($group_id) {
406      //group already exist, so just create acl
407      $gacl->add_acl(array("patients"=>array("appt")),
408       NULL, array($group_id), NULL, NULL, 1, 1, $return_value, $note);
409     }
410     else {
411      //create group, then create acl
412      $parent_id = $gacl->get_root_group_id();
413      $aro_id = $gacl->add_group($acl_name, $acl_title, $parent_id, 'ARO');
414      $gacl->add_acl(array("patients"=>array("appt")),
415       NULL, array($aro_id), NULL, NULL, 1, 1, $return_value, $note);
416     }
417     return;
418    }
419    return 0;
420   }
422   //
423   // This will remove acl. It will also remove group(if the group
424   // is no longer associated with any acl's).
425   //   $acl_title = title of acl (string)
426   //   $acl_name = name of acl (string)
427   //   $return_value = return value of acl (string)
428   //   $note = description of acl (array)
429   //
430   function acl_remove($acl_title, $return_value) {
431    global $phpgacl_location;
432    if (isset ($phpgacl_location)) {
433     include_once("$phpgacl_location/gacl_api.class.php");
434     $gacl = new gacl_api();
435     //First, delete the acl
436     $acl_id=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
437     $gacl->del_acl($acl_id[0]);
438     //Then, remove the group(if no more acl's are remaining)
439     $acl_search=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, FALSE);
440     if (empty($acl_search)){
441      $group_id=$gacl-> get_group_id(NULL, $acl_title, 'ARO');
442      $gacl->del_group($group_id, TRUE, 'ARO');
443     }
444     return;
445    }
446    return 0;
447   }
449   //
450   // This will place the aco(s) into the selected acl
451   //   $acl_title = title of acl (string)
452   //   $return_value = return value of acl (string)
453   //   $aco_id = id of aco (array)
454   //
455   function acl_add_acos($acl_title, $return_value, $aco_id) {
456    global $phpgacl_location;
457    if (isset ($phpgacl_location)) {
458     include_once("$phpgacl_location/gacl_api.class.php");
459     $gacl = new gacl_api();
460     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
461     foreach ($aco_id as $value) { 
462      $aco_data = $gacl->get_object_data($value, 'ACO');
463      $aco_section = $aco_data[0][0];
464      $aco_name = $aco_data[0][1];   
465      $gacl->append_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
466     }
467     return;
468    }
469    return 0;
470   }
472   //
473   // This will remove the aco(s) from the selected acl
474   //   $acl_title = title of acl (string)
475   //   $return_value = return value of acl (string)
476   //   $aco_id = id of aco (array)
477   //
478   function acl_remove_acos($acl_title, $return_value, $aco_id) {
479    global $phpgacl_location;
480    if (isset ($phpgacl_location)) {
481     include_once("$phpgacl_location/gacl_api.class.php");
482     $gacl = new gacl_api();
483     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
484     foreach ($aco_id as $value) {
485      $aco_data = $gacl->get_object_data($value, 'ACO');
486      $aco_section = $aco_data[0][0];
487      $aco_name = $aco_data[0][1];
488      $gacl->shift_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
489      }
490     return;
491    }
492    return 0;
493   }
495   //
496   // This will return the number of aco objects
497   //  in a specified acl.
498   //   $acl_title = title of acl (string)
499   //   $return_value = return value of acl (string)
500   //
501   function acl_count_acos($acl_title, $return_value) {
502    global $phpgacl_location;
503    if (isset ($phpgacl_location)) {
504     include_once("$phpgacl_location/gacl_api.class.php");
505     $gacl = new gacl_api();
506     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
507     $acl_data = $gacl->get_acl($acl_id[0]);
508     $aco_count = 0;
509     foreach ($acl_data['aco'] as $key => $value) {
510      $aco_count = $aco_count + count($acl_data['aco'][$key]);
511     }
512     return $aco_count;
513    }
514    return 0;
515   }