I am trying to change the default session time out value. In my controller i have done this:
public function beforeAction($action) {
$session = new CHttpSession;
$timeout = $session->getTimeout();
if ($timeout != 10) {
$session->setTimeout(10);
}
return true;
}
But my session never gets timed out an i can access the page even after being inactive for 10 sec.
I also tried to do it through config by session component like this:
'session' => array(
'sessionName' => SITE_SESSION_COOKIE_NAME,
'class' => 'CHttpSession',
'timeout' => 10
),
but same result. Session dosent time out! Am I missing out on something?
Try to turn off autostart session in configs:
'session' => array(
'sessionName' => SITE_SESSION_COOKIE_NAME,
'class' => 'CHttpSession',
'autoStart' => false
),
In this case you need manually starting session: Yii::app()->session->open(), but BEFORE IT for changing life time try do:
Yii::app()->session->open($session_lifetime);
$cook_p = Yii::app()->session->getCookieParams();
$cook_p['lifetime'] = $session_lifetime;
Yii::app()->session->setCookieParams($cook_p);
OR you may inherit CHttpSession with new parameter lifetime and do it in method init():
class MyHttpSession extends CHttpSession{
public $lifetime = false;
public function init()
{
if($this->lifetime !== false){
$cook_p = $this->getCookieParams();
$cook_p['lifetime'] = $this->lifetime;
$this->setCookieParams($cook_p);
$this->setTimeout($this->lifetime);
}
parent::init();
}
}
and in configs:
'session' => array(
'sessionName' => SITE_SESSION_COOKIE_NAME,
'class' => 'MyHttpSession',
'lifetime' => 60 // 1 minute
),
The class in the session array should apparently be CDbHttpSession for this to work.
See here for a similar issue..
for session timeout based on user being in-active for 30 minutes, in configs:
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=> true,
'autoRenewCookie'=> true,
'authTimeout' => 1800
),
'session' => array(
'class' => 'FrontCHttpSession',
'savePath' => dirname(__FILE__),
'cookieMode' => 'allow',
'cookieParams' => array(
'path' => '/',
'domain' => 'mydomain.com',
'httpOnly' => true,
'lifetime' => 1800
),
'timeout' => 1800
),
Extended session class, similar idea can be used for CDbHttpSession
<?php
class FrontCHttpSession extends CHttpSession
{
/*default is 0 which means the cookie lifetime will last as long as the browser is open*/
private $_clientLifetime;
/*time in seconds how long the session should remain open after user in-activity*/
private $_sessionTimeout;
/*cookie params defined in config*/
private $_cookieParams;
/**
* Starts the session if it has not started yet.
*/
public function open()
{
$this->_cookieParams = $this->getCookieParams();
$this->_clientLifetime = $this->_cookieParams['lifetime'];
$this->_sessionTimeout = $this->timeout;
if($this->getUseCustomStorage())
#session_set_save_handler(array($this,'openSession'),
array($this,'closeSession'),
array($this,'readSession'),
array($this,'writeSession'),
array($this,'destroySession'),
array($this,'gcSession'));
//session is already started, check if session has been not been active longer than timeout
if (session_id() != '')
{
if ($this->get('last_active') < time() - $this->_sessionTimeout)
{
$this->destroy();
}
else if ($this->_clientLifetime > 0)
{
$this->updateSessionCookieExpire();
}
}
#session_set_cookie_params($this->_clientLifetime, array($this->_cookieParams['path'],
$this->_cookieParams['domain'], $this->_cookieParams['secure'], $this->_cookieParams['httpOnly']));
#session_start();
$this->add('last_active', time());
if(YII_DEBUG && session_id()=='')
{
$message=Yii::t('yii','Failed to start session.');
if(function_exists('error_get_last'))
{
$error=error_get_last();
if(isset($error['message']))
$message=$error['message'];
}
Yii::log($message, CLogger::LEVEL_WARNING, 'system.web.CHttpSession');
}
}
public function updateSessionCookieExpire()
{
if (isset(Yii::app()->request->cookies[$this->getSessionName()]))
{
$c = Yii::app()->request->cookies[$this->getSessionName()];
$c->expire = time() + $this->_clientLifetime;
$c->path = $this->_cookieParams['path'];
$c->domain = $this->_cookieParams['domain'];
$c->httpOnly = $this->_cookieParams['httponly'];
$c->secure = $this->_cookieParams['secure'];
Yii::app()->request->cookies[$this->getSessionName()] = $c;
}
}
}
Related
I've got the file 'init.php'. This one is being used to start the session, set some settings and that sort of stuff. I call to this file using this line:
require_once 'core/init.php';
This works perfectly in my opinion. Now, I've written the following script so that it becomes very easy to call a setting in the init.php file.
class Config {
public static function get($path = null) {
if ($path){
$config = $GLOBALS['config'];
$path = explode('/', $path);
foreach($path as $bit) {
if(isset($config[$bit])) {
$config = $config[$bit];
}
}
return $config;
}
return false;
}
}
So now I can use this line of code in my other pages to use the setting:
Config::get('settings/main_color')
This is very easy of course. But now I'd like to edit a setting without having to change the file myself. It should all be done by scripts in the browser. The rest of my init.php settings global looks like this:
$GLOBALS['config'] = array(
'mysql' => array(
'host' => 'localhost:3307',
'username' => 'root',
'password' => 'usbw',
'db' => 'webshop'
),
'remember' => array(
'cookie_name' => 'hash',
'cookie_expiry' => 604800
),
'sessions' => array(
'session_name' => 'user',
'token_name' => 'token'
),
'settings' => array(
'main_color' => '#069CDE',
'front_page_cat' => 'Best Verkocht,Populaire Producten',
'title_block_first' => 'GRATIS verzending van €50,-',
'title_block_second' => 'Vandaag besteld morgen in huis!',
),
'statics' => array(
'header' => 'enabled',
'title_block' => 'enabled',
'menu' => 'enabled',
'slideshow' => 'enabled',
'left_box' => 'enabled',
'email_block' => 'enabled',
'footer' => 'enabled',
'keurmerken' => 'enabled',
'copyright' => 'enabled'
)
);
What I hope for is a solution like this:
Config::update('settings/main_color','blue')
What is the best way to achieve this? Use str_replace and replace the word in the file? I hope there's a better way of doing this, and I'd be very pleased if you could help me out.
EDIT: (my complete init.php file)
<?php
session_start();
define('DS',DIRECTORY_SEPARATOR);
$GLOBALS['config'] = json_decode(__DIR__.DS.'prefs.json', true);
spl_autoload_register(function($class) {
require_once 'classes/' . $class . '.php';
});
require_once 'functions/sanitize.php';
require_once 'functions/statics.php';
require_once 'functions/pagination.php';
if(Cookie::exists(Config::get('remember/cookie_name')) && !Session::exists(Config::get('sessions/session_name'))) {
$hash = Cookie::get(Config::get('remember/cookie_name'));
$hashCheck = DB::getInstance()->get('users_session', array('hash', '=', $hash));
if($hashCheck->count()) {
$user = new User($hashCheck->first()->user_id);
$user->login();
}
}
$_link = DB::getConnected();
$url_parts = explode('/',$_SERVER['REQUEST_URI']);
$current = $url_parts[count($url_parts)-2];
if($current == 'page'){
$_SESSION['location'] = 1;
}
else{
$_SESSION['location'] = 0;
}
This is somewhat opinion-based, but I use a json or xml file that the config file parses. The update would call the file, parse it then resave it.
/core/init.php
$GLOBALS['config'] = json_decode(__DIR__.DS.'prefs.json', true);
/core/prefs.json
{"mysql":{"host":"localhost:3307","username":"root","password":"usbw","db":"webshop"},"remember":{"cookie_name":"hash","cookie_expiry":604800},"sessions":{"session_name":"user","token_name":"token"},"settings":{"main_color":"#069CDE","front_page_cat":"Best Verkocht,Populaire Producten","title_block_first":"GRATIS verzending van €50,-","title_block_second":"Vandaag besteld morgen in huis!"},"statics":{"header":"enabled","title_block":"enabled","menu":"enabled","slideshow":"enabled","left_box":"enabled","email_block":"enabled","footer":"enabled","keurmerken":"enabled","copyright":"enabled"}}
Pseudo-code for your update:
class Config
{
public static function update($path,$value)
{
# Fetch the file and convert it to json
$file = json_decode(file_get_contents(CONFIG_PATH),true);
# Do some code that will update the value....
# Save file back
file_put_contents(CONFIG_PATH,json_encode($data));
# Call your prefs to GLOBALS function here so the settings
# are updated in your global array
}
}
I have two controllers. One of them is called OAMLController and the other is called LoginController. I would like to set HTTP Cookies in OAMLController and then make a call to LoginController and read it in this controller.
I know how to do this in PHP, but I don't know how to do this in Zend Framework 2.
PHP (OAML.php):
setcookie("_ga", "GA1.2.1622977711.1433494392", 0, "/", "http://gnsys.local");
setcookie("_gat", "1", 0, "/", "http://gnsys.local");
header("Location: http://gnsys.local/publico/login.php");
PHP (login.php):
$cookie = "";
foreach (getallheaders() as $name => $value) {
echo "$name: $value</br>";
if ($name == "Cookie")
$cookie = $value;
}
I have tried to follow the ZF2 tutorial but is so confusing.
More questions:
I have redirect to the other controller using $this->redirect()->toUrl($url).
$cookie = new \Zend\Http\Header\SetCookie("param1", "Hola", null, null, "http://gnsys.local", null, null, null, null);
$this->getResponse()->getHeaders()->addHeader($cookie);
return $this->redirect()->toUrl("http://gnsys.local/publico/login");
Because if I redirect with:
$controllerName = "LoginController";
$actionName = "index";
return $this->redirect()->toRoute(
"publico",
array(
"controller" => $controllerName,
"action" => $actionName
));
I always access to http://gnsys.local/publico and not to where I want http://gnsys.local/publico/login.
Another question, in LoginController I can't read the cookie. If I check the cookies via Firebug I can see that I have created the cookie in ".gnsys.local" domain and not in "gnsys.local" domain.
Why has that happened? If I make the redirect using toRoute or toUrl I create the cookie on the same domain ".gnsys.local" and not in "gnsys.local".
module.config:
'router' => array(
'routes' => array(
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /application/:controller/:action
'publico' => array(
'type' => 'Literal',
'options' => array(
'route' => '/publico',
'defaults' => array(
'__NAMESPACE__' => 'Publico\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
Updated 2:
Finally, the redirection works fine with the solution from Jangya Satapathy. But I have a new problem and this is that I can't read the cookie because the domain is not correct. With these code I create a cookie with domain ".gnsys.local" and not with the domain "gnsys.local"
$cookie = new \Zend\Http\Header\SetCookie("param1", "Hola", null, null, "http://gnsys.local", null, null, null, null);
$this->getResponse()->getHeaders()->addHeader($cookie);
$controllerName = "login";
$actionName = "index";
return $this->redirect()->toRoute(
"publico/default",
array(
"controller" => $controllerName,
"action" => $actionName
));
So, when I try to write the value of cookie "param1", I've got the next error:
Notice: Undefined index: param1 in /var/www/html/gnsys/module/Publico/src/Publico/Controller/LoginController.php
If we check the value of the cookies with firebug, we've got the next screen capture:
What am I doing wrong?
Updated 3:
I don't understand what happened but getCookie is null.
getcookie IS NULL
And print_r($this->getRequest()->getCookie()); doesn't write anything.
$getcookie = $this->getRequest()->getCookie(); // returns object of Zend\Http\Header\Cookie
if ($getcookie != null)
echo "getcookie is NOT NULL";
else
echo "getcookie IS NULL";
print_r($this->getRequest()->getCookie());
return new ViewModel();
Updated 4:
I have found the cookie, but I cannot retrieve its value. To find the cookie, I have to indicate the path where I'm going to read it then.
$cookie = new \Zend\Http\Header\SetCookie("param1", "Hola", 0, "/publico/login/index", "gnsys.local");
$this->getResponse()->getHeaders()->addHeader($cookie);
$controllerName = "login";
$actionName = "index";
return $this->redirect()->toRoute(
"publico/default",
array(
"controller" => $controllerName,
"action" => $actionName
));
And, now I have this exit ...
getcookie is NOT NULL
Zend\Http\Header\Cookie Object ( [encodeValue:protected] => 1 [storage:ArrayObject:private] => Array ( [zdt-hidden] => 0 ) )
If I try to retrieve the value of the cookie through
$cookie = $getcookie->param1;
I've got the next error ...
Notice: Undefined index: param1 in /var/www/html/gnsys/module/Publico/src/Publico/Controller/LoginController.php on line 84
If I try to get all the values from $getcookie
foreach ($getcookie as $key => $value){
echo "Key: " . $key . " Value: " . $value . "<br />";
}
And I've got ...
Key: zdt-hidden Value: 0
Update 5:
I don't understand anything here. I'm not creating the cookie with these code!
$cookie = new \Zend\Http\Header\SetCookie("param1", "Hola", 0, "/", "http://gnsys.local");
$this->getResponse()->getHeaders()->addHeader($cookie);
$controllerName = "login";
$actionName = "index";
return $this->redirect()->toRoute(
"publico/default",
array(
"controller" => $controllerName,
"action" => $actionName
));
Checking the cookies using firebug we can't see the cookie.
In your cookie set action:
Public function cookiesetAction(){
$cookie = new \Zend\Http\Header\SetCookie($name, $value, $expires, $path, $domain, $secure, $httponly, $maxAge, $version);
$this->getResponse()->getHeaders()->addHeader($cookie);
return $this->redirect()->toRoute('cookieget'); //to your login controller
}
In your cookie get action:
public function cookiegetAction(){
$getcookie = $this->getRequest()->getCookie(); // returns object of Zend\Http\Header\Cookie
$getcookie->name1; // value1
$getcookie->name2; // value2
return new ViewModel();
}
Question about cookies in ZF2.
Answer Update
Add child route followed by the main route.
return $this->redirect()->toRoute('publicio/default',array(
'controller'=>$controllername,
'action'=>$actioname
));
Working with the Yii framework in the config-file session storaged is handled as follows:
'session' => array(
//'sessionName' => 'SomeSession',
'class' => 'CDbHttpSession',
'connectionID' => 'SomeConnection',
'autoCreateSessionTable' => false,
'sessionTableName' => 'SomeTable',
'autoStart' => 'false',
'cookieMode' => 'only',
'useTransparentSessionID' => false,
'timeout' => CSESSIONTIMEOUT,
'cookieParams' => array(
'path' => '/',
'domain' => '.somedomain.extension',
'expire' => time()+5256000,
'lifetime' => time()+5256000,
//'httpOnly' => true,
),
),
So as you see sessions are stored in a table in a database with a given lifetime. But if I check the stored sessions in the database they are not stored with the given lifetime they are stored with a lifetime of a year.
The only thing I can find in our application that has a lifetime of a year are the cookies. For example like this:
setcookie("cookie_name", $someValue, time()+31536000, "/", "somedomain");
What is confusing for me are the cookies in our application. Could it be possible that this overrides the Yii session storage config?
UPDATE
I also came across this line of code
$_SESSION['POLL_'.$idPoll.'somekey'] = strtotime("now");
And that line of code inserted a session record in the database. But that record also has an lifetime of a year. How is this possible?
You need to add timeout param to config like this:
'session' => array(
'class' => 'CDbHttpSession',
'timeout' => 5256000,
// ...
Try Cookies Like this : -
if (isset($_POST['remember'])) {
$cookieUsername = new CHttpCookie('phoenix_admin_username', $_POST['LoginForm']['username']);
$cookiePassword = new CHttpCookie('phoenix_admin_password', base64_encode($_POST['LoginForm']['password']));
$cookieUsername->expire = time() + 604800;
$cookiePassword->expire = time() + 604800;
Yii::app()->request->cookies['phoenix_admin_username'] = $cookieUsername;
Yii::app()->request->cookies['phoenix_admin_password'] = $cookiePassword;
}
////////////Check like this//////////////
if(isset(Yii::app()->request->cookies['phoenix_admin_username'])){
$model->username = Yii::app()->request->cookies['phoenix_admin_username']->value;
$model->password = base64_decode(Yii::app()->request->cookies['phoenix_admin_password']->value);
}else{
$model->username = "";
$model->password = "";
}
I am working on optimizing Zend Framework Application with Doctrine ORM. I can't figure it out what particular code would I use in my controller to get this caching. Whenever I pass again the same url it should use the cache code instead of processing that logic again.
My Bootstrap file for cache looks like this:-
protected function _initCache() {
$frontendOptions = array(
'lifetime' => 7200, 'content_type_memorization' => true,
'default_options' => array(
'cache' => true,
'cache_with_get_variables' => true,
'cache_with_post_variables' => true,
'cache_with_session_variables' => true,
'cache_with_cookie_variables' => true, ),
'regexps' => array(
// cache the whole IndexController
'^/.*' => array('cache' => true),
'^/index/' => array('cache' => true),
// place more controller links here to cache them
)
);
$backendOptions = array(
'cache_dir' => APPLICATION_PATH ."/../cache" // Directory where to put the cache files
);
$cache = Zend_Cache::factory('Page', 'File', $frontendOptions, $backendOptions);
$cache->start();
Zend_Registry::set("cache", $cache);
}
Any help would be appreciated.
Check this below code to set cache if not exist or get cache if exists.
$result =””;
$cache = Zend_Registry::get('cache');
if(!$result = $cache->load('mydata')) {
echo 'caching the data…..';
$data=array(1,2,3); // demo data which you want to store in cache
$cache->save($data, 'mydata');
} else {
echo 'retrieving cache data…….';
Zend_Debug::dump($result);
}
I'm saving my session data on my database(mongodb), the customer asked that he want the system to be idle for 2 hours(he has videos on the site which may take 2 hours to finish, so he asked to set session timeout value as 2 hour). I did it as Zend Framework suggested. see my config.php below
return array(
'env2_session' => array(
'config' => array(
'class' => 'Zend\Session\Config\SessionConfig',
'options' => array(
'name' => 'test',
'remember_me_seconds' => 7200,
'gc_maxlifetime' => 7200,
),
),
'mongo_handler' => array(
'options' => array(
'class' => 'Zend\Session\SaveHandler\MongoDBOptions',
'collection' => 'sessions',
),
),
'save_handler' => 'Env2Session/Mongo/Handler',
'validators' => array(
array(
'Zend\Session\Validator\RemoteAddr',
'Zend\Session\Validator\HttpUserAgent',
),
),
),
);
But this is not the correct code as I couldn't see the session extended. it still get timed out after 24 minutes.
It will work if I add 'cookie_lifetime' => 7200 after 'gc_maxlifetime' => 7200 But this get timedout even if I'm using the site.
I want the timeout only when the system is idle. Please get me some thing on this.
Here is the save handler code which I written in Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'Env2Session/Mongo/Handler' => function ($sm) {
$config = $sm->get('config');
$session = $config['env2_session'];
$mongo = $sm->get('Env2\Mongo');
$class = isset($session['mongo_handler']['options']['class']) ? $session['mongo_handler']['options']['class'] : 'Zend\Session\SaveHandler\MongoDBOptions';
$options = array();
$options['collection'] = $session['mongo_handler']['options']['collection'];
$options['database'] = $config['db']['mongo']['db_name'];
$mongoOption = new $class($options);
$sessionSaveHandler = new MongoDB($mongo, $mongoOption);
return $sessionSaveHandler;
},
'Env2Session' => function ($sm) {
$config = $sm->get('config');
if (isset($config['env2_session'])) {
$session = $config['env2_session'];
$sessionConfig = null;
if (isset($session['config'])) {
$class = isset($session['config']['class']) ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
$options = isset($session['config']['options']) ? $session['config']['options'] : array();
$sessionConfig = new $class();
$sessionConfig->setOptions($options);
}
$sessionStorage = null;
if (isset($session['storage'])) {
$class = $session['storage'];
$sessionStorage = new $class();
}
$sessionSaveHandler = null;
if (isset($session['save_handler'])) {
$sessionSaveHandler = $sm->get($session['save_handler']);
}
$sessionManager = new SessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);
if (isset($session['validator'])) {
$chain = $sessionManager->getValidatorChain();
foreach ($session['validator'] as $validator) {
$validator = new $validator();
$chain->attach('session.validate', array($validator, 'isValid'));
}
}
} else {
$sessionManager = new SessionManager();
}
Container::setDefaultManager($sessionManager);
return $sessionManager;
}
),
);
}
I was struggling with the same issue for zend session timeouts. Finally I implemented own solution for this case. I set up the expiration time which is refreshed during each request. But if user is not active, the time will expire and session will be destroyed.
I put all tutorial how to do it here: http://blog.tulikowski.com/zend-framework-2-implementation-of-session-authentication-timeouts/
Go to your autoload/global.php and either create or edit this key:
'session_config' => array
(
'cache_expire' => 60*60*2,
'name' => 'sessionName',
'cookie_lifetime' => 60*60*2,
'gc_maxlifetime' => 60*60*2,
'cookie_path' => '/',
'cookie_secure' => FALSE,
'remember_me_seconds' => 60*60*2,
'use_cookies' => true,
),