soap-client icon indicating copy to clipboard operation
soap-client copied to clipboard

Documentation needed for ClientMethodAssembler, ClientContext, ClientMethodContext

Open GaryJones opened this issue 8 years ago • 3 comments

I can see that ClientMethodAssembler, ClientContext and ClientMethodContext classes exist, but there is no relevant documentation about them on the Assemblers docs or Custom Rules docs.

GaryJones avatar Dec 29 '17 16:12 GaryJones

My use case (which I've not figured out yet):

The generate:client gives me the following:

public function demoSetup(\GAA\CorpManagerApi\SoapTypes\DemoSetup $DemoSetup) : \GAA\CorpManagerApi\SoapTypes\DemoSetupResponse
{
    return $this->call('DemoSetup', $DemoSetup);
}

public function demoSetupGain(\GAA\CorpManagerApi\SoapTypes\DemoSetupGain $DemoSetupGain) : \GAA\CorpManagerApi\SoapTypes\DemoSetupGainResponse
{
    return $this->call('DemoSetupGain', $DemoSetupGain);
}

But I need those two "demoSetup" methods to be consolidated as per my manually created (and working) client, and a new method (and ideally documentation for each method) added:

    /**
     * Setup demo.
     *
     * @param RequestInterface $request
     *
     * @return DemoSetupResult|ResultInterface
     * @throws \Phpro\SoapClient\Exception\SoapException
     */
    public function demoSetup(RequestInterface $request)
    {
        return $this->call($this->getClassName($request), $request);
    }

    /**
     * Get the name of a class, without its namespace.
     *
     * @param RequestInterface $request
     *
     * @return string
     */
    private function getClassName(RequestInterface $request): string
    {
        $classname = \get_class($request);
        $pos = strrpos($classname, '\\');
        if ($pos) {
            return substr($classname, $pos + 1);
        }

        return $request;
    }

(That allows a consistent API to the Client, and it's the Request object passed to it which determines what is actually called).

An example in the documentation of how to setup rules in the code generation config to apply the above would be wonderful!

GaryJones avatar Dec 29 '17 16:12 GaryJones

The current implementation of the generate:client is mostly targeted to generate basic client code which can be customized afterwards.

The case you mention probably won't be possible without writing some custom assemblers or rules. At the moment you can assemble in ClientMethodContext. Currently the ClientContext doesn't trigger the rules to assemble. This is a rather easy enhancement.

Currently we don't have access to the soap function description since we are using the built-in SoapClient::__getFunctions method.

veewee avatar Dec 29 '17 18:12 veewee

Here's what I've got which I think is working:

Config:

->addRule(new ClientMethodMatchesRule(
	new AssembleRule(new ConsolidatedClientMethodAssembler()),
	'/^(demoSetup|thirdPartySubscribe)$/'
))

->addRule(new ClientMethodMatchesRule(
	new AssembleRule(new RemovedClientMethodAssembler()),
	'/^(demoSetupGain|thirdPartySubscribeGain)$/'
))

ClientMethodMatchesRule

See https://github.com/phpro/soap-client/issues/118#issuecomment-354496590


RemoveClientMethodAssembler

<?php

namespace GAA\CorpManagerApi\CodeGenerator\Assembler;

use Phpro\SoapClient\Client;
use Phpro\SoapClient\CodeGenerator\Assembler\AssemblerInterface;
use Phpro\SoapClient\CodeGenerator\Context\ContextInterface;
use Phpro\SoapClient\CodeGenerator\Context\ClientMethodContext;
use Phpro\SoapClient\Exception\AssemblerException;

/**
 * Class ClientMethodAssembler
 *
 * @package Phpro\SoapClient\CodeGenerator\Assembler
 */
class RemovedClientMethodAssembler implements AssemblerInterface
{
    /**
     * @param ContextInterface $context
     *
     * @return bool
     */
    public function canAssemble(ContextInterface $context): bool
    {
        return $context instanceof ClientMethodContext;
    }

    /**
     * @param ContextInterface|ClientMethodContext $context
     *
     * @return bool
     * @throws AssemblerException
     */
    public function assemble(ContextInterface $context): bool
    {
        $class = $context->getClass();
        $class->setExtendedClass(Client::class);
        $method = $context->getMethod();
        try {
            $class->removeMethod($method->getMethodName());
        } catch (\Exception $e) {
            throw AssemblerException::fromException($e);
        }

        return true;
    }
}

ConsolidatedClientMethodAssembler

Similar to RemovedClientMethod Assembler, but with a different assemble method to produce the code I need for this project (little value in sharing here).


Output

Generated client that has default method output (getExchanges) (albeit with extra documentation per #117), modified method (demoSetup) with interface-level param and return types, removed method (demoSetupGain - not shown, obviously), and an extra private method (getClassName).

screenshot 2017-12-29 20 52 52

GaryJones avatar Dec 29 '17 21:12 GaryJones