Avoid pass-by-reference issues in config parsing leading to duplicated responses; ref #2511
This commit is contained in:
parent
63f8f53367
commit
b946b20193
1 changed files with 28 additions and 35 deletions
|
@ -104,47 +104,33 @@ class EggConfigurationService
|
||||||
// can property map the egg placeholders to values.
|
// can property map the egg placeholders to values.
|
||||||
$structure = $this->configurationStructureService->handle($server, true);
|
$structure = $this->configurationStructureService->handle($server, true);
|
||||||
|
|
||||||
foreach ($configs as $file => &$data) {
|
|
||||||
$this->iterate($data->find, $structure);
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = [];
|
$response = [];
|
||||||
// Normalize the output of the configuration for the new Wings Daemon to more
|
// Normalize the output of the configuration for the new Wings Daemon to more
|
||||||
// easily ingest, as well as make things more flexible down the road.
|
// easily ingest, as well as make things more flexible down the road.
|
||||||
foreach ($configs as $file => $data) {
|
foreach ($configs as $file => $data) {
|
||||||
$append = ['file' => $file, 'replace' => []];
|
$append = array_merge((array)$data, ['file' => $file, 'replace' => []]);
|
||||||
|
|
||||||
|
foreach ($this->iterate($data->find, $structure) as $find => $replace) {
|
||||||
|
if (is_object($replace)) {
|
||||||
|
foreach ($replace as $match => $replaceWith) {
|
||||||
|
$append['replace'][] = [
|
||||||
|
'match' => $find,
|
||||||
|
'if_value' => $match,
|
||||||
|
'replace_with' => $replaceWith,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/** @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection */
|
|
||||||
// I like to think I understand PHP pretty well, but if you don't pass $value
|
|
||||||
// by reference here, you'll end up with a resursive array loop if the config
|
|
||||||
// file has two replacements that reference the same item in the configuration
|
|
||||||
// array for the server.
|
|
||||||
foreach ($data as $key => &$value) {
|
|
||||||
if ($key !== 'find') {
|
|
||||||
$append[$key] = $value;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($value as $find => $replace) {
|
$append['replace'][] = [
|
||||||
if (is_object($replace)) {
|
'match' => $find,
|
||||||
foreach ($replace as $match => $replaceWith) {
|
'replace_with' => $replace,
|
||||||
$append['replace'][] = [
|
];
|
||||||
'match' => $find,
|
|
||||||
'if_value' => $match,
|
|
||||||
'replace_with' => $replaceWith,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$append['replace'][] = [
|
|
||||||
'match' => $find,
|
|
||||||
'replace_with' => $replace,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unset($append['find']);
|
||||||
|
|
||||||
$response[] = $append;
|
$response[] = $append;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,21 +234,28 @@ class EggConfigurationService
|
||||||
*
|
*
|
||||||
* @param mixed $data
|
* @param mixed $data
|
||||||
* @param array $structure
|
* @param array $structure
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function iterate(&$data, array $structure)
|
private function iterate($data, array $structure)
|
||||||
{
|
{
|
||||||
if (! is_iterable($data) && ! is_object($data)) {
|
if (! is_iterable($data) && ! is_object($data)) {
|
||||||
return;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($data as &$value) {
|
// Remember, in PHP objects are always passed by reference, so if we do not clone this object
|
||||||
|
// instance we'll end up making modifications to the object outside the scope of this function
|
||||||
|
// which leads to some fun behavior in the parser.
|
||||||
|
$clone = clone $data;
|
||||||
|
foreach ($clone as $key => &$value) {
|
||||||
if (is_iterable($value) || is_object($value)) {
|
if (is_iterable($value) || is_object($value)) {
|
||||||
$this->iterate($value, $structure);
|
$value = $this->iterate($value, $structure);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = $this->matchAndReplaceKeys($value, $structure);
|
$value = $this->matchAndReplaceKeys($value, $structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $clone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue