custom Shopware6 route gives "405 Method Not Allowed" - php

I created a shopware6 plugin which includes a frontend custom route which should be able to receive POST requests from ExactOnline.
But when I make some tests with Postman, I receive "405 Method Not allowed".
Here is my controller :
<?php
namespace Emakers\TransmissionPlugin\Controller;
//use Emakers\TransmissionPlugin\Controller\Frontend\Services\ExactRequirements;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\Routing\Annotation\Route;
/**
* #RouteScope(scopes={"storefront"})
*/
class AccountsController extends StorefrontController
{
/**
* #Route("/accounts", name="frontend.accounts", options={"seo"="false"}, methods={"POST"})
*/
public function accounts()
{
die('ok boy');
$file = 'custom/plugins/TransmissionPlugin/Resources/webhooks/accountWebhook.txt';
}
}
When I replace the methods={"POST"} by methods={"GET"}, the same test request returns "ok boy" which is normal.
I had already created a plugin like this in Shopware5 and GET and POST requests were already working without doing anything special.
How to make POST requests ALLOW in my case on Shopware6?
Thanks !

You have limited the route to POST. When you call it from another Method then POST, it will result in Method not allowed error. Maybe you want to whitelist both GET and POST?
So change it to methods={"GET", "POST"}

Related

How do I restrict an auto-generated route to accept only POST requests?

We have overridden Sonata's RegistrationController using Easy Extends. In our generated appDevProjectContainerUrlMatcher class, we now have the following lines:
if ($pathinfo === '/password/reset') {
return array ( '_controller' => 'Application\\Sonata\\UserBundle\\Controller\\RegistrationController::passwordResetAction', '_route' => 'fos_user_password_reset',);
}
I am able to open my customized RegistrationController class and see the following:
/**
* #return RedirectResponse
*/
public function passwordResetAction()
{
...
}
Now the question: I want to make this action only accept POST requests. How do I do that if there is no route annotation already present? (I can't find anywhere where this route is being explicitly defined, excluding the auto-generated class mentioned above.)
===
Edit: This is in a Symfony 2.7 application.
you can verify if it's a Post request like :
if ($request->isMethod('post')) { // Uppercase request method:POST
// your code
}
the symfony 2.7 doc said
getMethod() Gets the request "intended" method.
may be you can try this also :
$request->getMethod()

Laravel Validation causes form to throw MethodNotAllowed error?

I'm pretty new to Laravel. I'm trying to create a form to post to a function in my controller. It works fine, exactly as expected, until I try to add in a custom request validation. As soon as I've added it, if I run the form again I get a MethodNotAllowed error. Can someone tell me what is going wrong?
edit** sorry I forgot to post the code.
The request I made is pretty simple. The authorize is set to return true.
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'campaign_name'=>'required',
'campaign_message'=>'required_without:campaign_link',
];
}
In the controller I'm calling the namespace for the request at the top and have the function using that request. The function works just fine when the regular laravel request is called rather than my custom one.
public function store(CreateCampaignRequest $request)
{
//do code here
}
My form is using this action to send the request.
{!! Form::open(['method'=>'POST',
'action'=>'OrganizationCampaignController#store'])!!}
and the route is set to this
Route::post('dashboard/campaigns/send','OrganizationCampaignController#store');
Like I said everything works when the normal Request is called, it only throws the method not allowed when I try using my custom request.
Thank you!

Prevent redirect to homepage after invalid in Laravel

I'm developing a RESTful API with Laravel 5.3, so I'm testing some functions and request with my controllers. One thing I need to do is validate the request that my user sends before add a field in my database, so, I use a custom FormRequest to validate it.
When I tested my API in Postman and send my invalid request, response redirect me to homepage. After reading documentation, I found the following statement
If validation fails, a redirect response will be generated to send the
user back to their previous location. The errors will also be flashed
to the session so they are available for display. If the request was
an AJAX request, a HTTP response with a 422 status code will be
returned to the user including a JSON representation of the validation
errors.
How can I prevent this? Or there is a AJAX mode in Postman? Any suggestion?
Also this can be achieved without overriding any function. Laravel is built to support both Json & normal pages.
Please change your settings in postman and set Accept to application/json like below
Laravel is SMART ;-)
Your custom FormRequest extends Illuminate\Foundation\Http\FormRequest. Within is a function that performs the redirect called response(). Simply override this function within your custom FormRequest to change how invalid validations are responded to.
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse;
class CustomFormRequest extends FormRequest
{
/**
* Custom Failed Response
*
* Overrides the Illuminate\Foundation\Http\FormRequest
* response function to stop it from auto redirecting
* and applies a API custom response format.
*
* #param array $errors
* #return JsonResponse
*/
public function response(array $errors) {
// Put whatever response you want here.
return new JsonResponse([
'status' => '422',
'errors' => $errors,
], 422);
}
}
I faced same problem in Laravel 8. In your request class, you can override failedValidation method.
<?php
...
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
class RegisterRequest extends FormRequest
{
...
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json(['errors' => $validator->errors()], 422));
}
...
}

How can allow the method in routes using laravel 5?

I'm trying to execute the method but it does not working. I know it is very basic and may be ask more time, but i didn't resolve.
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class LockController extends Controller {
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function index()
{
return view('lock');
}
public function login()
{
return view('login');
}
}
?>
Route
Route::get('/lock', 'LockController#index');
Route::get('/lock', 'LockController#login');
This Route::get('/lock', 'LockController#index'); route working fine using this http://localhost/laravelDev/public/index.php/lock url but another route does not working properly and i'm getting this error NotFoundHttpException in RouteCollection.php line 161:. For login method i'm using this url http://localhost/laravelDev/public/index.php/lock/login.
I searched about it, i follow the instruction of this accepted answer but it does not work, can any one guide me where i'm wrong.
You can mention the required methods which will be handled in controller file(s) in routes.php file.
Example:
Route::get('url/of/the/resource', 'controllername#action'); (o handle 'GET' requests).
Route::post('url/of/the/resource', 'controllername#action'); (For 'POST' requests).
Details:
Route::get('/user/register', 'UserController#showRegistrationForm');
This indicates to show a registration from when given url (When GET request is made) is given like below:.
http://localhost/your_laravel_project_folder/user/register
Route::post('/user/register', 'UserController#handleUserRegistration');
This indicates to handle the registration from data when user submits the registration form. (When POST request is made).
class UserController extends Controller
{
public function showRegistrationForm()
{
return view('User.register');
}
public function handleUserRegistration()
{
$registerInput = Input::all();
var_dump($registerInput);
}
}
You have two identicals routes for different methods? I don't think that should work.
I could work if one was get and the other post.
Also, usualy, the url is would be http://localhost/lock or http://localhost/lock/login. The public/index.php shouldn't be necessaire.
Change the second route to this, pretty sure it'll work:
Route::get('/lock/login', 'LockController#login');

Symfony2 Check Route on Db

one question about Symfony2 and the routes.
In my routing file i have this route:
offers_category:
pattern: /offers/{category}
defaults: { _controller: MyBundle:Offers:category}
In this way i can call any url and all of them will respond with an 200 (HTTP CODE).
The categories list is dynamic, inserted by an admin panel (created with Sonata) and saved on db.
I would like to check if the "category" exist and then respond with 200 or 404.
There is a way to tell to Symfony2 (in the route file) the dictionary available for the placeholder?
I think that i have to check inside my controller calling a query on db, but i hope to find a better or cleaned solution.
Thanks all
I found the solution!
Thanks to #lenybernard for the precious advice on his post.
With the #lenybernard solution i was able to configure a route with an indexed field like:
www.sitename.com/offers/1
but i needed a url like:
www.sitename.com/offers/travel
and to do that i used this method to mapping a label not indexed to an url:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use NameProject\MyBundle\Entity\Category;
/**
* #Route("/offers/{category}")
* #ParamConverter("type", class="NameProjectMyBundle:Category", options={"mapping": {"category": "name"}})
*/
...and everthing works!
There is a simple and nice way called ParamConverter to do but there is nothing to do in the routing file directly (furthermore this is not its role) and you're right, this is ControllerSide :
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use My\Bundle\MyBundle\Entity\Offers\Category;
class OffersController
{
/**
* #param Category $category
* #ParamConverter("category", class="MyBundle:Offers/category")
*/
public function showAction(Category $category)
{
...
}
}
As said in the documentation, several things happen under the hood:
The converter tries to get a MyBundle:Offers/category object from the
request attributes (request attributes comes from route placeholders
-- here id); If no Category object is found, a 404 Response is generated; If a Category object is found, a new category request attribute is defined
(accessible via $request->attributes->get('category')); As for other
request attributes, it is automatically injected in the controller
when present in the method signature. If you use type hinting as in
the example above, you can even omit the #ParamConverter annotation
altogether because it's automatic :
So you just have to cast the variable and the param converter will throw a 404 automatically, cool right ?
use My\Bundle\MyBundle\Entity\Offers\Category;
class OffersController
{
/**
* #param Category $category
*/
public function showAction(Category $category)
{
...
}
}

Categories