PageRenderTime 66ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/gacl/gacl_api.class.php

https://github.com/robytj/openemr
PHP | 3899 lines | 2601 code | 556 blank | 742 comment | 347 complexity | e1dabccf280b19c3ef6a3556d4b7d0cd MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * phpGACL - Generic Access Control List
  4. * Copyright (C) 2002,2003 Mike Benoit
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library 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 GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * For questions, help, comments, discussion, etc., please join the
  21. * phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103
  22. *
  23. * You may contact the author of phpGACL by e-mail at:
  24. * ipso@snappymail.ca
  25. *
  26. * The latest version of phpGACL can be obtained from:
  27. * http://phpgacl.sourceforge.net/
  28. *
  29. * @package phpGACL
  30. *
  31. */
  32. /*
  33. *
  34. * For examples, see example.php or the Administration interface,
  35. * as it makes use of nearly every API Call.
  36. *
  37. */
  38. /**
  39. * gacl_api Extended API Class
  40. *
  41. * Class gacl_api should be used for applications that must interface directly with
  42. * phpGACL's data structures, objects, and rules.
  43. *
  44. * @package phpGACL
  45. * @author Mike Benoit <ipso@snappymail.ca>
  46. *
  47. */
  48. class gacl_api extends gacl {
  49. /*
  50. *
  51. * Misc helper functions.
  52. *
  53. */
  54. /**
  55. * showarray()
  56. *
  57. * Dump all contents of an array in HTML (kinda)
  58. *
  59. * @param array
  60. *
  61. */
  62. function showarray($array) {
  63. echo "<br><pre>\n";
  64. var_dump($array);
  65. echo "</pre><br>\n";
  66. }
  67. /**
  68. * count_all()
  69. *
  70. * Recursively counts elements in an array and sub-arrays.
  71. *
  72. * This is different from count($arg, COUNT_RECURSIVE)
  73. * in PHP >= 4.2.0, which includes sub-arrays in the count.
  74. *
  75. * @return int The returned count is a count of all scalar elements found.
  76. *
  77. * @param array Array to count
  78. */
  79. function count_all($arg = NULL) {
  80. switch (TRUE) {
  81. case is_scalar($arg):
  82. case is_object($arg):
  83. // single object
  84. return 1;
  85. case is_array($arg):
  86. // call recursively for all elements of $arg
  87. $count = 0;
  88. foreach ($arg as $val) {
  89. $count += $this->count_all($val);
  90. }
  91. return $count;
  92. }
  93. return FALSE;
  94. }
  95. /**
  96. * get_version()
  97. *
  98. * Grabs phpGACL version from the database.
  99. *
  100. * @return string Version of phpGACL
  101. */
  102. function get_version() {
  103. $query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'version'";
  104. $version = $this->db->GetOne($query);
  105. return $version;
  106. }
  107. /**
  108. * get_schema_version()
  109. *
  110. * Grabs phpGACL schema version from the database.
  111. *
  112. * @return string Schema Version
  113. */
  114. function get_schema_version() {
  115. $query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'schema_version'";
  116. $version = $this->db->GetOne($query);
  117. return $version;
  118. }
  119. /*
  120. *
  121. * ACL
  122. *
  123. */
  124. /**
  125. * consolidated_edit_acl()
  126. *
  127. * Add's an ACL but checks to see if it can consolidate it with another one first.
  128. *
  129. * This ONLY works with ACO's and ARO's. Groups, and AXO are excluded.
  130. * As well this function is designed for handling ACLs with return values,
  131. * and consolidating on the return_value, in hopes of keeping the ACL count to a minimum.
  132. *
  133. * A return value of false must _always_ be handled outside this function.
  134. * As this function will remove AROs from ACLs and return false, in most cases
  135. * you will need to a create a completely new ACL on a false return.
  136. *
  137. * @return bool Special boolean return value. See note.
  138. *
  139. * @param string ACO Section Value
  140. * @param string ACO Value
  141. * @param string ARO Section Value
  142. * @param string ARO Value
  143. * @param string Return Value of ACL
  144. */
  145. function consolidated_edit_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, $return_value) {
  146. $this->debug_text("consolidated_edit_acl(): ACO Section Value: $aco_section_value ACO Value: $aco_value ARO Section Value: $aro_section_value ARO Value: $aro_value Return Value: $return_value");
  147. $acl_ids = array();
  148. if (empty($aco_section_value) ) {
  149. $this->debug_text("consolidated_edit_acl(): ACO Section Value ($aco_section_value) is empty, this is required!");
  150. return false;
  151. }
  152. if (empty($aco_value) ) {
  153. $this->debug_text("consolidated_edit_acl(): ACO Value ($aco_value) is empty, this is required!");
  154. return false;
  155. }
  156. if (empty($aro_section_value) ) {
  157. $this->debug_text("consolidated_edit_acl(): ARO Section Value ($aro_section_value) is empty, this is required!");
  158. return false;
  159. }
  160. if (empty($aro_value) ) {
  161. $this->debug_text("consolidated_edit_acl(): ARO Value ($aro_value) is empty, this is required!");
  162. return false;
  163. }
  164. if (empty($return_value) ) {
  165. $this->debug_text("consolidated_edit_acl(): Return Value ($return_value) is empty, this is required!");
  166. return false;
  167. }
  168. //See if a current ACL exists with the current objects, excluding return value
  169. $current_acl_ids = $this->search_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, FALSE, FALSE, FALSE, FALSE, FALSE);
  170. //showarray($current_acl_ids);
  171. if (is_array($current_acl_ids)) {
  172. $this->debug_text("add_consolidated_acl(): Found current ACL_IDs, counting ACOs");
  173. foreach ($current_acl_ids as $current_acl_id) {
  174. //Check to make sure these ACLs only have a single ACO mapped to them.
  175. $current_acl_array = &$this->get_acl($current_acl_id);
  176. //showarray($current_acl_array);
  177. $this->debug_text("add_consolidated_acl(): Current Count: ".$this->count_all($current_acl_array['aco'])."");
  178. if ( $this->count_all($current_acl_array['aco']) == 1) {
  179. $this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO.");
  180. //Test to see if the return values match, if they do, no need removing or appending ARO. Just return true.
  181. if ($current_acl_array['return_value'] == $return_value) {
  182. $this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO, and the same return value. No need to modify.");
  183. return true;
  184. }
  185. $acl_ids[] = $current_acl_id;
  186. }
  187. }
  188. }
  189. //showarray($acl_ids);
  190. $acl_ids_count = count($acl_ids);
  191. //If acl_id's turns up more then one ACL, lets remove the ARO from all of them in hopes to
  192. //eliminate any conflicts.
  193. if (is_array($acl_ids) AND $acl_ids_count > 0) {
  194. $this->debug_text("add_consolidated_acl(): Removing specified ARO from existing ACL.");
  195. foreach ($acl_ids as $acl_id) {
  196. //Remove ARO from current ACLs, so we don't create conflicting ACLs later on.
  197. if (!$this->shift_acl($acl_id, array($aro_section_value => array($aro_value)) ) ) {
  198. $this->debug_text("add_consolidated_acl(): Error removing specified ARO from ACL ID: $acl_id");
  199. return false;
  200. }
  201. }
  202. } else {
  203. $this->debug_text("add_consolidated_acl(): Didn't find any current ACLs with a single ACO. ");
  204. }
  205. //unset($acl_ids);
  206. $acl_ids = array();
  207. unset($acl_ids_count);
  208. //At this point there should be no conflicting ACLs, searching for an existing ACL with the new values.
  209. $new_acl_ids = $this->search_acl($aco_section_value, $aco_value, FALSE, FALSE, NULL, NULL, NULL, NULL, $return_value);
  210. $new_acl_count = count($new_acl_ids);
  211. //showarray($new_acl_ids);
  212. if (is_array($new_acl_ids)) {
  213. $this->debug_text("add_consolidated_acl(): Found new ACL_IDs, counting ACOs");
  214. foreach ($new_acl_ids as $new_acl_id) {
  215. //Check to make sure these ACLs only have a single ACO mapped to them.
  216. $new_acl_array = &$this->get_acl($new_acl_id);
  217. //showarray($new_acl_array);
  218. $this->debug_text("add_consolidated_acl(): New Count: ".$this->count_all($new_acl_array['aco'])."");
  219. if ( $this->count_all($new_acl_array['aco']) == 1) {
  220. $this->debug_text("add_consolidated_acl(): ACL ID: $new_acl_id has 1 ACO, append should be able to take place.");
  221. $acl_ids[] = $new_acl_id;
  222. }
  223. }
  224. }
  225. //showarray($acl_ids);
  226. $acl_ids_count = count($acl_ids);
  227. if (is_array($acl_ids) AND $acl_ids_count == 1) {
  228. $this->debug_text("add_consolidated_acl(): Appending specified ARO to existing ACL.");
  229. $acl_id=$acl_ids[0];
  230. if (!$this->append_acl($acl_id, array($aro_section_value => array($aro_value)) ) ) {
  231. $this->debug_text("add_consolidated_acl(): Error appending specified ARO to ACL ID: $acl_id");
  232. return false;
  233. }
  234. $this->debug_text("add_consolidated_acl(): Hot damn, ACL consolidated!");
  235. return true;
  236. } elseif($acl_ids_count > 1) {
  237. $this->debug_text("add_consolidated_acl(): Found more then one ACL with a single ACO. Possible conflicting ACLs.");
  238. return false;
  239. } elseif ($acl_ids_count == 0) {
  240. $this->debug_text("add_consolidated_acl(): No existing ACLs found, create a new one.");
  241. if (!$this->add_acl( array( $aco_section_value => array($aco_value) ),
  242. array( $aro_section_value => array($aro_value) ),
  243. NULL,
  244. NULL,
  245. NULL,
  246. TRUE,
  247. TRUE,
  248. $return_value,
  249. NULL)
  250. ) {
  251. $this->debug_text("add_consolidated_acl(): Error adding new ACL for ACO Section: $aco_section_value ACO Value: $aco_value Return Value: $return_value");
  252. return false;
  253. }
  254. $this->debug_text("add_consolidated_acl(): ADD_ACL() successfull, returning True.");
  255. return true;
  256. }
  257. $this->debug_text("add_consolidated_acl(): Returning false.");
  258. return false;
  259. }
  260. /**
  261. * search_acl()
  262. *
  263. * Searches for ACL's with specified objects mapped to them.
  264. *
  265. * NULL values are included in the search, if you want to ignore
  266. * for instance aro_groups use FALSE instead of NULL.
  267. *
  268. * @return array containing ACL IDs if search is successful
  269. *
  270. * @param string ACO Section Value
  271. * @param string ACO Value
  272. * @param string ARO Section Value
  273. * @param string ARO Value
  274. * @param string ARO Group Name
  275. * @param string AXO Section Value
  276. * @param string AXO Value
  277. * @param string AXO Group Name
  278. * @param string Return Value
  279. */
  280. function search_acl($aco_section_value=NULL, $aco_value=NULL, $aro_section_value=NULL, $aro_value=NULL, $aro_group_name=NULL, $axo_section_value=NULL, $axo_value=NULL, $axo_group_name=NULL, $return_value=NULL) {
  281. $this->debug_text("search_acl(): aco_section_value: $aco_section_value aco_value: $aco_value, aro_section_value: $aro_section_value, aro_value: $aro_value, aro_group_name: $aro_group_name, axo_section_value: $axo_section_value, axo_value: $axo_value, axo_group_name: $axo_group_name, return_value: $return_value");
  282. $query = '
  283. SELECT a.id
  284. FROM '. $this->_db_table_prefix .'acl a';
  285. $where_query = array();
  286. // ACO
  287. if ($aco_section_value !== FALSE AND $aco_value !== FALSE) {
  288. $query .= '
  289. LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON a.id=ac.acl_id';
  290. if ($aco_section_value == NULL AND $aco_value == NULL) {
  291. $where_query[] = '(ac.section_value IS NULL AND ac.value IS NULL)';
  292. } else {
  293. $where_query[] = '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value='. $this->db->quote($aco_value) .')';
  294. }
  295. }
  296. // ARO
  297. if ($aro_section_value !== FALSE AND $aro_value !== FALSE) {
  298. $query .= '
  299. LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON a.id=ar.acl_id';
  300. if ($aro_section_value == NULL AND $aro_value == NULL) {
  301. $where_query[] = '(ar.section_value IS NULL AND ar.value IS NULL)';
  302. } else {
  303. $where_query[] = '(ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value='. $this->db->quote($aro_value) .')';
  304. }
  305. }
  306. // AXO
  307. if ($axo_section_value !== FALSE AND $axo_value !== FALSE) {
  308. $query .= '
  309. LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON a.id=ax.acl_id';
  310. if ($axo_section_value == NULL AND $axo_value == NULL) {
  311. $where_query[] = '(ax.section_value IS NULL AND ax.value IS NULL)';
  312. } else {
  313. $where_query[] = '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value='. $this->db->quote($axo_value) .')';
  314. }
  315. }
  316. // ARO Group
  317. if ($aro_group_name !== FALSE) {
  318. $query .= '
  319. LEFT JOIN '. $this->_db_table_prefix .'aro_groups_map arg ON a.id=arg.acl_id
  320. LEFT JOIN '. $this->_db_table_prefix .'aro_groups rg ON arg.group_id=rg.id';
  321. if ($aro_group_name == NULL) {
  322. $where_query[] = '(rg.name IS NULL)';
  323. } else {
  324. $where_query[] = '(rg.name='. $this->db->quote($aro_group_name) .')';
  325. }
  326. }
  327. // AXO Group
  328. if ($axo_group_name !== FALSE) {
  329. $query .= '
  330. LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON a.id=axg.acl_id
  331. LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON axg.group_id=xg.id';
  332. if ($axo_group_name == NULL) {
  333. $where_query[] = '(xg.name IS NULL)';
  334. } else {
  335. $where_query[] = '(xg.name='. $this->db->quote($axo_group_name) .')';
  336. }
  337. }
  338. if ($return_value != FALSE) {
  339. if ($return_value == NULL) {
  340. $where_query[] = '(a.return_value IS NULL)';
  341. } else {
  342. $where_query[] = '(a.return_value='. $this->db->quote($return_value) .')';
  343. }
  344. }
  345. if (count($where_query) > 0) {
  346. $query .= '
  347. WHERE '. implode (' AND ', $where_query);
  348. }
  349. return $this->db->GetCol($query);
  350. }
  351. /**
  352. * append_acl()
  353. *
  354. * Appends objects on to a specific ACL.
  355. *
  356. * @return bool TRUE if successful, FALSE otherwise.
  357. *
  358. * @param int ACL ID #
  359. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  360. * @param array Array of Group IDs
  361. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  362. * @param array Array of Group IDs
  363. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  364. */
  365. function append_acl($acl_id, $aro_array=NULL, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $aco_array=NULL) {
  366. $this->debug_text("append_acl(): ACL_ID: $acl_id");
  367. $update = 0;
  368. if (empty($acl_id)) {
  369. $this->debug_text("append_acl(): No ACL_ID specified! ACL_ID: $acl_id");
  370. return false;
  371. }
  372. //Grab ACL data.
  373. $acl_array = &$this->get_acl($acl_id);
  374. //Append each object type seperately.
  375. if (is_array($aro_array) AND count($aro_array) > 0) {
  376. $this->debug_text("append_acl(): Appending ARO's");
  377. while (list($aro_section_value,$aro_value_array) = @each($aro_array)) {
  378. foreach ($aro_value_array as $aro_value) {
  379. if ( count($acl_array['aro'][$aro_section_value]) != 0 ) {
  380. if (!in_array($aro_value, $acl_array['aro'][$aro_section_value])) {
  381. $this->debug_text("append_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value");
  382. $acl_array['aro'][$aro_section_value][] = $aro_value;
  383. $update=1;
  384. } else {
  385. $this->debug_text("append_acl(): Duplicate ARO, ignoring... ");
  386. }
  387. } else { //Array is empty so add this aro value.
  388. $acl_array['aro'][$aro_section_value][] = $aro_value;
  389. $update = 1;
  390. }
  391. }
  392. }
  393. }
  394. if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) {
  395. $this->debug_text("append_acl(): Appending ARO_GROUP_ID's");
  396. while (list(,$aro_group_id) = @each($aro_group_ids)) {
  397. if (!is_array($acl_array['aro_groups']) OR !in_array($aro_group_id, $acl_array['aro_groups'])) {
  398. $this->debug_text("append_acl(): ARO Group ID: $aro_group_id");
  399. $acl_array['aro_groups'][] = $aro_group_id;
  400. $update = 1;
  401. } else {
  402. $this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
  403. }
  404. }
  405. }
  406. if (is_array($axo_array) AND count($axo_array) > 0) {
  407. $this->debug_text("append_acl(): Appending AXO's");
  408. while (list($axo_section_value,$axo_value_array) = @each($axo_array)) {
  409. foreach ($axo_value_array as $axo_value) {
  410. if (!in_array($axo_value, $acl_array['axo'][$axo_section_value])) {
  411. $this->debug_text("append_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value");
  412. $acl_array['axo'][$axo_section_value][] = $axo_value;
  413. $update = 1;
  414. } else {
  415. $this->debug_text("append_acl(): Duplicate AXO, ignoring... ");
  416. }
  417. }
  418. }
  419. }
  420. if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) {
  421. $this->debug_text("append_acl(): Appending AXO_GROUP_ID's");
  422. while (list(,$axo_group_id) = @each($axo_group_ids)) {
  423. if (!is_array($acl_array['axo_groups']) OR !in_array($axo_group_id, $acl_array['axo_groups'])) {
  424. $this->debug_text("append_acl(): AXO Group ID: $axo_group_id");
  425. $acl_array['axo_groups'][] = $axo_group_id;
  426. $update = 1;
  427. } else {
  428. $this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
  429. }
  430. }
  431. }
  432. if (is_array($aco_array) AND count($aco_array) > 0) {
  433. $this->debug_text("append_acl(): Appending ACO's");
  434. while (list($aco_section_value,$aco_value_array) = @each($aco_array)) {
  435. foreach ($aco_value_array as $aco_value) {
  436. if (!in_array($aco_value, $acl_array['aco'][$aco_section_value])) {
  437. $this->debug_text("append_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value");
  438. $acl_array['aco'][$aco_section_value][] = $aco_value;
  439. $update = 1;
  440. } else {
  441. $this->debug_text("append_acl(): Duplicate ACO, ignoring... ");
  442. }
  443. }
  444. }
  445. }
  446. if ($update == 1) {
  447. $this->debug_text("append_acl(): Update flag set, updating ACL.");
  448. //function edit_acl($acl_id, $aco_array, $aro_array, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $allow=1, $enabled=1, $return_value=NULL, $note=NULL) {
  449. return $this->edit_acl($acl_id, $acl_array['aco'], $acl_array['aro'], $acl_array['aro_groups'], $acl_array['axo'], $acl_array['axo_groups'], $acl_array['allow'], $acl_array['enabled'], $acl_array['return_value'], $acl_array['note']);
  450. }
  451. //Return true if everything is duplicate and no ACL id updated.
  452. $this->debug_text("append_acl(): Update flag not set, NOT updating ACL.");
  453. return true;
  454. }
  455. /**
  456. * shift_acl()
  457. *
  458. * Opposite of append_acl(). Removes objects from a specific ACL. (named after PHP's array_shift())
  459. *
  460. * @return bool TRUE if successful, FALSE otherwise.
  461. *
  462. * @param int ACL ID #
  463. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  464. * @param array Array of Group IDs
  465. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  466. * @param array Array of Group IDs
  467. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  468. */
  469. function shift_acl($acl_id, $aro_array=NULL, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $aco_array=NULL) {
  470. $this->debug_text("shift_acl(): ACL_ID: $acl_id");
  471. $update = 0;
  472. if (empty($acl_id)) {
  473. $this->debug_text("shift_acl(): No ACL_ID specified! ACL_ID: $acl_id");
  474. return false;
  475. }
  476. //Grab ACL data.
  477. $acl_array = &$this->get_acl($acl_id);
  478. //showarray($acl_array);
  479. //Remove each object type seperately.
  480. if (is_array($aro_array) AND count($aro_array) > 0) {
  481. $this->debug_text("shift_acl(): Removing ARO's");
  482. while (list($aro_section_value,$aro_value_array) = @each($aro_array)) {
  483. foreach ($aro_value_array as $aro_value) {
  484. $this->debug_text("shift_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value");
  485. //Only search if aro array contains data.
  486. if ( count($acl_array['aro'][$aro_section_value]) != 0 ) {
  487. $aro_key = array_search($aro_value, $acl_array['aro'][$aro_section_value]);
  488. if ($aro_key !== FALSE) {
  489. $this->debug_text("shift_acl(): Removing ARO. ($aro_key)");
  490. unset($acl_array['aro'][$aro_section_value][$aro_key]);
  491. $update = 1;
  492. } else {
  493. $this->debug_text("shift_acl(): ARO doesn't exist, can't remove it.");
  494. }
  495. }
  496. }
  497. }
  498. }
  499. if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) {
  500. $this->debug_text("shift_acl(): Removing ARO_GROUP_ID's");
  501. while (list(,$aro_group_id) = @each($aro_group_ids)) {
  502. $this->debug_text("shift_acl(): ARO Group ID: $aro_group_id");
  503. $aro_group_key = array_search($aro_group_id, $acl_array['aro_groups']);
  504. if ($aro_group_key !== FALSE) {
  505. $this->debug_text("shift_acl(): Removing ARO Group. ($aro_group_key)");
  506. unset($acl_array['aro_groups'][$aro_group_key]);
  507. $update = 1;
  508. } else {
  509. $this->debug_text("shift_acl(): ARO Group doesn't exist, can't remove it.");
  510. }
  511. }
  512. }
  513. if (is_array($axo_array) AND count($axo_array) > 0) {
  514. $this->debug_text("shift_acl(): Removing AXO's");
  515. while (list($axo_section_value,$axo_value_array) = @each($axo_array)) {
  516. foreach ($axo_value_array as $axo_value) {
  517. $this->debug_text("shift_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value");
  518. $axo_key = array_search($axo_value, $acl_array['axo'][$axo_section_value]);
  519. if ($axo_key !== FALSE) {
  520. $this->debug_text("shift_acl(): Removing AXO. ($axo_key)");
  521. unset($acl_array['axo'][$axo_section_value][$axo_key]);
  522. $update = 1;
  523. } else {
  524. $this->debug_text("shift_acl(): AXO doesn't exist, can't remove it.");
  525. }
  526. }
  527. }
  528. }
  529. if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) {
  530. $this->debug_text("shift_acl(): Removing AXO_GROUP_ID's");
  531. while (list(,$axo_group_id) = @each($axo_group_ids)) {
  532. $this->debug_text("shift_acl(): AXO Group ID: $axo_group_id");
  533. $axo_group_key = array_search($axo_group_id, $acl_array['axo_groups']);
  534. if ($axo_group_key !== FALSE) {
  535. $this->debug_text("shift_acl(): Removing AXO Group. ($axo_group_key)");
  536. unset($acl_array['axo_groups'][$axo_group_key]);
  537. $update = 1;
  538. } else {
  539. $this->debug_text("shift_acl(): AXO Group doesn't exist, can't remove it.");
  540. }
  541. }
  542. }
  543. if (is_array($aco_array) AND count($aco_array) > 0) {
  544. $this->debug_text("shift_acl(): Removing ACO's");
  545. while (list($aco_section_value,$aco_value_array) = @each($aco_array)) {
  546. foreach ($aco_value_array as $aco_value) {
  547. $this->debug_text("shift_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value");
  548. $aco_key = array_search($aco_value, $acl_array['aco'][$aco_section_value]);
  549. if ($aco_key !== FALSE) {
  550. $this->debug_text("shift_acl(): Removing ACO. ($aco_key)");
  551. unset($acl_array['aco'][$aco_section_value][$aco_key]);
  552. $update = 1;
  553. } else {
  554. $this->debug_text("shift_acl(): ACO doesn't exist, can't remove it.");
  555. }
  556. }
  557. }
  558. }
  559. if ($update == 1) {
  560. //We know something was changed, so lets see if no ACO's or no ARO's are left assigned to this ACL, if so, delete the ACL completely.
  561. //$this->showarray($acl_array);
  562. $this->debug_text("shift_acl(): ACOs: ". $this->count_all($acl_array['aco']) ." AROs: ".$this->count_all($acl_array['aro'])."");
  563. if ( $this->count_all($acl_array['aco']) == 0
  564. OR ( $this->count_all($acl_array['aro']) == 0
  565. AND ( $this->count_all($acl_array['axo']) == 0 OR $acl_array['axo'] == FALSE)
  566. AND (count($acl_array['aro_groups']) == 0 OR $acl_array['aro_groups'] == FALSE)
  567. AND (count($acl_array['axo_groups']) == 0 OR $acl_array['axo_groups'] == FALSE)
  568. ) ) {
  569. $this->debug_text("shift_acl(): No ACOs or ( AROs AND AXOs AND ARO Groups AND AXO Groups) left assigned to this ACL (ID: $acl_id), deleting ACL.");
  570. return $this->del_acl($acl_id);
  571. }
  572. $this->debug_text("shift_acl(): Update flag set, updating ACL.");
  573. return $this->edit_acl($acl_id, $acl_array['aco'], $acl_array['aro'], $acl_array['aro_groups'], $acl_array['axo'], $acl_array['axo_groups'], $acl_array['allow'], $acl_array['enabled'], $acl_array['return_value'], $acl_array['note']);
  574. }
  575. //Return true if everything is duplicate and no ACL id updated.
  576. $this->debug_text("shift_acl(): Update flag not set, NOT updating ACL.");
  577. return true;
  578. }
  579. /**
  580. * get_acl()
  581. *
  582. * Grabs ACL data.
  583. *
  584. * @return bool FALSE if not found, or Associative Array with the following items:
  585. *
  586. * - 'aco' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  587. * - 'aro' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  588. * - 'axo' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  589. * - 'aro_groups' => Array of Group IDs
  590. * - 'axo_groups' => Array of Group IDs
  591. * - 'acl_id' => int ACL ID #
  592. * - 'allow' => int Allow flag
  593. * - 'enabled' => int Enabled flag
  594. * - 'return_value' => string Return Value
  595. * - 'note' => string Note
  596. *
  597. * @param int ACL ID #
  598. */
  599. function get_acl($acl_id) {
  600. $this->debug_text("get_acl(): ACL_ID: $acl_id");
  601. if (empty($acl_id)) {
  602. $this->debug_text("get_acl(): No ACL_ID specified! ACL_ID: $acl_id");
  603. return false;
  604. }
  605. //Grab ACL information
  606. $query = "select id, allow, enabled, return_value, note from ".$this->_db_table_prefix."acl where id = ".$acl_id."";
  607. $acl_row = $this->db->GetRow($query);
  608. // return false if not found
  609. if (!$acl_row) {
  610. $this->debug_text("get_acl(): No ACL found for that ID! ACL_ID: $acl_id");
  611. return false;
  612. }
  613. list($retarr['acl_id'], $retarr['allow'], $retarr['enabled'], $retarr['return_value'], $retarr['note']) = $acl_row;
  614. //Grab selected ACO's
  615. $query = "select distinct a.section_value, a.value, c.name, b.name from ".$this->_db_table_prefix."aco_map a, ".$this->_db_table_prefix."aco b, ".$this->_db_table_prefix."aco_sections c
  616. where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
  617. $rs = $this->db->Execute($query);
  618. $rows = $rs->GetRows();
  619. $retarr['aco'] = array();
  620. while (list(,$row) = @each($rows)) {
  621. list($section_value, $value, $section, $aco) = $row;
  622. $this->debug_text("Section Value: $section_value Value: $value Section: $section ACO: $aco");
  623. $retarr['aco'][$section_value][] = $value;
  624. }
  625. //showarray($aco);
  626. //Grab selected ARO's
  627. $query = "select distinct a.section_value, a.value, c.name, b.name from ".$this->_db_table_prefix."aro_map a, ".$this->_db_table_prefix."aro b, ".$this->_db_table_prefix."aro_sections c
  628. where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
  629. $rs = $this->db->Execute($query);
  630. $rows = $rs->GetRows();
  631. $retarr['aro'] = array();
  632. while (list(,$row) = @each($rows)) {
  633. list($section_value, $value, $section, $aro) = $row;
  634. $this->debug_text("Section Value: $section_value Value: $value Section: $section ARO: $aro");
  635. $retarr['aro'][$section_value][] = $value;
  636. }
  637. //showarray($options_aro);
  638. //Grab selected AXO's
  639. $query = "select distinct a.section_value, a.value, c.name, b.name from ".$this->_db_table_prefix."axo_map a, ".$this->_db_table_prefix."axo b, ".$this->_db_table_prefix."axo_sections c
  640. where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
  641. $rs = $this->db->Execute($query);
  642. $rows = $rs->GetRows();
  643. $retarr['axo'] = array();
  644. while (list(,$row) = @each($rows)) {
  645. list($section_value, $value, $section, $axo) = $row;
  646. $this->debug_text("Section Value: $section_value Value: $value Section: $section AXO: $axo");
  647. $retarr['axo'][$section_value][] = $value;
  648. }
  649. //showarray($options_aro);
  650. //Grab selected ARO groups.
  651. $retarr['aro_groups'] = array();
  652. $query = "select distinct group_id from ".$this->_db_table_prefix."aro_groups_map where acl_id = $acl_id";
  653. $retarr['aro_groups'] = $this->db->GetCol($query);
  654. //showarray($selected_groups);
  655. //Grab selected AXO groups.
  656. $retarr['axo_groups'] = array();
  657. $query = "select distinct group_id from ".$this->_db_table_prefix."axo_groups_map where acl_id = $acl_id";
  658. $retarr['axo_groups'] = $this->db->GetCol($query);
  659. //showarray($selected_groups);
  660. return $retarr;
  661. }
  662. /**
  663. * is_conflicting_acl()
  664. *
  665. * Checks for conflicts when adding a specific ACL.
  666. *
  667. * @return bool Returns true if conflict is found.
  668. *
  669. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  670. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  671. * @param array Array of Group IDs
  672. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  673. * @param array Array of Group IDs
  674. * @param array Array of ACL IDs to ignore from the result set.
  675. *
  676. */
  677. function is_conflicting_acl($aco_array, $aro_array, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $ignore_acl_ids=NULL) {
  678. //Check for potential conflicts. Ignore groups, as groups will almost always have "conflicting" ACLs.
  679. //Thats part of inheritance.
  680. if (!is_array($aco_array)) {
  681. $this->debug_text('is_conflicting_acl(): Invalid ACO Array.');
  682. return FALSE;
  683. }
  684. if (!is_array($aro_array)) {
  685. $this->debug_text('is_conflicting_acl(): Invalid ARO Array.');
  686. return FALSE;
  687. }
  688. $query = '
  689. SELECT a.id
  690. FROM '. $this->_db_table_prefix .'acl a
  691. LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON ac.acl_id=a.id
  692. LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON ar.acl_id=a.id
  693. LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON ax.acl_id=a.id
  694. LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON axg.acl_id=a.id
  695. LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON xg.id=axg.group_id
  696. ';
  697. //ACO
  698. foreach ($aco_array as $aco_section_value => $aco_value_array) {
  699. $this->debug_text("is_conflicting_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value_array");
  700. //showarray($aco_array);
  701. if (!is_array($aco_value_array)) {
  702. $this->debug_text('is_conflicting_acl(): Invalid Format for ACO Array item. Skipping...');
  703. continue;
  704. // return TRUE;
  705. }
  706. //Move the below line in to the LEFT JOIN above for PostgreSQL sake.
  707. //'ac1' => 'ac.acl_id=a.id',
  708. $where_query = array(
  709. 'ac2' => '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value IN (\''. implode ('\',\'', $aco_value_array) .'\'))'
  710. );
  711. //ARO
  712. foreach ($aro_array as $aro_section_value => $aro_value_array) {
  713. $this->debug_text("is_conflicting_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value_array");
  714. if (!is_array($aro_value_array))
  715. {
  716. $this->debug_text('is_conflicting_acl(): Invalid Format for ARO Array item. Skipping...');
  717. continue;
  718. // return TRUE;
  719. }
  720. $this->debug_text("is_conflicting_acl(): Search: ACO Section: $aco_section_value ACO Value: $aco_value_array ARO Section: $aro_section_value ARO Value: $aro_value_array");
  721. //Move the below line in to the LEFT JOIN above for PostgreSQL sake.
  722. //$where_query['ar1'] = 'ar.acl_id=a.id';
  723. $where_query['ar2'] = '(ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value IN (\''. implode ('\',\'', $aro_value_array) .'\'))';
  724. if (is_array($axo_array) AND count($axo_array) > 0) {
  725. foreach ($axo_array as $axo_section_value => $axo_value_array) {
  726. $this->debug_text("is_conflicting_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value_array");
  727. if (!is_array($axo_value_array)) {
  728. $this->debug_text('is_conflicting_acl(): Invalid Format for AXO Array item. Skipping...');
  729. continue;
  730. // return TRUE;
  731. }
  732. $this->debug_text("is_conflicting_acl(): Search: ACO Section: $aco_section_value ACO Value: $aco_value_array ARO Section: $aro_section_value ARO Value: $aro_value_array AXO Section: $axo_section_value AXO Value: $axo_value_array");
  733. //$where_query['ax1'] = 'ax.acl_id=x.id';
  734. $where_query['ax1'] = 'ax.acl_id=a.id';
  735. $where_query['ax2'] = '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value IN (\''. implode ('\',\'', $axo_value_array) .'\'))';
  736. $where = 'WHERE ' . implode(' AND ', $where_query);
  737. $conflict_result = $this->db->GetCol($query . $where);
  738. if (is_array($conflict_result) AND !empty($conflict_result)) {
  739. // showarray($conflict_result);
  740. if (is_array($ignore_acl_ids)) {
  741. $conflict_result = array_diff($conflict_result, $ignore_acl_ids);
  742. }
  743. if (count($conflict_result) > 0) {
  744. $conflicting_acls_str = implode(',', $conflict_result);
  745. $this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)");
  746. return TRUE;
  747. }
  748. }
  749. }
  750. } else {
  751. $where_query['ax1'] = '(ax.section_value IS NULL AND ax.value IS NULL)';
  752. $where_query['ax2'] = 'xg.name IS NULL';
  753. $where = 'WHERE ' . implode(' AND ', $where_query);
  754. $conflict_result = $this->db->GetCol($query . $where);
  755. if (is_array($conflict_result) AND !empty($conflict_result)) {
  756. // showarray($conflict_result);
  757. if (is_array($ignore_acl_ids)) {
  758. $conflict_result = array_diff($conflict_result, $ignore_acl_ids);
  759. }
  760. if (count($conflict_result) > 0) {
  761. $conflicting_acls_str = implode(',', $conflict_result);
  762. $this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)");
  763. return TRUE;
  764. }
  765. }
  766. }
  767. }
  768. }
  769. $this->debug_text('is_conflicting_acl(): No conflicting ACL found.');
  770. return FALSE;
  771. }
  772. /**
  773. * add_acl()
  774. *
  775. * Add's an ACL. ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
  776. *
  777. * @return bool Return ACL ID of new ACL if successful, FALSE otherewise.
  778. *
  779. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  780. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  781. * @param array Array of Group IDs
  782. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  783. * @param array Array of Group IDs
  784. * @param int Allow flag
  785. * @param int Enabled flag
  786. * @param string Return Value
  787. * @param string Note
  788. * @param string ACL Section Value
  789. * @param int ACL ID # Specific Request
  790. */
  791. function add_acl($aco_array, $aro_array, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $allow=1, $enabled=1, $return_value=NULL, $note=NULL, $section_value=NULL, $acl_id=FALSE ) {
  792. $this->debug_text("add_acl():");
  793. if (count($aco_array) == 0) {
  794. $this->debug_text("Must select at least one Access Control Object");
  795. return false;
  796. }
  797. if (count($aro_array) == 0 AND count($aro_group_ids) == 0) {
  798. $this->debug_text("Must select at least one Access Request Object or Group");
  799. return false;
  800. }
  801. if (empty($allow)) {
  802. $allow=0;
  803. }
  804. if (empty($enabled)) {
  805. $enabled=0;
  806. }
  807. if (!empty($section_value)
  808. AND !$this->get_object_section_section_id(NULL, $section_value, 'ACL')) {
  809. $this->debug_text("add_acl(): Section Value: $section_value DOES NOT exist in the database.");
  810. return false;
  811. }
  812. //Unique the group arrays. Later one we unique ACO/ARO/AXO arrays.
  813. if (is_array($aro_group_ids)) {
  814. $aro_group_ids = array_unique($aro_group_ids);
  815. }
  816. if (is_array($axo_group_ids)) {
  817. $axo_group_ids = array_unique($axo_group_ids);
  818. }
  819. //Check for conflicting ACLs.
  820. if ($this->is_conflicting_acl($aco_array,$aro_array,$aro_group_ids,$axo_array,$axo_group_ids,array($acl_id))) {
  821. $this->debug_text("add_acl(): Detected possible ACL conflict, not adding ACL!");
  822. return false;
  823. }
  824. //Edit ACL if acl_id is set. This is simply if we're being called by edit_acl().
  825. if ($this->get_acl($acl_id) == FALSE) {
  826. if ( empty($section_value) ) {
  827. $section_value='system';
  828. if( !$this->get_object_section_section_id(NULL, $section_value, 'ACL') ) {
  829. // Use the acl section with the lowest order value.
  830. $acl_sections_table = $this->_db_table_prefix .'acl_sections';
  831. $acl_section_order_value = $this->db->GetOne("SELECT min(order_value) from $acl_sections_table");
  832. $query = "
  833. SELECT value
  834. FROM $acl_sections_table
  835. WHERE order_value = $acl_section_order_value
  836. ";
  837. $section_value = $this->db->GetOne($query);
  838. if ( empty($section_value) ) {
  839. $this->debug_text("add_acl(): No valid acl section found.");
  840. return false;
  841. } else {
  842. $this->debug_text("add_acl(): Using default section value: $section_value.");
  843. }
  844. }
  845. }
  846. //ACL not specified, so create acl_id
  847. if (empty($acl_id)) {
  848. //Create ACL row first, so we have the acl_id
  849. $acl_id = $this->db->GenID($this->_db_table_prefix.'acl_seq',10);
  850. //Double check the ACL ID was generated.
  851. if (empty($acl_id)) {
  852. $this->debug_text("add_acl(): ACL_ID generation failed!");
  853. return false;
  854. }
  855. }
  856. //Begin transaction _after_ GenID. Because on the first run, if GenID has to create the sequence,
  857. //the transaction will fail.
  858. $this->db->BeginTrans();
  859. $query = 'INSERT INTO '.$this->_db_table_prefix.'acl (id,section_value,allow,enabled,return_value,note,updated_date) VALUES('. $acl_id .','. $this->db->quote($section_value) .','. $allow .','. $enabled .','. $this->db->quote($return_value) .', '. $this->db->quote($note) .','. time() .')';
  860. $result = $this->db->Execute($query);
  861. } else {
  862. $section_sql = '';
  863. if ( !empty($section_value) ) {
  864. $section_sql = 'section_value='. $this->db->quote ($section_value) .',';
  865. }
  866. $this->db->BeginTrans();
  867. //Update ACL row, and remove all mappings so they can be re-inserted.
  868. $query = '
  869. UPDATE '. $this->_db_table_prefix .'acl
  870. SET ' . $section_sql . '
  871. allow='. $allow .',
  872. enabled='. $enabled .',
  873. return_value='. $this->db->quote($return_value) .',
  874. note='. $this->db->quote($note) .',
  875. updated_date='. time() .'
  876. WHERE id='. $acl_id;
  877. $result = $this->db->Execute($query);
  878. if ($result) {
  879. $this->debug_text("Update completed without error, delete mappings...");
  880. //Delete all mappings so they can be re-inserted.
  881. foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) {
  882. $query = 'DELETE FROM '. $this->_db_table_prefix . $map .' WHERE acl_id='. $acl_id;
  883. $rs = $this->db->Execute($query);
  884. if (!is_object($rs))
  885. {
  886. $this->debug_db('add_acl');
  887. $this->db->RollBackTrans();
  888. return FALSE;
  889. }
  890. }
  891. }
  892. }
  893. if (!is_object($result)) {
  894. $this->debug_db('add_acl');
  895. $this->db->RollBackTrans();
  896. return false;
  897. }
  898. $this->debug_text("Insert or Update completed without error, insert new mappings.");
  899. // Insert ACO/ARO/AXO mappings
  900. foreach (array('aco', 'aro', 'axo') as $map) {
  901. $map_array = ${$map .'_array'};
  902. if (!is_array ($map_array)) {
  903. continue;
  904. }
  905. foreach ($map_array as $section_value => $value_array) {
  906. $this->debug_text ('Insert: '. strtoupper($map) .' Section Value: '. $section_value .' '. strtoupper($map) .' VALUE: '. $value_array);
  907. // $this->showarray ($aco_value_array);
  908. if (!is_array($value_array)) {
  909. $this->debug_text ('add_acl (): Invalid Format for '. strtoupper ($map) .' Array item. Skipping...');
  910. continue;
  911. // return true;
  912. }
  913. $value_array = array_unique($value_array);
  914. foreach ($value_array as $value) {
  915. $object_id = &$this->get_object_id($section_value, $value, $map);
  916. if (empty($object_id))
  917. {
  918. $this->debug_text('add_acl(): '. strtoupper($map) . " Object Section Value: $section_value Value: $value DOES NOT exist in the database. Skipping...");
  919. $this->db->RollBackTrans();
  920. return false;
  921. }
  922. $query = 'INSERT INTO '. $this->_db_table_prefix . $map .'_map (acl_id,section_value,value) VALUES ('. $acl_id .', '. $this->db->quote($section_value) .', '. $this->db->quote($value) .')';
  923. $rs = $this->db->Execute($query);
  924. if (!is_object($rs))
  925. {
  926. $this->debug_db('add_acl');
  927. $this->db->RollBackTrans();
  928. return false;
  929. }
  930. }
  931. }
  932. }
  933. // Insert ARO/AXO GROUP mappings
  934. foreach (array('aro', 'axo') as $map) {
  935. $map_group_ids = ${$map .'_group_ids'};
  936. if (!is_array($map_group_ids)) {
  937. continue;
  938. }
  939. foreach ($map_group_ids as $group_id) {
  940. $this->debug_text ('Insert: '. strtoupper($map) .' GROUP ID: '. $group_id);
  941. $group_data = &$this->get_group_data($group_id, $map);
  942. if (empty($group_data)) {
  943. $this->debug_text('add_acl(): '. strtoupper($map) . " Group: $group_id DOES NOT exist in the database. Skipping...");
  944. $this->db->RollBackTrans();
  945. return false;
  946. }
  947. $query = 'INSERT INTO '. $this->_db_table_prefix . $map .'_groups_map (acl_id,group_id) VALUES ('. $acl_id .', '. $group_id .')';
  948. $rs = $this->db->Execute($query);
  949. if (!is_object($rs)) {
  950. $this->debug_db('add_acl');
  951. $this->db->RollBackTrans();
  952. return false;
  953. }
  954. }
  955. }
  956. $this->db->CommitTrans();
  957. if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
  958. //Expire all cache.
  959. $this->Cache_Lite->clean('default');
  960. }
  961. //Return only the ID in the first row.
  962. return $acl_id;
  963. }
  964. /**
  965. * edit_acl()
  966. *
  967. * Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
  968. *
  969. * @return bool Return TRUE if successful, FALSE otherewise.
  970. *
  971. * @param int ACL ID # to edit
  972. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  973. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  974. * @param array Array of Group IDs
  975. * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
  976. * @param array Array of Group IDs
  977. * @param int Allow flag
  978. * @param int Enabled flag
  979. * @param string Return Value
  980. * @param string Note
  981. * @param string ACL Section Value
  982. */
  983. function edit_acl($acl_id, $aco_array, $aro_array, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $allow=1, $enabled=1, $return_value=NULL, $note=NULL, $section_value=NULL) {
  984. $this->debug_text("edit_acl():");
  985. if (empty($acl_id) ) {
  986. $this->debug_text("edit_acl(): Must specify a single ACL_ID to edit");
  987. return false;
  988. }
  989. if (count($aco_array) == 0) {
  990. $this->debug_text("edit_acl(): Must select at least one Access Control Object");
  991. return false;
  992. }
  993. if (count($aro_array) == 0 AND count($aro_group_ids) == 0) {
  994. $this->debug_text("edit_acl(): Must select at least one Access Request Object or Group");
  995. return false;
  996. }
  997. if (empty($allow)) {
  998. $allow=0;
  999. }
  1000. if (empty($enabled)) {
  1001. $enabled=0;
  1002. }
  1003. //if ($this->add_acl($aco_array, $aro_array, $group_ids, $allow, $enabled, $acl_id)) {
  1004. if ($this->add_acl($aco_array, $aro_array, $aro_group_ids, $axo_array, $axo_group_ids, $allow, $enabled, $return_value, $note, $section_value, $acl_id)) {
  1005. return true;
  1006. } else {
  1007. $this->debug_text("edit_acl(): error in add_acl()");
  1008. return false;
  1009. }
  1010. }
  1011. /**
  1012. * del_acl()
  1013. *
  1014. * Deletes a given ACL
  1015. *
  1016. * @return bool Returns TRUE if successful, FALSE otherwise.
  1017. *
  1018. * @param int ACL ID # to delete
  1019. */
  1020. function del_acl($acl_id) {
  1021. $this->debug_text("del_acl(): ID: $acl_id");
  1022. if (empty($acl_id) ) {
  1023. $this->debug_text("del_acl(): ACL_ID ($acl_id) is empty, this is required");
  1024. return false;
  1025. }
  1026. $this->db->BeginTrans();
  1027. // Delete all mappings to the ACL first
  1028. foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) {
  1029. $query = 'DELETE FROM '. $this->_db_table_prefix . $map .' WHERE acl_id='. $acl_id;
  1030. $rs = $this->db->Execute($query);
  1031. if (!is_object($rs)) {
  1032. $this->debug_db('del_acl');
  1033. $this->db->RollBackTrans();
  1034. return false;
  1035. }
  1036. }
  1037. // Delete the ACL
  1038. $query = 'DELETE FROM '. $this->_db_table_prefix .'acl WHERE id='. $acl_id;
  1039. $this->debug_text('delete query: '. $query);
  1040. $rs = $this->db->Execute($query);
  1041. if (!is_object($rs)) {
  1042. $this->debug_db('del_acl');
  1043. $this->db->RollBackTrans();
  1044. return false;
  1045. }
  1046. $this->debug_text("del_acl(): deleted ACL ID: $acl_id");
  1047. $this->db->CommitTrans();
  1048. if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
  1049. //Expire all cache.
  1050. $this->Cache_Lite->clean('default');
  1051. }
  1052. return TRUE;
  1053. }
  1054. /*
  1055. *
  1056. * Groups
  1057. *
  1058. */
  1059. /**
  1060. * sort_groups()
  1061. *
  1062. * Grabs all the groups from the database doing preliminary grouping by parent
  1063. *
  1064. * @return array Returns 2-Dimensional array: $array[<parent_id>][<group_id>] = <group_name>
  1065. *
  1066. * @param string Group Type, either 'ARO' or 'AXO'
  1067. */
  1068. function sort_groups($group_type='ARO') {
  1069. switch(strtolower(trim($group_type))) {
  1070. case 'axo':
  1071. $table = $this->_db_table_prefix .'axo_groups';
  1072. break;
  1073. default:
  1074. $table = $this->_db_table_prefix .'aro_groups';
  1075. break;
  1076. }
  1077. //Grab all groups from the database.
  1078. $query = 'SELECT id, parent_id, name FROM '. $table .' ORDER BY parent_id, name';
  1079. $rs = $this->db->Execute($query);
  1080. if (!is_object($rs)) {
  1081. $this->debug_db('sort_groups');
  1082. return false;
  1083. }
  1084. /*
  1085. * Save groups in an array sorted by parent. Should be make it easier for later on.
  1086. */
  1087. $sorted_groups = array();
  1088. while ($row = $rs->FetchRow()) {
  1089. $id = &$row[0];
  1090. $parent_id = &$row[1];
  1091. $name = &$row[2];
  1092. $sorted_groups[$parent_id][$id] = $name;
  1093. }
  1094. return $sorted_groups;
  1095. }
  1096. /**
  1097. * format_groups()
  1098. *
  1099. * Takes the array returned by sort_groups() and formats for human
  1100. * consumption. Recursively calls itself to produce the desired output.
  1101. *
  1102. * @return array Array of formatted text, ordered by group id, formatted according to $type
  1103. *
  1104. * @param array Output from gacl_api->sorted_groups($group_type)
  1105. * @param array Output type desired, either 'TEXT', 'HTML', or 'ARRAY'
  1106. * @param int Root of tree to produce
  1107. * @param int Current level of depth
  1108. * @param array Pass the current formatted groups object for appending via recursion.
  1109. */
  1110. function format_groups($sorted_groups, $type='TEXT', $root_id=0, $level=0, $formatted_groups=NULL) {
  1111. if ( !is_array ($sorted_groups) ) {
  1112. return FALSE;
  1113. }
  1114. if ( !is_array ($formatted_groups) ) {
  1115. $formatted_groups = array ();
  1116. }
  1117. //$this->showarray($formatted_groups);
  1118. //while (list($id,$name) = @each($sorted_groups[$root_id])) {
  1119. if (isset($sorted_groups[$root_id])) {
  1120. //$last_id = end( array_keys($sorted_groups[$root_id]));
  1121. //PHP5 compatibility
  1122. $keys = array_keys($sorted_groups[$root_id]);
  1123. $last_id = end($keys);
  1124. unset($keys);
  1125. foreach ($sorted_groups[$root_id] as $id => $name) {
  1126. switch (strtoupper($type)) {
  1127. case 'TEXT':
  1128. /*
  1129. * Formatting optimized for TEXT (combo box) output.
  1130. */
  1131. if ( is_numeric($level) ) {
  1132. $level = str_repeat('&nbsp;&nbsp; ', $level);
  1133. }
  1134. if ( strlen($level) >= 8 ) {
  1135. if ( $id == $last_id ) {
  1136. $spacing = substr($level, 0, -8) .'\'- ';
  1137. $level = substr($level, 0, -8) .'&nbsp;&nbsp; ';
  1138. } else {
  1139. $spacing = substr($level, 0, -8) .'|- ';
  1140. }
  1141. } else {
  1142. $spacing = $level;
  1143. }
  1144. $next = $level .'|&nbsp; ';
  1145. $text = $spacing.$name;
  1146. break;
  1147. case 'HTML':
  1148. /*
  1149. * Formatting optimized for HTML (tables) output.
  1150. */
  1151. $width= $level * 20;
  1152. $spacing = "<img src=\"s.gif\" width=\"$width\">";
  1153. $next = $level + 1;
  1154. $text = $spacing." ".$name;
  1155. break;
  1156. case 'ARRAY':
  1157. $next = $level;
  1158. $text = $name;
  1159. break;
  1160. default:
  1161. return FALSE;
  1162. }
  1163. $formatted_groups[$id] = $text;
  1164. /*
  1165. * Recurse if we can.
  1166. */
  1167. //if (isset($sorted_groups[$id]) AND count($sorted_groups[$id]) > 0) {
  1168. if (isset($sorted_groups[$id]) ) {
  1169. //$this->debug_text("format_groups(): Recursing! Level: $level");
  1170. $formatted_groups = $this->format_groups($sorted_groups, $type, $id, $next, $formatted_groups);
  1171. } else {
  1172. //$this->debug_text("format_groups(): Found last branch!");
  1173. }
  1174. }
  1175. }
  1176. //$this->debug_text("format_groups(): Returning final array.");
  1177. return $formatted_groups;
  1178. }
  1179. /**
  1180. * get_group_id()
  1181. *
  1182. * Gets the group_id given the name or value.
  1183. *
  1184. * Will only return one group id, so if there are duplicate names, it will return false.
  1185. *
  1186. * @return int Returns Group ID if found and Group ID is unique in database, otherwise, returns FALSE
  1187. *
  1188. * @param string Group Value
  1189. * @param string Group Name
  1190. * @param string Group Type, either 'ARO' or 'AXO'
  1191. */
  1192. function get_group_id($value = NULL, $name = NULL, $group_type = 'ARO') {
  1193. $this->debug_text("get_group_id(): Value: $value, Name: $name, Type: $group_type" );
  1194. switch(strtolower(trim($group_type))) {
  1195. case 'axo':
  1196. $table = $this->_db_table_prefix .'axo_groups';
  1197. break;
  1198. default:
  1199. $table = $this->_db_table_prefix .'aro_groups';
  1200. break;
  1201. }
  1202. $name = trim($name);
  1203. $value = trim($value);
  1204. if (empty($name) AND empty($value) ) {
  1205. $this->debug_text("get_group_id(): name and value, at least one is required");
  1206. return false;
  1207. }
  1208. $query = 'SELECT id FROM '. $table .' WHE…

Large files files are truncated, but you can click here to view the full file