| [ Index ] |
|
Code source de Joomla 1.0.13 |
1 <?php 2 /** 3 * @version $Id: gacl_api.class.php 5318 2006-10-04 01:40:31Z pasamio $ 4 * @package Joomla 5 * @copyright Copyright (C) 2005 Open Source Matters. All rights reserved. 6 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php 7 * Joomla! is free software. This version may have been modified pursuant 8 * to the GNU General Public License, and as distributed it includes or 9 * is derivative of works licensed under the GNU General Public License or 10 * other free or open source software licenses. 11 * See COPYRIGHT.php for copyright notices and details. 12 */ 13 14 /* 15 * phpGACL - Generic Access Control List 16 * Copyright (C) 2002,2003 Mike Benoit 17 * 18 * This library is free software; you can redistribute it and/or 19 * modify it under the terms of the GNU Lesser General Public 20 * License as published by the Free Software Foundation; either 21 * version 2.1 of the License, or (at your option) any later version. 22 * 23 * This library is distributed in the hope that it will be useful, 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26 * Lesser General Public License for more details. 27 * 28 * You should have received a copy of the GNU Lesser General Public 29 * License along with this library; if not, write to the Free Software 30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 31 * 32 * For questions, help, comments, discussion, etc., please join the 33 * phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103 34 * 35 * You may contact the author of phpGACL by e-mail at: 36 * ipso@snappymail.ca 37 * 38 * The latest version of phpGACL can be obtained from: 39 * http://phpgacl.sourceforge.net/ 40 * 41 */ 42 43 // no direct access 44 defined( '_VALID_MOS' ) or die( 'Restricted access' ); 45 46 /* 47 * 48 * 49 * == If you find a feature may be missing from this API, please email me: ipso@snappymail.ca and I will be happy to add it. == 50 * 51 * 52 * Example: 53 * $gacl_api = new gacl_api; 54 * 55 * $section_id = $gacl_api->get_aco_section_id('System'); 56 * $aro_id= $gacl_api->add_aro($section_id, 'John Doe', 10); 57 * 58 * For more examples, see the Administration interface, as it makes use of nearly every API Call. 59 * 60 */ 61 62 class gacl_api extends gacl { 63 /* 64 * Administration interface settings 65 */ 66 var $_items_per_page = 100; 67 var $_max_select_box_items = 100; 68 var $_max_search_return_items = 100; 69 70 /* 71 * 72 * Misc helper functions. 73 * 74 */ 75 76 /*======================================================================*\ 77 Function: showarray() 78 Purpose: Dump all contents of an array in HTML (kinda). 79 \*======================================================================*/ 80 function showarray($array) { 81 echo "<br><pre>\n"; 82 var_dump($array); 83 echo "</pre><br>\n"; 84 } 85 86 /*======================================================================*\ 87 Function: $gacl_api->return_page() 88 Purpose: Sends the user back to a passed URL, unless debug is enabled, then we don't redirect. 89 If no URL is passed, try the REFERER 90 \*======================================================================*/ 91 function return_page($url="") { 92 global $_SERVER, $debug; 93 94 if (empty($url) AND !empty($_SERVER[HTTP_REFERER])) { 95 $this->debug_text("return_page(): URL not set, using referer!"); 96 $url = $_SERVER[HTTP_REFERER]; 97 } 98 99 if (!$debug OR $debug==0) { 100 header("Location: $url\n\n"); 101 } else { 102 $this->debug_text("return_page(): URL: $url -- Referer: $_SERVER[HTTP_REFERRER]"); 103 } 104 } 105 106 /*======================================================================*\ 107 Function: get_paging_data() 108 Purpose: Creates a basic array for Smarty to deal with paging large recordsets. 109 Pass it the ADODB recordset. 110 \*======================================================================*/ 111 function get_paging_data($rs) { 112 return array( 113 'prevpage' => $rs->absolutepage() - 1, 114 'currentpage' => $rs->absolutepage(), 115 'nextpage' => $rs->absolutepage() + 1, 116 'atfirstpage' => $rs->atfirstpage(), 117 'atlastpage' => $rs->atlastpage(), 118 'lastpageno' => $rs->lastpageno() 119 ); 120 } 121 122 /*======================================================================*\ 123 Function: count_all() 124 Purpose: Recursively counts elements in an array and sub-arrays. 125 The returned count is a count of all scalar elements found. 126 127 This is different from count($arg, COUNT_RECURSIVE) 128 in PHP >= 4.2.0, which includes sub-arrays in the count. 129 \*======================================================================*/ 130 function count_all($arg = NULL) { 131 switch (TRUE) { 132 case is_scalar($arg): 133 case is_object($arg): 134 // single object 135 return 1; 136 case is_array($arg): 137 // call recursively for all elements of $arg 138 $count = 0; 139 foreach ($arg as $val) { 140 $count += $this->count_all($val); 141 } 142 return $count; 143 } 144 return FALSE; 145 } 146 147 /*======================================================================*\ 148 Function: get_version() 149 Purpose: Grabs phpGACL version from the database. 150 \*======================================================================*/ 151 152 153 /*======================================================================*\ 154 Function: get_schema_version() 155 Purpose: Grabs phpGACL schema version from the database. 156 \*======================================================================*/ 157 /* 158 * 159 * ACL 160 * 161 */ 162 163 /*======================================================================*\ 164 Function: consolidated_edit_acl() 165 Purpose: Add's an ACL but checks to see if it can consolidate it with another one first. 166 This ONLY works with ACO's and ARO's. Groups, and AXO are excluded. 167 As well this function is designed for handling ACLs with return values, 168 and consolidating on the return_value, in hopes of keeping the ACL count to a minimum. 169 170 A return value of false must _always_ be handled outside this function. 171 As this function will remove AROs from ACLs and return false, in most cases 172 you will need to a create a completely new ACL on a false return. 173 \*======================================================================*/ 174 175 /*======================================================================*\ 176 Function: shift_acl() 177 Purpose: Opposite of append_acl(). Removes objects from a specific ACL. (named after PHP's array_shift()) 178 \*======================================================================*/ 179 180 /*======================================================================*\ 181 Function: get_acl() 182 Purpose: Grabs ACL data. 183 \*======================================================================*/ 184 185 /*======================================================================*\ 186 Function: is_conflicting_acl() 187 Purpose: Checks for conflicts when adding a specific ACL. 188 \*======================================================================*/ 189 190 /*======================================================================*\ 191 Function: add_acl() 192 Purpose: Add's an ACL. ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays. 193 \*======================================================================*/ 194 195 /*======================================================================*\ 196 Function: edit_acl() 197 Purpose: Edit's an ACL, ACO_IDS, ARO_IDS, GROUP_IDS must all be arrays. 198 \*======================================================================*/ 199 200 /*======================================================================*\ 201 Function: del_acl() 202 Purpose: Deletes a given ACL 203 \*======================================================================*/ 204 205 206 /* 207 * 208 * Groups 209 * 210 */ 211 212 /*======================================================================*\ 213 Function: sort_groups() 214 Purpose: Grabs all the groups from the database doing preliminary grouping by parent 215 \*======================================================================*/ 216 217 /*======================================================================*\ 218 Function: format_groups() 219 Purpose: Takes the array returned by sort_groups() and formats for human consumption. 220 \*======================================================================*/ 221 222 /*======================================================================*\ 223 Function: get_group_id() 224 Purpose: Gets the group_id given the name. 225 Will only return one group id, so if there are duplicate names, it will return false. 226 \*======================================================================*/ 227 function get_group_id($name = null, $group_type = 'ARO') { 228 229 $this->debug_text("get_group_id(): Name: $name"); 230 231 switch(strtolower(trim($group_type))) { 232 case 'axo': 233 $table = $this->_db_table_prefix .'axo_groups'; 234 break; 235 default: 236 $table = $this->_db_table_prefix .'aro_groups'; 237 break; 238 } 239 240 $name = trim($name); 241 242 if (empty($name) ) { 243 $this->debug_text("get_group_id(): name ($name) is empty, this is required"); 244 return false; 245 } 246 247 $this->db->setQuery( "SELECT group_id FROM $table WHERE name=" . $this->db->Quote( $name ) ); 248 249 $rows = $this->db->loadRowList(); 250 if ($this->db->getErrorNum()) { 251 $this->debug_db('get_group_id'); 252 return false; 253 } 254 255 $row_count = count( $rows ); 256 257 if ($row_count > 1) { 258 $this->debug_text("get_group_id(): Returned $row_count rows, can only return one. Please make your names unique."); 259 return false; 260 } 261 262 if ($row_count == 0) { 263 $this->debug_text("get_group_id(): Returned $row_count rows"); 264 return false; 265 } 266 267 $row = $rows[0]; 268 269 //Return the ID. 270 return $row[0]; 271 } 272 273 /*======================================================================*\ 274 Function: get_group_name() 275 Purpose: Gets the name given the group_id. 276 Will only return one group id, so if there are duplicate names, it will return false. 277 \*======================================================================*/ 278 function get_group_name($group_id = null, $group_type = 'ARO') { 279 280 $this->debug_text("get_group_name(): ID: $group_id"); 281 282 switch(strtolower(trim($group_type))) { 283 case 'axo': 284 $table = $this->_db_table_prefix .'axo_groups'; 285 break; 286 default: 287 $table = $this->_db_table_prefix .'aro_groups'; 288 break; 289 } 290 291 $group_id = intval($group_id); 292 293 if (!$group_id) { 294 $this->debug_text("get_group_name(): group_id ($group_id) is empty, this is required"); 295 return false; 296 } 297 298 $this->db->setQuery( "SELECT name FROM $table WHERE group_id=" . (int) $group_id ); 299 300 $rows = $this->db->loadRowList(); 301 if ($this->db->getErrorNum()) { 302 $this->debug_db('get_group_name'); 303 return false; 304 } 305 306 $row_count = count( $rows ); 307 308 if ($row_count > 1) { 309 $this->debug_text("get_group_name(): Returned $row_count rows, can only return one. Please make your names unique."); 310 return false; 311 } 312 313 if ($row_count == 0) { 314 $this->debug_text("get_group_name(): Returned $row_count rows"); 315 return false; 316 } 317 318 $row = $rows[0]; 319 320 //Return the ID. 321 return $row[0]; 322 } 323 324 /*======================================================================*\ 325 Function: get_group_children() 326 Purpose: Gets a groups child IDs 327 \*======================================================================*/ 328 function get_group_children($group_id, $group_type = 'ARO', $recurse = 'NO_RECURSE') { 329 $this->debug_text("get_group_children(): Group_ID: $group_id Group Type: $group_type Recurse: $recurse"); 330 331 switch (strtolower(trim($group_type))) { 332 case 'axo': 333 $group_type = 'axo'; 334 $table = $this->_db_table_prefix .'axo_groups'; 335 break; 336 default: 337 $group_type = 'aro'; 338 $table = $this->_db_table_prefix .'aro_groups'; 339 } 340 341 if (empty($group_id)) { 342 $this->debug_text("get_group_children(): ID ($group_id) is empty, this is required"); 343 return FALSE; 344 } 345 346 $query = ' 347 SELECT g1.group_id 348 FROM '. $table .' g1'; 349 350 //FIXME-mikeb: Why is group_id in quotes? 351 switch (strtoupper($recurse)) { 352 case 'RECURSE': 353 $query .= ' 354 LEFT JOIN '. $table .' g2 ON g2.lft<g1.lft AND g2.rgt>g1.rgt 355 WHERE g2.group_id='. (int) $group_id; 356 break; 357 default: 358 $query .= ' 359 WHERE g1.parent_id='. (int) $group_id; 360 } 361 362 $query .= ' 363 ORDER BY g1.name'; 364 365 366 $this->db->setQuery( $query ); 367 return $this->db->loadResultArray(); 368 } 369 370 /*======================================================================*\ 371 Function: get_group_data() 372 Purpose: Gets the group data given the GROUP_ID. 373 \*======================================================================*/ 374 375 /*======================================================================*\ 376 Function: get_group_parent_id() 377 Purpose: Grabs the parent_id of a given group 378 \*======================================================================*/ 379 380 /*======================================================================*\ 381 Function: get_group_children() 382 Purpose: Gets a groups child IDs 383 \*======================================================================*/ 384 function get_group_parents($group_id, $group_type = 'ARO', $recurse = 'NO_RECURSE') { 385 $this->debug_text("get_group_parents(): Group_ID: $group_id Group Type: $group_type Recurse: $recurse"); 386 387 switch (strtolower(trim($group_type))) { 388 case 'axo': 389 $group_type = 'axo'; 390 $table = $this->_db_table_prefix .'axo_groups'; 391 break; 392 default: 393 $group_type = 'aro'; 394 $table = $this->_db_table_prefix .'aro_groups'; 395 } 396 397 if (empty($group_id)) { 398 $this->debug_text("get_group_parents(): ID ($group_id) is empty, this is required"); 399 return FALSE; 400 } 401 402 $query = ' 403 SELECT g2.group_id 404 FROM '. $table .' g1'; 405 406 //FIXME-mikeb: Why is group_id in quotes? 407 switch (strtoupper($recurse)) { 408 case 'RECURSE': 409 $query .= ' 410 LEFT JOIN '. $table .' g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt 411 WHERE g1.group_id='. (int) $group_id; 412 break; 413 case 'RECURSE_INCL': 414 // inclusive resurse 415 $query .= ' 416 LEFT JOIN '. $table .' g2 ON g1.lft >= g2.lft AND g1.lft <= g2.rgt 417 WHERE g1.group_id='. (int) $group_id; 418 break; 419 default: 420 $query .= ' 421 LEFT JOIN '. $table .' g2 ON g1.parent_id = g2.group_id 422 WHERE g1.group_id='. (int) $group_id; 423 } 424 425 $query .= ' 426 ORDER BY g2.lft'; 427 $this->db->setQuery( $query ); 428 return $this->db->loadResultArray(); 429 } 430 431 /*======================================================================*\ 432 Function: get_root_group_id () 433 Purpose: Grabs the id of the root group for the specified tree 434 \*======================================================================*/ 435 436 /*======================================================================*\ 437 Function: map_path_to_root() 438 Purpose: Maps a unique path to root to a specific group. Each group can only have 439 one path to root. 440 \*======================================================================*/ 441 /** REMOVED **/ 442 /*======================================================================*\ 443 Function: put_path_to_root() 444 Purpose: Writes the unique path to root to the database. There should really only be 445 one path to root for each level "deep" the groups go. If the groups are branched 446 10 levels deep, there should only be 10 unique path to roots. These of course 447 overlap each other more and more the closer to the root/trunk they get. 448 \*======================================================================*/ 449 /** REMOVED **/ 450 /*======================================================================*\ 451 Function: clean_path_to_root() 452 Purpose: Cleans up any paths that are not being used. 453 \*======================================================================*/ 454 /** REMOVED **/ 455 /*======================================================================*\ 456 Function: get_path_to_root() 457 Purpose: Generates the path to root for a given group. 458 \*======================================================================*/ 459 /** REMOVED **/ 460 461 /*======================================================================*\ 462 Function: add_group() 463 Purpose: Inserts a group, defaults to be on the "root" branch. 464 \*======================================================================*/ 465 function add_group($name, $parent_id=0, $group_type='ARO') { 466 467 switch(strtolower(trim($group_type))) { 468 case 'axo': 469 $group_type = 'axo'; 470 $table = $this->_db_table_prefix .'axo_groups'; 471 break; 472 default: 473 $group_type = 'aro'; 474 $table = $this->_db_table_prefix .'aro_groups'; 475 break; 476 } 477 478 $this->debug_text("add_group(): Name: $name Parent ID: $parent_id Group Type: $group_type"); 479 480 $name = trim($name); 481 482 if (empty($name)) { 483 $this->debug_text("add_group(): name ($name) OR parent id ($parent_id) is empty, this is required"); 484 return false; 485 } 486 487 //This has to be outside the transaction, because the first time it is run, it will say the sequence 488 //doesn't exist. Then try to create it, but the transaction will already by aborted by then. 489 //$insert_id = $this->db->GenID($this->_db_table_prefix.$group_type.'_groups_id_seq',10); 490 $this->db->setQuery( "SELECT MAX(group_id)+1 FROM $table" ); 491 $insert_id = intval( $this->db->loadResult() ); 492 493 // <mos> $this->db->BeginTrans(); 494 495 // special case for root group 496 if ($parent_id == 0) { 497 // check a root group is not already defined 498 $$this->db->setQuery( 'SELECT group_id FROM '. $table .' WHERE parent_id=0' ); 499 $rs = $this->db->loadResultArray(); 500 501 if (!is_array( $rs )) { 502 $this->debug_db('add_group'); 503 $this->db->RollBackTrans(); 504 return FALSE; 505 } 506 507 if (count( $rs ) > 0) { 508 $this->debug_text('add_group (): A root group already exists.'); 509 // <mos> $this->db->RollBackTrans(); 510 return FALSE; 511 } 512 513 $parent_lft = 0; 514 $parent_rgt = 1; 515 } else { 516 if (empty($parent_id)) { 517 $this->debug_text("add_group (): parent id ($parent_id) is empty, this is required"); 518 return FALSE; 519 } 520 521 // grab parent details from database 522 $this->db->setQuery( 'SELECT group_id, lft, rgt FROM '. $table .' WHERE group_id='. (int) $parent_id ); 523 $rows = $this->db->loadRowList(); 524 525 if (!is_array($rows) OR $this->db->getErrorNum() > 0) { 526 $this->debug_db('add_group'); 527 // <mos> $this->db->RollBackTrans(); 528 return FALSE; 529 } 530 531 if (empty($rows)) { 532 $this->debug_text('add_group (): Parent ID: '. $parent_id .' not found.'); 533 // <mos> $this->db->RollBackTrans(); 534 return FALSE; 535 } 536 $row = $rows[0]; 537 $parent_lft = &$row[1]; 538 $parent_rgt = &$row[2]; 539 540 // make room for the new group 541 $this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt+2 WHERE rgt>='. (int) $parent_rgt ); 542 $rs = $this->db->query(); 543 544 if (!$rs) { 545 $this->debug_db('add_group: make room for the new group - right'); 546 // <mos> $this->db->RollBackTrans(); 547 return FALSE; 548 } 549 550 $this->db->setQuery( 'UPDATE '. $table .' SET lft=lft+2 WHERE lft>'. (int) $parent_rgt ); 551 $rs = $this->db->query(); 552 553 if (!$rs) { 554 $this->debug_db('add_group: make room for the new group - left'); 555 // <mos> $this->db->RollBackTrans(); 556 return FALSE; 557 } 558 } 559 560 $this->db->setQuery( 'INSERT INTO '. $table .' (group_id,parent_id,name,lft,rgt) VALUES ('. (int) $insert_id .','. (int) $parent_id .',\''. $this->db->getEscaped($name) .'\','. (int) $parent_rgt .','. (int) ($parent_rgt + 1) .')' ); 561 $rs = $this->db->query(); 562 563 if (!$rs) { 564 $this->debug_db('add_group: insert record'); 565 // <mos> $this->db->RollBackTrans(); 566 return FALSE; 567 } 568 569 // <mos> $this->db->CommitTrans(); 570 571 $this->debug_text('add_group (): Added group as ID: '. $insert_id); 572 return $insert_id; 573 } 574 575 /*======================================================================*\ 576 Function: get_group_objects() 577 Purpose: Gets all objects assigned to a group. 578 If $option == 'RECURSE' it will get all objects in child groups as well. 579 defaults to omit child groups. 580 \*======================================================================*/ 581 function get_group_objects($group_id, $group_type='ARO', $option='NO_RECURSE') { 582 583 switch(strtolower(trim($group_type))) { 584 case 'axo': 585 $group_type = 'axo'; 586 $object_table = $this->_db_table_prefix .'axo'; 587 $group_table = $this->_db_table_prefix .'axo_groups'; 588 $map_table = $this->_db_table_prefix .'groups_axo_map'; 589 break; 590 default: 591 $group_type = 'aro'; 592 $object_table = $this->_db_table_prefix .'aro'; 593 $group_table = $this->_db_table_prefix .'aro_groups'; 594 $map_table = $this->_db_table_prefix .'groups_aro_map'; 595 break; 596 } 597 598 $this->debug_text("get_group_objects(): Group ID: $group_id"); 599 600 if (empty($group_id)) { 601 $this->debug_text("get_group_objects(): Group ID: ($group_id) is empty, this is required"); 602 return false; 603 } 604 605 $query = ' 606 SELECT o.section_value,o.value 607 FROM '. $object_table .' o 608 LEFT JOIN '. $map_table .' gm ON o.'. $group_type .'_id=gm.'. $group_type .'_id'; 609 610 if ($option == 'RECURSE') { 611 $query .= ' 612 LEFT JOIN '. $group_table .' g1 ON g1.group_id=gm.group_id 613 LEFT JOIN '. $group_table .' g2 ON g2.lft<=g1.lft AND g2.rgt>=g1.rgt 614 WHERE g2.group_id='. (int) $group_id; 615 } else { 616 $query .= ' 617 WHERE gm.group_id='. (int) $group_id; 618 } 619 620 $this->db->setQuery( $query ); 621 622 $rs = $this->db->loadRowList(); 623 624 if (!is_array( $rs )) { 625 $this->debug_db('get_group_objects'); 626 return false; 627 } 628 629 $this->debug_text("get_group_objects(): Got group objects, formatting array."); 630 631 $retarr = array(); 632 633 //format return array. 634 foreach ($rs as $row) { 635 $section = &$row[0]; 636 $value = &$row[1]; 637 638 $retarr[$section][] = $value; 639 } 640 641 return $retarr; 642 } 643 644 /*======================================================================*\ 645 Function: add_group_object() 646 Purpose: Assigns an Object to a group 647 \*======================================================================*/ 648 function add_group_object($group_id, $object_section_value, $object_value, $group_type='ARO') { 649 650 switch(strtolower(trim($group_type))) { 651 case 'axo': 652 $group_type = 'axo'; 653 $table = $this->_db_table_prefix .'groups_axo_map'; 654 $object_table = $this->_db_table_prefix .'axo'; 655 $group_table = $this->_db_table_prefix .'axo_groups'; 656 break; 657 default: 658 $group_type = 'aro'; 659 $table = $this->_db_table_prefix .'groups_aro_map'; 660 $object_table = $this->_db_table_prefix .'aro'; 661 $group_table = $this->_db_table_prefix .'aro_groups'; 662 break; 663 } 664 665 $this->debug_text("add_group_object(): Group ID: $group_id, Section Value: $object_section_value, Value: $object_value, Group Type: $group_type"); 666 667 $object_section_value = trim($object_section_value); 668 $object_value = trim($object_value); 669 670 if (empty($group_id) OR empty($object_value) OR empty($object_section_value)) { 671 $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"); 672 return false; 673 } 674 675 // test to see if object & group exist and if object is already a member 676 $this->db->setQuery( ' 677 SELECT g.group_id,o.'. $group_type .'_id,gm.group_id AS member 678 FROM '. $object_table .' o 679 LEFT JOIN '. $group_table .' g ON g.group_id='. (int) $group_id .' 680 LEFT JOIN '. $table .' gm ON (gm.group_id=g.group_id AND gm.'. $group_type .'_id=o.'. $group_type .'_id) 681 WHERE (o.section_value=\''. $this->db->getEscaped($object_section_value) .'\' AND o.value=\''. $this->db->getEscaped($object_value) .'\')' 682 ); 683 684 $rows = $this->db->loadRowList(); 685 if ($this->db->getErrorNum()) { 686 $this->debug_db('add_group_object'); 687 return FALSE; 688 } 689 690 if (count( $rows ) != 1) { 691 $this->debug_text("add_group_object (): Group ID ($group_id) OR Value ($object_value) OR Section value ($object_section_value) is invalid. Does this object exist?"); 692 return FALSE; 693 } 694 695 $row = $rows[0]; 696 697 if ($row[2] == 1) { 698 $this->debug_text("add_group_object (): Object: $object_value is already a member of Group ID: $group_id"); 699 //Object is already assigned to group. Return true. 700 return true; 701 } 702 703 $object_id = $row[1]; 704 705 $this->db->setQuery( 'INSERT INTO '. $table .' (group_id,'. $group_type .'_id) VALUES ('. (int) $group_id .','. (int) $object_id .')' ); 706 707 if (!$this->db->query()) { 708 $this->debug_db('add_group_object'); 709 return FALSE; 710 } 711 712 $this->debug_text('add_group_object(): Added Object: '. $object_id .' to Group ID: '. $group_id); 713 714 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 715 //Expire all cache. 716 $this->Cache_Lite->clean('default'); 717 } 718 719 return TRUE; 720 } 721 722 /*======================================================================*\ 723 Function: del_group_object() 724 Purpose: Removes an Object from a group. 725 \*======================================================================*/ 726 function del_group_object($group_id, $object_section_value, $object_value, $group_type='ARO') { 727 728 switch(strtolower(trim($group_type))) { 729 case 'axo': 730 $group_type = 'axo'; 731 $table = $this->_db_table_prefix .'groups_axo_map'; 732 break; 733 default: 734 $group_type = 'aro'; 735 $table = $this->_db_table_prefix .'groups_aro_map'; 736 break; 737 } 738 739 $this->debug_text("del_group_object(): Group ID: $group_id Section value: $object_section_value Value: $object_value"); 740 741 $object_section_value = trim($object_section_value); 742 $object_value = trim($object_value); 743 744 if (empty($group_id) OR empty($object_value) OR empty($object_section_value)) { 745 $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"); 746 return false; 747 } 748 749 if (!$object_id = $this->get_object_id($object_section_value, $object_value, $group_type)) { 750 $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?"); 751 return FALSE; 752 } 753 754 $this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id .' AND '. $group_type .'_id='. (int) $object_id ); 755 $this->db->query(); 756 757 if ($this->db->getErrorNum()) { 758 $this->debug_db('del_group_object'); 759 return false; 760 } 761 762 $this->debug_text("del_group_object(): Deleted Value: $object_value to Group ID: $group_id assignment"); 763 764 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 765 //Expire all cache. 766 $this->Cache_Lite->clean('default'); 767 } 768 769 return true; 770 } 771 772 /*======================================================================*\ 773 Function: edit_group() 774 Purpose: Edits a group 775 \*======================================================================*/ 776 777 /*======================================================================*\ 778 Function: rebuild_tree () 779 Purpose: rebuilds the group tree for the given type 780 \*======================================================================*/ 781 782 /*======================================================================*\ 783 Function: del_group() 784 Purpose: deletes a given group 785 \*======================================================================*/ 786 function del_group($group_id, $reparent_children=TRUE, $group_type='ARO') { 787 788 switch(strtolower(trim($group_type))) { 789 case 'axo': 790 $group_type = 'axo'; 791 $table = $this->_db_table_prefix .'axo_groups'; 792 $groups_map_table = $this->_db_table_prefix .'axo_groups_map'; 793 $groups_object_map_table = $this->_db_table_prefix .'groups_axo_map'; 794 break; 795 default: 796 $group_type = 'aro'; 797 $table = $this->_db_table_prefix .'aro_groups'; 798 $groups_map_table = $this->_db_table_prefix .'aro_groups_map'; 799 $groups_object_map_table = $this->_db_table_prefix .'groups_aro_map'; 800 break; 801 } 802 803 $this->debug_text("del_group(): ID: $group_id Reparent Children: $reparent_children Group Type: $group_type"); 804 805 if (empty($group_id) ) { 806 $this->debug_text("del_group(): Group ID ($group_id) is empty, this is required"); 807 return false; 808 } 809 810 // Get details of this group 811 $this->db->setQuery( 'SELECT group_id, parent_id, name, lft, rgt FROM '. $table .' WHERE group_id='. (int) $group_id ); 812 $group_details = $this->db->loadRow(); 813 814 if (!is_array($group_details)) { 815 $this->debug_db('del_group: get group details'); 816 return false; 817 } 818 819 $parent_id = $group_details[1]; 820 821 $left = $group_details[3]; 822 $right = $group_details[4]; 823 824 // <mos> $this->db->BeginTrans(); 825 826 // grab list of all children 827 $children_ids = $this->get_group_children($group_id, $group_type, 'RECURSE'); 828 829 // prevent deletion of root group & reparent of children if it has more than one immediate child 830 if ($parent_id == 0) { 831 $this->db->setQuery( 'SELECT count(*) FROM '. $table .' WHERE parent_id='. (int) $group_id ); 832 $child_count = $this->db->loadResult(); 833 834 if ($child_count > 1 && $reparent_children) { 835 $this->debug_text ('del_group (): You cannot delete the root group and reparent children, this would create multiple root groups.'); 836 return FALSE; 837 } 838 } 839 840 $success = FALSE; 841 842 /* 843 * Handle children here. 844 */ 845 switch (TRUE) { 846 // there are no child groups, just delete group 847 case !is_array($children_ids): 848 case count($children_ids) == 0: 849 // remove acl maps 850 /* Reapply when ACL's implemented 851 $this->db->setQuery( 'DELETE FROM '. $groups_map_table .' WHERE group_id='. $group_id ); 852 $rs = $this->db->Execute($query); 853 854 if (!is_object($rs)) { 855 break; 856 }*/ 857 858 // remove group object maps 859 $this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id ); 860 $rs = $this->db->query(); 861 862 if (!$rs) { 863 break; 864 } 865 866 // remove group 867 $this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id ); 868 $rs = $this->db->query(); 869 870 if (!$rs) { 871 break; 872 } 873 874 // move all groups right of deleted group left by width of deleted group 875 $this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-'. (int) ($right-$left+1) .' WHERE lft>'. (int) $right ); 876 $rs = $this->db->query(); 877 878 if (!$rs) { 879 break; 880 } 881 882 $this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-'. (int) ($right-$left+1) .' WHERE rgt>'. (int) $right ); 883 $rs = $this->db->query(); 884 885 if (!$rs) { 886 break; 887 } 888 889 $success = TRUE; 890 break; 891 case $reparent_children == TRUE: 892 // remove acl maps 893 /* Reapply when ACL's implemented 894 $query = 'DELETE FROM '. $groups_map_table .' WHERE group_id='. $group_id; 895 $rs = $this->db->Execute($query); 896 897 if (!is_object($rs)) { 898 break; 899 }*/ 900 901 // remove group object maps 902 $this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id='. (int) $group_id ); 903 $rs = $this->db->query(); 904 905 if (!$rs) { 906 break; 907 } 908 909 // remove group 910 $this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id='. (int) $group_id ); 911 $rs = $this->db->query(); 912 913 if (!$rs) { 914 break; 915 } 916 917 // set parent of immediate children to parent group 918 $this->db->setQuery( 'UPDATE '. $table .' SET parent_id='. (int) $parent_id .' WHERE parent_id='. (int) $group_id ); 919 $rs = $this->db->query(); 920 921 if (!$rs) { 922 break; 923 } 924 925 // move all children left by 1 926 $this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-1, rgt=rgt-1 WHERE lft>'. (int) $left .' AND rgt<'. (int) $right ); 927 $rs = $this->db->query(); 928 929 if (!$rs) { 930 break; 931 } 932 933 // move all groups right of deleted group left by 2 934 $this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-2 WHERE lft>'. (int) $right ); 935 $rs = $this->db->query(); 936 937 if (!$rs) { 938 break; 939 } 940 941 $this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-2 WHERE rgt>'. (int) $right ); 942 $rs = $this->db->query(); 943 944 if (!$rs) { 945 break; 946 } 947 948 $success = TRUE; 949 break; 950 default: 951 // make list of group and all children 952 $group_ids = $children_ids; 953 $group_ids[] = $group_id; 954 955 // remove acl maps 956 /* Reapply when ACL's implemented 957 $query = 'DELETE FROM '. $groups_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')'; 958 $rs = $this->db->Execute($query); 959 960 if (!is_object($rs)) { 961 break; 962 }*/ 963 964 // remove group object maps 965 mosArrayToInts( $group_ids ); 966 $this->db->setQuery( 'DELETE FROM '. $groups_object_map_table .' WHERE group_id IN ('. implode (',', $group_ids) .')' ); 967 $rs = $this->db->query(); 968 969 if (!$rs) { 970 break; 971 } 972 973 // remove groups 974 $this->db->setQuery( 'DELETE FROM '. $table .' WHERE group_id IN ('. implode (',', $group_ids) .')' ); 975 $rs = $this->db->query(); 976 977 if (!$rs) { 978 break; 979 } 980 981 // move all groups right of deleted group left by width of deleted group 982 $this->db->setQuery( 'UPDATE '. $table .' SET lft=lft-'. (int) ($right - $left + 1) .' WHERE lft>'. (int) $right ); 983 $rs = $this->db->query(); 984 985 if (!$rs) { 986 break; 987 } 988 989 $this->db->setQuery( 'UPDATE '. $table .' SET rgt=rgt-'. (int) ($right - $left + 1) .' WHERE rgt>'. (int) $right ); 990 $rs = $this->db->query(); 991 992 if (!$rs) { 993 break; 994 } 995 996 $success = TRUE; 997 } 998 999 // if the delete failed, rollback the trans and return false 1000 if (!$success) { 1001 1002 $this->debug_db('del_group'); 1003 $this->db->RollBackTrans(); 1004 return false; 1005 } 1006 1007 $this->debug_text("del_group(): deleted group ID: $group_id"); 1008 // <mos> $this->db->CommitTrans(); 1009 1010 if ($this->_caching == TRUE AND $this->_force_cache_expire == TRUE) { 1011 //Expire all cache. 1012 $this->Cache_Lite->clean('default'); 1013 } 1014 1015 return true; 1016 1017 } 1018 1019 1020 /* 1021 * 1022 * Objects (ACO/ARO/AXO) 1023 * 1024 */ 1025 /*======================================================================*\ 1026 Function: get_object() 1027 Purpose: Grabs all Objects's in the database, or specific to a section_value 1028 \*======================================================================*/ 1029 function get_object($section_value = null, $return_hidden=1, $object_type=NULL) { 1030 1031 switch(strtolower(trim($object_type))) { 1032 case 'aco': 1033 $object_type = 'aco'; 1034 $table = $this->_db_table_prefix .'aco'; 1035 break; 1036 case 'aro': 1037 $object_type = 'aro'; 1038 $table = $this->_db_table_prefix .'aro'; 1039 break; 1040 case 'axo': 1041 $object_type = 'axo'; 1042 $table = $this->_db_table_prefix .'axo'; 1043 break; 1044 default: 1045 $this->debug_text('get_object(): Invalid Object Type: '. $object_type); 1046 return FALSE; 1047 } 1048 1049 $this->debug_text("get_object(): Section Value: $section_value Object Type: $object_type"); 1050 1051 $$this->db->setQuery( 'SELECT '. $object_type .'_id FROM '. $table ); 1052 1053 $where = array(); 1054 1055 if (!empty($section_value)) { 1056 $where[] = 'section_value='. $this->db->getEscaped($section_value); 1057 } 1058 1059 if ($return_hidden==0) { 1060 $where[] = 'hidden=0'; 1061 } 1062 1063 if (!empty($where)) { 1064 $query .= ' WHERE '. implode(' AND ', $where); 1065 } 1066 1067 $rs = $this->db->loadResultArray(); 1068 1069 if (!is_array($rs)) { 1070 $this->debug_db('get_object'); 1071 return false; 1072 } 1073 1074 // Return Object IDs 1075 return $rs; 1076 } 1077 1078 /*======================================================================*\ 1079 Function: get_objects () 1080 Purpose: Grabs all Objects in the database, or specific to a section_value 1081 returns format suitable for add_acl and is_conflicting_acl 1082 \*======================================================================*/ 1083 1084 /*======================================================================*\ 1085 Function: get_object_data() 1086 Purpose: Gets all data pertaining to a specific Object. 1087 \*======================================================================*/ 1088 1089 /*======================================================================*\ 1090 Function: get_object_groups() 1091 Purpose: Gets the group_id's for the given the section_value AND value 1092 of the object. 1093 \*======================================================================*/ 1094 function get_object_groups($object_section_value, $object_value, $object_type=NULL) { 1095 1096 switch(strtolower(trim($object_type))) { 1097 case 'aro': 1098 $group_type = 'aro'; 1099 $table = $this->_db_table_prefix .'groups_aro_map'; 1100 $object_table = $this->_db_table_prefix .'aro'; 1101 $group_table = $this->_db_table_prefix .'aro_groups'; 1102 break; 1103 case 'axo': 1104 $group_type = 'axo'; 1105 $table = $this->_db_table_prefix .'groups_axo_map'; 1106 $object_table = $this->_db_table_prefix .'axo'; 1107 $group_table = $this->_db_table_prefix .'axo_groups'; 1108 break; 1109 default: 1110 $this->debug_text('get_object_groups(): Invalid Object Type: '. $object_type); 1111 return FALSE; 1112 } 1113 1114 $this->debug_text("get_object_groups(): Section Value: $object_section_value Value: $object_value Object Type: $object_type"); 1115 1116 $object_section_value = trim($object_section_value); 1117 $object_value = trim($object_value); 1118 1119 if (empty($object_section_value) AND empty($object_value) ) { 1120 $this->debug_text("get_object_groups(): Section Value ($object_section_value) AND value ($object_value) is empty, this is required"); 1121 return false; 1122 } 1123 1124 if (empty($object_type) ) { 1125 $this->debug_text("get_object_groups(): Object Type ($object_type) is empty, this is required"); 1126 return false; 1127 } 1128 // SELECT g.group_id,o.'. $group_type .'_id,(gm.group_id IS NOT NULL) AS member 1129 1130 $this->db->setQuery( ' 1131 SELECT g.group_id,o.'. $group_type .'_id,(gm.group_id IS NOT NULL) AS member 1132 FROM '. $group_table .' g 1133 LEFT JOIN '. $table .' gm ON gm.group_id=g.group_id 1134 LEFT JOIN '. $object_table .' o ON o.'. $group_type .'_id = gm.'. $group_type .'_id 1135 WHERE (o.section_value=\''. $this->db->getEscaped($object_section_value) .'\' AND o.value=\''. $this->db->getEscaped($object_value) .'\')' 1136 ); 1137 $rs = $this->db->loadResultArray(); 1138 1139 if ($this->db->getErrorNum()) { 1140 $this->debug_db('get_object_id'); 1141 return false; 1142 } 1143 1144 //Return the array of group id's 1145 return $rs; 1146 } 1147 1148 /*======================================================================*\ 1149 Function: get_object_id() 1150 Purpose: Gets the object_id given the section_value AND value of the object. 1151 \*======================================================================*/ 1152 function get_object_id($section_value, $value, $object_type=NULL) { 1153 1154 switch(strtolower(trim($object_type))) { 1155 case 'aco': 1156 $object_type = 'aco'; 1157 $table = $this->_db_table_prefix .'aco'; 1158 break; 1159 case 'aro': 1160 $object_type = 'aro'; 1161 $table = $this->_db_table_prefix .'aro'; 1162 break; 1163 case 'axo': 1164 $object_type = 'axo'; 1165 $table = $this->_db_table_prefix .'axo'; 1166 break; 1167 default: 1168 $this->debug_text('get_object_id(): Invalid Object Type: '. $object_type); 1169 return FALSE; 1170 } 1171 1172 $this->debug_text("get_object_id(): Section Value: $section_value Value: $value Object Type: $object_type"); 1173 1174 $section_value = trim($section_value); 1175 $value = trim($value); 1176 1177 if (empty($section_value) AND empty($value) ) { 1178 $this->debug_text("get_object_id(): Section Value ($value) AND value ($value) is empty, this is required"); 1179 return false; 1180 } 1181 1182 if (empty($object_type) ) { 1183 $this->debug_text("get_object_id(): Object Type ($object_type) is empty, this is required"); 1184 return false; 1185 } 1186 1187 $this->db->setQuery( 'SELECT '. $object_type .'_id FROM '. $table .' WHERE section_value=\''. $this->db->getEscaped($section_value) .'\' AND value=\''. $this->db->getEscaped($value) .'\'' 1188 ); 1189 $rs = $this->db->loadRowList(); 1190 1191 if ($this->db->getErrorNum()) { 1192 $this->debug_db('get_object_id'); 1193 return false; 1194 } 1195 1196 $row_count = count( $rs ); 1197 1198 if ($row_count > 1) { 1199 $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."); 1200 return false; 1201 } 1202 1203 if ($row_count == 0) { 1204 $this->debug_text("get_object_id(): Returned $row_count rows"); 1205 return false; 1206 } 1207 1208 $row = $rs[0]; 1209 1210 //Return the ID. 1211 return $row[0]; 1212 } 1213 1214 /*======================================================================*\ 1215 Function: get_object_section_value() 1216 Purpose: Gets the object_section_value given object id 1217 \*======================================================================*/ 1218 1219 /*======================================================================*\ 1220 Function: get_object_groups() 1221 Purpose: Gets all groups an object is a member of. 1222 If $option == 'RECURSE' it will get all ancestor groups. 1223 defaults to only get direct parents. 1224 \*======================================================================*/ 1225 1226 /*======================================================================*\ 1227 Function: add_object() 1228 Purpose: Inserts a new object 1229 \*======================================================================*/ 1230 function add_object($section_value, $name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 1231 1232 switch(strtolower(trim($object_type))) { 1233 case 'aco': 1234 $object_type = 'aco'; 1235 $table = $this->_db_table_prefix .'aco'; 1236 $object_sections_table = $this->_db_table_prefix .'aco_sections'; 1237 break; 1238 case 'aro': 1239 $object_type = 'aro'; 1240 $table = $this->_db_table_prefix .'aro'; 1241 $object_sections_table = $this->_db_table_prefix .'aro_sections'; 1242 break; 1243 case 'axo': 1244 $object_type = 'axo'; 1245 $table = $this->_db_table_prefix .'axo'; 1246 $object_sections_table = $this->_db_table_prefix .'axo_sections'; 1247 break; 1248 default: 1249 $this->debug_text('add_object(): Invalid Object Type: '. $object_type); 1250 return FALSE; 1251 } 1252 1253 $this->debug_text("add_object(): Section Value: $section_value Value: $value Order: $order Name: $name Object Type: $object_type"); 1254 1255 $section_value = trim($section_value); 1256 $name = trim($name); 1257 $value = trim($value); 1258 $order = trim($order); 1259 $hidden = (int) $hidden; 1260 1261 if ($order == NULL OR $order == '') { 1262 $order = 0; 1263 } 1264 1265 if (empty($name) OR empty($section_value) ) { 1266 $this->debug_text("add_object(): name ($name) OR section value ($section_value) is empty, this is required"); 1267 return false; 1268 } 1269 1270 if (strlen($name) >= 255 OR strlen($value) >= 230 ) { 1271 $this->debug_text("add_object(): name ($name) OR value ($value) is too long."); 1272 return false; 1273 } 1274 1275 if (empty($object_type) ) { 1276 $this->debug_text("add_object(): Object Type ($object_type) is empty, this is required"); 1277 return false; 1278 } 1279 1280 // Test to see if the section is invalid or object already exists. 1281 $this->db->setQuery( ' 1282 SELECT (o.'. $object_type .'_id IS NOT NULL) AS object_exists 1283 FROM '. $object_sections_table .' s 1284 LEFT JOIN '. $table .' o ON (s.value=o.section_value AND o.value=\''. $this->db->getEscaped($value) .'\') 1285 WHERE s.value=\''. $this->db->getEscaped($section_value). '\'' 1286 ); 1287 1288 $rows = $this->db->loadRowList(); 1289 if ($this->db->getErrorNum()) { 1290 $this->debug_db('add_object'); 1291 return FALSE; 1292 } 1293 1294 if (count( $rows ) != 1) { 1295 // Section is invalid 1296 $this->debug_text("add_object(): Section Value: $section_value Object Type ($object_type) does not exist, this is required"); 1297 return false; 1298 } 1299 1300 $row = $rows[0]; 1301 1302 if ($row[0] == 1) { 1303 //Object is already created. 1304 return true; 1305 } 1306 1307 $insert_id = $this->db->GenID($this->_db_table_prefix.$object_type.'_seq',10); 1308 $this->db->setQuery( "INSERT INTO $table ({$object_type}_id,section_value,value,order_value,name,hidden) VALUES(" . (int) $insert_id . "," . $this->db->Quote( $section_value ) . "," . $this->db->Quote( $value ) . "," . $this->db->Quote( $order ) . "," . $this->db->Quote( $name ) . "," . (int) $hidden . ")" ); 1309 1310 if (!$this->db->query()) { 1311 $this->debug_db('add_object'); 1312 return false; 1313 } 1314 1315 $insert_id = $this->db->insertid(); 1316 $this->debug_text("add_object(): Added object as ID: $insert_id"); 1317 return $insert_id; 1318 } 1319 /*======================================================================*\ 1320 Function: edit_object() 1321 Purpose: Edits a given Object 1322 \*======================================================================*/ 1323 function edit_object($object_id, $section_value, $name, $value=0, $order=0, $hidden=0, $object_type=NULL) { 1324 1325 switch(strtolower(trim($object_type))) { 1326 case 'aco': 1327 $object_type = 'aco'; 1328 $table = $this->_db_table_prefix .'aco'; 1329 $object_map_table = 'aco_map'; 1330 break; 1331 case 'aro': 1332 $object_type = 'aro'; 1333 $table = $this->_db_table_prefix .'aro'; 1334 $object_map_table = 'aro_map'; 1335 break; 1336 case 'axo': 1337 $object_type = 'axo'; 1338 $table = $this->_db_table_prefix .'axo'; 1339 $object_map_table = 'axo_map'; 1340 break; 1341 } 1342 1343 $this->debug_text("edit_object(): ID: $object_id, Section Value: $section_value, Value: $value, Order: $order, Name: $name, Object Type: $object_type"); 1344 1345 $section_value = trim($section_value); 1346 $name = trim($name); 1347 $value = trim($value); 1348 $order = trim($order); 1349 1350 if (empty($object_id) OR empty($section_value) ) { 1351 $this->debug_text("edit_object(): Object ID ($object_id) OR Section Value ($section_value) is empty, this is required"); 1352 return false; 1353 } 1354 1355 if (empty($name) ) { 1356 $this->debug_text("edit_object(): name ($name) is empty, this is required"); 1357 return false; 1358 } 1359 1360 if (empty($object_type) ) { 1361 $this->debug_text("edit_object(): Object Type ($object_type) is empty, this is required"); 1362 return false; 1363 } 1364 1365 //Get old value incase it changed, before we do the update. 1366 $this->db->setQuery( 'SELECT value, section_value FROM '. $table .' WHERE '. $object_type .'_id='. (int) $object_id ); 1367 $old = $this->db->loadRow(); 1368 1369 $this->db->setQuery( ' 1370 UPDATE '. $table .' 1371 SET section_value=\''. $this->db->getEscaped($section_value) .'\', 1372 value=\''. $this->db->getEscaped($value) .'\', 1373 order_value=\''. $this->db->getEscaped($order) .'\', 1374 name=\''. $this->db->getEscaped($name) .'\', 1375 hidden='. (int) $hidden .' 1376 WHERE '. $object_type .'_id='. (int) $object_id 1377 ); 1378 $this->db->query(); 1379 1380 if (!$this->db->getErrorNum()) { 1381 $this->debug_db('edit_object'); 1382 return false; 1383 } 1384 1385 $this->debug_text('edit_object(): Modified '. strtoupper($object_type) .' ID: '. $object_id); 1386 1387 if ($old[0] != $value OR $old[1] != $section_value) { 1388 $this->debug_text("edit_object(): Value OR Section Value Changed, update other tables."); 1389 1390 $this->db->setQuery( ' 1391 UPDATE '. $object_map_table .' 1392 SET value=\''. $this->db->getEscaped($value) .'\', 1393 section_value=\''. $this->db->getEscaped($section_value) .'\' 1394 WHERE section_value=\''. $this->db->getEscaped($old[1]) .'\' 1395 AND value=\''. $this->db->getEscaped($old[0]) . '\'' 1396 ); 1397 $this->db->query(); 1398 1399 if (!$this->db->getErrorNum()) { 1400 $this->debug_db('edit_object'); 1401 return FALSE; 1402 } 1403 1404 $this->debug_text ('edit_object(): Modified Map Value: '. $value .' Section Value: '. $section_value); 1405 } 1406 1407 return TRUE; 1408 } 1409 1410 /*======================================================================*\ 1411 Function: del_object() 1412 Purpose: Deletes a given Object and, if instructed to do so, 1413 erase all referencing objects 1414 ERASE feature by: Martino Piccinato 1415 \*======================================================================*/ 1416 function del_object($object_id, $object_type=NULL, $erase=FALSE) { 1417 1418 switch(strtolower(trim($object_type))) { 1419 case 'aco': 1420 $object_type = 'aco'; 1421 $table = $this->_db_table_prefix .'aco'; 1422 $object_map_table = $this->_db_table_prefix .'aco_map'; 1423 break; 1424 case 'aro': 1425 $object_type = 'aro'; 1426 $table = $this->_db_table_prefix .'aro'; 1427 $object_map_table = $this->_db_table_prefix .'aro_map'; 1428 $groups_map_table = $this->_db_table_prefix .'aro_groups_map'; 1429 $object_group_table = $this->_db_table_prefix .'groups_aro_map'; 1430 break; 1431 case 'axo': 1432 $object_type = 'axo'; 1433 $table = $this->_db_table_prefix .'axo'; 1434 $object_map_table = $this->_db_table_prefix .'axo_map'; 1435 $groups_map_table = $this->_db_table_prefix .'axo_groups_map'; 1436 $object_group_table = $this->_db_table_prefix .'groups_axo_map'; 1437 break; 1438 default: 1439 $this->debug_text('del_object(): Invalid Object Type: '. $object_type); 1440 return FALSE; 1441 } 1442 1443 $this->debug_text("del_object(): ID: $object_id Object Type: $object_type, Erase all referencing objects: $erase"); 1444 1445 if (empty($object_id) ) { 1446 $this->debug_text("del_object(): Object ID ($object_id) is empty, this is required"); 1447 return false; 1448 } 1449 1450 if (empty($object_type) ) { 1451 $this->debug_text("del_object(): Object Type ($object_type) is empty, this is required"); 1452 return false; 1453 } 1454 1455 // <mos> $this->db->BeginTrans(); 1456 1457 // Get Object section_value/value (needed to look for referencing objects) 1458 $this->db->setQuery( 'SELECT section_value,value FROM '. $table .' WHERE '. $object_type .'_id='. (int) $object_id ); 1459 $object = $this->db->loadRow(); 1460 1461 if (empty($object)) { 1462 $this->debug_text('del_object(): The specified object ('. strtoupper($object_type) .' ID: '. $object_id .') could not be found.<br />SQL = '.$this->db->stderr()); 1463 return FALSE; 1464 } 1465 1466 $section_value = $object[0]; 1467 $value = $object[1]; 1468 1469 // Get ids of acl referencing the Object (if any) 1470 $this->db->setQuery( "SELECT acl_id FROM $object_map_table WHERE value=" . $this->db->Quote( $value ) . " AND section_value=" . $this->db->Quote( $section_value ) ); 1471 $acl_ids = $this->db->loadResultArray(); 1472 1473 if ($erase) { 1474 // We were asked to erase all acl referencing it 1475 1476 $this->debug_text("del_object(): Erase was set to TRUE, delete all referencing objects"); 1477 1478 if ($object_type == "aro" OR $object_type == "axo") { 1479 // The object can be referenced in groups_X_map tables 1480 // in the future this branching may become useless because 1481 // ACO might me "groupable" too 1482 1483 // Get rid of groups_map referencing the Object 1484 $this->db->setQuery( 'DELETE FROM '. $object_group_table .' WHERE '. $object_type .'_id='. (int) $object_id ); 1485 $rs = $this->db->query(); 1486 1487 if (!$rs) { 1488 $this->debug_db('edit_object'); 1489 // <mos> $this->db->RollBackTrans(); 1490 return false; 1491 } 1492 } 1493 1494 if ($acl_ids) { 1495 //There are acls actually referencing the object 1496 1497 if ($object_type == 'aco') { 1498 // I know it's extremely dangerous but 1499 // if asked to really erase an ACO 1500 // we should delete all acl referencing it 1501 // (and relative maps) 1502 1503 // Do this below this branching 1504 // where it uses $orphan_acl_ids as 1505 // the array of the "orphaned" acl 1506 // in this case all referenced acl are 1507 // orhpaned acl 1508 1509 $orphan_acl_ids = $acl_ids; 1510 } else { 1511 // The object is not an ACO and might be referenced 1512 // in still valid acls regarding also other object. 1513 // In these cases the acl MUST NOT be deleted 1514 1515 // Get rid of $object_id map referencing erased objects 1516 $this->db->setQuery( "DELETE FROM $object_map_table WHERE section_value=" . $this->db->Quote( $section_value ) . " AND value=" . $this->db->Quote( $value ) ); 1517 $rs = $this->db->query(); 1518 1519 if (!$rs) { 1520 $this->debug_db('edit_object'); 1521 $this->db->RollBackTrans(); 1522 return false; 1523 } 1524 1525 // Find the "orphaned" acl. I mean acl referencing the erased Object (map) 1526 // not referenced anymore by other objects 1527 1528 mosArrayToInts( $acl_ids ); 1529 $sql_acl_ids = implode(",", $acl_ids); 1530 1531 $this->db->setQuery( ' 1532 SELECT a.id 1533 FROM '. $this->_db_table_prefix .'acl a 1534 LEFT JOIN '. $object_map_table .' b ON a.id=b.acl_id 1535 './* <mos return for full acl stuff> LEFT JOIN '. $groups_map_table .' c ON a.id=c.acl_id*/' 1536 WHERE value IS NULL 1537 AND section_value IS NULL 1538 AND group_id IS NULL 1539 AND a.id in ('. $sql_acl_ids .')'); 1540 $orphan_acl_ids = $this->db->loadResultArray(); 1541 1542 } // End of else section of "if ($object_type == "aco")" 1543 1544 if ($orphan_acl_ids) { 1545 // If there are orphaned acls get rid of them 1546 1547 foreach ($orphan_acl_ids as $acl) { 1548 $this->del_acl($acl); 1549 } 1550 } 1551 1552 } // End of if ($acl_ids) 1553 1554 // Finally delete the Object itself 1555 $this->db->setQuery( "DELETE FROM $table WHERE {$object_type}_id=" . (int) $object_id ); 1556 $rs = $this->db->query(); 1557 1558 if (!$rs) { 1559 $this->debug_db('edit_object'); 1560 // <mos> $this->db->RollBackTrans(); 1561 return false; 1562 } 1563 1564 // <mos> $this->db->CommitTrans(); 1565 return true; 1566 1567 } // End of "if ($erase)" 1568 1569 $groups_ids = FALSE; 1570 1571 if ($object_type == 'axo' OR $object_type == 'aro') { 1572 // If the object is "groupable" (may become unnecessary, 1573 // see above 1574 1575 // Get id of groups where the object is assigned: 1576 // you must explicitly remove the object from its groups before 1577 // deleting it (don't know if this is really needed, anyway it's safer ;-) 1578 1579 $this->db->setQuery( 'SELECT group_id FROM '. $object_group_table .' WHERE '. $object_type .'_id='. (int) $object_id ); 1580 $groups_ids = $this->db->loadResultArray(); 1581 } 1582 1583 if ( ( isset($acl_ids) AND $acl_ids !== FALSE ) OR ( isset($groups_ids) AND $groups_ids !== FALSE) ) { 1584 // The Object is referenced somewhere (group or acl), can't delete it 1585 1586 $this->debug_text("del_object(): Can't delete the object as it is being referenced by GROUPs (".@implode($group_ids).") or ACLs (".@implode($acl_ids,",").")"); 1587 1588 return false; 1589 } else { 1590 // The Object is NOT referenced anywhere, delete it 1591 1592 $this->db->setQuery( "DELETE FROM $table WHERE {$object_type}_id=" . (int) $object_id ); 1593 $this->db->query(); 1594 1595 if ( $this->db->getErrorNum() ) { 1596 $this->debug_db('edit_object'); 1597 // <mos> $this->db->RollBackTrans(); 1598 return false; 1599 } 1600 1601 // <mos> $this->db->CommitTrans(); 1602 return true; 1603 } 1604 1605 return false; 1606 } 1607 1608 /* 1609 * 1610 * Object Sections 1611 * 1612 */ 1613 1614 /*======================================================================*\ 1615 Function: get_object_section_section_id() 1616 Purpose: Gets the object_section_id given the name AND/OR value of the section. 1617 Will only return one section id, so if there are duplicate names it will return false. 1618 \*======================================================================*/ 1619 1620 /*======================================================================*\ 1621 Function: add_object_section() 1622 Purpose: Inserts an object Section 1623 \*======================================================================*/ 1624 1625 /*======================================================================*\ 1626 Function: edit_object_section() 1627 Purpose: Edits a given Object Section 1628 \*======================================================================*/ 1629 1630 /*======================================================================*\ 1631 Function: del_object_section() 1632 Purpose: Deletes a given Object Section and, if explicitly 1633 asked, all the section objects 1634 ERASE feature by: Martino Piccinato 1635 \*======================================================================*/ 1636 1637 /* 1638 * 1639 * Joomla! Utility Methods 1640 * 1641 */ 1642 1643 /*======================================================================*\ 1644 Function: has_group_parent 1645 Purpose: Checks whether the 'source' group is a child of the 'target' 1646 \*======================================================================*/ 1647 function is_group_child_of( $grp_src, $grp_tgt, $group_type='ARO' ) { 1648 $this->debug_text("has_group_parent(): Source=$grp_src, Target=$grp_tgt, Type=$group_type"); 1649 1650 switch(strtolower(trim($group_type))) { 1651 case 'axo': 1652 $table = $this->_db_table_prefix .'axo_groups'; 1653 break; 1654 default: 1655 $table = $this->_db_table_prefix .'aro_groups'; 1656 break; 1657 } 1658 1659 if (is_int( $grp_src ) && is_int($grp_tgt)) { 1660 $this->db->setQuery( "SELECT COUNT(*)" 1661 . "\nFROM $table AS g1" 1662 . "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt" 1663 . "\nWHERE g1.group_id=" . (int) $grp_src . " AND g2.group_id=" . (int) $grp_tgt 1664 ); 1665 } else if (is_string( $grp_src ) && is_string($grp_tgt)) { 1666 $this->db->setQuery( "SELECT COUNT(*)" 1667 . "\nFROM $table AS g1" 1668 . "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt" 1669 . "\nWHERE g1.name=" . $this->db->Quote( $grp_src ) . " AND g2.name=" . $this->db->Quote( $grp_tgt ) 1670 ); 1671 } else if (is_int( $grp_src ) && is_string($grp_tgt)) { 1672 $this->db->setQuery( "SELECT COUNT(*)" 1673 . "\nFROM $table AS g1" 1674 . "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt" 1675 . "\nWHERE g1.group_id=" . (int) $grp_src . " AND g2.name=" . $this->db->Quote( $grp_tgt ) 1676 ); 1677 } else { 1678 $this->db->setQuery( "SELECT COUNT(*)" 1679 . "\nFROM $table AS g1" 1680 . "\nLEFT JOIN $table AS g2 ON g1.lft > g2.lft AND g1.lft < g2.rgt" 1681 . "\nWHERE g1.name=" . $this->db->Quote( $grp_src ) . " AND g2.group_id=" . (int) $grp_tgt 1682 ); 1683 } 1684 1685 return $this->db->loadResult(); 1686 } 1687 1688 function getAroGroup( $value ) { 1689 return $this->_getGroup( 'aro', $value ); 1690 } 1691 1692 function _getGroup( $type, $value ) { 1693 global $database; 1694 1695 $database->setQuery( "SELECT g.*" 1696 . "\nFROM #__core_acl_{$type}_groups AS g" 1697 . "\nINNER JOIN #__core_acl_groups_{$type}_map AS gm ON gm.group_id = g.group_id" 1698 . "\nINNER JOIN #__core_acl_{$type} AS ao ON ao.{$type}_id = gm.{$type}_id" 1699 . "\nWHERE ao.value=" . $this->db->Quote( $value ) 1700 ); 1701 $obj = null; 1702 $database->loadObject( $obj ); 1703 return $obj; 1704 } 1705 1706 function _getAbove() { 1707 } 1708 1709 function _getBelow( $table, $fields, $groupby=null, $root_id=null, $root_name=null, $inclusive=true ) { 1710 global $database; 1711 1712 $root = new stdClass(); 1713 $root->lft = 0; 1714 $root->rgt = 0; 1715 1716 if ($root_id) { 1717 } else if ($root_name) { 1718 $database->setQuery( "SELECT lft, rgt FROM $table WHERE name=" . $this->db->Quote( $root_name ) ); 1719 $database->loadObject( $root ); 1720 } 1721 1722 $where = ''; 1723 if ($root->lft+$root->rgt != 0) { 1724 if ($inclusive) { 1725 $where = "WHERE g1.lft BETWEEN " . (int) $root->lft . " AND " . (int) $root->rgt; 1726 } else { 1727 $where = "WHERE g1.lft BETWEEN " . (int) ($root->lft+1) . " AND " . (int) ($root->rgt-1); 1728 } 1729 } 1730 1731 $database->setQuery( "SELECT $fields" 1732 . "\nFROM $table AS g1" 1733 . "\nINNER JOIN $table AS g2 ON g1.lft BETWEEN g2.lft AND g2.rgt" 1734 . "\n$where" 1735 . ($groupby ? "\nGROUP BY $groupby" : "") 1736 . "\nORDER BY g1.lft" 1737 ); 1738 1739 //echo $database->getQuery(); 1740 return $database->loadObjectList(); 1741 } 1742 1743 function get_group_children_tree( $root_id=null, $root_name=null, $inclusive=true ) { 1744 global $database; 1745 1746 $tree = gacl_api::_getBelow( '#__core_acl_aro_groups', 1747 'g1.group_id, g1.name, COUNT(g2.name) AS level', 1748 'g1.name', 1749 $root_id, $root_name, $inclusive ); 1750 1751 // first pass get level limits 1752 $n = count( $tree ); 1753 $min = $tree[0]->level; 1754 $max = $tree[0]->level; 1755 for ($i=0; $i < $n; $i++) { 1756 $min = min( $min, $tree[$i]->level ); 1757 $max = max( $max, $tree[$i]->level ); 1758 } 1759 1760 $indents = array(); 1761 foreach (range( $min, $max ) as $i) { 1762 $indents[$i] = ' '; 1763 } 1764 // correction for first indent 1765 $indents[$min] = ''; 1766 1767 $list = array(); 1768 for ($i=$n-1; $i >= 0; $i--) { 1769 $shim = ''; 1770 foreach (range( $min, $tree[$i]->level ) as $j) { 1771 $shim .= $indents[$j]; 1772 } 1773 1774 if (@$indents[$tree[$i]->level+1] == '. ') { 1775 $twist = ' '; 1776 } else { 1777 $twist = "- "; 1778 } 1779 1780 //$list[$i] = $tree[$i]->level.$shim.$twist.$tree[$i]->name; 1781 $list[$i] = mosHTML::makeOption( $tree[$i]->group_id, $shim.$twist.$tree[$i]->name ); 1782 if ($tree[$i]->level < @$tree[$i-1]->level) { 1783 $indents[$tree[$i]->level+1] = '. '; 1784 } 1785 } 1786 1787 ksort($list); 1788 return $list; 1789 } 1790 } 1791 1792 class mosARO extends mosDBTable { 1793 /** @var int Primary key */ 1794 var $aro_id=null; 1795 var $section_value=null; 1796 var $value=null; 1797 var $order_value=null; 1798 var $name=null; 1799 var $hidden=null; 1800 1801 function mosARO( &$db ) { 1802 $this->mosDBTable( '#__core_acl_aro', 'aro_id', $db ); 1803 } 1804 1805 /** 1806 * Utility function for returning groups 1807 */ 1808 1809 } 1810 1811 class mosAroGroup extends mosDBTable { 1812 /** @var int Primary key */ 1813 var $group_id=null; 1814 var $parent_id=null; 1815 var $name=null; 1816 var $lft=null; 1817 var $rgt=null; 1818 1819 function mosAroGroup( &$db ) { 1820 $this->mosDBTable( '#__core_acl_aro_groups', 'group_id', $db ); 1821 } 1822 } 1823 1824 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
|