<?php
namespace JExtstore\Component\JRealtimeAnalytics\Administrator\Table;
/**
 *
 * @package JREALTIMEANALYTICS::EVENTSTATS::administrator::components::com_jrealtimeanalytics
 * @subpackage tables
 * @author Joomla! Extensions Store
 * @copyright (C) 2014 - Joomla! Extensions Store
 * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html
 */
// no direct access
defined ( '_JEXEC' ) or die ( 'Restricted access' );
use Joomla\Database\DatabaseInterface;
use Joomla\Database\DatabaseDriver;
use Joomla\Event\DispatcherInterface;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Table\Table;
use JExtstore\Component\JRealtimeAnalytics\Administrator\Framework\Exception\Exceptions;

/**
 * ORM Table for sessions
 *
 * @package JREALTIMEANALYTICS::EVENTSTATS::administrator::components::com_jrealtimeanalytics
 * @subpackage tables
 * @since 1.0
 */
class SessionTable extends Table {
	use Exceptions;
	
	/**
	 * DatabaseInterface object.
	 * @protected DatabaseInterface Object
	 */
	protected $dbo;
	
	/**
	 * Insert a session
	 *
	 * @param string $sessionId
	 *        	The session id
	 * @param integer $clientId
	 *        	The id of the client application
	 *        	
	 * @return boolean True on success
	 */
	public function insert($sessionId, $clientId) {
		$this->session_id = $sessionId;
		$this->client_id = $clientId;
		
		$this->time = time ();
		$ret = $this->dbo->insertObject ( $this->_tbl, $this, 'session_id' );
		
		if (! $ret) {
			$this->setException ( Text::sprintf ( 'JLIB_DATABASE_ERROR_STORE_FAILED', strtolower ( get_class ( $this ) ), $this->dbo->stderr () ) );
			
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * Updates the session
	 *
	 * @param boolean $updateNulls
	 *        	True to update fields even if they are null.
	 *        	
	 * @return boolean True on success.
	 */
	public function update($updateNulls = false) {
		$this->time = time ();
		$ret = $this->dbo->updateObject ( $this->_tbl, $this, 'session_id', $updateNulls );
		
		if (! $ret) {
			$this->setException ( Text::sprintf ( 'JLIB_DATABASE_ERROR_STORE_FAILED', strtolower ( get_class ( $this ) ), $this->dbo->stderr () ) );
			
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * Destroys the pre-existing session
	 *
	 * @param integer $userId
	 *        	Identifier of the user for this session.
	 * @param array $clientIds
	 *        	Array of client ids for which session(s) will be destroyed
	 *        	
	 * @return boolean True on success.
	 */
	public function destroy($userId, $clientIds = array()) {
		$clientIds = implode ( ',', $clientIds );
		
		$query = method_exists ( $this->dbo, 'createQuery' ) ? $this->dbo->createQuery () : $this->dbo->getQuery ( true );
		$query->delete ( $this->dbo->quoteName ( $this->_tbl ) )
			  ->where ( $this->dbo->quoteName ( 'userid' ) . ' = ' . $this->dbo->quote ( $userId ) )
			  ->where ( $this->dbo->quoteName ( 'client_id' ) . ' IN (' . $clientIds . ')' );
		$this->dbo->setQuery ( $query );
		
		if (! $this->dbo->execute ()) {
			$this->setException ( $this->dbo->stderr () );
			
			return false;
		}
		
		return true;
	}
	
	/**
	 * Purge old sessions
	 *
	 * @param integer $maxLifetime
	 *        	Session age in seconds
	 *        	
	 * @return mixed Resource on success, null on fail
	 */
	public function purge($maxLifetime = 1440) {
		$past = time () - $maxLifetime;
		$query = method_exists ( $this->dbo, 'createQuery' ) ? $this->dbo->createQuery () : $this->dbo->getQuery ( true );
		$query->delete ( $this->dbo->quoteName ( $this->_tbl ) )
			  ->where ( $this->dbo->quoteName ( 'time' ) . ' < ' . ( int ) $past );
		$this->dbo->setQuery ( $query );
		
		return $this->dbo->execute ();
	}
	
	/**
	 * Find out if a user has a one or more active sessions
	 *
	 * @param integer $userid
	 *        	The identifier of the user
	 *        	
	 * @return boolean True if a session for this user exists
	 */
	public function exists($userid) {
		$query = method_exists ( $this->dbo, 'createQuery' ) ? $this->dbo->createQuery () : $this->dbo->getQuery ( true );
		$query->select ( 'COUNT(userid)' )
			  ->from ( $this->dbo->quoteName ( $this->_tbl ) )
			  ->where ( $this->dbo->quoteName ( 'userid' ) . ' = ' . $this->dbo->quote ( $userid ) );
		$this->dbo->setQuery ( $query );
		
		if (! $result = $this->dbo->loadResult ()) {
			$this->setException ( $this->dbo->stderr () );
			
			return false;
		}
		
		return ( boolean ) $result;
	}
	
	/**
	 * Overloaded delete method
	 *
	 * We must override it because of the non-integer primary key
	 *
	 * @param integer $oid
	 *        	The object id (optional).
	 *        	
	 * @return mixed True if successful otherwise an error message
	 */
	public function delete($oid = null) {
		$k = $this->_tbl_key;
		
		if ($oid) {
			$this->$k = $oid;
		}
		
		$query = method_exists ( $this->dbo, 'createQuery' ) ? $this->dbo->createQuery () : $this->dbo->getQuery ( true );
		$query->delete ( $this->dbo->quoteName ( $this->_tbl ) )
			  ->where ( $this->dbo->quoteName ( $this->_tbl_key ) . ' = ' . $this->dbo->quote ( $this->$k ) );
		$this->dbo->setQuery ( $query );
		
		$this->dbo->execute ();
		
		return true;
	}
	
	/**
	 * Class constructor
	 * @param DatabaseDriver $db DatabaseDriver object.
	 * @param DispatcherInterface  $dispatcher  Event dispatcher for this table
	 *
	 * return Object&
	 */
	public function __construct(DatabaseInterface $db, ?DispatcherInterface $dispatcher = null) {
		parent::__construct ( '#__session', 'session_id', $db, $dispatcher );
		
		$this->dbo = $db;
		
		$this->guest = 1;
		$this->username = '';
		$this->session_id = '';
		$this->userid = 0;
	}
}