Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect HTTP method causes error #2467

Closed
simonhamp opened this issue Nov 26, 2019 · 2 comments
Closed

Incorrect HTTP method causes error #2467

simonhamp opened this issue Nov 26, 2019 · 2 comments

Comments

@simonhamp
Copy link

@simonhamp simonhamp commented Nov 26, 2019

Describe the bug
When using add-on URLs that respond to a specific HTTP method (e.g. /!/MySexyAddon/SomeMethod => MySexyAddon\MySexyAddonController@postSomeMethod), any other HTTP method used to call that URL will cause an error.

To Reproduce
Steps to reproduce the behavior:

  1. Create an addon
  2. Create a POST method in the addon
  3. Call the URL for that method using a GET request in your browser
  4. See error

Expected behavior
I expect either a 404 or a 405 error.

Environment details (please complete the following information):

  • Statamic Version 2.11.9
  • OS: macOS 10.14.6
  • Browser: chrome
  • Web Server: Valet
  • PHP Version: 7.3
  • Addons installed: any
@simonhamp

This comment has been minimized.

Copy link
Author

@simonhamp simonhamp commented Nov 26, 2019

I've managed to patch this by changing the following methods in Statamic\Http\Controllers\StatamicController. Obviously would be better if this was in the core:


    /**
     * Call an addon's controller method and inject any dependencies
     *
     * @param string $name
     * @param string $method
     * @param array $parameters
     * @return mixed
     */
    private function callControllerMethod($name, $method, $parameters)
    {
        $studly = Str::studly($name);
        $method = strtolower($this->request->method()) . Str::studly($method);
        $namespace = "Statamic\\Addons\\$studly\\";
        $params = $parameters ?: [];

        // First check the root level controller, named after the addon.
        // eg. Statamic\Addons\AddonName\AddonNameController
        if (class_exists($rootClass = $namespace . "{$studly}Controller") && method_exists($rootClass, $method)) {
            return app()->call($rootClass.'@'.$method, $params);
        }

        // Next, check the controller namespace, still named after the addon.
        // eg. Statamic\Addons\AddonName\Controllers\AddonNameController
        if (class_exists($namespacedClass = $namespace."Controllers\\{$studly}Controller") && method_exists($namespacedClass, $method)) {
            return app()->call($namespacedClass.'@'.$method, $params);
        }
    }

    /**
     * Fire an event
     *
     * @param string  $namespace   URL segment 1
     * @param string  $event       URL segment 2
     * @param array   $parameters  Additional data
     * @return \Illuminate\Http\Response
     */
    private function fireEvent($namespace, $event, $parameters = [])
    {
        $response = array_get(Event::fire("{$namespace}.{$event}", $parameters), 0);

        // If a view has been returned from an event, we want to render it.
        if ($response instanceof \Illuminate\Contracts\View\View ||
            $response instanceof \Illuminate\Http\RedirectResponse ||
            $response instanceof \Illuminate\Http\Response
        ) {
            return $response;
        }
    }
@simonhamp

This comment has been minimized.

Copy link
Author

@simonhamp simonhamp commented Jan 10, 2020

@jasonvarga Thanks for applying a fix for this!

Just a note for others who may come across this later: the fix behaves as expected when APP_DEBUG=false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.