Fixed bug that can cause saving of user edits to fail.
[openemr.git] / library / ajax / adminacl_ajax.php
blob4d5b534bda72b0bc0e90984bff52383a7e5e2ff2
1 <?php
2 // Copyright (C) 2007 Brady Miller <brady@sparmy.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 //
10 // This file contains functions that service ajax requests for
11 // ACL(php-gacl) administration within OpenEMR. All returns are
12 // done via xml.
14 // Important - Ensure that display_errors=Off in php.ini settings.
16 include_once("../../interface/globals.php");
17 include_once("$srcdir/acl.inc");
18 include_once("$srcdir/user.inc");
19 include_once("$srcdir/calendar.inc");
21 header("Content-type: text/xml");
22 header("Cache-Control: no-cache");
24 //initiate error array
25 $error = array();
27 //PENDING, need to clean this up on client side
28 //ensure user has proper access
29 if (!acl_check('admin', 'acl')) {
30 echo error_xml(xl('ACL Administration Not Authorized'));
31 exit;
33 //ensure php is installed
34 if (!isset($phpgacl_location)) {
35 echo error_xml(xl('PHP-gacl is not installed'));
36 exit;
39 //Display red alert if Emergency Login ACL is activated for a user.
40 if($_POST["action"] == "add"){
41 if (in_array("Emergency Login",$_POST["selection"])) {
42 array_push($error, (xl('Emergency Login ACL is chosen. The user is still in active state, please de-activate the user and activate the same when required during emergency situations. Visit Administration->Users for activation or de-activation.') ));
46 //PROCESS USERNAME REQUESTS
47 if ($_POST["control"] == "username") {
48 if ($_POST["action"] == "list") {
49 //return username list with alert if user is not joined to group
50 echo username_listings_xml($error);
55 //PROCESS MEMBERSHIP REQUESTS
56 if ($_POST["control"] == "membership") {
57 if ($_POST["action"] == "list") {
58 //return membership data
59 echo user_group_listings_xml($_POST["name"], $error);
62 if ($_POST["action"] == "add") {
63 if ($_POST["selection"][0] == "null") {
64 //no selection, return soft error, and just return membership data
65 array_push($error, (xl('No group was selected') . "!"));
66 echo user_group_listings_xml($_POST["name"], $error);
67 exit;
69 //add the group, then return updated membership data
70 add_user_aros($_POST["name"], $_POST["selection"]);
71 echo user_group_listings_xml($_POST["name"], $error);
74 if ($_POST["action"] == "remove") {
75 if ($_POST["selection"][0] == "null") {
76 //no selection, return soft error, and just return membership data
77 array_push($error, (xl('No group was selected') . "!"));
78 echo user_group_listings_xml($_POST["name"], $error);
79 exit;
81 // check if user is protected. If so, then state message unable to remove from admin group.
82 $userNametoID = getIDfromUser($_POST["name"]);
83 if (checkUserSetting("gacl_protect","1",$userNametoID) || ($_POST["name"] == "admin")) {
84 $gacl_protect = true;
86 else {
87 $gacl_protect = false;
89 if ($gacl_protect && in_array("Administrators",$_POST["selection"])) {
90 //unable to remove admin user from administrators group, process remove,
91 // send soft error, then return data
92 array_push($error, (xl('Not allowed to remove this user from the Administrators group') . "!"));
93 remove_user_aros($_POST["name"], $_POST["selection"]);
94 echo user_group_listings_xml($_POST["name"], $error);
95 exit;
97 //remove the group(s), then return updated membership data
98 remove_user_aros($_POST["name"], $_POST["selection"]);
99 echo user_group_listings_xml($_POST["name"], $error);
104 //PROCESS ACL REQUESTS
105 if ($_POST["control"] == "acl") {
106 if ($_POST["action"] == "list") {
107 //return acl titles with return values
108 echo acl_listings_xml($error);
111 if ($_POST["action"] == "add") {
112 //validate form data
113 $form_error = false;
114 if (empty($_POST["title"])) {
115 $form_error = true;
116 array_push($error, ("title_" . xl('Need to enter title') . "!"));
118 else if (!ctype_alpha(str_replace(' ', '', $_POST["title"]))) {
119 $form_error = true;
120 array_push($error, ("title_" . xl('Please only use alphabetic characters') . "!"));
122 else if (acl_exist($_POST["title"], FALSE, $_POST["return_value"])) {
123 $form_error = true;
124 array_push($error, ("title_" . xl('Already used, choose another title') . "!"));
126 if (empty($_POST["identifier"])) {
127 $form_error = true;
128 array_push($error, ("identifier_" . xl('Need to enter identifier') . "!"));
130 else if (!ctype_alpha($_POST["identifier"])) {
131 $form_error = true;
132 array_push($error, ("identifier_" . xl('Please only use alphabetic characters with no spaces') . "!"));
134 else if (acl_exist(FALSE, $_POST["identifier"], $_POST["return_value"])) {
135 $form_error = true;
136 array_push($error, ("identifier_" . xl('Already used, choose another identifier') . "!"));
138 if (empty($_POST["return_value"])) {
139 $form_error = true;
140 array_push($error, ("return_" . xl('Need to enter a Return Value') . "!"));
142 if (empty($_POST["description"])) {
143 $form_error = true;
144 array_push($error, ("description_" . xl('Need to enter a description') . "!"));
146 else if (!ctype_alpha(str_replace(' ', '', $_POST["description"]))) {
147 $form_error = true;
148 array_push($error, ("description_" . xl('Please only use alphabetic characters') . "!"));
150 //process if data is valid
151 if (!$form_error) {
152 acl_add($_POST["title"], $_POST["identifier"], $_POST["return_value"], $_POST["description"]);
153 echo "<?xml version=\"1.0\"?>\n" .
154 "<response>\n" .
155 "\t<success>SUCCESS</success>\n" .
156 "</response>\n";
158 else { //$form_error = true, so return errors
159 echo error_xml($error);
163 if ($_POST["action"] == "remove") {
164 //validate form data
165 $form_error = false;
166 if (empty($_POST["title"])) {
167 $form_error = true;
168 array_push($error, ("aclTitle_" . xl('Need to enter title') . "!"));
170 if ($_POST["title"] == "Administrators") {
171 $form_error = true;
172 array_push($error, ("aclTitle_" . xl('Not allowed to delete the Administrators group') . "!"));
174 //process if data is valid
175 if (!$form_error) {
176 acl_remove($_POST["title"], $_POST["return_value"]);
177 echo "<?xml version=\"1.0\"?>\n" .
178 "<response>\n" .
179 "\t<success>SUCCESS</success>\n" .
180 "</response>\n";
182 else { //$form_error = true, so return errors
183 echo error_xml($error);
187 if ($_POST["action"] == "returns") {
188 //simply return all the possible acl return_values
189 echo return_values_xml($error);
194 //PROCESS ACO REQUESTS
195 if ($_POST["control"] == "aco") {
196 if ($_POST["action"] == "list") {
197 //send acl data
198 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
201 if ($_POST["action"] == "add") {
202 if ($_POST["selection"][0] == "null") {
203 //no selection, return soft error, and just return data
204 array_push($error, (xl('Nothing was selected') . "!"));
205 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
206 exit;
208 //add the aco, then return updated membership data
209 acl_add_acos($_POST["name"], $_POST["return_value"], $_POST["selection"]);
210 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
213 if ($_POST["action"] == "remove") {
214 if ($_POST["selection"][0] == "null") {
215 //no selection, return soft error, and just return data
216 array_push($error, (xl('Nothing was selected') . "!"));
217 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
218 exit;
220 if ($_POST["name"] == "Administrators") {
221 //will not allow removal of acos from Administrators ACL
222 array_push($error, (xl('Not allowed to inactivate anything from the Administrators ACL') . "!"));
223 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
224 exit;
226 //remove the acos, then return updated data
227 acl_remove_acos($_POST["name"], $_POST["return_value"], $_POST["selection"]);
228 echo aco_listings_xml($_POST["name"], $_POST["return_value"], $error);
234 // Returns username listings via xml message.
235 // It will also include alert if user is not joined
236 // to a group yet
237 // $err = error strings (array)
239 function username_listings_xml($err) {
240 $message = "<?xml version=\"1.0\"?>\n" .
241 "<response>\n";
242 $res = sqlStatement("select * from users where username != '' order by username");
243 for ($iter = 0;$row = sqlFetchArray($res);$iter++)
244 $result4[$iter] = $row;
245 foreach ($result4 as $iter) {
246 $message .= "\t<user>\n" .
247 "\t\t<username>" . $iter{"username"} . "</username>\n";
248 $username_acl_groups = acl_get_group_titles($iter{"username"});
249 if (!$username_acl_groups) {
250 //not joined to any group, so send alert
251 $message .= "\t\t<alert>no membership</alert>\n";
253 $message .= "\t</user>\n";
255 if (isset($err)) {
256 foreach ($err as $value) {
257 $message .= "\t<error>" . $value . "</error>\n";
260 $message .= "</response>\n";
261 return $message;
265 // Returns user group listings(active and inactive lists)
266 // via xml message.
267 // $username = username
268 // $err = error strings (array)
270 function user_group_listings_xml($username, $err) {
271 $list_acl_groups = acl_get_group_title_list();
272 $username_acl_groups = acl_get_group_titles($username);
273 //note acl_get_group_titles() returns a 0 if user in no groups
275 $message = "<?xml version=\"1.0\"?>\n" .
276 "<response>\n" .
277 "\t<inactive>\n";
278 foreach ($list_acl_groups as $value) {
279 if ((!$username_acl_groups) || (!(in_array($value, $username_acl_groups)))) {
280 $message .= "\t\t<group>\n";
281 $message .= "\t\t\t<value>" . $value . "</value>\n";
283 // Modified 6-2009 by BM - Translate gacl group name if applicable
284 $message .= "\t\t\t<label>" . xl_gacl_group($value) . "</label>\n";
286 $message .= "\t\t</group>\n";
289 $message .= "\t</inactive>\n" .
290 "\t<active>\n";
291 if ($username_acl_groups) {
292 foreach ($username_acl_groups as $value) {
293 $message .= "\t\t<group>\n";
294 $message .= "\t\t\t<value>" . $value . "</value>\n";
296 // Modified 6-2009 by BM - Translate gacl group name if applicable
297 $message .= "\t\t\t<label>" . xl_gacl_group($value) . "</label>\n";
299 $message .= "\t\t</group>\n";
302 $message .= "\t</active>\n";
303 if (isset($err)) {
304 foreach ($err as $value) {
305 $message .= "\t<error>" . $value . "</error>\n";
308 $message .= "</response>\n";
309 return $message;
313 // Returns acl listings(including return value) via xml message.
314 // $err = error strings (array)
316 function acl_listings_xml($err) {
317 global $phpgacl_location;
318 include_once("$phpgacl_location/gacl_api.class.php");
319 $gacl = new gacl_api();
321 $message = "<?xml version=\"1.0\"?>\n" .
322 "<response>\n";
323 foreach (acl_get_group_title_list() as $value) {
324 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $value, FALSE, FALSE, FALSE, FALSE);
325 foreach ($acl_id as $value2) {
326 $acl = $gacl->get_acl($value2);
327 $ret = $acl["return_value"];
328 $note = $acl["note"];
330 // Modified 6-2009 by BM - Translate gacl group name if applicable
331 // Translate return value
332 // Translate description
333 $message .= "\t<acl>\n" .
334 "\t\t<value>" . $value . "</value>\n" .
335 "\t\t<title>" . xl_gacl_group($value) . "</title>\n" .
336 "\t\t<returnid>" . $ret . "</returnid>\n" .
337 "\t\t<returntitle>" . xl($ret) . "</returntitle>\n" .
338 "\t\t<note>" . xl($note) . "</note>\n" .
339 "\t</acl>\n";
342 if (isset($err)) {
343 foreach ($err as $value) {
344 $message .= "\t<error>" . $value . "</error>\n";
347 $message .= "</response>\n";
348 return $message;
352 // Return aco listings by sections(active and inactive lists)
353 // via xml message.
354 // $group = group title (string)
355 // $return_value = return value (string)
356 // $err = error strings (array)
358 function aco_listings_xml($group, $return_value, $err) {
359 global $phpgacl_location;
360 include_once("$phpgacl_location/gacl_api.class.php");
361 $gacl = new gacl_api();
363 //collect and sort all aco objects
364 $list_aco_objects = $gacl->get_objects(NULL, 0, 'ACO');
365 foreach ($list_aco_objects as $key => $value) {
366 asort($list_aco_objects[$key]);
369 //collect aco objects within the specified acl(already sorted)
370 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $group, FALSE, FALSE, FALSE, $return_value);
371 $acl = $gacl->get_acl($acl_id[0]);
372 $active_aco_objects = $acl["aco"];
374 $message = "<?xml version=\"1.0\"?>\n" .
375 "<response>\n" .
376 "\t<inactive>\n";
377 foreach ($list_aco_objects as $key => $value) {
378 $counter = 0;
379 foreach($list_aco_objects[$key] as $value2) {
380 if (!array_key_exists($key,$active_aco_objects) || !in_array($value2, $active_aco_objects[$key])) {
382 if ($counter == 0) {
383 $counter = $counter + 1;
384 $aco_section_data = $gacl->get_section_data($key, 'ACO');
385 $aco_section_title = $aco_section_data[3];
387 // Modified 6-2009 by BM - Translate gacl aco section name
388 $message .= "\t\t<section>\n" .
389 "\t\t\t<name>" . xl($aco_section_title) . "</name>\n";
392 $aco_id = $gacl->get_object_id($key, $value2,'ACO');
393 $aco_data = $gacl->get_object_data($aco_id, 'ACO');
394 $aco_title = $aco_data[0][3];
395 $message .= "\t\t\t<aco>\n";
397 // Modified 6-2009 by BM - Translate gacl aco name
398 $message .= "\t\t\t\t<title>" . xl($aco_title) . "</title>\n";
400 $message .= "\t\t\t\t<id>" . $aco_id . "</id>\n";
401 $message .= "\t\t\t</aco>\n";
404 if ($counter != 0) {
405 $message .= "\t\t</section>\n";
408 $message .= "\t</inactive>\n" .
409 "\t<active>\n";
410 foreach ($active_aco_objects as $key => $value) {
411 $aco_section_data = $gacl->get_section_data($key, 'ACO');
412 $aco_section_title = $aco_section_data[3];
414 // Modified 6-2009 by BM - Translate gacl aco section name
415 $message .= "\t\t<section>\n" .
416 "\t\t\t<name>" . xl($aco_section_title) . "</name>\n";
418 foreach($active_aco_objects[$key] as $value2) {
419 $aco_id = $gacl->get_object_id($key, $value2,'ACO');
420 $aco_data = $gacl->get_object_data($aco_id, 'ACO');
421 $aco_title = $aco_data[0][3];
422 $message .= "\t\t\t<aco>\n";
424 // Modified 6-2009 by BM - Translate gacl aco name
425 $message .= "\t\t\t\t<title>" . xl($aco_title) . "</title>\n";
427 $message .= "\t\t\t\t<id>" . $aco_id . "</id>\n";
428 $message .= "\t\t\t</aco>\n";
430 $message .= "\t\t</section>\n";
432 $message .= "\t</active>\n";
433 if (isset($err)) {
434 foreach ($err as $value) {
435 $message .= "\t<error>" . $value . "</error>\n";
438 $message .= "</response>\n";
439 return $message;
443 // Returns listing of all possible return values via xml message.
444 // $err = error strings (array)
446 function return_values_xml($err) {
447 global $phpgacl_location;
448 include_once("$phpgacl_location/gacl_api.class.php");
449 $gacl = new gacl_api();
450 $returns = array();
452 $message = "<?xml version=\"1.0\"?>\n" .
453 "<response>\n";
454 foreach(acl_get_group_title_list() as $value) {
455 $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $value, FALSE, FALSE, FALSE, FALSE);
456 foreach($acl_id as $value2){
457 $acl = $gacl->get_acl($value2);
458 $ret = $acl["return_value"];
459 if (!in_array($ret, $returns)) {
461 // Modified 6-2009 by BM - Translate return value
462 $message .= "\t<return>\n";
463 $message .= "\t\t<returnid>" . $ret . "</returnid>\n";
464 $message .= "\t\t<returntitle>" . xl($ret) . "</returntitle>\n";
465 $message .= "\t</return>\n";
467 array_push($returns, $ret);
471 if (isset($err)) {
472 foreach ($err as $value) {
473 $message .= "\t<error>" . $value . "</error>\n";
476 $message .= "</response>\n";
477 return $message;
481 // Returns error string(s) via xml
482 // $err = error (string or array)
484 function error_xml($err) {
485 $message = "<?xml version=\"1.0\"?>\n" .
486 "<response>\n";
487 if (is_array($err)){
488 foreach ($err as $value){
489 $message .= "\t<error>" . $value . "</error>\n";
492 else {
493 $message .= "\t<error>" . $err . "</error>\n";
495 $message .= "</response>\n";
496 return $message;