Skip to content

Commit

Permalink
Bug fixes 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnathonKoster committed Feb 1, 2023
1 parent 85b64f7 commit 89c28b6
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/Analyzers/ConfigAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,26 @@ public function isNodeArray($key)
return false;
}

private function isFunctionLike($node)
{
if ($node instanceof Node\Expr\Cast\Bool_ ||
$node instanceof Node\Expr\Cast\String_ ||
$node instanceof Node\Expr\Cast\Int_ ||
$node instanceof Node\Expr\Cast\Double ||
$node instanceof FuncCall) {
return true;
}

return false;
}

public function containsFunctionCall($key)
{
if (!$this->hasNode($key) || !$this->nodeMapping[$key] instanceof ArrayItem) { return false; }

return $this->isFunctionLike($this->nodeMapping[$key]->value);
}

/**
* Appends a value to an existing array at a known location.
*
Expand Down
38 changes: 37 additions & 1 deletion src/ConfigUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,38 @@ public function setIgnoreFunctions($ignore)
*/
public function setPreserveKeys($keys)
{
$this->preserveKeys = $keys;
$this->preserveKeys = $this->flattenKeys($keys);

return $this;
}

/**
* Flattens deeply nested arrays using "dot" notation, while preserving root keys.
*
* @param array $array
* @param string $prefix
* @return array
*/
private function flattenKeys($array, $prefix = '')
{
$newArray = [];

foreach ($array as $key => $value) {
$prefixToUse = $prefix;
if (strlen(trim($prefixToUse)) > 0) {
$prefixToUse = $prefix.'.';
}

if (is_array($value)) {
$newArray = array_merge($this->flattenKeys($value, $prefixToUse.$key), $newArray);
} else {
$newArray[] = $prefixToUse.$value;
}
}

return $newArray;
}

/**
* Attempts to remove the key and its value from the configuration.
*
Expand Down Expand Up @@ -178,10 +205,19 @@ public function replaceStructure($key, $newKey, $value, $docBlock, $forceNewLine
*/
public function update(array $changes, $isMerge = false)
{
// If we have keys to preserve, writing without all the
// required values will just stomp all over everything.
if (count($this->preserveKeys) > 0) {
$isMerge = true;
}

if (! empty($this->preserveKeys)) {
$currentConfig = $this->analyzer->getValues();

foreach ($this->preserveKeys as $keyToPreserve) {
if ($this->ignoreFunctions && $this->analyzer->containsFunctionCall($keyToPreserve)) {
continue;
}
unset($changes[$keyToPreserve]);
Arr::set($changes, $keyToPreserve, Arr::get($currentConfig, $keyToPreserve));
}
Expand Down
2 changes: 1 addition & 1 deletion src/LaravelConfigWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ protected function getChanges($file, $namespace, array $changes, $isMerge = fals
*
* @param string $configNamespace The root configuration namespace.
* @param array $values The key/value mapping of all changes.
* @param bool $isMerge Indiciates if the current operation is a merge, or forced update.
* @param bool $isMerge Indicates if the current operation is a merge, or forced update.
* @return string
* @throws ConfigNotFoundException
* @throws ConfigNotWriteableException
Expand Down
43 changes: 43 additions & 0 deletions tests/IgnoreFunctionsWriteManyPreserveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

require_once 'ProteusTestCase.php';

use Stillat\Proteus\ConfigUpdater;
use Stillat\Proteus\Document\Transformer;

class IgnoreFunctionsWriteManyPreserveTest extends ProteusTestCase
{
public function testFunctionsAreRestoredWhenWritingItemsAndPreservingKeys()
{
$updater = new ConfigUpdater();
$updater->setIgnoreFunctions(true);
$updater->open(__DIR__ . '/configs/issues/014.php');
$expected = Transformer::normalizeLineEndings(file_get_contents(__DIR__ . '/expected/issues/014.php'));
$updater->setPreserveKeys([
'stripe' => [
'api_base',
'dg_price_1',
'dg_product_1',
'dg_product_2',
'public',
'secret',
'webhook',
'query_params',
]
])->update([
'stripe' => [
'reports' => [
[
'id' => 'a new thing',
'frequency' => 'daily',
'email_addresses' => '[email protected]',
],
],
]
], false); // The false merge should get overridden internally.

$doc = $updater->getDocument();

$this->assertEquals($expected, $doc);
}
}
52 changes: 52 additions & 0 deletions tests/PreserveArrayKeysTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

require_once 'ProteusTestCase.php';

use Stillat\Proteus\ConfigUpdater;
use Stillat\Proteus\Document\Transformer;

class PreserveArrayKeysTest extends ProteusTestCase
{
public function testUsingArraysForKeyPreservationWorks()
{
$updater = new ConfigUpdater();
$updater->setIgnoreFunctions(true);
$updater->open(__DIR__ . '/configs/merge.php');
$expected = Transformer::normalizeLineEndings(file_get_contents(__DIR__ . '/expected/merge.php'));
$updater->setPreserveKeys([
'stripe' => [
'leave',
]
])->update([
'stripe' => [
'leave' => 'hello, there!',
'reports' => [
[
'frequency' => 'daily',
'email_addresses' => 'entry1',
],
[
'frequency' => 'daily',
'email_addresses' => 'entry2',
],
[
'frequency' => 'daily',
'email_addresses' => 'entry3',
],
],
'test' => [
'what' => [
'nested' => 'value',
'happens' => [
1, 2, 3, 'four', 'five', 5, 'six', 'seven' => [8]
]
]
]
]
], true);

$doc = $updater->getDocument();

$this->assertEquals($expected, $doc);
}
}
33 changes: 33 additions & 0 deletions tests/configs/issues/014.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

return [
'stripe' => [
'api_base' => env('STRIPE_API_BASE'),
'dg_price_1' => env('STRIPE_PRICE_ONE'),
'dg_product_1' => env('STRIPE_PRODUCT_ONE'),
'dg_product_2' => env('STRIPE_PRODUCT_TWO'),
'public' => env('STRIPE_PUBLIC_KEY'),
'secret' => env('STRIPE_SECRET_KEY'),
'webhook' => env('STRIPE_WEBHOOK_SECRET'),

'reports' => [
[
'id' => 'eq48Qzwt',
'frequency' => 'daily',
'email_addresses' => '[email protected],[email protected]',
],
[
'id' => 'firstid',
'frequency' => 'monthly',
'email_addresses' => '[email protected],[email protected]',
],
],

// Misc
'query_params' => [
'utm_source',
'utm_medium',
'utm_campaign',
],
],
];
28 changes: 28 additions & 0 deletions tests/expected/issues/014.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

return [
'stripe' => [
'api_base' => env('STRIPE_API_BASE'),
'dg_price_1' => env('STRIPE_PRICE_ONE'),
'dg_product_1' => env('STRIPE_PRODUCT_ONE'),
'dg_product_2' => env('STRIPE_PRODUCT_TWO'),
'public' => env('STRIPE_PUBLIC_KEY'),
'secret' => env('STRIPE_SECRET_KEY'),
'webhook' => env('STRIPE_WEBHOOK_SECRET'),

'reports' => [
[
'id' => 'a new thing',
'frequency' => 'daily',
'email_addresses' => '[email protected]',
],
],

// Misc
'query_params' => [
'utm_source',
'utm_medium',
'utm_campaign',
],
],
];

0 comments on commit 89c28b6

Please sign in to comment.