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

Request parameter PathLocation #46

Closed
bonndan opened this issue Sep 10, 2014 · 4 comments
Closed

Request parameter PathLocation #46

bonndan opened this issue Sep 10, 2014 · 4 comments

Comments

@bonndan
Copy link
Contributor

bonndan commented Sep 10, 2014

I have to retrieve a REST subresource at /foo/{id}/bars?someParam=baz, i.e. the path contains a parameter. QueryLocation does not help here, so how can I send the proper query?

My plan is to add a PathLocation to the PrepareRequest subscriber, but how?

class PathLocation extends AbstractLocation
{
    public function visit(
        GuzzleCommandInterface $command,
        RequestInterface $request,
        Parameter $param,
        array $context
    ) {
        $value = $this->prepareValue(
            $command[$param->getName()],
            $param
        );
        $this->replaceParam($request, $param->getWireName(), $value);
    }

    public function after(
        GuzzleCommandInterface $command,
        RequestInterface $request,
        Operation $operation,
        array $context
    ) {
        $additional = $operation->getAdditionalParameters();
        if ($additional && $additional->getLocation() == $this->locationName) {
            foreach ($command->toArray() as $key => $value) {
                if (!$operation->hasParam($key)) {
                    $this->replaceParam($request, $key, $this->prepareValue(
                        $value,
                        $additional
                    ));
                }
            }
        }
    }

    private function replaceParam(RequestInterface $request, $name, $value)
    {
        $path = str_replace('{' . $name . '}', $value, $request->getPath());
        $request->setPath($path);
    }
}
@bonndan
Copy link
Contributor Author

bonndan commented Sep 10, 2014

Meanwhile I have a workaround:

$emitter = $this->client->getEmitter();
        foreach ($emitter->listeners() as $listeners)
        {
            foreach ($listeners as $listener)
            {
                if ($listener[0] instanceof PrepareRequest)
                {
                    $emitter->detach($listener[0]);
                    $emitter->attach(new PrepareRequest(array("path" => new PathLocation('path'))));
                    break;
                }
            }
        }

with the following PathLocation implementation (using underscores for the placeholder)

namespace XYZ;

use GuzzleHttp\Command\Guzzle\Parameter;
use GuzzleHttp\Message\RequestInterface;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\GuzzleCommandInterface;
use GuzzleHttp\Command\Guzzle\RequestLocation\AbstractLocation;

/**
 * Inserts url path parameters.
 *
 */
class PathLocation extends AbstractLocation
{
    public function visit(
        GuzzleCommandInterface $command,
        RequestInterface $request,
        Parameter $param,
        array $context
    ) {
        $value = $this->prepareValue(
            $command[$param->getName()],
            $param
        );
        $this->replaceParam($request, $param->getWireName(), $value);
    }

    public function after(
        GuzzleCommandInterface $command,
        RequestInterface $request,
        Operation $operation,
        array $context
    ) {
        return;
        $additional = $operation->getAdditionalParameters();
        if ($additional && $additional->getLocation() == $this->locationName) {
            foreach ($command->toArray() as $key => $value) {
                if (!$operation->hasParam($key)) {
                    $this->replaceParam($request, $key, $this->prepareValue(
                        $value,
                        $additional
                    ));
                }
            }
        }
    }

    private function replaceParam(RequestInterface $request, $name, $value)
    {
        $path = str_replace('_' . $name . '_', $value, $request->getPath());
        $request->setPath($path);
    }
}

@mtdowling
Copy link
Member

You can just use the uri template functionality of Guzzle and set the location of the parameter to "uri".

@bonndan
Copy link
Contributor Author

bonndan commented Sep 14, 2014

Many thanks, that fixed it. No code necessary. Since I have been (and still am) too dumb to find the proper place in the documentation, I quickly hacked the readme.

#48

mtdowling added a commit that referenced this issue Sep 15, 2014
Update readme to improve documentation (#46)
@bonndan
Copy link
Contributor Author

bonndan commented Sep 15, 2014

Thanks again. I'm closing this.

@bonndan bonndan closed this as completed Sep 15, 2014
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

No branches or pull requests

2 participants