Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: phpGACL

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /phpgacl/gacl_api.php

Documentation is available at gacl_api.php

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

Documentation generated on Mon, 05 Mar 2007 21:04:03 +0000 by phpDocumentor 1.3.1