Skip to content

Commit

Permalink
Added EMongoSession
Browse files Browse the repository at this point in the history
  • Loading branch information
Sammaye committed Nov 1, 2013
1 parent 208c6d9 commit eb0a85f
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 2 deletions.
14 changes: 12 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,6 @@ So I expect all modifications to certain parts of MongoYii to be compatible with
The `util` folder contains general awesome extensions to MongoYii that people may find useful. The sort of things that count as part of this folder are replacements for internal pieces
of Yii that might seem outside of the scope of the root of this repository.

THESE ARE NOT MADE BY THE AUTHOR OF MONGOYII. That being said I will attempt to maintain them.

## EMongoCache

This is a MongoYii implementation of `CCache` by [Rajcsányi Zoltán](http://ezmegaz.hu/).
Expand Down Expand Up @@ -995,6 +993,18 @@ And then add some messages to the translation table:
And then simply get that message:

<?=Yii::t('users', 'Freund'); ?>

## EMongoSession

This is a MongoYii `CHttpSession` implementation by yours truly.

To use it simply include it in your configuration:

'session' => array(
'class' => 'application.extensions.MongoYii.util.EMongoSession',
)

And use it as you would Yiis own normal session.

## Upgrade Notes

Expand Down
183 changes: 183 additions & 0 deletions util/EMongoSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
<?php
/**
* EMongoSession extends {@link CHttpSession} by using database as session data storage.
*
* EMongoSession stores session data in a DB collection named 'YiiSession'. The collection name
* can be changed by setting {@link sessionTableName}.
*
* @property boolean $useCustomStorage Whether to use custom storage.
*/
class EMongoSession extends CHttpSession
{
/**
* @var string the ID of a {@link CDbConnection} application component.
*/
public $connectionID;
/**
* @var string the name of the DB table to store session content.
*/
public $sessionTableName='YiiSession';
/**
* @var EMongoClient the DB connection instance
*/
private $_db;

/**
* Returns a value indicating whether to use custom session storage.
* This method overrides the parent implementation and always returns true.
* @return boolean whether to use custom storage.
*/
public function getUseCustomStorage()
{
return true;
}

/**
* Updates the current session id with a newly generated one.
* Please refer to {@link http://php.net/session_regenerate_id} for more details.
* @param boolean $deleteOldSession Whether to delete the old associated session file or not.
* @since 1.1.8
*/
public function regenerateID($deleteOldSession=false)
{
$oldID=session_id();

// if no session is started, there is nothing to regenerate
if(empty($oldID))
return;

parent::regenerateID(false);
$newID=session_id();
$db=$this->getDbConnection();

$row = $db->{$this->sessionTableName}->findOne(array('id'=>$oldID));
if($row!==false)
{
if($deleteOldSession)
$db->{$this->sessionTableName}->update(array('id'=>$oldID),array('$set'=>array('id'=>$newID)));
else
{
$row['id']=$newID;
$db->{$this->sessionTableName}->insert($row);
}
}
else
{
// shouldn't reach here normally
$db->{$this->sessionTableName}->insert(array(
'id'=>$newID,
'expire'=>time()+$this->getTimeout()
));
}
}

/**
* @return EMongoClient the DB connection instance
* @throws CException if {@link connectionID} does not point to a valid application component.
*/
protected function getDbConnection()
{
if($this->_db!==null)
return $this->_db;
elseif(($id=$this->connectionID)!==null)
{
if(($this->_db=Yii::app()->getComponent($id)) instanceof CDbConnection)
return $this->_db;
else
throw new CException(Yii::t('yii','EMongoSession.connectionID "{id}" is invalid. Please make sure it refers to the ID of a EMongoClient application component.',
array('{id}'=>$id)));
}
else
{
return $this->_db=Yii::app()->getComponent('mongodb');
}
}

/**
* Session open handler.
* Do not call this method directly.
* @param string $savePath session save path
* @param string $sessionName session name
* @return boolean whether session is opened successfully
*/
public function openSession($savePath,$sessionName)
{
return true; // Do not need to explicitly create tables in MongoDB
}

/**
* Session read handler.
* Do not call this method directly.
* @param string $id session ID
* @return string the session data
*/
public function readSession($id)
{
$data=$this->getDbConnection()->{$this->sessionTableName}->findOne(array(
'expire' => array('$gt' => time()),
'id' => $id
));
return $data===null?'':$data['data'];
}

/**
* Session write handler.
* Do not call this method directly.
* @param string $id session ID
* @param string $data session data
* @return boolean whether session write is successful
*/
public function writeSession($id,$data)
{
// exception must be caught in session write handler
// http://us.php.net/manual/en/function.session-set-save-handler.php
try
{
$expire=time()+$this->getTimeout();
$db=$this->getDbConnection();
if($db->{$this->sessionTableName}->findOne(array('id'=>$id))===null)
$db->{$this->sessionTableName}->insert(array(
'id'=>$id,
'data'=>$data,
'expire'=>$expire,
));
else
$db->{$this->sessionTableName}->update(array('id'=>$id), array('$set' => array(
'data'=>$data,
'expire'=>$expire
)));
}
catch(Exception $e)
{
if(YII_DEBUG)
echo $e->getMessage();
// it is too late to log an error message here
return false;
}
return true;
}

/**
* Session destroy handler.
* Do not call this method directly.
* @param string $id session ID
* @return boolean whether session is destroyed successfully
*/
public function destroySession($id)
{
$this->getDbConnection()->{$this->sessionTableName}->remove(array('id'=>$id));
return true;
}

/**
* Session GC (garbage collection) handler.
* Do not call this method directly.
* @param integer $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
* @return boolean whether session is GCed successfully
*/
public function gcSession($maxLifetime)
{
$this->getDbConnection()->{$this->sessionTableName}->remove(array('expire'=>array('$lt'=>time())));
return true;
}
}

0 comments on commit eb0a85f

Please sign in to comment.