CakePHP check if user is logged in inside a view - php

I have the following code:
<?php
if (!$this->Auth->user())
{
echo $this->element('header');
}
else
{
echo $this->element('header-bar');
}
?>
inside my view which should show a different header for logged in users but throws the following error:
Notice (8): Undefined property: View::$Auth [APP/views/layouts/page.ctp, line 17]
Fatal error: Call to a member function user() on a non-object in /Users/cameron/Sites/thehive/app/views/layouts/page.ctp on line 17
How do I fix this? Thanks

You don't need to do $this->set(compact('authUser'));
only use this in View:
if ($this->Session->read('Auth.User')){
// do something
}

As of CakePHP 2.x:
<?php if (AuthComponent::user('id')): ?>
Logged in as <?= AuthComponent::user('name') ?>
<?php endif; ?>

Note: Also check out meotimdihia's answer below. It's got a lot of upvotes.
The Auth component is for use in the Controller. You'll want to check for authorization in the controller, then set a variable for the view, e.g., $this->set('authUser', $this->Auth->user());. Then in your view you can do:
if (!$authUser)
{
echo $this->element('header');
}
If you want this to be done automatically for all controller methods, you can look into modifying cake/libs/controller/app_controller.php so that it includes the Auth component.

To summarize the answers on this page, evaluate one of the following based on which version of CakePHP you are using:
For version 1.x
$this->Session->read('Auth.User')
For version 2.x
AuthComponent::user('id')
For version 3.x
$this->request->session()->read('Auth.User.id')
For version 4.x, using the Authentication component
$this->loadHelper('Authentication.Identity');
...
$this->Identity->isLoggedIn()

This works in Cakephp 3+ (juts modify: "Auth.User.username" to suit your session data)
<?php
if (is_null($this->request->session()->read('Auth.User.username'))) {
echo "....logged out";
} else {
echo "You are Logged in As " . $this->request->session()->read('Auth.User.username');
}
?>

its been a while that I have used CakePHP but as far as I can remember CakePHP
doesn't support Auth in View. What you can do of course is set a variable in the
controller to use it in the view
<?
class AppController {
....
function beforeFilter(){
....
$this->set('auth',$this->Auth);
}
....
}
?>
and then use it in the view like this
$auth->....
or you can use the AuthHelper written by Ritesh Agrawal
http://bakery.cakephp.org/articles/ragrawal/2008/07/29/authhelper
BTW
I think if it comes to only test if somebody is logged in #webbiedave's answer
is better MVC style wise.
Nevertheless if you have to access userdata in view the just extract the userinfo
from Auth component and set it in the controller as I showed you and use it in the view
Regards

Try this
class AppController extends Controller{
$this->user = false;
public function beforeFilter(){
$this->user = $this->Auth->user();
}
public function beforeRender(){
$this->set('logged_user',$this->user);
}
}
Now You can check $logged_user in the view as
if($logged_user){
// users logged in $logged_user have all the details
}else{
// not logged in
}

in cakephp 3 you can check authentication session in the view like this
if($this->request->Session()->read('Auth.User')){
//do when login
}
else{
//do not login
}

If it helps anyone out in cakephp version 3.7.8 session has been depriciated to getSession so to update Lee Nielsen's comment
if (is_null($this->request->getSession()->read('Auth.User.username'))) {
echo "....logged out";
} else {
echo "You are Logged in As " . $this->request->getSession()->read('Auth.User.username');
}

For cakephp 4.2.6 Strawberry with Auth Component
<?php
// Note: Change email param to yours
if (is_null($this->request->getSession()->read('Auth')->email)) {
?>
<?= $this->Html->link(__('Login'), [ 'action' => 'login','controller' => 'Users']) ?>
<?php
} else { ?>
<?= $this->Html->link(__('Logout'), [ 'action' => 'logout','controller' => 'Users']) ?>
<?php }
?>

You need to set the user details from a controller, preferably the AppController which is inherited by all controllers across your site. Create/amend your app_controller.php to contain this beforeFilter(); method.
<?php
class AppController extends Controller {
function beforeFilter() {
$user = $this->Auth->user();
$this->set(compact('user'));
}
This will set a var called $user to the views which will be empty if the user is not logged in, or contain their data if they are.

//In the views (or layout)
$session->check('Auth.User.id');
//In controller
$this->Auth->User('id');

I found something worth mentioning, In CakePHP 3.x session handler is deprecated,
if we want to access session in view, we can do it via request handler. we have to use
<?php
// For CakePHP 3.x to access all user information
$this->request->session()->read('Auth.User');
// For CakePHP 3.x to check session
if($this->request->session()->read('Auth.User.id')) {
}
?>

Related

Zend Framework 2 Flash Messenger returning no messages

I'm having a rather odd problem with flash messenger in ZF2. I'm using it in quite a simple scenario, save a 'registration complete' message after registering and redirect to the login page and display the message however the messages are never returned by the flash messenger.
In controller register action:
$this->flashMessenger()->addMessage('Registration complete');
return $this->redirect()->toRoute('default', array('controller' => 'user', 'action' => 'login'));
In controller login action:
$flashMessenger = $this->flashMessenger();
$mes = $flashMessenger->hasMessages();
$cur = $flashMessenger->hasCurrentMessages();
Both $mes and $cur are false (I tried both just to be sure). Can anyone shed any light on this?
I'm using ZF 2.2.2 and PHP 5.3.14. Session save handler is using the dbtable adapter and I have tried disabling this as well as setting the flashmessenger session manager to the use the same dbtable save handler with no result.
To use the FlashMessenger controller plugin, you need to add the following in your controller:
<?php
class IndexController extends AbstractActionController {
public function indexAction() {
$this->flashMessenger()->addMessage('Your message');
return $this->redirect()->toRoute('admin/default', array('controller'=>'index', 'action'=>'thankyou'));
}
public function thankyouAction() {
return new ViewModel();
}
}
Add the following to the thankyou.phtml view template:
<?php
if ($this->flashMessenger()->hasMessages()) {
echo '<div class="alert alert-info">';
$messages = $this->flashMessenger()->getMessages();
foreach($messages as $message) {
echo $message;
}
echo '</div>';
}
?>
It seems that your code is as it should be, there must be something tricky in the workflow.
In this case, you can debug the old way : try var_dump($_SESSION) to see if it is populated by your flashMessenger.
Use
echo $this->flashMessenger()->renderCurrent(...
instead of
echo $this->flashMessenger()->render(...
I also faced same problem for (login flashmessage after registration) I solved it in the following way
Apply a check on your layout page like
<?php if($this->zfcUserIdentity()) { ?>
<div id="flashMessageDiv" class="hide">
<?php echo isset($flashMessages) && isset($flashMessages['0']) ? $flashMessages['0'] : ''; ?>
</div>
<?php } ?>
That means layout flashMessageDiv is accessible only to the logined user . now on your login view file (login.phtml)
apply the following code
<?php $pathArray = $_SERVER['HTTP_REFERER'];
$pathArray = explode("/",$pathArray);
?>
<?php if ($pathArray[4] === 'register') { ?>
<div id="flashMessageDiv" class="hide">
<?php echo "User details saved successfully"; ?>
</div>
<?php } ?>
In the above code i used HTTP_REFERER which will simply give us the referer url details check if referer url is register then show falshmessage.
Hope it will help you.
The FlashMessenger is now an official view helper in ZF2 and can be easily integrated in every view / layout:
FlashMessenger Helper — Zend Framework 2 2.3.1 documentation - Zend Framework
It works with TwitterBootstrap3 too and there is an alternative configuration for your module.config.php.

Changing content when user has logged in i.e. when session starts

How do I change the content for a user when he logs in? I mean like enabling voting, changing "login" to "logout" etc.
What I think to do is to start the session when user logs in (I am preferring to start session only when user logs in, not all the time). Then add data to the session's cookie like-
//controller
$moredata = array(
'username' => $this->username,
'login' => TRUE
);
$this->session->set_userdata($modedata);
//redirect
Then in the other controller, where he has been redirected I check the following-
$login = $this->session->userdata('login');
if ($login==TRUE)
Depending on the 'if' condition I will pass a variable to the view, with the help of that variable I will forward only the div/sections which should be shown to a logged-in user.
The problem is, while performing the above comparison Codeigniter shows following error (remember I haven't added 'session' in autoload array yet)
Message: Undefined property: NameOfController::$session
And If I set following in the autoload file
$autoload['libraries'] = array('session');
then the "if ($login==TRUE)" comparison always shows FALSE.
What should I do?
If I were you, I'd place all your session checks in a base controller which all your other main controllers extend. This allows you to keep things DRY:
class BaseController extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function isLoggedIn()
{
// Will return true or false
return $this->session->userdata('login');
}
}
And in one of your functional controllers (the example below handles users):
class UserController extends BaseController {
public function __construct()
{
parent::__construct();
}
public function profile()
{
// Redirect if not logged in
if (!$this->isLoggedIn()) {
$this->redirect('some/other/page')
}
}
public function register()
{
// Show different HTML if not logged in
$data = array(
'isLoggedIn' => $this->isLoggedIn()
);
$this->load->view('register', $data);
}
}
The second method in UserController allows you to render different content in your view:
<? if ($isLoggedIn): ?>
<p>You're logged in!</p>
<? else: ?>
<p>Not logged in</p>
<? endif; ?>
On my last project we created a simple permissions helper that had functions to check for logged-in status and for privilege levels. Then we'd just call the helper's functions as needed from anywhere in the system. If the user is logged in and has privs for that content then they get the content - otherwise we'd redirect them to a registration or other error page. Since all of that logic is in the helper functions, we could wrap any permission-requiring code in a quick permissions call like if(is_logged_in()){code requiring login to access}.

Cannot call CakePHP setFlash function

My client inherited an incomplete CMS and I am trying to help them fix it. Keep in mind that I come from front end development, some logic that may appear obvious to some of you totally elude me.
So I managed to almost complete and better the CMS, however there is the issue of logging in. If a user enters the right username and password, all works properly.
However, it would be simple courtesy to indicate to the user when something wrong was done, like "retry to enter your password" or some better phrased message. But nothing happens now.
So I looked into the code, ended up comparing these two files:
login.ctp (the view, as I understand it)
<?php
echo $this->Session->flash('auth');
?>
<div id="loginColumns">
<!-- input fields -->
<div id="loginLeftColumn">
<?php
echo $this->Form->create('User',array('action'=>'login'));
echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</div>
<!-- login button -->
<div id="loginRightColumn">
<?php echo $this->Form->end('Continue'); ?>
</div>
</div>
UsersController.php (the controller, as the name implies)
<?php
class UsersController extends AppController
{
var $name = 'Users';
public $scaffold;
public function beforeFilter()
{
$this -> Auth -> allow(array('login', 'logout'));
}
public function login()
{
if($this -> request -> is('post'))
{
if($this -> Auth -> login())
{
$this -> redirect($this -> Auth -> redirect());
}
else
{
// this does not work, maybe because there is no session yet
// when users have not logged in yet?
$this -> Session -> setFlash(__('Invalid username or password, try again'));
}
}
}
function logout()
{
$this -> redirect($this -> Auth -> logout());
}
}
?>
As you can see, there seems to be something that handles erros when logging, but there is nothing showing. That setFlash function is used in a couple of places once the user is logged in, and it works like a charm.
Is there any way for me to use it before the user logs in, or do I have to recreate it from scratch? And if so, what could be some leads into doing it so it looks and feels similar?
Thanks!
Stick with using this in your view:
<?php echo $this->Session->flash(); ?>
This will display the Flash message you are setting in the controller.
In your app/View/Layouts/default.ctp file add the line:
<?php
echo $this->Session->flash();
?>
public $components = array('Session');
check and add "session" component if it is not set by default in your AppController class, then add
<?php echo $this->Session->flash('your message'); ?>
to your view!

CakePHP controller/action question with http://mysite.com/mycontroller/absentaction

Suppose someone hits in url http://mysite.com/comments/view/13
But that absentaction is not present in comments controller.
Then it gets normal error like that =>
Error: The action view is not defined in controller CommentsController
Error: Create CommentsController::view() in file: app/controllers/comments_controller.php.
<?php
class CommentsController extends AppController {
var $name = 'Comments';
function view() {
}
}
?>
Notice: If you want to customize this error message, create app/views/errors/missing_action.ctp
What i'm trying to do is that if someone hits url http://mysite.com/comments/view/13 and if the action is not present then it will redirect to http://mysite.com/.
How can i do this for unknown/absent action?
This trick is actually working pretty well.
You need to create a file app/app_error.php
<?php
class AppError extends ErrorHandler {
public function error404($params){
extract($params);
if(!isset($url)){
$url = $action;
}
if(!isset($message)){
$message ="";
}
if(!isset($base)){
$base = "";
}
$this->controller->redirect(array('controller'=>'pages','action'=>'home'));
//Or the page you want...
}
}
?>
How does it work?
It actually override the error404() function from the ErrorHandler and redirect the user whith $this->controller->redict();
Notice at the bottom of the error message, it says you can customize it by creating app/views/errors/missing_action.ctp. So all you need to do is create that .ctp file and include a redirect in it like this:
<?php
header( 'Location: http://mysite.com' ) ;
?>
It says it right in the error...
create app/views/errors/missing_action.ctp
And that's what you should do...
Try using a header in the missing_action.ctp to redirect to where you want the page to go.
You can either customise app/views/errors/missing_action.ctp or you can turn off debugging in app/config/core.php

Is there an easy way to get AuthComponent user data from a view in CakePHP?

According to the cakebook section on the Auth component, I can implement simple authentication by using the following Users controller:
class UsersController extends AppController {
var $name = 'Users';
var $components = array('Auth'); // Not necessary if declared in your app controller
/**
* The AuthComponent provides the needed functionality
* for login, so you can leave this function blank.
*/
function login() {
}
function logout() {
$this->redirect($this->Auth->logout());
}
}
I would like to be able to something like the following into my view:
<?php
$username = $auth->user('username');
echo "Welcome " . $username;
?>
Is there a simple way to do this, or do I need to overwrite the login function and store the username to the session?
Update
Alexander's answer is exactly what I wanted. However, I will add the following in case someone else gets confused like I did.
It took me a while to understand that if you change the model that Auth uses (for example, you might have a 'persons' table instead of 'users'), then you need to use something like:
$persondata = $session->read('Auth.Person');
Actually this information is easily available from the session. You use the session helper to grab it. I believe the correct syntax is :
$userdata = $session->read('Auth.User');
$username = $session->read('Auth.User.username');
EDIT:
For CakePHP 2.X and on the syntax is:
$userdata = $this->session->read('Auth.User');
$username = $this->session->read('Auth.User.username');
Check out AuthComponent-Methods in the CakePHP manual....
You can access an user info after a user has logged in from the session via $this->Auth->User(). So if you want the username, just use this in the controller.
$this->set('username', $this->Auth->User('username'));
You can now use $username in the view.
Add a method in your AppController
function beforeFilter() {
$ath = $this->Auth->user();
$this->set('userDetails', $ath['User']);
}
And then you can access it from your views and/or layouts via $userDetails
To access Auth vars in views just do it:
echo $session->read('Auth.User.id');

Categories