Source code for file /phpgacl/gacl_api.php
Documentation is available at gacl_api.php
* phpGACL - Generic Access Control List
* Copyright (C) 2002,2003 Mike Benoit
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For questions, help, comments, discussion, etc., please join the
* phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103
* You may contact the author of phpGACL by e-mail at:
* The latest version of phpGACL can be obtained from:
* http://phpgacl.sourceforge.net/
// Check to ensure this file is within the rest of the framework
* For examples, see example.php or the Administration interface,
* as it makes use of nearly every API Call.
* gacl_api Extended API Class
* Class gacl_api should be used for applications that must interface directly with
* phpGACL's data structures, objects, and rules.
* Dump all contents of an array in HTML (kinda)
* Recursively counts elements in an array and sub-arrays.
* This is different from count($arg, COUNT_RECURSIVE)
* in PHP >= 4.2.0, which includes sub-arrays in the count.
* @return int The returned count is a count of all scalar elements found.
* @param array Array to count
// call recursively for all elements of $arg
* Grabs phpGACL version from the database.
* @return string Version of phpGACL
$query =
"select value from ".
$this->_db_table_prefix.
"phpgacl where name = 'version'";
$version =
$this->db->GetOne($query);
* Grabs phpGACL schema version from the database.
* @return string Schema Version
$query =
"select value from ".
$this->_db_table_prefix.
"phpgacl where name = 'schema_version'";
$version =
$this->db->GetOne($query);
* consolidated_edit_acl()
* Add's an ACL but checks to see if it can consolidate it with another one first.
* This ONLY works with ACO's and ARO's. Groups, and AXO are excluded.
* As well this function is designed for handling ACLs with return values,
* and consolidating on the return_value, in hopes of keeping the ACL count to a minimum.
* A return value of false must _always_ be handled outside this function.
* As this function will remove AROs from ACLs and return false, in most cases
* you will need to a create a completely new ACL on a false return.
* @return bool Special boolean return value. See note.
* @param string ACO Section Value
* @param string ACO Value
* @param string ARO Section Value
* @param string ARO Value
* @param string Return Value of ACL
function consolidated_edit_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, $return_value) {
$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");
if (empty($aco_section_value) ) {
$this->debug_text("consolidated_edit_acl(): ACO Section Value ($aco_section_value) is empty, this is required!");
if (empty($aco_value) ) {
$this->debug_text("consolidated_edit_acl(): ACO Value ($aco_value) is empty, this is required!");
if (empty($aro_section_value) ) {
$this->debug_text("consolidated_edit_acl(): ARO Section Value ($aro_section_value) is empty, this is required!");
if (empty($aro_value) ) {
$this->debug_text("consolidated_edit_acl(): ARO Value ($aro_value) is empty, this is required!");
if (empty($return_value) ) {
$this->debug_text("consolidated_edit_acl(): Return Value ($return_value) is empty, this is required!");
//See if a current ACL exists with the current objects, excluding return value
$current_acl_ids =
$this->search_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, FALSE, FALSE, FALSE, FALSE, FALSE);
//showarray($current_acl_ids);
$this->debug_text("add_consolidated_acl(): Found current ACL_IDs, counting ACOs");
foreach ($current_acl_ids as $current_acl_id) {
//Check to make sure these ACLs only have a single ACO mapped to them.
$current_acl_array =
&$this->get_acl($current_acl_id);
//showarray($current_acl_array);
$this->debug_text("add_consolidated_acl(): Current Count: ".
$this->count_all($current_acl_array['aco']).
"");
if ( $this->count_all($current_acl_array['aco']) ==
1) {
$this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO.");
//Test to see if the return values match, if they do, no need removing or appending ARO. Just return true.
if ($current_acl_array['return_value'] ==
$return_value) {
$this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO, and the same return value. No need to modify.");
$acl_ids[] =
$current_acl_id;
$acl_ids_count =
count($acl_ids);
//If acl_id's turns up more then one ACL, lets remove the ARO from all of them in hopes to
//eliminate any conflicts.
if (is_array($acl_ids) AND $acl_ids_count >
0) {
$this->debug_text("add_consolidated_acl(): Removing specified ARO from existing ACL.");
foreach ($acl_ids as $acl_id) {
//Remove ARO from current ACLs, so we don't create conflicting ACLs later on.
if (!$this->shift_acl($acl_id, array($aro_section_value =>
array($aro_value)) ) ) {
$this->debug_text("add_consolidated_acl(): Error removing specified ARO from ACL ID: $acl_id");
$this->debug_text("add_consolidated_acl(): Didn't find any current ACLs with a single ACO. ");
//At this point there should be no conflicting ACLs, searching for an existing ACL with the new values.
$new_acl_ids =
$this->search_acl($aco_section_value, $aco_value, FALSE, FALSE, NULL, NULL, NULL, NULL, $return_value);
$new_acl_count =
count($new_acl_ids);
//showarray($new_acl_ids);
$this->debug_text("add_consolidated_acl(): Found new ACL_IDs, counting ACOs");
foreach ($new_acl_ids as $new_acl_id) {
//Check to make sure these ACLs only have a single ACO mapped to them.
$new_acl_array =
&$this->get_acl($new_acl_id);
//showarray($new_acl_array);
$this->debug_text("add_consolidated_acl(): New Count: ".
$this->count_all($new_acl_array['aco']).
"");
if ( $this->count_all($new_acl_array['aco']) ==
1) {
$this->debug_text("add_consolidated_acl(): ACL ID: $new_acl_id has 1 ACO, append should be able to take place.");
$acl_ids[] =
$new_acl_id;
$acl_ids_count =
count($acl_ids);
if (is_array($acl_ids) AND $acl_ids_count ==
1) {
$this->debug_text("add_consolidated_acl(): Appending specified ARO to existing ACL.");
if (!$this->append_acl($acl_id, array($aro_section_value =>
array($aro_value)) ) ) {
$this->debug_text("add_consolidated_acl(): Error appending specified ARO to ACL ID: $acl_id");
$this->debug_text("add_consolidated_acl(): Hot damn, ACL consolidated!");
} elseif($acl_ids_count >
1) {
$this->debug_text("add_consolidated_acl(): Found more then one ACL with a single ACO. Possible conflicting ACLs.");
} elseif ($acl_ids_count ==
0) {
$this->debug_text("add_consolidated_acl(): No existing ACLs found, create a new one.");
if (!$this->add_acl( array( $aco_section_value =>
array($aco_value) ),
array( $aro_section_value =>
array($aro_value) ),
$this->debug_text("add_consolidated_acl(): Error adding new ACL for ACO Section: $aco_section_value ACO Value: $aco_value Return Value: $return_value");
$this->debug_text("add_consolidated_acl(): ADD_ACL() successfull, returning True.");
$this->debug_text("add_consolidated_acl(): Returning false.");
* Searches for ACL's with specified objects mapped to them.
* NULL values are included in the search, if you want to ignore
* for instance aro_groups use FALSE instead of NULL.
* @return array containing ACL IDs if search is successful
* @param string ACO Section Value
* @param string ACO Value
* @param string ARO Section Value
* @param string ARO Value
* @param string ARO Group Name
* @param string AXO Section Value
* @param string AXO Value
* @param string AXO Group Name
* @param string Return Value
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) {
$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");
if ($aco_section_value !==
FALSE AND $aco_value !==
FALSE) {
if ($aco_section_value ==
NULL AND $aco_value ==
NULL) {
$where_query[] =
'(ac.section_value IS NULL AND ac.value IS NULL)';
$where_query[] =
'(ac.section_value='.
$this->db->quote($aco_section_value) .
' AND ac.value='.
$this->db->quote($aco_value) .
')';
if ($aro_section_value !==
FALSE AND $aro_value !==
FALSE) {
if ($aro_section_value ==
NULL AND $aro_value ==
NULL) {
$where_query[] =
'(ar.section_value IS NULL AND ar.value IS NULL)';
$where_query[] =
'(ar.section_value='.
$this->db->quote($aro_section_value) .
' AND ar.value='.
$this->db->quote($aro_value) .
')';
if ($axo_section_value !==
FALSE AND $axo_value !==
FALSE) {
if ($axo_section_value ==
NULL AND $axo_value ==
NULL) {
$where_query[] =
'(ax.section_value IS NULL AND ax.value IS NULL)';
$where_query[] =
'(ax.section_value='.
$this->db->quote($axo_section_value) .
' AND ax.value='.
$this->db->quote($axo_value) .
')';
if ($aro_group_name !==
FALSE) {
if ($aro_group_name ==
NULL) {
$where_query[] =
'(rg.name IS NULL)';
$where_query[] =
'(rg.name='.
$this->db->quote($aro_group_name) .
')';
if ($axo_group_name !==
FALSE) {
if ($axo_group_name ==
NULL) {
$where_query[] =
'(xg.name IS NULL)';
$where_query[] =
'(xg.name='.
$this->db->quote($axo_group_name) .
')';
if ($return_value !=
FALSE) {
if ($return_value ==
NULL) {
$where_query[] =
'(a.return_value IS NULL)';
$where_query[] =
'(a.return_value='.
$this->db->quote($return_value) .
')';
if (count($where_query) >
0) {
WHERE '.
implode (' AND ', $where_query);
return $this->db->GetCol($query);
* Appends objects on to a specific ACL.
* @return bool TRUE if successful, FALSE otherwise.
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
function append_acl($acl_id, $aro_array=
NULL, $aro_group_ids=
NULL, $axo_array=
NULL, $axo_group_ids=
NULL, $aco_array=
NULL) {
$this->debug_text("append_acl(): ACL_ID: $acl_id");
$this->debug_text("append_acl(): No ACL_ID specified! ACL_ID: $acl_id");
$acl_array =
&$this->get_acl($acl_id);
//Append each object type seperately.
$this->debug_text("append_acl(): Appending ARO's");
while (list
($aro_section_value,$aro_value_array) =
@each($aro_array)) {
foreach ($aro_value_array as $aro_value) {
if ( count($acl_array['aro'][$aro_section_value]) !=
0 ) {
if (!in_array($aro_value, $acl_array['aro'][$aro_section_value])) {
$this->debug_text("append_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value");
$acl_array['aro'][$aro_section_value][] =
$aro_value;
$this->debug_text("append_acl(): Duplicate ARO, ignoring... ");
} else { //Array is empty so add this aro value.
$acl_array['aro'][$aro_section_value][] =
$aro_value;
$this->debug_text("append_acl(): Appending ARO_GROUP_ID's");
while (list
(,$aro_group_id) =
@each($aro_group_ids)) {
if (!is_array($acl_array['aro_groups']) OR !in_array($aro_group_id, $acl_array['aro_groups'])) {
$this->debug_text("append_acl(): ARO Group ID: $aro_group_id");
$acl_array['aro_groups'][] =
$aro_group_id;
$this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
$this->debug_text("append_acl(): Appending AXO's");
while (list
($axo_section_value,$axo_value_array) =
@each($axo_array)) {
foreach ($axo_value_array as $axo_value) {
if (!in_array($axo_value, $acl_array['axo'][$axo_section_value])) {
$this->debug_text("append_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value");
$acl_array['axo'][$axo_section_value][] =
$axo_value;
$this->debug_text("append_acl(): Duplicate AXO, ignoring... ");
$this->debug_text("append_acl(): Appending AXO_GROUP_ID's");
while (list
(,$axo_group_id) =
@each($axo_group_ids)) {
if (!is_array($acl_array['axo_groups']) OR !in_array($axo_group_id, $acl_array['axo_groups'])) {
$this->debug_text("append_acl(): AXO Group ID: $axo_group_id");
$acl_array['axo_groups'][] =
$axo_group_id;
$this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
$this->debug_text("append_acl(): Appending ACO's");
while (list
($aco_section_value,$aco_value_array) =
@each($aco_array)) {
foreach ($aco_value_array as $aco_value) {
if (!in_array($aco_value, $acl_array['aco'][$aco_section_value])) {
$this->debug_text("append_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value");
$acl_array['aco'][$aco_section_value][] =
$aco_value;
$this->debug_text("append_acl(): Duplicate ACO, ignoring... ");
$this->debug_text("append_acl(): Update flag set, updating ACL.");
//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) {
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']);
//Return true if everything is duplicate and no ACL id updated.
$this->debug_text("append_acl(): Update flag not set, NOT updating ACL.");
* Opposite of append_acl(). Removes objects from a specific ACL. (named after PHP's array_shift())
* @return bool TRUE if successful, FALSE otherwise.
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
function shift_acl($acl_id, $aro_array=
NULL, $aro_group_ids=
NULL, $axo_array=
NULL, $axo_group_ids=
NULL, $aco_array=
NULL) {
$this->debug_text("shift_acl(): ACL_ID: $acl_id");
$this->debug_text("shift_acl(): No ACL_ID specified! ACL_ID: $acl_id");
$acl_array =
&$this->get_acl($acl_id);
//Remove each object type seperately.
while (list
($aro_section_value,$aro_value_array) =
@each($aro_array)) {
foreach ($aro_value_array as $aro_value) {
$this->debug_text("shift_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value");
//Only search if aro array contains data.
if ( count($acl_array['aro'][$aro_section_value]) !=
0 ) {
$aro_key =
array_search($aro_value, $acl_array['aro'][$aro_section_value]);
if ($aro_key !==
FALSE) {
$this->debug_text("shift_acl(): Removing ARO. ($aro_key)");
unset
($acl_array['aro'][$aro_section_value][$aro_key]);
$this->debug_text("shift_acl(): ARO doesn't exist, can't remove it.");
$this->debug_text("shift_acl(): Removing ARO_GROUP_ID's");
while (list
(,$aro_group_id) =
@each($aro_group_ids)) {
$this->debug_text("shift_acl(): ARO Group ID: $aro_group_id");
$aro_group_key =
array_search($aro_group_id, $acl_array['aro_groups']);
if ($aro_group_key !==
FALSE) {
$this->debug_text("shift_acl(): Removing ARO Group. ($aro_group_key)");
unset
($acl_array['aro_groups'][$aro_group_key]);
$this->debug_text("shift_acl(): ARO Group doesn't exist, can't remove it.");
while (list
($axo_section_value,$axo_value_array) =
@each($axo_array)) {
foreach ($axo_value_array as $axo_value) {
$this->debug_text("shift_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value");
$axo_key =
array_search($axo_value, $acl_array['axo'][$axo_section_value]);
if ($axo_key !==
FALSE) {
$this->debug_text("shift_acl(): Removing AXO. ($axo_key)");
unset
($acl_array['axo'][$axo_section_value][$axo_key]);
$this->debug_text("shift_acl(): AXO doesn't exist, can't remove it.");
$this->debug_text("shift_acl(): Removing AXO_GROUP_ID's");
while (list
(,$axo_group_id) =
@each($axo_group_ids)) {
$this->debug_text("shift_acl(): AXO Group ID: $axo_group_id");
$axo_group_key =
array_search($axo_group_id, $acl_array['axo_groups']);
if ($axo_group_key !==
FALSE) {
$this->debug_text("shift_acl(): Removing AXO Group. ($axo_group_key)");
unset
($acl_array['axo_groups'][$axo_group_key]);
$this->debug_text("shift_acl(): AXO Group doesn't exist, can't remove it.");
while (list
($aco_section_value,$aco_value_array) =
@each($aco_array)) {
foreach ($aco_value_array as $aco_value) {
$this->debug_text("shift_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value");
$aco_key =
array_search($aco_value, $acl_array['aco'][$aco_section_value]);
if ($aco_key !==
FALSE) {
$this->debug_text("shift_acl(): Removing ACO. ($aco_key)");
unset
($acl_array['aco'][$aco_section_value][$aco_key]);
$this->debug_text("shift_acl(): ACO doesn't exist, can't remove it.");
//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.
//$this->showarray($acl_array);
if ( $this->count_all($acl_array['aco']) ==
0
OR ( $this->count_all($acl_array['aro']) ==
0
AND ( $this->count_all($acl_array['axo']) ==
0 OR $acl_array['axo'] ==
FALSE)
AND (count($acl_array['aro_groups']) ==
0 OR $acl_array['aro_groups'] ==
FALSE)
AND (count($acl_array['axo_groups']) ==
0 OR $acl_array['axo_groups'] ==
FALSE)
$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.");
$this->debug_text("shift_acl(): Update flag set, updating ACL.");
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']);
//Return true if everything is duplicate and no ACL id updated.
$this->debug_text("shift_acl(): Update flag not set, NOT updating ACL.");
* @return array Associative Array with the following items:
* - 'aco' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* - 'aro' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* - 'axo' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* - 'aro_groups' => Array of Group IDs
* - 'axo_groups' => Array of Group IDs
* - 'acl_id' => int ACL ID #
* - 'allow' => int Allow flag
* - 'enabled' => int Enabled flag
* - 'return_value' => string Return Value
* - 'note' => string Note
$this->debug_text("get_acl(): No ACL_ID specified! ACL_ID: $acl_id");
$query =
"select id, allow, enabled, return_value, note from ".
$this->_db_table_prefix.
"acl where id = ".
$acl_id.
"";
$acl_row =
$this->db->GetRow($query);
// return false if not found
$this->debug_text("get_acl(): No ACL found for that ID! ACL_ID: $acl_id");
list
($retarr['acl_id'], $retarr['allow'], $retarr['enabled'], $retarr['return_value'], $retarr['note']) =
$acl_row;
where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
$rs =
$this->db->Execute($query);
while (list
(,$row) =
@each($rows)) {
list
($section_value, $value, $section, $aco) =
$row;
$this->debug_text("Section Value: $section_value Value: $value Section: $section ACO: $aco");
$retarr['aco'][$section_value][] =
$value;
where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
$rs =
$this->db->Execute($query);
while (list
(,$row) =
@each($rows)) {
list
($section_value, $value, $section, $aro) =
$row;
$this->debug_text("Section Value: $section_value Value: $value Section: $section ARO: $aro");
$retarr['aro'][$section_value][] =
$value;
//showarray($options_aro);
where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id";
$rs =
$this->db->Execute($query);
while (list
(,$row) =
@each($rows)) {
list
($section_value, $value, $section, $axo) =
$row;
$this->debug_text("Section Value: $section_value Value: $value Section: $section AXO: $axo");
$retarr['axo'][$section_value][] =
$value;
//showarray($options_aro);
//Grab selected ARO groups.
$query =
"select distinct group_id from ".
$this->_db_table_prefix.
"aro_groups_map where acl_id = $acl_id";
$retarr['aro_groups'] =
$this->db->GetCol($query);
//showarray($selected_groups);
//Grab selected AXO groups.
$query =
"select distinct group_id from ".
$this->_db_table_prefix.
"axo_groups_map where acl_id = $acl_id";
$retarr['axo_groups'] =
$this->db->GetCol($query);
//showarray($selected_groups);
* Checks for conflicts when adding a specific ACL.
* @return bool Returns true if conflict is found.
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Array of ACL IDs to ignore from the result set.
function is_conflicting_acl($aco_array, $aro_array, $aro_group_ids=
NULL, $axo_array=
NULL, $axo_group_ids=
NULL, $ignore_acl_ids=
NULL) {
//Check for potential conflicts. Ignore groups, as groups will almost always have "conflicting" ACLs.
//Thats part of inheritance.
$this->debug_text('is_conflicting_acl(): Invalid ACO Array.');
$this->debug_text('is_conflicting_acl(): Invalid ARO Array.');
foreach ($aco_array as $aco_section_value =>
$aco_value_array) {
$this->debug_text("is_conflicting_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value_array");
$this->debug_text('is_conflicting_acl(): Invalid Format for ACO Array item. Skipping...');
//Move the below line in to the LEFT JOIN above for PostgreSQL sake.
//'ac1' => 'ac.acl_id=a.id',
'ac2' =>
'(ac.section_value='.
$this->db->quote($aco_section_value) .
' AND ac.value IN (\''.
implode ('\',\'', $aco_value_array) .
'\'))'
foreach ($aro_array as $aro_section_value =>
$aro_value_array) {
$this->debug_text("is_conflicting_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value_array");
$this->debug_text('is_conflicting_acl(): Invalid Format for ARO Array item. Skipping...');
$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");
//Move the below line in to the LEFT JOIN above for PostgreSQL sake.
//$where_query['ar1'] = 'ar.acl_id=a.id';
$where_query['ar2'] =
'(ar.section_value='.
$this->db->quote($aro_section_value) .
' AND ar.value IN (\''.
implode ('\',\'', $aro_value_array) .
'\'))';
foreach ($axo_array as $axo_section_value =>
$axo_value_array) {
$this->debug_text("is_conflicting_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value_array");
$this->debug_text('is_conflicting_acl(): Invalid Format for AXO Array item. Skipping...');
$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");
//$where_query['ax1'] = 'ax.acl_id=x.id';
$where_query['ax1'] =
'ax.acl_id=a.id';
$where_query['ax2'] =
'(ax.section_value='.
$this->db->quote($axo_section_value) .
' AND ax.value IN (\''.
implode ('\',\'', $axo_value_array) .
'\'))';
$where =
'WHERE ' .
implode(' AND ', $where_query);
$conflict_result =
$this->db->GetCol($query .
$where);
if (is_array($conflict_result) AND !empty($conflict_result)) {
// showarray($conflict_result);
$conflict_result =
array_diff($conflict_result, $ignore_acl_ids);
if (count($conflict_result) >
0) {
$conflicting_acls_str =
implode(',', $conflict_result);
$this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)");
$where_query['ax1'] =
'(ax.section_value IS NULL AND ax.value IS NULL)';
$where_query['ax2'] =
'xg.name IS NULL';
$where =
'WHERE ' .
implode(' AND ', $where_query);
$conflict_result =
$this->db->GetCol($query .
$where);
if (is_array($conflict_result) AND !empty($conflict_result)) {
// showarray($conflict_result);
$conflict_result =
array_diff($conflict_result, $ignore_acl_ids);
if (count($conflict_result) >
0) {
$conflicting_acls_str =
implode(',', $conflict_result);
$this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)");
$this->debug_text('is_conflicting_acl(): No conflicting ACL found.');
* Add's an ACL. ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
* @return bool Return ACL ID of new ACL if successful, FALSE otherewise.
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param int Enabled flag
* @param string Return Value
* @param string ACL Section Value
* @param int ACL ID # Specific Request
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 ) {
if (count($aco_array) ==
0) {
$this->debug_text("Must select at least one Access Control Object");
if (count($aro_array) ==
0 AND count($aro_group_ids) ==
0) {
$this->debug_text("Must select at least one Access Request Object or Group");
if (!empty($section_value)
$this->debug_text("add_acl(): Section Value: $section_value DOES NOT exist in the database.");
//Unique the group arrays. Later one we unique ACO/ARO/AXO arrays.
//Check for conflicting ACLs.
if ($this->is_conflicting_acl($aco_array,$aro_array,$aro_group_ids,$axo_array,$axo_group_ids,array($acl_id))) {
$this->debug_text("add_acl(): Detected possible ACL conflict, not adding ACL!");
//Edit ACL if acl_id is set. This is simply if we're being called by edit_acl().
if ($this->get_acl($acl_id) ==
FALSE) {
if ( empty($section_value) ) {
// Use the acl section with the lowest order value.
$acl_section_order_value =
$this->db->GetOne("SELECT min(order_value) from $acl_sections_table");
WHERE order_value = $acl_section_order_value
$section_value =
$this->db->GetOne($query);
if ( empty($section_value) ) {
$this->debug_text("add_acl(): No valid acl section found.");
$this->debug_text("add_acl(): Using default section value: $section_value.");
//ACL not specified, so create acl_id
//Create ACL row first, so we have the acl_id
//Double check the ACL ID was generated.
$this->debug_text("add_acl(): ACL_ID generation failed!");
//Begin transaction _after_ GenID. Because on the first run, if GenID has to create the sequence,
//the transaction will fail.
$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().
')';
$result =
$this->db->Execute($query);
if ( !empty($section_value) ) {
$section_sql =
'section_value='.
$this->db->quote ($section_value) .
',';
//Update ACL row, and remove all mappings so they can be re-inserted.
allow='. (int)
$allow .
',
enabled='. (int)
$enabled .
',
return_value='.
$this->db->quote($return_value) .
',
note='.
$this->db->quote($note) .
',
updated_date='.
time() .
'
WHERE id='. (int)
$acl_id;
$result =
$this->db->Execute($query);
$this->debug_text("Update completed without error, delete mappings...");
//Delete all mappings so they can be re-inserted.
foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) {
$query =
'DELETE FROM '.
$this->_db_table_prefix .
$map .
' WHERE acl_id='. (int)
$acl_id;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->db->RollBackTrans();
$this->debug_text("Insert or Update completed without error, insert new mappings.");
// Insert ACO/ARO/AXO mappings
foreach (array('aco', 'aro', 'axo') as $map) {
$map_array = $
{$map .
'_array'};
foreach ($map_array as $section_value =>
$value_array) {
// $this->showarray ($aco_value_array);
$this->debug_text ('add_acl (): Invalid Format for '.
strtoupper ($map) .
' Array item. Skipping...');
foreach ($value_array as $value) {
$object_id =
&$this->get_object_id($section_value, $value, $map);
$this->debug_text('add_acl(): '.
strtoupper($map) .
" Object Section Value: $section_value Value: $value DOES NOT exist in the database. Skipping...");
$this->db->RollBackTrans();
$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) .
')';
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
// Insert ARO/AXO GROUP mappings
foreach (array('aro', 'axo') as $map) {
$map_group_ids = $
{$map .
'_group_ids'};
foreach ($map_group_ids as $group_id) {
if (empty($group_data)) {
$this->debug_text('add_acl(): '.
strtoupper($map) .
" Group: $group_id DOES NOT exist in the database. Skipping...");
$this->db->RollBackTrans();
$query =
'INSERT INTO '.
$this->_db_table_prefix .
$map .
'_groups_map (acl_id,group_id) VALUES ('. (int)
$acl_id .
', '. (int)
$group_id .
')';
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->db->CommitTrans();
$this->Cache_Lite->clean('default');
//Return only the ID in the first row.
* Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
* @return bool Return ACL ID of new ACL if successful, FALSE otherewise.
* @param int ACL ID # to edit
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param array Array of Group IDs
* @param int Enabled flag
* @param string Return Value
* @param string ACL Section Value
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) {
$this->debug_text("edit_acl(): Must specify a single ACL_ID to edit");
if (count($aco_array) ==
0) {
$this->debug_text("edit_acl(): Must select at least one Access Control Object");
if (count($aro_array) ==
0 AND count($aro_group_ids) ==
0) {
$this->debug_text("edit_acl(): Must select at least one Access Request Object or Group");
//if ($this->add_acl($aco_array, $aro_array, $group_ids, $allow, $enabled, $acl_id)) {
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)) {
$this->debug_text("edit_acl(): error in add_acl()");
* @return bool Returns TRUE if successful, FALSE otherwise.
* @param int ACL ID # to delete
$this->debug_text("del_acl(): ACL_ID ($acl_id) is empty, this is required");
// Delete all mappings to the ACL first
foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) {
$query =
'DELETE FROM '.
$this->_db_table_prefix .
$map .
' WHERE acl_id='. (int)
$acl_id;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$query =
'DELETE FROM '.
$this->_db_table_prefix .
'acl WHERE id='. (int)
$acl_id;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->debug_text("del_acl(): deleted ACL ID: $acl_id");
$this->db->CommitTrans();
$this->Cache_Lite->clean('default');
* Grabs all the groups from the database doing preliminary grouping by parent
* @return array Returns 2-Dimensional array: $array[<parent_id>][<group_id>] = <group_name>
* @param string Group Type, either 'ARO' or 'AXO'
//Grab all groups from the database.
$query =
'SELECT id, parent_id, name FROM '.
$table .
' ORDER BY parent_id, name';
$rs =
$this->db->Execute($query);
* Save groups in an array sorted by parent. Should be make it easier for later on.
$sorted_groups =
array();
while ($row =
$rs->FetchRow()) {
$sorted_groups[$parent_id][$id] =
$name;
* Takes the array returned by sort_groups() and formats for human
* consumption. Recursively calls itself to produce the desired output.
* @return array Array of formatted text, ordered by group id, formatted according to $type
* @param array Output from gacl_api->sorted_groups($group_type)
* @param array Output type desired, either 'TEXT', 'TEXT_ASSOC', 'HTML', 'ARRAY' or 'ASSOC'
* @param int Root of tree to produce
* @param int Current level of depth
* @param array Pass the current formatted groups object for appending via recursion.
function format_groups($sorted_groups, $type=
'TEXT', $root_id=
0, $level=
0, $formatted_groups=
NULL) {
$formatted_groups =
array ();
//$this->showarray($formatted_groups);
//while (list($id,$name) = @each($sorted_groups[$root_id])) {
if (isset
($sorted_groups[$root_id])) {
foreach ($sorted_groups[$root_id] as $id =>
$name) {
* Formatting optimized for TEXT (combo box) output.
$spacing =
substr($level, 0, -
8) .
'\'- ';
$level =
substr($level, 0, -
8) .
' ';
$spacing =
substr($level, 0, -
8) .
'|- ';
$next =
$level .
'| ';
if ($type ==
'TEXT_ASSOC') {
$formatted_groups[] =
array( 'value'=>
$id, 'text'=>
$spacing.
$name );
$formatted_groups[$id] =
$spacing.
$name;
* Formatting optimized for HTML (tables) output.
$spacing =
"<img src=\"images/blank.png\" width=\"$width\" height=\"0\" alt=\"\" />";
$formatted_groups[$id] =
$spacing.
" ".
$name;
$formatted_groups[$id] =
$name;
* Formatting optimized for HTML: <option value="value">text</option>.
$formatted_groups[] =
array( 'value'=>
$id, 'text'=>
$name, 'level'=>
$level );
//if (isset($sorted_groups[$id]) AND count($sorted_groups[$id]) > 0) {
if (isset
($sorted_groups[$id]) ) {
//$this->debug_text("format_groups(): Recursing! Level: $level");
$formatted_groups =
$this->format_groups($sorted_groups, $type, $id, $next, $formatted_groups);
//$this->debug_text("format_groups(): Found last branch!");
//$this->debug_text("format_groups(): Returning final array.");
return $formatted_groups;
* Gets the group_id given the name or value.
* Will only return one group id, so if there are duplicate names, it will return false.
* @return int Returns Group ID if found and Group ID is unique in database, otherwise, returns FALSE
* @param string Group Value
* @param string Group Name
* @param string Group Type, either 'ARO' or 'AXO'
$this->debug_text("get_group_id(): name ($name) is empty, this is required");
$this->db->setQuery( "SELECT id FROM $table WHERE name='$name'" );
$rows =
$this->db->loadRowList();
if ($this->db->getErrorNum()) {
$row_count =
count( $rows );
$this->debug_text("get_group_id(): Returned $row_count rows, can only return one. Please make your names unique.");
$this->debug_text("get_group_id(): Returned $row_count rows");
* Gets a groups child IDs
* @return array Array of Child ID's of the referenced group
* @param int Group Type, either 'ARO' or 'AXO'
* @param string Either 'RECURSE' or 'NO_RECURSE', to recurse while fetching group children.
$this->debug_text("get_group_children(): Group_ID: $group_id Group Type: $group_type Recurse: $recurse");
$this->debug_text("get_group_children(): ID ($group_id) is empty, this is required");
//FIXME-mikeb: Why is group_id in quotes?
LEFT JOIN '.
$table .
' g2 ON g2.lft<g1.lft AND g2.rgt>g1.rgt
WHERE g2.id='. (int)
$group_id;
WHERE g1.parent_id='. (int)
$group_id;
return $this->db->GetCol($query);
* Gets the group data given the GROUP_ID.
* @return array Returns numerically indexed array with the following columns:
* - array[0] = (int) Group ID #
* - array[1] = (int) Parent Group ID #
* - array[2] = (string) Group Value
* - array[3] = (string) Group Name
* - array[4] = (int) lft MPTT Value
* - array[5] = (int) rgt MPTT Value
* @param string Group Type, either 'ARO' or 'AXO'
$this->debug_text("get_group_data(): Group_ID: $group_id Group Type: $group_type");
$this->debug_text("get_group_data(): ID ($group_id) is empty, this is required");
$query =
'SELECT id, parent_id, value, name, lft, rgt FROM '.
$table .
' WHERE id='. (int)
$group_id;
//$rs = $this->db->Execute($query);
$row =
$this->db->GetRow($query);
$this->debug_text("get_object_data(): Group does not exist.");
* Grabs the parent_id of a given group
* @return int Parent ID of the Group
* @param string Group Type, either 'ARO' or 'AXO'
$this->debug_text("get_group_parent_id(): ID: $id Group Type: $group_type");
$this->debug_text("get_group_parent_id(): ID ($id) is empty, this is required");
$query =
'SELECT parent_id FROM '.
$table .
' WHERE id='. (int)
$id;
$rs =
$this->db->Execute($query);
$row_count =
$rs->RecordCount();
$this->debug_text("get_group_parent_id(): Returned $row_count rows, can only return one. Please make your names unique.");
$this->debug_text("get_group_parent_id(): Returned $row_count rows");
* Grabs the id of the root group for the specified tree
* @return int Root Group ID #
* @param string Group Type, either 'ARO' or 'AXO'
$this->debug_text('get_root_group_id(): Group Type: '.
$group_type);
$this->debug_text('get_root_group_id(): Invalid Group Type: '.
$group_type);
$query =
'SELECT id FROM '.
$table .
' WHERE parent_id=0';
$rs =
$this->db->Execute($query);
$row_count =
$rs->RecordCount();
$this->debug_text('get_root_group_id(): Returned 0 rows, you do not have a root group defined yet.');
$this->debug_text('get_root_group_id(): Returned '.
$row_count .
' rows, can only return one. Your tree is very broken.');
/*======================================================================*\
Function: map_path_to_root()
Purpose: Maps a unique path to root to a specific group. Each group can only have
\*======================================================================*/
/*======================================================================*\
Function: put_path_to_root()
Purpose: Writes the unique path to root to the database. There should really only be
one path to root for each level "deep" the groups go. If the groups are branched
10 levels deep, there should only be 10 unique path to roots. These of course
overlap each other more and more the closer to the root/trunk they get.
\*======================================================================*/
/*======================================================================*\
Function: clean_path_to_root()
Purpose: Cleans up any paths that are not being used.
\*======================================================================*/
/*======================================================================*\
Function: get_path_to_root()
Purpose: Generates the path to root for a given group.
\*======================================================================*/
* Inserts a group, defaults to be on the "root" branch.
* Since v3.3.x you can only create one group with Parent_ID=0
* So, its a good idea to create a "Virtual Root" group with Parent_ID=0
* Then assign other groups to that.
* @return int New Group ID # if successful, FALSE if otherwise.
* @param string Group Value
* @param string Group Name
* @param int Parent Group ID #
* @param string Group Type, either 'ARO' or 'AXO'
function add_group($value, $name, $parent_id=
0, $group_type=
'ARO') {
$this->debug_text("add_group(): Name: $name Value: $value Parent ID: $parent_id Group Type: $group_type");
$this->debug_text("add_group(): name ($name) OR parent id ($parent_id) is empty, this is required");
//This has to be outside the transaction, because the first time it is run, it will say the sequence
//doesn't exist. Then try to create it, but the transaction will already by aborted by then.
$insert_id =
$this->db->GenID($table.
'_id_seq', $this->_defaultGenID( $table ));
// special case for root group
// check a root group is not already defined
$query =
'SELECT id FROM '.
$table .
' WHERE parent_id=0';
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
if ($rs->RowCount() >
0) {
$this->debug_text('add_group (): A root group already exists.');
$this->db->RollBackTrans();
$this->debug_text("add_group (): parent id ($parent_id) is empty, this is required");
$this->db->RollbackTrans();
// grab parent details from database
$query =
'SELECT id, lft, rgt FROM '.
$table .
' WHERE id='. (int)
$parent_id;
$row =
$this->db->GetRow($query);
$this->db->RollBackTrans();
$this->debug_text('add_group (): Parent ID: '.
$parent_id .
' not found.');
$this->db->RollBackTrans();
// make room for the new group
$query =
'UPDATE '.
$table .
' SET rgt=rgt+2 WHERE rgt>='. (int)
$parent_rgt;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$query =
'UPDATE '.
$table .
' SET lft=lft+2 WHERE lft>'.
$parent_rgt;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$query =
'INSERT INTO '.
$table .
' (id,parent_id,name,value,lft,rgt) VALUES ('.
$insert_id .
','.
$parent_id .
','.
$this->db->quote($name) .
','.
$this->db->quote($value) .
','.
$parent_rgt .
','.
($parent_rgt +
1) .
')';
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->db->CommitTrans();
$this->debug_text('add_group (): Added group as ID: '.
$insert_id);
* Gets all objects assigned to a group.
* If $option == 'RECURSE' it will get all objects in child groups as well.
* defaults to omit child groups.
* @return array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param string Group Type, either 'ARO' or 'AXO'
* @param string Option, either 'RECURSE' or 'NO_RECURSE'
$this->debug_text("get_group_objects(): Group ID: $group_id");
$this->debug_text("get_group_objects(): Group ID: ($group_id) is empty, this is required");
SELECT o.section_value,o.value';
if ($option ==
'RECURSE') {
FROM '.
$group_table .
' g2
JOIN '.
$group_table .
' g1 ON g1.lft>=g2.lft AND g1.rgt<=g2.rgt
JOIN '.
$map_table .
' AS gm ON gm.group_id=g1.id
JOIN '.
$object_table .
' AS o ON o.id=gm.'.
$group_type .
'_id
WHERE g2.id='. (int)
$group_id;
FROM '.
$map_table .
' AS gm
LEFT JOIN '.
$object_table .
' AS o ON o.id=gm.'.
$group_type .
'_id
WHERE gm.group_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
$this->debug_text("get_group_objects(): Got group objects, formatting array.");
while ($row =
$rs->FetchRow()) {
$retarr[$section][] =
$value;
* Assigns an Object to a group
* @return bool Returns TRUE if successful, FALSE otherwise.
* @param string Object Section Value
* @param string Object Value
* @param string Group Type, either 'ARO' or 'AXO'
function add_group_object($group_id, $object_section_value, $object_value, $group_type=
'ARO') {
$this->debug_text("add_group_object(): Group ID: $group_id Section Value: $object_section_value Value: $object_value Group Type: $group_type");
$object_section_value =
trim($object_section_value);
$object_value =
trim($object_value);
if (empty($group_id) OR empty($object_value) OR empty($object_section_value)) {
$this->debug_text("add_group_object(): Group ID: ($group_id) OR Value ($object_value) OR Section value ($object_section_value) is empty, this is required");
// test to see if object & group exist and if object is already a member
SELECT o.id AS id,g.id AS group_id,gm.group_id AS member
FROM '.
$object_table .
' o
LEFT JOIN '.
$group_table .
' g ON g.id='. (int)
$group_id .
'
LEFT JOIN '.
$table .
' gm ON (gm.'.
$group_type .
'_id=o.id AND gm.group_id=g.id)
WHERE (o.section_value='.
$this->db->quote($object_section_value) .
' AND o.value='.
$this->db->quote($object_value) .
')';
$rs =
$this->db->Execute($query);
if ($rs->RecordCount() !=
1) {
$this->debug_text('add_group_object(): Value ('.
$object_value .
') OR Section value ('.
$object_section_value .
') is invalid. Does this object exist?');
if ($row[1] !=
$group_id) {
$this->debug_text('add_group_object(): Group ID ('.
$group_id .
') is invalid. Does this group exist?');
if ($row[1] ==
$row[2]) {
$this->debug_text('add_group_object(): Object: ('.
$object_section_value .
' -> '.
$object_value .
') is already a member of Group: ('.
$group_id .
')');
//Object is already assigned to group. Return true.
$query =
'INSERT INTO '.
$table .
' (group_id,'.
$group_type .
'_id) VALUES ('. (int)
$group_id .
','. (int)
$object_id .
')';
$rs =
$this->db->Execute($query);
$this->debug_text('add_group_object(): Added Object: '.
$object_id .
' to Group ID: '.
$group_id);
$this->Cache_Lite->clean('default');
* Removes an Object from a group.
* @return bool Returns TRUE if successful, FALSE otherwise
* @param string Object Section Value
* @param string Object Value
* @param string Group Type, either 'ARO' or 'AXO'
function del_group_object($group_id, $object_section_value, $object_value, $group_type=
'ARO') {
$this->debug_text("del_group_object(): Group ID: $group_id Section value: $object_section_value Value: $object_value");
$object_section_value =
trim($object_section_value);
$object_value =
trim($object_value);
if (empty($group_id) OR empty($object_value) OR empty($object_section_value)) {
$this->debug_text("del_group_object(): Group ID: ($group_id) OR Section value: $object_section_value OR Value ($object_value) is empty, this is required");
if (!$object_id =
$this->get_object_id($object_section_value, $object_value, $group_type)) {
$this->debug_text ("del_group_object (): Group ID ($group_id) OR Value ($object_value) OR Section value ($object_section_value) is invalid. Does this object exist?");
$query =
'DELETE FROM '.
$table .
' WHERE group_id='. (int)
$group_id .
' AND '.
$group_type .
'_id='. (int)
$object_id;
$rs =
$this->db->Execute($query);
$this->debug_text("del_group_object(): Deleted Value: $object_value to Group ID: $group_id assignment");
$this->Cache_Lite->clean('default');
* @returns bool Returns TRUE if successful, FALSE otherwise
* @param string Group Value
* @param string Group Name
* @param string Group Type, either 'ARO' or 'AXO'
function edit_group($group_id, $value=
NULL, $name=
NULL, $parent_id=
NULL, $group_type=
'ARO') {
$this->debug_text("edit_group(): ID: $group_id Name: $name Value: $value Parent ID: $parent_id Group Type: $group_type");
$this->debug_text('edit_group(): Group ID ('.
$group_id .
') is empty, this is required');
$this->debug_text('edit_group(): Invalid Group ID: '.
$group_id);
// don't set name if it is unchanged
// don't set parent_id if it is unchanged
if ($parent_id ==
$curr[1]) {
if (!empty($parent_id)) {
if ($group_id ==
$parent_id) {
$this->debug_text('edit_group(): Groups can\'t be a parent to themselves. Incest is bad. ;)');
//Make sure we don't re-parent to our own children.
//Grab all children of this group_id.
if (@in_array($parent_id, $children_ids) ) {
$this->debug_text('edit_group(): Groups can\'t be re-parented to their own children, this would be incestuous!');
// make sure parent exists
$this->debug_text('edit_group(): Parent Group ('.
$parent_id .
') doesn\'t exist');
// update name if it is specified.
$set[] =
'name='.
$this->db->quote($name);
// update parent_id if it is specified.
if (!empty($parent_id)) {
$set[] =
'parent_id='. (int)
$parent_id;
// update value if it is specified.
$set[] =
'value='.
$this->db->quote($value);
$this->debug_text('edit_group(): Nothing to update.');
$query =
'UPDATE '.
$table .
' SET '.
implode(',', $set) .
' WHERE id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
$this->debug_text('edit_group(): Modified group ID: '.
$group_id);
// rebuild group tree if parent_id has changed
if (!empty($parent_id)) {
$this->db->RollbackTrans();
$this->db->CommitTrans();
$this->Cache_Lite->clean('default');
* rebuilds the group tree for the given type
* @return bool Returns TRUE if successful, FALSE otherwise
* @param string Group Type, either 'ARO' or 'AXO'
* @param int Left value of Group
function rebuild_tree($group_type =
'ARO', $group_id =
NULL, $left =
1) {
$this->debug_text("rebuild_tree(): Group Type: $group_type Group ID: $group_id Left: $left");
$this->debug_text('rebuild_tree(): No Group ID Specified, using Root Group ID: '.
$group_id);
$this->debug_text('rebuild_tree(): A Root group could not be found, are there any groups defined?');
if ($rebuilt ===
FALSE) {
$this->debug_text('rebuild_tree(): Error rebuilding tree!');
$this->db->RollBackTrans();
$this->db->CommitTrans();
$this->debug_text('rebuild_tree(): Tree rebuilt.');
* Utility recursive function called by rebuild_tree()
* @return int Returns right value of this node + 1
* @param string Table name of group type
* @param int Left value of Group
$this->debug_text("_rebuild_tree(): Table: $table Group ID: $group_id Left: $left");
// get all children of this node
$query =
'SELECT id FROM '.
$table .
' WHERE parent_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// the right value of this node is the left value + 1
while ($row =
$rs->FetchRow()) {
// recursive execution of this function for each
// $right is the current right value, which is
// incremented by the rebuild_tree function
// we've got the left value, and now that we've processed
// the children of this node we also know the right value
$query =
'UPDATE '.
$table .
' SET lft='. (int)
$left .
', rgt='. (int)
$right .
' WHERE id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// return the right value of this node + 1
* @return bool Returns TRUE if successful, FALSE otherwise.
* @param bool If TRUE, child groups of this group will be reparented to the current group's parent.
* @param string Group Type, either 'ARO' or 'AXO'
function del_group($group_id, $reparent_children=
TRUE, $group_type=
'ARO') {
$this->debug_text("del_group(): ID: $group_id Reparent Children: $reparent_children Group Type: $group_type");
$this->debug_text("del_group(): Group ID ($group_id) is empty, this is required");
// Get details of this group
$query =
'SELECT id, parent_id, name, lft, rgt FROM '.
$table .
' WHERE id='. (int)
$group_id;
$group_details =
$this->db->GetRow($query);
$parent_id =
$group_details[1];
$left =
$group_details[3];
$right =
$group_details[4];
// grab list of all children
// prevent deletion of root group & reparent of children if it has more than one immediate child
$query =
'SELECT count(*) FROM '.
$table .
' WHERE parent_id='. (int)
$group_id;
$child_count =
$this->db->GetOne($query);
if (($child_count >
1) AND $reparent_children) {
$this->debug_text ('del_group (): You cannot delete the root group and reparent children, this would create multiple root groups.');
$this->db->RollbackTrans();
// there are no child groups, just delete group
case count($children_ids) ==
0:
$query =
'DELETE FROM '.
$groups_map_table .
' WHERE group_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// remove group object maps
$query =
'DELETE FROM '.
$groups_object_map_table .
' WHERE group_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
$query =
'DELETE FROM '.
$table .
' WHERE id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// move all groups right of deleted group left by width of deleted group
$query =
'UPDATE '.
$table .
' SET lft=lft-'. (int)
($right-
$left+
1) .
' WHERE lft>'. (int)
$right;
$rs =
$this->db->Execute($query);
$query =
'UPDATE '.
$table .
' SET rgt=rgt-'. (int)
($right-
$left+
1) .
' WHERE rgt>'. (int)
$right;
$rs =
$this->db->Execute($query);
case $reparent_children ==
TRUE:
$query =
'DELETE FROM '.
$groups_map_table .
' WHERE group_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// remove group object maps
$query =
'DELETE FROM '.
$groups_object_map_table .
' WHERE group_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
$query =
'DELETE FROM '.
$table .
' WHERE id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// set parent of immediate children to parent group
$query =
'UPDATE '.
$table .
' SET parent_id='. (int)
$parent_id .
' WHERE parent_id='. (int)
$group_id;
$rs =
$this->db->Execute($query);
// move all children left by 1
$query =
'UPDATE '.
$table .
' SET lft=lft-1, rgt=rgt-1 WHERE lft>'. (int)
$left .
' AND rgt<'. (int)
$right;
$rs =
$this->db->Execute($query);
// move all groups right of deleted group left by 2
$query =
'UPDATE '.
$table .
' SET lft=lft-2 WHERE lft>'. (int)
$right;
$rs =
$this->db->Execute($query);
$query =
'UPDATE '.
$table .
' SET rgt=rgt-2 WHERE rgt>'. (int)
$right;
$rs =
$this->db->Execute($query);
// make list of group and all children
$group_ids =
$children_ids;
$group_ids[] = (int)
$group_id;
$query =
'DELETE FROM '.
$groups_map_table .
' WHERE group_id IN ('.
implode (',', $group_ids) .
')';
$rs =
$this->db->Execute($query);
// remove group object maps
$query =
'DELETE FROM '.
$groups_object_map_table .
' WHERE group_id IN ('.
implode (',', $group_ids) .
')';
$rs =
$this->db->Execute($query);
$query =
'DELETE FROM '.
$table .
' WHERE id IN ('.
implode (',', $group_ids) .
')';
$rs =
$this->db->Execute($query);
// move all groups right of deleted group left by width of deleted group
$query =
'UPDATE '.
$table .
' SET lft=lft-'.
($right -
$left +
1) .
' WHERE lft>'. (int)
$right;
$rs =
$this->db->Execute($query);
$query =
'UPDATE '.
$table .
' SET rgt=rgt-'.
($right -
$left +
1) .
' WHERE rgt>'. (int)
$right;
$rs =
$this->db->Execute($query);
// if the delete failed, rollback the trans and return false
$this->db->RollBackTrans();
$this->debug_text("del_group(): deleted group ID: $group_id");
$this->db->CommitTrans();
$this->Cache_Lite->clean('default');
* Grabs all Objects's in the database, or specific to a section_value
* @return ADORecordSet Returns recordset directly, with object ID only selected:
* @param string Filter to this section value
* @param int Returns hidden objects if 1, leaves them out otherwise.
* @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL'
function get_object($section_value =
null, $return_hidden=
1, $object_type=
NULL) {
$this->debug_text('get_object(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_object(): Section Value: $section_value Object Type: $object_type");
$query =
'SELECT id FROM '.
$table;
if (!empty($section_value)) {
$where[] =
'section_value='.
$this->db->quote($section_value);
if ($return_hidden==
0 AND $object_type !=
'acl') {
$query .=
' WHERE '.
implode(' AND ', $where);
$rs =
$this->db->GetCol($query);
* get_ungrouped_objects()
* Grabs ID's of all Objects (ARO's and AXO's only) in the database not assigned to a Group.
* This function is useful for applications that synchronize user databases with an outside source.
* If syncrhonization doesn't automatically place users in an appropriate group, this function can
* quickly identify them so that they can be assigned to the correct group.
* @return array Returns an array of object ID's
* @param int Returns hidden objects if 1, does not if 0.
* @param string Object Type, either 'ARO' or 'AXO' (groupable types)
$this->debug_text('get_ungrouped_objects(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_ungrouped_objects(): Section Value: $section_value Object Type: $object_type");
$query =
'SELECT id FROM '.
$table .
'
LEFT JOIN groups_' .
$table .
'_map
ON ' .
$table .
'.id = groups_' .
$table .
'_map.' .
$table .
'_id
$where[] =
'groups_' .
$table .
'_map.group_id IS NULL';
$query .=
' WHERE '.
implode(' AND ', $where);
$rs =
$this->db->Execute($query);
$this->debug_db('get_ungrouped_objects');
$retarr[] =
$rs->fields[0];
// Return Array of object IDS
* Grabs all Objects in the database, or specific to a section_value
* @return array Returns objects in format suitable for add_acl and is_conflicting_acl
* - i.e. Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...]
* @param string Filter for section value
* @param int Returns hidden objects if 1, does not if 0
* @param string Object Type, either 'ACO', 'ARO', 'AXO'
function get_objects($section_value =
NULL, $return_hidden =
1, $object_type =
NULL) {
$this->debug_text('get_objects(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_objects(): Section Value: $section_value Object Type: $object_type");
$query =
'SELECT section_value,value FROM '.
$table;
if (!empty($section_value)) {
$where[] =
'section_value='.
$this->db->quote($section_value);
$query .=
' WHERE '.
implode(' AND ', $where);
$rs =
$this->db->Execute($query);
while ($row =
$rs->FetchRow()) {
$retarr[$row[0]][] =
$row[1];
* Gets all data pertaining to a specific Object.
* @return array Returns 2-Dimensional array of rows with columns = ( section_value, value, order_value, name, hidden )
* @param string Object Type, either 'ACO', 'ARO', 'AXO'
$this->debug_text('get_object_data(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_object_data(): Object ID: $object_id Object Type: $object_type");
if (empty($object_id) ) {
$this->debug_text("get_object_data(): Object ID ($object_id) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("get_object_data(): Object Type ($object_type) is empty, this is required");
$query =
'SELECT section_value,value,order_value,name,hidden FROM '.
$table .
' WHERE id='. (int)
$object_id;
$rs =
$this->db->Execute($query);
if ($rs->RecordCount() <
1) {
$this->debug_text('get_object_data(): Returned '.
$row_count .
' rows');
* Gets the object_id given the section_value AND value of the object.
* @return int Object ID #
* @param string Object Section Value
* @param string Object Value
* @param string Object Type, either 'ACO', 'ARO', 'AXO'
function get_object_id($section_value, $value, $object_type=
NULL) {
$this->debug_text('get_object_id(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_object_id(): Section Value: $section_value Value: $value Object Type: $object_type");
$section_value =
trim($section_value);
if (empty($section_value) AND empty($value) ) {
$this->debug_text("get_object_id(): Section Value ($value) AND value ($value) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("get_object_id(): Object Type ($object_type) is empty, this is required");
$query =
'SELECT id FROM '.
$table .
' WHERE section_value='.
$this->db->quote($section_value) .
' AND value='.
$this->db->quote($value);
$rs =
$this->db->Execute($query);
$row_count =
$rs->RecordCount();
$this->debug_text("get_object_id(): Returned $row_count rows, can only return one. This should never happen, the database may be missing a unique key.");
$this->debug_text("get_object_id(): Returned $row_count rows");
* get_object_section_value()
* Gets the object_section_value given object id
* @return string Object Section Value
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
$this->debug_text('get_object_section_value(): Invalid Object Type: '.
$object_type);
$this->debug_text("get_object_section_value(): Object ID: $object_id Object Type: $object_type");
if (empty($object_id) ) {
$this->debug_text("get_object_section_value(): Object ID ($object_id) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("get_object_section_value(): Object Type ($object_type) is empty, this is required");
$query =
'SELECT section_value FROM '.
$table .
' WHERE id='. (int)
$object_id;
$rs =
$this->db->Execute($query);
$this->debug_db('get_object_section_value');
$row_count =
$rs->RecordCount();
$this->debug_text("get_object_section_value(): Returned $row_count rows, can only return one.");
$this->debug_text("get_object_section_value(): Returned $row_count rows");
* Gets all groups an object is a member of.
* If $option == 'RECURSE' it will get all ancestor groups.
* defaults to only get direct parents.
* @return array Array of Group ID #'s, or FALSE if Failed
* @param string Object Type, either 'ARO' or 'AXO'
* @param string Option, either 'RECURSE', or 'NO_RECURSE'
function get_object_groups($object_id, $object_type =
'ARO', $option =
'NO_RECURSE') {
$this->debug_text('get_object_groups(): Object ID: '.
$object_id .
' Object Type: '.
$object_type .
' Option: '.
$option);
$this->debug_text('get_object_groups(): Invalid Object Type: '.
$object_type);
$this->debug_text('get_object_groups(): Object ID: ('.
$object_id .
') is empty, this is required');
SELECT DISTINCT g.id AS group_id
LEFT JOIN '.
$group_table .
' g1 ON g1.id=gm.group_id
LEFT JOIN '.
$group_table .
' g ON g.lft<=g1.lft AND g.rgt>=g1.rgt';
FROM '.
$map_table .
' gm';
WHERE gm.'.
$object_type .
'_id='. (int)
$object_id;
$rs =
$this->db->Execute($query);
while ($row =
$rs->FetchRow()) {
* @return int Returns the ID # of the new object if successful, FALSE otherwise
* @param string Object Section Value
* @param string Object Name
* @param string Object Value
* @param int Display Order
* @param int Hidden Flag, either 1 to hide, or 0 to show.
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
function add_object($section_value, $name, $value=
0, $order=
0, $hidden=
0, $object_type=
NULL) {
$this->debug_text('add_object(): Invalid Object Type: '.
$object_type);
$this->debug_text("add_object(): Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type");
$section_value =
trim($section_value);
if ($order ==
NULL OR $order ==
'') {
if (empty($name) OR empty($section_value) ) {
$this->debug_text("add_object(): name ($name) OR section value ($section_value) is empty, this is required");
$this->debug_text("add_object(): name ($name) OR value ($value) is too long.");
if (empty($object_type) ) {
$this->debug_text("add_object(): Object Type ($object_type) is empty, this is required");
// Test to see if the section is invalid or object already exists.
SELECT CASE WHEN o.id IS NULL THEN 0 ELSE 1 END AS object_exists
FROM '.
$object_sections_table .
' s
LEFT JOIN '.
$table .
' o ON (s.value=o.section_value AND o.value='.
$this->db->quote($value) .
')
WHERE s.value='.
$this->db->quote($section_value);
$rs =
$this->db->Execute($query);
if ($rs->RecordCount() !=
1) {
$this->debug_text("add_object(): Section Value: $section_value Object Type ($object_type) does not exist, this is required");
//Object is already created.
$insert_id =
$this->db->GenID($table .
'_seq', $this->_defaultGenID( $table ));
$query =
"INSERT INTO $table (id,section_value,value,order_value,name,hidden) " .
"VALUES(". (int)
$insert_id .
"," .
$this->db->quote($section_value) .
"," .
$this->db->quote($value) .
",$order," .
$this->db->quote($name) .
",$hidden)";
$rs =
$this->db->Execute($query);
$this->debug_text("add_object(): Added object as ID: $insert_id");
* @return bool Returns TRUE if successful, FALSE otherwise
* @param string Object Section Value
* @param string Object Name
* @param string Object Value
* @param int Display Order
* @param int Hidden Flag, either 1 to hide, or 0 to show
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
function edit_object($object_id, $section_value, $name, $value=
0, $order=
0, $hidden=
0, $object_type=
NULL) {
$this->debug_text("edit_object(): ID: $object_id Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type");
$object_id = (int)
$object_id;
$section_value =
trim($section_value);
if (empty($object_id) OR empty($section_value) ) {
$this->debug_text("edit_object(): Object ID ($object_id) OR Section Value ($section_value) is empty, this is required");
$this->debug_text("edit_object(): name ($name) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("edit_object(): Object Type ($object_type) is empty, this is required");
//Get old value incase it changed, before we do the update.
$query =
'SELECT value, section_value FROM '.
$table .
' WHERE id='.
$object_id;
$old =
$this->db->GetRow($query);
SET section_value='.
$this->db->quote($section_value) .
',
value='.
$this->db->quote($value) .
',
order_value='.
$order .
',
name='.
$this->db->quote($name) .
',
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
if ($old[0] !=
$value OR $old[1] !=
$section_value) {
$this->debug_text("edit_object(): Value OR Section Value Changed, update other tables.");
UPDATE '.
$object_map_table .
'
SET value='.
$this->db->quote($value) .
',
section_value='.
$this->db->quote($section_value) .
'
WHERE section_value='.
$this->db->quote($old[1]) .
'
AND value='.
$this->db->quote($old[0]);
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
$this->debug_text ('edit_object(): Modified Map Value: '.
$value .
' Section Value: '.
$section_value);
$this->db->CommitTrans();
* Deletes a given Object and, if instructed to do so, erase all referencing objects
* ERASE feature by: Martino Piccinato
* @return bool Returns TRUE if successful, FALSE otherwise.
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
* @param bool Erases all referencing objects if TRUE, leaves them alone otherwise.
function del_object($object_id, $object_type=
NULL, $erase=
FALSE) {
$this->debug_text('del_object(): Invalid Object Type: '.
$object_type);
$this->debug_text("del_object(): ID: $object_id Object Type: $object_type, Erase all referencing objects: $erase");
if (empty($object_id) ) {
$this->debug_text("del_object(): Object ID ($object_id) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("del_object(): Object Type ($object_type) is empty, this is required");
$object_id = (int)
$object_id;
// Get Object section_value/value (needed to look for referencing objects)
$query =
'SELECT section_value,value FROM '.
$table .
' WHERE id='.
$object_id;
$object =
$this->db->GetRow($query);
$this->debug_text('del_object(): The specified object ('.
strtoupper($object_type) .
' ID: '.
$object_id .
') could not be found.');
$this->db->RollbackTrans();
$section_value =
$this->db->quote( $object[0] );
$value =
$this->db->quote( $object[1] );
// Get ids of acl referencing the Object (if any)
$query =
"SELECT acl_id FROM $object_map_table WHERE value=$value AND section_value=$section_value";
$acl_ids =
$this->db->GetCol($query);
// We were asked to erase all acl referencing it
$this->debug_text("del_object(): Erase was set to TRUE, delete all referencing objects");
if ($object_type ==
"aro" OR $object_type ==
"axo") {
// The object can be referenced in groups_X_map tables
// in the future this branching may become useless because
// ACO might me "groupable" too
// Get rid of groups_map referencing the Object
$query =
'DELETE FROM '.
$object_group_table .
' WHERE '.
$object_type .
'_id='.
$object_id;
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
//There are acls actually referencing the object
if ($object_type ==
'aco') {
// I know it's extremely dangerous but
// if asked to really erase an ACO
// we should delete all acl referencing it
// Do this below this branching
// where it uses $orphan_acl_ids as
// the array of the "orphaned" acl
// in this case all referenced acl are
$orphan_acl_ids =
$acl_ids;
// The object is not an ACO and might be referenced
// in still valid acls regarding also other object.
// In these cases the acl MUST NOT be deleted
// Get rid of $object_id map referencing erased objects
$query =
"DELETE FROM $object_map_table WHERE section_value='$section_value' AND value='$value'";
$this->db->Execute($query);
$this->db->RollBackTrans();
// Find the "orphaned" acl. I mean acl referencing the erased Object (map)
// not referenced anymore by other objects
$sql_acl_ids =
implode(",", $acl_ids);
LEFT JOIN '.
$object_map_table .
' b ON a.id=b.acl_id
LEFT JOIN '.
$groups_map_table .
' c ON a.id=c.acl_id
AND b.section_value IS NULL
AND a.id in ('.
$sql_acl_ids .
')';
$orphan_acl_ids =
$this->db->GetCol($query);
} // End of else section of "if ($object_type == "aco")"
// If there are orphaned acls get rid of them
foreach ($orphan_acl_ids as $acl) {
} // End of if ($acl_ids)
// Finally delete the Object itself
$query =
"DELETE FROM $table WHERE id=$object_id";
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->db->CommitTrans();
} // End of "if ($erase)"
if ($object_type ==
'axo' OR $object_type ==
'aro') {
// If the object is "groupable" (may become unnecessary,
// Get id of groups where the object is assigned:
// you must explicitly remove the object from its groups before
// deleting it (don't know if this is really needed, anyway it's safer ;-)
$query =
'SELECT group_id FROM '.
$object_group_table .
' WHERE '.
$object_type .
'_id='.
$object_id;
$groups_ids =
$this->db->GetCol($query);
if ( ( isset
($acl_ids) AND !empty($acl_ids) ) OR ( isset
($groups_ids) AND !empty($groups_ids) ) ) {
// The Object is referenced somewhere (group or acl), can't delete it
$this->debug_text("del_object(): Can't delete the object as it is being referenced by GROUPs (".
@implode($groups_ids).
") or ACLs (".
@implode($acl_ids,",").
")");
$this->db->RollBackTrans();
// The Object is NOT referenced anywhere, delete it
$query =
"DELETE FROM $table WHERE id=$object_id";
$rs =
$this->db->Execute($query);
$this->db->RollBackTrans();
$this->db->CommitTrans();
$this->db->RollbackTrans();
* get_object_section_section_id()
* Gets the object_section_id given the name AND/OR value of the section.
* Will only return one section id, so if there are duplicate names it will return false.
* @return int Object Section ID if the object section is found AND is unique, or FALSE otherwise.
* @param string Object Name
* @param string Object Value
* @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL'
$this->debug_text("get_object_section_section_id(): Value: $value Name: $name Object Type: $object_type");
$this->debug_text('get_object_section_section_id(): Invalid Object Type ('.
$object_type .
')');
if (empty($name) AND empty($value) ) {
$this->debug_text('get_object_section_section_id(): Both Name ('.
$name .
') and Value ('.
$value .
') are empty, you must specify at least one.');
$query =
'SELECT id FROM '.
$object_sections_table;
// limit by value if specified
$query .=
$where .
'value='.
$this->db->quote($value);
// only use name if asked, this is SLOW
$query .=
$where .
'name='.
$this->db->quote($name);
$rs =
$this->db->Execute($query);
$this->debug_db('get_object_section_section_id');
$row_count =
$rs->RecordCount();
// If only one row is returned
// Return only the ID in the first row.
// If more than one row is returned
// should only ever occur when using name as values are unique.
$this->debug_text('get_object_section_section_id(): Returned '.
$row_count .
' rows, can only return one. Please search by value not name, or make your names unique.');
// No rows returned, no matching section found
$this->debug_text('get_object_section_section_id(): Returned '.
$row_count .
' rows, no matching section found.');
* Inserts an object Section
* @return int Object Section ID of new section
* @param string Object Name
* @param string Object Value
* @param int Display Order
* @param int Hidden flag, hides section if 1, shows section if 0
* @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL'
$this->debug_text("add_object_section(): Value: $value Order: $order Name: $name Object Type: $object_type");
if ($order ==
NULL OR $order ==
'') {
$this->debug_text("add_object_section(): name ($name) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("add_object_section(): Object Type ($object_type) is empty, this is required");
$insert_id =
$this->db->GenID($this->_db_table_prefix.
$object_type.
'_sections_seq',10);
$query =
"insert into $object_sections_table (id,value,order_value,name,hidden) VALUES($insert_id, '$value', '$order', '$name', $hidden)";
$rs =
$this->db->Execute($query);
$this->debug_text("add_object_section(): Added object_section as ID: $insert_id");
* Edits a given Object Section
* @return bool Returns TRUE if successful, FALSE otherwise
* @param int Object Section ID #
* @param string Object Section Name
* @param string Object Section Value
* @param int Display Order
* @param int Hidden Flag, hide object section if 1, show if 0
* @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL'
function edit_object_section($object_section_id, $name, $value=
0, $order=
0, $hidden=
0, $object_type=
NULL) {
$this->debug_text('edit_object_section(): Invalid Object Type: '.
$object_type);
$this->debug_text("edit_object_section(): ID: $object_section_id Value: $value Order: $order Name: $name Object Type: $object_type");
if (empty($object_section_id) ) {
$this->debug_text("edit_object_section(): Section ID ($object_section_id) is empty, this is required");
$this->debug_text("edit_object_section(): name ($name) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("edit_object_section(): Object Type ($object_type) is empty, this is required");
$object_section_id = (int)
$object_section_id;
//Get old value incase it changed, before we do the update.
$query =
"select value from $object_sections_table where id=$object_section_id";
$old_value =
$this->db->GetOne($query);
$query =
"update $object_sections_table set
value=" .
$this->db-
quote($value) .
"',
name=" .
$this->db-
quote($name) .
",
where id=$object_section_id";
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
$this->debug_text("edit_object_section(): Modified aco_section ID: $object_section_id");
if ($old_value !=
$value) {
$this->debug_text("edit_object_section(): Value Changed, update other tables.");
$query =
"update $table set
section_value=" .
$this->db-
quote($value) .
"
where section_value = " .
$this->db-
quote($old_value);
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
if (!empty($object_map_table)) {
$query =
"update $object_map_table set
section_value=" .
$this->db-
quote($value) .
"
where section_value = " .
$this->db-
quote($old_value);
$rs =
$this->db->Execute($query);
$this->db->RollbackTrans();
$this->debug_text("edit_object_section(): Modified ojbect_map value: $value");
$this->db->CommitTrans();
//ACL sections, have no mapping table. Return true.
$this->db->CommitTrans();
$this->db->CommitTrans();
* Deletes a given Object Section and, if explicitly asked, all the section objects
* ERASE feature by: Martino Piccinato
* @return bool Returns TRUE if successful, FALSE otherwise
* @param int Object Section ID # to delete
* @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL'
* @param bool Erases all section objects assigned to the section
$this->debug_text("del_object_section(): ID: $object_section_id Object Type: $object_type, Erase all: $erase");
if (empty($object_section_id) ) {
$this->debug_text("del_object_section(): Section ID ($object_section_id) is empty, this is required");
if (empty($object_type) ) {
$this->debug_text("del_object_section(): Object Type ($object_type) is empty, this is required");
$object_section_id = (int)
$object_section_id;
// Get the value of the section
$query=
"SELECT value FROM $object_sections_table WHERE id=$object_section_id";
$section_value =
$this->db->GetOne($query);
// Get all objects ids in the section
$object_ids =
$this->get_object($section_value, 1, $object_type);
// Delete all objects in the section and for
// each object delete the referencing object
// (see del_object method)
foreach ($object_ids as $id) {
if ( $object_type ===
'acl' ) {
if($object_ids AND !$erase) {
// There are objects in the section and we
// were not asked to erase them: don't delete it
$this->debug_text("del_object_section(): Could not delete the section ($section_value) as it is not empty.");
// The section is empty (or emptied by this method)
$query =
"DELETE FROM $object_sections_table where id=$object_section_id";
$rs =
$this->db->Execute($query);
$this->debug_text("del_object_section(): deleted section ID: $object_section_id Value: $section_value");
* Deletes all data from the phpGACL tables. USE WITH CAUTION.
* @return bool Returns TRUE if successful, FALSE otherwise
// Get all the table names and loop
$tableNames =
$this->db->MetaTables('TABLES');
foreach ($tableNames as $key =>
$value){
if (in_array($value, $tablesToClear) ) {
$query[] =
'TRUNCATE TABLE '.
$value.
';';
// Loop the queries and return.
foreach ($query as $key =>
$value){
$result =
$this->db->Execute($value);
* Calculates the start number for a sequence table
* @param string The name of the table
* @return int The highest id plus one
$query =
"SELECT MAX(id) from " .
$table;
$id =
$this->db->GetOne( $query ) +
1;