Skip to content

Commit

Permalink
Use Nette/DI:3 schema feature
Browse files Browse the repository at this point in the history
  • Loading branch information
trejjam committed Mar 30, 2019
1 parent 23e4ff8 commit a9dc5d4
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 143 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ jobs:
script:
- composer run-script tests

- env: title="Bleading edge dependencies 7.3"
php: 7.3
install:
- composer config minimum-stability RC
- travis_retry composer update --no-progress --prefer-dist
script:
- composer run-script tests

- stage: Quality Assurance
php: 7.1
script:
Expand Down
5 changes: 0 additions & 5 deletions bin/run-tests.sh

This file was deleted.

247 changes: 152 additions & 95 deletions src/DI/ThePayExtension.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php declare(strict_types = 1);
<?php declare(strict_types=1);

namespace Contributte\ThePay\DI;

Expand All @@ -9,105 +9,162 @@
use Contributte\ThePay\IPermanentPayment;
use Contributte\ThePay\IReturnedPayment;
use Contributte\ThePay\MerchantConfig;
use Nette;
use Nette\DI\CompilerExtension;
use Nette\DI\Config\Expect;
use Nette\DI\ContainerBuilder;
use Nette\Utils\Validators;

class ThePayExtension extends CompilerExtension
{

/** @var mixed[] */
protected $default = [
'demo' => true,
'merchant' => [
'gateUrl' => 'https://www.thepay.cz/gate/',
'merchantId' => null,
'accountId' => null,
'password' => '',
'dataApiPassword' => '',
'webServicesWsdl' => 'https://www.thepay.cz/gate/api/gate-api.wsdl',
'dataWebServicesWsdl' => 'https://www.thepay.cz/gate/api/data.wsdl',
],
];

/** @var mixed[] */
protected $merchantDemo = [
'gateUrl' => 'https://www.thepay.cz/demo-gate/',
'merchantId' => 1,
'accountId' => 1,
'password' => 'my$up3rsecr3tp4$$word',
'dataApiPassword' => 'my$up3rsecr3tp4$$word',
'webServicesWsdl' => 'https://www.thepay.cz/demo-gate/api/gate-api-demo.wsdl',
'dataWebServicesWsdl' => 'https://www.thepay.cz/demo-gate/api/data-demo.wsdl',
];

public function loadConfiguration(): void
{
$this->validateConfig($this->default);

Validators::assertField($this->config, 'demo', 'bool');

if ($this->config['demo'] === true) {
$this->config['merchant'] = $this->merchantDemo;
}

Validators::assertField($this->config, 'merchant', 'array');
Validators::assertField($this->config['merchant'], 'gateUrl', 'string');
Validators::assertField($this->config['merchant'], 'merchantId', 'int');
Validators::assertField($this->config['merchant'], 'accountId', 'int');
Validators::assertField($this->config['merchant'], 'password', 'string');
Validators::assertField($this->config['merchant'], 'dataApiPassword', 'string');
Validators::assertField($this->config['merchant'], 'webServicesWsdl', 'string');
Validators::assertField($this->config['merchant'], 'dataWebServicesWsdl', 'string');
}

public function beforeCompile(): void
{
parent::beforeCompile();

$merchantConfig = $this->config['merchant'];

$builder = $this->getContainerBuilder();

$merchantConfigDefinition = $builder->addDefinition($this->prefix('merchantConfig'))->setType(MerchantConfig::class);
$builder->addDefinition($this->prefix('helper.dataApi'))->setType(DataApi::class);

$this->registerFactory($builder, $this->prefix('paymentFactory'), IPayment::class);
$this->registerFactory($builder, $this->prefix('permanentPaymentFactory'), IPermanentPayment::class);
$this->registerFactory($builder, $this->prefix('returnedPaymentFactory'), IReturnedPayment::class);
$this->registerFactory($builder, $this->prefix('helper.radioMerchantFactory'), IRadioMerchant::class);
$this->registerFactory($builder, $this->prefix('helper.divMerchantFactory'), IDivMerchant::class);

$merchantConfigDefinition
->addSetup(
'$service->isDemo = ?;' . "\n" .
'$service->gateUrl = ?;' . "\n" .
'$service->merchantId = ?;' . "\n" .
'$service->accountId = ?;' . "\n" .
'$service->password = ?;' . "\n" .
'$service->dataApiPassword = ?;' . "\n" .
'$service->webServicesWsdl = ?;' . "\n" .
'$service->dataWebServicesWsdl = ?',
[
$this->config['demo'],
$merchantConfig['gateUrl'],
$merchantConfig['merchantId'],
$merchantConfig['accountId'],
$merchantConfig['password'],
$merchantConfig['dataApiPassword'],
$merchantConfig['webServicesWsdl'],
$merchantConfig['dataWebServicesWsdl'],
]
);
}

private function registerFactory(ContainerBuilder $builder, string $name, string $interface): void
{
if (method_exists($builder, 'addFactoryDefinition')) {
$builder->addFactoryDefinition($name)->setImplement($interface);
} else {
$builder->addDefinition($name)->setImplement($interface);
}
}
/**
* pre Nette 3.0 compatibility
* @var \stdClass
*/
private $shadowConfig;

public function __construct()
{
$this->config = new class
{
/** @var bool */
public $demo;
/** @var \stdClass */
public $merchant;

public function __construct()
{
$this->merchant = new class
{
/** @var string */
public $gateUrl = 'https://www.thepay.cz/gate/';
/** @var int */
public $merchantId;
/** @var int */
public $accountId;
/** @var string */
public $password;
/** @var string */
public $dataApiPassword;
/** @var string */
public $webServicesWsdl = 'https://www.thepay.cz/gate/api/gate-api.wsdl';
/** @var string */
public $dataWebServicesWsdl = 'https://www.thepay.cz/gate/api/data.wsdl';
};
}

public function setDemoMerchant() : void
{
$this->merchant->gateUrl = 'https://www.thepay.cz/demo-gate/';
$this->merchant->merchantId = 1;
$this->merchant->accountId = 1;
$this->merchant->password = 'my$up3rsecr3tp4$$word';
$this->merchant->dataApiPassword = 'my$up3rsecr3tp4$$word';
$this->merchant->webServicesWsdl = 'https://www.thepay.cz/demo-gate/api/gate-api-demo.wsdl';
$this->merchant->dataWebServicesWsdl = 'https://www.thepay.cz/demo-gate/api/data-demo.wsdl';
}
};

if (!method_exists(get_parent_class($this), 'getConfigSchema')) {
// pre Nette 3.0 compatibility
$this->shadowConfig = $this->config;
}
}

public function getConfigSchema() : Nette\DI\Config\Schema
{
return Expect::from($this->config)->normalize(
function (array $config) {
if ($config['demo'] === true) {
$this->config->setDemoMerchant();
$config['merchant'] = (array)$this->config->merchant;
}

return $config;
}
);
}

public function loadConfiguration() : void
{
if (!method_exists(get_parent_class($this), 'getConfigSchema')) {

This comment has been minimized.

Copy link
@f3l1x

f3l1x Mar 30, 2019

Member

Osobne mi prijde tohle jako skoda casu. Podporovat obe 2 varianty. Pak zase ten kod budes mazat. :-)

This comment has been minimized.

Copy link
@trejjam

trejjam Mar 30, 2019

Author Member

Bral jsem to jako osobni seznameni s v3 - a potreboval jsem si overit jeden svuj omyl. Ve vysledku tohle zmenilo netypovou konfiguraci na typovou (DTO) a stara napsana validace se pouzije jen pro DI bez podpory schematu.
Opacny extrem podporovat jen v3 mi zatim nepride vhodny, kdyz nejsou vsechny balicky se stable v3.

// pre Nette 3.0 compatibility

$config = (array)$this->shadowConfig;
$config['demo'] = true; // Backward compatibility
$config['merchant'] = (array)$this->shadowConfig->merchant;

$this->validateConfig($config);

Validators::assertField($this->config, 'demo', 'bool');

if ($this->config['demo'] === true) {
$this->shadowConfig->setDemoMerchant();
$this->config['merchant'] = (array)$this->shadowConfig->merchant;
}

Validators::assertField($this->config, 'merchant', 'array');
Validators::assertField($this->config['merchant'], 'gateUrl', 'string');
Validators::assertField($this->config['merchant'], 'merchantId', 'int');
Validators::assertField($this->config['merchant'], 'accountId', 'int');
Validators::assertField($this->config['merchant'], 'password', 'string');
Validators::assertField($this->config['merchant'], 'dataApiPassword', 'string');
Validators::assertField($this->config['merchant'], 'webServicesWsdl', 'string');
Validators::assertField($this->config['merchant'], 'dataWebServicesWsdl', 'string');

$this->config = (object)$this->config;
$this->config->merchant = (object)$this->config->merchant;
}
}

public function beforeCompile() : void
{
parent::beforeCompile();

$merchantConfig = $this->config->merchant;

$builder = $this->getContainerBuilder();

$merchantConfigDefinition = $builder->addDefinition($this->prefix('merchantConfig'))->setType(MerchantConfig::class);
$builder->addDefinition($this->prefix('helper.dataApi'))->setType(DataApi::class);

$this->registerFactory($builder, $this->prefix('paymentFactory'), IPayment::class);
$this->registerFactory($builder, $this->prefix('permanentPaymentFactory'), IPermanentPayment::class);
$this->registerFactory($builder, $this->prefix('returnedPaymentFactory'), IReturnedPayment::class);
$this->registerFactory($builder, $this->prefix('helper.radioMerchantFactory'), IRadioMerchant::class);
$this->registerFactory($builder, $this->prefix('helper.divMerchantFactory'), IDivMerchant::class);

$merchantConfigDefinition
->addSetup(
'$service->isDemo = ?;' . "\n" .
'$service->gateUrl = ?;' . "\n" .
'$service->merchantId = ?;' . "\n" .
'$service->accountId = ?;' . "\n" .
'$service->password = ?;' . "\n" .
'$service->dataApiPassword = ?;' . "\n" .
'$service->webServicesWsdl = ?;' . "\n" .
'$service->dataWebServicesWsdl = ?',
[
$this->config->demo,
$merchantConfig->gateUrl,
$merchantConfig->merchantId,
$merchantConfig->accountId,
$merchantConfig->password,
$merchantConfig->dataApiPassword,
$merchantConfig->webServicesWsdl,
$merchantConfig->dataWebServicesWsdl,
]
);
}

private function registerFactory(ContainerBuilder $builder, string $name, string $interface) : void
{
if (method_exists($builder, 'addFactoryDefinition')) {
$builder->addFactoryDefinition($name)->setImplement($interface);
}
else {
$builder->addDefinition($name)->setImplement($interface);
}
}

}
82 changes: 41 additions & 41 deletions tests/cases/DITest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,68 @@ use Tester\Assert;

require __DIR__ . '/../bootstrap.php';

class DITest extends TestCase
final class DITest extends TestCase
{
private const NAME = 'contributte.thepay';

public function testDemoConfig()
{
$thePayExtension = new ThePayExtension;

$thePayExtension->setCompiler(new Compiler, 'container_' . __FUNCTION__);
$thePayExtension->loadConfiguration();

$thePayConfig = $thePayExtension->getConfig();

Assert::same(
$compiler = new Compiler;
$compiler->addExtension(self::NAME, $thePayExtension);
$compiler->addConfig(
[
'demo' => true,
'merchant' => [
'gateUrl' => 'https://www.thepay.cz/demo-gate/',
'merchantId' => 1,
'accountId' => 1,
'password' => 'my$up3rsecr3tp4$$word',
'dataApiPassword' => 'my$up3rsecr3tp4$$word',
'webServicesWsdl' => 'https://www.thepay.cz/demo-gate/api/gate-api-demo.wsdl',
'dataWebServicesWsdl' => 'https://www.thepay.cz/demo-gate/api/data-demo.wsdl',
self::NAME => [
'demo' => true,
],
], $thePayConfig
]
);
$compiler->processExtensions();

$thePayConfig = $thePayExtension->getConfig();

Assert::same(true, $thePayConfig->demo);
Assert::same('https://www.thepay.cz/demo-gate/', $thePayConfig->merchant->gateUrl);
Assert::same(1, $thePayConfig->merchant->merchantId);
Assert::same(1, $thePayConfig->merchant->accountId);
Assert::same('my$up3rsecr3tp4$$word', $thePayConfig->merchant->password);
Assert::same('my$up3rsecr3tp4$$word', $thePayConfig->merchant->dataApiPassword);
Assert::same('https://www.thepay.cz/demo-gate/api/gate-api-demo.wsdl', $thePayConfig->merchant->webServicesWsdl);
Assert::same('https://www.thepay.cz/demo-gate/api/data-demo.wsdl', $thePayConfig->merchant->dataWebServicesWsdl);
}

public function testProductionConfig()
{
$thePayExtension = new ThePayExtension;

$thePayExtension->setCompiler(new Compiler, 'container_' . __FUNCTION__);

$thePayExtension->setConfig(
$compiler = new Compiler;
$compiler->addExtension(self::NAME, $thePayExtension);
$compiler->addConfig(
[
'demo' => false,
'merchant' => [
'merchantId' => 10,
'accountId' => 42,
'password' => 'abc',
'dataApiPassword' => 'def',
self::NAME => [
'demo' => false,
'merchant' => [
'merchantId' => 10,
'accountId' => 42,
'password' => 'abc',
'dataApiPassword' => 'def',
],
],
]
);
$thePayExtension->loadConfiguration();
$compiler->processExtensions();

$thePayConfig = $thePayExtension->getConfig();

Assert::same(
[
'demo' => false,
'merchant' => [
'gateUrl' => 'https://www.thepay.cz/gate/',
'merchantId' => 10,
'accountId' => 42,
'password' => 'abc',
'dataApiPassword' => 'def',
'webServicesWsdl' => 'https://www.thepay.cz/gate/api/gate-api.wsdl',
'dataWebServicesWsdl' => 'https://www.thepay.cz/gate/api/data.wsdl',
],
], $thePayConfig
);
Assert::same(false, $thePayConfig->demo);
Assert::same('https://www.thepay.cz/gate/', $thePayConfig->merchant->gateUrl);
Assert::same(10, $thePayConfig->merchant->merchantId);
Assert::same(42, $thePayConfig->merchant->accountId);
Assert::same('abc', $thePayConfig->merchant->password);
Assert::same('def', $thePayConfig->merchant->dataApiPassword);
Assert::same('https://www.thepay.cz/gate/api/gate-api.wsdl', $thePayConfig->merchant->webServicesWsdl);
Assert::same('https://www.thepay.cz/gate/api/data.wsdl', $thePayConfig->merchant->dataWebServicesWsdl);
}
}

Expand Down
Loading

0 comments on commit a9dc5d4

Please sign in to comment.