Show:

File: platform/plugins/Users/classes/Users/Session.php

<?php
/**
 * @module Users
 */
/**
 * Class representing 'Session' rows in the 'Users' database
 * You can create an object of this class either to
 * access its non-static methods, or to actually
 * represent a session row in the Users database.
 *
 * @class Users_Session
 * @extends Base_Users_Session
 */
class Users_Session extends Base_Users_Session
{
	/**
	 * The setUp() method is called the first time
	 * an object of this class is constructed.
	 * @method setUp
	 */
	function setUp()
	{
		parent::setUp();
	}
	
	/**
	 * Saves a new Users_Session row with a copy of all the content from the current session.
	 * Does not change the current session id.
	 * @method copyToNewSesion
	 * @static
	 * @param {array} $sessionFields Pass an array with keys such as
	 *   "platform", "appId", "version", "deviceId", "formFactor"
	 * @param {string|integer} [$duration='year'] The key in the Q/session/durations config field
	 *   or number of seconds. Pass 0 to expire at the end of browser session.
	 * @return {string} the id of the newly saved Users_Session row
	 */
	static function copyToNewSession($sessionFields, $duration = 'year')
	{
		$id = Q_Session::id();
		if (!$id) {
			return null;
		}
		$seconds = is_string($duration)
			? Q_Config::expect('Q', 'session', 'durations', $duration)
			: $duration;

		$arr = isset($_SESSION['Q']) ? $_SESSION['Q'] : null;
		if (isset($arr)) {
			$fields = Q_Config::get('Q', 'session', 'userAgentInfo', array());
			$_SESSION['Q'] = Q::take($sessionFields, $fields, $arr);
			$_SESSION['Q']['nonce'] = sha1(mt_rand().microtime());
		}

		$us = new Users_Session();
		$us->id = $id;
		$us->retrieve(null, null, array('lock' => 'FOR UPDATE'));
		$us2 = new Users_Session();
		if ($us->wasRetrieved()) {
			$us2->copyFromRow($us, null, false, true);
			$us2->wasRetrieved(false);
			$us2->insertedTime = new Db_Expression('CURRENT_TIMESTAMP');
		} else {
			$us2->timeout = 0;
		}
		$us2->content = Q::json_encode($_SESSION, JSON_FORCE_OBJECT);
		$us2->php = session_encode();
		$us2->id = Q_Session::generateId();
		$us2->duration = $seconds;
		$us2->timeout = 0;
		foreach ($sessionFields as $k => $v) {
			$us2->$k = $v;
		}
		$us2->save(false, true);

		if (isset($arr)) {
			$_SESSION['Q'] = $arr;
		}
		/**
		 * This is a hook for after the session has been copied to a new session.
		 * You may want to do extra security checks here.
		 * You may also want to notify the user that there has been a new session
		 * started from a new platform + appId.
		 * @event Users/Session/copyToNewSession {after}
		 * @param {Users_Session} $from The session that was copied from
		 * @param {Users_Session} $to The session that was copied to
		 */
		Q::event("Users/Session/copyToNewSession", array(
			'from' => $us,
			'to' => $us2
		), 'after');
		return $us2->id;
	}

	/**
	 * Implements the __set_state method, so it can work with
	 * with var_export and be re-imported successfully.
	 * @method __set_state
	 * @param {array} $array
	 * @return {Users_Session} Class instance
	 */
	static function __set_state(array $array) {
		$result = new Users_Session();
		foreach($array as $k => $v)
			$result->$k = $v;
		return $result;
	}
};