Add analytics
[bus.git] / busui / owa / modules / base / classes / state.php
blob:a/busui/owa/modules/base/classes/state.php -> blob:b/busui/owa/modules/base/classes/state.php
  <?php
   
  //
  // Open Web Analytics - An Open Source Web Analytics Framework
  //
  // Copyright 2008 Peter Adams. All rights reserved.
  //
  // Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  //
  // $Id$
  //
   
  /**
  * Service User Class
  *
  * @author Peter Adams <peter@openwebanalytics.com>
  * @copyright Copyright &copy; 2008 Peter Adams <peter@openwebanalytics.com>
  * @license http://www.gnu.org/copyleft/gpl.html GPL v2.0
  * @category owa
  * @package owa
  * @version $Revision$
  * @since owa 1.0.0
  */
   
   
  class owa_state {
   
  var $stores = array();
  var $stores_meta = array();
  var $is_dirty;
  var $dirty_stores;
  var $default_store_type = 'cookie';
  var $stores_with_cdh = array('c','v','s');
  var $store_formats = array ('v' => 'assoc', 's' => 'assoc');
  var $initial_state = array();
   
  function __construct() {
   
  }
   
  function __destruct() {
   
  $this->persistState();
  }
   
  function persistState() {
   
  return false;
   
  }
   
  function get($store, $name = '') {
  owa_coreAPI::debug("Getting state - store: ".$store.' key: '.$name);
   
  if ( ! isset($this->stores[$store] ) ) {
  $this->loadState($store);
  }
   
  if (array_key_exists($store, $this->stores)) {
   
  if (!empty($name)) {
  // check to ensure this is an array, could be a string.
  if (is_array($this->stores[$store]) && array_key_exists($name, $this->stores[$store])) {
   
  return $this->stores[$store][$name];
  } else {
  return false;
  }
  } else {
   
  return $this->stores[$store];
  }
  } else {
   
  return false;
  }
  }
   
  function setState($store, $name = '', $value, $store_type = '', $is_perminent = false) {
   
  owa_coreAPI::debug(sprintf('populating state for store: %s, name: %s, value: %s, store type: %s, is_perm: %s', $store, $name, print_r($value, true), $store_type, $is_perminent));
   
  // first call to set for a store sets the meta
  if (!array_key_exists($store, $this->stores)) {
   
  if (empty($store_type)) {
  $store_type = $this->default_store_type;
  }
   
  $this->stores_meta[$store]['type'] = $store_type;
   
  if ($is_perminent === true) {
  $this->stores_meta[$store]['is_perminent'] = true;
  }
   
  }
   
  // set values
  if (empty($name)) {
  $this->stores[$store] = $value;
  //owa_coreAPI::debug(print_r($this->stores, true));
  } else {
  //just in case the store was set first as a string instead of as an array.
  if ( array_key_exists($store, $this->stores)) {
   
  if ( ! is_array( $this->stores[$store] ) ) {
  $new_store = array();
  // check to see if we need ot ad a cdh
  if ( $this->isCdhRequired($store) ) {
  $new_store['cdh'] = $this->getCookieDomainHash();
  }
   
  $new_store[$name] = $value;
  $this->stores[$store] = $new_store;
   
  } else {
  $this->stores[$store][$name] = $value;
  }
  // if the store does not exist then maybe add a cdh and the value
  } else {
   
  if ( $this->isCdhRequired($store) ) {
  $this->stores[$store]['cdh'] = $this->getCookieDomainHash();
  }
   
  $this->stores[$store][$name] = $value;
  }
   
  }
   
  $this->dirty_stores[] = $store;
  //owa_coreAPI::debug(print_r($this->stores, true));
  }
   
  function isCdhRequired($store_name) {
   
  return in_array( $store_name, $this->stores_with_cdh );
  }
   
  function set($store, $name = '', $value, $store_type = '', $is_perminent = false) {
   
  if ( ! isset($this->stores[$store] ) ) {
  $this->loadState($store);
  }
   
  $this->setState($store, $name, $value, $store_type, $is_perminent);
   
  // persist immeadiately if the store type is cookie
  if ($this->stores_meta[$store]['type'] === 'cookie') {
   
  $time = 0;
   
  // needed? i dont think so.
  if (isset($this->stores_meta[$store]['is_perminent']) && $this->stores_meta[$store]['is_perminent'] === true) {
  $time = $this->getPermExpiration();
  } elseif (isset($this->stores_meta[$store]['is_perminent']) && $this->stores_meta[$store]['is_perminent'] > 0) {
  $time = $this->stores_meta[$store]['is_perminent'] * 3600 * 24;
  }
   
  if ($is_perminent === true) {
  $time = $this->getPermExpiration();
  }
   
  // transform state array into a string using proper format
  if ( is_array( $this->stores[$store] ) ) {
   
  // check for old style assoc format
  if (isset($this->store_formats[$store]) && $this->store_formats[$store] === 'assoc') {
  $cookie_value = owa_lib::implode_assoc('=>', '|||', $this->stores[$store] );
  } else {
  $cookie_value = json_encode( $this->stores[$store] );
  }
  }
   
   
  owa_coreAPI::createCookie($store, $this->stores[$store], $time, "/", owa_coreAPI::getSetting('base', 'cookie_domain'));
  }
  }
   
  function setInitialState($store, $value, $store_type) {
   
  if ($value) {
  $this->initial_state[$store] = $value;
  }
  }
   
  function loadState($store, $name = '', $value = '', $store_type = 'cookie') {
   
  if ( ! $value && isset( $this->initial_state[$store] ) ) {
  $value = $this->initial_state[$store];
  } else {
  return;
  }
   
  // check format of value
  if (strpos($value, "|||")) {
  $value = owa_lib::assocFromString($value);
  } else if (strpos($value, '{')) {
  $value = json_decode($value);
  } else {
  $value = $value;
  }
   
  if ( in_array( $store, $this->stores_with_cdh ) ) {
   
  if ( is_array( $value ) && isset( $value['cdh'] ) ) {
   
  $runtime_cdh = $this->getCookieDomainHash();
  $cdh_from_state = $value['cdh'];
   
  // return as the cdh's do not match
  if ( $cdh_from_state != $runtime_cdh ) {
  // cookie domains do not match so we need to delete the cookie in the offending domain
  // which is always likely to be a sub.domain.com and thus HTTP_HOST.
  // if ccokie is not deleted then new cookies set on .domain.com will never be seen by PHP
  // as only the sub domain cookies are available.
  owa_coreAPI::debug("Not loading state store: $store. Domain hashes do not match - runtime: $runtime_cdh, cookie: $cdh_from_state");
  owa_coreAPI::debug("deleting cookie: owa_$store");
  owa_coreAPI::deleteCookie($store,'/', $_SERVER['HTTP_HOST']);
  unset($this->initial_state[$store]);
  return;
  }
  } else {
   
  owa_coreAPI::debug("Not loading state store: $store. No domain hash found.");
  return;
   
  }
  }
   
  return $this->setState($store, $name, $value, $store_type);
   
  }
   
  function clear($store) {
   
  if ( ! isset($this->stores[$store] ) ) {
  $this->loadState($store);
  }
   
  if (array_key_exists($store, $this->stores)) {
   
  unset($this->stores[$store]);
   
  if ($this->stores_meta[$store]['type'] === 'cookie') {
   
  return owa_coreAPI::deleteCookie($store);
  }
  }
  }
   
  function getPermExpiration() {
   
  $time = time()+3600*24*365*15;
  return $time;
  }
   
  function addStores($array) {
   
  $this->stores = array_merge($this->stores, $array);
  return;
  }
   
  function getCookieDomainHash($domain = '') {
   
  if ( ! $domain ) {
  $domain = owa_coreAPI::getSetting( 'base', 'cookie_domain' );
  }
   
  return owa_lib::crc32AsHex($domain);
  }
  }
   
   
  ?>