Laravel: Show or hide content depending on a Session variable - php

I'm doing a view that has a password protection. Basically when you access that resource, you have a view that indicates that you need to put a password.
The correct behavior of this should be
You access the View
The user enters the password and sends the POST form
If the method redirects back with certain value, you must see the real content of the page.
So my blade code is the following:
#if ($passedPassword = Session::get('passedPassword'))
...here goes the real/true view content
#else
<section class="questionnaire-questions">
<div>
<form
action="{{ route('questionnaire.password', ['questionnaire' => $questionnaire->id]) }}"
method="POST">
{{ csrf_field() }}
<h3 class="text-center">#lang('questionnaire.password.advice')<h3>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="goal-input-group numeric">
<label>PASSWORD</label>
<input
style='visibility: visible;'
name="password"
type="password"
>
</div>
</div>
</div>
<div class="text-center">
<button type="submit" class="goal-btn goal-btn-lg goal-btn-artic-blue">#lang('questionnaire.password')</button>
</div>
</form>
</div>
</section>
#endif
That view is rendered with the following method:
public function show(Questionnaire $questionnaire) {
$data = [];
$data['questionnaire'] = $questionnaire;
\Session::flash('passedPassword', false);
return view('questionnaires.show', array('data' => $data));
}
In the previous method I'm passing the passedPassword, but I can't find a way to pass it as a flash variable. If there is a way to add data like
return back()->with(array(
'passedPassword' => false
));
But using the view method I'll really appreciate to know how.
Then, when the user clics the button I call the next function:
public function password(Request $request, Questionnaire $questionnaire) {
if (strcmp($questionnaire->password, $request->input('password')) == 0) {
return back()->with(array(
'passedPassword' => false
));
}
}
But even when the password is correct, I got the password view, the flash/session variable never arrived to the view.
Is there something I'm missing or doing wrong?
Thanks in advance.

As Dan told me in the comments, I was setting to false the value of the session variable.
So first I remove the \Session::flash('passedPassword', false); during the show method.
Then I modify my blade logic. In my case sometimes the password is needed and sometimes not.
#if (($passwordLength === 0) || ($passwordLength !== 0 && Session::has('passedPassword')))
With that, If the resource has no password we let the user pass. Or in the case it has a password and also we have the passedPassword variable, we also let the user see the content.

Related

i'm trying to create a search method by name but it showing this error

I'm very confused, I need your help, this is the error:
Missing required parameter for [Route: single.temp] [URI: singlepost/{name}] [Missing parameter: name]. (View: C:\Users\Toshiba\Desktop\working\mouhawla\resources\views\index.blade.php)
The search field:
<div class="search">
<form role="form" action="{{route('single.temp')}}">
<i class="fa fa-search"></i>
<div class="field-toggle">
<input type="text" name="name" class="search-form" autocomplete="off" placeholder="Search">
</div>
</form>
</div>
The method:
public function getPostByName($name) {
$products = DB::table('templates')
->where('name', $name)
->first();
return view('singlepost', compact('products'));
}
The route:
Route::get('/singlepost/{name}', 'App\http\controllers\TemplatesController#getPostByName')->name('single.temp');
The final view:
<h1 style="text-align: center;">ACH-template</h1>
<table>
<tr>
<td><img src="/storage/{{$products->image_path}}"></td>
<td><img src="/storage/{{$products->image_path2}}"></td>
<td><img src="/storage/{{$products->image_path3}}"></td>
<td>
<p>
<h2 style="text-align:center;">{{$products->name}}</h2>
</br>
<p>{{$products->description}}</p>
</p>
</td>
</tr>
</table>
<a href="/storage/{{$products->file_path}}" class="btn btn-primary">
<button class="btn" style="width:100%">
<i class="fa fa-download"></i> Download
</button>
</a>
The error is very explanatory. You are trying to use /singlepost/{name} route, but on your blade file, you are doing route('single.temp'), it is telling you that it needs the parameter name, else it cannot create the URL as it is a missing parameter.
You should have something like:
<form role="form" action="{{route('single.temp', ['name' => VALUE'])}}">
But that will not solve your problem, as you are trying to do a search, so you want something like /singlepost/John, and John is going to be input by the user on the input field. So you have to do an AJAX call because {{ route('single.temp') }} is going to be rendered by PHP and served to the user, so it is always going to miss the needed parameter.
What you can also do is get that value from the Request instead of a URL parameter.
You have defined a route which requires a parameter: {$name}. You have also used the route helper to generate a URL which takes the name of a route as the first argument and an array of parameters as an optional second argument.
When you have used route('single.temp') in your form action, you have not specified any parameters and so Laravel is throwing the error you're seeing. To resolve this error, you would need to specify a $name parameter as the second argument (i.e. route('single.temp', ['name' => 'something'])). This is not ideal though as if you're using $name as a search term, you don't know the value when the page is first rendered and so can't provide that value.
There are a few ways you could achieve your goal of searching records, a basic example of how you could do this follows.
web.php
Define two routes, the first to return a view with a form and another to process the form submission and show the results.
Route::get('/templates', [TemplateController::class, 'index'])
->name('templates.index');
Route::get('/templates/search', [TemplateController::class, 'search')
->name('templates.search');
TemplateController.php
Define the two functions which will be used when one of the routes defined above is requested.
class TemplateController extends Controller
{
// return a view
public function index()
{
return view('templates.search', ['templates' => []]);
}
// process the form submission
// perform a search for the $request search term
// return a view with the results
public function search(Request $request)
{
$request->validate([
'term' => ['required', 'string']
]);
$templates = Template::where('name', $request->term)->get();
return view('templates.search', ['templates' => $templates]);
}
}
templates/search.blade.php
{{-- create a form which will submit to the search route --}}
{{-- note I use GET rather than POST here, explained later --}}
<form action="{{ route('templates.search') }}" method="GET">
#csrf
<input type="text" id="term" name="term" />
<button type="submit">
{{ __('Search') }}
</button>
{{-- loop over and show results if there are any --}}
#forelse ($templates as $template)
{{ $template->name }}
#empty
{{ __('Empty') }}
#endforelse
</form>
The above should be self explanatory. My reason for using GET rather than POST in the search is because the value will be added to the URL as a query string parameter meaning it can be bookmarked or shared with ease.

How to solve the problem of getting unusual id in laravel

Here is my routes
Route::get('add-members/{id}','MemberController#create');
Route::post('save-member/{id}','MemberController#store');
This is my code to show the create form
public function create($id)
{
$team=Team::find($id);
$users = User::doesntHave('teams')->whereHas('roles', function($role) {
$role->where('name', 'member');
})->get();
return view('members.create',compact('users','team'));
}
An this is my code to store it
public function store(Request $request,$id)
{
$team=Team::find($id);
dd($request->id);
$team->users()->attach($request->id);
return redirect('home');
}
and this is my blade file
#extends('layouts.app')
#section('content')
<form action="{{url('save-member',$team->id)}}" method="post" accept-charset="utf-8">
#csrf
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Select Member/s') }}</label>
<div class="col-md-6">
#foreach($users as $key => $user)
<input type="checkbox" name="id[]" value="{{$user->id}}">{{$user->email}}<br>
#endforeach
#error('member_id')
<span class="invalid-feedback" role="alert"><strong><font
color="red">{{ $message }}</font></strong></span>
#enderror
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
#endsection
Now when i select none of the user and just click save button it will save the the user id as 1. After i am doing dd($request->id) it will show me the output 1. But in my form there is no users left or my form is empty.So where from 1 is coming. you can see this picture for clearify.
Please help me to solve this problems
You should be more specific with what data you are requesting from the Request:
$request->id; // could be an input named 'id' or a route parameter named 'id'
$request->input('id'); // is an input
$request->route('id'); // is a route parameter
You are running into a situation where you have a route parameter named id and potentially an input named id. Using the dynamic property of the Request, $request->id, will return the input id if it is there, if not it falls back to returning a route parameter named id.
Here is an article from the past that shows the issue with not being specific about what you are trying to get from the Request object:
asklagbox - blog - watch out for request

Laravel - Method Not Allowed HTTP Exception (RouteCollection.php line 218)

I'm currently new on Laravel and trying to develop my first project. I have this MethodNotAllowedHttpException in RouteCollection.php line 218 error during my development for inserting data into database. I have searched both Google & Stackoverflow for solutions but non are related to my current problem and some of them way too complex for this simple problem (I think so...).
I have my form in my checklist page:-
<form action="{{url('addchecklist')}}" method="POST">
{{ csrf_field() }}
<div class="row">
<div class="col-sm-12">
<div class="text-left">
<input type="hidden" name="schmFK" value="{{$id}}">
<div class="col-sm-6">
<h4>
<label>Section</label>
<select class="selectpicker form-control" data-live-search="true" name="sctionPK">
<option selected>Select the Section</option>
#foreach ($sction as $key=>$slct1)
<option value="{{$slct1->ssctionPK}}">{{strtoupper($slct1->ssctionName)}}</option>
#endforeach
</select>
</h4>
</div>
<div class="col-sm-2">
<button type="button" data-toggle="modal" data-target=".bs-example-modal-lg" class="btn btn-primary btn-sm" style="margin-top:33px; padding-top:7px; padding-bottom:7px;">Add Section</button>
</div>
<div class="col-sm-4">
<h4>
<label>Severity</label>
<select class="selectpicker form-control" name="svrityPK">
<option selected>Select the Severity</option>
#foreach ($svrity as $key=>$slct2)
<option value="{{$slct2->severityPK}}">{{strtoupper($slct2->severityName)}}</option>
#endforeach
</select>
</h4>
</div>
<div class="col-sm-12">
<h4>
<label>Question</label>
<input class="form-control" type="text" placeholder="Question" name="question">
</h4>
</div>
<div class="col-sm-6">
#include('widgets.button', array('class'=>'primary btnaddstd', 'size'=>'lg', 'type'=>'submit', 'value'=>'Add Checklist'))
</div>
</div>
</div>
</div>
</form>
Then I have this route for inserting data from the form into database:-
Route::post('/addchecklist', function (Request $request){
// Create instance to store record
$scheme = new App\checklists;
$scheme->schmFK = $request->schmFK;
$scheme->schSectionFK = $request->sctionPK;
$scheme->severityFK = $request->svrityPK;
$scheme->clQuestion = $request->question;
$scheme->save(); // save the input
// Sort all records descending to retrieve the newest added record
$input = App\checklists::orderBy('cklistPK','desc')->first();
// Set search field variable default value of null
$src = isset($src) ? $src : null;
// Get Checklist reference from cklists_stddetails with the designated ID
$chkstd = App\Cklists_stddetail::where('cklistFK', $input->cklistPK)
->join('stddetails', 'stdDtlFK', '=', 'stddetails.sdtlPK')
->get();
// Get the newest stored record
$chcklst = App\checklists::where('cklistPK', $input->cklistPK)->firstOrFail();
// Get all data from table 'stddetails'
$stddetail = App\stddetails::all();
// Get all data from table 'standards'
$stndrd = App\standard::all();
// Get all data from table 'sections'
$sction = App\Section::all();
// Redirect to 'addref.blade' page with the newest added record
return redirect('addref/'.$input->cklistPK)
->with('src', $src)
->with('chkstd', $chkstd)
->with('id',$input->cklistPK)
->with('schmid', $request->schmFK)
->with('chcklst', $chcklst)
->with('stddetail', $stddetail)
->with('stndrd', $stndrd)
->with('sction', $sction);
});
My scenario is this, I have a form for user to input data in it. Then when the data is saved, they will be redirected to the page of that data to do something there. The data is successfully saved in the database but the redirection to the designated page (addref.blade) with the newest record ID return error:-
But the URL goes where I wanted it to go (means the URL is right):-
As you can see, the usual solution from the net that I found are:-
Make sure both method from routes and the form is the same, and mine it is:-
method="POST"
Route::post
Make sure the URL routes can recognize the form's action URL, and mine it is:-
<form action="{{url('addchecklist')}}" method="POST">
Route::post('/addchecklist', function (Request $request)
Include CSRF token field in the form, and mine it have been included:-
<form action="{{url('addchecklist')}}" method="POST">
{{ csrf_field() }}
I have tried those simple solution provided on the net and nothing is helpful enough. I'm still wondering what else I have missed and hoped that anyone here can assist on solving my issue.
I think the error is that you have a redirect which you have not registered in your routes or web.php file.
Sample redirect:
Route::post('/addchecklist', function (Request $request){
//some post process here...
return redirect('addref/'.$input->cklistPK)
->with('src', $src)
->with('chkstd', $chkstd)
->with('id',$input->cklistPK)
->with('schmid', $request->schmFK)
->with('chcklst', $chcklst)
->with('stddetail', $stddetail)
->with('stndrd', $stndrd)
->with('sction', $sction);
});
Route::get('addref/{id}', function(Request $request){
//show the blade.php with data
});
Can you please write :
url('/addchecklist')
instead of :
url('addchecklist')
and then print_r('in');
and die; and check what you get.
Route::post('/addchecklist', function (Request $request){
print_r('in');
die;
});

Difficulties with 'Remember me' function in laravel

So, I'm trying to create a 'remember me' function in the login process in my laravel application. I created a basic form with email, password and remember me checkbox as input, as can be seen below:
<div class="col-xs-0 col-sm-6 col-md-6 col-md-offset-3 col-sm-offset-3 col-cs-offset-5" id="content">
{{ Form::open(['route' => 'sessions.store']) }}
<div>
{{ Form::label('email', 'Email:') }}
{{ Form::email('email') }}
</div>
<div>
{{ Form::label('password', 'Password:') }}
{{ Form::password('password') }}
</div>
<div>
{{ Form::label('remember', 'Remember me:') }}
{{ Form::checkbox('remember', 'Remember-me') }}
</div>
<div>{{ Form::submit('login') }}</div>
{{ Form::close() }}
</div>
This posts to the function below. But what happens right now, is that the user is always logged in with the true parameter. What am I doing wrong?
public function store()
{
$email = Input::get('email');
$password = Input::get('password');
$remember = Input::get('remember');
if ($remember == 'Remember-me') {
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
return Redirect::intended('/');
}
return Redirect::back()->withInput();
} else {
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
return Redirect::intended('/');
}
return Redirect::back()->withInput();
}
}
Passing true as the third parameter of Auth::attempt will remember the login on success. Additionally your $remember check makes no sense because checkbox is supposed to represent a boolean value and Input::get returns it as either 1 or null which evaluates to true or false respectively.
What you probably want is this:
public function store()
{
$input = Input::only('email', 'password');
$remember = Input::get('remember');
if (Auth::attempt($input, $remember)
{
return Redirect::intended('/');
}
return Redirect::back()->withInput();
}
One of the reasons remember me is hard to do right (and there are many) is that the first time someone logs in with the box checked they need to login conventionally and that triggers the storage that you are going to do which allows them to log in without supplying their user name and password when they come back after their session has expired and they have closed their browser etc. So the initial authentication must be totally normal except for the addition of the step where the storage for future login happens. The remember me box being checked plays no role in that initial authentication. Assuming you are going to store the data in a cookie, checking the box means that after successful authentication the cookie is created and the other logic that will be needed for remember me authentication is implemented (and I won't go into the issues around that).
Later when they come back they shouldn't need to check the box or anything like that, they should just be logged in. That's when the remember me functionality comes into play however it is that you are implementing that.
This worked for me:
$remember = (Input::has('remember')) ? true : false;
The View looks like this:
<div class="field">
<input type="checkbox" name="remember" id="remember" />
<label for="remember">Remember me</label>
</div>
Off an old tutorial I don't know where I found, but it works.

Keep modal open after validation redirect

i am currently working on a project where the login/register is handled through modal boxes (so i click the login button and a nice modal reveals with a form in).
Im using foundation 5's reveal modal to house my login form but when the form is submitted and theres a validation error the modal closes. The reason this is happening is because i am redirecting back to the route where the login form is and in that route a button needs to be clicked to fire the modal.
What i was wondering is, is there something i can set so that modal stays open if there is a validation error or exception (account not found etc.) So if there is a validation error the modal stays open.
looking for any type of solution. my code is shown below.
Login function
public function postLogin()
{
// Declare the rules for the form validation
$rules = array(
'email' => 'required|email',
'password' => 'required|between:3,32',
);
// Create a new validator instance from our validation rules
$validator = Validator::make(Input::all(), $rules);
// If validation fails, we'll exit the operation now.
if ($validator->fails())
{
// Ooops.. something went wrong
return Redirect::back()->withInput()->withErrors($validator);
}
try
{
// Try to log the user in
Sentry::authenticate(Input::only('email', 'password'), Input::get('remember-me', 0));
// Get the page we were before
$redirect = Session::get('loginRedirect', 'dashboard');
// Unset the page we were before from the session
Session::forget('loginRedirect');
// Redirect to the users page
return Redirect::to($redirect)->with('success', Lang::get('auth/message.signin.success'));
}
catch (Cartalyst\Sentry\Users\UserNotFoundException $e)
{
$this->messageBag->add('email', Lang::get('auth/message.account_not_found'));
}
catch (Cartalyst\Sentry\Users\UserNotActivatedException $e)
{
$this->messageBag->add('email', Lang::get('auth/message.account_not_activated'));
}
catch (Cartalyst\Sentry\Throttling\UserSuspendedException $e)
{
$this->messageBag->add('email', Lang::get('auth/message.account_suspended'));
}
catch (Cartalyst\Sentry\Throttling\UserBannedException $e)
{
$this->messageBag->add('email', Lang::get('auth/message.account_banned'));
}
// Ooops.. something went wrong
return Redirect::back()->withInput()->withErrors($this->messageBag);
}
Login modal
<div id="myModalLogin" class="reveal-modal small" data-reveal>
<h2>Login</h2>
<form method="post" action="{{ route('login') }}">
{{-- CSRF Token --}}
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
{{-- Email --}}
<label for="email"> Email
<input type="text" name="email" id="email" value="{{ Input::old('email') }}" />
</label>
{{ $errors->first('email', '<label class="error">:message</label>') }}
{{-- Password --}}
<label for="password"> Email
<input type="password" name="password" id="password" value=""/>
</label>
{{ $errors->first('password', '<label class="error">:message</label>') }}
{{-- Remember me --}}
<input name="remember-me" value="1" id="remember-me" type="checkbox"><label for="remember-me">Remember me</label>
<hr>
{{-- Form Actions --}}
<button type="submit" class="button">Sign in</button>
I forgot my password
<a class="close-reveal-modal">×</a>
</div>
You need to create a flag variable that you will pass to your view and set it true if you want the modal to auto open and set it false if you don't want to open it:
The problem with this is that ->with() doesn't work with Redirect::back() so we need a workaround: lets pass our flag variable as an input. For this you have to get all the old input and add the new flag variable to them. Make sure that the key (your flag variable name) doesn't already exist. You can check this with a var_dump(Input::all()).
$input = Input::all();//Get all the old input.
$input['autoOpenModal'] = 'true';//Add the auto open indicator flag as an input.
return Redirect::back()
->withErrors($this->messageBag)
->withInput($input);//Passing the old input and the flag.
Now in your view you have to print this "old" input into your JavaScript condition. If it exists it will print its value: true, otherwise it will print the second argument: false.
<script>
$(document).ready(function () {
if ({{ Input::old('autoOpenModal', 'false') }}) {
//JavaScript code that open up your modal.
}
});
</script>
You can return false; when you return the validations results.

Categories