No route found for POST ... : Method Not Allowed (Allow: PUT) - php

Currently, I am updating the system running on the existing Symfony 2.3 (currently 3.0.9), and checking the operation.
When I tried to change the state of an item to the selected state, I got an error.
Do you have any advice for determining the case?
Error Code
No route found for "POST /admin/hq/article/3999/articleStatus":
Method Not Allowed (Allow: PUT)
Code
ArticleController.php
/**
* Article status change
*
* #Method("PUT")
* #Route("/article/{ids}/articleStatus")
* #Secure(roles="ROLE_HQ_MANAGE")
*/
public function updateArticleStatusAction(Request $request, $ids)
{
return parent::updateArticleStatusAction($request, $ids);
}
Version
CentOS 6.7
PHP 5.6
Symfony3.0.9

I'm guessing you are using a web browser to submit a form and the action goes to /admin/hq/article/3999/articleStatus which only allows PUT operations (because of the #Method("PUT") annotation). Wheras submitting a form with a browser is a POST operation. Change that line to #Method("POST") and you should be fine.

Go vendor/symfony/http-foundation/Request.php and check line 80 in Symfony 6.2 and change this value from false to true
protected static $httpMethodParameterOverride = true;

Related

Laravel 5.1 - errors views on live website, which ones or one for all and how to implement?

I'm building a Laravel app and everything is working fine (as far as I can see) and now I would like to make the website public.
However I can't figure out how to implement custom messages for bad/unauthorized request.
I know I can put views in /resources/views/errors/ folder like:
404.blade.php
503.blade.php
... and so on.
However I'm not sure for which errors should I build views or is there a simpler way to make one main view for all errors. There is no reason to notify user which error occurred but if it can be done easily I would go that way.
Here is the list of all errors that I just Googled:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Here is the Laravel 5.1 error documentation:
http://laravel.com/docs/5.1/errors
I tried changing the file /app/Exceptions/Handler.php and in it function
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
return parent::render($request, $e);
}
to
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
return view('errors.allerrors'); // only this line is changed
}
but that only returns empty page.
Thanks.
I will leave this as a partial answer in case someone ends up here with the same problem.
The answer will not redirect all errors to the same page but will handle most of the errors, as far as I can tell.
Add these files to the /resources/views/errors/ folder:
401.blade.php - this page will be shown if user is not authorized to access the webpage (when you are using some kind of user authentification)
404.blade.php - this page will be shown if user writes url that you haven't declared in your /app/Http/routes.php file
503.blade.php - this page will be shown when your site is down, ie. when you run the php artisan down command
There is still one error page that I don't know how to hadle, better say, I don't know its error number. It shows when an user tries to access the model instance (I don't know the right terminology here so please correct me) that doesn't exist. In example; if an user tries to acces yourwebsite.com/articles/123 but you don't have article with that id/slug in your db you will still get an whoops... message.
I am not completely satisfied with this solution, since there might be other errors I wasn't able to produce, but it's best/only solution I have.

TYPO3 6.2: "Could not find a suitable type converter for "String" " exeption after update

TYPO3 was from a very old version updated to TYPO3 6.2. The most things are working now, but I have one own written extension that give me the following error:
Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1297759968: Exception while property mapping at property path "":Could not find a suitable type converter for "String" because no such class or interface exists. | TYPO3\CMS\Extbase\Property\Exception thrown in file /srv/vhosts.d/typo3_src-6.2.9/typo3/sysext/extbase/Classes/Property/PropertyMapper.php in line 106.
I have a list Method in one of the controller that generates a link:
<f:link.action action="show" arguments="{id : course.id}"> {course.name}</f:link.action>
This list method works, but when I want to open this generated link in the website I get the error from above.
I delete all stuff in the showAction method and also change the template to a basic output without special things. The method looks than like this:
/**
* action show
*
* #param String Course-Id
* #return void
*/
public function showAction($id){
}
But the error is still there. I have absolutely no idea anymore what is the problem. It would be great when someone have a different view and properly have some ideas where I can try to find out what the problem really is.
I think it needs to be
/**
* action show
*
* #param string $id Course-Id
* #return void
*/
public function showAction($id){
}
string lowercase and the argument $id must be specified as well
I want to share my solution way:
The first problem was that I don't know that there is a new way to delete the cache of the core. That I find out because of Jost comment in my answer with the "clear the cache from install tool". So I go in the Backend of Typo3 to edit a user and edit there my own under Options the TSconfig field. I add there a row with options.clearCache.system = 1. Now I can clear the system core over the flash symbol in the Backend of Typo3.
After that I try to change the #param String in #param string. I deleted the core cache and then I got a different error. I found out that this new error say that only arrays or objects are as parameters are allowed in the action method (See: http://wiki.typo3.org/Exception/CMS/1253175643).
So I deleted the parameter and follow the instruction on the website where the error is explained. So my new method looks as follow:
/**
* action show
*
* #return void
*/
public function showAction(){
if ($this->request->hasArgument('id')) {
$id= $this->request->getArgument('id');
}
// Do stuff with the id
}
And that works now :)

In Laravel 5, why is Request::root() different when called during phpunit test?

I defined a test which tests the creation of a user. The controller is set to redirect back to the same page on error (using validation through a generated App\Http\Requests\Request). This works correctly when manually clicking in a browser, but fails during a test. Instead of being redirected to:
http://localhost/account/create
The test redirects to (missing a slash):
http://localhostaccount/create
Neither of these urls are what I have setup in the .htaccess or in the $url variable in config/app.php. Which is (On OSX Yosemite):
http://~username/laravel_projects/projectname/public
I finally pinpointed the issue to have something to do with how the result of Request::root() is generated. Making a call to this outside of a test results in the expected value defined in .htaccess and $url. Inside the test it results in:
http://localhost
What configuration needs to change in order to get this function to return the correct value in both contexts?
I should also mention I made the painful upgrade from Laravel 4 to the current version 5.0.27.
****** UPDATE *******
I was able to figure out an acceptable solution/workaround to this issue!
In Laravel 5, FormRequests were introduced to help move validation logic out of controllers. Once a request is mapped to the controller, if a FormRequest (or just Request) is specified, this is executed before hitting the controller action.
This FormRequest by default handles the response if the validation fails. It attempts to construct a redirect based on the route you posted the form data to. In my case, possibly related to an error of mine updating from Laravel 4 to 5, this default redirect was being constructed incorrectly. The Laravel System code for handling the response looks like this:
/**
* Get the proper failed validation response for the request.
*
* #param array $errors
* #return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
if ($this->ajax() || $this->wantsJson())
{
return new JsonResponse($errors, 422);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
Notice how the returned redirect is NOT the same as calling Redirect::route('some_route'). You can override this response function by including use Response in your Request class.
After using Redirect::route() to create the redirect, the logic in my tests passed with the expected results. Here is my Request code that worked:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\Request;
use Response;
class AccountRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'email' => 'required|max:50|email|unique:users',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password'
];
}
public function response(array $errors){
return \Redirect::route('account_create');
}
}
The important part is that I called Redirect::route instead of letting the default response code execute.
Override the response function in the FormRequest validation handler to force the redirect to be constructed with Redirect::route('named_route') instead of allowing the default redirect.
You need to change config/app.php file's url value. Default value is http://localhost
Doc from config/app.php
This URL is used by the console to properly generate URLs when using the Artisan command line tool. You should set this to the root of your application so that it is used when running Artisan tasks.
I know this isn't an exact answer to your question since it is not a configuration update that solves the problem. But I was struggling with a related problem and this seems to be the only post on the internet of someone dealing with something similar - I thought I'd put in my two cents for anyone that wants a different fix.
Please note that I'm using Laravel 4.2 at the moment, so this might have changed in Laravel 5 (although I doubt it).
You can specify the HTTP_HOST header when you're testing a controller using the function:
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
To specify the header just provided the $server variable as an array like so:
array('HTTP_HOST' => 'testing.mydomain.com');
When I did the above, the value produced for my Request::root() was http://testing.mydomain.com.
Again, I know this isn't a configuration update to solve you're issue, but hopefully this can help someone struggling with a semi-related issue.
If you tried changine config/app.php and it did not help.
it is better to use $_ENV - global variable in phpunit.
say, you want Request::root() to return 'my.site'
but you cannot touch phpunit.xml
you can simply set an env param like so
$_ENV['APP_URL'] = 'my.site';
and call $this->refreshApplication(); in your unittest.
viola, your request()->root() is giving you my.site now.

symfony2 phpunit - functional testing error (host_with_path)

So thanks to Matteo (phpunit in symfony2 - No tests executed) I can now test my functional tests.
Now I got the following error when running phpunit -c app:
You must change the main Request object in the front controller (app.php)
in order to use the `host_with_path` strategy.
so I did change it in the app.php, from:
$request = RequestFactory::createFromGlobals('host_with_path');
to:
$request = Request::createFromGlobals();
I also updated my swiftmailer-bundle from version 2.3 to 5.4.0.
Unfortunately This did not fix my error.
and this is my ../app/config_test.yml
swiftmailer:
disable_delivery: true
Am I missing something here?
I cannot seem to find this error anywhere on the web. Does someone know how I should fix this error?
After some searching I noticed that the app.php wasn't the problem. It was the DefaultControllerTest.php. The error could be fixed by removing the following lines from the DefaultControllerTest:
$crawler = $client->request('GET', '/hello/Fabien');
$this->assertTrue($crawler->filter('html:contains("Hello Fabien")')->count() > 0);
Due to recent developments our development team decided to stop using Sonata. As a side effect this bug got fixed. So I won't have a solution for this problem.
The problem here is, that the Client object is using neither app.php nor app_dev.php.
The client creates the request internally. So it won't be the request you need.
The only solution I can see is to override the method Symfony\Bundle\FrameworkBundle\Test\WebTestCase::createClient to return your own client. This client is than responsible for creating the actual request object. The following is the current behavior.
namespace Symfony\Component\HttpKernel;
use Symfony\Component\BrowserKit\Client as BaseClient;
class Client extends BaseClient
{
...
/**
* Converts the BrowserKit request to a HttpKernel request.
*
* #param DomRequest $request A DomRequest instance
*
* #return Request A Request instance
*/
protected function filterRequest(DomRequest $request)
{
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
$httpRequest->files->set($key, $value);
}
return $httpRequest;
}
...
}
You have to override method filterRequest to return kind of a request you want.

Laravel resource controller testing gives NotFoundHttpException the second time

I am encountering a very strange thing while doing testing with Laravel 4. It looks like a bug but there's probably a logical explanation.
I have replicated the "bug" in a clean Laravel install and here's my code:
My resource controller /app/controllers/TestController.php:
(Created with php artisan controller:make TestController)
class TestController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return Response::json(array());
}
// The end of the file is unchanged
In my app/routes.php:
Route::get('/', function()
{
return View::make('hello');
});
// Note the composed part of the URL.
// My problem isn't present if I just use `myapi` or `path` as a url
Route::resource('myapi/path', 'TestController');
Added in /app/test/ExampleTest.php:
public function testTest()
{
$res = $this->call('GET', 'myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', 'myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
Now I run phpunit and here's what I get:
There was 1 error:
1) ExampleTest::testTest
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/laraveltest/bootstrap/compiled.php:5531
/home/me/Web/laraveltest/bootstrap/compiled.php:4848
/home/me/Web/laraveltest/bootstrap/compiled.php:4836
/home/me/Web/laraveltest/bootstrap/compiled.php:4828
/home/me/Web/laraveltest/bootstrap/compiled.php:721
/home/me/Web/laraveltest/bootstrap/compiled.php:702
/home/me/Web/laraveltest/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/laraveltest/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
/home/me/Web/laraveltest/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/laraveltest/app/tests/ExampleTest.php:25
In my other project I get a slightly different backtrace, but I have the impression that's the same problem: (but I have no idea of why the other is compiled and this one not)
2) UnitModelTest::testOther
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:148
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1049
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1017
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:996
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:775
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:745
/home/me/Web/my-project/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/my-project/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:327
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/my-project/app/tests/UnitModelTest.php:32
In both case the line given in the trace for the test file corresponds to the second call of the test.
As I noted in the comments of the routes.php file, if I use a simple url with no slash, the test passes without problem.
I have no problem when I use the api from the browser.
I found many topics related to the NotFoundHttpException on StackOverflow, but none looks like mine. This one is specifically present when testing and only trigger an error at the second call.
So what am I doing wrong here ? Or is it really a bug ?
The problem is that calls made with the same client will use the provided URI relatively. That means what you actually call is:
myapi/path
myapi/myapi/path
You can fix this if you add a preface the urls with a / to make them absolute to the root of the application.
public function testTest()
{
$res = $this->call('GET', '/myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', '/myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
If you experience other issues like that it often helps to call
$this->refreshApplication();
(This would also create a new client and therefore solve this issue as well)
In my case this error happened because i change public directory name to public_html my solution was put this in the \App\Providers\AppServiceProvider register method.
public function register()
{
// ...
$this->app->bind('path.public', function() {
return base_path('public_html');
});
}

Categories