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!
Related
created a simple page of session, Even after logout from the page i'm still able to access the login page.
I have also destroyed all the session but still can't find any solution.
view - flashdata_home.php
<form action='add' method='post'>
<input type ='text' name='value'/>
<input type='submit' value='Enter ' />
</form>
Controller - FlashData_Controller.php
<?php
class FlashData_Controller Extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('session');
$this->load->helper('url');
}
public function index(){
$this->load->view('flashdata_home');
}
public function add(){
// adding flash data
//$this->session->set_flashdata('item','This is me');
$this->session->set_userdata('Name',$this->input->post('value'));
//redirect to home page
// redirect('flashdata');
if($this->session->has_userdata('Name')){
$data = array('value' => $this->session->Name);
$this->load->view('adminflashdata_home',$data);
}
else
{
$this->load->view('flashdata_home');
}
}
public function logout(){
$this->session->unset_userdata('Name');
$this->session->sess_destroy('Name');
$this->load->view('flashdata_home');
}
}
view - adminflashdata_home.php
<?php
echo $value;
<li>Logout</li>
?>
Unsettling the session in CI is very simple and it looks like this.
In your Code you have unset the data but you have to unset the variable as i did.
For Single Data:
$this->session->unset_userdata('some_name');
For Array of Datas:
$array_items = array('username' => '', 'email' => '');
$this->session->unset_userdata($array_items);
For destroy the session:
$this->session->sess_destroy();
I think your problem is, though we destroy session we can still access the page that should be loaded only if the user in logged in.
For example, when user log in with correct credentials the url should look like this: localhost/app/controller/function (just for instance). And later when the user log out you will redirect back to login page. But if we type localhost/app/controller/function in url or if we click back button in browser, the browser will load the page !!! I consider your stated problem is same like this.
For this problem I always use a solution in every function of controller. Like;
class MainController extends CI_Controller {
function test {
$user_name = $this->session->userdata('user_name');
if(isset($user_name)) {
//the actual function code goes here
}
else {
//redirect to the login function
}
}
}
I hope this helped some one.. cheers..
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.
I'm new to cakephp and trying to simply display form data once it is posted. I would like to type something on "add.ctp" which then redirects to "index.ctp" where the information I just typed should be displayed.
The reason why I'm doing this is because I like to echo my variables and forms at various places throughout my program for debugging purposes. I tend to work a lot with data that needs to be converted or manipulated so I like to check and make sure each part is doing its job correctly. I'm new to cakephp so I'm just trying to figure out how I can do this.
Here is the code for add.ctp where the information is entered.
View\Mysorts\add.ctp
<h1>Add Numbers</h1>
<?php
echo $this->Form->create('Mysort');
echo $this->Form->input('original');
echo $this->Form->end('Add Numbers');
?>
Here is my function in the controller
Controller\MysortsController.php
<?php
class MysortsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this ->set('mysorts', $this->Mysort->find('all'));
}
public function add() {
if($this->request->is('post')) {
Configure::read();
pr($this->data); //attempting to print posted information
$this->redirect(array('action' => 'index'));
}
}
function isempty(){
$mysorts = $this->Mysort->find('all');
$this->set('mysorts', $mysorts);
}
}
?>
And finally, here is my index file where I would like to display the posted information.
View\Mysorts\index.ctp
<h1>Sorted Entries</h1>
<?php
echo $this->Html->link("Add List", array('controller'=>'mysorts', 'action' => 'add'));
if (!empty($mysorts)) {
?>
<table>
<tr>
<th>ID</th>
<th>Original</th>
<th>Sorted</th>
</tr>
<?php foreach ($mysorts as $mysort): ?>
<tr>
<td><?php echo $mysort['Mysort']['id']; ?></td>
<td>
<?php echo $mysort['Mysort']['original']; ?>
</td>
<td> <?php echo $mysort['Mysort']['sorted']; ?>
</td>
</tr>
<?php endforeach;
} else {
echo '<p>No results found!</p>';
}
?>
</table>
If the code you have posted is the exact you are using that could not work at all.
You do not save the data you receive while being in the "add" method. This is done by $this->ModelName->save($data) where ModelName is the Model to use (in your case it should be MySort and $data is the posted data.
You are using Cakephp2.x? I assume so cause you are using $this->request->is('post') which was not there in 1.3, i think. The problem about that is, that the posted data is not stored in $this->data anymore. It is in $this->request->data.
Do not use pr(). It is too "dangerous" to forget something like that in the code. Use debug() instead. The output will be disabled as soon as you see the DEBUG constant in Config/core.php in your application root to 0.
Calling the redirect() method in a controller generates a real 301 redirect. Which means the old output is dumped and lost. That and point 1 makes clear why you can not see anything. Nothing is saved and before you see the output of pr() your browser gets redirected. If you want to debug something use an exit; afterwards to make sure you wont miss the output. Sometimes you do not need it, but if you can not find your output, use it ;)
Hope this helps you.
Greetings
func0der
Maybe what you need is something like this.
For your add.ctp you define the action you want your post.
<h1>Add Numbers</h1>
<?php
echo $this->Form->create(array('action' => 'view'));
echo $this->Form->input('original');
echo $this->Form->end('Add Numbers');
?>
For your Controller You'll need to set the variable you want in your view
public function add() {
}
public function index(){
if($this->request->is('post')) {
$this->set('mysorts', $this->request->data);
}
}
And I'm not sure if what I see in your index.ctp makes sense.
I don't understand what your point is in trying to print something and then redirecting immediately? You won't see it when it redirects.
Anyhow, since your Form probably does not consist of a representation of an actual model, you might want to inspect your $this->params['form'] variable as opposed to the normal $this->data that you would use in a FormHelper.
Also, do you realize you are missing a closing } in your Controller\MysortsController.php? It closes the add() function but not the class...
The issue here is that when my user logs into my app, they always are redirected to the default controller.
I would like the user to be redirected to the page they were on before logging in.
So for example, if the user is reading forum post #12 (reading does not require login) and then decides to post an answer (answering requires login), once they login they should go back to post #12.
I am using PHP/Codeigniter 2.0.2 and the Tank_Auth library, and have in several of my controllers
function __construct()
{
parent::__construct();
if (!$this->tank_auth->is_logged_in()) {
redirect('/auth/login/');
} else {
//load stuff
}
My question is
What is the best way to set a return URL (Cookie? GET?), and how would that be implemented?
If you're familiar with Tank_Auth, in which files should I make these changes?
Any roadmaps are welcome, even if you don't use Tank_Auth.
I Recently implemented this solution on a webpage I was working.
In the controller/auth file add a reference to the user_agent library:
function __construct()
{
parent::__construct();
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->load->library('security');
$this->load->library('tank_auth');
$this->lang->load('tank_auth');
$this->load->library('user_agent'); //This is the line you are adding
}
In the views/auth/login_form.php and taking advantage of the CodeIgniter's user_agent library add a hidden input tag which will contain the referrer url as follows:
<?=form_hidden('redirect_url', $this->agent->referrer());?>
<?php echo form_submit('submit', 'Let me in'); ?>
<?php echo form_close(); ?>
After that, all you have to do is redirect the users to the content of the input named "redirect_url" when the user posts the login data to the login action:
/**
* Login user on the site
*
* #return void
*/
function login()
{
/*.... Beginning of the login action function...
....
....
*/
if ($this->tank_auth->login(
$this->form_validation->set_value('login'),
$this->form_validation->set_value('password'),
$this->form_validation->set_value('remember'),
$data['login_by_username'],$data['login_by_email'])) //valid
{
redirect( $this->input->post('redirect_url'));
}
}
This works great for me... It's fine and simple. I believe it can help you.
Let me know about anything.
This is the solution I've been using with tank_auth, it's probably not the best, but I've found it works well for me.
In the controller
if (!$this->tank_auth->is_logged_in()){
$encoded_uri = preg_replace('"/"', '_', $_SERVER['REQUEST_URI']);
redirect('/login/'.$encoded_uri);
}elseif($this->tank_auth->is_logged_in(FALSE)){ // logged in, not activated
redirect('/user/reactivate/');
}else{
//Logged IN Stuff Here
}
Modified Tank Auth Login Function (controllers/auth.php)
function login($return_to = "")
{
if ($this->form_validation->run()) {
if ($this->tank_auth->login(
$this->form_validation->set_value('login'),
$this->form_validation->set_value('password'),
$this->form_validation->set_value('remember'),
$data['login_by_username'],
$data['login_by_email'])) {
//...Other Stuff Here
$decoded_uri = preg_replace('"_"','/',$return_to);
redirect($decoded_uri);
}
}
}
You may need to change the preg_replace to something else if your urls have _ in them, I just used that because it works for me
EDIT
I've updated the function, this is one from another project that we heavily modified the tank auth stuff, so if stuff is a bit different, I'm sorry
As for the passing the encode_uri stuff, I've added the following to the routes.php file (config/routes.php)
$route['auth/login/(:any)'] = 'auth/login/$1';
$route['auth/login'] = 'auth/login'; //Probably don't need this one now
Hi I solved it as follows
In your controller
Add this: $this->load->library(array('tank_auth');
if (!$this->tank_auth->is_logged_in()) {
$encoded_uri = preg_replace('"/"', '_', $this->uri->uri_string());
redirect('/auth/login/'.$encoded_uri);
} else {
// Logged IN Stuff Here
}
In Tank Auth Controller (controllers/auth.php)
function login($return_to = "")
{
if ($this->form_validation->run()) {
if ($this->tank_auth->login(
$this->form_validation->set_value('login'),
$this->form_validation->set_value('password'),
$this->form_validation->set_value('remember'),
$data['login_by_username'],
$data['login_by_email'])) {
// success
$decoded_uri = preg_replace('"_"','/',$return_to);
redirect($decoded_uri);
}
}
}
I replaced $_SERVER['REQUEST_URI'] with this $this->uri->uri_string() because that allow you get /controller/method/...etc. to redirect later in tank auth controller
That work perfect for me and how said #Cubed Eye "You may need to change the preg_replace to something else if your urls have _ in them"
Thanks to #Cubed Eye
I hope this helps someone else too.
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')) {
}
?>