• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wol-soft / php-json-schema-model-generator / 17651542034

11 Sep 2025 04:52PM UTC coverage: 96.804% (-1.8%) from 98.564%
17651542034

Pull #92

github

wol-soft
BuilderClassPostProcessor draft
Pull Request #92: BuilderClassPostProcessor

70 of 133 new or added lines in 8 files covered. (52.63%)

4 existing lines in 1 file now uncovered.

3332 of 3442 relevant lines covered (96.8%)

563.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/SchemaProcessor/PostProcessor/BuilderClassPostProcessor.php
1
<?php
2

3
declare(strict_types = 1);
4

5
namespace PHPModelGenerator\SchemaProcessor\PostProcessor;
6

7
use PHPMicroTemplate\Render;
8
use PHPModelGenerator\Exception\FileSystemException;
9
use PHPModelGenerator\Model\GeneratorConfiguration;
10
use PHPModelGenerator\Model\Property\PropertyInterface;
11
use PHPModelGenerator\Model\Property\PropertyType;
12
use PHPModelGenerator\Model\Schema;
13
use PHPModelGenerator\Model\Validator;
14
use PHPModelGenerator\Model\Validator\FilterValidator;
15
use PHPModelGenerator\PropertyProcessor\Decorator\TypeHint\TypeHintTransferDecorator;
16
use PHPModelGenerator\Utils\RenderHelper;
17

18
/**
19
 * Class PopulatePostProcessor
20
 *
21
 * @package PHPModelGenerator\SchemaProcessor\PostProcessor
22
 */
23
class BuilderClassPostProcessor extends PostProcessor
24
{
25
    /** @var Schema[] */
26
    private array $schemas = [];
27
    private GeneratorConfiguration $generatorConfiguration;
28

NEW
29
    public function process(Schema $schema, GeneratorConfiguration $generatorConfiguration): void
×
30
    {
NEW
31
        $this->schemas[] = $schema;
×
NEW
32
        $this->generatorConfiguration = $generatorConfiguration;
×
33
    }
34

NEW
35
    public function postProcess(): void
×
36
    {
NEW
37
        parent::postProcess();
×
38

39
        // TODO: implicit null?
40
        // TODO: nested objects
41

NEW
42
        foreach ($this->schemas as $schema) {
×
NEW
43
            $properties = [];
×
NEW
44
            foreach ($schema->getProperties() as $property) {
×
NEW
45
                if (!$property->isInternal()) {
×
NEW
46
                    $properties[] = (clone $property)
×
NEW
47
                        ->setReadOnly(false)
×
NEW
48
                        ->setType($property->getType(), new PropertyType($property->getType(true)->getName(), true))
×
NEW
49
                        ->addTypeHintDecorator(new TypeHintTransferDecorator($property))
×
NEW
50
                        ->filterValidators(static fn(Validator $validator): bool
×
NEW
51
                            => is_a($validator->getValidator(), FilterValidator::class)
×
NEW
52
                        );
×
53
                }
54
            }
55

NEW
56
            $this->generateModelDirectory($schema->getTargetFileName());
×
57

NEW
58
            $namespace = trim(
×
NEW
59
                join('\\', [$this->generatorConfiguration->getNamespacePrefix(), $schema->getClassPath()]),
×
NEW
60
                '\\',
×
NEW
61
            );
×
62

NEW
63
            $result = file_put_contents(
×
NEW
64
                str_replace('.php', 'Builder.php', $schema->getTargetFileName()),
×
NEW
65
                (new Render(__DIR__ . DIRECTORY_SEPARATOR . 'Templates' . DIRECTORY_SEPARATOR))->renderTemplate(
×
NEW
66
                    'BuilderClass.phptpl',
×
NEW
67
                    [
×
NEW
68
                        'namespace'              => $namespace,
×
NEW
69
                        'class'                  => $schema->getClassName(),
×
NEW
70
                        'schema'                 => $schema,
×
NEW
71
                        'properties'             => $properties,
×
NEW
72
                        'use'                    => $this->getBuilderClassImports($properties, $schema->getUsedClasses(), $namespace),
×
NEW
73
                        'generatorConfiguration' => $this->generatorConfiguration,
×
NEW
74
                        'viewHelper'             => new RenderHelper($this->generatorConfiguration),
×
NEW
75
                    ],
×
NEW
76
                )
×
NEW
77
            );
×
78

NEW
79
            $fqcn = "{$schema->getClassPath()}\\{$schema->getClassName()}Builder";
×
80

NEW
81
            if ($result === false) {
×
82
                // @codeCoverageIgnoreStart
83
                throw new FileSystemException("Can't write builder class $fqcn.",);
84
                // @codeCoverageIgnoreEnd
85
            }
86

NEW
87
            if ($this->generatorConfiguration->isOutputEnabled()) {
×
88
                // @codeCoverageIgnoreStart
89
                echo "Rendered builder class $fqcn\n";
90
                // @codeCoverageIgnoreEnd
91
            }
92
        }
93
    }
94

NEW
95
    protected function generateModelDirectory(string $targetFileName): void
×
96
    {
NEW
97
        $destination = dirname($targetFileName);
×
NEW
98
        if (!is_dir($destination) && !mkdir($destination, 0777, true)) {
×
NEW
99
            throw new FileSystemException("Can't create path $destination");
×
100
        }
101
    }
102

103
    /**
104
     * @param PropertyInterface[] $properties
105
     *
106
     * @return string[]
107
     */
NEW
108
    private function getBuilderClassImports(array $properties, array $originalClassImports, string $namespace): array
×
109
    {
NEW
110
        $imports = [];
×
111

NEW
112
        if ($this->generatorConfiguration->collectErrors()) {
×
NEW
113
            $imports[] = $this->generatorConfiguration->getErrorRegistryClass();
×
114
        }
115

NEW
116
        foreach ($properties as $property) {
×
NEW
117
            foreach (array_unique(
×
NEW
118
                [...explode('|', $property->getTypeHint()), ...explode('|', $property->getTypeHint(true))]
×
NEW
119
            ) as $type) {
×
120
                // as the typehint only knows the class name but not the fqcn, lookup in the original imports
NEW
121
                foreach ($originalClassImports as $originalClassImport) {
×
NEW
122
                    if (str_ends_with($originalClassImport, "\\$type")) {
×
NEW
123
                        $type = $originalClassImport;
×
124
                    }
125
                }
126

NEW
127
                if (class_exists($type)) {
×
NEW
128
                    $imports[] = $type;
×
129
                }
130
            }
131
        }
132

NEW
133
        return RenderHelper::filterClassImports(array_unique($imports), $namespace);
×
134
    }
135
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc