Skip to content

Commit f26cefc

Browse files
authored
Merge pull request #72 from andreaswolf/MigrateEmailFlagToEmailTypeFlexFormFractor
[FEATURE] Add MigrateEmailFlagToEmailTypeFlexFormFractor
2 parents 18d23b7 + e874d65 commit f26cefc

25 files changed

+752
-13
lines changed

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,25 @@ return FractorConfiguration::configure()
8181
]);
8282
```
8383

84+
### Configure code style
85+
86+
Fractor tries to format the code as good as possible.
87+
If you want to adjust the indentation of your xml files, you can configure it this way:
88+
89+
```php
90+
<?php
91+
92+
use a9f\Fractor\Configuration\FractorConfiguration;
93+
use a9f\Fractor\ValueObject\Indent;
94+
use a9f\FractorXml\Configuration\XmlProcessorOption;
95+
96+
return FractorConfiguration::configure()
97+
->withOptions([
98+
XmlProcessorOption::INDENT_CHARACTER => Indent::STYLE_TAB,
99+
XmlProcessorOption::INDENT_SIZE => 1,
100+
])
101+
```
102+
84103
## Processing
85104

86105
Execute Fractor from the command line, passing the path to your configuration file as an argument:

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"nette/utils": "^4.0",
2020
"phpstan/phpstan": "^1.10.9",
2121
"sebastian/diff": "^5.0",
22+
"shanethehat/pretty-xml": "^1.0",
2223
"symfony/config": "^6.4 || ^7.0",
2324
"symfony/console": "^6.4 || ^7.0",
2425
"symfony/dependency-injection": "^6.4 || ^7.0",

packages/fractor-xml/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"ext-xml": "*",
1717
"a9f/fractor": "^0.2",
1818
"a9f/fractor-extension-installer": "^0.2",
19+
"shanethehat/pretty-xml": "^1.0",
1920
"webmozart/assert": "^1.11"
2021
},
2122
"require-dev": {

packages/fractor-xml/config/application.php

+12
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
declare(strict_types=1);
44

5+
use a9f\Fractor\ValueObject\Indent;
6+
use a9f\FractorXml\Contract\Formatter;
57
use a9f\FractorXml\Contract\XmlFractor;
8+
use a9f\FractorXml\IndentFactory;
9+
use a9f\FractorXml\PrettyXmlFormatter;
610
use a9f\FractorXml\XmlFileProcessor;
711
use Symfony\Component\DependencyInjection\ContainerBuilder;
812
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
13+
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
914
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;
1015

1116
return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void {
@@ -16,8 +21,15 @@
1621

1722
$services->load('a9f\\FractorXml\\', __DIR__ . '/../src/');
1823

24+
$services->set('fractor.xml_processor.indent', Indent::class)
25+
->factory([service(IndentFactory::class), 'create']);
26+
1927
$services->set(XmlFileProcessor::class)
28+
->arg('$indent', service('fractor.xml_processor.indent'))
2029
->arg('$rules', tagged_iterator('fractor.xml_rule'));
2130

31+
$services->set(\PrettyXml\Formatter::class);
32+
$services->alias(Formatter::class, PrettyXmlFormatter::class);
33+
2234
$containerBuilder->registerForAutoconfiguration(XmlFractor::class)->addTag('fractor.xml_rule');
2335
};

packages/fractor-xml/src/AbstractXmlFractor.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
abstract class AbstractXmlFractor implements DomNodeVisitor, XmlFractor
1414
{
15-
private ?File $file = null;
15+
protected ?File $file = null;
1616

17-
public function beforeTraversal(File $file, \DOMNode $rootNode): void
17+
public function beforeTraversal(File $file, \DOMDocument $rootNode): void
1818
{
1919
$this->file = $file;
2020
}
@@ -41,7 +41,7 @@ public function leaveNode(\DOMNode $node): void
4141
// no-op for now
4242
}
4343

44-
public function afterTraversal(\DOMNode $rootNode): void
44+
public function afterTraversal(\DOMDocument $rootNode): void
4545
{
4646
// no-op for now
4747
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorXml\Configuration;
6+
7+
final class XmlProcessorOption
8+
{
9+
public const INDENT_SIZE = 'xml-processor-indent-size';
10+
11+
public const INDENT_CHARACTER = 'xml-processor-indent-character';
12+
}

packages/fractor-xml/src/Contract/DomNodeVisitor.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
interface DomNodeVisitor
1414
{
15-
public function beforeTraversal(File $file, \DOMNode $rootNode): void;
15+
public function beforeTraversal(File $file, \DOMDocument $rootNode): void;
1616

1717
/**
1818
* @return \DOMNode|DomDocumentIterator::*
@@ -21,5 +21,5 @@ public function enterNode(\DOMNode $node): \DOMNode|int;
2121

2222
public function leaveNode(\DOMNode $node): void;
2323

24-
public function afterTraversal(\DOMNode $rootNode): void;
24+
public function afterTraversal(\DOMDocument $rootNode): void;
2525
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorXml\Contract;
6+
7+
use a9f\Fractor\ValueObject\Indent;
8+
9+
interface Formatter
10+
{
11+
public function format(Indent $indent, string $content): string;
12+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorXml;
6+
7+
use a9f\Fractor\ValueObject\Indent;
8+
use a9f\FractorXml\Configuration\XmlProcessorOption;
9+
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
10+
11+
final readonly class IndentFactory
12+
{
13+
public function __construct(
14+
private ContainerBagInterface $parameterBag
15+
) {
16+
}
17+
18+
public function create(): Indent
19+
{
20+
$size = $this->parameterBag->has(XmlProcessorOption::INDENT_SIZE) ? $this->parameterBag->get(
21+
XmlProcessorOption::INDENT_SIZE
22+
) : 4;
23+
$style = $this->parameterBag->has(XmlProcessorOption::INDENT_CHARACTER) ? $this->parameterBag->get(
24+
XmlProcessorOption::INDENT_CHARACTER
25+
) : Indent::STYLE_SPACE;
26+
27+
return Indent::fromSizeAndStyle($size, $style);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorXml;
6+
7+
use a9f\Fractor\ValueObject\Indent;
8+
use a9f\FractorXml\Contract\Formatter;
9+
10+
final readonly class PrettyXmlFormatter implements Formatter
11+
{
12+
public function __construct(
13+
private \PrettyXml\Formatter $prettyXmlFormatter
14+
) {
15+
}
16+
17+
public function format(Indent $indent, string $content): string
18+
{
19+
$indentCharacter = $indent->isSpace() ? Indent::CHARACTERS[Indent::STYLE_SPACE] : Indent::CHARACTERS[Indent::STYLE_TAB];
20+
$this->prettyXmlFormatter->setIndentCharacter($indentCharacter);
21+
$this->prettyXmlFormatter->setIndentSize($indent->length());
22+
23+
return $this->prettyXmlFormatter->format($content);
24+
}
25+
}

packages/fractor-xml/src/XmlFileProcessor.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use a9f\Fractor\Application\Contract\FileProcessor;
88
use a9f\Fractor\Application\ValueObject\File;
99
use a9f\Fractor\Exception\ShouldNotHappenException;
10+
use a9f\Fractor\ValueObject\Indent;
11+
use a9f\FractorXml\Contract\Formatter;
1012
use a9f\FractorXml\Contract\XmlFractor;
1113
use a9f\FractorXml\ValueObjectFactory\DomDocumentFactory;
1214

@@ -20,7 +22,9 @@
2022
*/
2123
public function __construct(
2224
private DomDocumentFactory $domDocumentFactory,
23-
private iterable $rules
25+
private Formatter $formatter,
26+
private iterable $rules,
27+
private Indent $indent
2428
) {
2529
}
2630

@@ -42,6 +46,7 @@ public function handle(File $file, iterable $appliedRules): void
4246
$iterator->traverseDocument($file, $document);
4347

4448
$newXml = $this->saveXml($document);
49+
$newXml = $this->formatter->format($this->indent, $newXml);
4550

4651
if ($newXml === $originalXml) {
4752
return;

packages/fractor-xml/tests/DomDocumentIteratorTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public function __construct(
231231
) {
232232
}
233233

234-
public function beforeTraversal(File $file, \DOMNode $rootNode): void
234+
public function beforeTraversal(File $file, \DOMDocument $rootNode): void
235235
{
236236
$this->calls[] = sprintf('%s:beforeTraversal:%s', $this->visitorName, $rootNode->nodeName);
237237
}
@@ -247,7 +247,7 @@ public function leaveNode(\DOMNode $node): void
247247
$this->calls[] = sprintf('%s:leaveNode:%s', $this->visitorName, $node->nodeName);
248248
}
249249

250-
public function afterTraversal(\DOMNode $rootNode): void
250+
public function afterTraversal(\DOMDocument $rootNode): void
251251
{
252252
$this->calls[] = sprintf('%s:afterTraversal:%s', $this->visitorName, $rootNode->nodeName);
253253
}

packages/fractor/src/Configuration/FractorConfigurationBuilder.php

+19
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ final class FractorConfigurationBuilder
4141
*/
4242
private array $imports = [];
4343

44+
/**
45+
* @var array<string, int|string>
46+
*/
47+
private array $options = [];
48+
4449
public function __invoke(ContainerConfigurator $containerConfigurator): void
4550
{
4651
Assert::allString($this->paths);
@@ -49,6 +54,10 @@ public function __invoke(ContainerConfigurator $containerConfigurator): void
4954
$parameters->set(Option::PATHS, $this->paths);
5055
$parameters->set(Option::SKIP, $this->skip);
5156

57+
foreach ($this->options as $optionName => $optionValue) {
58+
$parameters->set($optionName, $optionValue);
59+
}
60+
5261
$services = $containerConfigurator->services();
5362

5463
foreach ($this->rules as $rule) {
@@ -146,4 +155,14 @@ public function import(string $import): self
146155

147156
return $this;
148157
}
158+
159+
/**
160+
* @param array<string, string|int> $options
161+
*/
162+
public function withOptions(array $options): self
163+
{
164+
$this->options = $options;
165+
166+
return $this;
167+
}
149168
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\Fractor\Helper;
6+
7+
class ArrayUtility
8+
{
9+
/**
10+
* @return string[]
11+
*
12+
* @see GeneralUtility::trimExplode in TYPO3 Core
13+
*/
14+
public static function trimExplode(string $delimiter, string $string, bool $removeEmptyValues = false): array
15+
{
16+
if ($delimiter === '') {
17+
throw new \InvalidArgumentException('Please define a correct delimiter');
18+
}
19+
20+
$result = explode($delimiter, $string);
21+
22+
if ($removeEmptyValues) {
23+
$temp = [];
24+
foreach ($result as $value) {
25+
if (trim($value) !== '') {
26+
$temp[] = $value;
27+
}
28+
}
29+
30+
$result = $temp;
31+
}
32+
33+
return array_map('trim', $result);
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\Fractor\Helper;
6+
7+
class StringUtility
8+
{
9+
/**
10+
* Check if an item exists in a comma-separated list of items.
11+
*
12+
* @param string $list Comma-separated list of items (string)
13+
* @param string $item Item to check for
14+
* @return bool TRUE if $item is in $list
15+
*
16+
* @see GeneralUtility::inList in TYPO3 Core
17+
*/
18+
public static function inList(string $list, string $item): bool
19+
{
20+
return str_contains(',' . $list . ',', ',' . $item . ',');
21+
}
22+
}

packages/fractor/src/ValueObject/Indent.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
*/
1313
final readonly class Indent
1414
{
15+
public const STYLE_SPACE = 'space';
16+
17+
public const STYLE_TAB = 'tab';
18+
1519
/**
1620
* @var array<string, string>
1721
*/
1822
public const CHARACTERS = [
19-
'space' => ' ',
20-
'tab' => "\t",
23+
self::STYLE_SPACE => ' ',
24+
self::STYLE_TAB => "\t",
2125
];
2226

2327
private function __construct(
@@ -41,15 +45,18 @@ public function toString(): string
4145

4246
public function isSpace(): bool
4347
{
44-
return \preg_match('#^( +).*#', $this->value) === 1;
48+
return \preg_match('/^( +)/', $this->value) === 1;
4549
}
4650

4751
public function length(): int
4852
{
4953
return strlen($this->value);
5054
}
5155

52-
private static function fromSizeAndStyle(int $size, string $style): self
56+
/**
57+
* @phpstan-param self::STYLE_* $style
58+
*/
59+
public static function fromSizeAndStyle(int $size, string $style): self
5360
{
5461
Assert::greaterThanEq($size, 1);
5562
Assert::keyExists(self::CHARACTERS, $style);

0 commit comments

Comments
 (0)