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

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

03 Dec 2025 04:23PM UTC coverage: 98.665%. Remained the same
19900971490

push

github

wol-soft
Make code output stable across multiple runs (#41)

2 of 2 new or added lines in 2 files covered. (100.0%)

3399 of 3445 relevant lines covered (98.66%)

566.51 hits per line

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

98.44
/src/Model/RenderJob.php
1
<?php
2

3
declare(strict_types = 1);
4

5
namespace PHPModelGenerator\Model;
6

7
use PHPMicroTemplate\Exception\PHPMicroTemplateException;
8
use PHPMicroTemplate\Render;
9
use PHPModelGenerator\Exception\FileSystemException;
10
use PHPModelGenerator\Exception\RenderException;
11
use PHPModelGenerator\Exception\ValidationException;
12
use PHPModelGenerator\Model\Validator\AbstractComposedPropertyValidator;
13
use PHPModelGenerator\SchemaProcessor\Hook\SchemaHookResolver;
14
use PHPModelGenerator\SchemaProcessor\PostProcessor\PostProcessor;
15
use PHPModelGenerator\Utils\RenderHelper;
16

17
/**
18
 * Class RenderJob
19
 *
20
 * @package PHPModelGenerator\Model
21
 */
22
class RenderJob
23
{
24
    /**
25
     * Create a new class render job
26
     *
27
     * @param Schema $schema The Schema object which holds properties and validators
28
     */
29
    public function __construct(
1,916✔
30
        protected Schema $schema,
31
    ) {}
1,916✔
32

33
    /**
34
     * @param PostProcessor[] $postProcessors
35
     */
36
    public function executePostProcessors(array $postProcessors, GeneratorConfiguration $generatorConfiguration): void
1,916✔
37
    {
38
        foreach ($postProcessors as $postProcessor) {
1,916✔
39
            $postProcessor->process($this->schema, $generatorConfiguration);
1,916✔
40
        }
41
    }
42

43
    /**
44
     * Execute the render job and render the class
45
     *
46
     * @throws FileSystemException
47
     * @throws RenderException
48
     */
49
    public function render(GeneratorConfiguration $generatorConfiguration): void
1,901✔
50
    {
51
        $this->generateModelDirectory();
1,901✔
52

53
        $class = $this->renderClass($generatorConfiguration);
1,901✔
54

55
        if (file_exists($this->schema->getTargetFileName())) {
1,901✔
56
            throw new FileSystemException(
1✔
57
                "File {$this->schema->getTargetFileName()} already exists. Make sure object IDs are unique.",
1✔
58
            );
1✔
59
        }
60

61
        if (!file_put_contents($this->schema->getTargetFileName(), $class)) {
1,901✔
62
            // @codeCoverageIgnoreStart
63
            throw new FileSystemException(
64
                "Can't write class {$this->schema->getClassPath()}\\{$this->schema->getClassName()}.",
65
            );
66
            // @codeCoverageIgnoreEnd
67
        }
68

69
        require $this->schema->getTargetFileName();
1,901✔
70

71
        if ($generatorConfiguration->isOutputEnabled()) {
1,901✔
72
            echo sprintf(
1✔
73
                "Rendered class %s\n",
1✔
74
                join(
1✔
75
                    '\\',
1✔
76
                    array_filter([
1✔
77
                        $generatorConfiguration->getNamespacePrefix(),
1✔
78
                        $this->schema->getClassPath(),
1✔
79
                        $this->schema->getClassName(),
1✔
80
                    ]),
1✔
81
                ),
1✔
82
            );
1✔
83
        }
84
    }
85

86
    /**
87
     * Generate the directory structure for saving a generated class
88
     *
89
     * @throws FileSystemException
90
     */
91
    protected function generateModelDirectory(): void
1,901✔
92
    {
93
        $destination = dirname($this->schema->getTargetFileName());
1,901✔
94
        if (!is_dir($destination) && !mkdir($destination, 0777, true)) {
1,901✔
95
            // @codeCoverageIgnoreStart
96
            throw new FileSystemException("Can't create path $destination");
97
            // @codeCoverageIgnoreEnd
98
        }
99
    }
100

101
    /**
102
     * Render a class. Returns the php code of the class
103
     *
104
     * @throws RenderException
105
     */
106
    protected function renderClass(GeneratorConfiguration $generatorConfiguration): string
1,901✔
107
    {
108
        $namespace = trim(
1,901✔
109
            join('\\', [$generatorConfiguration->getNamespacePrefix(), $this->schema->getClassPath()]),
1,901✔
110
            '\\',
1,901✔
111
        );
1,901✔
112

113
        try {
114
            $class = (new Render(__DIR__ . '/../Templates/'))->renderTemplate(
1,901✔
115
                'Model.phptpl',
1,901✔
116
                [
1,901✔
117
                    'namespace'                         => $namespace,
1,901✔
118
                    'use'                               => $this->getUseForSchema($generatorConfiguration, $namespace),
1,901✔
119
                    'schema'                            => $this->schema,
1,901✔
120
                    'schemaHookResolver'                => new SchemaHookResolver($this->schema),
1,901✔
121
                    'generatorConfiguration'            => $generatorConfiguration,
1,901✔
122
                    'viewHelper'                        => new RenderHelper($generatorConfiguration),
1,901✔
123
                    // one hack a day keeps the problems away. Make true literal available for the templating. Easy fix
124
                    'true'                              => true,
1,901✔
125
                    'baseValidatorsWithoutCompositions' => array_filter(
1,901✔
126
                        $this->schema->getBaseValidators(),
1,901✔
127
                        static fn($validator): bool => !is_a($validator, AbstractComposedPropertyValidator::class),
1,901✔
128
                    ),
1,901✔
129
                ],
1,901✔
130
            );
1,901✔
131
        } catch (PHPMicroTemplateException $exception) {
×
132
            // @codeCoverageIgnoreStart
133
            throw new RenderException(
134
                "Can't render class {$this->schema->getClassPath()}\\{$this->schema->getClassName()}",
135
                0,
136
                $exception,
137
            );
138
            // @codeCoverageIgnoreEnd
139
        }
140

141
        return $class;
1,901✔
142
    }
143

144
    /**
145
     * @return string[]
146
     */
147
    protected function getUseForSchema(GeneratorConfiguration $generatorConfiguration, string $namespace): array
1,901✔
148
    {
149
        return RenderHelper::filterClassImports(
1,901✔
150
            array_unique(
1,901✔
151
                array_merge(
1,901✔
152
                    $this->schema->getUsedClasses(),
1,901✔
153
                    $generatorConfiguration->collectErrors()
1,901✔
154
                        ? [$generatorConfiguration->getErrorRegistryClass()]
497✔
155
                        : [ValidationException::class],
1,901✔
156
                ),
1,901✔
157
            ),
1,901✔
158
            $namespace,
1,901✔
159
        );
1,901✔
160
    }
161
}
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

© 2025 Coveralls, Inc