I am following this tutorial http://www.yiiframework.com/wiki/459/integrating-hybridauth-directly-into-yii-without-an-extension/
into my own application but I get an error and I spend many hours to find wich step that I miss.
Here is my error.
Alias "components.HybridAuthIdentity" is invalid. Make sure it points to an existing directory or file.
In components directory, I create a file named HybridAuthIdentity.php
class HybridAuthIdentity extends CUserIdentity{`
public $hybridAuth;
public $adapter;
public $userProfile;
public $allowedProviders = array('google', 'facebook', 'linkedin', 'yahoo', 'live',);
protected $config;
function __construct()
{
$path = Yii::getPathOfAlias('ext.hybridauth');
require_once $path . '/hybridauth/Hybrid/Auth.php';
$this->config = array(
"base_url" => "touchtalent.dev/login/SocialLogin",
"providers" => array(
"LinkedIn" => array(
"enabled" => true,
"keys" => array (
"key" => "My key",
"secret" => "my secret id",
),
),
),
"debug_mode" => false,
"debug_file" => "",
);
$this->hybridAuth = new Hybrid_Auth($this->config);
}
}
In my siteController, I write :
Yii::import('components.HybridAuthIdentity');
$haComp = new HybridAuthIdentity;
if(!$haComp->validateProviderName($_GET['provider']))
{
throw new CHttpException("500", "Invalid action. Please Try again");
}
else
{
$haComp->adaptor = $haComp->hibrydAuth->authenticate($_GET['provider']);
$haComp->userProfile = $haComp->adaptor->getUserProfile();
$haComp->login();
$this->redirect('create');
}
How I can fix it? Thanks for all resposes...
Related
To be very specific - there is CRM system written in Codeigniter called Rise. I would like to make (automatically) an expense entry ( call save() method of an Expenses class ) each time someone logs in ( inside save_timelog() method of a Projects class ) time manually.
Expense Controller:
function save() {
validate_submitted_data(array(
"id" => "numeric",
"expense_date" => "required",
"category_id" => "required",
"amount" => "required"
));
$id = $this->input->post('id');
$target_path = get_setting("timeline_file_path");
$files_data = move_files_from_temp_dir_to_permanent_dir($target_path, "expense");
$has_new_files = count(unserialize($files_data));
$data = array(
"expense_date" => $this->input->post('expense_date'),
"title" => $this->input->post('title'),
"description" => $this->input->post('description'),
"category_id" => $this->input->post('category_id'),
"amount" => unformat_currency($this->input->post('amount')),
"project_id" => $this->input->post('expense_project_id'),
"user_id" => $this->input->post('expense_user_id'),
"files" => $files_data
);
<.. ETC. CHECKING FILES ..>
$save_id = $this->Expenses_model->save($data, $id);
if ($save_id) {
echo json_encode(array("success" => true, "data" => $this->_row_data($save_id), 'id' => $save_id, 'message' => lang('record_saved')));
} else {
echo json_encode(array("success" => false, 'message' => lang('error_occurred')));
}
}
Projects Controller:
function save_timelog() {
$this->access_only_team_members();
$id = $this->input->post('id');
$start_time = $this->input->post('start_time');
$end_time = $this->input->post('end_time');
$note = $this->input->post("note");
$task_id = $this->input->post("task_id");
if (get_setting("time_format") != "24_hours") {
$start_time = convert_time_to_24hours_format($start_time);
$end_time = convert_time_to_24hours_format($end_time);
}
$start_date_time = $this->input->post('start_date') . " " . $start_time;
$end_date_time = $this->input->post('end_date') . " " . $end_time;
$start_date_time = convert_date_local_to_utc($start_date_time);
$end_date_time = convert_date_local_to_utc($end_date_time);
$data = array(
"project_id" => $this->input->post('project_id'),
"start_time" => $start_date_time,
"end_time" => $end_date_time,
"note" => $note ? $note : "",
"task_id" => $task_id ? $task_id : 0,
);
if (!$id) {
//insert mode
$data["user_id"] = $this->input->post('user_id') ? $this->input->post('user_id') : $this->login_user->id;
} else {
//edit mode
//check edit permission
$this->check_timelog_updte_permission($id);
}
$save_id = $this->Timesheets_model->save($data, $id);
if ($save_id) {
echo json_encode(array("success" => true, "data" => $this->_timesheet_row_data($save_id), 'id' => $save_id, 'message' => lang('record_saved')));
} else {
echo json_encode(array("success" => false, 'message' => lang('error_occurred')));
}
}
So now what I'm trying to do is inside Projects controller, save_timelog() method just below these lines:
<...>
if (!$id) {
//insert mode
$data["user_id"] = $this->input->post('user_id') ? $this->input->post('user_id') : $this->login_user->id;
} else {
//edit mode
//check edit permission
$this->check_timelog_updte_permission($id);
}
/* CREATING A SAMPLE ARRAY WITH STATIC DATA FOR AN EXAMPLE EXPENSE ENTRY */
$a = array(
"expense_date" => '2018-03-13',
"title" => 'Cat Food',
"description" => 'Sheba, Felix, KiteKat',
"category_id" => '85',
"amount" => '500',
"project_id" => '84',
"user_id" => '10',
"files" => $files_data
);
/* TRYING TO SAVE/SEND EXAMPLE ARRAY TO Expenses Class save() method (?) */
$b = $this->Expenses_model->save($a);
/* RESULT (?) */
$save_id = $this->Timesheets_model->save($data, $id);
if ($save_id) {
echo json_encode(
array(
array(
"success" => true,
"data" => $this->_timesheet_row_data($save_id),
'id' => $save_id,
'message' => lang('record_saved')
),
array(
"success" => true,
"data" => _row_data($b),
'id' => $save_id,
'message' => lang('record_saved')
)
)
);
} else {
echo json_encode(array("success" => false, 'message' => lang('error_occurred')));
}
<.. Closing save_timelog() method ..>
However it surely doesn't work and all I get is "POST http://rise.test/index.php/projects/save_timelog 500 (Internal Server Error)".
I also load Expenses model and Expenses categories model in Projects _construct():
Projects Controller:
public function __construct() {
parent::__construct();
$this->load->model("Project_settings_model");
$this->load->model("Expense_categories_model");
$this->load->model("Expenses_model");
}
I also contacted developers of Rise with following question/answer:
Me:
In Projects controller save_timelog() method I just want to call
Expenses controller save() method, and if save_timelog() is successful
I would like to save an Expense ( $this->Expenses_model->save($data,
$id); ) with appropriate data. Could be static values for now for
$data array in save() method - just to find out it's working.
Rise Devs:
Hi, You are doing almost right. Just remove the 2nd parameter $id. It
should be used only for update. $this->Expenses_model->save($data)
Would really appreciate any help and directions! Thanks.
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
));
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,
),
I'm using twig, and i'm attempting to add a function.
$Func = new \Twig_SimpleFunction('placeholder', function ($title) {
$this->module->CurrentPage->addPlaceholder($title);
});
\App::make('twig')->addFunction($Func);
I will get the following exception
Unable to add function "placeholder" as extensions have already been initialized.
I've checked twice that the "addFunction" is executed before the twig "loadTemplate". So, it does not seem to be the problem.
Does anyone have a hint, or an idea about this? Or what its all about.
Thanks in advance.
You need to add twig functions right after you created Twig_Environment instance. For example, the following WILL NOT work:
$loader = new Twig_Loader_Filesystem($this->resourceRoot . '/views');
$twig = new Twig_Environment($loader, array(
'cache' => storage_path('twig'),
'debug' => Config::get('app.debug'),
'strict_variables' => true,
));
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('{#', '#}'),
'tag_block' => array('{%', '%}'),
'tag_variable' => array('{^', '^}'),
'interpolation' => array('#{', '}'),
));
$twig->setLexer($lexer);
$function = new Twig_SimpleFunction('widget', function ($widget, array $params) {
WidgetFactory::renderWidget($widget, $params);
});
$twig->addFunction($function);
Because Lexer is initialized before functions are added. You need to make it like this:
$loader = new Twig_Loader_Filesystem($this->resourceRoot . '/views');
$twig = new Twig_Environment($loader, array(
'cache' => storage_path('twig'),
'debug' => Config::get('app.debug'),
'strict_variables' => true,
));
$function = new Twig_SimpleFunction('widget', function ($widget, array $params) {
WidgetFactory::renderWidget($widget, $params);
});
$twig->addFunction($function);
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('{#', '#}'),
'tag_block' => array('{%', '%}'),
'tag_variable' => array('{^', '^}'),
'interpolation' => array('#{', '}'),
));
$twig->setLexer($lexer);