Yii 1.1: Syncing sessions between Yii and KCFinder

6 followers

Info: As KCFinder's documentation mentions, if your application (Yii in our case) session handling is using the PHP environment configuration - meaning no change in session handling at all, then no change is needed also on KCFinder side to be able to use this session and thus have this simple interface between your Yii webapp and KCFinder. If that's your case then you probably need not read the rest of this article but rather just make sure that before a user attempts to upload or browse your server a session variable is already set for him (or her) with his specific configuration already waiting for KCFinder there. What can this session interface be useful for? For example, for having per-user upload directory. You could have uploadURL variable established in the session variable to contain the user's id. When an upload or browse use case will occur, the client side will trigger the KCFinder completely decoupled from the Yii application. Yet, since you've already synced your user-specific-configuration with KCFinder via the session, KCFinder will pick it up and use it.

I have been trying to find information on how to sync the sessions between Yii and KCFinder so that the two applications can "communicate" with each other. I managed to find some bits and pieces on the correct approach to use, but not a definite guide or concrete code.

So... if you are using Yii with CDbHttpSession and also want KCFinder to share the same session as Yii, you must create your own SESSION SAVE HANDLER as described here.

This handler must be placed inside file core/autoload.php of KCFinder.

class SessionSaveHandler 
{
    protected $savePath;
    protected $sessionName;
 
    public $db;
    public $sessionTableName;
 
    public function __construct() 
    {
        $this->loadConfig();
 
        session_name($this->sessionName);
 
        session_set_save_handler(
            array($this, "open"),
            array($this, "close"),
            array($this, "read"),
            array($this, "write"),
            array($this, "destroy"),
            array($this, "gc")
        );
    }
 
    public function loadConfig()
    {   
        // application configuration file
        $config_file = dirname(__FILE__) . '/../../../protected/config/main.php';
        $find = array('<?php', '?>');
        $replace = array('', '');
        $configuration = eval(str_replace($find, $replace, file_get_contents($config_file)));
 
        $this->sessionName = $configuration['components']['session']['sessionName'];
 
        $this->db = $configuration['components']['db'];
        $this->sessionTableName = $configuration['components']['session']['sessionTableName'];
    }
 
    public function open($savePath, $sessionName) {
        return true;
    }
 
    public function close() {
        return true;
    }
 
    public function read($id) {
        try {
            $dbh = new PDO($this->db['connectionString'], $this->db['username'], $this->db['password']);
            $statement = $dbh->prepare("SELECT data FROM $this->sessionTableName WHERE id = :id AND expire > :expire");
            $statement->bindParam(':id', $id, PDO::PARAM_STR);
            $statement->bindParam(':expire', time(), PDO::PARAM_INT);
            $statement->setFetchMode(PDO::FETCH_ASSOC);
            $result = $statement->execute();
            if ($result) {
                $row = $statement->fetch();
                return $row['data'];
            }
        } catch (PDOException $e) {
            //
        }
 
        return '';
    }
 
    public function write($id, $data) {
        return true;
    }
 
    public function destroy($id) {
        return true;
    }
 
    public function gc($maxlifetime) {
        return true;
    }
}
 
new SessionSaveHandler();

That's It!

Feel free to comment on the approach used and suggest any other tips.

Total 8 comments

#19588 report it
Nabi at 2015/09/19 02:17am
using yii session handler

I thinks @Maciej Liżewski's solution in #10743 comment, was perfect and very simple, this is works for each third-party software component just with include some lines code.

But that code have an little bug. that's use open() method for session, It means correct code is here:

//create app instance, same way as in index.php
$yii = 'yii/framework/yii.php';
$config = dirname( __FILE__ ) . '/protected/config/main.php';
require_once( $yii );
Yii::createWebApplication( $config );
//initialize session
Yii::app()->session->open();
#16640 report it
Thanasis Fotis at 2014/03/14 03:47am
re: Possibly no change at all is needed

@Boaz, i haven't tried syncing my app with CKFinder using the default session settings. I guess that if you intend to use sessions, you probably aren't going to keep the default settings anyway :)

but if you tried it and it works, then by all means, edit the post and add this information freely.

#16631 report it
Boaz at 2014/03/13 04:52am
Possibly no change at all is needed

As KCFinder's documentation mentions, if your application (Yii in our case) session handling is as configured for the entire PHP environment - meaning no change in session handling at all, then no change is needed at all. Just make sure that before a user attempts to upload or browse your server a session variable is already set for it with this user's specific upload dir (if you need it) and any other custom configuration you'd like him to have, and you're set to go. When an upload or browse use case will occur, the client side will trigger the KCFinder regardless of the Yii application. Yet, Since you've already synced your user-specific-configuration with KCFinder via the session, KCFinder will pick it up and use it. I believe this needs to be edited in the article above. Let me know if you want me to edit it there.

#10774 report it
Thanasis Fotis at 2012/11/22 03:05pm
re: Hi, Have you try it with suhosin enabled?

@Dayak Ngoding I came upon your approach while i was searching for this topic, and i did give it a try. But unfortunately it didn't work for my installation and also i wanted a solution that i could configure the session parameters by using a yii extension. ezzeelfinder looks nice, i didn't know about it.

#10765 report it
Dayak Ngoding at 2012/11/22 05:32am
Hi, Have you try it with suhosin enabled?

I used my own approach like what I've write in this link:

http://www.yiiframework.com/forum/index.php/topic/28561-integrating-yii-ckeditor-and-kcfinder/

Unfortunately kcfinder needs safe mode ON and it usually doesn't implemented by Web Hosting Provider, beside Suhosin enabled issue. So I give up and currently use ezzeelfinder ...

#10748 report it
Maciej Liżewski at 2012/11/21 03:47am
reply: reply: using yii session handler

ok. I haven't tried this approach by myself but it seemed correct.

#10747 report it
Thanasis Fotis at 2012/11/21 02:37am
reply: using yii session handler

@redguy i tried this approach at first, but i couldn't get it to work. at first i tried creating a Yii app using my main configuration but it was giving many errors regarding paths. i then tried a stripped down version of the configuration file with only the bare minimum, but it gave errors also, later in the process. so, i gave up this approach and tried the one that is described here. Maybe i will give it another go when i find some time. If anyone else succeeds in creating a Yii app inside kcfinder/core/autoload.php, please share it.

#10743 report it
Maciej Liżewski at 2012/11/20 05:11pm
using yii session handler

why can't you just use session handler provided with Yii? you could create Yii application without calling 'run()', then fetch 'session' component which should initialise session handling in Yii way:

//create app instance, same way as in index.php
$yii = 'yii/framework/yii.php';
$config = dirname( __FILE__ ) . '/protected/config/main.php';
require_once( $yii );
Yii::createWebApplication( $config );
//initialize session
Yii::app()->session;

just put it in same place where you put your custom handler... it will give you some overhead initialising whole application but you will have exactly same session handling as in main application.

Leave a comment

Please to leave your comment.

Write new article
  • Written by: Thanasis Fotis
  • Updated by: Boaz
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +2
  • Viewed: 8,005 times
  • Created on: Nov 20, 2012
  • Last updated: Mar 14, 2014
  • Tags: File upload