Skip to content

Commit

Permalink
Prepare soap-client for new php-soap/encoding package
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Jun 10, 2024
1 parent 66eb962 commit cc9b67f
Show file tree
Hide file tree
Showing 71 changed files with 560 additions and 910 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Want more information about the future of this project? Check out this list of t
You can choose what HTTP client you want to use.
This package expects some PSR implementations to be present in order to be installed:

* PSR-6: `psr/cache-implementation` like `symfony/cache` or `cache/*-adapter`
* PSR-7: `psr/http-message-implementation` like `nyholm/psr7` or `guzzlehttp/psr7`
* PSR-17: `psr/http-factory-implementation` like `nyholm/psr7` or `guzzlehttp/psr7`
* PSR-18: `psr/http-client-implementation` like `symfony/http-client` or `guzzlehttp/guzzle`
Expand Down Expand Up @@ -73,8 +74,8 @@ You can customize the generated code based on the manual installation pages in t
- [Get in control of the soap-client](https://github.com/php-soap/engine)
- [Psr-18 HTTP Transport](https://github.com/php-soap/psr18-transport/)
- [Configure one or multiple HTTP middlewares.](https://github.com/php-soap/psr18-transport/#middleware)
- [Customize how ext-soap behaves](https://github.com/php-soap/ext-soap-engine/)
- [Select a WSDL Provider](https://github.com/php-soap/ext-soap-engine/#wsdlprovider)
- [Customize how the encoding behaves](https://github.com/php-soap/encoding)
- [Select a WSDL loader](https://github.com/php-soap/wsdl#wsdl-loader)
- [Manipulate the metadata](docs/drivers/metadata.md)


Expand All @@ -88,10 +89,6 @@ For more advanced configuration, you can check the documentation inside the php-
- [Specify generation `Rules`](docs/code-generation/rules.md)
- [Generate code through `Assemblers`](docs/code-generation/assemblers.md)

## Known issues

- [ext-soap](docs/known-issues/ext-soap.md)

# Why this soap client was made

By default, the SoapClient works with a mix of arrays, stdClasses and other scalar types.
Expand Down
3 changes: 2 additions & 1 deletion UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ Full example on how you can personalize your factory class:
use Http\Client\Common\PluginClient;
use Http\Discovery\Psr18ClientDiscovery;
use Phpro\SoapClient\Soap\DefaultEngineFactory;
use Phpro\SoapClient\Soap\ExtSoap\Metadata\Manipulators\DuplicateTypes\RemoveDuplicateTypesStrategy;use Phpro\SoapClient\Soap\Metadata\Manipulators\TypesManipulatorChain;
use Phpro\SoapClient\Soap\Metadata\Manipulators\DuplicateTypes\RemoveDuplicateTypesStrategy;
use Phpro\SoapClient\Soap\Metadata\Manipulators\TypesManipulatorChain;
use Phpro\SoapClient\Soap\Metadata\MetadataOptions;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Soap\ExtSoapEngine\Wsdl\Naming\Md5Strategy;
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"azjezz/psl": "^2.1",
"laminas/laminas-code": "^4.8.0",
"php-soap/cached-engine": "^0.1",
"php-soap/engine": "^2.7",
"php-soap/ext-soap-engine": "^1.4",
"php-soap/encoding": "^0.2",
"php-soap/psr18-transport": "^1.3",
"php-soap/wsdl-reader": "~0.6",
"psr/event-dispatcher": "^1.0",
Expand All @@ -36,7 +37,8 @@
"phpspec/prophecy-phpunit": "^2.0.1",
"phpstan/phpstan": "^1.10.15",
"phpunit/phpunit": "~9.5",
"squizlabs/php_codesniffer": "^3.7.1"
"squizlabs/php_codesniffer": "^3.7.1",
"symfony/cache": "^6.4 || ^7.0"
},
"config": {
"sort-packages": true,
Expand Down
10 changes: 5 additions & 5 deletions docs/cli/generate-classmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ Example output:

namespace Myapp\Example\Classmap;

use Soap\ExtSoapEngine\Configuration\ClassMap\ClassMapCollection;
use Soap\ExtSoapEngine\Configuration\ClassMap\ClassMap;
use Soap\Encoding\ClassMap\ClassMapCollection;
use Soap\Encoding\ClassMap\ClassMap;

class OrderClassMap
{

public static function getCollection() : ClassMapCollection
{
return new ClassMapCollection(
new ClassMap('CreateOrder', Type\Example1::class),
new ClassMap('CardOrder', Type\Example2::class),
new ClassMap('OrderDetails', Type\Example3::class)
new ClassMap('http://namespace', 'CreateOrder', Type\Example1::class),
new ClassMap('http://namespace', 'CardOrder', Type\Example2::class),
new ClassMap('http://namespace', 'OrderDetails', Type\Example3::class)
);
}
}
Expand Down
51 changes: 36 additions & 15 deletions docs/cli/generate-clientfactory.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Generate a base client factory

To make things a little easier to get started a client factory generator method is available.
The generated factory can be seen as a good starting point to initialize the client.
It can be customized to your needs.

```bash
vendor/bin/soap-client generate:clientfactory
Expand Down Expand Up @@ -33,31 +35,50 @@ More advanced client factory:

use Http\Client\Common\PluginClient;
use Http\Discovery\Psr18ClientDiscovery;
use Phpro\SoapClient\Soap\ExtSoap\Metadata\Manipulators\DuplicateTypes\IntersectDuplicateTypesStrategy;
use Phpro\SoapClient\Caller\EngineCaller;
use Phpro\SoapClient\Caller\EventDispatchingCaller;
use Phpro\SoapClient\Soap\EngineOptions;
use Phpro\SoapClient\Soap\ExtSoap\DefaultEngineFactory;
use Phpro\SoapClient\Soap\Metadata\Manipulators\DuplicateTypes\IntersectDuplicateTypesStrategy;
use Phpro\SoapClient\Soap\Metadata\MetadataOptions;
use Soap\CachedEngine\CacheConfig;
use Soap\Encoding\EncoderRegistry;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Soap\Psr18Transport\Psr18Transport;
use Soap\Psr18Transport\Wsdl\Psr18Loader;
use Soap\Wsdl\Loader\FlatteningLoader;
use Soap\WsdlReader\Model\Definitions\SoapVersion;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Phpro\SoapClient\Soap\ExtSoap\DefaultEngineFactory;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Phpro\SoapClient\Caller\EventDispatchingCaller;
use Phpro\SoapClient\Caller\EngineCaller;

class CalculatorClientFactory
{
public static function factory(string $wsdl) : CalculatorClient
{
$engine = DefaultEngineFactory::create(
ExtSoapOptions::defaults($wsdl, [])
->withClassMap(CalculatorClassmap::getCollection()),
Psr18Transport::createForClient(
new PluginClient(
Psr18ClientDiscovery::find(),
[$plugin1, $plugin2]
EngineOptions::defaults($wsdl)
->withEncoderRegistry(
EncoderRegistry::default()
->addClassMapCollection(CalculatorClassmap::getCollection())
)
->withTransport(
Psr18Transport::createForClient(
new PluginClient(
Psr18ClientDiscovery::find(),
[$plugin1, $plugin2]
)
)
)
->withWsdlLoader(
new FlatteningLoader(
new Psr18Loader(Psr18ClientDiscovery::find())
)
)
->withCache(
new RedisAdapter(RedisAdapter::createConnection('redis://localhost')),
new CacheConfig('my-wsdl-cache-key', ttlInSeconds: 3600)
)
),
MetadataOptions::empty()->withTypesManipulator(
new IntersectDuplicateTypesStrategy()
)
->withPreferredSoapVersion(SoapVersion::SOAP_12)
);

$eventDispatcher = new EventDispatcher();
Expand Down
2 changes: 0 additions & 2 deletions docs/cli/generate-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ Usage:

Options:
--config=CONFIG The location of the soap code-generator config file

```

This generator will read all XSD types from the provided WSDL and convert it to PHP classes.
Expand All @@ -27,7 +26,6 @@ Keep in mind that the WSDL must provide all XSD types for the generation of valu
Options:

- **config**: A [configuration file](../code-generation/configuration.md) is required to build the types.
- **overwrite**: The soap-client overrides a file that cannot be patched without asking for confirmation.


When the value objects are generated, you will still need to customize them.
Expand Down
18 changes: 12 additions & 6 deletions docs/code-generation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ The code generation commands require a configuration file to determine how the S
use Phpro\SoapClient\CodeGenerator\Config\Config;
use Phpro\SoapClient\CodeGenerator\Rules;
use Phpro\SoapClient\CodeGenerator\Assembler;
use Phpro\SoapClient\Soap\CodeGeneratorEngineFactory;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Phpro\SoapClient\Soap\DefaultEngineFactory;
use Phpro\SoapClient\Soap\EngineOptions;
use Phpro\SoapClient\Soap\Metadata\Manipulators\DuplicateTypes\IntersectDuplicateTypesStrategy;
use Phpro\SoapClient\Soap\Metadata\MetadataOptions;
use Soap\Wsdl\Loader\FlatteningLoader;
use Soap\Wsdl\Loader\StreamWrapperLoader;

return Config::create()
->setEngine(CodeGeneratorEngineFactory::create(
'wsdl.xml',
new FlatteningLoader(new StreamWrapperLoader())
->setEngine(DefaultEngineFactory::create(
EngineOptions::defaults('wsdl.xml')
->withWsdlLoader(new FlatteningLoader(new StreamWrapperLoader()))
))
->setTypeDestination('src/SoapTypes')
->setTypeNamespace('SoapTypes')
Expand All @@ -27,6 +29,10 @@ return Config::create()
->setClassMapNamespace('Acme\\Classmap')
->setClassMapDestination('src/acme/classmap')
->setClassMapName('AcmeClassmap')
->setTypeMetadataOptions(
MetadataOptions::empty()
->withTypesManipulator(new IntersectDuplicateTypesStrategy())
)
->addRule(new Rules\AssembleRule(new Assembler\GetterAssembler(
(new Assembler\GetterAssemblerOptions())
->withReturnType()
Expand All @@ -52,7 +58,7 @@ Execute `vendor/bin/soap-client generate:config` to start the interactive config

Specify how the code generation tool can talk to SOAP.
By default, we push a custom engine that deeply parses the WSDL for code generation purpose.
For loading the WSDL, a PSR-18 based WSDL loader is being used in 'flattening' mode.
For loading the WSDL, a stream based WSDL loader is being used in 'flattening' mode.
It is possible to change this to any other configuration you want to use
and provide additional options like the preferred SOAP version.

Expand Down
42 changes: 27 additions & 15 deletions docs/drivers/metadata.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
# Driver metadata

## Dealing with ext-soap issues

### Duplicate types

Ext-soap does not add any namespace or unique identifier to the types it knows.
You can read more about this in the [known ext-soap issues](../known-issues/ext-soap.md#duplicate-typenames) section.
Therefore, we added some strategies to deal with duplicate types:
XSDs can have both internal and external types making that the names of the type can be non-unique in a given XML namespace.
It might not be possible to generate unique types for all types in the WSDL.
Therefore, we added some strategies to deal with duplicate types.

This can be configured in the [client configuration](/docs/code-generation/configuration.md):

**IntersectDuplicateTypesStrategy**

Enabled by default when using `DefaultEngineFactory::create()`.
Enabled by default when using `Config::create()`.

This duplicate types strategy will merge all duplicate types into one big type which contains all properties.


```php
use Phpro\SoapClient\CodeGenerator\Config\Config;
use Phpro\SoapClient\Soap\Metadata\Manipulators\DuplicateTypes\IntersectDuplicateTypesStrategy;
use Phpro\SoapClient\Soap\Metadata\MetadataOptions;

return Config::create()
//...
->setTypeMetadataOptions(
MetadataOptions::empty()->withTypesManipulator(new IntersectDuplicateTypesStrategy())
)
// ...
```

**RemoveDuplicateTypesStrategy**

This duplicate types strategy will remove all duplicate types it finds.

You can overwrite the strategy on the `DefaultEngineFactory` object inside the client factory:

```php
<?php

use Phpro\SoapClient\Soap\DefaultEngineFactory;
use Phpro\SoapClient\Soap\ExtSoap\Metadata\Manipulators\DuplicateTypes\RemoveDuplicateTypesStrategy;
use Phpro\SoapClient\CodeGenerator\Config\Config;
use Phpro\SoapClient\Soap\Metadata\Manipulators\DuplicateTypes\RemoveDuplicateTypesStrategy;
use Phpro\SoapClient\Soap\Metadata\MetadataOptions;

$engine = DefaultEngineFactory::create(
$options, $transport,
MetadataOptions::empty()->withTypesManipulator(
new RemoveDuplicateTypesStrategy()
return Config::create()
//...
->setTypeMetadataOptions(
MetadataOptions::empty()->withTypesManipulator(new RemoveDuplicateTypesStrategy())
)
);
// ...
```
116 changes: 0 additions & 116 deletions docs/known-issues/ext-soap.md

This file was deleted.

Loading

0 comments on commit cc9b67f

Please sign in to comment.