Show variable on blade template - php

I tried to show a variable this way on a blade template on laravel
<input type="text" name="win-phone" class="modal-input" value="{{ $info['fields']['phone'] }}">
and it doesn't work , but this way
<input type="text" name="win-phone" class="modal-input" value="{!! $info['fields']['phone'] !!}">
It worked, why? the first way its no the correct wat?

By default, Blade {{ }} statements are automatically sent through PHP's htmlspecialchars function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:
Hello, {!! $name !!}.
In summary, if used in this way disabled HTML is allowed.
Source : https://laravel.com/docs/7.x/blade

There are two way to print your php variable in blade template.
1. Statements are automatically sent through PHP's htmlspecialchars function to prevent XSS attack
{{ $your_variable }}
2. If you do not want your data to be escaped, you may use the following syntax
{!! $your_variable !!}

Related

Laravel Blade ( Displaying data as new line)

So i have a <textarea> in my form. User can either enter a new line or single line. So when the user views the text it will be showed like how he/she inputs it.
Form
<textarea name="jo_unit" class = 'form-control' required="required" cols = '4'></textarea>
Expected Output
TESTING 1 TESTING 2 TESTING 3
What i get
My code on displaying it
{{ nl2br(#$get['result'][0]->jo_unit_2) }}
Security: This code allows XSS attacks and is not production ready.
use {!! !!}:
{!! nl2br(#$get['result'][0]->jo_unit_2) !!}
Use
{!! nl2br(e(#$get['result'][0]->jo_unit_2)) !!}
{!! !!} creates an escaped output and allows HTML (and XSS attacks).
To make it secure again you also need to use e() see helpers documentation.

Why is my variable displaying incorrect value in Laravel 5.4 Blade file?

I have a variable $country_code that is displaying the correct value in one part of my form but not in a different part. Why is this happening?
This is my code:
{{ Form::open(['action' => ['PinVerificationController#valid'],'id'=>'pin_code_form']) }}
//$country_code shows 1
We sent a text message to {{$country_code}} {{$phone_number}}. You should receive it within a few seconds.<br><br>
{{ Form::label('Pin Code', null, ['class' => 'control-label']) }}
{{ Form::hidden('country_code', $country_code) }}//<------shows 1-US instead of 1
{{ Form::hidden('phone_number', $phone_number) }}
{{ Form::hidden('type', $pin_notification_type) }}
{{ Form::text('pin_code', null,['placeholder' => 'Pin Code'])}}<br><br>
Enter a 4 digit pin you received by phone.
<br>
<br>
{{ Form::submit('Verify',['name'=>'validate'])}}
{{ Form::close() }}
So if I set $country_code to "1" in my controller it'll display We sent a text message to 1 5555555. You should receive it within a few seconds.
But if I do an inspect element on my hidden form it displays 1-US. I've tried php artisan view:clear and php artisan clear-compiled but the problem still persists.
I've also tried hardcoding a value {{ Form::hidden('country_code', 'asdf') }} and i'm not seeing the change. I tried adding a test {{ Form::hidden('country_code1', 'asdf') }} and see the update.
I also renamed country_code to country_code111 for my hidden field and it displayed the correct value of 1. I thought it was a caching issue but like I mentioned I've tried php artisan cache:clear and the problem is still there.
Since you are using Laravel 5.4, I assume you are using Form from the LaravelCollective, since they were removed from baseline Laravel in 5.x.
LaravelCollective Forms will override the value you provide to the input if it exists in the request data, or in old posted data (the old() function). I suspect this is the case for you.
You can see this behavior implementation here.
To solve this problem, you have a few options:
change the name of the request parameter feeding into the page (if you have control over it)
rename your field name to something that doesn't conflict
Don't use Form:: to generate the form and just use classic html/Blade to create the hidden input automatically
Personally, I would recommend #3 because then you have full control over your code.
<input type="hidden" name="country_code" value="{{ $country_code }}"/>

Laravel blade "old input or default variable"?

I want to show the old input in input value. If there isn't old input, than show other variable:
value="{{ old('salary_' . $employee->id) or 'Default' }}"
But when there is no old input, it gives me 1 instead of the default value!
I think the problem has something to do with the concatenation, but I don't know how to fix it!?
or is a comparison operator in PHP, so your code is evaluating to true, or 1. What you want is a ternary if statement.
As mentioned, or can be used in blade as shorthand for a ternary if statement.
But you can (and should) just pass the default value as the second argument to the function, like so:
value="{{ old('salary_' . $employee->id, 'Default') }}"
You can use the code (for PHP 7):
{{ old('field_name') ?? $model->field_name ?? 'default' }}
For checkbox checked attribute use the code (if default value is false):
{{ (old() ? old('field_name', false) : $model->field_name ?? false) ? 'checked' : '' }}
Construction {{ $something or 'default'}} works only for variables
You can use:
old($key, $defaultValue)
See more:
https://github.com/laravel/framework/blob/87df108bb487714d205002aba7e7317533976a8d/src/Illuminate/Foundation/helpers.php#L541-L553
As described in the Laravel doc: "If you are displaying old input within a Blade template, it is more convenient to use the old helper:".
So if you need add/edit data form (when you need to use edit form for add and edit in edit mode you need to use loaded data from model (database)) to show values from the model (through controller) you can use following:
name="some_value" value="{{ $some_value or old('some_value', $the_value) }}"
where is "some_value_from_model" variable name in view array.
In this case it should be at first $some_value will be used to set in the "value" and, if no, it will try to use old (value from request from name "some_value") and if not old then '' should be used.
Thanks WoodyDRN for comment.
Try this:
value="{{ old('salary_' . $employee->id) ?? 'Default' }}"
Explanation:
If an old value is there, it will be set, otherwise, 'Default' will be set as value.
Try this:
<textarea name="alamat" id="" class="form-control" placeholder="Alamat">{{ old('alamat').#$biodata->alamat }}</textarea>

Laravel Form methods VS traditional coding

I am currently learning Laravel and finding it really useful and interesting.
At the moment I am making a simple online application form.
What are the biggest advantages to doing things using the Laravel syntax like:
{{ Form::open(array('url' => 'foo/bar')) }}
As opposed to simply:
<form action="foo/bar">
Or:
echo Form::text('username');
Instead of:
<input type="text" name="username" />
The Laravel way must be better, I just wish to know why exactly?
Using built-in HTML helpers have many benefits:
Using Form::open you add CSRF protection input hidden (by default)
Using form elements (inputs/textarea etc.) and withInput method for Redirection allows you to easily fill in the form with the same data with almost no coding
If you use Redirect::route('form'->withInput(); and have input
text {{Form::text('username')}} it will automatically set input's value the old data - you don't need to code it yourself checking it
Also if you want to match fields with labels its much easier:
{{ Form::label('username', 'Enter username') }}
{{ Form::text('username') }}
it will generate the following code:
<label for="username">Enter username</label>
<input name="username" type="text" id="username">
so as you see id will be created automatically
Probably there are some more. However the main disadvantage is that you need to learn and it's not portable in case you want to move your site to other Framework but each solution has pros and cons.
There are so many advantages of using Laravel's Form component but one useful advantage is that, when you just use this:
{{ Form::open(array('url' => 'foo/bar')) }}
{{ Form::close() }}
It automatically appends a hidden _token field which is useful for CSRF protection. otherwise you have to manually create the _token field using echo Form::token() or other way maybe. Also, when you use RESTful routes then Laravel's Form component appends the corresponding hidden _method field as well. Following note is taken from Laravel website:
Note: Since HTML forms only support POST and GET, PUT and DELETE
methods will be spoofed by automatically adding a _method hidden field
to your form.
There are also other advantages like Form Model Binding, generating form elements (specially select) easily and many more. Read more about Form on documentation.
BTW, the Redirect::back()->withInput() doesn't deppend only on use of Form component, if you use something like this, for example:
<input type='text' name='username' value='<?php echo Input::old('username') ?>' />
This will still work, the field will be repopulated on redirect back with inputs.

The CSRF token is invalid. Please try to resubmit the form

I'm getting this error message every time I try to submit the form:
The CSRF token is invalid. Please try to resubmit the form
My form code is this:
<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
<div class="form-group">
{{ form_label(form.email, 'Email', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.email, {'attr': {'class': 'col-md-2'}}) }}
{{ form_errors(form.email) }}
</div>
<div class="form-group">
{{ form_label(form.nickname, 'Nickname', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.nickname, {'attr':{'class': 'col-md-2'}}) }}
{{ form_errors(form.nickname, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
{{ form_label(form.password, 'password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.password, {'attr': {'class': 'col-md-2'}}) }}
{{ form_errors(form.password, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
{{ form_label(form.password_repeat, 'Repeat password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
{{ form_widget(form.password_repeat, {'attr':{'class': 'col-md-2'}}) }}
{{ form_errors(form.password_repeat, {'attr': {'class': 'col-md-3'}}) }}
</div>
<div class="form-group">
<div class="col-md-1 control-label">
<input type="submit" value="submit">
</div>
</div>
</form>
Any ideas?
You need to add the _token in your form i.e
{{ form_row(form._token) }}
As of now your form is missing the CSRF token field. If you use the twig form functions to render your form like form(form) this will automatically render the CSRF token field for you, but your code shows you are rendering your form with raw HTML like <form></form>, so you have to manually render the field.
Or, simply add {{ form_rest(form) }} before the closing tag of the form.
According to docs
This renders all fields that have not yet been rendered for the given
form. It's a good idea to always have this somewhere inside your form
as it'll render hidden fields for you and make any fields you forgot
to render more obvious (since it'll render the field for you).
form_rest(view, variables)
Also you can see this error message when your form has a lot of elements.
This option in php.ini cause of problem
; How many GET/POST/COOKIE input variables may be accepted
max_input_vars = 1000
Problem is that _token field misses PUT (GET) request, so you have to increase value.
Also, it concerns a big files. Increasing the
upload_max_filesize
option will solve problem.
This happens because forms by default contain CSRF protection, which is not necessary in some cases.
You can disable this CSRF protection in your form class in getDefaultOptions method like this:
// Other methods omitted
public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
// Rest of options omitted
);
}
If you don't want to disable CSRF protection, then you need to render the CSRF protecion field in your form. It can be done by using {{ form_rest(form) }} in your view file, like this:
<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
<!-- Code omitted -->
<div class="form-group">
<div class="col-md-1 control-label">
<input type="submit" value="submit">
</div>
</div>
{{ form_rest(form) }}
</form>
{{ form_rest(form) }} renders all fields which you haven't entered manually.
Before your </form> tag put:
{{ form_rest(form) }}
It will automatically insert other important (hidden) inputs.
I had this issue with a weird behavior: clearing the browser cache didn't fix it but clearing the cookies (that is, the PHP session ID cookie) did solve the issue.
This has to be done after you have checked all other answers, including verifying you do have the token in a hidden form input field.
In addition to others' suggestions you can get CSRF token errors if your session storage is not working.
In a recent case a colleague of mine changed 'session_prefix' to a value that had a space in it.
session_prefix: 'My Website'
This broke session storage, which in turn meant my form could not obtain the CSRF token from the session.
If you have converted your form from plain HTML to twig, be sure you didn't miss deleting a closing </form> tag. Silly mistake, but as I discovered it's a possible cause for this problem.
When I got this error, I couldn't figure it out at first. I'm using form_start() and form_end() to generate the form, so I shouldn't have to explicitly add the token with form_row(form._token), or use form_rest() to get it. It should have already been added automatically by form_end().
The problem was, the view I was working with was one that I had converted from plain HTML to twig, and I had missed deleting the closing </form> tag, so instead of :
{{ form_end(form) }}
I had:
</form>
{{ form_end(form) }}
That actually seems like something that might throw an error, but apparently it doesn't, so when form_end() outputs form_rest(), the form is already closed. The actual generated page source of the form was like this:
<form>
<!-- all my form fields... -->
</form>
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" />
</form>
Obviously the solution is to delete the extra closing tag and maybe drink some more coffee.
I had this error recently. Turns out that my cookie settings were incorrect in config.yml. Adding the cookie_path and cookie_domain settings to framework.session fixed it.
I hade the same issue recently, and my case was something that's not mentioned here yet:
The problem was I was testing it on localhost domain. I'm not sure why exactly was this an issue, but it started to work after I added a host name alias for localhost into /etc/hosts like this:
127.0.0.1 foobar
There's probably something wrong with the session while using Apache and localhost as a domain. If anyone can elaborate in the comments I'd be happy to edit this answer to include more details.
In case you don't want to use form_row or form_rest and just want to access value of the _token in your twig template. Use the following:
<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" />
In my case I got a trouble with the maxSize annotation in the entity, so I increased it from 2048 to 20048.
/**
* #Assert\File(
* maxSize = "20048k",
* mimeTypes = {"application/pdf", "application/x-pdf"},
* mimeTypesMessage = "Please upload a valid PDF"
* )
*/
private $file;
hope this answer helps!
I faced a similar issue. After ensuring the token field was actually rendered (see accepted answer) I checked my cookies.
There were 2(!) cookies for the domain in my Chrome browser, apparently because I was running the application on the same domain as another app, but with a different port (i.e. mydomain.com set the original cookie while the buggy app was running on mydomain.com:123)
Now apparently Chrome sent the wrong cookie so the CSRF protection was unable to link the token to the correct session.
Fix: clear all the cookies for the domain in question, make sure you don't run multiple applications on the same domain with differing ports.
I had the same error, but in my case the problem was that my application was using multiple first-level domains, while the cookie was using one. Removing cookie_domain: ".%domain%" from framework.session in the config.yml caused cookies to default to whatever domain the form was on, and that fixed the problem.
You need to remember that CSRF token is stored in the session, so this problem can also occur due to invalid session handling. If you're working on the localhost, check e.g. if session cookie domain is set correctly (in PHP it should be empty when on localhost).
This seems to be an issue when using bootstrap unless you are rendering the form by {{ form(form)}}. In addition, the issues seems to only occur on input type="hidden". If you inspect the page the with the form, you'll find that the hidden input is not part of the markup at all or it's being rendered but not submitted for some reason. As suggested above, adding {{form_rest(form)}} or wrapping the input like below should do the trick.
<div class="form-group">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</div>

Categories