git-svn-id: https://192.168.0.254/svn/Proyectos.MatritumCantat_Web/trunk@2 8e3496fd-7892-4c45-be36-0ff06e9dacc6
1825 lines
58 KiB
PHP
1825 lines
58 KiB
PHP
<?php
|
|
/**
|
|
* @version $Id: gacl_api.class.php 9849 2008-01-04 04:49:28Z eddieajau $
|
|
* @package Joomla
|
|
* @copyright Copyright (C) 2005 Open Source Matters. All rights reserved.
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
|
|
* Joomla! is free software. This version may have been modified pursuant
|
|
* to the GNU General Public License, and as distributed it includes or
|
|
* is derivative of works licensed under the GNU General Public License or
|
|
* other free or open source software licenses.
|
|
* See COPYRIGHT.php for copyright notices and details.
|
|
*/
|
|
|
|
/*
|
|
* 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/
|
|
*
|
|
*/
|
|
|
|
// no direct access
|
|
defined( '_VALID_MOS' ) or die( 'Restricted access' );
|
|
|
|
/*
|
|
*
|
|
*
|
|
* == If you find a feature may be missing from this API, please email me: ipso@snappymail.ca and I will be happy to add it. ==
|
|
*
|
|
*
|
|
* Example:
|
|
* $gacl_api = new gacl_api;
|
|
*
|
|
* $section_id = $gacl_api->get_aco_section_id('System');
|
|
* $aro_id= $gacl_api->add_aro($section_id, 'John Doe', 10);
|
|
*
|
|
* For more examples, see the Administration interface, as it makes use of nearly every API Call.
|
|
*
|
|
*/
|
|
|
|
class gacl_api extends gacl {
|
|
/*
|
|
* Administration interface settings
|
|
*/
|
|
var $_items_per_page = 100;
|
|
var $_max_select_box_items = 100;
|
|
var $_max_search_return_items = 100;
|
|
|
|
/*
|
|
*
|
|
* Misc helper functions.
|
|
*
|
|
*/
|
|
|
|
/*======================================================================*\
|
|
Function: showarray()
|
|
Purpose: Dump all contents of an array in HTML (kinda).
|
|
\*======================================================================*/
|
|
function showarray($array) {
|
|
echo "<br><pre>\n";
|
|
var_dump($array);
|
|
echo "</pre><br>\n";
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: $gacl_api->return_page()
|
|
Purpose: Sends the user back to a passed URL, unless debug is enabled, then we don't redirect.
|
|
If no URL is passed, try the REFERER
|
|
\*======================================================================*/
|
|
function return_page($url="") {
|
|
global $_SERVER, $debug;
|
|
|
|
if (empty($url) AND !empty($_SERVER[HTTP_REFERER])) {
|
|
$this->debug_text("return_page(): URL not set, using referer!");
|
|
$url = $_SERVER[HTTP_REFERER];
|
|
}
|
|
|
|
if (!$debug OR $debug==0) {
|
|
header("Location: $url\n\n");
|
|
} else {
|
|
$this->debug_text("return_page(): URL: $url -- Referer: $_SERVER[HTTP_REFERRER]");
|
|
}
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_paging_data()
|
|
Purpose: Creates a basic array for Smarty to deal with paging large recordsets.
|
|
Pass it the ADODB recordset.
|
|
\*======================================================================*/
|
|
function get_paging_data($rs) {
|
|
return array(
|
|
'prevpage' => $rs->absolutepage() - 1,
|
|
'currentpage' => $rs->absolutepage(),
|
|
'nextpage' => $rs->absolutepage() + 1,
|
|
'atfirstpage' => $rs->atfirstpage(),
|
|
'atlastpage' => $rs->atlastpage(),
|
|
'lastpageno' => $rs->lastpageno()
|
|
);
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: count_all()
|
|
Purpose: Recursively counts elements in an array and sub-arrays.
|
|
The returned count is a count of all scalar elements found.
|
|
|
|
This is different from count($arg, COUNT_RECURSIVE)
|
|
in PHP >= 4.2.0, which includes sub-arrays in the 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;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_version()
|
|
Purpose: Grabs phpGACL version from the database.
|
|
\*======================================================================*/
|
|
|
|
|
|
/*======================================================================*\
|
|
Function: get_schema_version()
|
|
Purpose: Grabs phpGACL schema version from the database.
|
|
\*======================================================================*/
|
|
/*
|
|
*
|
|
* ACL
|
|
*
|
|
*/
|
|
|
|
/*======================================================================*\
|
|
Function: consolidated_edit_acl()
|
|
Purpose: 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.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: shift_acl()
|
|
Purpose: Opposite of append_acl(). Removes objects from a specific ACL. (named after PHP's array_shift())
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_acl()
|
|
Purpose: Grabs ACL data.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: is_conflicting_acl()
|
|
Purpose: Checks for conflicts when adding a specific ACL.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: add_acl()
|
|
Purpose: Add's an ACL. ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: edit_acl()
|
|
Purpose: Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: del_acl()
|
|
Purpose: Deletes a given ACL
|
|
\*======================================================================*/
|
|
|
|
|
|
/*
|
|
*
|
|
* Groups
|
|
*
|
|
*/
|
|
|
|
/*======================================================================*\
|
|
Function: sort_groups()
|
|
Purpose: Grabs all the groups from the database doing preliminary grouping by parent
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: format_groups()
|
|
Purpose: Takes the array returned by sort_groups() and formats for human consumption.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_id()
|
|
Purpose: Gets the group_id given the name.
|
|
Will only return one group id, so if there are duplicate names, it will return false.
|
|
\*======================================================================*/
|
|
function get_group_id($name = null, $group_type = 'ARO') {
|
|
|
|
$this->debug_text("get_group_id(): Name: $name");
|
|
|
|
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);
|
|
|
|
if (empty($name) ) {
|
|
$this->debug_text("get_group_id(): name ($name) is empty, this is required");
|
|
return false;
|
|
}
|
|
|
|
$this->db->setQuery( "SELECT group_id FROM $table WHERE name=" . $this->db->Quote( $name ) );
|
|
|
|
$rows = $this->db->loadRowList();
|
|
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;
|
|
}
|
|
|
|
$row = $rows[0];
|
|
|
|
//Return the ID.
|
|
return $row[0];
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_name()
|
|
Purpose: Gets the name given the group_id.
|
|
Will only return one group id, so if there are duplicate names, it will return false.
|
|
\*======================================================================*/
|
|
function get_group_name($group_id = null, $group_type = 'ARO') {
|
|
|
|
$this->debug_text("get_group_name(): ID: $group_id");
|
|
|
|
switch(strtolower(trim($group_type))) {
|
|
case 'axo':
|
|
$table = $this->_db_table_prefix .'axo_groups';
|
|
break;
|
|
default:
|
|
$table = $this->_db_table_prefix .'aro_groups';
|
|
break;
|
|
}
|
|
|
|
$group_id = intval($group_id);
|
|
|
|
if (!$group_id) {
|
|
$this->debug_text("get_group_name(): group_id ($group_id) is empty, this is required");
|
|
return false;
|
|
}
|
|
|
|
$this->db->setQuery( "SELECT name FROM $table WHERE group_id=" . (int) $group_id );
|
|
|
|
$rows = $this->db->loadRowList();
|
|
if ($this->db->getErrorNum()) {
|
|
$this->debug_db('get_group_name');
|
|
return false;
|
|
}
|
|
|
|
$row_count = count( $rows );
|
|
|
|
if ($row_count > 1) {
|
|
$this->debug_text("get_group_name(): Returned $row_count rows, can only return one. Please make your names unique.");
|
|
return false;
|
|
}
|
|
|
|
if ($row_count == 0) {
|
|
$this->debug_text("get_group_name(): Returned $row_count rows");
|
|
return false;
|
|
}
|
|
|
|
$row = $rows[0];
|
|
|
|
//Return the ID.
|
|
return $row[0];
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_children()
|
|
Purpose: Gets a groups child IDs
|
|
\*======================================================================*/
|
|
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.group_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.group_id='. (int) $group_id;
|
|
break;
|
|
default:
|
|
$query .= '
|
|
WHERE g1.parent_id='. (int) $group_id;
|
|
}
|
|
|
|
$query .= '
|
|
ORDER BY g1.name';
|
|
|
|
|
|
$this->db->setQuery( $query );
|
|
return $this->db->loadResultArray();
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_data()
|
|
Purpose: Gets the group data given the GROUP_ID.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_parent_id()
|
|
Purpose: Grabs the parent_id of a given group
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_children()
|
|
Purpose: Gets a groups child IDs
|
|
\*======================================================================*/
|
|
function get_group_parents($group_id, $group_type = 'ARO', $recurse = 'NO_RECURSE') {
|
|
$this->debug_text("get_group_parents(): 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_parents(): ID ($group_id) is empty, this is required");
|
|
return FALSE;
|
|
}
|
|
|
|
$query = '
|
|
SELECT g2.group_id
|
|
FROM '. $table .' g1';
|
|
|
|
//FIXME-mikeb: Why is group_id in quotes?
|
|
switch (strtoupper($recurse)) {
|
|
case 'RECURSE':
|
|
$query .= '
|
|
LEFT JOIN '. $table .' g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt
|
|
WHERE g1.group_id='. (int) $group_id;
|
|
break;
|
|
case 'RECURSE_INCL':
|
|
// inclusive resurse
|
|
$query .= '
|
|
LEFT JOIN '. $table .' g2 ON g1.lft >= g2.lft AND g1.lft <= g2.rgt
|
|
WHERE g1.group_id='. (int) $group_id;
|
|
break;
|
|
default:
|
|
$query .= '
|
|
LEFT JOIN '. $table .' g2 ON g1.parent_id = g2.group_id
|
|
WHERE g1.group_id='. (int) $group_id;
|
|
}
|
|
|
|
$query .= '
|
|
ORDER BY g2.lft';
|
|
$this->db->setQuery( $query );
|
|
return $this->db->loadResultArray();
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_root_group_id ()
|
|
Purpose: Grabs the id of the root group for the specified tree
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
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 **/
|
|
|
|
/*======================================================================*\
|
|
Function: add_group()
|
|
Purpose: Inserts a group, defaults to be on the "root" branch.
|
|
\*======================================================================*/
|
|
function add_group($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 Parent ID: $parent_id Group Type: $group_type");
|
|
|
|
$name = trim($name);
|
|
|
|
if (empty($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($this->_db_table_prefix.$group_type.'_groups_id_seq',10);
|
|
$this->db->setQuery( "SELECT MAX(group_id)+1 FROM $table" );
|
|
$insert_id = intval( $this->db->loadResult() );
|
|
|
|
// <mos> $this->db->BeginTrans();
|
|
|
|
// special case for root group
|
|
if ($parent_id == 0) {
|
|
// check a root group is not already defined
|
|
$$this->db->setQuery( 'SELECT group_id FROM '. $table .' WHERE parent_id=0' );
|
|
$rs = $this->db->loadResultArray();
|
|
|
|
if (!is_array( $rs )) {
|
|
$this->debug_db('add_group');
|
|
$this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
|
|
if (count( $rs ) > 0) {
|
|
$this->debug_text('add_group (): A root group already exists.');
|
|
// <mos> $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");
|
|
return FALSE;
|
|
}
|
|
|
|
// grab parent details from database
|
|
$this->db->setQuery( 'SELECT group_id, lft, rgt FROM '. $table .' WHERE group_id='. (int) $parent_id );
|
|
$rows = $this->db->loadRowList();
|
|
|
|
if (!is_array($rows) OR $this->db->getErrorNum() > 0) {
|
|
$this->debug_db('add_group');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
|
|
if (empty($rows)) {
|
|
$this->debug_text('add_group (): Parent ID: '. $parent_id .' not found.');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
$row = $rows[0];
|
|
$parent_lft = &$row[1];
|
|
$parent_rgt = &$row[2];
|
|
|
|
// make room for the new group
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt+2 WHERE rgt>='. (int) $parent_rgt );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
$this->debug_db('add_group: make room for the new group - right');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET lft=lft+2 WHERE lft>'. (int) $parent_rgt );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
$this->debug_db('add_group: make room for the new group - left');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
$this->db->setQuery( 'INSERT INTO '. $table .' (group_id,parent_id,name,lft,rgt) VALUES ('. (int) $insert_id .','. (int) $parent_id .',\''. $this->db->getEscaped($name) .'\','. (int) $parent_rgt .','. (int) ($parent_rgt + 1) .')' );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
$this->debug_db('add_group: insert record');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return FALSE;
|
|
}
|
|
|
|
// <mos> $this->db->CommitTrans();
|
|
|
|
$this->debug_text('add_group (): Added group as ID: '. $insert_id);
|
|
return $insert_id;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_group_objects()
|
|
Purpose: 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.
|
|
\*======================================================================*/
|
|
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
|
|
FROM '. $object_table .' o
|
|
LEFT JOIN '. $map_table .' gm ON o.'. $group_type .'_id=gm.'. $group_type .'_id';
|
|
|
|
if ($option == 'RECURSE') {
|
|
$query .= '
|
|
LEFT JOIN '. $group_table .' g1 ON g1.group_id=gm.group_id
|
|
LEFT JOIN '. $group_table .' g2 ON g2.lft<=g1.lft AND g2.rgt>=g1.rgt
|
|
WHERE g2.group_id='. (int) $group_id;
|
|
} else {
|
|
$query .= '
|
|
WHERE gm.group_id='. (int) $group_id;
|
|
}
|
|
|
|
$this->db->setQuery( $query );
|
|
|
|
$rs = $this->db->loadRowList();
|
|
|
|
if (!is_array( $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.
|
|
foreach ($rs as $row) {
|
|
$section = &$row[0];
|
|
$value = &$row[1];
|
|
|
|
$retarr[$section][] = $value;
|
|
}
|
|
|
|
return $retarr;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: add_group_object()
|
|
Purpose: Assigns an Object to a group
|
|
\*======================================================================*/
|
|
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 empty($object_value) OR empty($object_section_value)) {
|
|
$this->debug_text("add_group_object(): Group ID: ($group_id) OR Value ($object_value) OR Section value ($object_section_value) is empty, this is required");
|
|
return false;
|
|
}
|
|
|
|
// test to see if object & group exist and if object is already a member
|
|
$this->db->setQuery( '
|
|
SELECT g.group_id,o.'. $group_type .'_id,gm.group_id AS member
|
|
FROM '. $object_table .' o
|
|
LEFT JOIN '. $group_table .' g ON g.group_id='. (int) $group_id .'
|
|
LEFT JOIN '. $table .' gm ON (gm.group_id=g.group_id AND gm.'. $group_type .'_id=o.'. $group_type .'_id)
|
|
WHERE (o.section_value=\''. $this->db->getEscaped($object_section_value) .'\' AND o.value=\''. $this->db->getEscaped($object_value) .'\')'
|
|
);
|
|
|
|
$rows = $this->db->loadRowList();
|
|
if ($this->db->getErrorNum()) {
|
|
$this->debug_db('add_group_object');
|
|
return FALSE;
|
|
}
|
|
|
|
if (count( $rows ) != 1) {
|
|
$this->debug_text("add_group_object (): Group ID ($group_id) OR Value ($object_value) OR Section value ($object_section_value) is invalid. Does this object exist?");
|
|
return FALSE;
|
|
}
|
|
|
|
$row = $rows[0];
|
|
|
|
if ($row[2] == 1) {
|
|
$this->debug_text("add_group_object (): Object: $object_value is already a member of Group ID: $group_id");
|
|
//Object is already assigned to group. Return true.
|
|
return true;
|
|
}
|
|
|
|
$object_id = $row[1];
|
|
|
|
$this->db->setQuery( 'INSERT INTO '. $table .' (group_id,'. $group_type .'_id) VALUES ('. (int) $group_id .','. (int) $object_id .')' );
|
|
|
|
if (!$this->db->query()) {
|
|
$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;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: del_group_object()
|
|
Purpose: Removes an Object from a group.
|
|
\*======================================================================*/
|
|
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 empty($object_value) OR empty($object_section_value)) {
|
|
$this->debug_text("del_group_object(): Group ID: ($group_id) OR Section value: $object_section_value OR Value ($object_value) is empty, this is required");
|
|
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;
|
|
}
|
|
|
|
$this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id .' AND '. $group_type .'_id='. (int) $object_id );
|
|
$this->db->query();
|
|
|
|
if ($this->db->getErrorNum()) {
|
|
$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;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: edit_group()
|
|
Purpose: Edits a group
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: rebuild_tree ()
|
|
Purpose: rebuilds the group tree for the given type
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: del_group()
|
|
Purpose: deletes a given group
|
|
\*======================================================================*/
|
|
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
|
|
$this->db->setQuery( 'SELECT group_id, parent_id, name, lft, rgt FROM '. $table .' WHERE group_id='. (int) $group_id );
|
|
$group_details = $this->db->loadRow();
|
|
|
|
if (!is_array($group_details)) {
|
|
$this->debug_db('del_group: get group details');
|
|
return false;
|
|
}
|
|
|
|
$parent_id = $group_details[1];
|
|
|
|
$left = $group_details[3];
|
|
$right = $group_details[4];
|
|
|
|
// <mos> $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) {
|
|
$this->db->setQuery( 'SELECT count(*) FROM '. $table .' WHERE parent_id='. (int) $group_id );
|
|
$child_count = $this->db->loadResult();
|
|
|
|
if ($child_count > 1 && $reparent_children) {
|
|
$this->debug_text ('del_group (): You cannot delete the root group and reparent children, this would create multiple root groups.');
|
|
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
|
|
/* Reapply when ACL's implemented
|
|
$this->db->setQuery( 'DELETE FROM '. $groups_map_table .' WHERE group_id='. $group_id );
|
|
$rs = $this->db->Execute($query);
|
|
|
|
if (!is_object($rs)) {
|
|
break;
|
|
}*/
|
|
|
|
// remove group object maps
|
|
$this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// remove group
|
|
$this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// move all groups right of deleted group left by width of deleted group
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-'. (int) ($right-$left+1) .' WHERE lft>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-'. (int) ($right-$left+1) .' WHERE rgt>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
$success = TRUE;
|
|
break;
|
|
case $reparent_children == TRUE:
|
|
// remove acl maps
|
|
/* Reapply when ACL's implemented
|
|
$query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. $group_id;
|
|
$rs = $this->db->Execute($query);
|
|
|
|
if (!is_object($rs)) {
|
|
break;
|
|
}*/
|
|
|
|
// remove group object maps
|
|
$this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// remove group
|
|
$this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// set parent of immediate children to parent group
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET parent_id='. (int) $parent_id .' WHERE parent_id='. (int) $group_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// move all children left by 1
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-1, rgt=rgt-1 WHERE lft>'. (int) $left .' AND rgt<'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// move all groups right of deleted group left by 2
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-2 WHERE lft>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-2 WHERE rgt>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
$success = TRUE;
|
|
break;
|
|
default:
|
|
// make list of group and all children
|
|
$group_ids = $children_ids;
|
|
$group_ids[] = $group_id;
|
|
|
|
// remove acl maps
|
|
/* Reapply when ACL's implemented
|
|
$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
|
|
mosArrayToInts( $group_ids );
|
|
$this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')' );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// remove groups
|
|
$this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id IN ('. implode (',', $group_ids) .')' );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
// move all groups right of deleted group left by width of deleted group
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-'. (int) ($right - $left + 1) .' WHERE lft>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
break;
|
|
}
|
|
|
|
$this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-'. (int) ($right - $left + 1) .' WHERE rgt>'. (int) $right );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$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");
|
|
// <mos> $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)
|
|
*
|
|
*/
|
|
/*======================================================================*\
|
|
Function: get_object()
|
|
Purpose: Grabs all Objects's in the database, or specific to a section_value
|
|
\*======================================================================*/
|
|
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;
|
|
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");
|
|
|
|
$$this->db->setQuery( 'SELECT '. $object_type .'_id FROM '. $table );
|
|
|
|
$where = array();
|
|
|
|
if (!empty($section_value)) {
|
|
$where[] = 'section_value='. $this->db->getEscaped($section_value);
|
|
}
|
|
|
|
if ($return_hidden==0) {
|
|
$where[] = 'hidden=0';
|
|
}
|
|
|
|
if (!empty($where)) {
|
|
$query .= ' WHERE '. implode(' AND ', $where);
|
|
}
|
|
|
|
$rs = $this->db->loadResultArray();
|
|
|
|
if (!is_array($rs)) {
|
|
$this->debug_db('get_object');
|
|
return false;
|
|
}
|
|
|
|
// Return Object IDs
|
|
return $rs;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_objects ()
|
|
Purpose: Grabs all Objects in the database, or specific to a section_value
|
|
returns format suitable for add_acl and is_conflicting_acl
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_data()
|
|
Purpose: Gets all data pertaining to a specific Object.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_groups()
|
|
Purpose: Gets the group_id's for the given the section_value AND value
|
|
of the object.
|
|
\*======================================================================*/
|
|
function get_object_groups($object_section_value, $object_value, $object_type=NULL) {
|
|
|
|
switch(strtolower(trim($object_type))) {
|
|
case 'aro':
|
|
$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;
|
|
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:
|
|
$this->debug_text('get_object_groups(): Invalid Object Type: '. $object_type);
|
|
return FALSE;
|
|
}
|
|
|
|
$this->debug_text("get_object_groups(): Section Value: $object_section_value Value: $object_value Object Type: $object_type");
|
|
|
|
$object_section_value = trim($object_section_value);
|
|
$object_value = trim($object_value);
|
|
|
|
if (empty($object_section_value) AND empty($object_value) ) {
|
|
$this->debug_text("get_object_groups(): Section Value ($object_section_value) AND value ($object_value) is empty, this is required");
|
|
return false;
|
|
}
|
|
|
|
if (empty($object_type) ) {
|
|
$this->debug_text("get_object_groups(): Object Type ($object_type) is empty, this is required");
|
|
return false;
|
|
}
|
|
// SELECT g.group_id,o.'. $group_type .'_id,(gm.group_id IS NOT NULL) AS member
|
|
|
|
$this->db->setQuery( '
|
|
SELECT g.group_id,o.'. $group_type .'_id,(gm.group_id IS NOT NULL) AS member
|
|
FROM '. $group_table .' g
|
|
LEFT JOIN '. $table .' gm ON gm.group_id=g.group_id
|
|
LEFT JOIN '. $object_table .' o ON o.'. $group_type .'_id = gm.'. $group_type .'_id
|
|
WHERE (o.section_value=\''. $this->db->getEscaped($object_section_value) .'\' AND o.value=\''. $this->db->getEscaped($object_value) .'\')'
|
|
);
|
|
$rs = $this->db->loadResultArray();
|
|
|
|
if ($this->db->getErrorNum()) {
|
|
$this->debug_db('get_object_id');
|
|
return false;
|
|
}
|
|
|
|
//Return the array of group id's
|
|
return $rs;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_id()
|
|
Purpose: Gets the object_id given the section_value AND value of the object.
|
|
\*======================================================================*/
|
|
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 empty($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;
|
|
}
|
|
|
|
$this->db->setQuery( 'SELECT '. $object_type .'_id FROM '. $table .' WHERE section_value=\''. $this->db->getEscaped($section_value) .'\' AND value=\''. $this->db->getEscaped($value) .'\''
|
|
);
|
|
$rs = $this->db->loadRowList();
|
|
|
|
if ($this->db->getErrorNum()) {
|
|
$this->debug_db('get_object_id');
|
|
return false;
|
|
}
|
|
|
|
$row_count = count( $rs );
|
|
|
|
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[0];
|
|
|
|
//Return the ID.
|
|
return $row[0];
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_section_value()
|
|
Purpose: Gets the object_section_value given object id
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_groups()
|
|
Purpose: Gets all groups an object is a member of.
|
|
If $option == 'RECURSE' it will get all ancestor groups.
|
|
defaults to only get direct parents.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: add_object()
|
|
Purpose: Inserts a new object
|
|
\*======================================================================*/
|
|
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 = trim($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.
|
|
$this->db->setQuery( '
|
|
SELECT (o.'. $object_type .'_id IS NOT NULL) AS object_exists
|
|
FROM '. $object_sections_table .' s
|
|
LEFT JOIN '. $table .' o ON (s.value=o.section_value AND o.value=\''. $this->db->getEscaped($value) .'\')
|
|
WHERE s.value=\''. $this->db->getEscaped($section_value). '\''
|
|
);
|
|
|
|
$rows = $this->db->loadRowList();
|
|
if ($this->db->getErrorNum()) {
|
|
$this->debug_db('add_object');
|
|
return FALSE;
|
|
}
|
|
|
|
if (count( $rows ) != 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 = $rows[0];
|
|
|
|
if ($row[0] == 1) {
|
|
//Object is already created.
|
|
return true;
|
|
}
|
|
|
|
$insert_id = $this->db->GenID($this->_db_table_prefix.$object_type.'_seq',10);
|
|
$this->db->setQuery( "INSERT INTO $table ({$object_type}_id,section_value,value,order_value,name,hidden) VALUES(" . (int) $insert_id . "," . $this->db->Quote( $section_value ) . "," . $this->db->Quote( $value ) . "," . $this->db->Quote( $order ) . "," . $this->db->Quote( $name ) . "," . (int) $hidden . ")" );
|
|
|
|
if (!$this->db->query()) {
|
|
$this->debug_db('add_object');
|
|
return false;
|
|
}
|
|
|
|
$insert_id = $this->db->insertid();
|
|
$this->debug_text("add_object(): Added object as ID: $insert_id");
|
|
return $insert_id;
|
|
}
|
|
/*======================================================================*\
|
|
Function: edit_object()
|
|
Purpose: Edits a given Object
|
|
\*======================================================================*/
|
|
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 = 'aco_map';
|
|
break;
|
|
case 'aro':
|
|
$object_type = 'aro';
|
|
$table = $this->_db_table_prefix .'aro';
|
|
$object_map_table = 'aro_map';
|
|
break;
|
|
case 'axo':
|
|
$object_type = 'axo';
|
|
$table = $this->_db_table_prefix .'axo';
|
|
$object_map_table = '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");
|
|
|
|
$section_value = trim($section_value);
|
|
$name = trim($name);
|
|
$value = trim($value);
|
|
$order = trim($order);
|
|
|
|
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;
|
|
}
|
|
|
|
//Get old value incase it changed, before we do the update.
|
|
$this->db->setQuery( 'SELECT value, section_value FROM '. $table .' WHERE '. $object_type .'_id='. (int) $object_id );
|
|
$old = $this->db->loadRow();
|
|
|
|
$this->db->setQuery( '
|
|
UPDATE '. $table .'
|
|
SET section_value=\''. $this->db->getEscaped($section_value) .'\',
|
|
value=\''. $this->db->getEscaped($value) .'\',
|
|
order_value=\''. $this->db->getEscaped($order) .'\',
|
|
name=\''. $this->db->getEscaped($name) .'\',
|
|
hidden='. (int) $hidden .'
|
|
WHERE '. $object_type .'_id='. (int) $object_id
|
|
);
|
|
$this->db->query();
|
|
|
|
if (!$this->db->getErrorNum()) {
|
|
$this->debug_db('edit_object');
|
|
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.");
|
|
|
|
$this->db->setQuery( '
|
|
UPDATE '. $object_map_table .'
|
|
SET value=\''. $this->db->getEscaped($value) .'\',
|
|
section_value=\''. $this->db->getEscaped($section_value) .'\'
|
|
WHERE section_value=\''. $this->db->getEscaped($old[1]) .'\'
|
|
AND value=\''. $this->db->getEscaped($old[0]) . '\''
|
|
);
|
|
$this->db->query();
|
|
|
|
if (!$this->db->getErrorNum()) {
|
|
$this->debug_db('edit_object');
|
|
return FALSE;
|
|
}
|
|
|
|
$this->debug_text ('edit_object(): Modified Map Value: '. $value .' Section Value: '. $section_value);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*======================================================================*\
|
|
Function: del_object()
|
|
Purpose: Deletes a given Object and, if instructed to do so,
|
|
erase all referencing objects
|
|
ERASE feature by: Martino Piccinato
|
|
\*======================================================================*/
|
|
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;
|
|
}
|
|
|
|
// <mos> $this->db->BeginTrans();
|
|
|
|
// Get Object section_value/value (needed to look for referencing objects)
|
|
$this->db->setQuery( 'SELECT section_value,value FROM '. $table .' WHERE '. $object_type .'_id='. (int) $object_id );
|
|
$object = $this->db->loadRow();
|
|
|
|
if (empty($object)) {
|
|
$this->debug_text('del_object(): The specified object ('. strtoupper($object_type) .' ID: '. $object_id .') could not be found.<br />SQL = '.$this->db->stderr());
|
|
return FALSE;
|
|
}
|
|
|
|
$section_value = $object[0];
|
|
$value = $object[1];
|
|
|
|
// Get ids of acl referencing the Object (if any)
|
|
//$this->db->setQuery( "SELECT acl_id FROM $object_map_table WHERE value=" . $this->db->Quote( $value ) . " AND section_value=" . $this->db->Quote( $section_value ) );
|
|
//$acl_ids = $this->db->loadResultArray();
|
|
$acl_ids = array();
|
|
|
|
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
|
|
$this->db->setQuery( 'DELETE FROM '. $object_group_table .' WHERE '. $object_type .'_id='. (int) $object_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
$this->debug_db('edit_object');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ($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
|
|
$this->db->setQuery( "DELETE FROM $object_map_table WHERE section_value=" . $this->db->Quote( $section_value ) . " AND value=" . $this->db->Quote( $value ) );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$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
|
|
|
|
mosArrayToInts( $acl_ids );
|
|
$sql_acl_ids = implode(",", $acl_ids);
|
|
|
|
$this->db->setQuery( '
|
|
SELECT a.id
|
|
FROM '. $this->_db_table_prefix .'acl a
|
|
LEFT JOIN '. $object_map_table .' b ON a.id=b.acl_id
|
|
'./* <mos return for full acl stuff> LEFT JOIN '. $groups_map_table .' c ON a.id=c.acl_id*/'
|
|
WHERE value IS NULL
|
|
AND section_value IS NULL
|
|
AND group_id IS NULL
|
|
AND a.id in ('. $sql_acl_ids .')');
|
|
$orphan_acl_ids = $this->db->loadResultArray();
|
|
|
|
} // 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
|
|
$this->db->setQuery( "DELETE FROM $table WHERE {$object_type}_id=" . (int) $object_id );
|
|
$rs = $this->db->query();
|
|
|
|
if (!$rs) {
|
|
$this->debug_db('edit_object');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return false;
|
|
}
|
|
|
|
// <mos> $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 ;-)
|
|
|
|
$this->db->setQuery( 'SELECT group_id FROM '. $object_group_table .' WHERE '. $object_type .'_id='. (int) $object_id );
|
|
$groups_ids = $this->db->loadResultArray();
|
|
}
|
|
|
|
if ( ( isset($acl_ids) AND $acl_ids !== FALSE ) OR ( isset($groups_ids) AND $groups_ids !== FALSE) ) {
|
|
// 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($group_ids).") or ACLs (".@implode($acl_ids,",").")");
|
|
|
|
return false;
|
|
} else {
|
|
// The Object is NOT referenced anywhere, delete it
|
|
|
|
$this->db->setQuery( "DELETE FROM $table WHERE {$object_type}_id=" . (int) $object_id );
|
|
$this->db->query();
|
|
|
|
if ( $this->db->getErrorNum() ) {
|
|
$this->debug_db('edit_object');
|
|
// <mos> $this->db->RollBackTrans();
|
|
return false;
|
|
}
|
|
|
|
// <mos> $this->db->CommitTrans();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
*
|
|
* Object Sections
|
|
*
|
|
*/
|
|
|
|
/*======================================================================*\
|
|
Function: get_object_section_section_id()
|
|
Purpose: 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.
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: add_object_section()
|
|
Purpose: Inserts an object Section
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: edit_object_section()
|
|
Purpose: Edits a given Object Section
|
|
\*======================================================================*/
|
|
|
|
/*======================================================================*\
|
|
Function: del_object_section()
|
|
Purpose: Deletes a given Object Section and, if explicitly
|
|
asked, all the section objects
|
|
ERASE feature by: Martino Piccinato
|
|
\*======================================================================*/
|
|
|
|
/*
|
|
*
|
|
* Joomla! Utility Methods
|
|
*
|
|
*/
|
|
|
|
/*======================================================================*\
|
|
Function: has_group_parent
|
|
Purpose: Checks whether the 'source' group is a child of the 'target'
|
|
\*======================================================================*/
|
|
function is_group_child_of( $grp_src, $grp_tgt, $group_type='ARO' ) {
|
|
$this->debug_text("has_group_parent(): Source=$grp_src, Target=$grp_tgt, 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 (is_int( $grp_src ) && is_int($grp_tgt)) {
|
|
$this->db->setQuery( "SELECT COUNT(*)"
|
|
. "\nFROM $table AS g1"
|
|
. "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt"
|
|
. "\nWHERE g1.group_id=" . (int) $grp_src . " AND g2.group_id=" . (int) $grp_tgt
|
|
);
|
|
} else if (is_string( $grp_src ) && is_string($grp_tgt)) {
|
|
$this->db->setQuery( "SELECT COUNT(*)"
|
|
. "\nFROM $table AS g1"
|
|
. "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt"
|
|
. "\nWHERE g1.name=" . $this->db->Quote( $grp_src ) . " AND g2.name=" . $this->db->Quote( $grp_tgt )
|
|
);
|
|
} else if (is_int( $grp_src ) && is_string($grp_tgt)) {
|
|
$this->db->setQuery( "SELECT COUNT(*)"
|
|
. "\nFROM $table AS g1"
|
|
. "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt"
|
|
. "\nWHERE g1.group_id=" . (int) $grp_src . " AND g2.name=" . $this->db->Quote( $grp_tgt )
|
|
);
|
|
} else {
|
|
$this->db->setQuery( "SELECT COUNT(*)"
|
|
. "\nFROM $table AS g1"
|
|
. "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt"
|
|
. "\nWHERE g1.name=" . $this->db->Quote( $grp_src ) . " AND g2.group_id=" . (int) $grp_tgt
|
|
);
|
|
}
|
|
|
|
return $this->db->loadResult();
|
|
}
|
|
|
|
function getAroGroup( $value ) {
|
|
return $this->_getGroup( 'aro', $value );
|
|
}
|
|
|
|
function _getGroup( $type, $value ) {
|
|
global $database;
|
|
|
|
$database->setQuery( "SELECT g.*"
|
|
. "\nFROM #__core_acl_{$type}_groups AS g"
|
|
. "\nINNER JOIN #__core_acl_groups_{$type}_map AS gm ON gm.group_id = g.group_id"
|
|
. "\nINNER JOIN #__core_acl_{$type} AS ao ON ao.{$type}_id = gm.{$type}_id"
|
|
. "\nWHERE ao.value=" . $this->db->Quote( $value )
|
|
);
|
|
$obj = null;
|
|
$database->loadObject( $obj );
|
|
return $obj;
|
|
}
|
|
|
|
function _getAbove() {
|
|
}
|
|
|
|
function _getBelow( $table, $fields, $groupby=null, $root_id=null, $root_name=null, $inclusive=true ) {
|
|
global $database;
|
|
|
|
$root = new stdClass();
|
|
$root->lft = 0;
|
|
$root->rgt = 0;
|
|
|
|
if ($root_id) {
|
|
} else if ($root_name) {
|
|
$database->setQuery( "SELECT lft, rgt FROM $table WHERE name=" . $this->db->Quote( $root_name ) );
|
|
$database->loadObject( $root );
|
|
}
|
|
|
|
$where = '';
|
|
if ($root->lft+$root->rgt != 0) {
|
|
if ($inclusive) {
|
|
$where = "WHERE g1.lft BETWEEN " . (int) $root->lft . " AND " . (int) $root->rgt;
|
|
} else {
|
|
$where = "WHERE g1.lft BETWEEN " . (int) ($root->lft+1) . " AND " . (int) ($root->rgt-1);
|
|
}
|
|
}
|
|
|
|
$database->setQuery( "SELECT $fields"
|
|
. "\nFROM $table AS g1"
|
|
. "\nINNER JOIN $table AS g2 ON g1.lft BETWEEN g2.lft AND g2.rgt"
|
|
. "\n$where"
|
|
. ($groupby ? "\nGROUP BY $groupby" : "")
|
|
. "\nORDER BY g1.lft"
|
|
);
|
|
|
|
//echo $database->getQuery();
|
|
return $database->loadObjectList();
|
|
}
|
|
|
|
function get_group_children_tree( $root_id=null, $root_name=null, $inclusive=true ) {
|
|
global $database;
|
|
|
|
$tree = gacl_api::_getBelow( '#__core_acl_aro_groups',
|
|
'g1.group_id, g1.name, COUNT(g2.name) AS level',
|
|
'g1.name',
|
|
$root_id, $root_name, $inclusive );
|
|
|
|
// first pass get level limits
|
|
$n = count( $tree );
|
|
$min = $tree[0]->level;
|
|
$max = $tree[0]->level;
|
|
for ($i=0; $i < $n; $i++) {
|
|
$min = min( $min, $tree[$i]->level );
|
|
$max = max( $max, $tree[$i]->level );
|
|
}
|
|
|
|
$indents = array();
|
|
foreach (range( $min, $max ) as $i) {
|
|
$indents[$i] = ' ';
|
|
}
|
|
// correction for first indent
|
|
$indents[$min] = '';
|
|
|
|
$list = array();
|
|
for ($i=$n-1; $i >= 0; $i--) {
|
|
$shim = '';
|
|
foreach (range( $min, $tree[$i]->level ) as $j) {
|
|
$shim .= $indents[$j];
|
|
}
|
|
|
|
if (@$indents[$tree[$i]->level+1] == '. ') {
|
|
$twist = ' ';
|
|
} else {
|
|
$twist = "- ";
|
|
}
|
|
|
|
//$list[$i] = $tree[$i]->level.$shim.$twist.$tree[$i]->name;
|
|
$list[$i] = mosHTML::makeOption( $tree[$i]->group_id, $shim.$twist.$tree[$i]->name );
|
|
if ($tree[$i]->level < @$tree[$i-1]->level) {
|
|
$indents[$tree[$i]->level+1] = '. ';
|
|
}
|
|
}
|
|
|
|
ksort($list);
|
|
return $list;
|
|
}
|
|
}
|
|
|
|
class mosARO extends mosDBTable {
|
|
/** @var int Primary key */
|
|
var $aro_id=null;
|
|
var $section_value=null;
|
|
var $value=null;
|
|
var $order_value=null;
|
|
var $name=null;
|
|
var $hidden=null;
|
|
|
|
function mosARO( &$db ) {
|
|
$this->mosDBTable( '#__core_acl_aro', 'aro_id', $db );
|
|
}
|
|
|
|
/**
|
|
* Utility function for returning groups
|
|
*/
|
|
|
|
}
|
|
|
|
class mosAroGroup extends mosDBTable {
|
|
/** @var int Primary key */
|
|
var $group_id=null;
|
|
var $parent_id=null;
|
|
var $name=null;
|
|
var $lft=null;
|
|
var $rgt=null;
|
|
|
|
function mosAroGroup( &$db ) {
|
|
$this->mosDBTable( '#__core_acl_aro_groups', 'group_id', $db );
|
|
}
|
|
}
|
|
|
|
?>
|