Skip to content

Commit f2bed10

Browse files
Merge branch 'release/7.0.1'
2 parents 60bef33 + 0cb3d37 commit f2bed10

File tree

13 files changed

+346
-9
lines changed

13 files changed

+346
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# In2publish Core Change Log
22

3+
7.0.1:
4+
5+
[BUGFIX] Merge configuration more decently
6+
[BUGFIX] Handle optional configuration nodes appropriately
7+
38
7.0.0:
49

510
- [TYPO] Correctly write "applies"

Classes/Config/Builder.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ public function addString($key, $default, array $validators = [])
115115
return $this;
116116
}
117117

118+
/**
119+
* @param string $key
120+
* @param string $default
121+
* @param array $validators
122+
* @return $this
123+
*/
124+
public function addOptionalString($key, $default, array $validators = [])
125+
{
126+
$this->addNode(Node::T_OPTIONAL_STRING, $key, $default, $validators);
127+
return $this;
128+
}
129+
118130
/**
119131
* @param string $key
120132
* @param int $default

Classes/Config/ConfigContainer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use In2code\In2publishCore\Config\Provider\ProviderInterface;
3434
use In2code\In2publishCore\Service\Context\ContextService;
3535
use In2code\In2publishCore\Utility\ArrayUtility;
36+
use In2code\In2publishCore\Utility\ConfigurationUtility;
3637
use TYPO3\CMS\Core\SingletonInterface;
3738
use TYPO3\CMS\Core\Utility\GeneralUtility;
3839

@@ -157,7 +158,7 @@ protected function processConfig(array $priority)
157158
$config = [];
158159
foreach (array_keys($priority) as $class) {
159160
$providerConfig = $this->providers[$class];
160-
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $providerConfig);
161+
$config = ConfigurationUtility::mergeConfiguration($config, $providerConfig);
161162
}
162163

163164
if (GeneralUtility::makeInstance(ContextService::class)->isLocal()) {

Classes/Config/Definer/SshConnectionDefiner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function getLocalDefinition()
5555
'/home/ssh-account/.ssh/id_rsa.pub',
5656
[FEV::class]
5757
)
58-
->addString('privateKeyPassphrase', '')
58+
->addOptionalString('privateKeyPassphrase', '')
5959
->addString('foreignKeyFingerprint', '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00')
6060
->addString('foreignKeyFingerprintHashingMethod', 'SSH2_FINGERPRINT_MD5')
6161
->addBoolean('ignoreChmodFail', false)

Classes/Config/Node/AbstractNode.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ abstract class AbstractNode implements Node
5656
*/
5757
protected $default;
5858

59+
/**
60+
* @var bool
61+
*/
62+
protected $skipValidators = false;
63+
5964
/**
6065
* AbstractNode constructor.
6166
*
@@ -107,12 +112,14 @@ public function validate(ValidationContainer $container, $value)
107112
$container->addError('Configuration format is wrong');
108113
} elseif (!array_key_exists($this->name, $value)) {
109114
$container->addError('Configuration value is not set');
110-
} elseif ('' === $value[$this->name] || null === $value[$this->name]) {
111-
$container->addError('Configuration value must not be empty');
112115
} else {
113116
$this->validateType($container, $value[$this->name]);
114-
$this->validateByValidators($container, $value);
115-
$this->nodes->validate($container, $value[$this->name]);
117+
118+
if (!$this->validatorsShouldBeSkipped()) {
119+
$this->validateByValidators($container, $value);
120+
$this->nodes->validate($container, $value[$this->name]);
121+
}
122+
116123
}
117124
}
118125

@@ -168,4 +175,17 @@ public function merge(Node $node)
168175
* @param mixed $value
169176
*/
170177
abstract protected function validateType(ValidationContainer $container, $value);
178+
179+
/**
180+
* @return bool
181+
*/
182+
public function validatorsShouldBeSkipped()
183+
{
184+
return $this->skipValidators;
185+
}
186+
187+
public function skipValidators()
188+
{
189+
$this->skipValidators = true;
190+
}
171191
}

Classes/Config/Node/Node.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ interface Node
3636
const T_ARRAY = 'array';
3737
const T_STRICT_ARRAY = 'strict_array';
3838
const T_STRING = 'string';
39+
const T_OPTIONAL_STRING = 'optional_string';
3940
const T_INTEGER = 'integer';
4041
const T_BOOLEAN = 'boolean';
4142

Classes/Config/Node/Specific/AbsSpecNode.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ abstract class AbsSpecNode extends AbstractNode
4141
*/
4242
protected static $types = [
4343
Node::T_STRING => SpecString::class,
44+
Node::T_OPTIONAL_STRING => SpecOptionalString::class,
4445
Node::T_INTEGER => SpecInteger::class,
4546
Node::T_ARRAY => SpecArray::class,
4647
Node::T_STRICT_ARRAY => SpecStrictArray::class,

Classes/Config/Node/Specific/SpecInteger.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class SpecInteger extends AbsSpecNode
3939
*/
4040
public function validateType(ValidationContainer $container, $value)
4141
{
42-
if (!is_integer($value)) {
42+
if ('' === $value || null === $value) {
43+
$container->addError('Configuration value must not be empty');
44+
} elseif (!is_integer($value)) {
4345
$container->addError('The value is not an integer');
4446
}
4547
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
namespace In2code\In2publishCore\Config\Node\Specific;
3+
4+
/***************************************************************
5+
* Copyright notice
6+
*
7+
* (c) 2018 in2code.de and the following authors:
8+
* Oliver Eglseder <[email protected]>
9+
*
10+
* All rights reserved
11+
*
12+
* This script is part of the TYPO3 project. The TYPO3 project is
13+
* free software; you can redistribute it and/or modify
14+
* it under the terms of the GNU General Public License as published by
15+
* the Free Software Foundation; either version 3 of the License, or
16+
* (at your option) any later version.
17+
*
18+
* The GNU General Public License can be found at
19+
* http://www.gnu.org/copyleft/gpl.html.
20+
*
21+
* This script is distributed in the hope that it will be useful,
22+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24+
* GNU General Public License for more details.
25+
*
26+
* This copyright notice MUST APPEAR in all copies of the script!
27+
***************************************************************/
28+
29+
use In2code\In2publishCore\Config\ValidationContainer;
30+
31+
/**
32+
* Class SpecString
33+
*/
34+
class SpecOptionalString extends AbsSpecNode
35+
{
36+
/**
37+
* @param ValidationContainer $container
38+
* @param mixed $value
39+
*/
40+
public function validateType(ValidationContainer $container, $value)
41+
{
42+
if (!is_string($value) && null !== $value) {
43+
$container->addError('The value is not a string');
44+
}
45+
46+
if ('' === $value || null === $value) {
47+
$this->skipValidators();
48+
}
49+
}
50+
51+
/**
52+
* @param array|bool|int|string $value
53+
*
54+
* @return string
55+
*/
56+
public function cast($value)
57+
{
58+
return (string)$value;
59+
}
60+
}

Classes/Config/Node/Specific/SpecString.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class SpecString extends AbsSpecNode
3939
*/
4040
public function validateType(ValidationContainer $container, $value)
4141
{
42-
if (!is_string($value)) {
42+
if ('' === $value || null === $value) {
43+
$container->addError('Configuration value must not be empty');
44+
} elseif (!is_string($value)) {
4345
$container->addError('The value is not a string');
4446
}
4547
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
namespace In2code\In2publishCore\Utility;
3+
4+
class ConfigurationUtility
5+
{
6+
/**
7+
* Merges two configuration arrays recursively
8+
*
9+
* - the value of items having an identical ALPHANUMERIC key will be REPLACED
10+
* - the value of items having an identical NUMERIC key will be ADDED
11+
*
12+
* @param array $original
13+
* @param array $additional
14+
* @return array
15+
*/
16+
public static function mergeConfiguration(array $original, array $additional)
17+
{
18+
$result = $original;
19+
20+
foreach ($additional as $key => $value) {
21+
if (!is_int($key)) {
22+
// Replace original value
23+
$result[$key] = self::getResultingValue($original, $additional, $key);
24+
} else {
25+
if (!in_array($value, $original, true)) {
26+
// Add additional value
27+
$result[] = self::getResultingValue($original, $additional, $key);
28+
}
29+
}
30+
}
31+
32+
return $result;
33+
}
34+
35+
/**
36+
* @param array $original
37+
* @param array $additional
38+
* @param mixed $key
39+
* @return array|mixed|null
40+
*/
41+
private static function getResultingValue(array $original, array $additional, $key)
42+
{
43+
$originalValue = array_key_exists($key, $original) ? $original[$key] : null;
44+
$additionalValue = array_key_exists($key, $additional) ? $additional[$key] : null;
45+
46+
if (is_array($originalValue)
47+
&&
48+
is_array($additionalValue)
49+
) {
50+
// Merge recursively
51+
$result = self::mergeConfiguration($originalValue, $additionalValue);
52+
} else {
53+
// Use additional value (to add/replace)
54+
$result = $additionalValue;
55+
}
56+
57+
return $result;
58+
}
59+
}

0 commit comments

Comments
 (0)