Skip to content

(Thoughts?) Feature - Allow users to Specify their own Http Classes Easily#1850

Closed
Raistlfiren wants to merge 5 commits into
slimphp:3.xfrom
Raistlfiren:feature-seperate-request-classes
Closed

(Thoughts?) Feature - Allow users to Specify their own Http Classes Easily#1850
Raistlfiren wants to merge 5 commits into
slimphp:3.xfrom
Raistlfiren:feature-seperate-request-classes

Conversation

@Raistlfiren

Copy link
Copy Markdown

The problem - Currently, you are limited to using Slims classes to parse requests for the Uri, Headers, Cookies, and UploadedFiles. https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Request.php#L139

Solution - Allow the user to specify the class they want to use in order to handle the request type in the settings file. For example, a user declares the setting => 'uploadedFileClass' => '<Their new UploadedFileClass>', then the users class will be used instead of the default.

Now users can go about extending the UploadedFile class and adding methods that they want.

I did break all tests, just curious if anyone else wanted the same functionality

@JoeBengalen

Copy link
Copy Markdown
Contributor

Slim is psr7 compliant, you can easily use a different http implementation.

@Raistlfiren

Copy link
Copy Markdown
Author

I am mostly just wanting to extend off of the default classes and add my own methods. Is there an easy way to go about doing that?

@JoeBengalen

Copy link
Copy Markdown
Contributor

Just overwrite the request and response factories in the container.

Or you could call the process and respond methods of App instead of run

@geggleto

Copy link
Copy Markdown
Member

👎 you can already do this by doing what @JoeBengalen said.
Slim accepts any PSR-7 compatible Request/Response strategy.

I am mostly just wanting to extend off of the default classes and add my own methods. Is there an easy way to go about doing that?

Currently, there is no easy way.

@Raistlfiren

Copy link
Copy Markdown
Author

True, but that is a lot of work to just add a few methods to the UploadedFile class. For instance, my scenario is say I want to add the method getExtension to UploadedFile or maybe I want to use Symfony's UploadedFile class. There isn't an easy way of switching that out without overwriting the whole request object. Should it really be that hard to do that?

@Raistlfiren

Copy link
Copy Markdown
Author

Currently, there is no easy way.

Exactly, this would enable us to overwrite that class easily.

@geggleto

Copy link
Copy Markdown
Member

It's on the roadmap :)

@Raistlfiren

Copy link
Copy Markdown
Author

but bUT BUT, I neeeeeed it now ;)

@geggleto

Copy link
Copy Markdown
Member

@Raistlfiren you can extend the Slim objects and place them into the container after you create the $app object then :)

@akrabat

akrabat commented Apr 20, 2016

Copy link
Copy Markdown
Member

I'm missing what the problem is. Just create some middleware:

$app->add(function ($request, $response, $next) {

    $uploadedFiles = MyUploadedFilesObject::createFrom($_FILES);
    $request = $request->withUploadedFiles($uploadedFiles);

    return $next($request, $response);
});

@Raistlfiren

Copy link
Copy Markdown
Author

@akrabat I suppose my problem/annoyance is that I can't override the default classes without replacing the Request object in the container or using middleware.

@Raistlfiren

Raistlfiren commented Apr 20, 2016

Copy link
Copy Markdown
Author

The problem with using the middleware as you displayed is that you are not only executing the previous UploadedFiles code/class as well, but now you are using your own class to parse $_FILES. In essence you are duplicating code with that middleware.

---Edit---
In this instance the middleware would be a hack in order to resolve a bigger problem, right?

@akrabat

akrabat commented Apr 20, 2016

Copy link
Copy Markdown
Member

In that case, you just have to override createFromEnvironment:

class MyUploadedFile extends UploadedFile
{
}

class MyRequest extends Request
{
    public static function createFromEnvironment(Environment $environment)
    {
        $method = $environment['REQUEST_METHOD'];
        $uri = Uri::createFromEnvironment($environment);
        $headers = Headers::createFromEnvironment($environment);
        $cookies = Cookies::parseHeader($headers->get('Cookie', []));
        $serverParams = $environment->all();
        $body = new RequestBody();
        $uploadedFiles = MyUploadedFile::createFromEnvironment($environment);

        $request = new static($method, $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles);

        if ($method === 'POST' &&
            in_array($request->getMediaType(), ['application/x-www-form-urlencoded', 'multipart/form-data'])
        ) {
            // parsed body must be $_POST
            $request = $request->withParsedBody($_POST);
        }
        return $request;
    }
}

$settings = [
    'settings' => [
        'displayErrorDetails' => true,
    ],
    'request' => function ($c) {
        return MyRequest::createFromEnvironment($container->get('environment'));
    },
];
$app = new \Slim\App($settings);

@Raistlfiren

Copy link
Copy Markdown
Author

@akrabat Absolutely, which does work just fine. I am just proposing that we get rid of this step and allow users to define their own MyUploadedFile class.

@akrabat

akrabat commented Apr 20, 2016

Copy link
Copy Markdown
Member

The ability to override a specific class within the Http classes via settings is not going to be accepted in Slim 3. This may change in Slim 4 when we look to create a base pure PSR-7 implementation with our enhancements in a separate system.

@akrabat

akrabat commented Apr 20, 2016

Copy link
Copy Markdown
Member

@akrabat Absolutely, which does work just fine. I am just proposing that we get rid of this step and allow users to define their own MyUploadedFile class.

From my point of view, I don't want the additional complexity for a rare situation the can be handled by a 23 line class.

Sorry.

@Raistlfiren

Copy link
Copy Markdown
Author

@akrabat Is that really all that complex? In my sample, which I know is incomplete, allows you to do what I am asking for in a few lines of code. It requires the static build method to look for that unique setting and call a different class.

There aren't to many classes that you need to override with Slim 3. Most of them can be overwritten pretty easily like the Request object that you displayed. Those Http classes are just more difficult because they are called statically.

@codeguy codeguy mentioned this pull request Apr 20, 2016
@akrabat

akrabat commented Apr 20, 2016

Copy link
Copy Markdown
Member

I've added a note to #1686 about this issue for when we design Slim\Http for 4.0.

@akrabat akrabat closed this Apr 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants