[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/phpgacl/ -> gacl.php (source)

   1  <?php
   2  // $Id: gacl.php 10381 2008-06-01 03:35:53Z pasamio $
   3  
   4  /**
   5   * phpGACL - Generic Access Control List
   6   * Copyright (C) 2002,2003 Mike Benoit
   7   *
   8   * This library is free software; you can redistribute it and/or
   9   * modify it under the terms of the GNU Lesser General Public
  10   * License as published by the Free Software Foundation; either
  11   * version 2.1 of the License, or (at your option) any later version.
  12   *
  13   * This library is distributed in the hope that it will be useful,
  14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16   * Lesser General Public License for more details.
  17   *
  18   * You should have received a copy of the GNU Lesser General Public
  19   * License along with this library; if not, write to the Free Software
  20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21   *
  22   * For questions, help, comments, discussion, etc., please join the
  23   * phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103
  24   *
  25   * You may contact the author of phpGACL by e-mail at:
  26   * ipso@snappymail.ca
  27   *
  28   * The latest version of phpGACL can be obtained from:
  29   * http://phpgacl.sourceforge.net/
  30   *
  31   * @package phpGACL
  32   */
  33  
  34  /*
  35   * Path to ADODB.
  36   */
  37  //if ( !defined('ADODB_DIR') ) {
  38  //    define('ADODB_DIR', dirname(__FILE__).'/adodb');
  39  //}
  40  // Causing conflicts with 3rd party apps using adodb
  41  
  42  /**
  43  * phpGACL main class
  44  *
  45  * Class gacl should be used in applications where only querying the phpGACL
  46  * database is required.
  47  *
  48  * @package phpGACL
  49  * @author Mike Benoit <ipso@snappymail.ca>
  50  */
  51  class gacl {
  52      /*
  53      --- Private properties ---
  54      */
  55      /** @var boolean Enables Debug output if true */
  56      var $_debug = FALSE;
  57  
  58      /**
  59       * Joomla usage
  60       */
  61      var $_debugLog = null;
  62  
  63      /*
  64      --- Database configuration. ---
  65      */
  66      /** @var string Prefix for all the phpgacl tables in the database */
  67      var $_db_table_prefix = '';
  68  
  69      /** @var string The database type, based on available ADODB connectors - mysql, postgres7, sybase, oci8po See here for more: http://php.weblogs.com/adodb_manual#driverguide */
  70      var $_db_type = 'mysql';
  71  
  72      /** @var string The database server */
  73      var $_db_host = 'localhost';
  74  
  75      /** @var string The database user name */
  76      var $_db_user = 'root';
  77  
  78      /** @var string The database user password */
  79      var $_db_password = '';
  80  
  81      /** @var string The database name */
  82      var $_db_name = 'gacl';
  83  
  84      /** @var object An ADODB database connector object */
  85      var $_db = '';
  86  
  87      /*
  88       * NOTE:     This cache must be manually cleaned each time ACL's are modified.
  89       *         Alternatively you could wait for the cache to expire.
  90       */
  91  
  92      /** @var boolean Caches queries if true */
  93      var $_caching = FALSE;
  94  
  95      /** @var boolean Force cache to expire */
  96      var $_force_cache_expire = TRUE;
  97  
  98      /** @var string The directory for cache file to eb written (ensure write permission are set) */
  99      var $_cache_dir = '/tmp/phpgacl_cache'; // NO trailing slash
 100  
 101      /** @var int The time for the cache to expire in seconds - 600 == Ten Minutes */
 102      var $_cache_expire_time=600;
 103  
 104      /** @var string A switch to put acl_check into '_group_' mode */
 105      var $_group_switch = '_group_';
 106  
 107      /**
 108       * Constructor
 109       * @param array An arry of options to oeverride the class defaults
 110       */
 111  	function gacl($options = NULL) {
 112  
 113          $available_options = array('db','debug','items_per_page','max_select_box_items','max_search_return_items','db_table_prefix','db_type','db_host','db_user','db_password','db_name','caching','force_cache_expire','cache_dir','cache_expire_time');
 114          if (is_array($options)) {
 115              foreach ($options as $key => $value) {
 116                  $this->debug_text("Option: $key");
 117  
 118                  if (in_array($key, $available_options) ) {
 119                      $this->debug_text("Valid Config options: $key");
 120                      $property = '_'.$key;
 121                      $this->$property = $value;
 122                  } else {
 123                      $this->debug_text("ERROR: Config option: $key is not a valid option");
 124                  }
 125              }
 126          }
 127  
 128          //Use NUM for slight performance/memory reasons.
 129          //Leave this in for backwards compatibility with older ADODB installations.
 130          //If your using ADODB v3.5+ feel free to comment out the following line if its giving you problems.
 131          //$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 132  
 133          if (is_object($this->_db)) {
 134              $this->db = &$this->_db;
 135          } else {
 136              require_once( ADODB_DIR .'/adodb.inc.php');
 137              require_once( ADODB_DIR .'/adodb-pager.inc.php');
 138  
 139              $this->db = ADONewConnection($this->_db_type);
 140              $this->db->SetFetchMode(ADODB_FETCH_NUM);
 141              $this->db->PConnect($this->_db_host, $this->_db_user, $this->_db_password, $this->_db_name);
 142          }
 143          $this->db->debug = $this->_debug;
 144  
 145          if ( $this->_caching == TRUE ) {
 146              if (!class_exists('Hashed_Cache_Lite')) {
 147                  require_once(dirname(__FILE__) .'/Cache_Lite/Hashed_Cache_Lite.php');
 148              }
 149  
 150              /*
 151               * Cache options. We default to the highest performance. If you run in to cache corruption problems,
 152               * Change all the 'false' to 'true', this will slow things down slightly however.
 153               */
 154  
 155              $cache_options = array(
 156                  'caching' => $this->_caching,
 157                  'cacheDir' => $this->_cache_dir.'/',
 158                  'lifeTime' => $this->_cache_expire_time,
 159                  'fileLocking' => TRUE,
 160                  'writeControl' => FALSE,
 161                  'readControl' => FALSE,
 162                  'memoryCaching' => TRUE,
 163                  'automaticSerialization' => FALSE
 164              );
 165              $this->Cache_Lite = new Hashed_Cache_Lite($cache_options);
 166          }
 167  
 168          return true;
 169      }
 170  
 171      /**
 172      * Prints debug text if debug is enabled.
 173      * @param string THe text to output
 174      * @return boolean Always returns true
 175      */
 176  	function debug_text($text) {
 177          if (!$this->_debugLog)
 178          {
 179              $this->_debugLog = array();
 180          }
 181  
 182          $this->_debugLog[] = $text;
 183          if ($this->_debug) {
 184              echo "$text<br>\n";
 185          }
 186  
 187          return true;
 188      }
 189  
 190      /**
 191      * Prints database debug text if debug is enabled.
 192      * @param string The name of the function calling this method
 193      * @return string Returns an error message
 194      */
 195  	function debug_db($function_name = '') {
 196          if ($function_name != '') {
 197              $function_name .= ' (): ';
 198          }
 199  
 200          return $this->debug_text ($function_name .'database error: '. $this->db->ErrorMsg() .' ('. $this->db->ErrorNo() .')');
 201      }
 202  
 203      /**
 204      * Wraps the actual acl_query() function.
 205      *
 206      * It is simply here to return TRUE/FALSE accordingly.
 207      * @param string The ACO section value
 208      * @param string The ACO value
 209      * @param string The ARO section value
 210      * @param string The ARO section
 211      * @param string The AXO section value (optional)
 212      * @param string The AXO section value (optional)
 213      * @param integer The group id of the ARO ??Mike?? (optional)
 214      * @param integer The group id of the AXO ??Mike?? (optional)
 215      * @return boolean TRUE if the check succeeds, false if not.
 216      */
 217  	function acl_check($aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL, $root_aro_group=NULL, $root_axo_group=NULL) {
 218          $acl_result = $this->acl_query($aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value, $axo_value, $root_aro_group, $root_axo_group);
 219  
 220          return $acl_result['allow'];
 221      }
 222  
 223      /**
 224      * Wraps the actual acl_query() function.
 225      *
 226      * Quick access to the return value of an ACL.
 227      * @param string The ACO section value
 228      * @param string The ACO value
 229      * @param string The ARO section value
 230      * @param string The ARO section
 231      * @param string The AXO section value (optional)
 232      * @param string The AXO section value (optional)
 233      * @param integer The group id of the ARO (optional)
 234      * @param integer The group id of the AXO (optional)
 235      * @return string The return value of the ACL
 236      */
 237  	function acl_return_value($aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL, $root_aro_group=NULL, $root_axo_group=NULL) {
 238          $acl_result = $this->acl_query($aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value, $axo_value, $root_aro_group, $root_axo_group);
 239  
 240          return $acl_result['return_value'];
 241      }
 242  
 243      /**
 244       * Handles ACL lookups over arrays of AROs
 245       * @param string The ACO section value
 246       * @param string The ACO value
 247      * @param array An named array of arrays, each element in the format aro_section_value=>array(aro_value1,aro_value1,...)
 248       * @return mixed The same data format as inputted.
 249       */
 250  	function acl_check_array($aco_section_value, $aco_value, $aro_array) {
 251          /*
 252              Input Array:
 253                  Section => array(Value, Value, Value),
 254                  Section => array(Value, Value, Value)
 255  
 256           */
 257  
 258          if (!is_array($aro_array)) {
 259              $this->debug_text("acl_query_array(): ARO Array must be passed");
 260              return false;
 261          }
 262  
 263          foreach($aro_array as $aro_section_value => $aro_value_array) {
 264              foreach ($aro_value_array as $aro_value) {
 265                  $this->debug_text("acl_query_array(): ARO Section Value: $aro_section_value ARO VALUE: $aro_value");
 266  
 267                  if( $this->acl_check($aco_section_value, $aco_value, $aro_section_value, $aro_value) ) {
 268                      $this->debug_text("acl_query_array(): ACL_CHECK True");
 269                      $retarr[$aro_section_value][] = $aro_value;
 270                  } else {
 271                      $this->debug_text("acl_query_array(): ACL_CHECK False");
 272                  }
 273              }
 274          }
 275  
 276          return $retarr;
 277  
 278      }
 279  
 280      /**
 281      * The Main function that does the actual ACL lookup.
 282      * @param string The ACO section value
 283      * @param string The ACO value
 284      * @param string The ARO section value
 285      * @param string The ARO section
 286      * @param string The AXO section value (optional)
 287      * @param string The AXO section value (optional)
 288      * @param string The value of the ARO group (optional)
 289      * @param string The value of the AXO group (optional)
 290      * @param boolean Debug the operation if true (optional)
 291      * @return array Returns as much information as possible about the ACL so other functions can trim it down and omit unwanted data.
 292      */
 293  	function acl_query($aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL, $root_aro_group=NULL, $root_axo_group=NULL, $debug=NULL) {
 294  
 295          $cache_id = 'acl_query_'.$aco_section_value.'-'.$aco_value.'-'.$aro_section_value.'-'.$aro_value.'-'.$axo_section_value.'-'.$axo_value.'-'.$root_aro_group.'-'.$root_axo_group.'-'.$debug;
 296  
 297          $retarr = $this->get_cache($cache_id);
 298  
 299          if (!$retarr) {
 300              /*
 301               * Grab all groups mapped to this ARO/AXO
 302               */
 303              $aro_group_ids = $this->acl_get_groups($aro_section_value, $aro_value, $root_aro_group, 'ARO');
 304  
 305              if (is_array($aro_group_ids) AND !empty($aro_group_ids)) {
 306                  $sql_aro_group_ids = implode(',', $aro_group_ids);
 307              }
 308  
 309              if ($axo_section_value !== '' AND $axo_value !== '') {
 310                  $axo_group_ids = $this->acl_get_groups($axo_section_value, $axo_value, $root_axo_group, 'AXO');
 311  
 312                  if (is_array($axo_group_ids) AND !empty($axo_group_ids)) {
 313                      $sql_axo_group_ids = implode(',', $axo_group_ids);
 314                  }
 315              }
 316  
 317              /*
 318               * This query is where all the magic happens.
 319               * The ordering is very important here, as well very tricky to get correct.
 320               * Currently there can be  duplicate ACLs, or ones that step on each other toes. In this case, the ACL that was last updated/created
 321               * is used.
 322               *
 323               * This is probably where the most optimizations can be made.
 324               */
 325  
 326              $order_by = array();
 327  
 328              $query = '
 329                      SELECT        a.id,a.allow,a.return_value
 330                      FROM        '. $this->_db_table_prefix .'acl a
 331                      LEFT JOIN     '. $this->_db_table_prefix .'aco_map ac ON ac.acl_id=a.id';
 332  
 333              if ($aro_section_value != $this->_group_switch) {
 334                  $query .= '
 335                      LEFT JOIN    '. $this->_db_table_prefix .'aro_map ar ON ar.acl_id=a.id';
 336              }
 337  
 338              if ($axo_section_value != $this->_group_switch) {
 339                  $query .= '
 340                      LEFT JOIN    '. $this->_db_table_prefix .'axo_map ax ON ax.acl_id=a.id';
 341              }
 342  
 343              /*
 344               * if there are no aro groups, don't bother doing the join.
 345               */
 346              if (isset($sql_aro_group_ids)) {
 347                  $query .= '
 348                      LEFT JOIN    '. $this->_db_table_prefix .'aro_groups_map arg ON arg.acl_id=a.id
 349                      LEFT JOIN    '. $this->_db_table_prefix .'aro_groups rg ON rg.id=arg.group_id';
 350              }
 351  
 352              // this join is necessary to weed out rules associated with axo groups
 353              $query .= '
 354                      LEFT JOIN    '. $this->_db_table_prefix .'axo_groups_map axg ON axg.acl_id=a.id';
 355  
 356              /*
 357               * if there are no axo groups, don't bother doing the join.
 358               * it is only used to rank by the level of the group.
 359               */
 360              if (isset($sql_axo_group_ids)) {
 361                  $query .= '
 362                      LEFT JOIN    '. $this->_db_table_prefix .'axo_groups xg ON xg.id=axg.group_id';
 363              }
 364  
 365              //Move the below line to the LEFT JOIN above for PostgreSQL's sake.
 366              //AND    ac.acl_id=a.id
 367              $query .= '
 368                      WHERE        a.enabled=1
 369                          AND        (ac.section_value='. $this->db->quote($aco_section_value) .' AND ac.value='. $this->db->quote($aco_value) .')';
 370  
 371              // if we are querying an aro group
 372              if ($aro_section_value == $this->_group_switch) {
 373                  // if acl_get_groups did not return an array
 374                  if ( !isset ($sql_aro_group_ids) ) {
 375                      $this->debug_text ('acl_query(): Invalid ARO Group: '. $aro_value);
 376                      return FALSE;
 377                  }
 378  
 379                  $query .= '
 380                          AND        rg.id IN ('. $sql_aro_group_ids .')';
 381  
 382                  $order_by[] = '(rg.rgt-rg.lft) ASC';
 383              } else {
 384                  $query .= '
 385                          AND        ((ar.section_value='. $this->db->quote($aro_section_value) .' AND ar.value='. $this->db->quote($aro_value) .')';
 386  
 387                  if ( isset ($sql_aro_group_ids) ) {
 388                      $query .= ' OR rg.id IN ('. $sql_aro_group_ids .')';
 389  
 390                      $order_by[] = '(CASE WHEN ar.value IS NULL THEN 0 ELSE 1 END) DESC';
 391                      $order_by[] = '(rg.rgt-rg.lft) ASC';
 392                  }
 393  
 394                  $query .= ')';
 395              }
 396  
 397  
 398              // if we are querying an axo group
 399              if ($axo_section_value == $this->_group_switch) {
 400                  // if acl_get_groups did not return an array
 401                  if ( !isset ($sql_axo_group_ids) ) {
 402                      $this->debug_text ('acl_query(): Invalid AXO Group: '. $axo_value);
 403                      return FALSE;
 404                  }
 405  
 406                  $query .= '
 407                          AND        xg.id IN ('. $sql_axo_group_ids .')';
 408  
 409                  $order_by[] = '(xg.rgt-xg.lft) ASC';
 410              } else {
 411                  $query .= '
 412                          AND        (';
 413  
 414                  if ($axo_section_value == '' AND $axo_value == '') {
 415                      $query .= '(ax.section_value IS NULL AND ax.value IS NULL)';
 416                  } else {
 417                      $query .= '(ax.section_value='. $this->db->quote($axo_section_value) .' AND ax.value='. $this->db->quote($axo_value) .')';
 418                  }
 419  
 420                  if (isset($sql_axo_group_ids)) {
 421                      $query .= ' OR xg.id IN ('. $sql_axo_group_ids .')';
 422  
 423                      $order_by[] = '(CASE WHEN ax.value IS NULL THEN 0 ELSE 1 END) DESC';
 424                      $order_by[] = '(xg.rgt-xg.lft) ASC';
 425                  } else {
 426                      $query .= ' AND axg.group_id IS NULL';
 427                  }
 428  
 429                  $query .= ')';
 430              }
 431  
 432              /*
 433               * The ordering is always very tricky and makes all the difference in the world.
 434               * Order (ar.value IS NOT NULL) DESC should put ACLs given to specific AROs
 435               * ahead of any ACLs given to groups. This works well for exceptions to groups.
 436               */
 437  
 438              $order_by[] = 'a.updated_date DESC';
 439  
 440              $query .= '
 441                      ORDER BY    '. implode (',', $order_by) . '
 442                      ';
 443  
 444              // we are only interested in the first row
 445              $rs = $this->db->SelectLimit($query, 1);
 446  
 447              if (!is_object($rs)) {
 448                  $this->debug_db('acl_query');
 449                  return FALSE;
 450              }
 451  
 452              $row =& $rs->FetchRow();
 453  
 454              /*
 455               * Return ACL ID. This is the key to "hooking" extras like pricing assigned to ACLs etc... Very useful.
 456               */
 457              if (is_array($row)) {
 458                  // Permission granted?
 459                  // This below oneliner is very confusing.
 460                  //$allow = (isset($row[1]) AND $row[1] == 1);
 461  
 462                  //Prefer this.
 463                  if ( isset($row[1]) AND $row[1] == 1 ) {
 464                      $allow = TRUE;
 465                  } else {
 466                      $allow = FALSE;
 467                  }
 468  
 469                  $retarr = array('acl_id' => &$row[0], 'return_value' => &$row[2], 'allow' => $allow);
 470              } else {
 471                  // Permission denied.
 472                  $retarr = array('acl_id' => NULL, 'return_value' => NULL, 'allow' => FALSE);
 473              }
 474  
 475              /*
 476               * Return the query that we ran if in debug mode.
 477               */
 478              if ($debug == TRUE) {
 479                  $retarr['query'] = &$query;
 480              }
 481  
 482              //Cache data.
 483              $this->put_cache($retarr, $cache_id);
 484          }
 485  
 486          $this->debug_text("<b>acl_query():</b> ACO Section: $aco_section_value ACO Value: $aco_value ARO Section: $aro_section_value ARO Value $aro_value ACL ID: ". $retarr['acl_id'] .' Result: '. $retarr['allow']);
 487          return $retarr;
 488      }
 489  
 490      /**
 491      * Grabs all groups mapped to an ARO. You can also specify a root_group for subtree'ing.
 492      * @param string The section value or the ARO or ACO
 493      * @param string The value of the ARO or ACO
 494      * @param integer The group id of the group to start at (optional)
 495      * @param string The type of group, either ARO or AXO (optional)
 496      */
 497  	function acl_get_groups($section_value, $value, $root_group=NULL, $group_type='ARO') {
 498  
 499          switch(strtolower($group_type)) {
 500              case 'axo':
 501                  $group_type = 'axo';
 502                  $object_table = $this->_db_table_prefix .'axo';
 503                  $group_table = $this->_db_table_prefix .'axo_groups';
 504                  $group_map_table = $this->_db_table_prefix .'groups_axo_map';
 505                  break;
 506              default:
 507                  $group_type = 'aro';
 508                  $object_table = $this->_db_table_prefix .'aro';
 509                  $group_table = $this->_db_table_prefix .'aro_groups';
 510                  $group_map_table = $this->_db_table_prefix .'groups_aro_map';
 511                  break;
 512          }
 513  
 514          //$profiler->startTimer( "acl_get_groups()");
 515  
 516          //Generate unique cache id.
 517          $cache_id = 'acl_get_groups_'.$section_value.'-'.$value.'-'.$root_group.'-'.$group_type;
 518  
 519          $retarr = $this->get_cache($cache_id);
 520  
 521          if (!$retarr) {
 522  
 523              // Make sure we get the groups
 524              $query = '
 525                      SELECT         DISTINCT g2.id';
 526  
 527              if ($section_value == $this->_group_switch) {
 528                  $query .= '
 529                      FROM        ' . $group_table . ' g1,' . $group_table . ' g2';
 530  
 531                  $where = '
 532                      WHERE        g1.value=' . $this->db->quote( $value );
 533              } else {
 534                  $query .= '
 535                      FROM        '. $object_table .' o,'. $group_map_table .' gm,'. $group_table .' g1,'. $group_table .' g2';
 536  
 537                  $where = '
 538                      WHERE        (o.section_value='. $this->db->quote($section_value) .' AND o.value='. $this->db->quote($value) .')
 539                          AND        gm.'. $group_type .'_id=o.id
 540                          AND        g1.id=gm.group_id';
 541              }
 542  
 543              /*
 544               * If root_group_id is specified, we have to narrow this query down
 545               * to just groups deeper in the tree then what is specified.
 546               * This essentially creates a virtual "subtree" and ignores all outside groups.
 547               * Useful for sites like sourceforge where you may seperate groups by "project".
 548               */
 549              if ( $root_group != '') {
 550                  //It is important to note the below line modifies the tables being selected.
 551                  //This is the reason for the WHERE variable.
 552                  $query .= ','. $group_table .' g3';
 553  
 554                  $where .= '
 555                          AND        g3.value='. $this->db->quote( $root_group ) .'
 556                          AND        ((g2.lft BETWEEN g3.lft AND g1.lft) AND (g2.rgt BETWEEN g1.rgt AND g3.rgt))';
 557              } else {
 558                  $where .= '
 559                          AND        (g2.lft <= g1.lft AND g2.rgt >= g1.rgt)';
 560              }
 561  
 562              $query .= $where;
 563  
 564              // $this->debug_text($query);
 565              $rs = $this->db->Execute($query);
 566  
 567              if (!is_object($rs)) {
 568                  $this->debug_db('acl_get_groups');
 569                  return FALSE;
 570              }
 571  
 572              $retarr = array();
 573  
 574              /*
 575               * Changed by: Louis Landry for Joomla ACL integration
 576               * 21-Jan-2006
 577               */
 578              for ($i = 0; $i < count($rs->data); $i++) {
 579                  //$retarr[] = $rs->data[$i]['id'];
 580                  $retarr[] = reset( $rs->data[$i] );
 581              }
 582  
 583              //Cache data.
 584              $this->put_cache($retarr, $cache_id);
 585          }
 586  
 587          return $retarr;
 588      }
 589  
 590      /**
 591      * Uses PEAR's Cache_Lite package to grab cached arrays, objects, variables etc...
 592      * using unserialize() so it can handle more then just text string.
 593      * @param string The id of the cached object
 594      * @return mixed The cached object, otherwise FALSE if the object identifier was not found
 595      */
 596  	function get_cache($cache_id) {
 597  
 598          if ( $this->_caching == TRUE ) {
 599              $this->debug_text("get_cache(): on ID: $cache_id");
 600  
 601              if ( is_string($this->Cache_Lite->get($cache_id) ) ) {
 602                  return unserialize($this->Cache_Lite->get($cache_id) );
 603              }
 604          }
 605  
 606          return false;
 607      }
 608  
 609      /**
 610      * Uses PEAR's Cache_Lite package to write cached arrays, objects, variables etc...
 611      * using serialize() so it can handle more then just text string.
 612      * @param mixed A variable to cache
 613      * @param string The id of the cached variable
 614      */
 615  	function put_cache($data, $cache_id) {
 616  
 617          if ( $this->_caching == TRUE ) {
 618              $this->debug_text("put_cache(): Cache MISS on ID: $cache_id");
 619  
 620              return $this->Cache_Lite->save(serialize($data), $cache_id);
 621          }
 622  
 623          return false;
 624      }
 625  }
 626  ?>


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1