<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package fusionLib
 * @copyright Copyright (c) 2008 - 2017 fusionLib. All rights reserved.
 * @link http://fusionlib.com
 */

/**
 * flSessionMemcached Class
 *
 * Class to implement memcached based sessions.
 *
 * @package fusionLib
 */
class flSessionMemcached extends flSessionDb {

	/**
	 * The Memcached interface object.
	 *
	 * @var Memcached
	 */
	private $cache = null;

	/**
	 * Construct and initialize the memcached session object.
	 *
	 * @param flResponse $response The response object to use.
	 * @param array|Memached $servers Array of host + port pairs e.g. localhost,11211 or Memcached object to use.
	 * @param flDb $db The database object.
	 * @param int $life The time in seconds a session should live for, must be greater than 0 or null to use the value of session.gc_maxlifetime.
	 * @param bool $expireCookieOnExit true to expire cookie at the end of the session or false to keep the cookie for the lifetime of the session data.
	 * @param string $cookieName The name of the cookie holding session data.
	 * @param string $cookieDomain The optional domain the cookie is available on, e.g. for all subdomains '.example.com'
	 * @param string $cookiePath The options path the cookie is valid on
	 * @param bool $cookieSecure true to use secure session cookies; else false.
	 * @throws flSessionException
	 */
	function __construct($response, $servers, $db, $life = null, $expireCookieOnExit = true, $cookieName = '__sessionid', $cookieDomain = '', $cookiePath = '/', $cookieSecure = false) {
		if($servers instanceof Memcached)
			$this->cache = $servers;
		else {
			// Test if memcached drivers present
			if(extension_loaded('memcached'))
				$this->cache = new Memcached();
			else
				throw new flSessionException('The memcached extension required by flSessionMemcached is not available.');

			// Connect to servers
			foreach($servers as $server) {
				$d = explode(',', $server);
				if(!isset($d[1])) $d[1] = 11211;
				$this->cache->addServer($d[0], $d[1]);
			}
		}

		parent::__construct($response, $db, $life, $expireCookieOnExit, $cookieName, $cookieDomain, $cookiePath, $cookieSecure);
	}

	/**
	 * Get the inner interface object.
	 *
	 * @return Memcached The inner interface object.
	 */
	function _getInnerObject() {
		return $this->cache;
	}

	/**
	 * @inheritdoc
	 */
	public function read($session_id) {
		if(($d = $this->cache->get($session_id)) === false)
			return parent::read($session_id);
		else
			return $d;
	}

	/**
	 * @inheritdoc
	 */
	public function write($session_id, $session_data) {
		$this->cache->set($session_id, $session_data, $this->expireat);
		parent::write($session_id, $session_data);
		return true;
	}

	/**
	 * @inheritdoc
	 */
	public function destroy($session_id) {
		$this->cache->delete($session_id);
		parent::destroy($session_id);
		return true;
	}
}
