| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * phpGACL - Generic Access Control List 4 * Copyright (C) 2002,2003 Mike Benoit 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * For questions, help, comments, discussion, etc., please join the 21 * phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103 22 * 23 * You may contact the author of phpGACL by e-mail at: 24 * ipso@snappymail.ca 25 * 26 * The latest version of phpGACL can be obtained from: 27 * http://phpgacl.sourceforge.net/ 28 * 29 * @package phpGACL 30 * 31 */ 32 33 // Check to ensure this file is within the rest of the framework 34 defined('JPATH_BASE') or die(); 35 36 /* 37 * 38 * For examples, see example.php or the Administration interface, 39 * as it makes use of nearly every API Call. 40 * 41 */ 42 /** 43 * gacl_api Extended API Class 44 * 45 * Class gacl_api should be used for applications that must interface directly with 46 * phpGACL's data structures, objects, and rules. 47 * 48 * @package phpGACL 49 * @author Mike Benoit <ipso@snappymail.ca> 50 * 51 */ 52 53 class gacl_api extends gacl { 54 55 /* 56 * 57 * Misc helper functions. 58 * 59 */ 60 61 /** 62 * showarray() 63 * 64 * Dump all contents of an array in HTML (kinda) 65 * 66 * @param array 67 * 68 */ 69 function showarray($array) { 70 echo "<br><pre>\n"; 71 var_dump($array); 72 echo "</pre><br>\n"; 73 } 74 75 /** 76 * count_all() 77 * 78 * Recursively counts elements in an array and sub-arrays. 79 * 80 * This is different from count($arg, COUNT_RECURSIVE) 81 * in PHP >= 4.2.0, which includes sub-arrays in the count. 82 * 83 * @return int The returned count is a count of all scalar elements found. 84 * 85 * @param array Array to count 86 */ 87 function count_all($arg = NULL) { 88 switch (TRUE) { 89 case is_scalar($arg): 90 case is_object($arg): 91 // single object 92 return 1; 93 case is_array($arg): 94 // call recursively for all elements of $arg 95 $count = 0; 96 foreach ($arg as $val) { 97 $count += $this->count_all($val); 98 } 99 return $count; 100 } 101 return FALSE; 102 } 103 104 /** 105 * get_version() 106 * 107 * Grabs phpGACL version from the database. 108 * 109 * @return string Version of phpGACL 110 */ 111 function get_version() { 112 $query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'version'"; 113 $version = $this->db->GetOne($query); 114 115 return $version; 116 } 117 118 /** 119 * get_schema_version() 120 * 121 * Grabs phpGACL schema version from the database. 122 * 123 * @return string Schema Version 124 */ 125 function get_schema_version() { 126 $query = "select value from ".$this->_db_table_prefix."phpgacl where name = 'schema_version'"; 127 $version = $this->db->GetOne($query); 128 129 return $version; 130 } 131 132 /* 133 * 134 * ACL 135 * 136 */ 137 138 /** 139 * consolidated_edit_acl() 140 * 141 * Add's an ACL but checks to see if it can consolidate it with another one first. 142 * 143 * This ONLY works with ACO's and ARO's. Groups, and AXO are excluded. 144 * As well this function is designed for handling ACLs with return values, 145 * and consolidating on the return_value, in hopes of keeping the ACL count to a minimum. 146 * 147 * A return value of false must _always_ be handled outside this function. 148 * As this function will remove AROs from ACLs and return false, in most cases 149 * you will need to a create a completely new ACL on a false return. 150 * 151 * @return bool Special boolean return value. See note. 152 * 153 * @param string ACO Section Value 154 * @param string ACO Value 155 * @param string ARO Section Value 156 * @param string ARO Value 157 * @param string Return Value of ACL 158 */ 159 function consolidated_edit_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, $return_value) { 160 161 $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"); 162 163 $acl_ids = array(); 164 165 if (empty($aco_section_value) ) { 166 $this->debug_text("consolidated_edit_acl(): ACO Section Value ($aco_section_value) is empty, this is required!"); 167 return false; 168 } 169 170 if (empty($aco_value) ) { 171 $this->debug_text("consolidated_edit_acl(): ACO Value ($aco_value) is empty, this is required!"); 172 return false; 173 } 174 175 if (empty($aro_section_value) ) { 176 $this->debug_text("consolidated_edit_acl(): ARO Section Value ($aro_section_value) is empty, this is required!"); 177 return false; 178 } 179 180 if (empty($aro_value) ) { 181 $this->debug_text("consolidated_edit_acl(): ARO Value ($aro_value) is empty, this is required!"); 182 return false; 183 } 184 185 if (empty($return_value) ) { 186 $this->debug_text("consolidated_edit_acl(): Return Value ($return_value) is empty, this is required!"); 187 return false; 188 } 189 190 //See if a current ACL exists with the current objects, excluding return value 191 $current_acl_ids = $this->search_acl($aco_section_value, $aco_value, $aro_section_value, $aro_value, FALSE, FALSE, FALSE, FALSE, FALSE); 192 //showarray($current_acl_ids); 193 194 if (is_array($current_acl_ids)) { 195 $this->debug_text("add_consolidated_acl(): Found current ACL_IDs, counting ACOs"); 196 197 foreach ($current_acl_ids as $current_acl_id) { 198 //Check to make sure these ACLs only have a single ACO mapped to them. 199 $current_acl_array = &$this->get_acl($current_acl_id); 200 201 //showarray($current_acl_array); 202 $this->debug_text("add_consolidated_acl(): Current Count: ".$this->count_all($current_acl_array['aco']).""); 203 204 if ( $this->count_all($current_acl_array['aco']) == 1) { 205 $this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO."); 206 207 //Test to see if the return values match, if they do, no need removing or appending ARO. Just return true. 208 if ($current_acl_array['return_value'] == $return_value) { 209 $this->debug_text("add_consolidated_acl(): ACL ID: $current_acl_id has 1 ACO, and the same return value. No need to modify."); 210 return true; 211 } 212 213 $acl_ids[] = $current_acl_id; 214 } 215 216 } 217 } 218 219 //showarray($acl_ids); 220 $acl_ids_count = count($acl_ids); 221 222 //If acl_id's turns up more then one ACL, lets remove the ARO from all of them in hopes to 223 //eliminate any conflicts. 224 if (is_array($acl_ids) AND $acl_ids_count > 0) { 225 $this->debug_text("add_consolidated_acl(): Removing specified ARO from existing ACL."); 226 227 foreach ($acl_ids as $acl_id) { 228 //Remove ARO from current ACLs, so we don't create conflicting ACLs later on. 229 if (!$this->shift_acl($acl_id, array($aro_section_value => array($aro_value)) ) ) { 230 $this->debug_text("add_consolidated_acl(): Error removing specified ARO from ACL ID: $acl_id"); 231 return false; 232 } 233 } 234 } else { 235 $this->debug_text("add_consolidated_acl(): Didn't find any current ACLs with a single ACO. "); 236 } 237 //unset($acl_ids); 238 $acl_ids = array(); 239 unset($acl_ids_count); 240 241 //At this point there should be no conflicting ACLs, searching for an existing ACL with the new values. 242 $new_acl_ids = $this->search_acl($aco_section_value, $aco_value, FALSE, FALSE, NULL, NULL, NULL, NULL, $return_value); 243 $new_acl_count = count($new_acl_ids); 244 //showarray($new_acl_ids); 245 246 if (is_array($new_acl_ids)) { 247 $this->debug_text("add_consolidated_acl(): Found new ACL_IDs, counting ACOs"); 248 249 foreach ($new_acl_ids as $new_acl_id) { 250 //Check to make sure these ACLs only have a single ACO mapped to them. 251 $new_acl_array = &$this->get_acl($new_acl_id); 252 //showarray($new_acl_array); 253 $this->debug_text("add_consolidated_acl(): New Count: ".$this->count_all($new_acl_array['aco']).""); 254 if ( $this->count_all($new_acl_array['aco']) == 1) { 255 256 $this->debug_text("add_consolidated_acl(): ACL ID: $new_acl_id has 1 ACO, append should be able to take place."); 257 $acl_ids[] = $new_acl_id; 258 } 259 260 } 261 } 262 263 //showarray($acl_ids); 264 $acl_ids_count = count($acl_ids); 265 266 if (is_array($acl_ids) AND $acl_ids_count == 1) { 267 $this->debug_text("add_consolidated_acl(): Appending specified ARO to existing ACL."); 268 269 $acl_id=$acl_ids[0]; 270 271 if (!$this->append_acl($acl_id, array($aro_section_value => array($aro_value)) ) ) { 272 $this->debug_text("add_consolidated_acl(): Error appending specified ARO to ACL ID: $acl_id"); 273 return false; 274 } 275 276 $this->debug_text("add_consolidated_acl(): Hot damn, ACL consolidated!"); 277 return true; 278 } elseif($acl_ids_count > 1) { 279 $this->debug_text("add_consolidated_acl(): Found more then one ACL with a single ACO. Possible conflicting ACLs."); 280 return false; 281 } elseif ($acl_ids_count == 0) { 282 $this->debug_text("add_consolidated_acl(): No existing ACLs found, create a new one."); 283 284 if (!$this->add_acl( array( $aco_section_value => array($aco_value) ), 285 array( $aro_section_value => array($aro_value) ), 286 NULL, 287 NULL, 288 NULL, 289 TRUE, 290 TRUE, 291 $return_value, 292 NULL) 293 ) { 294 $this->debug_text("add_consolidated_acl(): Error adding new ACL for ACO Section: $aco_section_value ACO Value: $aco_value Return Value: $return_value"); 295 return false; 296 } 297 298 $this->debug_text("add_consolidated_acl(): ADD_ACL() successfull, returning True."); 299 return true; 300 } 301 302 $this->debug_text("add_consolidated_acl(): Returning false."); 303 return false; 304 } 305 306 /** 307 * search_acl() 308 * 309 * Searches for ACL's with specified objects mapped to them. 310 * 311 * NULL values are included in the search, if you want to ignore 312 * for instance aro_groups use FALSE instead of NULL. 313 * 314 * @return array containing ACL IDs if search is successful 315 * 316 * @param string ACO Section Value 317 * @param string ACO Value 318 * @param string ARO Section Value 319 * @param string ARO Value 320 * @param string ARO Group Name 321 * @param string AXO Section Value 322 * @param string AXO Value 323 * @param string AXO Group Name 324 * @param string Return Value 325 */ 326 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) { 327 $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"); 328 329 $query = ' 330 SELECT a.id 331 FROM '. $this->_db_table_prefix .'acl a'; 332 333 $where_query = array(); 334 335 // ACO 336 if ($aco_section_value !== FALSE AND $aco_value !== FALSE) { 337 $query .= ' 338 LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON a.id=ac.acl_id'; 339 340 if ($aco_section_value == NULL AND $aco_value == NULL) { 341 $where_query[] = '(ac.section_value IS NULL AND ac.value IS NULL)'; 342 } else { 343 $where_query[] = '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value='. $this->db->quote($aco_value) .')'; 344 } 345 } 346 347 // ARO 348 if ($aro_section_value !== FALSE AND $aro_value !== FALSE) { 349 $query .= ' 350 LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON a.id=ar.acl_id'; 351 352 if ($aro_section_value == NULL AND $aro_value == NULL) { 353 $where_query[] = '(ar.section_value IS NULL AND ar.value IS NULL)'; 354 } else { 355 $where_query[] = '(ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value='. $this->db->quote($aro_value) .')'; 356 } 357 } 358 359 // AXO 360 if ($axo_section_value !== FALSE AND $axo_value !== FALSE) { 361 $query .= ' 362 LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON a.id=ax.acl_id'; 363 364 if ($axo_section_value == NULL AND $axo_value == NULL) { 365 $where_query[] = '(ax.section_value IS NULL AND ax.value IS NULL)'; 366 } else { 367 $where_query[] = '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value='. $this->db->quote($axo_value) .')'; 368 } 369 } 370 371 // ARO Group 372 if ($aro_group_name !== FALSE) { 373 $query .= ' 374 LEFT JOIN '. $this->_db_table_prefix .'aro_groups_map arg ON a.id=arg.acl_id 375 LEFT JOIN '. $this->_db_table_prefix .'aro_groups rg ON arg.group_id=rg.id'; 376 377 if ($aro_group_name == NULL) { 378 $where_query[] = '(rg.name IS NULL)'; 379 } else { 380 $where_query[] = '(rg.name='. $this->db->quote($aro_group_name) .')'; 381 } 382 } 383 384 // AXO Group 385 if ($axo_group_name !== FALSE) { 386 $query .= ' 387 LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON a.id=axg.acl_id 388 LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON axg.group_id=xg.id'; 389 390 if ($axo_group_name == NULL) { 391 $where_query[] = '(xg.name IS NULL)'; 392 } else { 393 $where_query[] = '(xg.name='. $this->db->quote($axo_group_name) .')'; 394 } 395 } 396 if ($return_value != FALSE) { 397 if ($return_value == NULL) { 398 $where_query[] = '(a.return_value IS NULL)'; 399 } else { 400 $where_query[] = '(a.return_value='. $this->db->quote($return_value) .')'; 401 } 402 } 403 404 if (count($where_query) > 0) { 405 $query .= ' 406 WHERE '. implode (' AND ', $where_query); 407 } 408 409 return $this->db->GetCol($query); 410 } 411 412 /** 413 * append_acl() 414 * 415 * Appends objects on to a specific ACL. 416 * 417 * @return bool TRUE if successful, FALSE otherwise. 418 * 419 * @param int ACL ID # 420 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 421 * @param array Array of Group IDs 422 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 423 * @param array Array of Group IDs 424 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 425 */ 426 function append_acl($acl_id, $aro_array=NULL, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $aco_array=NULL) { 427 $this->debug_text("append_acl(): ACL_ID: $acl_id"); 428 429 $update = 0; 430 431 if (empty($acl_id)) { 432 $this->debug_text("append_acl(): No ACL_ID specified! ACL_ID: $acl_id"); 433 return false; 434 } 435 436 //Grab ACL data. 437 $acl_array = &$this->get_acl($acl_id); 438 439 //Append each object type seperately. 440 if (is_array($aro_array) AND count($aro_array) > 0) { 441 $this->debug_text("append_acl(): Appending ARO's"); 442 443 while (list($aro_section_value,$aro_value_array) = @each($aro_array)) { 444 foreach ($aro_value_array as $aro_value) { 445 if ( count($acl_array['aro'][$aro_section_value]) != 0 ) { 446 if (!in_array($aro_value, $acl_array['aro'][$aro_section_value])) { 447 $this->debug_text("append_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value"); 448 $acl_array['aro'][$aro_section_value][] = $aro_value; 449 $update=1; 450 } else { 451 $this->debug_text("append_acl(): Duplicate ARO, ignoring... "); 452 } 453 } else { //Array is empty so add this aro value. 454 $acl_array['aro'][$aro_section_value][] = $aro_value; 455 $update = 1; 456 } 457 } 458 } 459 } 460 461 if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) { 462 $this->debug_text("append_acl(): Appending ARO_GROUP_ID's"); 463 464 while (list(,$aro_group_id) = @each($aro_group_ids)) { 465 if (!is_array($acl_array['aro_groups']) OR !in_array($aro_group_id, $acl_array['aro_groups'])) { 466 $this->debug_text("append_acl(): ARO Group ID: $aro_group_id"); 467 $acl_array['aro_groups'][] = $aro_group_id; 468 $update = 1; 469 } else { 470 $this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... "); 471 } 472 } 473 } 474 475 if (is_array($axo_array) AND count($axo_array) > 0) { 476 $this->debug_text("append_acl(): Appending AXO's"); 477 478 while (list($axo_section_value,$axo_value_array) = @each($axo_array)) { 479 foreach ($axo_value_array as $axo_value) { 480 if (!in_array($axo_value, $acl_array['axo'][$axo_section_value])) { 481 $this->debug_text("append_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value"); 482 $acl_array['axo'][$axo_section_value][] = $axo_value; 483 $update = 1; 484 } else { 485 $this->debug_text("append_acl(): Duplicate AXO, ignoring... "); 486 } 487 488 } 489 } 490 } 491 492 if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) { 493 $this->debug_text("append_acl(): Appending AXO_GROUP_ID's"); 494 while (list(,$axo_group_id) = @each($axo_group_ids)) { 495 if (!is_array($acl_array['axo_groups']) OR !in_array($axo_group_id, $acl_array['axo_groups'])) { 496 $this->debug_text("append_acl(): AXO Group ID: $axo_group_id"); 497 $acl_array['axo_groups'][] = $axo_group_id; 498 $update = 1; 499 } else { 500 $this->debug_text("append_acl(): Duplicate ARO_Group_ID, ignoring... "); 501 } 502 } 503 } 504 505 if (is_array($aco_array) AND count($aco_array) > 0) { 506 $this->debug_text("append_acl(): Appending ACO's"); 507 508 while (list($aco_section_value,$aco_value_array) = @each($aco_array)) { 509 foreach ($aco_value_array as $aco_value) { 510 if (!in_array($aco_value, $acl_array['aco'][$aco_section_value])) { 511 $this->debug_text("append_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value"); 512 $acl_array['aco'][$aco_section_value][] = $aco_value; 513 $update = 1; 514 } else { 515 $this->debug_text("append_acl(): Duplicate ACO, ignoring... "); 516 } 517 } 518 } 519 } 520 521 if ($update == 1) { 522 $this->debug_text("append_acl(): Update flag set, updating ACL."); 523 //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) { 524 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']); 525 } 526 527 //Return true if everything is duplicate and no ACL id updated. 528 $this->debug_text("append_acl(): Update flag not set, NOT updating ACL."); 529 return true; 530 } 531 532 /** 533 * shift_acl() 534 * 535 * Opposite of append_acl(). Removes objects from a specific ACL. (named after PHP's array_shift()) 536 * 537 * @return bool TRUE if successful, FALSE otherwise. 538 * 539 * @param int ACL ID # 540 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 541 * @param array Array of Group IDs 542 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 543 * @param array Array of Group IDs 544 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 545 */ 546 function shift_acl($acl_id, $aro_array=NULL, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $aco_array=NULL) { 547 $this->debug_text("shift_acl(): ACL_ID: $acl_id"); 548 549 $update = 0; 550 551 if (empty($acl_id)) { 552 $this->debug_text("shift_acl(): No ACL_ID specified! ACL_ID: $acl_id"); 553 return false; 554 } 555 556 //Grab ACL data. 557 $acl_array = &$this->get_acl($acl_id); 558 559 //showarray($acl_array); 560 //Remove each object type seperately. 561 if (is_array($aro_array) AND count($aro_array) > 0) { 562 $this->debug_text("shift_acl(): Removing ARO's"); 563 564 while (list($aro_section_value,$aro_value_array) = @each($aro_array)) { 565 foreach ($aro_value_array as $aro_value) { 566 $this->debug_text("shift_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value"); 567 568 //Only search if aro array contains data. 569 if ( count($acl_array['aro'][$aro_section_value]) != 0 ) { 570 $aro_key = array_search($aro_value, $acl_array['aro'][$aro_section_value]); 571 572 if ($aro_key !== FALSE) { 573 $this->debug_text("shift_acl(): Removing ARO. ($aro_key)"); 574 unset($acl_array['aro'][$aro_section_value][$aro_key]); 575 $update = 1; 576 } else { 577 $this->debug_text("shift_acl(): ARO doesn't exist, can't remove it."); 578 } 579 } 580 581 } 582 } 583 } 584 585 if (is_array($aro_group_ids) AND count($aro_group_ids) > 0) { 586 $this->debug_text("shift_acl(): Removing ARO_GROUP_ID's"); 587 588 while (list(,$aro_group_id) = @each($aro_group_ids)) { 589 $this->debug_text("shift_acl(): ARO Group ID: $aro_group_id"); 590 $aro_group_key = array_search($aro_group_id, $acl_array['aro_groups']); 591 592 if ($aro_group_key !== FALSE) { 593 $this->debug_text("shift_acl(): Removing ARO Group. ($aro_group_key)"); 594 unset($acl_array['aro_groups'][$aro_group_key]); 595 $update = 1; 596 } else { 597 $this->debug_text("shift_acl(): ARO Group doesn't exist, can't remove it."); 598 } 599 } 600 } 601 602 if (is_array($axo_array) AND count($axo_array) > 0) { 603 $this->debug_text("shift_acl(): Removing AXO's"); 604 605 while (list($axo_section_value,$axo_value_array) = @each($axo_array)) { 606 foreach ($axo_value_array as $axo_value) { 607 $this->debug_text("shift_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value"); 608 $axo_key = array_search($axo_value, $acl_array['axo'][$axo_section_value]); 609 610 if ($axo_key !== FALSE) { 611 $this->debug_text("shift_acl(): Removing AXO. ($axo_key)"); 612 unset($acl_array['axo'][$axo_section_value][$axo_key]); 613 $update = 1; 614 } else { 615 $this->debug_text("shift_acl(): AXO doesn't exist, can't remove it."); 616 } 617 } 618 } 619 } 620 621 if (is_array($axo_group_ids) AND count($axo_group_ids) > 0) { 622 $this->debug_text("shift_acl(): Removing AXO_GROUP_ID's"); 623 624 while (list(,$axo_group_id) = @each($axo_group_ids)) { 625 $this->debug_text("shift_acl(): AXO Group ID: $axo_group_id"); 626 $axo_group_key = array_search($axo_group_id, $acl_array['axo_groups']); 627 628 if ($axo_group_key !== FALSE) { 629 $this->debug_text("shift_acl(): Removing AXO Group. ($axo_group_key)"); 630 unset($acl_array['axo_groups'][$axo_group_key]); 631 $update = 1; 632 } else { 633 $this->debug_text("shift_acl(): AXO Group doesn't exist, can't remove it."); 634 } 635 } 636 } 637 638 if (is_array($aco_array) AND count($aco_array) > 0) { 639 $this->debug_text("shift_acl(): Removing ACO's"); 640 641 while (list($aco_section_value,$aco_value_array) = @each($aco_array)) { 642 foreach ($aco_value_array as $aco_value) { 643 $this->debug_text("shift_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value"); 644 $aco_key = array_search($aco_value, $acl_array['aco'][$aco_section_value]); 645 646 if ($aco_key !== FALSE) { 647 $this->debug_text("shift_acl(): Removing ACO. ($aco_key)"); 648 unset($acl_array['aco'][$aco_section_value][$aco_key]); 649 $update = 1; 650 } else { 651 $this->debug_text("shift_acl(): ACO doesn't exist, can't remove it."); 652 } 653 } 654 } 655 } 656 657 if ($update == 1) { 658 //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. 659 //$this->showarray($acl_array); 660 $this->debug_text("shift_acl(): ACOs: ". $this->count_all($acl_array['aco']) ." AROs: ".$this->count_all($acl_array['aro']).""); 661 662 if ( $this->count_all($acl_array['aco']) == 0 663 OR ( $this->count_all($acl_array['aro']) == 0 664 AND ( $this->count_all($acl_array['axo']) == 0 OR $acl_array['axo'] == FALSE) 665 AND (count($acl_array['aro_groups']) == 0 OR $acl_array['aro_groups'] == FALSE) 666 AND (count($acl_array['axo_groups']) == 0 OR $acl_array['axo_groups'] == FALSE) 667 ) ) { 668 $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."); 669 670 return $this->del_acl($acl_id); 671 } 672 673 $this->debug_text("shift_acl(): Update flag set, updating ACL."); 674 675 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']); 676 } 677 678 //Return true if everything is duplicate and no ACL id updated. 679 $this->debug_text("shift_acl(): Update flag not set, NOT updating ACL."); 680 return true; 681 } 682 683 /** 684 * get_acl() 685 * 686 * Grabs ACL data. 687 * 688 * @return mixed bool FALSE if not found, or Associative Array with the following items: 689 * 690 * - 'aco' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 691 * - 'aro' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 692 * - 'axo' => Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 693 * - 'aro_groups' => Array of Group IDs 694 * - 'axo_groups' => Array of Group IDs 695 * - 'acl_id' => int ACL ID # 696 * - 'allow' => int Allow flag 697 * - 'enabled' => int Enabled flag 698 * - 'return_value' => string Return Value 699 * - 'note' => string Note 700 * 701 * @param int ACL ID # 702 */ 703 function get_acl($acl_id) { 704 705 $this->debug_text("get_acl(): ACL_ID: $acl_id"); 706 707 if (empty($acl_id)) { 708 $this->debug_text("get_acl(): No ACL_ID specified! ACL_ID: $acl_id"); 709 return false; 710 } 711 $acl_id = (int) $acl_id; 712 713 //Grab ACL information 714 $query = "select id, allow, enabled, return_value, note from ".$this->_db_table_prefix."acl where id = ".$acl_id.""; 715 $acl_row = $this->db->GetRow($query); 716 717 // return false if not found 718 if (!$acl_row) { 719 $this->debug_text("get_acl(): No ACL found for that ID! ACL_ID: $acl_id"); 720 return false; 721 } 722 723 list($retarr['acl_id'], $retarr['allow'], $retarr['enabled'], $retarr['return_value'], $retarr['note']) = $acl_row; 724 725 //Grab selected ACO's 726 $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 727 where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id"; 728 $rs = $this->db->Execute($query); 729 $rows = $rs->GetRows(); 730 731 $retarr['aco'] = array(); 732 while (list(,$row) = @each($rows)) { 733 list($section_value, $value, $section, $aco) = $row; 734 $this->debug_text("Section Value: $section_value Value: $value Section: $section ACO: $aco"); 735 736 $retarr['aco'][$section_value][] = $value; 737 738 } 739 //showarray($aco); 740 741 //Grab selected ARO's 742 $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 743 where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id"; 744 $rs = $this->db->Execute($query); 745 $rows = $rs->GetRows(); 746 747 $retarr['aro'] = array(); 748 while (list(,$row) = @each($rows)) { 749 list($section_value, $value, $section, $aro) = $row; 750 $this->debug_text("Section Value: $section_value Value: $value Section: $section ARO: $aro"); 751 752 $retarr['aro'][$section_value][] = $value; 753 754 } 755 //showarray($options_aro); 756 757 //Grab selected AXO's 758 $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 759 where ( a.section_value=b.section_value AND a.value = b.value) AND b.section_value=c.value AND a.acl_id = $acl_id"; 760 $rs = $this->db->Execute($query); 761 $rows = $rs->GetRows(); 762 763 $retarr['axo'] = array(); 764 while (list(,$row) = @each($rows)) { 765 list($section_value, $value, $section, $axo) = $row; 766 $this->debug_text("Section Value: $section_value Value: $value Section: $section AXO: $axo"); 767 768 $retarr['axo'][$section_value][] = $value; 769 770 } 771 //showarray($options_aro); 772 773 //Grab selected ARO groups. 774 $retarr['aro_groups'] = array(); 775 $query = "select distinct group_id from ".$this->_db_table_prefix."aro_groups_map where acl_id = $acl_id"; 776 $retarr['aro_groups'] = $this->db->GetCol($query); 777 //showarray($selected_groups); 778 779 //Grab selected AXO groups. 780 $retarr['axo_groups'] = array(); 781 $query = "select distinct group_id from ".$this->_db_table_prefix."axo_groups_map where acl_id = $acl_id"; 782 $retarr['axo_groups'] = $this->db->GetCol($query); 783 //showarray($selected_groups); 784 785 return $retarr; 786 } 787 788 /** 789 * is_conflicting_acl() 790 * 791 * Checks for conflicts when adding a specific ACL. 792 * 793 * @return bool Returns true if conflict is found. 794 * 795 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 796 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 797 * @param array Array of Group IDs 798 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 799 * @param array Array of Group IDs 800 * @param array Array of ACL IDs to ignore from the result set. 801 * 802 */ 803 function is_conflicting_acl($aco_array, $aro_array, $aro_group_ids=NULL, $axo_array=NULL, $axo_group_ids=NULL, $ignore_acl_ids=NULL) { 804 //Check for potential conflicts. Ignore groups, as groups will almost always have "conflicting" ACLs. 805 //Thats part of inheritance. 806 807 if (!is_array($aco_array)) { 808 $this->debug_text('is_conflicting_acl(): Invalid ACO Array.'); 809 return FALSE; 810 } 811 812 if (!is_array($aro_array)) { 813 $this->debug_text('is_conflicting_acl(): Invalid ARO Array.'); 814 return FALSE; 815 } 816 817 $query = ' 818 SELECT a.id 819 FROM '. $this->_db_table_prefix .'acl a 820 LEFT JOIN '. $this->_db_table_prefix .'aco_map ac ON ac.acl_id=a.id 821 LEFT JOIN '. $this->_db_table_prefix .'aro_map ar ON ar.acl_id=a.id 822 LEFT JOIN '. $this->_db_table_prefix .'axo_map ax ON ax.acl_id=a.id 823 LEFT JOIN '. $this->_db_table_prefix .'axo_groups_map axg ON axg.acl_id=a.id 824 LEFT JOIN '. $this->_db_table_prefix .'axo_groups xg ON xg.id=axg.group_id 825 '; 826 827 //ACO 828 foreach ($aco_array as $aco_section_value => $aco_value_array) { 829 $this->debug_text("is_conflicting_acl(): ACO Section Value: $aco_section_value ACO VALUE: $aco_value_array"); 830 //showarray($aco_array); 831 832 if (!is_array($aco_value_array)) { 833 $this->debug_text('is_conflicting_acl(): Invalid Format for ACO Array item. Skipping...'); 834 continue; 835 // return TRUE; 836 } 837 //Move the below line in to the LEFT JOIN above for PostgreSQL sake. 838 //'ac1' => 'ac.acl_id=a.id', 839 $where_query = array( 840 'ac2' => '(ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value IN (\''. implode ('\',\'', $aco_value_array) .'\'))' 841 ); 842 843 //ARO 844 foreach ($aro_array as $aro_section_value => $aro_value_array) { 845 $this->debug_text("is_conflicting_acl(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value_array"); 846 847 if (!is_array($aro_value_array)) 848 { 849 $this->debug_text('is_conflicting_acl(): Invalid Format for ARO Array item. Skipping...'); 850 continue; 851 // return TRUE; 852 } 853 854 $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"); 855 856 //Move the below line in to the LEFT JOIN above for PostgreSQL sake. 857 //$where_query['ar1'] = 'ar.acl_id=a.id'; 858 $where_query['ar2'] = '(ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value IN (\''. implode ('\',\'', $aro_value_array) .'\'))'; 859 860 if (is_array($axo_array) AND count($axo_array) > 0) { 861 foreach ($axo_array as $axo_section_value => $axo_value_array) { 862 $this->debug_text("is_conflicting_acl(): AXO Section Value: $axo_section_value AXO VALUE: $axo_value_array"); 863 864 if (!is_array($axo_value_array)) { 865 $this->debug_text('is_conflicting_acl(): Invalid Format for AXO Array item. Skipping...'); 866 continue; 867 // return TRUE; 868 } 869 870 $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"); 871 872 //$where_query['ax1'] = 'ax.acl_id=x.id'; 873 $where_query['ax1'] = 'ax.acl_id=a.id'; 874 $where_query['ax2'] = '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value IN (\''. implode ('\',\'', $axo_value_array) .'\'))'; 875 876 $where = 'WHERE ' . implode(' AND ', $where_query); 877 878 $conflict_result = $this->db->GetCol($query . $where); 879 880 if (is_array($conflict_result) AND !empty($conflict_result)) { 881 // showarray($conflict_result); 882 883 if (is_array($ignore_acl_ids)) { 884 $conflict_result = array_diff($conflict_result, $ignore_acl_ids); 885 } 886 887 if (count($conflict_result) > 0) { 888 $conflicting_acls_str = implode(',', $conflict_result); 889 $this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)"); 890 return TRUE; 891 } 892 } 893 } 894 } else { 895 $where_query['ax1'] = '(ax.section_value IS NULL AND ax.value IS NULL)'; 896 $where_query['ax2'] = 'xg.name IS NULL'; 897 898 $where = 'WHERE ' . implode(' AND ', $where_query); 899 900 $conflict_result = $this->db->GetCol($query . $where); 901 902 if (is_array($conflict_result) AND !empty($conflict_result)) { 903 // showarray($conflict_result); 904 905 if (is_array($ignore_acl_ids)) { 906 $conflict_result = array_diff($conflict_result, $ignore_acl_ids); 907 } 908 909 if (count($conflict_result) > 0) { 910 $conflicting_acls_str = implode(',', $conflict_result); 911 $this->debug_text("is_conflicting_acl(): Conflict FOUND!!! ACL_IDS: ($conflicting_acls_str)"); 912 return TRUE; 913 } 914 } 915 } 916 } 917 } 918 919 $this->debug_text('is_conflicting_acl(): No conflicting ACL found.'); 920 return FALSE; 921 } 922 923 /** 924 * add_acl() 925 * 926 * Add's an ACL. ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays. 927 * 928 * @return bool Return ACL ID of new ACL if successful, FALSE otherewise. 929 * 930 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 931 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 932 * @param array Array of Group IDs 933 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 934 * @param array Array of Group IDs 935 * @param int Allow flag 936 * @param int Enabled flag 937 * @param string Return Value 938 * @param string Note 939 * @param string ACL Section Value 940 * @param int ACL ID # Specific Request 941 942 */ 943 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 ) { 944 945 $this->debug_text("add_acl():"); 946 947 if (count($aco_array) == 0) { 948 $this->debug_text("Must select at least one Access Control Object"); 949 return false; 950 } 951 952 if (count($aro_array) == 0 AND count($aro_group_ids) == 0) { 953 $this->debug_text("Must select at least one Access Request Object or Group"); 954 return false; 955 } 956 957 if (empty($allow)) { 958 $allow=0; 959 } 960 961 if (empty($enabled)) { 962 $enabled=0; 963 } 964 965 if (!empty($section_value) 966 AND !$this->get_object_section_section_id(NULL, $section_value, 'ACL')) { 967 $this->debug_text("add_acl(): Section Value: $section_value DOES NOT exist in the database."); 968 return false; 969 } 970 971 //Unique the group arrays. Later one we unique ACO/ARO/AXO arrays. 972 if (is_array($aro_group_ids)) { 973 $aro_group_ids = array_unique($aro_group_ids); 974 } 975 if (is_array($axo_group_ids)) { 976 $axo_group_ids = array_unique($axo_group_ids); 977 } 978 979 //Check for conflicting ACLs. 980 if ($this->is_conflicting_acl($aco_array,$aro_array,$aro_group_ids,$axo_array,$axo_group_ids,array($acl_id))) { 981 $this->debug_text("add_acl(): Detected possible ACL conflict, not adding ACL!"); 982 return false; 983 } 984 985 //Edit ACL if acl_id is set. This is simply if we're being called by edit_acl(). 986 if ($this->get_acl($acl_id) == FALSE) { 987 if ( empty($section_value) ) { 988 $section_value='system'; 989 if( !$this->get_object_section_section_id(NULL, $section_value, 'ACL') ) { 990 // Use the acl section with the lowest order value. 991 $acl_sections_table = $this->_db_table_prefix .'acl_sections'; 992 $acl_section_order_value = $this->db->GetOne("SELECT min(order_value) from $acl_sections_table"); 993 994 $query = " 995 SELECT value 996 FROM $acl_sections_table 997 WHERE order_value = $acl_section_order_value 998 "; 999 $section_value = $this->db->GetOne($query); 1000 1001 if ( empty($section_value) ) { 1002 $this->debug_text("add_acl(): No valid acl section found."); 1003 return false; 1004 } else { 1005 $this->debug_text("add_acl(): Using default section value: $section_value."); 1006 } 1007 } 1008 } 1009 1010 //ACL not specified, so create acl_id 1011 if (empty($acl_id)) { 1012 //Create ACL row first, so we have the acl_id 1013 $acl_id = $this->db->GenID($this->_db_table_prefix.'acl_seq',10); 1014 1015 //Double check the ACL ID was generated. 1016 if (empty($acl_id)) { 1017 // Not Required in Joomla! (yet) 1018 //$this->debug_text("add_acl(): ACL_ID generation failed!"); 1019 //return false; 1020 } 1021 } 1022 1023 //Begin transaction _after_ GenID. Because on the first run, if GenID has to create the sequence, 1024 //the transaction will fail. 1025 $this->db->BeginTrans(); 1026 1027 $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().')'; 1028 $result = $this->db->Execute($query); 1029 1030 // Joomla/MySQL 1031 $acl_id = $this->db->insertid(); 1032 } else { 1033 $section_sql = ''; 1034 if ( !empty($section_value) ) { 1035 $section_sql = 'section_value='. $this->db->quote ($section_value) .','; 1036 } 1037 1038 $this->db->BeginTrans(); 1039 1040 //Update ACL row, and remove all mappings so they can be re-inserted. 1041 $query = ' 1042 UPDATE '. $this->_db_table_prefix .'acl 1043 SET ' . $section_sql . ' 1044 allow='. (int) $allow .', 1045 enabled='. (int) $enabled .', 1046 return_value='. $this->db->quote($return_value) .', 1047 note='. $this->db->quote($note) .', 1048 updated_date='. time() .' 1049 WHERE id='. (int) $acl_id; 1050 $result = $this->db->Execute($query); 1051 1052 if ($result) { 1053 $this->debug_text("Update completed without error, delete mappings..."); 1054 //Delete all mappings so they can be re-inserted. 1055 foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) { 1056 $query = 'DELETE FROM '. $this->_db_table_prefix . $map .' WHERE acl_id='. (int) $acl_id; 1057 $rs = $this->db->Execute($query); 1058 1059 if (!is_object($rs)) 1060 { 1061 $this->debug_db('add_acl'); 1062 $this->db->RollBackTrans(); 1063 return FALSE; 1064 } 1065 } 1066 } 1067 } 1068 1069 if (!is_object($result)) { 1070 $this->debug_db('add_acl'); 1071 $this->db->RollBackTrans(); 1072 return false; 1073 } 1074 1075 $this->debug_text("Insert or Update completed without error, insert new mappings."); 1076 // Insert ACO/ARO/AXO mappings 1077 foreach (array('aco', 'aro', 'axo') as $map) { 1078 $map_array = ${$map .'_array'}; 1079 1080 if (!is_array ($map_array)) { 1081 continue; 1082 } 1083 1084 foreach ($map_array as $section_value => $value_array) { 1085 $this->debug_text ('Insert: '. strtoupper($map) .' Section Value: '. $section_value .' '. strtoupper($map) .' VALUE: '. $value_array); 1086 // $this->showarray ($aco_value_array); 1087 1088 if (!is_array($value_array)) { 1089 $this->debug_text ('add_acl (): Invalid Format for '. strtoupper ($map) .' Array item. Skipping...'); 1090 continue; 1091 // return true; 1092 } 1093 1094 $value_array = array_unique($value_array); 1095 1096 foreach ($value_array as $value) { 1097 $object_id = &$this->get_object_id($section_value, $value, $map); 1098 1099 if (empty($object_id)) 1100 { 1101 $this->debug_text('add_acl(): '. strtoupper($map) . " Object Section Value: $section_value Value: $value DOES NOT exist in the database. Skipping..."); 1102 $this->db->RollBackTrans(); 1103 return false; 1104 } 1105 1106 $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) .')'; 1107 $rs = $this->db->Execute($query); 1108 1109 if (!is_object($rs)) 1110 { 1111 $this->debug_db('add_acl'); 1112 $this->db->RollBackTrans(); 1113 return false; 1114 } 1115 } 1116 } 1117 } 1118 1119 // Insert ARO/AXO GROUP mappings 1120 foreach (array('aro', 'axo') as $map) { 1121 $map_group_ids = ${$map .'_group_ids'}; 1122 1123 if (!is_array($map_group_ids)) { 1124 continue; 1125 } 1126 1127 foreach ($map_group_ids as $group_id) { 1128 $this->debug_text ('Insert: '. strtoupper($map) .' GROUP ID: '. $group_id); 1129 1130 $group_data = &$this->get_group_data($group_id, $map); 1131 1132 if (empty($group_data)) { 1133 $this->debug_text('add_acl(): '. strtoupper($map) . " Group: $group_id DOES NOT exist in the database. Skipping..."); 1134 $this->db->RollBackTrans(); 1135 return false; 1136 } 1137 1138 $query = 'INSERT INTO '. $this->_db_table_prefix . $map .'_groups_map (acl_id,group_id) VALUES ('. (int) $acl_id .', '. (int) $group_id .')'; 1139 $rs = $this->db->Execute($query); 1140 1141 if (!is_object($rs)) { 1142 $this->debug_db('add_acl'); 1143 $this->db->RollBackTrans(); 1144 return false; 1145 } 1146 } 1147 } 1148 1149 $this->db->CommitTrans(); 1150 1151 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 1152 //Expire all cache. 1153 $this->Cache_Lite->clean('default'); 1154 } 1155 1156 //Return only the ID in the first row. 1157 return $acl_id; 1158 } 1159 1160 /** 1161 * edit_acl() 1162 * 1163 * Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays. 1164 * 1165 * @return bool Return TRUE if successful, FALSE otherewise. 1166 * 1167 * @param int ACL ID # to edit 1168 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 1169 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 1170 * @param array Array of Group IDs 1171 * @param array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 1172 * @param array Array of Group IDs 1173 * @param int Allow flag 1174 * @param int Enabled flag 1175 * @param string Return Value 1176 * @param string Note 1177 * @param string ACL Section Value 1178 */ 1179 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) { 1180 1181 $this->debug_text("edit_acl():"); 1182 1183 if (empty($acl_id) ) { 1184 $this->debug_text("edit_acl(): Must specify a single ACL_ID to edit"); 1185 return false; 1186 } 1187 if (count($aco_array) == 0) { 1188 $this->debug_text("edit_acl(): Must select at least one Access Control Object"); 1189 return false; 1190 } 1191 1192 if (count($aro_array) == 0 AND count($aro_group_ids) == 0) { 1193 $this->debug_text("edit_acl(): Must select at least one Access Request Object or Group"); 1194 return false; 1195 } 1196 1197 if (empty($allow)) { 1198 $allow=0; 1199 } 1200 1201 if (empty($enabled)) { 1202 $enabled=0; 1203 } 1204 1205 //if ($this->add_acl($aco_array, $aro_array, $group_ids, $allow, $enabled, $acl_id)) { 1206 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)) { 1207 return true; 1208 } else { 1209 $this->debug_text("edit_acl(): error in add_acl()"); 1210 return false; 1211 } 1212 } 1213 1214 /** 1215 * del_acl() 1216 * 1217 * Deletes a given ACL 1218 * 1219 * @return bool Returns TRUE if successful, FALSE otherwise. 1220 * 1221 * @param int ACL ID # to delete 1222 */ 1223 function del_acl($acl_id) { 1224 1225 $this->debug_text("del_acl(): ID: $acl_id"); 1226 1227 if (empty($acl_id) ) { 1228 $this->debug_text("del_acl(): ACL_ID ($acl_id) is empty, this is required"); 1229 return false; 1230 } 1231 1232 $this->db->BeginTrans(); 1233 1234 // Delete all mappings to the ACL first 1235 foreach (array('aco_map', 'aro_map', 'axo_map', 'aro_groups_map', 'axo_groups_map') as $map) { 1236 $query = 'DELETE FROM '. $this->_db_table_prefix . $map .' WHERE acl_id='. (int) $acl_id; 1237 $rs = $this->db->Execute($query); 1238 1239 if (!is_object($rs)) { 1240 $this->debug_db('del_acl'); 1241 $this->db->RollBackTrans(); 1242 return false; 1243 } 1244 } 1245 1246 // Delete the ACL 1247 $query = 'DELETE FROM '. $this->_db_table_prefix .'acl WHERE id='. (int) $acl_id; 1248 $this->debug_text('delete query: '. $query); 1249 $rs = $this->db->Execute($query); 1250 1251 if (!is_object($rs)) { 1252 $this->debug_db('del_acl'); 1253 $this->db->RollBackTrans(); 1254 return false; 1255 } 1256 1257 $this->debug_text("del_acl(): deleted ACL ID: $acl_id"); 1258 $this->db->CommitTrans(); 1259 1260 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 1261 //Expire all cache. 1262 $this->Cache_Lite->clean('default'); 1263 } 1264 1265 return TRUE; 1266 } 1267 1268 1269 /* 1270 * 1271 * Groups 1272 * 1273 */ 1274 1275 /** 1276 * sort_groups() 1277 * 1278 * Grabs all the groups from the database doing preliminary grouping by parent 1279 * 1280 * @return array Returns 2-Dimensional array: $array[<parent_id>][<group_id>] = <group_name> 1281 * 1282 * @param string Group Type, either 'ARO' or 'AXO' 1283 */ 1284 function sort_groups($group_type='ARO') { 1285 1286 switch(strtolower(trim($group_type))) { 1287 case 'axo': 1288 $table = $this->_db_table_prefix .'axo_groups'; 1289 break; 1290 default: 1291 $table = $this->_db_table_prefix .'aro_groups'; 1292 break; 1293 } 1294 1295 //Grab all groups from the database. 1296 $query = 'SELECT id, parent_id, name FROM '. $table .' ORDER BY parent_id, name'; 1297 $rs = $this->db->Execute($query); 1298 1299 if (!is_object($rs)) { 1300 $this->debug_db('sort_groups'); 1301 return false; 1302 } 1303 1304 /* 1305 * Save groups in an array sorted by parent. Should be make it easier for later on. 1306 */ 1307 $sorted_groups = array(); 1308 1309 while ($row = $rs->FetchRow()) { 1310 $id = &$row[0]; 1311 $parent_id = &$row[1]; 1312 $name = &$row[2]; 1313 1314 $sorted_groups[$parent_id][$id] = $name; 1315 } 1316 1317 return $sorted_groups; 1318 } 1319 1320 /** 1321 * format_groups() 1322 * 1323 * Takes the array returned by sort_groups() and formats for human 1324 * consumption. Recursively calls itself to produce the desired output. 1325 * 1326 * @return array Array of formatted text, ordered by group id, formatted according to $type 1327 * 1328 * @param array Output from gacl_api->sorted_groups($group_type) 1329 * @param array Output type desired, either 'TEXT', 'TEXT_ASSOC', 'HTML', 'ARRAY' or 'ASSOC' 1330 * @param int Root of tree to produce 1331 * @param int Current level of depth 1332 * @param array Pass the current formatted groups object for appending via recursion. 1333 */ 1334 function format_groups($sorted_groups, $type='TEXT', $root_id=0, $level=0, $formatted_groups=NULL) { 1335 1336 if ( !is_array ($sorted_groups) ) { 1337 return FALSE; 1338 } 1339 1340 if ( !is_array ($formatted_groups) ) { 1341 $formatted_groups = array (); 1342 } 1343 1344 $type = strtoupper($type); 1345 1346 //$this->showarray($formatted_groups); 1347 1348 //while (list($id,$name) = @each($sorted_groups[$root_id])) { 1349 if (isset($sorted_groups[$root_id])) { 1350 $temp = array_keys( $sorted_groups[$root_id] ); 1351 $last_id = end( $temp ); 1352 1353 foreach ($sorted_groups[$root_id] as $id => $name) { 1354 switch ($type) { 1355 case 'TEXT': 1356 case 'TEXT_ASSOC': 1357 /* 1358 * Formatting optimized for TEXT (combo box) output. 1359 */ 1360 1361 if ( is_numeric($level) ) { 1362 $level = str_repeat(' ', $level); 1363 } 1364 1365 if ( strlen($level) >= 8 ) { 1366 if ( $id == $last_id ) { 1367 $spacing = substr($level, 0, -8) .'\'- '; 1368 $level = substr($level, 0, -8) .' '; 1369 } else { 1370 $spacing = substr($level, 0, -8) .'|- '; 1371 } 1372 } else { 1373 $spacing = $level; 1374 } 1375 1376 $next = $level .'| '; 1377 1378 if ($type == 'TEXT_ASSOC') { 1379 $formatted_groups[] = array( 'value'=>$id, 'text'=>$spacing.$name ); 1380 } else { 1381 $formatted_groups[$id] = $spacing.$name; 1382 } 1383 break; 1384 case 'HTML': 1385 /* 1386 * Formatting optimized for HTML (tables) output. 1387 */ 1388 $width = $level * 12; 1389 $spacing = "<img src=\"images/blank.png\" width=\"$width\" height=\"0\" alt=\"\" />"; 1390 $next = $level + 1; 1391 $formatted_groups[$id] = $spacing." ".$name; 1392 break; 1393 case 'ARRAY': 1394 $next = $level; 1395 $formatted_groups[$id] = $name; 1396 break; 1397 case 'ASSOC': 1398 /* 1399 * Formatting optimized for HTML: <option value="value">text</option>. 1400 */ 1401 $next = $level; 1402 $formatted_groups[] = array( 'value'=>$id, 'text'=>$name, 'level'=>$level ); 1403 break; 1404 default: 1405 return FALSE; 1406 } 1407 1408 /* 1409 * Recurse if we can. 1410 */ 1411 1412 //if (isset($sorted_groups[$id]) AND count($sorted_groups[$id]) > 0) { 1413 if (isset($sorted_groups[$id]) ) { 1414 //$this->debug_text("format_groups(): Recursing! Level: $level"); 1415 $formatted_groups = $this->format_groups($sorted_groups, $type, $id, $next, $formatted_groups); 1416 } else { 1417 //$this->debug_text("format_groups(): Found last branch!"); 1418 } 1419 } 1420 } 1421 1422 //$this->debug_text("format_groups(): Returning final array."); 1423 1424 return $formatted_groups; 1425 } 1426 1427 /** 1428 * get_group_id() 1429 * 1430 * Gets the group_id given the name or value. 1431 * 1432 * Will only return one group id, so if there are duplicate names, it will return false. 1433 * 1434 * @return int Returns Group ID if found and Group ID is unique in database, otherwise, returns FALSE 1435 * 1436 * @param string Group Value 1437 * @param string Group Name 1438 * @param string Group Type, either 'ARO' or 'AXO' 1439 */ 1440 function get_group_id($value = NULL, $name = NULL, $group_type = 'ARO') { 1441 1442 $this->debug_text("get_group_id(): Value: $value, Name: $name, Type: $group_type" ); 1443 1444 switch(strtolower(trim($group_type))) { 1445 case 'axo': 1446 $table = $this->_db_table_prefix .'axo_groups'; 1447 break; 1448 default: 1449 $table = $this->_db_table_prefix .'aro_groups'; 1450 break; 1451 } 1452 1453 $name = trim($name); 1454 $value = trim($value); 1455 1456 if (empty($name) AND $value === '') { 1457 $this->debug_text("get_group_id(): name and value, at least one is required"); 1458 return false; 1459 } 1460 1461 $query = 'SELECT id FROM '. $table .' WHERE '; 1462 if ($value !== '') { 1463 $query .= ' value='. $this->db->quote($value); 1464 } else { 1465 $query .= ' name='. $this->db->quote($name); 1466 } 1467 1468 $this->db->setQuery( $query ); 1469 1470 $rows = $this->db->loadResultArray(); 1471 if ($this->db->getErrorNum()) { 1472 $this->debug_db('get_group_id'); 1473 return false; 1474 } 1475 1476 $row_count = count( $rows ); 1477 1478 if ($row_count > 1) { 1479 $this->debug_text("get_group_id(): Returned $row_count rows, can only return one. Please make your names unique."); 1480 return false; 1481 } 1482 1483 if ($row_count == 0) { 1484 $this->debug_text("get_group_id(): Returned $row_count rows"); 1485 return false; 1486 } 1487 1488 //Return the ID. 1489 return $rows[0]; 1490 } 1491 1492 /** 1493 * get_group_children() 1494 * 1495 * Gets a groups child IDs 1496 * 1497 * @return array Array of Child ID's of the referenced group 1498 * 1499 * @param int Group ID # 1500 * @param int Group Type, either 'ARO' or 'AXO' 1501 * @param string Either 'RECURSE' or 'NO_RECURSE', to recurse while fetching group children. 1502 */ 1503 function get_group_children($group_id, $group_type = 'ARO', $recurse = 'NO_RECURSE') { 1504 $this->debug_text("get_group_children(): Group_ID: $group_id Group Type: $group_type Recurse: $recurse"); 1505 1506 switch (strtolower(trim($group_type))) { 1507 case 'axo': 1508 $group_type = 'axo'; 1509 $table = $this->_db_table_prefix .'axo_groups'; 1510 break; 1511 default: 1512 $group_type = 'aro'; 1513 $table = $this->_db_table_prefix .'aro_groups'; 1514 } 1515 1516 if (empty($group_id)) { 1517 $this->debug_text("get_group_children(): ID ($group_id) is empty, this is required"); 1518 return FALSE; 1519 } 1520 1521 $query = ' 1522 SELECT g1.id 1523 FROM '. $table .' g1'; 1524 1525 //FIXME-mikeb: Why is group_id in quotes? 1526 switch (strtoupper($recurse)) { 1527 case 'RECURSE': 1528 $query .= ' 1529 LEFT JOIN '. $table .' g2 ON g2.lft<g1.lft AND g2.rgt>g1.rgt 1530 WHERE g2.id='. (int) $group_id; 1531 break; 1532 default: 1533 $query .= ' 1534 WHERE g1.parent_id='. (int) $group_id; 1535 } 1536 1537 $query .= ' 1538 ORDER BY g1.value'; 1539 1540 return $this->db->GetCol($query); 1541 } 1542 1543 /** 1544 * get_group_data() 1545 * 1546 * Gets the group data given the GROUP_ID. 1547 * 1548 * @return array Returns numerically indexed array with the following columns: 1549 * - array[0] = (int) Group ID # 1550 * - array[1] = (int) Parent Group ID # 1551 * - array[2] = (string) Group Value 1552 * - array[3] = (string) Group Name 1553 * - array[4] = (int) lft MPTT Value 1554 * - array[5] = (int) rgt MPTT Value 1555 * 1556 * @param int Group ID # 1557 * @param string Group Type, either 'ARO' or 'AXO' 1558 */ 1559 function get_group_data($group_id, $group_type = 'ARO') { 1560 1561 $this->debug_text("get_group_data(): Group_ID: $group_id Group Type: $group_type"); 1562 1563 switch(strtolower(trim($group_type))) { 1564 case 'axo': 1565 $group_type = 'axo'; 1566 $table = $this->_db_table_prefix .'axo_groups'; 1567 break; 1568 default: 1569 $group_type = 'aro'; 1570 $table = $this->_db_table_prefix .'aro_groups'; 1571 break; 1572 } 1573 1574 if (empty($group_id) ) { 1575 $this->debug_text("get_group_data(): ID ($group_id) is empty, this is required"); 1576 return false; 1577 } 1578 1579 $query = 'SELECT id, parent_id, value, name, lft, rgt FROM '. $table .' WHERE id='. (int) $group_id; 1580 //$rs = $this->db->Execute($query); 1581 $row = $this->db->GetRow($query); 1582 1583 if ($row) { 1584 return $row; 1585 } 1586 1587 $this->debug_text("get_object_data(): Group does not exist."); 1588 return false; 1589 } 1590 1591 /** 1592 * get_group_parent_id() 1593 * 1594 * Grabs the parent_id of a given group 1595 * 1596 * @return int Parent ID of the Group 1597 * 1598 * @param int Group ID # 1599 * @param string Group Type, either 'ARO' or 'AXO' 1600 */ 1601 function get_group_parent_id($id, $group_type='ARO') { 1602 1603 $this->debug_text("get_group_parent_id(): ID: $id Group Type: $group_type"); 1604 1605 switch(strtolower(trim($group_type))) { 1606 case 'axo': 1607 $table = $this->_db_table_prefix .'axo_groups'; 1608 break; 1609 default: 1610 $table = $this->_db_table_prefix .'aro_groups'; 1611 break; 1612 } 1613 1614 if (empty($id) ) { 1615 $this->debug_text("get_group_parent_id(): ID ($id) is empty, this is required"); 1616 return false; 1617 } 1618 1619 $query = 'SELECT parent_id FROM '. $table .' WHERE id='. (int) $id; 1620 $rs = $this->db->Execute($query); 1621 1622 if (!is_object($rs)) { 1623 $this->debug_db('get_group_parent_id'); 1624 return false; 1625 } 1626 1627 $row_count = $rs->RecordCount(); 1628 1629 if ($row_count > 1) { 1630 $this->debug_text("get_group_parent_id(): Returned $row_count rows, can only return one. Please make your names unique."); 1631 return false; 1632 } 1633 1634 if ($row_count == 0) { 1635 $this->debug_text("get_group_parent_id(): Returned $row_count rows"); 1636 return false; 1637 } 1638 1639 $row = $rs->FetchRow(); 1640 1641 //Return the ID. 1642 return $row[0]; 1643 } 1644 1645 1646 /** 1647 * get_root_group_id () 1648 * 1649 * Grabs the id of the root group for the specified tree 1650 * 1651 * @return int Root Group ID # 1652 * 1653 * @param string Group Type, either 'ARO' or 'AXO' 1654 */ 1655 function get_root_group_id($group_type='ARO') { 1656 1657 $this->debug_text('get_root_group_id(): Group Type: '. $group_type); 1658 1659 switch (strtolower($group_type)) { 1660 case 'axo': 1661 $table = $this->_db_table_prefix .'axo_groups'; 1662 break; 1663 case 'aro': 1664 $table = $this->_db_table_prefix .'aro_groups'; 1665 break; 1666 default: 1667 $this->debug_text('get_root_group_id(): Invalid Group Type: '. $group_type); 1668 return FALSE; 1669 } 1670 1671 $query = 'SELECT id FROM '. $table .' WHERE parent_id=0'; 1672 $rs = $this->db->Execute($query); 1673 1674 if (!is_object($rs)) { 1675 $this->debug_db('get_root_group_id'); 1676 return FALSE; 1677 } 1678 1679 $row_count = $rs->RecordCount(); 1680 1681 switch ($row_count) { 1682 case 1: 1683 $row = $rs->FetchRow(); 1684 // Return the ID. 1685 return $row[0]; 1686 case 0: 1687 $this->debug_text('get_root_group_id(): Returned 0 rows, you do not have a root group defined yet.'); 1688 return FALSE; 1689 } 1690 1691 $this->debug_text('get_root_group_id(): Returned '. $row_count .' rows, can only return one. Your tree is very broken.'); 1692 return FALSE; 1693 } 1694 1695 /*======================================================================*\ 1696 Function: map_path_to_root() 1697 Purpose: Maps a unique path to root to a specific group. Each group can only have 1698 one path to root. 1699 \*======================================================================*/ 1700 /** REMOVED **/ 1701 /*======================================================================*\ 1702 Function: put_path_to_root() 1703 Purpose: Writes the unique path to root to the database. There should really only be 1704 one path to root for each level "deep" the groups go. If the groups are branched 1705 10 levels deep, there should only be 10 unique path to roots. These of course 1706 overlap each other more and more the closer to the root/trunk they get. 1707 \*======================================================================*/ 1708 /** REMOVED **/ 1709 /*======================================================================*\ 1710 Function: clean_path_to_root() 1711 Purpose: Cleans up any paths that are not being used. 1712 \*======================================================================*/ 1713 /** REMOVED **/ 1714 /*======================================================================*\ 1715 Function: get_path_to_root() 1716 Purpose: Generates the path to root for a given group. 1717 \*======================================================================*/ 1718 /** REMOVED **/ 1719 1720 /** 1721 * add_group() 1722 * 1723 * Inserts a group, defaults to be on the "root" branch. 1724 * 1725 * Since v3.3.x you can only create one group with Parent_ID=0 1726 * So, its a good idea to create a "Virtual Root" group with Parent_ID=0 1727 * Then assign other groups to that. 1728 * 1729 * @return int New Group ID # if successful, FALSE if otherwise. 1730 * 1731 * @param string Group Value 1732 * @param string Group Name 1733 * @param int Parent Group ID # 1734 * @param string Group Type, either 'ARO' or 'AXO' 1735 */ 1736 function add_group($value, $name, $parent_id=0, $group_type='ARO') { 1737 1738 switch(strtolower(trim($group_type))) { 1739 case 'axo': 1740 $group_type = 'axo'; 1741 $table = $this->_db_table_prefix .'axo_groups'; 1742 break; 1743 default: 1744 $group_type = 'aro'; 1745 $table = $this->_db_table_prefix .'aro_groups'; 1746 break; 1747 } 1748 1749 $this->debug_text("add_group(): Name: $name Value: $value Parent ID: $parent_id Group Type: $group_type"); 1750 1751 $name = trim($name); 1752 $value = trim($value); 1753 1754 if ( $name == '' ) { 1755 $this->debug_text("add_group(): name ($name) OR parent id ($parent_id) is empty, this is required"); 1756 return false; 1757 } 1758 1759 //This has to be outside the transaction, because the first time it is run, it will say the sequence 1760 //doesn't exist. Then try to create it, but the transaction will already by aborted by then. 1761 $insert_id = $this->db->GenID($table.'_id_seq', $this->_defaultGenID( $table )); 1762 if ( $value === '' ) { 1763 $value = $insert_id; 1764 } 1765 1766 $this->db->BeginTrans(); 1767 1768 // special case for root group 1769 if ($parent_id == 0) { 1770 // check a root group is not already defined 1771 $query = 'SELECT id FROM '. $table .' WHERE parent_id=0'; 1772 $rs = $this->db->Execute($query); 1773 1774 if (!is_object($rs)) { 1775 $this->debug_db('add_group'); 1776 $this->db->RollBackTrans(); 1777 return FALSE; 1778 } 1779 1780 if ($rs->RowCount() > 0) { 1781 $this->debug_text('add_group (): A root group already exists.'); 1782 $this->db->RollBackTrans(); 1783 return FALSE; 1784 } 1785 1786 $parent_lft = 0; 1787 $parent_rgt = 1; 1788 } else { 1789 if (empty($parent_id)) { 1790 $this->debug_text("add_group (): parent id ($parent_id) is empty, this is required"); 1791 $this->db->RollbackTrans(); 1792 return FALSE; 1793 } 1794 1795 // grab parent details from database 1796 $query = 'SELECT id, lft, rgt FROM '. $table .' WHERE id='. (int) $parent_id; 1797 $row = $this->db->GetRow($query); 1798 1799 if (!is_array($row)) { 1800 $this->debug_db('add_group'); 1801 $this->db->RollBackTrans(); 1802 return FALSE; 1803 } 1804 1805 if (empty($row)) { 1806 $this->debug_text('add_group (): Parent ID: '. $parent_id .' not found.'); 1807 $this->db->RollBackTrans(); 1808 return FALSE; 1809 } 1810 1811 $parent_lft = &$row[1]; 1812 $parent_rgt = &$row[2]; 1813 1814 // make room for the new group 1815 $query = 'UPDATE '. $table .' SET rgt=rgt+2 WHERE rgt>='. (int) $parent_rgt; 1816 $rs = $this->db->Execute($query); 1817 1818 if (!is_object($rs)) { 1819 $this->debug_db('add_group'); 1820 $this->db->RollBackTrans(); 1821 return FALSE; 1822 } 1823 1824 $query = 'UPDATE '. $table .' SET lft=lft+2 WHERE lft>'. $parent_rgt; 1825 $rs = $this->db->Execute($query); 1826 1827 if (!is_object($rs)) { 1828 $this->debug_db('add_group'); 1829 $this->db->RollBackTrans(); 1830 return FALSE; 1831 } 1832 } 1833 1834 $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) .')'; 1835 $rs = $this->db->Execute($query); 1836 1837 if (!is_object($rs)) { 1838 $this->debug_db('add_group'); 1839 $this->db->RollBackTrans(); 1840 return FALSE; 1841 } 1842 1843 $this->db->CommitTrans(); 1844 1845 // Joomla/MySQL 1846 $insert_id = $this->db->insertid(); 1847 1848 $this->debug_text('add_group (): Added group as ID: '. $insert_id); 1849 return $insert_id; 1850 } 1851 1852 /** 1853 * get_group_objects() 1854 * 1855 * Gets all objects assigned to a group. 1856 * 1857 * If $option == 'RECURSE' it will get all objects in child groups as well. 1858 * defaults to omit child groups. 1859 * 1860 * @return array Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 1861 1862 * 1863 * @param int Group ID # 1864 * @param string Group Type, either 'ARO' or 'AXO' 1865 * @param string Option, either 'RECURSE' or 'NO_RECURSE' 1866 */ 1867 function get_group_objects($group_id, $group_type='ARO', $option='NO_RECURSE') { 1868 1869 switch(strtolower(trim($group_type))) { 1870 case 'axo': 1871 $group_type = 'axo'; 1872 $object_table = $this->_db_table_prefix .'axo'; 1873 $group_table = $this->_db_table_prefix .'axo_groups'; 1874 $map_table = $this->_db_table_prefix .'groups_axo_map'; 1875 break; 1876 default: 1877 $group_type = 'aro'; 1878 $object_table = $this->_db_table_prefix .'aro'; 1879 $group_table = $this->_db_table_prefix .'aro_groups'; 1880 $map_table = $this->_db_table_prefix .'groups_aro_map'; 1881 break; 1882 } 1883 1884 $this->debug_text("get_group_objects(): Group ID: $group_id"); 1885 1886 if (empty($group_id)) { 1887 $this->debug_text("get_group_objects(): Group ID: ($group_id) is empty, this is required"); 1888 return false; 1889 } 1890 1891 $query = ' 1892 SELECT o.section_value,o.value'; 1893 1894 if ($option == 'RECURSE') { 1895 $query .= ' 1896 FROM '. $group_table .' g2 1897 JOIN '. $group_table .' g1 ON g1.lft>=g2.lft AND g1.rgt<=g2.rgt 1898 JOIN '. $map_table .' AS gm ON gm.group_id=g1.id 1899 JOIN '. $object_table .' AS o ON o.id=gm.'. $group_type .'_id 1900 WHERE g2.id='. (int) $group_id; 1901 } else { 1902 $query .= ' 1903 FROM '. $map_table .' AS gm 1904 JOIN '. $object_table .' AS o ON o.id=gm.'. $group_type .'_id 1905 WHERE gm.group_id='. (int) $group_id; 1906 } 1907 1908 $rs = $this->db->Execute($query); 1909 1910 if (!is_object($rs)) { 1911 $this->debug_db('get_group_objects'); 1912 return false; 1913 } 1914 1915 $this->debug_text("get_group_objects(): Got group objects, formatting array."); 1916 1917 $retarr = array(); 1918 1919 //format return array. 1920 while ($row = $rs->FetchRow()) { 1921 $section = &$row[0]; 1922 $value = &$row[1]; 1923 1924 $retarr[$section][] = $value; 1925 } 1926 1927 return $retarr; 1928 } 1929 1930 /** 1931 * add_group_object() 1932 * 1933 * Assigns an Object to a group 1934 * 1935 * @return bool Returns TRUE if successful, FALSE otherwise. 1936 * 1937 * @param int Group ID # 1938 * @param string Object Section Value 1939 * @param string Object Value 1940 * @param string Group Type, either 'ARO' or 'AXO' 1941 */ 1942 function add_group_object($group_id, $object_section_value, $object_value, $group_type='ARO') { 1943 1944 switch(strtolower(trim($group_type))) { 1945 case 'axo': 1946 $group_type = 'axo'; 1947 $table = $this->_db_table_prefix .'groups_axo_map'; 1948 $object_table = $this->_db_table_prefix .'axo'; 1949 $group_table = $this->_db_table_prefix .'axo_groups'; 1950 break; 1951 default: 1952 $group_type = 'aro'; 1953 $table = $this->_db_table_prefix .'groups_aro_map'; 1954 $object_table = $this->_db_table_prefix .'aro'; 1955 $group_table = $this->_db_table_prefix .'aro_groups'; 1956 break; 1957 } 1958 1959 $this->debug_text("add_group_object(): Group ID: $group_id Section Value: $object_section_value Value: $object_value Group Type: $group_type"); 1960 1961 $object_section_value = trim($object_section_value); 1962 $object_value = trim($object_value); 1963 1964 if (empty($group_id) OR $object_value === '' OR $object_section_value === '') { 1965 $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"); 1966 return false; 1967 } 1968 1969 // test to see if object & group exist and if object is already a member 1970 $query = ' 1971 SELECT o.id AS id,g.id AS group_id,gm.group_id AS member 1972 FROM '. $object_table .' o 1973 LEFT JOIN '. $group_table .' g ON g.id='. (int) $group_id .' 1974 LEFT JOIN '. $table .' gm ON (gm.'. $group_type .'_id=o.id AND gm.group_id=g.id) 1975 WHERE (o.section_value='. $this->db->quote($object_section_value) .' AND o.value='. $this->db->quote($object_value) .')'; 1976 $rs = $this->db->Execute($query); 1977 1978 if (!is_object($rs)) { 1979 $this->debug_db('add_group_object'); 1980 return FALSE; 1981 } 1982 1983 if ($rs->RecordCount() != 1) { 1984 $this->debug_text('add_group_object(): Value ('. $object_value .') OR Section value ('. $object_section_value .') is invalid. Does this object exist?'); 1985 return FALSE; 1986 } 1987 1988 $row = $rs->FetchRow(); 1989 1990 if ($row[1] != $group_id) { 1991 $this->debug_text('add_group_object(): Group ID ('. $group_id .') is invalid. Does this group exist?'); 1992 return FALSE; 1993 } 1994 1995 //Group_ID == Member 1996 if ($row[1] == $row[2]) { 1997 $this->debug_text('add_group_object(): Object: ('. $object_section_value .' -> '. $object_value .') is already a member of Group: ('. $group_id .')'); 1998 //Object is already assigned to group. Return true. 1999 return TRUE; 2000 } 2001 2002 $object_id = $row[0]; 2003 2004 $query = 'INSERT INTO '. $table .' (group_id,'. $group_type .'_id) VALUES ('. (int) $group_id .','. (int) $object_id .')'; 2005 $rs = $this->db->Execute($query); 2006 2007 if (!is_object($rs)) { 2008 $this->debug_db('add_group_object'); 2009 return FALSE; 2010 } 2011 2012 $this->debug_text('add_group_object(): Added Object: '. $object_id .' to Group ID: '. $group_id); 2013 2014 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 2015 //Expire all cache. 2016 $this->Cache_Lite->clean('default'); 2017 } 2018 2019 return TRUE; 2020 } 2021 2022 /** 2023 * del_group_object() 2024 * 2025 * Removes an Object from a group. 2026 * 2027 * @return bool Returns TRUE if successful, FALSE otherwise 2028 * 2029 * @param int Group ID # 2030 * @param string Object Section Value 2031 * @param string Object Value 2032 * @param string Group Type, either 'ARO' or 'AXO' 2033 */ 2034 function del_group_object($group_id, $object_section_value, $object_value, $group_type='ARO') { 2035 2036 switch(strtolower(trim($group_type))) { 2037 case 'axo': 2038 $group_type = 'axo'; 2039 $table = $this->_db_table_prefix .'groups_axo_map'; 2040 break; 2041 default: 2042 $group_type = 'aro'; 2043 $table = $this->_db_table_prefix .'groups_aro_map'; 2044 break; 2045 } 2046 2047 $this->debug_text("del_group_object(): Group ID: $group_id Section value: $object_section_value Value: $object_value"); 2048 2049 $object_section_value = trim($object_section_value); 2050 $object_value = trim($object_value); 2051 2052 if (empty($group_id) OR $object_value === '' OR $object_section_value === '') { 2053 $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"); 2054 return false; 2055 } 2056 2057 if (!$object_id = $this->get_object_id($object_section_value, $object_value, $group_type)) { 2058 $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?"); 2059 return FALSE; 2060 } 2061 2062 $query = 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id .' AND '. $group_type .'_id='. (int) $object_id; 2063 $rs = $this->db->Execute($query); 2064 2065 if (!is_object($rs)) { 2066 $this->debug_db('del_group_object'); 2067 return false; 2068 } 2069 2070 $this->debug_text("del_group_object(): Deleted Value: $object_value to Group ID: $group_id assignment"); 2071 2072 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 2073 //Expire all cache. 2074 $this->Cache_Lite->clean('default'); 2075 } 2076 2077 return true; 2078 } 2079 2080 /** 2081 * edit_group() 2082 * 2083 * Edits a group 2084 * 2085 * @returns bool Returns TRUE if successful, FALSE otherwise 2086 * 2087 * @param int Group ID # 2088 * @param string Group Value 2089 * @param string Group Name 2090 * @param int Parent ID # 2091 * @param string Group Type, either 'ARO' or 'AXO' 2092 */ 2093 function edit_group($group_id, $value=NULL, $name=NULL, $parent_id=NULL, $group_type='ARO') { 2094 $this->debug_text("edit_group(): ID: $group_id Name: $name Value: $value Parent ID: $parent_id Group Type: $group_type"); 2095 2096 switch(strtolower(trim($group_type))) { 2097 case 'axo': 2098 $group_type = 'axo'; 2099 $table = $this->_db_table_prefix .'axo_groups'; 2100 break; 2101 default: 2102 $group_type = 'aro'; 2103 $table = $this->_db_table_prefix .'aro_groups'; 2104 break; 2105 } 2106 2107 if (empty($group_id) ) { 2108 $this->debug_text('edit_group(): Group ID ('. $group_id .') is empty, this is required'); 2109 return FALSE; 2110 } 2111 2112 if ( !is_array($curr = $this->get_group_data($group_id, $group_type)) ) { 2113 $this->debug_text('edit_group(): Invalid Group ID: '. $group_id); 2114 return FALSE; 2115 } 2116 2117 $name = trim($name); 2118 2119 // don't set name if it is unchanged 2120 if ($name == $curr[3]) { 2121 unset($name); 2122 } 2123 2124 // don't set parent_id if it is unchanged 2125 if ($parent_id == $curr[1]) { 2126 unset($parent_id); 2127 } 2128 2129 if (!empty($parent_id)) { 2130 if ($group_id == $parent_id) { 2131 $this->debug_text('edit_group(): Groups can\'t be a parent to themselves. Incest is bad. ;)'); 2132 return FALSE; 2133 } 2134 2135 //Make sure we don't re-parent to our own children. 2136 //Grab all children of this group_id. 2137 $children_ids = $this->get_group_children($group_id, $group_type, 'RECURSE'); 2138 if (is_array($children_ids)) { 2139 if (@in_array($parent_id, $children_ids) ) { 2140 $this->debug_text('edit_group(): Groups can\'t be re-parented to their own children, this would be incestuous!'); 2141 return FALSE; 2142 } 2143 } 2144 unset($children_ids); 2145 2146 // make sure parent exists 2147 if (!$this->get_group_data($parent_id, $group_type)) { 2148 $this->debug_text('edit_group(): Parent Group ('. $parent_id .') doesn\'t exist'); 2149 return FALSE; 2150 } 2151 } 2152 2153 $set = array(); 2154 2155 // update name if it is specified. 2156 if (!empty($name)) { 2157 $set[] = 'name='. $this->db->quote($name); 2158 } 2159 2160 // update parent_id if it is specified. 2161 if (!empty($parent_id)) { 2162 $set[] = 'parent_id='. (int) $parent_id; 2163 } 2164 2165 // update value if it is specified. 2166 if ($value !== '' OR $value !== null) { 2167 $set[] = 'value='. $this->db->quote($value); 2168 } 2169 2170 if (empty($set)) { 2171 $this->debug_text('edit_group(): Nothing to update.'); 2172 return FALSE; 2173 } 2174 2175 $this->db->BeginTrans(); 2176 2177 $query = 'UPDATE '. $table .' SET '. implode(',', $set) .' WHERE id='. (int) $group_id; 2178 $rs = $this->db->Execute($query); 2179 2180 if (!is_object($rs)) { 2181 $this->debug_db('edit_group'); 2182 $this->db->RollbackTrans(); 2183 return FALSE; 2184 } 2185 2186 $this->debug_text('edit_group(): Modified group ID: '. $group_id); 2187 2188 // rebuild group tree if parent_id has changed 2189 if (!empty($parent_id)) { 2190 if (!$this->_rebuild_tree($table, $this->get_root_group_id($group_type))) { 2191 $this->db->RollbackTrans(); 2192 return FALSE; 2193 } 2194 } 2195 2196 $this->db->CommitTrans(); 2197 2198 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 2199 // Expire all cache. 2200 $this->Cache_Lite->clean('default'); 2201 } 2202 2203 return TRUE; 2204 } 2205 2206 /** 2207 * rebuild_tree () 2208 * 2209 * rebuilds the group tree for the given type 2210 * 2211 * @return bool Returns TRUE if successful, FALSE otherwise 2212 * 2213 * @param string Group Type, either 'ARO' or 'AXO' 2214 * @param int Group ID # 2215 * @param int Left value of Group 2216 */ 2217 function rebuild_tree($group_type = 'ARO', $group_id = NULL, $left = 1) { 2218 $this->debug_text("rebuild_tree(): Group Type: $group_type Group ID: $group_id Left: $left"); 2219 2220 switch (strtolower(trim($group_type))) { 2221 case 'axo': 2222 $group_type = 'axo'; 2223 $table = $this->_db_table_prefix .'axo_groups'; 2224 break; 2225 default: 2226 $group_type = 'aro'; 2227 $table = $this->_db_table_prefix .'aro_groups'; 2228 break; 2229 } 2230 2231 if (!isset($group_id)) { 2232 if ($group_id = $this->get_root_group_id($group_type)) { 2233 $left = 1; 2234 $this->debug_text('rebuild_tree(): No Group ID Specified, using Root Group ID: '. $group_id); 2235 } else { 2236 $this->debug_text('rebuild_tree(): A Root group could not be found, are there any groups defined?'); 2237 return FALSE; 2238 } 2239 } 2240 2241 $this->db->BeginTrans(); 2242 $rebuilt = $this->_rebuild_tree($table, $group_id, $left); 2243 2244 if ($rebuilt === FALSE) { 2245 $this->debug_text('rebuild_tree(): Error rebuilding tree!'); 2246 $this->db->RollBackTrans(); 2247 return FALSE; 2248 } 2249 2250 $this->db->CommitTrans(); 2251 $this->debug_text('rebuild_tree(): Tree rebuilt.'); 2252 return TRUE; 2253 } 2254 /** 2255 * _rebuild_tree () 2256 * 2257 * Utility recursive function called by rebuild_tree() 2258 * 2259 * @return int Returns right value of this node + 1 2260 * 2261 * @param string Table name of group type 2262 * @param int Group ID # 2263 * @param int Left value of Group 2264 */ 2265 function _rebuild_tree($table, $group_id, $left = 1) { 2266 $this->debug_text("_rebuild_tree(): Table: $table Group ID: $group_id Left: $left"); 2267 2268 // get all children of this node 2269 $query = 'SELECT id FROM '. $table .' WHERE parent_id='. (int) $group_id; 2270 $rs = $this->db->Execute($query); 2271 2272 if (!is_object($rs)) { 2273 $this->debug_db('_rebuild_tree'); 2274 return FALSE; 2275 } 2276 2277 // the right value of this node is the left value + 1 2278 $right = $left + 1; 2279 2280 while ($row = $rs->FetchRow()) { 2281 // recursive execution of this function for each 2282 // child of this node 2283 // $right is the current right value, which is 2284 // incremented by the rebuild_tree function 2285 $right = $this->_rebuild_tree($table, $row[0], $right); 2286 2287 if ($right === FALSE) { 2288 return FALSE; 2289 } 2290 } 2291 2292 // we've got the left value, and now that we've processed 2293 // the children of this node we also know the right value 2294 $query = 'UPDATE '. $table .' SET lft='. (int) $left .', rgt='. (int) $right .' WHERE id='. (int) $group_id; 2295 $rs = $this->db->Execute($query); 2296 2297 if (!is_object($rs)) { 2298 $this->debug_db('_rebuild_tree'); 2299 return FALSE; 2300 } 2301 2302 // return the right value of this node + 1 2303 return $right + 1; 2304 } 2305 2306 /** 2307 * del_group() 2308 * 2309 * deletes a given group 2310 * 2311 * @return bool Returns TRUE if successful, FALSE otherwise. 2312 * 2313 * @param int Group ID # 2314 * @param bool If TRUE, child groups of this group will be reparented to the current group's parent. 2315 * @param string Group Type, either 'ARO' or 'AXO' 2316 */ 2317 function del_group($group_id, $reparent_children=TRUE, $group_type='ARO') { 2318 2319 switch(strtolower(trim($group_type))) { 2320 case 'axo': 2321 $group_type = 'axo'; 2322 $table = $this->_db_table_prefix .'axo_groups'; 2323 $groups_map_table = $this->_db_table_prefix .'axo_groups_map'; 2324 $groups_object_map_table = $this->_db_table_prefix .'groups_axo_map'; 2325 break; 2326 default: 2327 $group_type = 'aro'; 2328 $table = $this->_db_table_prefix .'aro_groups'; 2329 $groups_map_table = $this->_db_table_prefix .'aro_groups_map'; 2330 $groups_object_map_table = $this->_db_table_prefix .'groups_aro_map'; 2331 break; 2332 } 2333 2334 $this->debug_text("del_group(): ID: $group_id Reparent Children: $reparent_children Group Type: $group_type"); 2335 2336 if (empty($group_id) ) { 2337 $this->debug_text("del_group(): Group ID ($group_id) is empty, this is required"); 2338 return false; 2339 } 2340 2341 // Get details of this group 2342 $query = 'SELECT id, parent_id, name, lft, rgt FROM '. $table .' WHERE id='. (int) $group_id; 2343 $group_details = $this->db->GetRow($query); 2344 2345 if (!is_array($group_details)) { 2346 $this->debug_db('del_group'); 2347 return false; 2348 } 2349 2350 $parent_id = $group_details[1]; 2351 2352 $left = $group_details[3]; 2353 $right = $group_details[4]; 2354 2355 $this->db->BeginTrans(); 2356 2357 // grab list of all children 2358 $children_ids = $this->get_group_children($group_id, $group_type, 'RECURSE'); 2359 2360 // prevent deletion of root group & reparent of children if it has more than one immediate child 2361 if ($parent_id == 0) { 2362 $query = 'SELECT count(*) FROM '. $table .' WHERE parent_id='. (int) $group_id; 2363 $child_count = $this->db->GetOne($query); 2364 2365 if (($child_count > 1) AND $reparent_children) { 2366 $this->debug_text ('del_group (): You cannot delete the root group and reparent children, this would create multiple root groups.'); 2367 $this->db->RollbackTrans(); 2368 return FALSE; 2369 } 2370 } 2371 2372 $success = FALSE; 2373 2374 /* 2375 * Handle children here. 2376 */ 2377 switch (TRUE) { 2378 // there are no child groups, just delete group 2379 case !is_array($children_ids): 2380 case count($children_ids) == 0: 2381 // remove acl maps 2382 $query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. (int) $group_id; 2383 $rs = $this->db->Execute($query); 2384 2385 if (!is_object($rs)) { 2386 break; 2387 } 2388 2389 // remove group object maps 2390 $query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id; 2391 $rs = $this->db->Execute($query); 2392 2393 if (!is_object($rs)) { 2394 break; 2395 } 2396 2397 // remove group 2398 $query = 'DELETE FROM '. $table .' WHERE id='. (int) $group_id; 2399 $rs = $this->db->Execute($query); 2400 2401 if (!is_object($rs)) { 2402 break; 2403 } 2404 2405 // move all groups right of deleted group left by width of deleted group 2406 $query = 'UPDATE '. $table .' SET lft=lft-'. (int)($right-$left+1) .' WHERE lft>'. (int) $right; 2407 $rs = $this->db->Execute($query); 2408 2409 if (!is_object($rs)) { 2410 break; 2411 } 2412 2413 $query = 'UPDATE '. $table .' SET rgt=rgt-'. (int)($right-$left+1) .' WHERE rgt>'. (int) $right; 2414 $rs = $this->db->Execute($query); 2415 2416 if (!is_object($rs)) { 2417 break; 2418 } 2419 2420 $success = TRUE; 2421 break; 2422 case $reparent_children == TRUE: 2423 // remove acl maps 2424 $query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. (int) $group_id; 2425 $rs = $this->db->Execute($query); 2426 2427 if (!is_object($rs)) { 2428 break; 2429 } 2430 2431 // remove group object maps 2432 $query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id; 2433 $rs = $this->db->Execute($query); 2434 2435 if (!is_object($rs)) { 2436 break; 2437 } 2438 2439 // remove group 2440 $query = 'DELETE FROM '. $table .' WHERE id='. (int) $group_id; 2441 $rs = $this->db->Execute($query); 2442 2443 if (!is_object($rs)) { 2444 break; 2445 } 2446 2447 // set parent of immediate children to parent group 2448 $query = 'UPDATE '. $table .' SET parent_id='. (int) $parent_id .' WHERE parent_id='. (int) $group_id; 2449 $rs = $this->db->Execute($query); 2450 2451 if (!is_object($rs)) { 2452 break; 2453 } 2454 2455 // move all children left by 1 2456 $query = 'UPDATE '. $table .' SET lft=lft-1, rgt=rgt-1 WHERE lft>'. (int) $left .' AND rgt<'. (int) $right; 2457 $rs = $this->db->Execute($query); 2458 2459 if (!is_object($rs)) { 2460 break; 2461 } 2462 2463 // move all groups right of deleted group left by 2 2464 $query = 'UPDATE '. $table .' SET lft=lft-2 WHERE lft>'. (int) $right; 2465 $rs = $this->db->Execute($query); 2466 2467 if (!is_object($rs)) { 2468 break; 2469 } 2470 2471 $query = 'UPDATE '. $table .' SET rgt=rgt-2 WHERE rgt>'. (int) $right; 2472 $rs = $this->db->Execute($query); 2473 2474 if (!is_object($rs)) { 2475 break; 2476 } 2477 2478 $success = TRUE; 2479 break; 2480 default: 2481 // make list of group and all children 2482 $group_ids = $children_ids; 2483 $group_ids[] = (int) $group_id; 2484 2485 // remove acl maps 2486 $query = 'DELETE FROM '. $groups_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')'; 2487 $rs = $this->db->Execute($query); 2488 2489 if (!is_object($rs)) { 2490 break; 2491 } 2492 2493 // remove group object maps 2494 $query = 'DELETE FROM '. $groups_object_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')'; 2495 $rs = $this->db->Execute($query); 2496 2497 if (!is_object($rs)) { 2498 break; 2499 } 2500 2501 // remove groups 2502 $query = 'DELETE FROM '. $table .' WHERE id IN ('. implode (',', $group_ids) .')'; 2503 $rs = $this->db->Execute($query); 2504 2505 if (!is_object($rs)) { 2506 break; 2507 } 2508 2509 // move all groups right of deleted group left by width of deleted group 2510 $query = 'UPDATE '. $table .' SET lft=lft-'. ($right - $left + 1) .' WHERE lft>'. (int) $right; 2511 $rs = $this->db->Execute($query); 2512 2513 if (!is_object($rs)) { 2514 break; 2515 } 2516 2517 $query = 'UPDATE '. $table .' SET rgt=rgt-'. ($right - $left + 1) .' WHERE rgt>'. (int) $right; 2518 $rs = $this->db->Execute($query); 2519 2520 if (!is_object($rs)) { 2521 break; 2522 } 2523 2524 $success = TRUE; 2525 } 2526 2527 // if the delete failed, rollback the trans and return false 2528 if (!$success) { 2529 2530 $this->debug_db('del_group'); 2531 $this->db->RollBackTrans(); 2532 return false; 2533 } 2534 2535 $this->debug_text("del_group(): deleted group ID: $group_id"); 2536 $this->db->CommitTrans(); 2537 2538 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 2539 //Expire all cache. 2540 $this->Cache_Lite->clean('default'); 2541 } 2542 2543 return true; 2544 2545 } 2546 2547 2548 /* 2549 * 2550 * Objects (ACO/ARO/AXO) 2551 * 2552 */ 2553 2554 /** 2555 * get_object() 2556 * 2557 * Grabs all Objects's in the database, or specific to a section_value 2558 * 2559 * @return ADORecordSet Returns recordset directly, with object ID only selected: 2560 * 2561 * @param string Filter to this section value 2562 * @param int Returns hidden objects if 1, leaves them out otherwise. 2563 * @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL' 2564 */ 2565 function get_object($section_value = null, $return_hidden=1, $object_type=NULL) { 2566 2567 switch(strtolower(trim($object_type))) { 2568 case 'aco': 2569 $object_type = 'aco'; 2570 $table = $this->_db_table_prefix .'aco'; 2571 break; 2572 case 'aro': 2573 $object_type = 'aro'; 2574 $table = $this->_db_table_prefix .'aro'; 2575 break; 2576 case 'axo': 2577 $object_type = 'axo'; 2578 $table = $this->_db_table_prefix .'axo'; 2579 break; 2580 case 'acl': 2581 $object_type = 'acl'; 2582 $table = $this->_db_table_prefix .'acl'; 2583 break; 2584 default: 2585 $this->debug_text('get_object(): Invalid Object Type: '. $object_type); 2586 return FALSE; 2587 } 2588 2589 $this->debug_text("get_object(): Section Value: $section_value Object Type: $object_type"); 2590 2591 $query = 'SELECT id FROM '. $table; 2592 2593 $where = array(); 2594 2595 if (!empty($section_value)) { 2596 $where[] = 'section_value='. $this->db->quote($section_value); 2597 } 2598 2599 if ($return_hidden==0 AND $object_type != 'acl') { 2600 $where[] = 'hidden=0'; 2601 } 2602 2603 if (!empty($where)) { 2604 $query .= ' WHERE '. implode(' AND ', $where); 2605 } 2606 2607 $rs = $this->db->GetCol($query); 2608 2609 if (!is_array($rs)) { 2610 $this->debug_db('get_object'); 2611 return false; 2612 } 2613 2614 // Return Object IDs 2615 return $rs; 2616 } 2617 /** 2618 * get_ungrouped_objects() 2619 * 2620 * Grabs ID's of all Objects (ARO's and AXO's only) in the database not assigned to a Group. 2621 * 2622 * This function is useful for applications that synchronize user databases with an outside source. 2623 * If syncrhonization doesn't automatically place users in an appropriate group, this function can 2624 * quickly identify them so that they can be assigned to the correct group. 2625 * 2626 * @return array Returns an array of object ID's 2627 * 2628 * @param int Returns hidden objects if 1, does not if 0. 2629 * @param string Object Type, either 'ARO' or 'AXO' (groupable types) 2630 */ 2631 2632 function get_ungrouped_objects($return_hidden=1, $object_type=NULL) { 2633 2634 switch(strtolower(trim($object_type))) { 2635 case 'aro': 2636 $object_type = 'aro'; 2637 $table = $this->_db_table_prefix .'aro'; 2638 break; 2639 case 'axo': 2640 $object_type = 'axo'; 2641 $table = $this->_db_table_prefix .'axo'; 2642 break; 2643 default: 2644 $this->debug_text('get_ungrouped_objects(): Invalid Object Type: '. $object_type); 2645 return FALSE; 2646 } 2647 2648 $this->debug_text("get_ungrouped_objects(): Object Type: $object_type"); 2649 2650 $query = 'SELECT id FROM '. $table . ' 2651 LEFT JOIN groups_' . $table . '_map 2652 ON ' . $table . '.id = groups_' . $table . '_map.' . $table . '_id'; 2653 2654 $where = array(); 2655 $where[] = 'groups_' . $table . '_map.group_id IS NULL'; 2656 2657 if ($return_hidden==0) { 2658 $where[] = 'a.hidden=0'; 2659 } 2660 2661 if (!empty($where)) { 2662 $query .= ' WHERE '. implode(' AND ', $where); 2663 } 2664 2665 $rs = $this->db->Execute($query); 2666 2667 if (!is_object($rs)) { 2668 $this->debug_db('get_ungrouped_objects'); 2669 return false; 2670 } 2671 2672 while(!$rs->EOF) { 2673 $retarr[] = $rs->fields[0]; 2674 $rs->MoveNext(); 2675 } 2676 2677 // Return Array of object IDS 2678 return $retarr; 2679 } 2680 2681 2682 /** 2683 * get_objects () 2684 * 2685 * Grabs all Objects in the database, or specific to a section_value 2686 * 2687 * @return array Returns objects in format suitable for add_acl and is_conflicting_acl 2688 * - i.e. Associative array, item={Section Value}, key={Array of Object Values} i.e. ["<Section Value>" => ["<Value 1>", "<Value 2>", "<Value 3>"], ...] 2689 * 2690 * @param string Filter for section value 2691 * @param int Returns hidden objects if 1, does not if 0 2692 * @param string Object Type, either 'ACO', 'ARO', 'AXO' 2693 */ 2694 function get_objects($section_value = NULL, $return_hidden = 1, $object_type = NULL) { 2695 switch (strtolower(trim($object_type))) { 2696 case 'aco': 2697 $object_type = 'aco'; 2698 $table = $this->_db_table_prefix .'aco'; 2699 break; 2700 case 'aro': 2701 $object_type = 'aro'; 2702 $table = $this->_db_table_prefix .'aro'; 2703 break; 2704 case 'axo': 2705 $object_type = 'axo'; 2706 $table = $this->_db_table_prefix .'axo'; 2707 break; 2708 default: 2709 $this->debug_text('get_objects(): Invalid Object Type: '. $object_type); 2710 return FALSE; 2711 } 2712 2713 $this->debug_text("get_objects(): Section Value: $section_value Object Type: $object_type"); 2714 2715 $query = 'SELECT section_value,value FROM '. $table; 2716 2717 $where = array(); 2718 2719 if (!empty($section_value)) { 2720 $where[] = 'section_value='. $this->db->quote($section_value); 2721 } 2722 2723 if ($return_hidden==0) { 2724 $where[] = 'hidden=0'; 2725 } 2726 2727 if (!empty($where)) { 2728 $query .= ' WHERE '. implode(' AND ', $where); 2729 } 2730 2731 $rs = $this->db->Execute($query); 2732 2733 if (!is_object($rs)) { 2734 $this->debug_db('get_objects'); 2735 return FALSE; 2736 } 2737 2738 $retarr = array(); 2739 2740 while ($row = $rs->FetchRow()) { 2741 $retarr[$row[0]][] = $row[1]; 2742 } 2743 2744 // Return objects 2745 return $retarr; 2746 } 2747 2748 /** 2749 * get_object_data() 2750 * 2751 * Gets all data pertaining to a specific Object. 2752 * 2753 * @return array Returns 2-Dimensional array of rows with columns = ( section_value, value, order_value, name, hidden ) 2754 * 2755 * @param int Object ID # 2756 * @param string Object Type, either 'ACO', 'ARO', 'AXO' 2757 */ 2758 function get_object_data($object_id, $object_type=NULL) { 2759 2760 switch(strtolower(trim($object_type))) { 2761 case 'aco': 2762 $object_type = 'aco'; 2763 $table = $this->_db_table_prefix .'aco'; 2764 break; 2765 case 'aro': 2766 $object_type = 'aro'; 2767 $table = $this->_db_table_prefix .'aro'; 2768 break; 2769 case 'axo': 2770 $object_type = 'axo'; 2771 $table = $this->_db_table_prefix .'axo'; 2772 break; 2773 default: 2774 $this->debug_text('get_object_data(): Invalid Object Type: '. $object_type); 2775 return FALSE; 2776 } 2777 2778 $this->debug_text("get_object_data(): Object ID: $object_id Object Type: $object_type"); 2779 2780 if (empty($object_id) ) { 2781 $this->debug_text("get_object_data(): Object ID ($object_id) is empty, this is required"); 2782 return false; 2783 } 2784 2785 if (empty($object_type) ) { 2786 $this->debug_text("get_object_data(): Object Type ($object_type) is empty, this is required"); 2787 return false; 2788 } 2789 2790 $query = 'SELECT section_value,value,order_value,name,hidden FROM '. $table .' WHERE id='. (int) $object_id; 2791 $rs = $this->db->Execute($query); 2792 2793 if (!is_object($rs)) { 2794 $this->debug_db('get_object_data'); 2795 return false; 2796 } 2797 2798 if ($rs->RecordCount() < 1) { 2799 $this->debug_text('get_object_data(): Returned '. $row_count .' rows'); 2800 return FALSE; 2801 } 2802 2803 // Return all objects 2804 return $rs->GetRows(); 2805 } 2806 2807 /** 2808 * get_object_id() 2809 * 2810 * Gets the object_id given the section_value AND value of the object. 2811 * 2812 * @return int Object ID # 2813 * 2814 * @param string Object Section Value 2815 * @param string Object Value 2816 * @param string Object Type, either 'ACO', 'ARO', 'AXO' 2817 */ 2818 function get_object_id($section_value, $value, $object_type=NULL) { 2819 2820 switch(strtolower(trim($object_type))) { 2821 case 'aco': 2822 $object_type = 'aco'; 2823 $table = $this->_db_table_prefix .'aco'; 2824 break; 2825 case 'aro': 2826 $object_type = 'aro'; 2827 $table = $this->_db_table_prefix .'aro'; 2828 break; 2829 case 'axo': 2830 $object_type = 'axo'; 2831 $table = $this->_db_table_prefix .'axo'; 2832 break; 2833 default: 2834 $this->debug_text('get_object_id(): Invalid Object Type: '. $object_type); 2835 return FALSE; 2836 } 2837 2838 $this->debug_text("get_object_id(): Section Value: $section_value Value: $value Object Type: $object_type"); 2839 2840 $section_value = trim($section_value); 2841 $value = trim($value); 2842 2843 if (empty($section_value) AND $value === '') { 2844 $this->debug_text("get_object_id(): Section Value ($value) AND value ($value) is empty, this is required"); 2845 return false; 2846 } 2847 2848 if (empty($object_type) ) { 2849 $this->debug_text("get_object_id(): Object Type ($object_type) is empty, this is required"); 2850 return false; 2851 } 2852 2853 $query = 'SELECT id FROM '. $table .' WHERE section_value='. $this->db->quote($section_value) .' AND value='. $this->db->quote($value); 2854 $rs = $this->db->Execute($query); 2855 2856 if (!is_object($rs)) { 2857 $this->debug_db('get_object_id'); 2858 return false; 2859 } 2860 2861 $row_count = $rs->RecordCount(); 2862 2863 if ($row_count > 1) { 2864 $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."); 2865 return false; 2866 } 2867 2868 if ($row_count == 0) { 2869 $this->debug_text("get_object_id(): Returned $row_count rows"); 2870 return false; 2871 } 2872 2873 $row = $rs->FetchRow(); 2874 2875 //Return the ID. 2876 return $row[0]; 2877 } 2878 2879 /** 2880 * get_object_section_value() 2881 * 2882 * Gets the object_section_value given object id 2883 * 2884 * @return string Object Section Value 2885 * 2886 * @param int Object ID # 2887 * @param string Object Type, either 'ACO', 'ARO', or 'AXO' 2888 */ 2889 function get_object_section_value($object_id, $object_type=NULL) { 2890 2891 switch(strtolower(trim($object_type))) { 2892 case 'aco': 2893 $object_type = 'aco'; 2894 $table = $this->_db_table_prefix .'aco'; 2895 break; 2896 case 'aro': 2897 $object_type = 'aro'; 2898 $table = $this->_db_table_prefix .'aro'; 2899 break; 2900 case 'axo': 2901 $object_type = 'axo'; 2902 $table = $this->_db_table_prefix .'axo'; 2903 break; 2904 default: 2905 $this->debug_text('get_object_section_value(): Invalid Object Type: '. $object_type); 2906 return FALSE; 2907 } 2908 2909 $this->debug_text("get_object_section_value(): Object ID: $object_id Object Type: $object_type"); 2910 2911 if (empty($object_id) ) { 2912 $this->debug_text("get_object_section_value(): Object ID ($object_id) is empty, this is required"); 2913 return false; 2914 } 2915 2916 if (empty($object_type) ) { 2917 $this->debug_text("get_object_section_value(): Object Type ($object_type) is empty, this is required"); 2918 return false; 2919 } 2920 2921 $query = 'SELECT section_value FROM '. $table .' WHERE id='. (int) $object_id; 2922 $rs = $this->db->Execute($query); 2923 2924 if (!is_object($rs)) { 2925 $this->debug_db('get_object_section_value'); 2926 return false; 2927 } 2928 2929 $row_count = $rs->RecordCount(); 2930 2931 if ($row_count > 1) { 2932 $this->debug_text("get_object_section_value(): Returned $row_count rows, can only return one."); 2933 return false; 2934 } 2935 2936 if ($row_count == 0) { 2937 $this->debug_text("get_object_section_value(): Returned $row_count rows"); 2938 return false; 2939 } 2940 2941 $row = $rs->FetchRow(); 2942 2943 //Return the ID. 2944 return $row[0]; 2945 } 2946 2947 /** 2948 * get_object_groups() 2949 * 2950 * Gets all groups an object is a member of. 2951 * 2952 * If $option == 'RECURSE' it will get all ancestor groups. 2953 * defaults to only get direct parents. 2954 * 2955 * @return array Array of Group ID #'s, or FALSE if Failed 2956 * 2957 * @param int Object ID # 2958 * @param string Object Type, either 'ARO' or 'AXO' 2959 * @param string Option, either 'RECURSE', or 'NO_RECURSE' 2960 */ 2961 function get_object_groups($object_id, $object_type = 'ARO', $option = 'NO_RECURSE') { 2962 $this->debug_text('get_object_groups(): Object ID: '. $object_id .' Object Type: '. $object_type .' Option: '. $option); 2963 2964 switch(strtolower(trim($object_type))) { 2965 case 'axo': 2966 $object_type = 'axo'; 2967 $group_table = $this->_db_table_prefix .'axo_groups'; 2968 $map_table = $this->_db_table_prefix .'groups_axo_map'; 2969 break; 2970 case 'aro': 2971 $object_type = 'aro'; 2972 $group_table = $this->_db_table_prefix .'aro_groups'; 2973 $map_table = $this->_db_table_prefix .'groups_aro_map'; 2974 break; 2975 default: 2976 $this->debug_text('get_object_groups(): Invalid Object Type: '. $object_type); 2977 return FALSE; 2978 } 2979 2980 if (empty($object_id)) { 2981 $this->debug_text('get_object_groups(): Object ID: ('. $object_id .') is empty, this is required'); 2982 return FALSE; 2983 } 2984 2985 if (strtoupper($option) == 'RECURSE') { 2986 $query = ' 2987 SELECT DISTINCT g.id AS group_id 2988 FROM '. $map_table .' gm 2989 LEFT JOIN '. $group_table .' g1 ON g1.id=gm.group_id 2990 LEFT JOIN '. $group_table .' g ON g.lft<=g1.lft AND g.rgt>=g1.rgt'; 2991 } else { 2992 $query = ' 2993 SELECT gm.group_id 2994 FROM '. $map_table .' gm'; 2995 } 2996 2997 $query .= ' 2998 WHERE gm.'. $object_type .'_id='. (int) $object_id; 2999 $rs = $this->db->Execute($query); 3000 3001 if (!is_object($rs)) { 3002 $this->debug_db('get_object_groups'); 3003 return FALSE; 3004 } 3005 3006 $retarr = array(); 3007 3008 while ($row = $rs->FetchRow()) { 3009 $retarr[] = $row[0]; 3010 } 3011 3012 return $retarr; 3013 } 3014 3015 /** 3016 * add_object() 3017 * 3018 * Inserts a new object 3019 * 3020 * @return int Returns the ID # of the new object if successful, FALSE otherwise 3021 * 3022 * @param string Object Section Value 3023 * @param string Object Name 3024 * @param string Object Value 3025 * @param int Display Order 3026 * @param int Hidden Flag, either 1 to hide, or 0 to show. 3027 * @param string Object Type, either 'ACO', 'ARO', or 'AXO' 3028 */ 3029 function add_object($section_value, $name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 3030 3031 switch(strtolower(trim($object_type))) { 3032 case 'aco': 3033 $object_type = 'aco'; 3034 $table = $this->_db_table_prefix .'aco'; 3035 $object_sections_table = $this->_db_table_prefix .'aco_sections'; 3036 break; 3037 case 'aro': 3038 $object_type = 'aro'; 3039 $table = $this->_db_table_prefix .'aro'; 3040 $object_sections_table = $this->_db_table_prefix .'aro_sections'; 3041 break; 3042 case 'axo': 3043 $object_type = 'axo'; 3044 $table = $this->_db_table_prefix .'axo'; 3045 $object_sections_table = $this->_db_table_prefix .'axo_sections'; 3046 break; 3047 default: 3048 $this->debug_text('add_object(): Invalid Object Type: '. $object_type); 3049 return FALSE; 3050 } 3051 3052 $this->debug_text("add_object(): Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type"); 3053 3054 $section_value = trim($section_value); 3055 $name = trim($name); 3056 $value = trim($value); 3057 $order = (int) $order; 3058 $hidden = (int) $hidden; 3059 3060 if ($order == NULL OR $order == '') { 3061 $order = 0; 3062 } 3063 3064 if (empty($name) OR empty($section_value) ) { 3065 $this->debug_text("add_object(): name ($name) OR section value ($section_value) is empty, this is required"); 3066 return false; 3067 } 3068 3069 if (strlen($name) >= 255 OR strlen($value) >= 230 ) { 3070 $this->debug_text("add_object(): name ($name) OR value ($value) is too long."); 3071 return false; 3072 } 3073 3074 if (empty($object_type) ) { 3075 $this->debug_text("add_object(): Object Type ($object_type) is empty, this is required"); 3076 return false; 3077 } 3078 3079 // Test to see if the section is invalid or object already exists. 3080 $query = ' 3081 SELECT CASE WHEN o.id IS NULL THEN 0 ELSE 1 END AS object_exists 3082 FROM '. $object_sections_table .' s 3083 LEFT JOIN '. $table .' o ON (s.value=o.section_value AND o.value='. $this->db->quote($value) .') 3084 WHERE s.value='. $this->db->quote($section_value); 3085 $rs = $this->db->Execute($query); 3086 3087 if (!is_object($rs)) { 3088 $this->debug_db('add_object'); 3089 return FALSE; 3090 } 3091 3092 if ($rs->RecordCount() != 1) { 3093 // Section is invalid 3094 $this->debug_text("add_object(): Section Value: $section_value Object Type ($object_type) does not exist, this is required"); 3095 return false; 3096 } 3097 3098 $row = $rs->FetchRow(); 3099 3100 if ($row[0] == 1) { 3101 //Object is already created. 3102 return true; 3103 } 3104 3105 $insert_id = $this->db->GenID($table . '_seq', $this->_defaultGenID( $table )); 3106 $query = "INSERT INTO $table (id,section_value,value,order_value,name,hidden) " . 3107 "VALUES(". (int) $insert_id . "," . $this->db->quote($section_value) . "," . 3108 $this->db->quote($value) . ",$order," . $this->db->quote($name) . ",$hidden)"; 3109 $rs = $this->db->Execute($query); 3110 3111 if (!is_object($rs)) { 3112 $this->debug_db('add_object'); 3113 return false; 3114 } 3115 3116 // Joomla/MySQL 3117 $insert_id = $this->db->insertid(); 3118 3119 $this->debug_text("add_object(): Added object as ID: $insert_id"); 3120 return $insert_id; 3121 } 3122 3123 /** 3124 * edit_object() 3125 * 3126 * Edits a given Object 3127 * 3128 * @return bool Returns TRUE if successful, FALSE otherwise 3129 * 3130 * @param int Object ID # 3131 * @param string Object Section Value 3132 * @param string Object Name 3133 * @param string Object Value 3134 * @param int Display Order 3135 * @param int Hidden Flag, either 1 to hide, or 0 to show 3136 * @param string Object Type, either 'ACO', 'ARO', or 'AXO' 3137 */ 3138 function edit_object($object_id, $section_value, $name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 3139 3140 switch(strtolower(trim($object_type))) { 3141 case 'aco': 3142 $object_type = 'aco'; 3143 $table = $this->_db_table_prefix .'aco'; 3144 $object_map_table = $this->_db_table_prefix .'aco_map'; 3145 break; 3146 case 'aro': 3147 $object_type = 'aro'; 3148 $table = $this->_db_table_prefix .'aro'; 3149 $object_map_table = $this->_db_table_prefix .'aro_map'; 3150 break; 3151 case 'axo': 3152 $object_type = 'axo'; 3153 $table = $this->_db_table_prefix .'axo'; 3154 $object_map_table = $this->_db_table_prefix .'axo_map'; 3155 break; 3156 } 3157 3158 $this->debug_text("edit_object(): ID: $object_id Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type"); 3159 3160 $object_id = (int) $object_id; 3161 $section_value = trim($section_value); 3162 $name = trim($name); 3163 $value = trim($value); 3164 $order = (int) $order; 3165 $hidden = (int) $hidden; 3166 3167 if (empty($object_id) OR empty($section_value) ) { 3168 $this->debug_text("edit_object(): Object ID ($object_id) OR Section Value ($section_value) is empty, this is required"); 3169 return false; 3170 } 3171 3172 if (empty($name) ) { 3173 $this->debug_text("edit_object(): name ($name) is empty, this is required"); 3174 return false; 3175 } 3176 3177 if (empty($object_type) ) { 3178 $this->debug_text("edit_object(): Object Type ($object_type) is empty, this is required"); 3179 return false; 3180 } 3181 3182 $this->db->BeginTrans(); 3183 3184 //Get old value incase it changed, before we do the update. 3185 $query = 'SELECT value, section_value FROM '. $table .' WHERE id='. $object_id; 3186 $old = $this->db->GetRow($query); 3187 3188 $query = ' 3189 UPDATE '. $table .' 3190 SET section_value='. $this->db->quote($section_value) .', 3191 value='. $this->db->quote($value) .', 3192 order_value='. $order .', 3193 name='. $this->db->quote($name) .', 3194 hidden='. $hidden .' 3195 WHERE id='. $object_id; 3196 $rs = $this->db->Execute($query); 3197 3198 if (!is_object($rs)) { 3199 $this->debug_db('edit_object'); 3200 $this->db->RollbackTrans(); 3201 return false; 3202 } 3203 3204 $this->debug_text('edit_object(): Modified '. strtoupper($object_type) .' ID: '. $object_id); 3205 3206 if ($old[0] != $value OR $old[1] != $section_value) { 3207 $this->debug_text("edit_object(): Value OR Section Value Changed, update other tables."); 3208 3209 $query = ' 3210 UPDATE '. $object_map_table .' 3211 SET value='. $this->db->quote($value) .', 3212 section_value='. $this->db->quote($section_value) .' 3213 WHERE section_value='. $this->db->quote($old[1]) .' 3214 AND value='. $this->db->quote($old[0]); 3215 $rs = $this->db->Execute($query); 3216 3217 if (!is_object($rs)) { 3218 $this->debug_db('edit_object'); 3219 $this->db->RollbackTrans(); 3220 return FALSE; 3221 } 3222 3223 $this->debug_text ('edit_object(): Modified Map Value: '. $value .' Section Value: '. $section_value); 3224 } 3225 3226 $this->db->CommitTrans(); 3227 3228 return TRUE; 3229 } 3230 3231 /** 3232 * del_object() 3233 * 3234 * Deletes a given Object and, if instructed to do so, erase all referencing objects 3235 * 3236 * ERASE feature by: Martino Piccinato 3237 * 3238 * @return bool Returns TRUE if successful, FALSE otherwise. 3239 * 3240 * @param int Object ID # 3241 * @param string Object Type, either 'ACO', 'ARO', or 'AXO' 3242 * @param bool Erases all referencing objects if TRUE, leaves them alone otherwise. 3243 */ 3244 function del_object($object_id, $object_type=NULL, $erase=FALSE) { 3245 3246 switch(strtolower(trim($object_type))) { 3247 case 'aco': 3248 $object_type = 'aco'; 3249 $table = $this->_db_table_prefix .'aco'; 3250 $object_map_table = $this->_db_table_prefix .'aco_map'; 3251 break; 3252 case 'aro': 3253 $object_type = 'aro'; 3254 $table = $this->_db_table_prefix .'aro'; 3255 $object_map_table = $this->_db_table_prefix .'aro_map'; 3256 $groups_map_table = $this->_db_table_prefix .'aro_groups_map'; 3257 $object_group_table = $this->_db_table_prefix .'groups_aro_map'; 3258 break; 3259 case 'axo': 3260 $object_type = 'axo'; 3261 $table = $this->_db_table_prefix .'axo'; 3262 $object_map_table = $this->_db_table_prefix .'axo_map'; 3263 $groups_map_table = $this->_db_table_prefix .'axo_groups_map'; 3264 $object_group_table = $this->_db_table_prefix .'groups_axo_map'; 3265 break; 3266 default: 3267 $this->debug_text('del_object(): Invalid Object Type: '. $object_type); 3268 return FALSE; 3269 } 3270 3271 $this->debug_text("del_object(): ID: $object_id Object Type: $object_type, Erase all referencing objects: $erase"); 3272 3273 if (empty($object_id) ) { 3274 $this->debug_text("del_object(): Object ID ($object_id) is empty, this is required"); 3275 return false; 3276 } 3277 3278 if (empty($object_type) ) { 3279 $this->debug_text("del_object(): Object Type ($object_type) is empty, this is required"); 3280 return false; 3281 } 3282 3283 // sanitise input 3284 $object_id = (int) $object_id; 3285 3286 $this->db->BeginTrans(); 3287 3288 // Get Object section_value/value (needed to look for referencing objects) 3289 $query = 'SELECT section_value,value FROM '. $table .' WHERE id='. $object_id; 3290 $object = $this->db->GetRow($query); 3291 3292 if (empty($object)) { 3293 $this->debug_text('del_object(): The specified object ('. strtoupper($object_type) .' ID: '. $object_id .') could not be found.'); 3294 $this->db->RollbackTrans(); 3295 return FALSE; 3296 } 3297 3298 $section_value = $this->db->quote( $object[0] ); 3299 $value = $this->db->quote( $object[1] ); 3300 3301 // Get ids of acl referencing the Object (if any) 3302 $query = "SELECT acl_id FROM $object_map_table WHERE value=$value AND section_value=$section_value"; 3303 $acl_ids = $this->db->GetCol($query); 3304 3305 if ($erase) { 3306 // We were asked to erase all acl referencing it 3307 3308 $this->debug_text("del_object(): Erase was set to TRUE, delete all referencing objects"); 3309 3310 if ($object_type == "aro" OR $object_type == "axo") { 3311 // The object can be referenced in groups_X_map tables 3312 // in the future this branching may become useless because 3313 // ACO might me "groupable" too 3314 3315 // Get rid of groups_map referencing the Object 3316 $query = 'DELETE FROM '. $object_group_table .' WHERE '. $object_type .'_id='. $object_id; 3317 $rs = $this->db->Execute($query); 3318 3319 if (!is_object($rs)) { 3320 $this->debug_db('edit_object'); 3321 $this->db->RollBackTrans(); 3322 return false; 3323 } 3324 } 3325 3326 if (!empty($acl_ids)) { 3327 //There are acls actually referencing the object 3328 3329 if ($object_type == 'aco') { 3330 // I know it's extremely dangerous but 3331 // if asked to really erase an ACO 3332 // we should delete all acl referencing it 3333 // (and relative maps) 3334 3335 // Do this below this branching 3336 // where it uses $orphan_acl_ids as 3337 // the array of the "orphaned" acl 3338 // in this case all referenced acl are 3339 // orhpaned acl 3340 3341 $orphan_acl_ids = $acl_ids; 3342 } else { 3343 // The object is not an ACO and might be referenced 3344 // in still valid acls regarding also other object. 3345 // In these cases the acl MUST NOT be deleted 3346 3347 // Get rid of $object_id map referencing erased objects 3348 $query = "DELETE FROM $object_map_table WHERE section_value=$section_value AND value=$value"; 3349 $this->db->Execute($query); 3350 3351 if (!is_object($rs)) { 3352 $this->debug_db('edit_object'); 3353 $this->db->RollBackTrans(); 3354 return false; 3355 } 3356 3357 // Find the "orphaned" acl. I mean acl referencing the erased Object (map) 3358 // not referenced anymore by other objects 3359 3360 $sql_acl_ids = implode(",", $acl_ids); 3361 3362 $query = ' 3363 SELECT a.id 3364 FROM '. $this->_db_table_prefix .'acl a 3365 LEFT JOIN '. $object_map_table .' b ON a.id=b.acl_id 3366 LEFT JOIN '. $groups_map_table .' c ON a.id=c.acl_id 3367 WHERE b.value IS NULL 3368 AND b.section_value IS NULL 3369 AND c.group_id IS NULL 3370 AND a.id in ('. $sql_acl_ids .')'; 3371 $orphan_acl_ids = $this->db->GetCol($query); 3372 3373 } // End of else section of "if ($object_type == "aco")" 3374 3375 if ($orphan_acl_ids) { 3376 // If there are orphaned acls get rid of them 3377 3378 foreach ($orphan_acl_ids as $acl) { 3379 $this->del_acl($acl); 3380 } 3381 } 3382 3383 } // End of if ($acl_ids) 3384 3385 // Finally delete the Object itself 3386 $query = "DELETE FROM $table WHERE id=$object_id"; 3387 $rs = $this->db->Execute($query); 3388 3389 if (!is_object($rs)) { 3390 $this->debug_db('edit_object'); 3391 $this->db->RollBackTrans(); 3392 return false; 3393 } 3394 3395 $this->db->CommitTrans(); 3396 return true; 3397 3398 } // End of "if ($erase)" 3399 3400 $groups_ids = FALSE; 3401 3402 if ($object_type == 'axo' OR $object_type == 'aro') { 3403 // If the object is "groupable" (may become unnecessary, 3404 // see above 3405 3406 // Get id of groups where the object is assigned: 3407 // you must explicitly remove the object from its groups before 3408 // deleting it (don't know if this is really needed, anyway it's safer ;-) 3409 3410 $query = 'SELECT group_id FROM '. $object_group_table .' WHERE '. $object_type .'_id='. $object_id; 3411 $groups_ids = $this->db->GetCol($query); 3412 } 3413 3414 if ( ( isset($acl_ids) AND !empty($acl_ids) ) OR ( isset($groups_ids) AND !empty($groups_ids) ) ) { 3415 // The Object is referenced somewhere (group or acl), can't delete it 3416 3417 $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,",").")"); 3418 $this->db->RollBackTrans(); 3419 return false; 3420 } else { 3421 // The Object is NOT referenced anywhere, delete it 3422 3423 $query = "DELETE FROM $table WHERE id=$object_id"; 3424 $rs = $this->db->Execute($query); 3425 3426 if ( !is_object($rs) ) { 3427 $this->debug_db('edit_object'); 3428 $this->db->RollBackTrans(); 3429 return false; 3430 } 3431 3432 $this->db->CommitTrans(); 3433 return true; 3434 } 3435 3436 $this->db->RollbackTrans(); 3437 return false; 3438 } 3439 3440 /* 3441 * 3442 * Object Sections 3443 * 3444 */ 3445 3446 /** 3447 * get_object_section_section_id() 3448 * 3449 * Gets the object_section_id given the name AND/OR value of the section. 3450 * 3451 * Will only return one section id, so if there are duplicate names it will return false. 3452 * 3453 * @return int Object Section ID if the object section is found AND is unique, or FALSE otherwise. 3454 * 3455 * @param string Object Name 3456 * @param string Object Value 3457 * @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL' 3458 * 3459 */ 3460 function get_object_section_section_id($name = NULL, $value = NULL, $object_type = NULL) { 3461 $this->debug_text("get_object_section_section_id(): Value: $value Name: $name Object Type: $object_type"); 3462 3463 switch(strtolower(trim($object_type))) { 3464 case 'aco': 3465 case 'aro': 3466 case 'axo': 3467 case 'acl': 3468 $object_type = strtolower(trim($object_type)); 3469 $table = $this->_db_table_prefix . $object_type; 3470 $object_sections_table = $this->_db_table_prefix . $object_type .'_sections'; 3471 break; 3472 default: 3473 $this->debug_text('get_object_section_section_id(): Invalid Object Type ('. $object_type . ')'); 3474 return FALSE; 3475 } 3476 3477 $name = trim($name); 3478 $value = trim($value); 3479 3480 if (empty($name) AND $value === '') { 3481 $this->debug_text('get_object_section_section_id(): Both Name ('. $name .') and Value ('. $value .') are empty, you must specify at least one.'); 3482 return FALSE; 3483 } 3484 3485 $query = 'SELECT id FROM '. $object_sections_table; 3486 $where = ' WHERE '; 3487 3488 // limit by value if specified 3489 if ($value !== '') { 3490 $query .= $where .'value='. $this->db->quote($value); 3491 $where = ' AND '; 3492 } 3493 3494 // only use name if asked, this is SLOW 3495 if (!empty($name)) { 3496 $query .= $where .'name='. $this->db->quote($name); 3497 } 3498 3499 $rs = $this->db->Execute($query); 3500 3501 if (!is_object($rs)) { 3502 $this->debug_db('get_object_section_section_id'); 3503 return FALSE; 3504 } 3505 3506 $row_count = $rs->RecordCount(); 3507 3508 // If only one row is returned 3509 if ($row_count == 1) { 3510 // Return only the ID in the first row. 3511 $row = $rs->FetchRow(); 3512 return $row[0]; 3513 } 3514 3515 // If more than one row is returned 3516 // should only ever occur when using name as values are unique. 3517 if ($row_count > 1) { 3518 $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.'); 3519 return FALSE; 3520 } 3521 3522 // No rows returned, no matching section found 3523 $this->debug_text('get_object_section_section_id(): Returned '. $row_count .' rows, no matching section found.'); 3524 return FALSE; 3525 } 3526 3527 /** 3528 * add_object_section() 3529 * 3530 * Inserts an object Section 3531 * 3532 * @return int Object Section ID of new section 3533 * 3534 * @param string Object Name 3535 * @param string Object Value 3536 * @param int Display Order 3537 * @param int Hidden flag, hides section if 1, shows section if 0 3538 * @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL' 3539 */ 3540 function add_object_section($name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 3541 3542 switch(strtolower(trim($object_type))) { 3543 case 'aco': 3544 $object_type = 'aco'; 3545 $object_sections_table = $this->_db_table_prefix .'aco_sections'; 3546 break; 3547 case 'aro': 3548 $object_type = 'aro'; 3549 $object_sections_table = $this->_db_table_prefix .'aro_sections'; 3550 break; 3551 case 'axo': 3552 $object_type = 'axo'; 3553 $object_sections_table = $this->_db_table_prefix .'axo_sections'; 3554 break; 3555 case 'acl': 3556 $object_type = 'acl'; 3557 $object_sections_table = $this->_db_table_prefix .'acl_sections'; 3558 break; 3559 } 3560 3561 $this->debug_text("add_object_section(): Value: $value Order: $order Name: $name Object Type: $object_type"); 3562 3563 $name = trim($name); 3564 $value = trim($value); 3565 $order = (int) $order; 3566 $hidden = (int) $hidden; 3567 3568 if ($order == NULL OR $order == '') { 3569 $order = 0; 3570 } 3571 3572 if (empty($name) ) { 3573 $this->debug_text("add_object_section(): name ($name) is empty, this is required"); 3574 return false; 3575 } 3576 3577 if (empty($object_type) ) { 3578 $this->debug_text("add_object_section(): Object Type ($object_type) is empty, this is required"); 3579 return false; 3580 } 3581 3582 $insert_id = $this->db->GenID($this->_db_table_prefix.$object_type.'_sections_seq',10); 3583 $query = "insert into $object_sections_table (id,value,order_value,name,hidden) VALUES($insert_id, '$value', '$order', '$name', $hidden)"; 3584 $rs = $this->db->Execute($query); 3585 3586 if (!is_object($rs)) { 3587 $this->debug_db('add_object_section'); 3588 return false; 3589 } else { 3590 $this->debug_text("add_object_section(): Added object_section as ID: $insert_id"); 3591 return $insert_id; 3592 } 3593 } 3594 3595 /** 3596 * edit_object_section() 3597 * 3598 * Edits a given Object Section 3599 * 3600 * @return bool Returns TRUE if successful, FALSE otherwise 3601 * 3602 * @param int Object Section ID # 3603 * @param string Object Section Name 3604 * @param string Object Section Value 3605 * @param int Display Order 3606 * @param int Hidden Flag, hide object section if 1, show if 0 3607 * @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL' 3608 */ 3609 function edit_object_section($object_section_id, $name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 3610 3611 switch(strtolower(trim($object_type))) { 3612 case 'aco': 3613 $object_type = 'aco'; 3614 $table = $this->_db_table_prefix .'aco'; 3615 $object_sections_table = $this->_db_table_prefix .'aco_sections'; 3616 $object_map_table = $this->_db_table_prefix .'aco_map'; 3617 break; 3618 case 'aro': 3619 $object_type = 'aro'; 3620 $table = $this->_db_table_prefix .'aro'; 3621 $object_sections_table = $this->_db_table_prefix .'aro_sections'; 3622 $object_map_table = $this->_db_table_prefix .'aro_map'; 3623 break; 3624 case 'axo': 3625 $object_type = 'axo'; 3626 $table = $this->_db_table_prefix .'axo'; 3627 $object_sections_table = $this->_db_table_prefix .'axo_sections'; 3628 $object_map_table = $this->_db_table_prefix .'axo_map'; 3629 break; 3630 case 'acl': 3631 $object_type = 'acl'; 3632 $table = $this->_db_table_prefix .'acl'; 3633 $object_sections_table = $this->_db_table_prefix .'acl_sections'; 3634 break; 3635 default: 3636 $this->debug_text('edit_object_section(): Invalid Object Type: '. $object_type); 3637 return FALSE; 3638 } 3639 3640 $this->debug_text("edit_object_section(): ID: $object_section_id Value: $value Order: $order Name: $name Object Type: $object_type"); 3641 3642 $name = trim($name); 3643 $value = trim($value); 3644 $order = (int) $order; 3645 $hidden = (int) $hidden; 3646 3647 if (empty($object_section_id) ) { 3648 $this->debug_text("edit_object_section(): Section ID ($object_section_id) is empty, this is required"); 3649 return false; 3650 } 3651 3652 if (empty($name) ) { 3653 $this->debug_text("edit_object_section(): name ($name) is empty, this is required"); 3654 return false; 3655 } 3656 3657 if (empty($object_type) ) { 3658 $this->debug_text("edit_object_section(): Object Type ($object_type) is empty, this is required"); 3659 return false; 3660 } 3661 3662 // sanitise input 3663 $object_section_id = (int) $object_section_id; 3664 3665 $this->db->BeginTrans(); 3666 3667 //Get old value incase it changed, before we do the update. 3668 $query = "select value from $object_sections_table where id=$object_section_id"; 3669 $old_value = $this->db->GetOne($query); 3670 3671 $query = "update $object_sections_table set 3672 value=" . $this->db-quote($value) . "', 3673 order_value=$order, 3674 name=" . $this->db-quote($name) . ", 3675 hidden=$hidden 3676 where id=$object_section_id"; 3677 $rs = $this->db->Execute($query); 3678 3679 if (!is_object($rs)) { 3680 $this->debug_db('edit_object_section'); 3681 3682 $this->db->RollbackTrans(); 3683 3684 return false; 3685 } else { 3686 $this->debug_text("edit_object_section(): Modified aco_section ID: $object_section_id"); 3687 3688 if ($old_value != $value) { 3689 $this->debug_text("edit_object_section(): Value Changed, update other tables."); 3690 3691 $query = "update $table set 3692 section_value=" . $this->db-quote($value) . " 3693 where section_value = " . $this->db-quote($old_value); 3694 $rs = $this->db->Execute($query); 3695 3696 if (!is_object($rs)) { 3697 $this->debug_db('edit_object_section'); 3698 3699 $this->db->RollbackTrans(); 3700 3701 return false; 3702 } else { 3703 if (!empty($object_map_table)) { 3704 $query = "update $object_map_table set 3705 section_value=" . $this->db-quote($value) . " 3706 where section_value = " . $this->db-quote($old_value); 3707 $rs = $this->db->Execute($query); 3708 3709 if ( !is_object($rs) ) { 3710 $this->debug_db('edit_object_section'); 3711 3712 $this->db->RollbackTrans(); 3713 3714 return false; 3715 } else { 3716 $this->debug_text("edit_object_section(): Modified ojbect_map value: $value"); 3717 3718 $this->db->CommitTrans(); 3719 return true; 3720 } 3721 } else { 3722 //ACL sections, have no mapping table. Return true. 3723 3724 $this->db->CommitTrans(); 3725 3726 return true; 3727 } 3728 } 3729 } 3730 3731 $this->db->CommitTrans(); 3732 return true; 3733 } 3734 } 3735 3736 /** 3737 * del_object_section() 3738 * 3739 * Deletes a given Object Section and, if explicitly asked, all the section objects 3740 * 3741 * ERASE feature by: Martino Piccinato 3742 * 3743 * @return bool Returns TRUE if successful, FALSE otherwise 3744 * 3745 * @param int Object Section ID # to delete 3746 * @param string Object Type, either 'ACO', 'ARO', 'AXO', or 'ACL' 3747 * @param bool Erases all section objects assigned to the section 3748 */ 3749 function del_object_section($object_section_id, $object_type=NULL, $erase=FALSE) { 3750 3751 switch(strtolower(trim($object_type))) { 3752 case 'aco': 3753 $object_type = 'aco'; 3754 $object_sections_table = $this->_db_table_prefix .'aco_sections'; 3755 break; 3756 case 'aro': 3757 $object_type = 'aro'; 3758 $object_sections_table = $this->_db_table_prefix .'aro_sections'; 3759 break; 3760 case 'axo': 3761 $object_type = 'axo'; 3762 $object_sections_table = $this->_db_table_prefix .'axo_sections'; 3763 break; 3764 case 'acl': 3765 $object_type = 'acl'; 3766 $object_sections_table = $this->_db_table_prefix .'acl_sections'; 3767 break; 3768 } 3769 3770 $this->debug_text("del_object_section(): ID: $object_section_id Object Type: $object_type, Erase all: $erase"); 3771 3772 if (empty($object_section_id) ) { 3773 $this->debug_text("del_object_section(): Section ID ($object_section_id) is empty, this is required"); 3774 return false; 3775 } 3776 3777 if (empty($object_type) ) { 3778 $this->debug_text("del_object_section(): Object Type ($object_type) is empty, this is required"); 3779 return false; 3780 } 3781 3782 // sanitise input 3783 $object_section_id = (int) $object_section_id; 3784 3785 // Get the value of the section 3786 $query="SELECT value FROM $object_sections_table WHERE id=$object_section_id"; 3787 $section_value = $this->db->GetOne($query); 3788 3789 // Get all objects ids in the section 3790 $object_ids = $this->get_object($section_value, 1, $object_type); 3791 3792 if($erase) { 3793 // Delete all objects in the section and for 3794 // each object delete the referencing object 3795 // (see del_object method) 3796 if (is_array($object_ids)) { 3797 foreach ($object_ids as $id) { 3798 if ( $object_type === 'acl' ) { 3799 $this->del_acl($id); 3800 } else { 3801 $this->del_object($id, $object_type, TRUE); 3802 } 3803 } 3804 } 3805 } 3806 3807 if($object_ids AND !$erase) { 3808 // There are objects in the section and we 3809 // were not asked to erase them: don't delete it 3810 3811 $this->debug_text("del_object_section(): Could not delete the section ($section_value) as it is not empty."); 3812 3813 return false; 3814 3815 } else { 3816 // The section is empty (or emptied by this method) 3817 3818 $query = "DELETE FROM $object_sections_table where id=$object_section_id"; 3819 $rs = $this->db->Execute($query); 3820 3821 if (!is_object($rs)) { 3822 $this->debug_db('del_object_section'); 3823 return false; 3824 } else { 3825 $this->debug_text("del_object_section(): deleted section ID: $object_section_id Value: $section_value"); 3826 return true; 3827 } 3828 3829 } 3830 3831 return false; 3832 } 3833 3834 /** 3835 * get_section_data() 3836 * 3837 * Gets the section data given the Section Value 3838 * 3839 * @return array Returns numerically indexed array with the following columns: 3840 * - array[0] = (int) Section ID # 3841 * - array[1] = (string) Section Value 3842 * - array[2] = (int) Section Order 3843 * - array[3] = (string) Section Name 3844 * - array[4] = (int) Section Hidden? 3845 * @param string Section Value 3846 * @param string Object Type, either 'ACO', 'ARO', or 'AXO' 3847 */ 3848 function get_section_data($section_value, $object_type=NULL) { 3849 3850 switch(strtolower(trim($object_type))) { 3851 case 'aco': 3852 $object_type = 'aco'; 3853 $table = $this->_db_table_prefix .'aco_sections'; 3854 break; 3855 case 'aro': 3856 $object_type = 'aro'; 3857 $table = $this->_db_table_prefix .'aro_sections'; 3858 break; 3859 case 'axo': 3860 $object_type = 'axo'; 3861 $table = $this->_db_table_prefix .'axo_sections'; 3862 break; 3863 default: 3864 $this->debug_text('get_section_data(): Invalid Object Type: '. $object_type); 3865 return FALSE; 3866 } 3867 3868 $this->debug_text("get_section_data(): Section Value: $section_value Object Type: $object_type"); 3869 3870 if (empty($section_value) ) { 3871 $this->debug_text("get_section_data(): Section Value ($section_value) is empty, this is required"); 3872 return false; 3873 } 3874 3875 if (empty($object_type) ) { 3876 $this->debug_text("get_section_data(): Object Type ($object_type) is empty, this is required"); 3877 return false; 3878 } 3879 3880 $query = 'SELECT id, value, order_value, name, hidden FROM '. $table .' WHERE value='.$this->db->Quote( $section_value ); 3881 $row = $this->db->GetRow($query); 3882 3883 if ($row) { 3884 return $row; 3885 } 3886 3887 $this->debug_text("get_section_data(): Section does not exist."); 3888 return false; 3889 } 3890 3891 /** 3892 * clear_database() 3893 * 3894 * Deletes all data from the phpGACL tables. USE WITH CAUTION. 3895 * 3896 * @return bool Returns TRUE if successful, FALSE otherwise 3897 * 3898 */ 3899 function clear_database() 3900 { 3901 $tablesToClear = array( 3902 $this->_db_table_prefix.'acl', 3903 $this->_db_table_prefix.'aco', 3904 $this->_db_table_prefix.'aco_map', 3905 $this->_db_table_prefix.'aco_sections', 3906 $this->_db_table_prefix.'aro', 3907 $this->_db_table_prefix.'aro_groups', 3908 $this->_db_table_prefix.'aro_groups_map', 3909 $this->_db_table_prefix.'aro_map', 3910 $this->_db_table_prefix.'aro_sections', 3911 $this->_db_table_prefix.'axo', 3912 $this->_db_table_prefix.'axo_groups', 3913 $this->_db_table_prefix.'axo_groups_map', 3914 $this->_db_table_prefix.'axo_map', 3915 $this->_db_table_prefix.'axo_sections', 3916 $this->_db_table_prefix.'groups_aro_map', 3917 $this->_db_table_prefix.'groups_axo_map' 3918 ); 3919 3920 // Get all the table names and loop 3921 $tableNames = $this->db->MetaTables('TABLES'); 3922 $query = array(); 3923 foreach ($tableNames as $key => $value){ 3924 if (in_array($value, $tablesToClear) ) { 3925 $query[] = 'TRUNCATE TABLE '.$value.';'; 3926 } 3927 } 3928 3929 // Loop the queries and return. 3930 foreach ($query as $key => $value){ 3931 $result = $this->db->Execute($value); 3932 } 3933 3934 return TRUE; 3935 } 3936 3937 /** 3938 * Calculates the start number for a sequence table 3939 * @protected 3940 * @param string The name of the table 3941 * @return int The highest id plus one 3942 */ 3943 function _defaultGenID( $table ) { 3944 $query = "SELECT MAX(id) from " . $table; 3945 $id = $this->db->GetOne( $query ) + 1; 3946 3947 return $id; 3948 } 3949 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |