jenssegers / lean

Use the PHP League's Container package with auto-wiring support as the core container in Slim 3
31 stars 5 forks source link

Url attributes not coming through #9

Closed fastsol closed 5 years ago

fastsol commented 5 years ago

I can't seem to get any of the url parameters to come through in a controller or route. I have switched everything over from a base Slim project that was previously working. I have not changed the routes or controllers other than adding the Request and Response type to the method signatures.

It appears that the traditional way of using $args is not working as it gives this error: Fatal error: Uncaught League\Container\Exception\NotFoundException: Unable to resolve a value for parameter (args) in the function/method (__invoke) in D:\rsleagueslim\vendor\league\container\src\Argument\ArgumentResolverTrait.php on line 78

This error happens even using your basic example in your Docs. I have tried using the other Slim ways to get the attributes by using $request->getAttribute('xyz'); and $request->getAttributes(); Both those methods return empty. Here is another example route and controller I had previously that no longer sees the attribute in the url.

class CheckOutController extends BaseController
{
    public function index(Request $request, Response $response)
    {
        $customer = $this->Customer->with(['jobs', 'sheets'])->find($request->getAttribute('customer'));

        if(!$customer || !$customer->sheets->get(0) || count($customer->sheets) > 1)
        {
            return redirect('home');
        }

        $employees = auth()->employees()->get();
        $radios = $customer->sheets->get(0)->subscribed_fields;

        return $this->twig->render($response, 'services/checkout.twig', $this->sendToView(['customer' => $customer, 'employees' => $employees, 'radios' => $radios]));
    }
}

And route which is inside a route group. $this->get('/checkout/customer/{customer: [0-9]+}', CheckOutController::class.':index')->setName('checkout.index');

fastsol commented 5 years ago

I figured out how to get the url attribute, the example code is wrong though. It appears you need to assign a variable to the same name that you called the parameter in the route. So in my example above, my route has it as "customer", so in the index() I would need to do: public function index(Request $request, Response $response, $customer) to access it. I guess that works for simple routes, but it really would be helpful to have the $request->getAttribute() and getAttributes() functions working.

When I do a dump on the $request in the controller index() the queryParams is null and the attributes are also empty. I even tried adding a ?test=something to the url and still shows empty.

jenssegers commented 5 years ago

Will check it out!

fastsol commented 5 years ago

Cool, I'm pretty much stuck until you tell me if there is a fix.

jenssegers commented 5 years ago

Looks like this is because of the new method inflection strategy. Wondering if I should disable it by default again...

With method injection, the request/response objects are fetched straight from the container. So adjusting them and placing them back on the container is a bit "hacky" actually.

fastsol commented 5 years ago

What exactly would we lose if you disabled it? Examples would be helpful.

jenssegers commented 5 years ago

Method injection allows you to use type-hinted injection on your controller methods. Similar to Laravel:

public function index(Request $request, Something $foo) {
...
}

Could disable this by default and allow it to be enabled with a setting.

jenssegers commented 5 years ago

I pushed a new version to master with method injection disabled by default. Also updated the documentation for both versions.

Although I'm not entirely sure if disabling method injection by default is the best solution... Feels like we're missing out on the power of the league container with this.

jenssegers commented 5 years ago

Scratch that, I enabled method injection again but now with the getAttribute support on the request object.

There is now also a setting to disable this feature.

jenssegers commented 5 years ago

Try the latest version, should be fixed!