3950 lines
120 KiB
PHP
3950 lines
120 KiB
PHP
|
|
<?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:
|
||
|
|
* ipso@snappymail.ca
|
||
|
|
*
|
||
|
|
* The latest version of phpGACL can be obtained from:
|
||
|
|
* http://phpgacl.sourceforge.net/
|
||
|
|
*
|
||
|
|
* @package phpGACL
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
// Check to ensure this file is within the rest of the framework
|
||
|
|
defined('JPATH_BASE') or die();
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* 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.
|
||
|
|
*
|
||
|
|
* @package phpGACL
|
||
|
|
* @author Mike Benoit <ipso@snappymail.ca>
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
class gacl_api extends gacl {
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* Misc helper functions.
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* showarray()
|
||
|
|
*
|
||
|
|
* Dump all contents of an array in HTML (kinda)
|
||
|
|
*
|
||
|
|
* @param array
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
function showarray($array) {
|
||
|
|
echo "<br><pre>\n";
|
||
|
|
var_dump($array);
|
||
|
|
echo "</pre><br>\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* count_all()
|
||
|
|
*
|
||
|
|
* 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
|
||
|
|
*/
|
||
|
|
function count_all($arg = NULL) {
|
||
|
|
switch (TRUE) {
|
||
|
|
case is_scalar($arg):
|
||
|
|
case is_object($arg):
|
||
|
|
// single object
|
||
|
|
return 1;
|
||
|
|
case is_array($arg):
|
||
|
|
// call recursively for all elements of $arg
|
||
|
|
$count = 0;
|
||
|
|
foreach ($arg as $val) {
|
||
|
|
$count += $this->count_all($val);
|
||
|
|
}
|
||
|
|
return $count;
|
||
|
|
}
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_version()
|
||
|
|
*
|
||
|
|
* Grabs phpGACL version from the database.
|
||
|
|
*
|
||
|
|
* @return string Version of phpGACL
|
||
|
|
*/
|
||
|
|
function get_version() {
|
||
|
|
$query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'version'";
|
||
|
|
$version = $this->db->GetOne($query);
|
||
|
|
|
||
|
|
return $version;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_schema_version()
|
||
|
|
*
|
||
|
|
* Grabs phpGACL schema version from the database.
|
||
|
|
*
|
||
|
|
* @return string Schema Version
|
||
|
|
*/
|
||
|
|
function get_schema_version() {
|
||
|
|
$query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'schema_version'";
|
||
|
|
$version = $this->db->GetOne($query);
|
||
|
|
|
||
|
|
return $version;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* ACL
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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");
|
||
|
|
|
||
|
|
$acl_ids = array();
|
||
|
|
|
||
|
|
if (empty($aco_section_value) ) {
|
||
|
|
$this->debug_text("consolidated_edit_acl(): ACO Section Value ($aco_section_value) is empty, this is required!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($aco_value) ) {
|
||
|
|
$this->debug_text("consolidated_edit_acl(): ACO Value ($aco_value) is empty, this is required!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($aro_section_value) ) {
|
||
|
|
$this->debug_text("consolidated_edit_acl(): ARO Section Value ($aro_section_value) is empty, this is required!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($aro_value) ) {
|
||
|
|
$this->debug_text("consolidated_edit_acl(): ARO Value ($aro_value) is empty, this is required!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($return_value) ) {
|
||
|
|
$this->debug_text("consolidated_edit_acl(): Return Value ($return_value) is empty, this is required!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//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);
|
||
|
|
|
||
|
|
if (is_array($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.");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$acl_ids[] = $current_acl_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//showarray($acl_ids);
|
||
|
|
$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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$this->debug_text("add_consolidated_acl(): Didn't find any current ACLs with a single ACO. ");
|
||
|
|
}
|
||
|
|
//unset($acl_ids);
|
||
|
|
$acl_ids = array();
|
||
|
|
unset($acl_ids_count);
|
||
|
|
|
||
|
|
//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);
|
||
|
|
|
||
|
|
if (is_array($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;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//showarray($acl_ids);
|
||
|
|
$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.");
|
||
|
|
|
||
|
|
$acl_id=$acl_ids[0];
|
||
|
|
|
||
|
|
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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_consolidated_acl(): Hot damn, ACL consolidated!");
|
||
|
|
return true;
|
||
|
|
} elseif($acl_ids_count > 1) {
|
||
|
|
$this->debug_text("add_consolidated_acl(): Found more then one ACL with a single ACO. Possible conflicting ACLs.");
|
||
|
|
return false;
|
||
|
|
} 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) ),
|
||
|
|
NULL,
|
||
|
|
NULL,
|
||
|
|
NULL,
|
||
|
|
TRUE,
|
||
|
|
TRUE,
|
||
|
|
$return_value,
|
||
|
|
NULL)
|
||
|
|
) {
|
||
|
|
$this->debug_text("add_consolidated_acl(): Error adding new ACL for ACO Section: $aco_section_value ACO Value: $aco_value Return Value: $return_value");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_consolidated_acl(): ADD_ACL() successfull, returning True.");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_consolidated_acl(): Returning false.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* search_acl()
|
||
|
|
*
|
||
|
|
* 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");
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
SELECT a.id
|
||
|
|
FROM '. $this->_db_table_prefix .'acl a';
|
||
|
|
|
||
|
|
$where_query = array();
|
||
|
|
|
||
|
|
// ACO
|
||
|
|
if ($aco_section_value !== FALSE AND $aco_value !== FALSE) {
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON a.id=ac.acl_id';
|
||
|
|
|
||
|
|
if ($aco_section_value == NULL AND $aco_value == NULL) {
|
||
|
|
$where_query[] = '(ac.section_value IS NULL AND ac.value IS NULL)';
|
||
|
|
} else {
|
||
|
|
$where_query[] = '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value='. $this->db->quote($aco_value) .')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ARO
|
||
|
|
if ($aro_section_value !== FALSE AND $aro_value !== FALSE) {
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON a.id=ar.acl_id';
|
||
|
|
|
||
|
|
if ($aro_section_value == NULL AND $aro_value == NULL) {
|
||
|
|
$where_query[] = '(ar.section_value IS NULL AND ar.value IS NULL)';
|
||
|
|
} else {
|
||
|
|
$where_query[] = '(ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value='. $this->db->quote($aro_value) .')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// AXO
|
||
|
|
if ($axo_section_value !== FALSE AND $axo_value !== FALSE) {
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON a.id=ax.acl_id';
|
||
|
|
|
||
|
|
if ($axo_section_value == NULL AND $axo_value == NULL) {
|
||
|
|
$where_query[] = '(ax.section_value IS NULL AND ax.value IS NULL)';
|
||
|
|
} else {
|
||
|
|
$where_query[] = '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value='. $this->db->quote($axo_value) .')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ARO Group
|
||
|
|
if ($aro_group_name !== FALSE) {
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aro_groups_map arg ON a.id=arg.acl_id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aro_groups rg ON arg.group_id=rg.id';
|
||
|
|
|
||
|
|
if ($aro_group_name == NULL) {
|
||
|
|
$where_query[] = '(rg.name IS NULL)';
|
||
|
|
} else {
|
||
|
|
$where_query[] = '(rg.name='. $this->db->quote($aro_group_name) .')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// AXO Group
|
||
|
|
if ($axo_group_name !== FALSE) {
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON a.id=axg.acl_id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON axg.group_id=xg.id';
|
||
|
|
|
||
|
|
if ($axo_group_name == NULL) {
|
||
|
|
$where_query[] = '(xg.name IS NULL)';
|
||
|
|
} else {
|
||
|
|
$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)';
|
||
|
|
} else {
|
||
|
|
$where_query[] = '(a.return_value='. $this->db->quote($return_value) .')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count($where_query) > 0) {
|
||
|
|
$query .= '
|
||
|
|
WHERE '. implode (' AND ', $where_query);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->db->GetCol($query);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* append_acl()
|
||
|
|
*
|
||
|
|
* Appends objects on to a specific ACL.
|
||
|
|
*
|
||
|
|
* @return bool TRUE if successful, FALSE otherwise.
|
||
|
|
*
|
||
|
|
* @param int ACL ID #
|
||
|
|
* @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");
|
||
|
|
|
||
|
|
$update = 0;
|
||
|
|
|
||
|
|
if (empty($acl_id)) {
|
||
|
|
$this->debug_text("append_acl(): No ACL_ID specified! ACL_ID: $acl_id");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Grab ACL data.
|
||
|
|
$acl_array = &$this->get_acl($acl_id);
|
||
|
|
|
||
|
|
//Append each object type seperately.
|
||
|
|
if (is_array($aro_array) AND count($aro_array) > 0) {
|
||
|
|
$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;
|
||
|
|
$update=1;
|
||
|
|
} else {
|
||
|
|
$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;
|
||
|
|
$update = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) {
|
||
|
|
$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;
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($axo_array) AND count($axo_array) > 0) {
|
||
|
|
$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;
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("append_acl(): Duplicate AXO, ignoring... ");
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) {
|
||
|
|
$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;
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... ");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($aco_array) AND count($aco_array) > 0) {
|
||
|
|
$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;
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("append_acl(): Duplicate ACO, ignoring... ");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($update == 1) {
|
||
|
|
$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.");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* shift_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 int ACL ID #
|
||
|
|
* @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");
|
||
|
|
|
||
|
|
$update = 0;
|
||
|
|
|
||
|
|
if (empty($acl_id)) {
|
||
|
|
$this->debug_text("shift_acl(): No ACL_ID specified! ACL_ID: $acl_id");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Grab ACL data.
|
||
|
|
$acl_array = &$this->get_acl($acl_id);
|
||
|
|
|
||
|
|
//showarray($acl_array);
|
||
|
|
//Remove each object type seperately.
|
||
|
|
if (is_array($aro_array) AND count($aro_array) > 0) {
|
||
|
|
$this->debug_text("shift_acl(): Removing ARO's");
|
||
|
|
|
||
|
|
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]);
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("shift_acl(): ARO doesn't exist, can't remove it.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) {
|
||
|
|
$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]);
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("shift_acl(): ARO Group doesn't exist, can't remove it.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($axo_array) AND count($axo_array) > 0) {
|
||
|
|
$this->debug_text("shift_acl(): Removing AXO's");
|
||
|
|
|
||
|
|
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]);
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("shift_acl(): AXO doesn't exist, can't remove it.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) {
|
||
|
|
$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]);
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("shift_acl(): AXO Group doesn't exist, can't remove it.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (is_array($aco_array) AND count($aco_array) > 0) {
|
||
|
|
$this->debug_text("shift_acl(): Removing ACO's");
|
||
|
|
|
||
|
|
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]);
|
||
|
|
$update = 1;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("shift_acl(): ACO doesn't exist, can't remove it.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($update == 1) {
|
||
|
|
//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);
|
||
|
|
$this->debug_text("shift_acl(): ACOs: ". $this->count_all($acl_array['aco']) ." AROs: ".$this->count_all($acl_array['aro'])."");
|
||
|
|
|
||
|
|
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.");
|
||
|
|
|
||
|
|
return $this->del_acl($acl_id);
|
||
|
|
}
|
||
|
|
|
||
|
|
$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 true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_acl()
|
||
|
|
*
|
||
|
|
* Grabs ACL data.
|
||
|
|
*
|
||
|
|
* @return mixed bool FALSE if not found, or 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
|
||
|
|
*
|
||
|
|
* @param int ACL ID #
|
||
|
|
*/
|
||
|
|
function get_acl($acl_id) {
|
||
|
|
|
||
|
|
$this->debug_text("get_acl(): ACL_ID: $acl_id");
|
||
|
|
|
||
|
|
if (empty($acl_id)) {
|
||
|
|
$this->debug_text("get_acl(): No ACL_ID specified! ACL_ID: $acl_id");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
$acl_id = (int) $acl_id;
|
||
|
|
|
||
|
|
//Grab ACL information
|
||
|
|
$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
|
||
|
|
if (!$acl_row) {
|
||
|
|
$this->debug_text("get_acl(): No ACL found for that ID! ACL_ID: $acl_id");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
list($retarr['acl_id'], $retarr['allow'], $retarr['enabled'], $retarr['return_value'], $retarr['note']) = $acl_row;
|
||
|
|
|
||
|
|
//Grab selected ACO's
|
||
|
|
$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
|
||
|
|
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);
|
||
|
|
$rows = $rs->GetRows();
|
||
|
|
|
||
|
|
$retarr['aco'] = array();
|
||
|
|
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;
|
||
|
|
|
||
|
|
}
|
||
|
|
//showarray($aco);
|
||
|
|
|
||
|
|
//Grab selected ARO's
|
||
|
|
$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
|
||
|
|
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);
|
||
|
|
$rows = $rs->GetRows();
|
||
|
|
|
||
|
|
$retarr['aro'] = array();
|
||
|
|
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);
|
||
|
|
|
||
|
|
//Grab selected AXO's
|
||
|
|
$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
|
||
|
|
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);
|
||
|
|
$rows = $rs->GetRows();
|
||
|
|
|
||
|
|
$retarr['axo'] = array();
|
||
|
|
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.
|
||
|
|
$retarr['aro_groups'] = array();
|
||
|
|
$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.
|
||
|
|
$retarr['axo_groups'] = array();
|
||
|
|
$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);
|
||
|
|
|
||
|
|
return $retarr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* is_conflicting_acl()
|
||
|
|
*
|
||
|
|
* 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.
|
||
|
|
|
||
|
|
if (!is_array($aco_array)) {
|
||
|
|
$this->debug_text('is_conflicting_acl(): Invalid ACO Array.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!is_array($aro_array)) {
|
||
|
|
$this->debug_text('is_conflicting_acl(): Invalid ARO Array.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
SELECT a.id
|
||
|
|
FROM '. $this->_db_table_prefix .'acl a
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON ac.acl_id=a.id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON ar.acl_id=a.id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON ax.acl_id=a.id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON axg.acl_id=a.id
|
||
|
|
LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON xg.id=axg.group_id
|
||
|
|
';
|
||
|
|
|
||
|
|
//ACO
|
||
|
|
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");
|
||
|
|
//showarray($aco_array);
|
||
|
|
|
||
|
|
if (!is_array($aco_value_array)) {
|
||
|
|
$this->debug_text('is_conflicting_acl(): Invalid Format for ACO Array item. Skipping...');
|
||
|
|
continue;
|
||
|
|
// return TRUE;
|
||
|
|
}
|
||
|
|
//Move the below line in to the LEFT JOIN above for PostgreSQL sake.
|
||
|
|
//'ac1' => 'ac.acl_id=a.id',
|
||
|
|
$where_query = array(
|
||
|
|
'ac2' => '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value IN (\''. implode ('\',\'', $aco_value_array) .'\'))'
|
||
|
|
);
|
||
|
|
|
||
|
|
//ARO
|
||
|
|
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");
|
||
|
|
|
||
|
|
if (!is_array($aro_value_array))
|
||
|
|
{
|
||
|
|
$this->debug_text('is_conflicting_acl(): Invalid Format for ARO Array item. Skipping...');
|
||
|
|
continue;
|
||
|
|
// return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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) .'\'))';
|
||
|
|
|
||
|
|
if (is_array($axo_array) AND count($axo_array) > 0) {
|
||
|
|
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");
|
||
|
|
|
||
|
|
if (!is_array($axo_value_array)) {
|
||
|
|
$this->debug_text('is_conflicting_acl(): Invalid Format for AXO Array item. Skipping...');
|
||
|
|
continue;
|
||
|
|
// return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (is_array($ignore_acl_ids)) {
|
||
|
|
$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)");
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (is_array($ignore_acl_ids)) {
|
||
|
|
$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)");
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text('is_conflicting_acl(): No conflicting ACL found.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add_acl()
|
||
|
|
*
|
||
|
|
* 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 Allow flag
|
||
|
|
* @param int Enabled flag
|
||
|
|
* @param string Return Value
|
||
|
|
* @param string Note
|
||
|
|
* @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 ) {
|
||
|
|
|
||
|
|
$this->debug_text("add_acl():");
|
||
|
|
|
||
|
|
if (count($aco_array) == 0) {
|
||
|
|
$this->debug_text("Must select at least one Access Control Object");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (count($aro_array) == 0 AND count($aro_group_ids) == 0) {
|
||
|
|
$this->debug_text("Must select at least one Access Request Object or Group");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($allow)) {
|
||
|
|
$allow=0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($enabled)) {
|
||
|
|
$enabled=0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($section_value)
|
||
|
|
AND !$this->get_object_section_section_id(NULL, $section_value, 'ACL')) {
|
||
|
|
$this->debug_text("add_acl(): Section Value: $section_value DOES NOT exist in the database.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Unique the group arrays. Later one we unique ACO/ARO/AXO arrays.
|
||
|
|
if (is_array($aro_group_ids)) {
|
||
|
|
$aro_group_ids = array_unique($aro_group_ids);
|
||
|
|
}
|
||
|
|
if (is_array($axo_group_ids)) {
|
||
|
|
$axo_group_ids = array_unique($axo_group_ids);
|
||
|
|
}
|
||
|
|
|
||
|
|
//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!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//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) ) {
|
||
|
|
$section_value='system';
|
||
|
|
if( !$this->get_object_section_section_id(NULL, $section_value, 'ACL') ) {
|
||
|
|
// Use the acl section with the lowest order value.
|
||
|
|
$acl_sections_table = $this->_db_table_prefix .'acl_sections';
|
||
|
|
$acl_section_order_value = $this->db->GetOne("SELECT min(order_value) from $acl_sections_table");
|
||
|
|
|
||
|
|
$query = "
|
||
|
|
SELECT 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.");
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("add_acl(): Using default section value: $section_value.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//ACL not specified, so create acl_id
|
||
|
|
if (empty($acl_id)) {
|
||
|
|
//Create ACL row first, so we have the acl_id
|
||
|
|
$acl_id = $this->db->GenID($this->_db_table_prefix.'acl_seq',10);
|
||
|
|
|
||
|
|
//Double check the ACL ID was generated.
|
||
|
|
if (empty($acl_id)) {
|
||
|
|
// Not Required in Joomla! (yet)
|
||
|
|
//$this->debug_text("add_acl(): ACL_ID generation failed!");
|
||
|
|
//return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//Begin transaction _after_ GenID. Because on the first run, if GenID has to create the sequence,
|
||
|
|
//the transaction will fail.
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
// Joomla/MySQL
|
||
|
|
$acl_id = $this->db->insertid();
|
||
|
|
} else {
|
||
|
|
$section_sql = '';
|
||
|
|
if ( !empty($section_value) ) {
|
||
|
|
$section_sql = 'section_value='. $this->db->quote ($section_value) .',';
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
//Update ACL row, and remove all mappings so they can be re-inserted.
|
||
|
|
$query = '
|
||
|
|
UPDATE '. $this->_db_table_prefix .'acl
|
||
|
|
SET ' . $section_sql . '
|
||
|
|
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);
|
||
|
|
|
||
|
|
if ($result) {
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs))
|
||
|
|
{
|
||
|
|
$this->debug_db('add_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!is_object($result)) {
|
||
|
|
$this->debug_db('add_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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'};
|
||
|
|
|
||
|
|
if (!is_array ($map_array)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($map_array as $section_value => $value_array) {
|
||
|
|
$this->debug_text ('Insert: '. strtoupper($map) .' Section Value: '. $section_value .' '. strtoupper($map) .' VALUE: '. $value_array);
|
||
|
|
// $this->showarray ($aco_value_array);
|
||
|
|
|
||
|
|
if (!is_array($value_array)) {
|
||
|
|
$this->debug_text ('add_acl (): Invalid Format for '. strtoupper ($map) .' Array item. Skipping...');
|
||
|
|
continue;
|
||
|
|
// return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$value_array = array_unique($value_array);
|
||
|
|
|
||
|
|
foreach ($value_array as $value) {
|
||
|
|
$object_id = &$this->get_object_id($section_value, $value, $map);
|
||
|
|
|
||
|
|
if (empty($object_id))
|
||
|
|
{
|
||
|
|
$this->debug_text('add_acl(): '. strtoupper($map) . " Object Section Value: $section_value Value: $value DOES NOT exist in the database. Skipping...");
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs))
|
||
|
|
{
|
||
|
|
$this->debug_db('add_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Insert ARO/AXO GROUP mappings
|
||
|
|
foreach (array('aro', 'axo') as $map) {
|
||
|
|
$map_group_ids = ${$map .'_group_ids'};
|
||
|
|
|
||
|
|
if (!is_array($map_group_ids)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($map_group_ids as $group_id) {
|
||
|
|
$this->debug_text ('Insert: '. strtoupper($map) .' GROUP ID: '. $group_id);
|
||
|
|
|
||
|
|
$group_data = &$this->get_group_data($group_id, $map);
|
||
|
|
|
||
|
|
if (empty($group_data)) {
|
||
|
|
$this->debug_text('add_acl(): '. strtoupper($map) . " Group: $group_id DOES NOT exist in the database. Skipping...");
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
//Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
//Return only the ID in the first row.
|
||
|
|
return $acl_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* edit_acl()
|
||
|
|
*
|
||
|
|
* Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
|
||
|
|
*
|
||
|
|
* @return bool Return TRUE 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 Allow flag
|
||
|
|
* @param int Enabled flag
|
||
|
|
* @param string Return Value
|
||
|
|
* @param string Note
|
||
|
|
* @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():");
|
||
|
|
|
||
|
|
if (empty($acl_id) ) {
|
||
|
|
$this->debug_text("edit_acl(): Must specify a single ACL_ID to edit");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (count($aco_array) == 0) {
|
||
|
|
$this->debug_text("edit_acl(): Must select at least one Access Control Object");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($allow)) {
|
||
|
|
$allow=0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($enabled)) {
|
||
|
|
$enabled=0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//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)) {
|
||
|
|
return true;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("edit_acl(): error in add_acl()");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* del_acl()
|
||
|
|
*
|
||
|
|
* Deletes a given ACL
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise.
|
||
|
|
*
|
||
|
|
* @param int ACL ID # to delete
|
||
|
|
*/
|
||
|
|
function del_acl($acl_id) {
|
||
|
|
|
||
|
|
$this->debug_text("del_acl(): ID: $acl_id");
|
||
|
|
|
||
|
|
if (empty($acl_id) ) {
|
||
|
|
$this->debug_text("del_acl(): ACL_ID ($acl_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('del_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Delete the ACL
|
||
|
|
$query = 'DELETE FROM '. $this->_db_table_prefix .'acl WHERE id='. (int) $acl_id;
|
||
|
|
$this->debug_text('delete query: '. $query);
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('del_acl');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("del_acl(): deleted ACL ID: $acl_id");
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
//Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* Groups
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* sort_groups()
|
||
|
|
*
|
||
|
|
* 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'
|
||
|
|
*/
|
||
|
|
function sort_groups($group_type='ARO') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Grab all groups from the database.
|
||
|
|
$query = 'SELECT id, parent_id, name FROM '. $table .' ORDER BY parent_id, name';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('sort_groups');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Save groups in an array sorted by parent. Should be make it easier for later on.
|
||
|
|
*/
|
||
|
|
$sorted_groups = array();
|
||
|
|
|
||
|
|
while ($row = $rs->FetchRow()) {
|
||
|
|
$id = &$row[0];
|
||
|
|
$parent_id = &$row[1];
|
||
|
|
$name = &$row[2];
|
||
|
|
|
||
|
|
$sorted_groups[$parent_id][$id] = $name;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $sorted_groups;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* format_groups()
|
||
|
|
*
|
||
|
|
* 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) {
|
||
|
|
|
||
|
|
if ( !is_array ($sorted_groups) ) {
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( !is_array ($formatted_groups) ) {
|
||
|
|
$formatted_groups = array ();
|
||
|
|
}
|
||
|
|
|
||
|
|
$type = strtoupper($type);
|
||
|
|
|
||
|
|
//$this->showarray($formatted_groups);
|
||
|
|
|
||
|
|
//while (list($id,$name) = @each($sorted_groups[$root_id])) {
|
||
|
|
if (isset($sorted_groups[$root_id])) {
|
||
|
|
$temp = array_keys( $sorted_groups[$root_id] );
|
||
|
|
$last_id = end( $temp );
|
||
|
|
|
||
|
|
foreach ($sorted_groups[$root_id] as $id => $name) {
|
||
|
|
switch ($type) {
|
||
|
|
case 'TEXT':
|
||
|
|
case 'TEXT_ASSOC':
|
||
|
|
/*
|
||
|
|
* Formatting optimized for TEXT (combo box) output.
|
||
|
|
*/
|
||
|
|
|
||
|
|
if ( is_numeric($level) ) {
|
||
|
|
$level = str_repeat(' ', $level);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strlen($level) >= 8 ) {
|
||
|
|
if ( $id == $last_id ) {
|
||
|
|
$spacing = substr($level, 0, -8) .'\'- ';
|
||
|
|
$level = substr($level, 0, -8) .' ';
|
||
|
|
} else {
|
||
|
|
$spacing = substr($level, 0, -8) .'|- ';
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$spacing = $level;
|
||
|
|
}
|
||
|
|
|
||
|
|
$next = $level .'| ';
|
||
|
|
|
||
|
|
if ($type == 'TEXT_ASSOC') {
|
||
|
|
$formatted_groups[] = array( 'value'=>$id, 'text'=>$spacing.$name );
|
||
|
|
} else {
|
||
|
|
$formatted_groups[$id] = $spacing.$name;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 'HTML':
|
||
|
|
/*
|
||
|
|
* Formatting optimized for HTML (tables) output.
|
||
|
|
*/
|
||
|
|
$width = $level * 12;
|
||
|
|
$spacing = "<img src=\"images/blank.png\" width=\"$width\" height=\"0\" alt=\"\" />";
|
||
|
|
$next = $level + 1;
|
||
|
|
$formatted_groups[$id] = $spacing." ".$name;
|
||
|
|
break;
|
||
|
|
case 'ARRAY':
|
||
|
|
$next = $level;
|
||
|
|
$formatted_groups[$id] = $name;
|
||
|
|
break;
|
||
|
|
case 'ASSOC':
|
||
|
|
/*
|
||
|
|
* Formatting optimized for HTML: <option value="value">text</option>.
|
||
|
|
*/
|
||
|
|
$next = $level;
|
||
|
|
$formatted_groups[] = array( 'value'=>$id, 'text'=>$name, 'level'=>$level );
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Recurse if we can.
|
||
|
|
*/
|
||
|
|
|
||
|
|
//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);
|
||
|
|
} else {
|
||
|
|
//$this->debug_text("format_groups(): Found last branch!");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//$this->debug_text("format_groups(): Returning final array.");
|
||
|
|
|
||
|
|
return $formatted_groups;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_group_id()
|
||
|
|
*
|
||
|
|
* 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'
|
||
|
|
*/
|
||
|
|
function get_group_id($value = NULL, $name = NULL, $group_type = 'ARO') {
|
||
|
|
|
||
|
|
$this->debug_text("get_group_id(): Value: $value, Name: $name, Type: $group_type" );
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
|
||
|
|
if (empty($name) AND $value === '') {
|
||
|
|
$this->debug_text("get_group_id(): name and value, at least one is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $table .' WHERE ';
|
||
|
|
if ($value !== '') {
|
||
|
|
$query .= ' value='. $this->db->quote($value);
|
||
|
|
} else {
|
||
|
|
$query .= ' name='. $this->db->quote($name);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->setQuery( $query );
|
||
|
|
|
||
|
|
$rows = $this->db->loadResultArray();
|
||
|
|
if ($this->db->getErrorNum()) {
|
||
|
|
$this->debug_db('get_group_id');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = count( $rows );
|
||
|
|
|
||
|
|
if ($row_count > 1) {
|
||
|
|
$this->debug_text("get_group_id(): Returned $row_count rows, can only return one. Please make your names unique.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($row_count == 0) {
|
||
|
|
$this->debug_text("get_group_id(): Returned $row_count rows");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Return the ID.
|
||
|
|
return $rows[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_group_children()
|
||
|
|
*
|
||
|
|
* Gets a groups child IDs
|
||
|
|
*
|
||
|
|
* @return array Array of Child ID's of the referenced group
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @param int Group Type, either 'ARO' or 'AXO'
|
||
|
|
* @param string Either 'RECURSE' or 'NO_RECURSE', to recurse while fetching group children.
|
||
|
|
*/
|
||
|
|
function get_group_children($group_id, $group_type = 'ARO', $recurse = 'NO_RECURSE') {
|
||
|
|
$this->debug_text("get_group_children(): Group_ID: $group_id Group Type: $group_type Recurse: $recurse");
|
||
|
|
|
||
|
|
switch (strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($group_id)) {
|
||
|
|
$this->debug_text("get_group_children(): ID ($group_id) is empty, this is required");
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
SELECT g1.id
|
||
|
|
FROM '. $table .' g1';
|
||
|
|
|
||
|
|
//FIXME-mikeb: Why is group_id in quotes?
|
||
|
|
switch (strtoupper($recurse)) {
|
||
|
|
case 'RECURSE':
|
||
|
|
$query .= '
|
||
|
|
LEFT JOIN '. $table .' g2 ON g2.lft<g1.lft AND g2.rgt>g1.rgt
|
||
|
|
WHERE g2.id='. (int) $group_id;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$query .= '
|
||
|
|
WHERE g1.parent_id='. (int) $group_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query .= '
|
||
|
|
ORDER BY g1.value';
|
||
|
|
|
||
|
|
return $this->db->GetCol($query);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_group_data()
|
||
|
|
*
|
||
|
|
* 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 int Group ID #
|
||
|
|
* @param string Group Type, either 'ARO' or 'AXO'
|
||
|
|
*/
|
||
|
|
function get_group_data($group_id, $group_type = 'ARO') {
|
||
|
|
|
||
|
|
$this->debug_text("get_group_data(): Group_ID: $group_id Group Type: $group_type");
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($group_id) ) {
|
||
|
|
$this->debug_text("get_group_data(): ID ($group_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if ($row) {
|
||
|
|
return $row;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_object_data(): Group does not exist.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_group_parent_id()
|
||
|
|
*
|
||
|
|
* Grabs the parent_id of a given group
|
||
|
|
*
|
||
|
|
* @return int Parent ID of the Group
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @param string Group Type, either 'ARO' or 'AXO'
|
||
|
|
*/
|
||
|
|
function get_group_parent_id($id, $group_type='ARO') {
|
||
|
|
|
||
|
|
$this->debug_text("get_group_parent_id(): ID: $id Group Type: $group_type");
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($id) ) {
|
||
|
|
$this->debug_text("get_group_parent_id(): ID ($id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT parent_id FROM '. $table .' WHERE id='. (int) $id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_group_parent_id');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = $rs->RecordCount();
|
||
|
|
|
||
|
|
if ($row_count > 1) {
|
||
|
|
$this->debug_text("get_group_parent_id(): Returned $row_count rows, can only return one. Please make your names unique.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($row_count == 0) {
|
||
|
|
$this->debug_text("get_group_parent_id(): Returned $row_count rows");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
|
||
|
|
//Return the ID.
|
||
|
|
return $row[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_root_group_id ()
|
||
|
|
*
|
||
|
|
* Grabs the id of the root group for the specified tree
|
||
|
|
*
|
||
|
|
* @return int Root Group ID #
|
||
|
|
*
|
||
|
|
* @param string Group Type, either 'ARO' or 'AXO'
|
||
|
|
*/
|
||
|
|
function get_root_group_id($group_type='ARO') {
|
||
|
|
|
||
|
|
$this->debug_text('get_root_group_id(): Group Type: '. $group_type);
|
||
|
|
|
||
|
|
switch (strtolower($group_type)) {
|
||
|
|
case 'axo':
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_root_group_id(): Invalid Group Type: '. $group_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $table .' WHERE parent_id=0';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_root_group_id');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = $rs->RecordCount();
|
||
|
|
|
||
|
|
switch ($row_count) {
|
||
|
|
case 1:
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
// Return the ID.
|
||
|
|
return $row[0];
|
||
|
|
case 0:
|
||
|
|
$this->debug_text('get_root_group_id(): Returned 0 rows, you do not have a root group defined yet.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text('get_root_group_id(): Returned '. $row_count .' rows, can only return one. Your tree is very broken.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*======================================================================*\
|
||
|
|
Function: map_path_to_root()
|
||
|
|
Purpose: Maps a unique path to root to a specific group. Each group can only have
|
||
|
|
one path to root.
|
||
|
|
\*======================================================================*/
|
||
|
|
/** REMOVED **/
|
||
|
|
/*======================================================================*\
|
||
|
|
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.
|
||
|
|
\*======================================================================*/
|
||
|
|
/** REMOVED **/
|
||
|
|
/*======================================================================*\
|
||
|
|
Function: clean_path_to_root()
|
||
|
|
Purpose: Cleans up any paths that are not being used.
|
||
|
|
\*======================================================================*/
|
||
|
|
/** REMOVED **/
|
||
|
|
/*======================================================================*\
|
||
|
|
Function: get_path_to_root()
|
||
|
|
Purpose: Generates the path to root for a given group.
|
||
|
|
\*======================================================================*/
|
||
|
|
/** REMOVED **/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add_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') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_group(): Name: $name Value: $value Parent ID: $parent_id Group Type: $group_type");
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
|
||
|
|
if ( $name == '' ) {
|
||
|
|
$this->debug_text("add_group(): name ($name) OR parent id ($parent_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//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 ));
|
||
|
|
if ( $value === '' ) {
|
||
|
|
$value = $insert_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
// special case for root group
|
||
|
|
if ($parent_id == 0) {
|
||
|
|
// check a root group is not already defined
|
||
|
|
$query = 'SELECT id FROM '. $table .' WHERE parent_id=0';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($rs->RowCount() > 0) {
|
||
|
|
$this->debug_text('add_group (): A root group already exists.');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$parent_lft = 0;
|
||
|
|
$parent_rgt = 1;
|
||
|
|
} else {
|
||
|
|
if (empty($parent_id)) {
|
||
|
|
$this->debug_text("add_group (): parent id ($parent_id) is empty, this is required");
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// grab parent details from database
|
||
|
|
$query = 'SELECT id, lft, rgt FROM '. $table .' WHERE id='. (int) $parent_id;
|
||
|
|
$row = $this->db->GetRow($query);
|
||
|
|
|
||
|
|
if (!is_array($row)) {
|
||
|
|
$this->debug_db('add_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($row)) {
|
||
|
|
$this->debug_text('add_group (): Parent ID: '. $parent_id .' not found.');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$parent_lft = &$row[1];
|
||
|
|
$parent_rgt = &$row[2];
|
||
|
|
|
||
|
|
// make room for the new group
|
||
|
|
$query = 'UPDATE '. $table .' SET rgt=rgt+2 WHERE rgt>='. (int) $parent_rgt;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'UPDATE '. $table .' SET lft=lft+2 WHERE lft>'. $parent_rgt;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
// Joomla/MySQL
|
||
|
|
$insert_id = $this->db->insertid();
|
||
|
|
|
||
|
|
$this->debug_text('add_group (): Added group as ID: '. $insert_id);
|
||
|
|
return $insert_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_group_objects()
|
||
|
|
*
|
||
|
|
* 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 int Group ID #
|
||
|
|
* @param string Group Type, either 'ARO' or 'AXO'
|
||
|
|
* @param string Option, either 'RECURSE' or 'NO_RECURSE'
|
||
|
|
*/
|
||
|
|
function get_group_objects($group_id, $group_type='ARO', $option='NO_RECURSE') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$object_table = $this->_db_table_prefix .'axo';
|
||
|
|
$group_table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
$map_table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$object_table = $this->_db_table_prefix .'aro';
|
||
|
|
$group_table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
$map_table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_group_objects(): Group ID: $group_id");
|
||
|
|
|
||
|
|
if (empty($group_id)) {
|
||
|
|
$this->debug_text("get_group_objects(): Group ID: ($group_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
SELECT o.section_value,o.value';
|
||
|
|
|
||
|
|
if ($option == 'RECURSE') {
|
||
|
|
$query .= '
|
||
|
|
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;
|
||
|
|
} else {
|
||
|
|
$query .= '
|
||
|
|
FROM '. $map_table .' AS gm
|
||
|
|
JOIN '. $object_table .' AS o ON o.id=gm.'. $group_type .'_id
|
||
|
|
WHERE gm.group_id='. (int) $group_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_group_objects');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_group_objects(): Got group objects, formatting array.");
|
||
|
|
|
||
|
|
$retarr = array();
|
||
|
|
|
||
|
|
//format return array.
|
||
|
|
while ($row = $rs->FetchRow()) {
|
||
|
|
$section = &$row[0];
|
||
|
|
$value = &$row[1];
|
||
|
|
|
||
|
|
$retarr[$section][] = $value;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $retarr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add_group_object()
|
||
|
|
*
|
||
|
|
* Assigns an Object to a group
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise.
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @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') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
$object_table = $this->_db_table_prefix .'axo';
|
||
|
|
$group_table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
$object_table = $this->_db_table_prefix .'aro';
|
||
|
|
$group_table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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 $object_value === '' OR $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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// test to see if object & group exist and if object is already a member
|
||
|
|
$query = '
|
||
|
|
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 (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group_object');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
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?');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
|
||
|
|
if ($row[1] != $group_id) {
|
||
|
|
$this->debug_text('add_group_object(): Group ID ('. $group_id .') is invalid. Does this group exist?');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Group_ID == Member
|
||
|
|
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.
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$object_id = $row[0];
|
||
|
|
|
||
|
|
$query = 'INSERT INTO '. $table .' (group_id,'. $group_type .'_id) VALUES ('. (int) $group_id .','. (int) $object_id .')';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_group_object');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text('add_group_object(): Added Object: '. $object_id .' to Group ID: '. $group_id);
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
//Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* del_group_object()
|
||
|
|
*
|
||
|
|
* Removes an Object from a group.
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @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') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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 $object_value === '' OR $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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
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?");
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id .' AND '. $group_type .'_id='. (int) $object_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('del_group_object');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("del_group_object(): Deleted Value: $object_value to Group ID: $group_id assignment");
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
//Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* edit_group()
|
||
|
|
*
|
||
|
|
* Edits a group
|
||
|
|
*
|
||
|
|
* @returns bool Returns TRUE if successful, FALSE otherwise
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @param string Group Value
|
||
|
|
* @param string Group Name
|
||
|
|
* @param int Parent ID #
|
||
|
|
* @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");
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($group_id) ) {
|
||
|
|
$this->debug_text('edit_group(): Group ID ('. $group_id .') is empty, this is required');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( !is_array($curr = $this->get_group_data($group_id, $group_type)) ) {
|
||
|
|
$this->debug_text('edit_group(): Invalid Group ID: '. $group_id);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
|
||
|
|
// don't set name if it is unchanged
|
||
|
|
if ($name == $curr[3]) {
|
||
|
|
unset($name);
|
||
|
|
}
|
||
|
|
|
||
|
|
// don't set parent_id if it is unchanged
|
||
|
|
if ($parent_id == $curr[1]) {
|
||
|
|
unset($parent_id);
|
||
|
|
}
|
||
|
|
|
||
|
|
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. ;)');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Make sure we don't re-parent to our own children.
|
||
|
|
//Grab all children of this group_id.
|
||
|
|
$children_ids = $this->get_group_children($group_id, $group_type, 'RECURSE');
|
||
|
|
if (is_array($children_ids)) {
|
||
|
|
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!');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
unset($children_ids);
|
||
|
|
|
||
|
|
// make sure parent exists
|
||
|
|
if (!$this->get_group_data($parent_id, $group_type)) {
|
||
|
|
$this->debug_text('edit_group(): Parent Group ('. $parent_id .') doesn\'t exist');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$set = array();
|
||
|
|
|
||
|
|
// update name if it is specified.
|
||
|
|
if (!empty($name)) {
|
||
|
|
$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.
|
||
|
|
if ($value !== '' OR $value !== null) {
|
||
|
|
$set[] = 'value='. $this->db->quote($value);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($set)) {
|
||
|
|
$this->debug_text('edit_group(): Nothing to update.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
$query = 'UPDATE '. $table .' SET '. implode(',', $set) .' WHERE id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_group');
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text('edit_group(): Modified group ID: '. $group_id);
|
||
|
|
|
||
|
|
// rebuild group tree if parent_id has changed
|
||
|
|
if (!empty($parent_id)) {
|
||
|
|
if (!$this->_rebuild_tree($table, $this->get_root_group_id($group_type))) {
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
// Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* rebuild_tree ()
|
||
|
|
*
|
||
|
|
* 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 Group ID #
|
||
|
|
* @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");
|
||
|
|
|
||
|
|
switch (strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isset($group_id)) {
|
||
|
|
if ($group_id = $this->get_root_group_id($group_type)) {
|
||
|
|
$left = 1;
|
||
|
|
$this->debug_text('rebuild_tree(): No Group ID Specified, using Root Group ID: '. $group_id);
|
||
|
|
} else {
|
||
|
|
$this->debug_text('rebuild_tree(): A Root group could not be found, are there any groups defined?');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
$rebuilt = $this->_rebuild_tree($table, $group_id, $left);
|
||
|
|
|
||
|
|
if ($rebuilt === FALSE) {
|
||
|
|
$this->debug_text('rebuild_tree(): Error rebuilding tree!');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
$this->debug_text('rebuild_tree(): Tree rebuilt.');
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* _rebuild_tree ()
|
||
|
|
*
|
||
|
|
* 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 Group ID #
|
||
|
|
* @param int Left value of Group
|
||
|
|
*/
|
||
|
|
function _rebuild_tree($table, $group_id, $left = 1) {
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('_rebuild_tree');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// the right value of this node is the left value + 1
|
||
|
|
$right = $left + 1;
|
||
|
|
|
||
|
|
while ($row = $rs->FetchRow()) {
|
||
|
|
// recursive execution of this function for each
|
||
|
|
// child of this node
|
||
|
|
// $right is the current right value, which is
|
||
|
|
// incremented by the rebuild_tree function
|
||
|
|
$right = $this->_rebuild_tree($table, $row[0], $right);
|
||
|
|
|
||
|
|
if ($right === FALSE) {
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('_rebuild_tree');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// return the right value of this node + 1
|
||
|
|
return $right + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* del_group()
|
||
|
|
*
|
||
|
|
* deletes a given group
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise.
|
||
|
|
*
|
||
|
|
* @param int Group ID #
|
||
|
|
* @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') {
|
||
|
|
|
||
|
|
switch(strtolower(trim($group_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$group_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
$groups_map_table = $this->_db_table_prefix .'axo_groups_map';
|
||
|
|
$groups_object_map_table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$group_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
$groups_map_table = $this->_db_table_prefix .'aro_groups_map';
|
||
|
|
$groups_object_map_table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("del_group(): ID: $group_id Reparent Children: $reparent_children Group Type: $group_type");
|
||
|
|
|
||
|
|
if (empty($group_id) ) {
|
||
|
|
$this->debug_text("del_group(): Group ID ($group_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_array($group_details)) {
|
||
|
|
$this->debug_db('del_group');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$parent_id = $group_details[1];
|
||
|
|
|
||
|
|
$left = $group_details[3];
|
||
|
|
$right = $group_details[4];
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
// grab list of all children
|
||
|
|
$children_ids = $this->get_group_children($group_id, $group_type, 'RECURSE');
|
||
|
|
|
||
|
|
// prevent deletion of root group & reparent of children if it has more than one immediate child
|
||
|
|
if ($parent_id == 0) {
|
||
|
|
$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();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = FALSE;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Handle children here.
|
||
|
|
*/
|
||
|
|
switch (TRUE) {
|
||
|
|
// there are no child groups, just delete group
|
||
|
|
case !is_array($children_ids):
|
||
|
|
case count($children_ids) == 0:
|
||
|
|
// remove acl maps
|
||
|
|
$query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove group object maps
|
||
|
|
$query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove group
|
||
|
|
$query = 'DELETE FROM '. $table .' WHERE id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'UPDATE '. $table .' SET rgt=rgt-'. (int)($right-$left+1) .' WHERE rgt>'. (int) $right;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = TRUE;
|
||
|
|
break;
|
||
|
|
case $reparent_children == TRUE:
|
||
|
|
// remove acl maps
|
||
|
|
$query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove group object maps
|
||
|
|
$query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove group
|
||
|
|
$query = 'DELETE FROM '. $table .' WHERE id='. (int) $group_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'UPDATE '. $table .' SET rgt=rgt-2 WHERE rgt>'. (int) $right;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = TRUE;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
// make list of group and all children
|
||
|
|
$group_ids = $children_ids;
|
||
|
|
$group_ids[] = (int) $group_id;
|
||
|
|
|
||
|
|
// remove acl maps
|
||
|
|
$query = 'DELETE FROM '. $groups_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove group object maps
|
||
|
|
$query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove groups
|
||
|
|
$query = 'DELETE FROM '. $table .' WHERE id IN ('. implode (',', $group_ids) .')';
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'UPDATE '. $table .' SET rgt=rgt-'. ($right - $left + 1) .' WHERE rgt>'. (int) $right;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$success = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// if the delete failed, rollback the trans and return false
|
||
|
|
if (!$success) {
|
||
|
|
|
||
|
|
$this->debug_db('del_group');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("del_group(): deleted group ID: $group_id");
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) {
|
||
|
|
//Expire all cache.
|
||
|
|
$this->Cache_Lite->clean('default');
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* Objects (ACO/ARO/AXO)
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_object()
|
||
|
|
*
|
||
|
|
* 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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
case 'acl':
|
||
|
|
$object_type = 'acl';
|
||
|
|
$table = $this->_db_table_prefix .'acl';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_object(): Section Value: $section_value Object Type: $object_type");
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $table;
|
||
|
|
|
||
|
|
$where = array();
|
||
|
|
|
||
|
|
if (!empty($section_value)) {
|
||
|
|
$where[] = 'section_value='. $this->db->quote($section_value);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($return_hidden==0 AND $object_type != 'acl') {
|
||
|
|
$where[] = 'hidden=0';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($where)) {
|
||
|
|
$query .= ' WHERE '. implode(' AND ', $where);
|
||
|
|
}
|
||
|
|
|
||
|
|
$rs = $this->db->GetCol($query);
|
||
|
|
|
||
|
|
if (!is_array($rs)) {
|
||
|
|
$this->debug_db('get_object');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Return Object IDs
|
||
|
|
return $rs;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* 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)
|
||
|
|
*/
|
||
|
|
|
||
|
|
function get_ungrouped_objects($return_hidden=1, $object_type=NULL) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_ungrouped_objects(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_ungrouped_objects(): Object Type: $object_type");
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $table . '
|
||
|
|
LEFT JOIN groups_' . $table . '_map
|
||
|
|
ON ' . $table . '.id = groups_' . $table . '_map.' . $table . '_id';
|
||
|
|
|
||
|
|
$where = array();
|
||
|
|
$where[] = 'groups_' . $table . '_map.group_id IS NULL';
|
||
|
|
|
||
|
|
if ($return_hidden==0) {
|
||
|
|
$where[] = 'a.hidden=0';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($where)) {
|
||
|
|
$query .= ' WHERE '. implode(' AND ', $where);
|
||
|
|
}
|
||
|
|
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_ungrouped_objects');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
while(!$rs->EOF) {
|
||
|
|
$retarr[] = $rs->fields[0];
|
||
|
|
$rs->MoveNext();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Return Array of object IDS
|
||
|
|
return $retarr;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_objects ()
|
||
|
|
*
|
||
|
|
* 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) {
|
||
|
|
switch (strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_objects(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_objects(): Section Value: $section_value Object Type: $object_type");
|
||
|
|
|
||
|
|
$query = 'SELECT section_value,value FROM '. $table;
|
||
|
|
|
||
|
|
$where = array();
|
||
|
|
|
||
|
|
if (!empty($section_value)) {
|
||
|
|
$where[] = 'section_value='. $this->db->quote($section_value);
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($return_hidden==0) {
|
||
|
|
$where[] = 'hidden=0';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($where)) {
|
||
|
|
$query .= ' WHERE '. implode(' AND ', $where);
|
||
|
|
}
|
||
|
|
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_objects');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$retarr = array();
|
||
|
|
|
||
|
|
while ($row = $rs->FetchRow()) {
|
||
|
|
$retarr[$row[0]][] = $row[1];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Return objects
|
||
|
|
return $retarr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_object_data()
|
||
|
|
*
|
||
|
|
* 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 int Object ID #
|
||
|
|
* @param string Object Type, either 'ACO', 'ARO', 'AXO'
|
||
|
|
*/
|
||
|
|
function get_object_data($object_id, $object_type=NULL) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object_data(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("get_object_data(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT section_value,value,order_value,name,hidden FROM '. $table .' WHERE id='. (int) $object_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_object_data');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($rs->RecordCount() < 1) {
|
||
|
|
$this->debug_text('get_object_data(): Returned '. $row_count .' rows');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Return all objects
|
||
|
|
return $rs->GetRows();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_object_id()
|
||
|
|
*
|
||
|
|
* 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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object_id(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_object_id(): Section Value: $section_value Value: $value Object Type: $object_type");
|
||
|
|
|
||
|
|
$section_value = trim($section_value);
|
||
|
|
$value = trim($value);
|
||
|
|
|
||
|
|
if (empty($section_value) AND $value === '') {
|
||
|
|
$this->debug_text("get_object_id(): Section Value ($value) AND value ($value) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("get_object_id(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $table .' WHERE section_value='. $this->db->quote($section_value) .' AND value='. $this->db->quote($value);
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_object_id');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = $rs->RecordCount();
|
||
|
|
|
||
|
|
if ($row_count > 1) {
|
||
|
|
$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.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($row_count == 0) {
|
||
|
|
$this->debug_text("get_object_id(): Returned $row_count rows");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
|
||
|
|
//Return the ID.
|
||
|
|
return $row[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_object_section_value()
|
||
|
|
*
|
||
|
|
* Gets the object_section_value given object id
|
||
|
|
*
|
||
|
|
* @return string Object Section Value
|
||
|
|
*
|
||
|
|
* @param int Object ID #
|
||
|
|
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
|
||
|
|
*/
|
||
|
|
function get_object_section_value($object_id, $object_type=NULL) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object_section_value(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("get_object_section_value(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT section_value FROM '. $table .' WHERE id='. (int) $object_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_object_section_value');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = $rs->RecordCount();
|
||
|
|
|
||
|
|
if ($row_count > 1) {
|
||
|
|
$this->debug_text("get_object_section_value(): Returned $row_count rows, can only return one.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($row_count == 0) {
|
||
|
|
$this->debug_text("get_object_section_value(): Returned $row_count rows");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
|
||
|
|
//Return the ID.
|
||
|
|
return $row[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_object_groups()
|
||
|
|
*
|
||
|
|
* 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 int Object ID #
|
||
|
|
* @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);
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$group_table = $this->_db_table_prefix .'axo_groups';
|
||
|
|
$map_table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$group_table = $this->_db_table_prefix .'aro_groups';
|
||
|
|
$map_table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object_groups(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_id)) {
|
||
|
|
$this->debug_text('get_object_groups(): Object ID: ('. $object_id .') is empty, this is required');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strtoupper($option) == 'RECURSE') {
|
||
|
|
$query = '
|
||
|
|
SELECT DISTINCT g.id AS group_id
|
||
|
|
FROM '. $map_table .' gm
|
||
|
|
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';
|
||
|
|
} else {
|
||
|
|
$query = '
|
||
|
|
SELECT gm.group_id
|
||
|
|
FROM '. $map_table .' gm';
|
||
|
|
}
|
||
|
|
|
||
|
|
$query .= '
|
||
|
|
WHERE gm.'. $object_type .'_id='. (int) $object_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_object_groups');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$retarr = array();
|
||
|
|
|
||
|
|
while ($row = $rs->FetchRow()) {
|
||
|
|
$retarr[] = $row[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $retarr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add_object()
|
||
|
|
*
|
||
|
|
* Inserts a new object
|
||
|
|
*
|
||
|
|
* @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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aco_sections';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aro_sections';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'axo_sections';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('add_object(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_object(): Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type");
|
||
|
|
|
||
|
|
$section_value = trim($section_value);
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
$order = (int) $order;
|
||
|
|
$hidden = (int) $hidden;
|
||
|
|
|
||
|
|
if ($order == NULL OR $order == '') {
|
||
|
|
$order = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($name) OR empty($section_value) ) {
|
||
|
|
$this->debug_text("add_object(): name ($name) OR section value ($section_value) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strlen($name) >= 255 OR strlen($value) >= 230 ) {
|
||
|
|
$this->debug_text("add_object(): name ($name) OR value ($value) is too long.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("add_object(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test to see if the section is invalid or object already exists.
|
||
|
|
$query = '
|
||
|
|
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 (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_object');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($rs->RecordCount() != 1) {
|
||
|
|
// Section is invalid
|
||
|
|
$this->debug_text("add_object(): Section Value: $section_value Object Type ($object_type) does not exist, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
|
||
|
|
if ($row[0] == 1) {
|
||
|
|
//Object is already created.
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_object');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Joomla/MySQL
|
||
|
|
$insert_id = $this->db->insertid();
|
||
|
|
|
||
|
|
$this->debug_text("add_object(): Added object as ID: $insert_id");
|
||
|
|
return $insert_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* edit_object()
|
||
|
|
*
|
||
|
|
* Edits a given Object
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise
|
||
|
|
*
|
||
|
|
* @param int Object ID #
|
||
|
|
* @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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aco_map';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aro_map';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'axo_map';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
$order = (int) $order;
|
||
|
|
$hidden = (int) $hidden;
|
||
|
|
|
||
|
|
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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($name) ) {
|
||
|
|
$this->debug_text("edit_object(): name ($name) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("edit_object(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
//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);
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
UPDATE '. $table .'
|
||
|
|
SET section_value='. $this->db->quote($section_value) .',
|
||
|
|
value='. $this->db->quote($value) .',
|
||
|
|
order_value='. $order .',
|
||
|
|
name='. $this->db->quote($name) .',
|
||
|
|
hidden='. $hidden .'
|
||
|
|
WHERE id='. $object_id;
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text('edit_object(): Modified '. strtoupper($object_type) .' ID: '. $object_id);
|
||
|
|
|
||
|
|
if ($old[0] != $value OR $old[1] != $section_value) {
|
||
|
|
$this->debug_text("edit_object(): Value OR Section Value Changed, update other tables.");
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text ('edit_object(): Modified Map Value: '. $value .' Section Value: '. $section_value);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* del_object()
|
||
|
|
*
|
||
|
|
* 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 int Object ID #
|
||
|
|
* @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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aco_map';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aro_map';
|
||
|
|
$groups_map_table = $this->_db_table_prefix .'aro_groups_map';
|
||
|
|
$object_group_table = $this->_db_table_prefix .'groups_aro_map';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'axo_map';
|
||
|
|
$groups_map_table = $this->_db_table_prefix .'axo_groups_map';
|
||
|
|
$object_group_table = $this->_db_table_prefix .'groups_axo_map';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('del_object(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("del_object(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// sanitise input
|
||
|
|
$object_id = (int) $object_id;
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (empty($object)) {
|
||
|
|
$this->debug_text('del_object(): The specified object ('. strtoupper($object_type) .' ID: '. $object_id .') could not be found.');
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if ($erase) {
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($acl_ids)) {
|
||
|
|
//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
|
||
|
|
// (and relative maps)
|
||
|
|
|
||
|
|
// 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
|
||
|
|
// orhpaned acl
|
||
|
|
|
||
|
|
$orphan_acl_ids = $acl_ids;
|
||
|
|
} else {
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Find the "orphaned" acl. I mean acl referencing the erased Object (map)
|
||
|
|
// not referenced anymore by other objects
|
||
|
|
|
||
|
|
$sql_acl_ids = implode(",", $acl_ids);
|
||
|
|
|
||
|
|
$query = '
|
||
|
|
SELECT a.id
|
||
|
|
FROM '. $this->_db_table_prefix .'acl a
|
||
|
|
LEFT JOIN '. $object_map_table .' b ON a.id=b.acl_id
|
||
|
|
LEFT JOIN '. $groups_map_table .' c ON a.id=c.acl_id
|
||
|
|
WHERE b.value IS NULL
|
||
|
|
AND b.section_value IS NULL
|
||
|
|
AND c.group_id 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 ($orphan_acl_ids) {
|
||
|
|
// If there are orphaned acls get rid of them
|
||
|
|
|
||
|
|
foreach ($orphan_acl_ids as $acl) {
|
||
|
|
$this->del_acl($acl);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
} // End of if ($acl_ids)
|
||
|
|
|
||
|
|
// Finally delete the Object itself
|
||
|
|
$query = "DELETE FROM $table WHERE id=$object_id";
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
return true;
|
||
|
|
|
||
|
|
} // End of "if ($erase)"
|
||
|
|
|
||
|
|
$groups_ids = FALSE;
|
||
|
|
|
||
|
|
if ($object_type == 'axo' OR $object_type == 'aro') {
|
||
|
|
// If the object is "groupable" (may become unnecessary,
|
||
|
|
// see above
|
||
|
|
|
||
|
|
// 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();
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
// The Object is NOT referenced anywhere, delete it
|
||
|
|
|
||
|
|
$query = "DELETE FROM $table WHERE id=$object_id";
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if ( !is_object($rs) ) {
|
||
|
|
$this->debug_db('edit_object');
|
||
|
|
$this->db->RollBackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
*
|
||
|
|
* Object Sections
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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'
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
function get_object_section_section_id($name = NULL, $value = NULL, $object_type = NULL) {
|
||
|
|
$this->debug_text("get_object_section_section_id(): Value: $value Name: $name Object Type: $object_type");
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
case 'aro':
|
||
|
|
case 'axo':
|
||
|
|
case 'acl':
|
||
|
|
$object_type = strtolower(trim($object_type));
|
||
|
|
$table = $this->_db_table_prefix . $object_type;
|
||
|
|
$object_sections_table = $this->_db_table_prefix . $object_type .'_sections';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_object_section_section_id(): Invalid Object Type ('. $object_type . ')');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
|
||
|
|
if (empty($name) AND $value === '') {
|
||
|
|
$this->debug_text('get_object_section_section_id(): Both Name ('. $name .') and Value ('. $value .') are empty, you must specify at least one.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT id FROM '. $object_sections_table;
|
||
|
|
$where = ' WHERE ';
|
||
|
|
|
||
|
|
// limit by value if specified
|
||
|
|
if ($value !== '') {
|
||
|
|
$query .= $where .'value='. $this->db->quote($value);
|
||
|
|
$where = ' AND ';
|
||
|
|
}
|
||
|
|
|
||
|
|
// only use name if asked, this is SLOW
|
||
|
|
if (!empty($name)) {
|
||
|
|
$query .= $where .'name='. $this->db->quote($name);
|
||
|
|
}
|
||
|
|
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('get_object_section_section_id');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$row_count = $rs->RecordCount();
|
||
|
|
|
||
|
|
// If only one row is returned
|
||
|
|
if ($row_count == 1) {
|
||
|
|
// Return only the ID in the first row.
|
||
|
|
$row = $rs->FetchRow();
|
||
|
|
return $row[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
// If more than one row is returned
|
||
|
|
// should only ever occur when using name as values are unique.
|
||
|
|
if ($row_count > 1) {
|
||
|
|
$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.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// No rows returned, no matching section found
|
||
|
|
$this->debug_text('get_object_section_section_id(): Returned '. $row_count .' rows, no matching section found.');
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* add_object_section()
|
||
|
|
*
|
||
|
|
* 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'
|
||
|
|
*/
|
||
|
|
function add_object_section($name, $value=0, $order=0, $hidden=0, $object_type=NULL) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aco_sections';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aro_sections';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'axo_sections';
|
||
|
|
break;
|
||
|
|
case 'acl':
|
||
|
|
$object_type = 'acl';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'acl_sections';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("add_object_section(): Value: $value Order: $order Name: $name Object Type: $object_type");
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
$order = (int) $order;
|
||
|
|
$hidden = (int) $hidden;
|
||
|
|
|
||
|
|
if ($order == NULL OR $order == '') {
|
||
|
|
$order = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($name) ) {
|
||
|
|
$this->debug_text("add_object_section(): name ($name) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("add_object_section(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('add_object_section');
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("add_object_section(): Added object_section as ID: $insert_id");
|
||
|
|
return $insert_id;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* edit_object_section()
|
||
|
|
*
|
||
|
|
* 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) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aco_sections';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aco_map';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aro_sections';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'aro_map';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'axo_sections';
|
||
|
|
$object_map_table = $this->_db_table_prefix .'axo_map';
|
||
|
|
break;
|
||
|
|
case 'acl':
|
||
|
|
$object_type = 'acl';
|
||
|
|
$table = $this->_db_table_prefix .'acl';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'acl_sections';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('edit_object_section(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("edit_object_section(): ID: $object_section_id Value: $value Order: $order Name: $name Object Type: $object_type");
|
||
|
|
|
||
|
|
$name = trim($name);
|
||
|
|
$value = trim($value);
|
||
|
|
$order = (int) $order;
|
||
|
|
$hidden = (int) $hidden;
|
||
|
|
|
||
|
|
if (empty($object_section_id) ) {
|
||
|
|
$this->debug_text("edit_object_section(): Section ID ($object_section_id) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($name) ) {
|
||
|
|
$this->debug_text("edit_object_section(): name ($name) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("edit_object_section(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// sanitise input
|
||
|
|
$object_section_id = (int) $object_section_id;
|
||
|
|
|
||
|
|
$this->db->BeginTrans();
|
||
|
|
|
||
|
|
//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) . "',
|
||
|
|
order_value=$order,
|
||
|
|
name=" . $this->db-quote($name) . ",
|
||
|
|
hidden=$hidden
|
||
|
|
where id=$object_section_id";
|
||
|
|
$rs = $this->db->Execute($query);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object_section');
|
||
|
|
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('edit_object_section');
|
||
|
|
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
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);
|
||
|
|
|
||
|
|
if ( !is_object($rs) ) {
|
||
|
|
$this->debug_db('edit_object_section');
|
||
|
|
|
||
|
|
$this->db->RollbackTrans();
|
||
|
|
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("edit_object_section(): Modified ojbect_map value: $value");
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
//ACL sections, have no mapping table. Return true.
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->db->CommitTrans();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* del_object_section()
|
||
|
|
*
|
||
|
|
* 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
|
||
|
|
*/
|
||
|
|
function del_object_section($object_section_id, $object_type=NULL, $erase=FALSE) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aco_sections';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'aro_sections';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'axo_sections';
|
||
|
|
break;
|
||
|
|
case 'acl':
|
||
|
|
$object_type = 'acl';
|
||
|
|
$object_sections_table = $this->_db_table_prefix .'acl_sections';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
$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");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("del_object_section(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// sanitise input
|
||
|
|
$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);
|
||
|
|
|
||
|
|
if($erase) {
|
||
|
|
// Delete all objects in the section and for
|
||
|
|
// each object delete the referencing object
|
||
|
|
// (see del_object method)
|
||
|
|
if (is_array($object_ids)) {
|
||
|
|
foreach ($object_ids as $id) {
|
||
|
|
if ( $object_type === 'acl' ) {
|
||
|
|
$this->del_acl($id);
|
||
|
|
} else {
|
||
|
|
$this->del_object($id, $object_type, TRUE);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
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.");
|
||
|
|
|
||
|
|
return false;
|
||
|
|
|
||
|
|
} else {
|
||
|
|
// 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);
|
||
|
|
|
||
|
|
if (!is_object($rs)) {
|
||
|
|
$this->debug_db('del_object_section');
|
||
|
|
return false;
|
||
|
|
} else {
|
||
|
|
$this->debug_text("del_object_section(): deleted section ID: $object_section_id Value: $section_value");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* get_section_data()
|
||
|
|
*
|
||
|
|
* Gets the section data given the Section Value
|
||
|
|
*
|
||
|
|
* @return array Returns numerically indexed array with the following columns:
|
||
|
|
* - array[0] = (int) Section ID #
|
||
|
|
* - array[1] = (string) Section Value
|
||
|
|
* - array[2] = (int) Section Order
|
||
|
|
* - array[3] = (string) Section Name
|
||
|
|
* - array[4] = (int) Section Hidden?
|
||
|
|
* @param string Section Value
|
||
|
|
* @param string Object Type, either 'ACO', 'ARO', or 'AXO'
|
||
|
|
*/
|
||
|
|
function get_section_data($section_value, $object_type=NULL) {
|
||
|
|
|
||
|
|
switch(strtolower(trim($object_type))) {
|
||
|
|
case 'aco':
|
||
|
|
$object_type = 'aco';
|
||
|
|
$table = $this->_db_table_prefix .'aco_sections';
|
||
|
|
break;
|
||
|
|
case 'aro':
|
||
|
|
$object_type = 'aro';
|
||
|
|
$table = $this->_db_table_prefix .'aro_sections';
|
||
|
|
break;
|
||
|
|
case 'axo':
|
||
|
|
$object_type = 'axo';
|
||
|
|
$table = $this->_db_table_prefix .'axo_sections';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
$this->debug_text('get_section_data(): Invalid Object Type: '. $object_type);
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_section_data(): Section Value: $section_value Object Type: $object_type");
|
||
|
|
|
||
|
|
if (empty($section_value) ) {
|
||
|
|
$this->debug_text("get_section_data(): Section Value ($section_value) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (empty($object_type) ) {
|
||
|
|
$this->debug_text("get_section_data(): Object Type ($object_type) is empty, this is required");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = 'SELECT id, value, order_value, name, hidden FROM '. $table .' WHERE value='.$this->db->Quote( $section_value );
|
||
|
|
$row = $this->db->GetRow($query);
|
||
|
|
|
||
|
|
if ($row) {
|
||
|
|
return $row;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->debug_text("get_section_data(): Section does not exist.");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* clear_database()
|
||
|
|
*
|
||
|
|
* Deletes all data from the phpGACL tables. USE WITH CAUTION.
|
||
|
|
*
|
||
|
|
* @return bool Returns TRUE if successful, FALSE otherwise
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
function clear_database()
|
||
|
|
{
|
||
|
|
$tablesToClear = array(
|
||
|
|
$this->_db_table_prefix.'acl',
|
||
|
|
$this->_db_table_prefix.'aco',
|
||
|
|
$this->_db_table_prefix.'aco_map',
|
||
|
|
$this->_db_table_prefix.'aco_sections',
|
||
|
|
$this->_db_table_prefix.'aro',
|
||
|
|
$this->_db_table_prefix.'aro_groups',
|
||
|
|
$this->_db_table_prefix.'aro_groups_map',
|
||
|
|
$this->_db_table_prefix.'aro_map',
|
||
|
|
$this->_db_table_prefix.'aro_sections',
|
||
|
|
$this->_db_table_prefix.'axo',
|
||
|
|
$this->_db_table_prefix.'axo_groups',
|
||
|
|
$this->_db_table_prefix.'axo_groups_map',
|
||
|
|
$this->_db_table_prefix.'axo_map',
|
||
|
|
$this->_db_table_prefix.'axo_sections',
|
||
|
|
$this->_db_table_prefix.'groups_aro_map',
|
||
|
|
$this->_db_table_prefix.'groups_axo_map'
|
||
|
|
);
|
||
|
|
|
||
|
|
// Get all the table names and loop
|
||
|
|
$tableNames = $this->db->MetaTables('TABLES');
|
||
|
|
$query = array();
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Calculates the start number for a sequence table
|
||
|
|
* @protected
|
||
|
|
* @param string The name of the table
|
||
|
|
* @return int The highest id plus one
|
||
|
|
*/
|
||
|
|
function _defaultGenID( $table ) {
|
||
|
|
$query = "SELECT MAX(id) from " . $table;
|
||
|
|
$id = $this->db->GetOne( $query ) + 1;
|
||
|
|
|
||
|
|
return $id;
|
||
|
|
}
|
||
|
|
}
|