I am a beginner PHP developer, i was implementing CRUD with Laravel 5.4 framework, and all works fine so far.
But i was then trying to make this code functional in website and mobile as well, so i get to know web services and it's protocols like Rest,Soap, i was successfully managed to work with them and build small size scripts for self learning and things get better.
When i try to apply what i have learned on my CRUD i stuck , there is no links to structure my code over just routes and a with api.php,web.php files , i don't know where to build my server or client scripts and how to link them in laravel even though i managed to implement this in native php , but things a little bit confusing for me in laravel i surfed the internet and found nothing useful for me actually ..
i will provide simple of my CRUD code on the (Create New User Function) .and wish if any one could help me or put me on track to start using this technique with different projects.
My Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\user;
class AddController extends Controller
{
public function create(){ //create new user page
return view('add.create');
}
public function store(){ //store new user added by a clint
$this->validate(request(), [ //validation for request records
'name' => 'required',
'email' => 'required',
'password' => 'required|min:8',
'password_confirmation' => 'required|same:password'
]);
$user = User::create([ //create new user with the request records
'name' => request('name'),
'email' => request('email'),
'password' =>bcrypt(request('password'))
]);
session()->flash('message','Changes has been Applied'); //flash a succcess message
return redirect()->home(); // redirect to home after submitting the new user
}
}
My Route (not a resource route , just a native route )
// add new user routes
Route::get('add','AddController#create')->middleware('authenticated');
Route::post('add','AddController#store');
My Model
is the Built-In User.php model provided by laravel.
My View add.create.blade.php
<!-- this is the view of the add new user tab , extending master layout and it's components-->
#extends('layouts.master')
#section('content')
<div class="col-md-8">
<h3>Enter the Values of the new User</h3>
<form method="POST" action="add">
{{csrf_field()}}
<div class="form group">
<label for="name">*Name:</label>
<input type="name" class="form-control" id="name" name="name">
</div>
<div class="form group">
<label for="Email">*Email Address:</label>
<input type="email" class="form-control" id="email" name="email">
</div>
<div class="form group">
<label for="password">*Password:</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group">
<label for="password confirmation">*Confirm Password:</label>
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" >
</div>
<br>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add User</button>
</div>
#include('layouts.errors')
</form>
</div>
#endsection
that's what i have reached so far and i wish if any one tell me how to apply api to this code to make it function on mobile as well , i really appreciate any help in advance .
Right now you controller returns a view file - HTML template with some PHP variables. Your API doesn't need that HTML code, so first of all, you should get rid of it.
Your API route(in API case route is called 'endpoint') should return information in structured format - if you are using REST API, you should return data in JSON format(http://jsonapi.org/examples/ - example of JSON responses), if you are using SOAP - response should be in XML(for first time I would recommend you to use REST, as it's much simpler to build REST API).
A good practice would be to use Transformers while building your response(take a look https://medium.com/#haydar_ai/how-to-start-using-transformers-in-laravel-4ff0158b325f here for example).
You should also create your endpoints in api.php file - this file is specially for this needs. Don't forget that all routes in this file have a prefix of 'api'.
There is a great video-series in https://laracasts.com/series/incremental-api-development, in which simple REST api is build.
Related
I am implementing Cartalyst Stripe to my laravel app.
https://cartalyst.com/manual/stripe/2.0#installation
This is my controller code at index method:
$stripe = new Stripe(env('STRIPE_API_KEY'));
$customer = $stripe->customers()->create([
'email' => Auth::user()->email,
'name' => Auth::user()->name
]);
$token = $stripe->tokens()->create([
'card' => [
'number' => '4242424242424242',
'exp_month' => 6,
'exp_year' => 2022,
'cvc' => 314,
],
]);
$card = $stripe->cards()->create($customer['id'], $token['id']);
$charge = $stripe->charges()->create([
'customer' => $customer['id'],
'currency' => Session::get('appcurrency'),
'amount' => Session::get('total_payment'),
'statement_descriptor' => 'Descriptor.com'
]);
I will use this bootstrap form to collect user info, so I ll pass all users input thru $request later (there will be month and year for expiration separated later, but its not important for now):
<form action="{{ \LaravelLocalization::localizeURL('/order-final') }}" method="post">
#csrf
#method('post')
<div class="section">
<div class="container mt-5">
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-6"><label>Card number:</label><input type="text" class="form-control" name="card_number" placeholder="Card number" value=""></div>
</div>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-3 mt-5"><label>Expiration:</label><input type="text" class="form-control" name="expiration_date" placeholder="Expiration"></div>
<div class="col-sm-3 mt-5"><label>CVC:</label><input type="text" class="form-control" name="cvc" placeholder=" CVC"></div>
<div class="col-sm-2"></div>
</div>
<div class="row">
<div class="col-lg-5"></div>
<div class="col-lg-4 mt-5"><button type="submit" class="btn btn-primary" id="card-button">Pay</button></div>
<div class="col-lg-4"></div>
</div>
</form>
So, once I make this test charge, everything works very good, so implementation is successful.
I am just trying to figure out, how to handle card where is 3D Secure required, because I want to make 3D Secure required for all payments, especially from SCA countries.
I tried to do that with paymentintent and setup intent, but I have no idea.
I want to let customers fill out card details, then it should be redirected to stripe 3D secure page and then redirected back to some url.
At payment intent is parameter return_url, but I have no idea how to set it up.
Never did stripe before.
I can use stripe without 3D secure now, which is okay, but I want to use 3D Secure.
I tried to use Stripe's form with Stripe.js:
<div id="card-element">
But it always mess up my bootstrap 5 code, so that redirect will be fine.
I also thought about Stripe Billing portal option and redirect customers to the stripe billing portal directly.
Also, I want to use customer's card in stripe, which works as well, just having that 3D secure issue.
So I just somehow need to trigger Stripe SCA redirection for authentication.
Can you help me, please?
Thanks a lot
You may need to reach out to Cartalyst for more detailed support, but at a high level it appears to largely act as a thin wrapper around the underlying stripe-php package (github).
You need to read about migrating to Payment Intents from Charges in order to support SCA/3D Secure properly, or the Accept a Payment guide.
While you can use the return_url for manual 3DS redirect handling, this is not recommended. Using the Stripe.js client-side helper confirmCardPayment (guide step) is likely to lead to a better integration experience.
I'm learning Laravel. The current stable version is, as far as I'm aware, 5.8. I'm following tutorials and really liking the framework, but it gets a bit troublesome when these tutorials get to the point where they introduce how forms are incorporated. All of those tutorials use LaravelCollective forms, which is no longer working as of 5.8 and it is an abandoned project so I'd prefer not to use it anyway.
But this leaves me confused as to what the best practices are for using forms with Laravel. I've had some goes at creating forms, but... most of it is just HTML with hardly any Laravel "in there", if that makes sense. The only Laravel bit here is the form action, where it points to the store function in the TodosController. See below, for a file called create.blade.php.
#extends('layouts.app')
#section('content')
<h1>Create Todo</h1>
<form action="{{action('TodosController#store')}}" method="post">
#csrf
<div class="form-group">
<label for="text">Text</label>
<input type="text" name="text" class="form-control" placeholder="Enter title"/>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" name="body" id="body" rows="10" placeholder="Enter details"></textarea>
</div>
<div class="form-group">
<label for="due">Due date</label>
<input type="text" name="due" class="form-control" placeholder="Enter due date"/>
</div>
<input type="submit" value="Submit" class="btn btn-primary">
</form>
#endsection
This works fine, but I just feel like I'm not utilising blade properly here at all. Any pointers would be greatly appreciated.
Actually, you're using more laravel there than just the form action. The #csrf stands for Cross-site request forgery and it's the laravel way to protect you against that, as said in the docs:
Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.
Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request. You may use the #csrf Blade directive to generate the token field:
When you have a PUT, PATCH OR DELETE form you should use the blade directive #method to inform wich action laravel should use:
HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:
You can achieve that, simply using:
<form action="/foo/bar" method="POST">
#method('PUT')
#csrf
</form>
Besides that, i think you're using laravel/blade just fine. Make sure you read the docs for more info.
Good luck!
What you have is a good point to start from, however another good place to take a look at is the boilerplate registration form (this is not from the official Laravel project page because the boilerplates are optionally introduced and are not in the official repo by default).
There are a few improvements you can do based on this:
<div class="form-group">
<label for="text">{{__('Text')}}</label>
<input type="text" name="text" class="form-control{{ $errors->has('text') ? ' is-invalid' : '' }}" value="{{ old('text') }}"placeholder="Enter title"/>
</div>
The extras:
__('Text') will automatically translate Text based on the selected locale and available language assets.
{{ $errors->has('text') ? ' is-invalid' : '' }} will "decorate" the field with the bootstrap-4 error style if serverside validation failed (and therefore passed the $errors variable to the view)
{{ old('text') }} will pre-fill the input with the value that was previously filled in case the form failed validation and the user was redirected back to the same page.
This will help improve the user experience, however keep in mind these are all server-side tools (because Laravel is a server-side framework) so it's probably a better user experience to also add client-side checks and validation.
I am creating an API for Laravel. I use the PUT method for updating data.
I send data with Postman using the PUT method. In my controller, I got an empty array. How to access the passed data?
In my route, I have:
Route::put('vehicletypes/{id}','API\VehicletypeController#update');
In my controller:
public function update(Request $request, $id){
print_r($request->all()); exit;
}
How to get the data passed in PUT method?
You are getting empty response because PHP have some security restrictions against PUT. But Laravel have a workaround for this.
So, to solve this you have to send a POST request from Postman instead, with a POST param _method with value PUT. And that should work.
Laravel cheats because html forms only support GET and POST, but it does understand a real PUT/PATCH request.
The problem looks like lies in Symfony it can't parse the data if it's multipart/form-data, as an alternative try using x-www-form-urlencoded content disposition.
public function putUpdate(Request $request, $id){
print_r($request->all()); exit;
}
And change route too,
Route::put('vehicletypes/{id}','API\VehicletypeController#putUpdate');
Checked "x-www-form-urlencoded" instead of "form-data" under body tab in the Postman, the put methood will work as well...
Why nobody is giving clear explanation
at first put method field of
{{method_field('put')}}
as your router uri is that is displayed using command
php artisan router:list
of update method is put/patch so first add
{{method_field('put')}}
and field in your form should be the same
<form action="{{route('posts.update',$post->id)}}" method="post">
after adding the csrf_toke form will be working. and final shape would be as below of form.
<form action="{{route('posts.update',$post->id)}}" method="post" >
{{method_field('put')}}
<input type="hidden" name="_token" value="{{csrf_token()}}">
<!-- Name input-->
<div class="form-group">
<label class="col-md-3 control-label" for="name">Title</label>
<div class="col-md-9">
<input id="name" name="title" type="text" value="{{$post->title}}" class="form-control">
</div>
</div>
<!-- Message body -->
<div class="form-group">
<label class="col-md-3 control-label" for="body">
Body</label><br>
<div class="col-md-9">
<textarea class="form-control" id="message" name="body" rows="5">
{{$post->body}}
</textarea>
</div>
</div>
<!-- Form actions -->
<div class="form-group">
<div class="col-md-9 text-right col-md-offset-3">
<button type="submit" class="btn btn-success btn-lg">Update</button>
Cancel
</div>
</div>
</form>
Following link will resolve the issue to get the request form data plus the images.
If you are working on Laravel, you can easily parse and bind the form params in the \Illuminate\Http\Request Instance
Simply just get the ParseInputStream Class from the link below:
Class ParseInputStream.php
Create another Validation Rule Class in Laravel optional but not required,
class NoteUpdateRequest extends Request {
public function all($keys = null)
{
if(strtolower($this->getMethod())=='put' && preg_match('/multipart\/form-data/', $this->headers->get('Content-Type')) or
preg_match('/multipart\/form-data/', $this->headers->get('content-type')))
{
$result = [];
new ParseInputStream($result);
$result = array_merge($result, $this->route()->parameters());
$this->request->add($result);
}
return parent::all($keys);
}
public function rules()
{
dd($this->all());
return [
'noteId' => 'required|integer|exists:notes,id',
'title' => 'required|string|max:200',
'note' => 'required|string|min:10|max:2000'
];
}
}
I hope it resolved what you want to achieve, using PUT or PATCH method along with Form Params
As mentioned, this isn't a laravel (or symfony, or any other framework) issue, it's a limitation of PHP.
That said, I managed to find this PECL extension. I'm not very familiar with pecl, and couldn't seem to get it working using pear. but I'm using CentOS and Remi PHP which has a yum package.
I believe there are other packages in various flavours of linux and I'm sure anybody with more knowledge of pear/pecl/general php extensions could get it running on windows or mac with no issue.
I ran yum install php-pecl-apfd and it literally fixed the issue straight away (well I had to restart my docker containers but that was a given).
That is, request->all() and files->get() started working again with PATCH and PUT requests using multipart/form-data.
Ergo, I managed to get my api playing nicely with my front-end without adding any quirks (that would need to be relayed to anybody developing front-end solutions) or breaking RESTful conventions.
I'm new to laravel and still learning about this framework.
I already found some questions on stackoverflow but it still didn't work out for me.
My problem is:
I got this
localhost/codehub/public/users/create
and the route:
Route::get('users/create',['uses' => 'UserController#create']);
Inside the page there's some form like this:
so when I click create button it is supposed to route it into store function in the user controller
Route::post('users',['uses' => 'UserController#store']);
public function store(Request $request)
{
return $request->all();
}
so the problem is when I click that create button it always redirects me to localhost/users and because of that, I can't process my store function.
Any advice?
this is my form code:
<form method="post" action="/users">
<input type="text" name="name">
<input type="email" name="email">
<input type="password" name="password">
<input type="submit" value="Create">
</form>
The problem may be because of relative path in form action.
You should always use named routes which allow the convenient way of generation of URLs or redirects for specific routes.
So you can change your route as:
Route::post('users', 'UserController#store')->name('users.create');
And in form you can write as:
<form method="post" action="{{ route('users.create') }}">
I'm having a very frustrating (super-newbie) experience with Laravel 5.1.
Sure there must be something that I'm missing, but unfortunately I couldn't find anything on Laravel docs.
The problem is this (and I believe is even relatively simple): while all GET routes are working, the routes in POST are 'rerouting' me to the wrong place.
For instance, assuming that the controller is this:
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use View;
class PagesController extends BaseController {
public function hello(){
return view('hello');
}
public function register(){
//Registration rules
$inputData=array(
'name' => \Input::get('name'),
'email' =>\Input::get('email'),
'password' => bcrypt(\Input::get('password')),
);
createUser($inputData);
return view('stat');
}
private function createUser($inputData){
return User::create($inputData);
}
}
and given the route:
Route::get('/','PagesController#hello');
this one redirects me correctly to the view specified in the controller,at the method indicated.
A POST operation cannot be successfully performed, since
Route::post('/','PagesController#register');
with the form having:
<form action="/" method="post">
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
<label for="name">User Name</label><br/>
<input type="text" name="name" id="name"/><br/>
<label for="name">E-mail</label><br/>
<input type="text" name="email" id="email"/><br/>
<label for="password">password</label><br/>
<input type="password" name="password" id="password"/><br/>
<input type="submit" value="auth!"/>
</form>
results in redirecting me to xampp home page.
For example, the "main registration page" is at this url:
http://localhost:8080/laravel/project1/public/
(GET OK)
and when I click on the submit button, I'm sent to
http://localhost:8080/
Just few more indicators for you to try and help me (I'm genuinely stuck):
1) I didn't use a VirtualHost (searched on the web, but had always no luck in configuring apache properly...good luck I've got xampp)
2) The page "hello" has a link that I used as a test:
Link
and it redirects me correctly to the sought-after
http://localhost:8080/laravel/project1/public/stat
3)In the POST method, I've used a dd($inputData) to see what was going wrong, and as a result I had...nothing. Not a blank page,just always the localhost page. This led me to think that somehow the controller method isn't called, since no dd(---) result got in page.
Hope someone can help.
Many thanks
Your domain is http://localhost:8080 , so when you set action to '/' , it goes to root. It`s not good practice , but your solution is to change :
<form action="/laravel/project1/public/" method="post">
I`d create a virtual host for the project in apache , so document root would be /laravel/project1/public/ .
you are posting your form to the root / that is why you are being routed to xampp page. To solve this problem, change your form action to this
<form action="/post/my/form" method="post">
in your routes
Route::post('/post/my/form','PagesController#register');