<blockquote>
  <p>So, the Comet Chat is not able to read the userid, even if I made a Craft plugin who writes UserID in $_SESSION['userid'].</p>
</blockquote>

<p>To access Craft's session variables outside Craft, you need to pull the session ID from the <code>CraftSessionId</code> cookie, and then use that to revive the session:</p>

<pre><code>$sessId = $_COOKIE[ 'CraftSessionId' ] ?: false;

if ( $sessId ) {

    session_id( $sessId );
    session_start();

    var_dump( $_SESSION );

}
</code></pre>

<p>The current user ID and username session variables will be named <code>__id</code> and <code>__name</code> respectively, but they'll be prefixed with a hash which isn't easily reconstructable outside of Craft (see the Yii class <a href="https://github.com/pixelandtonic/Craft-Release/blob/3718e966808e5eb461b4ce42b17e24915af77aba/app/framework/web/auth/CWebUser.php" rel="nofollow">CWebUser</a>, line 547).</p>

<p>To pull the current user's ID from session, that means you could either</p>

<p>a) Write a Craft plugin, which sets your own session variable with the current user's ID:</p>

<pre><code>$currentUser = craft()-&gt;userSession-&gt;getUser();
$_SESSION[ 'craftUserId' ] = $currentUser ? $currentUser-&gt;id : null;
</code></pre>

<p>b) ...or loop through the session variables and look for a key ending in <code>__id</code>, with a valid integer value:</p>

<pre><code>$craftUserId = false;

foreach ( $_SESSION as $key =&gt; $value ) {

    if ( substr( $key, -4 ) === '__id' &amp;&amp; ! is_nan( intval( $value ) ) ) {
        $craftUserId = $value;
        break;
    }

}
</code></pre>

<p><em>Obviously, option a) is your safest bet, as you can never be 100% certain you won't have multiple keys ending in <code>__id</code>, so if you're able to write a plugin to set your own session variable, that would best.</em></p>

<p>For completions sake, here's what your CometChat <code>getUserId()</code> method could look like:</p>

<pre><code>function getUserID() {

    $userId = 0; // Return 0 if user is not logged in

    $sessId = $_COOKIE[ 'CraftSessionId' ] ?: false;

    if ( $sessId ) {

        session_id( $sessId );
        session_start();

        $userId = $_SESSION[ 'craftUserId' ] ?: 0;

    }

    return intval( $userId );

}
</code></pre>

CC BY-SA 3.0
2015-04-05T20:59:02.890Z
Almost there! The problem now is the getUserID function in Comet chat already started the session so I get this:

Notice: A session had already been started - ignoring session_start() in /XXXXXX/public_html/cometchat/integration.php on line 46

Notice: Undefined index: craftUserId in /XXXXXX/public_html/cometchat/integration.php on line 48
r-ninja
CC BY-SA 3.0
2015-04-05T21:06:08.333Z
Difficult to advice as CometChat's source code isn't available without purchase, but is it possible to hunt down CometChat's ```session_start``` call and put ```session_name( 'CraftSessionId' )``` before it? Either that, or use a wrapper where you start the session yourself before including the CometChat app, I'd wager the latter will probably check for an existing session before attempting to start a new one?
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T21:08:48.340Z
Found it. Change in cometchat_init.php is required. I add it to the answer for the benefit of others. Thanks!
r-ninja
CC BY-SA 3.0
2015-04-05T21:10:16.157Z
Aces. No problem!
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T20:43:57.073Z
2015-04-05T20:49:03.640Z
2015-04-05T20:49:03.640Z
Mats Mikkel Rummelhoff
<p>The Matt's answer was pretty complete and worked almost, but for the benefit of others, there is the changes required files to make it works:</p>

<p>in integration.php</p>

<p>find</p>

<pre><code>define('SET_SESSION_NAME','');
</code></pre>

<p>change for</p>

<pre><code>define('SET_SESSION_NAME','CraftSessionId');
</code></pre>

<p>and make your getUserID functions look like</p>

<pre><code>function getUserID() {
            $userId = 0; // Return 0 if user is not logged in

            if ( $_SESSION[ 'craftUserId' ] ) 
            {
                $userId = $_SESSION[ 'craftUserId' ]; // Set this session variable in a Craft plugin
            }

            return intval( $userId );
    }
</code></pre>

<p>and in a Craft plugin, add this to a init() function</p>

<pre><code>public function init()
    {            
        craft()-&gt;on('userSession.onLogin', function(Event $event) {
            $currentUser = craft()-&gt;userSession-&gt;getUser();
            craft()-&gt;httpSession-&gt;add( 'craftUserId', $currentUser ? $currentUser-&gt;id : null );            
        });
   }
</code></pre>

<p>If you want to be full-padded, you can also add something to unset your CraftUserId variable onLogout event, but I don't think it's needed.</p>

<p>Thanks a lot to Matt and Brad who helped me out on Easter day!</p>

CC BY-SA 3.0
2015-04-05T21:17:27.757Z
2015-04-05T21:48:12.117Z
2015-04-05T21:48:12.117Z
r-ninja
<p>You can write a simple Craft plugin that listens for the <a href="http://buildwithcraft.com/docs/plugins/events-reference#userSession-onLogin" rel="nofollow">onLogin</a> event, like so:</p>

<pre><code>public function init()
{
    craft()-&gt;on('userSession.onLogin', function(Event $event)
    {
        $username=$event-&gt;params['username'];
        $user = craft()-&gt;users-&gt;getUserByUsernameOrEmail($username);
        $_SESSION['userid'] = $user-&gt;id;
    });
}
</code></pre>

<p>Note that you'll want to write to and read from <code>$_SESSION</code> directly here instead of going through <code>craft()-&gt;session-&gt;add()</code> because that will have to additional data hashing that your integration script would need to be aware of.</p>

<p>Craft automatically renames what the PHP session cookie is called from the default <code>PHPSESSID</code> to <code>CraftSessionId</code>.</p>

<p>So your Comet Chat integration script would have to use that same name before it calls <code>session_start()</code>, otherwise it's going to create a new session cookie with the name <code>PHPSESSID</code> that won't have your information in it.</p>

<p>Something like this from your integration script should do it:</p>

<pre><code>if (!isset($_SESSION))
{
    session_name('CraftSessionId');
    session_start();
}

if (isset($_SESSION['userId]))
{
    $userId = $_SESSION['userId'];
}
</code></pre>

CC BY-SA 3.0
2015-04-05T21:14:53.990Z
Didn't know about ```session_name()```. Very clean stuff!
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T21:33:07.457Z
I suppose this whole scenario makes a valid use case for us making the PHP session cookie name configurable...
Brad Bell
CC BY-SA 3.0
2015-04-05T21:33:10.813Z
Not sure about the difference between session_name and session_id. In this case, both works I guess...
r-ninja
CC BY-SA 3.0
2015-04-05T21:35:34.230Z
@mkweb Both works, but if you use ```session_name( 'CraftSessionId' );``` you don't have to check for and pull the session ID from the cookie. Less code, that's all :)
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T21:36:29.367Z
@BradBell Couldn't hurt :)
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T21:45:54.900Z
Ok, then I found a very simple way to fix my problem without changing the comet chat core files... Seems they planned this kind or problem by having a global: define('SET_SESSION_NAME',''); I changed for define('SET_SESSION_NAME','CraftSessionId'); and of course, it does the trick! Thanks again!
r-ninja
CC BY-SA 3.0
2015-04-05T21:53:16.707Z
@BradBell Quick question; is ```craft()->session``` an alias for ```craft()->httpSession``` (HttpSessionService), or a different service? Adding session variables through ```craft()->httpSession->add()``` doesn't hash the data in any way, far as I can tell.
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-05T22:02:29.927Z
@MatsMikkelRummelhoff `craft()->session` is an alias for `UserSessionService`. `craft()->httpSession` maps to `HttpSessionService`
Brad Bell
CC BY-SA 3.0
2015-04-05T20:43:24.180Z
2015-04-05T21:04:13.963Z
2015-04-05T21:04:13.963Z
Brad Bell
<p>I need to implement Comet Chat, a facebook-chat-like third-party script, into my Craft project. </p>

<p>Comet Chat can connect to most CMS and PHP framework but there is no Craft integration yet, so I tried to use the "custom coded site" procedure.</p>

<p><a href="http://www.cometchat.com/documentation/installing-cometchat/custom-coded-site/php-site/" rel="nofollow">http://www.cometchat.com/documentation/installing-cometchat/custom-coded-site/php-site/</a></p>

<p>Comet Chat need to access a session variable to authenticate user. Ex: $_SESSION['userid'].</p>

<p>The problem: Craft write its session variables with some nice sorcelery that makes outside script unable to read it.</p>

<p>So, the Comet Chat is not able to read the userid, even if I made a Craft plugin who writes UserID in $_SESSION['userid'].</p>

<p>I also tried, by the Craft cookie ($_COOKIE values are bidirectionally accessible unlike $_SESSION values, of course) to find some relation or mechanism to tells Comet Chat who's the current user in Craft, unsuccessfuly.</p>

<p>Perhaps some other PHP scripts or cases may need to read the Craft session, so I'm pretty sure this question can be relevant for more than Comet Chat integration.</p>

<p>Any ideas?</p>

<p>Thanks in advance!</p>

<users><session><usermodel><current-user>
CometChat integration
# CometChat integration

(Asked by: username_0 on 2015-04-05)

I need to implement Comet Chat, a facebook-chat-like third-party script, into my Craft project.

Comet Chat can connect to most CMS and PHP framework but there is no Craft integration yet, so I tried to use the "custom coded site" procedure.

<http://www.cometchat.com/documentation/installing-cometchat/custom-coded-site/php-site/>

Comet Chat need to access a session variable to authenticate user. Ex: $\_SESSION['userid'].

The problem: Craft write its session variables with some nice sorcelery that makes outside script unable to read it.

So, the Comet Chat is not able to read the userid, even if I made a Craft plugin who writes UserID in $\_SESSION['userid'].

I also tried, by the Craft cookie ($\_COOKIE values are bidirectionally accessible unlike $\_SESSION values, of course) to find some relation or mechanism to tells Comet Chat who's the current user in Craft, unsuccessfuly.

Perhaps some other PHP scripts or cases may need to read the Craft session, so I'm pretty sure this question can be relevant for more than Comet Chat integration.

Any ideas?

Thanks in advance!

**Tags:** users, session, usermodel, current-user

---

## 3 answers

### Answer by username_1 on 2015-04-05. Score: 2 | Accepted answer

So, the Comet Chat is not able to read the userid, even if I made a Craft plugin who writes UserID in $_SESSION['userid'].

To access Craft's session variables outside Craft, you need to pull the session ID from the CraftSessionId cookie, and then use that to revive the session:
$sessId = $_COOKIE[ 'CraftSessionId' ] ?: false;

if ( $sessId ) {

    session_id( $sessId );
    session_start();

    var_dump( $_SESSION );

}

The current user ID and username session variables will be named __id and __name respectively, but they'll be prefixed with a hash which isn't easily reconstructable outside of Craft (see the Yii class CWebUser, line 547).
To pull the current user's ID from session, that means you could either
a) Write a Craft plugin, which sets your own session variable with the current user's ID:
$currentUser = craft()->userSession->getUser();
$_SESSION[ 'craftUserId' ] = $currentUser ? $currentUser->id : null;

b) ...or loop through the session variables and look for a key ending in __id, with a valid integer value:
$craftUserId = false;

foreach ( $_SESSION as $key => $value ) {

    if ( substr( $key, -4 ) === '__id' && ! is_nan( intval( $value ) ) ) {
        $craftUserId = $value;
        break;
    }

}

Obviously, option a) is your safest bet, as you can never be 100% certain you won't have multiple keys ending in __id, so if you're able to write a plugin to set your own session variable, that would best.
For completions sake, here's what your CometChat getUserId() method could look like:
function getUserID() {

    $userId = 0; // Return 0 if user is not logged in

    $sessId = $_COOKIE[ 'CraftSessionId' ] ?: false;

    if ( $sessId ) {

        session_id( $sessId );
        session_start();

        $userId = $_SESSION[ 'craftUserId' ] ?: 0;

    }

    return intval( $userId );

}

> **Comments:**
> **username_0**: Almost there! The problem now is the getUserID function in Comet chat already started the session so I get this:  Notice: A session had already been started - ignoring session_start() in /XXXXXX/public_html/cometchat/integration.php on line 46  Notice: Undefined index: craftUserId in /XXXXXX/public_html/cometchat/integration.php on line 48  
> **username_1**: Difficult to advice as CometChat's source code isn't available without purchase, but is it possible to hunt down CometChat's ```session_start``` call and put ```session_name( 'CraftSessionId' )``` before it? Either that, or use a wrapper where you start the session yourself before including the CometChat app, I'd wager the latter will probably check for an existing session before attempting to start a new one?  
> **username_0**: Found it. Change in cometchat_init.php is required. I add it to the answer for the benefit of others. Thanks!  
> **username_1**: Aces. No problem!  

---

### Answer by username_0 on 2015-04-05. Score: 3

The Matt's answer was pretty complete and worked almost, but for the benefit of others, there is the changes required files to make it works:
in integration.php
find
define('SET_SESSION_NAME','');

change for
define('SET_SESSION_NAME','CraftSessionId');

and make your getUserID functions look like
function getUserID() {
            $userId = 0; // Return 0 if user is not logged in

            if ( $_SESSION[ 'craftUserId' ] ) 
            {
                $userId = $_SESSION[ 'craftUserId' ]; // Set this session variable in a Craft plugin
            }

            return intval( $userId );
    }

and in a Craft plugin, add this to a init() function
public function init()
    {            
        craft()->on('userSession.onLogin', function(Event $event) {
            $currentUser = craft()->userSession->getUser();
            craft()->httpSession->add( 'craftUserId', $currentUser ? $currentUser->id : null );            
        });
   }

If you want to be full-padded, you can also add something to unset your CraftUserId variable onLogout event, but I don't think it's needed.
Thanks a lot to Matt and Brad who helped me out on Easter day!


---

### Answer by username_2 on 2015-04-05. Score: 1

You can write a simple Craft plugin that listens for the onLogin event, like so:
public function init()
{
    craft()->on('userSession.onLogin', function(Event $event)
    {
        $username=$event->params['username'];
        $user = craft()->users->getUserByUsernameOrEmail($username);
        $_SESSION['userid'] = $user->id;
    });
}

Note that you'll want to write to and read from $_SESSION directly here instead of going through craft()->session->add() because that will have to additional data hashing that your integration script would need to be aware of.
Craft automatically renames what the PHP session cookie is called from the default PHPSESSID to CraftSessionId.
So your Comet Chat integration script would have to use that same name before it calls session_start(), otherwise it's going to create a new session cookie with the name PHPSESSID that won't have your information in it.
Something like this from your integration script should do it:
if (!isset($_SESSION))
{
    session_name('CraftSessionId');
    session_start();
}

if (isset($_SESSION['userId]))
{
    $userId = $_SESSION['userId'];
}

> **Comments:**
> **username_1**: Didn't know about ```session_name()```. Very clean stuff!  
> **username_2**: I suppose this whole scenario makes a valid use case for us making the PHP session cookie name configurable...  
> **username_0**: Not sure about the difference between session_name and session_id. In this case, both works I guess...  
> **username_1**: @mkweb Both works, but if you use ```session_name( 'CraftSessionId' );``` you don't have to check for and pull the session ID from the cookie. Less code, that's all :)  
> **username_1**: @BradBell Couldn't hurt :)  
> **username_0**: Ok, then I found a very simple way to fix my problem without changing the comet chat core files... Seems they planned this kind or problem by having a global: define('SET_SESSION_NAME',''); I changed for define('SET_SESSION_NAME','CraftSessionId'); and of course, it does the trick! Thanks again!  
> **username_1**: @BradBell Quick question; is ```craft()->session``` an alias for ```craft()->httpSession``` (HttpSessionService), or a different service? Adding session variables through ```craft()->httpSession->add()``` doesn't hash the data in any way, far as I can tell.  
> **username_2**: @MatsMikkelRummelhoff `craft()->session` is an alias for `UserSessionService`. `craft()->httpSession` maps to `HttpSessionService`  

---

