Skip to content

Commit 7d57d1a

Browse files
committed
fix: prevent creating reserved name classes
1 parent c5120a8 commit 7d57d1a

123 files changed

Lines changed: 4713 additions & 4287 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/phpmd.md

Lines changed: 1002 additions & 0 deletions
Large diffs are not rendered by default.

src/Command/BatchGeneratorCommand.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Html\Element\BlockElement;
1414
use Html\Element\InlineElement;
1515
use Html\Element\VoidElement;
16+
use Html\Helper\Helper;
1617
use Html\Trait\ClassResolverTrait;
1718
use Html\Trait\GeneratorResolverTrait;
1819
use ReflectionClass;
@@ -114,7 +115,7 @@ public function __invoke(
114115
// Generate PHP component class for twig-component generator
115116
if ($name === 'twig-component' && method_exists($generatorInstance, 'renderComponentClass')) {
116117
$componentClass = $generatorInstance->renderComponentClass($elementInstance);
117-
$componentName = ucfirst($elementInstance::QUALIFIED_NAME);
118+
$componentName = $this->getSafeComponentClassName(ucfirst($elementInstance::QUALIFIED_NAME));
118119

119120
// PHP classes go in src/Twig/{Block|Inline|Void}
120121
$levelCap = ucfirst($level);
@@ -227,9 +228,9 @@ private function generateBundleFiles(string $bundleDir, bool $overwrite): void
227228
228229
/**
229230
* HTML Component Bundle
230-
*
231+
*
231232
* Provides Symfony UX Twig Components for all HTML5 elements with ARIA support.
232-
*
233+
*
233234
* @author vardumper <info@erikpoehler.com>
234235
* @package Html\ComponentBundle
235236
*/
@@ -319,4 +320,16 @@ public function getPath(): string
319320
$this->io->success("Generated: {$readmeFile}");
320321
}
321322
}
323+
324+
/**
325+
* Get safe component class name, avoiding PHP reserved words
326+
*/
327+
private function getSafeComponentClassName(string $className): string
328+
{
329+
$reserved = Helper::getReservedWords();
330+
if (in_array(strtolower($className), $reserved, true)) {
331+
return $className . 'Element';
332+
}
333+
return $className;
334+
}
322335
}

src/TemplateGenerator/TwigComponentsGenerator.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Html\TemplateGenerator;
44

5+
use Html\Helper\Helper;
56
use Html\Interface\HTMLElementDelegatorInterface;
67
use Html\Interface\TemplateGeneratorInterface;
78
use Html\Mapping\TemplateGenerator;
@@ -101,7 +102,7 @@ public function renderComponentClass(HTMLElementDelegatorInterface $element): st
101102
? $ref->getConstant('QUALIFIED_NAME')
102103
: strtolower($ref->getShortName());
103104

104-
$componentName = ucfirst($elementName);
105+
$componentName = $this->getComponentClassName(ucfirst($elementName));
105106

106107
// Determine the level (Block, Inline, or Void)
107108
$level = $this->determineComponentLevel($ref->getName());
@@ -282,6 +283,9 @@ public function renderComponentClass(HTMLElementDelegatorInterface $element): st
282283
return "'{$type}'";
283284
}, $propData['allowedTypes']);
284285

286+
if (in_array('null', $propData['allowedTypes'])) {
287+
$php .= " \$resolver->setDefaults(['{$propName}' => null]);\n";
288+
}
285289
$php .= " \$resolver->setAllowedTypes('{$propName}', [" . implode(
286290
', ',
287291
$allowedTypesFormatted
@@ -416,6 +420,7 @@ private function renderTemplate(HTMLElementDelegatorInterface $element): string
416420
}
417421
}
418422
$name = ucfirst($elementName);
423+
$componentName = $this->getComponentClassName(ucfirst($elementName));
419424

420425
// Build Twig Component template
421426
$twig = "{#\n";
@@ -424,7 +429,7 @@ private function renderTemplate(HTMLElementDelegatorInterface $element): string
424429
$twig .= " Symfony UX Twig Component (Anonymous)\n";
425430
$twig .= " @see https://symfony.com/bundles/ux-twig-component/current/index.html\n\n";
426431
$twig .= " Usage:\n";
427-
$twig .= ' <twig:' . ucfirst($elementName);
432+
$twig .= ' <twig:' . $componentName;
428433

429434
// Add example usage
430435
$exampleProps = [];
@@ -447,7 +452,7 @@ private function renderTemplate(HTMLElementDelegatorInterface $element): string
447452
} else {
448453
$twig .= ">\n";
449454
$twig .= " Content goes here\n";
450-
$twig .= ' </twig:' . ucfirst($elementName) . ">\n";
455+
$twig .= ' </twig:' . $componentName . ">\n";
451456
}
452457

453458
$twig .= "\n @author vardumper <info@erikpoehler.com>\n";
@@ -495,7 +500,7 @@ private function buildComposedTemplate(
495500
string $description,
496501
array $parentOf
497502
): string {
498-
$componentName = ucfirst($elementName);
503+
$componentName = $this->getComponentClassName(ucfirst($elementName));
499504

500505
$twig = "{#\n";
501506
$twig .= " This file is auto-generated.\n\n";
@@ -550,7 +555,7 @@ private function collectChildrenForComposedTemplate(array $parentOf): array
550555
? $childRef->getConstant('QUALIFIED_NAME')
551556
: strtolower($childRef->getShortName());
552557

553-
$childComponentName = ucfirst($childElementName);
558+
$childComponentName = $this->getComponentClassName(ucfirst($childElementName));
554559
$isSelfClosing = $childRef->hasConstant('SELF_CLOSING') && $childRef->getConstant('SELF_CLOSING');
555560

556561
$twigCode = '';
@@ -606,4 +611,16 @@ private function determineComponentLevel(string $className): string
606611
}
607612
return 'block';
608613
}
614+
615+
/**
616+
* Get safe component class name, avoiding PHP reserved words
617+
*/
618+
private function getComponentClassName(string $className): string
619+
{
620+
$reserved = Helper::getReservedWords();
621+
if (in_array(strtolower($className), $reserved, true)) {
622+
return $className . 'Element';
623+
}
624+
return $className;
625+
}
609626
}

templates/twig-component/README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
# Twig Component Bundle with all HTML5 elements
1+
# HTML Component Bundle
22

3-
Symfony UX Twig Components for all HTML5 elements with ARIA support and static attribute validation via Enums.
4-
It provides auto-completion in your IDE of choice, so all available attributes can be quickly accessed.
3+
Symfony UX Twig Components for all HTML5 elements with ARIA support.
54

65
## Installation
76

87
```bash
9-
composer require vardumper/html5-twig-component-bundle
8+
composer require html/component-bundle
109
```
1110

1211
## Configuration
@@ -16,7 +15,7 @@ Register the bundle in `config/bundles.php`:
1615
```php
1716
return [
1817
// ...
19-
Html\TwigComponentBundle\HtmlTwigComponentBundle::class => ['all' => true],
18+
Html\ComponentBundle\HtmlComponentBundle::class => ['all' => true],
2019
];
2120
```
2221

@@ -51,8 +50,6 @@ Components are organized by type:
5150
- `Inline` - Inline elements (span, a, strong, etc.)
5251
- `Void` - Self-closing elements (img, input, br, etc.)
5352

54-
## Read More
55-
* [Extended HTMLDocument Documentation](https://vardumper.github.io/extended-htmldocument/)
56-
* [Extended HTMLDocument Github Repository](https://github.com/vardumper/extended-htmldocument)
57-
* [Twig Components](https://symfony.com/bundles/ux-twig-component/current/index.html)
58-
* [Symfony UX](https://ux.symfony.com/)
53+
## License
54+
55+
MIT

templates/twig-component/composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "vardumper/html5-twig-component-bundle",
2+
"name": "vardumper/html5-ux-twig-component-bundle",
33
"description": "Symfony UX Twig Components for typesafe HTML5 elements with ARIA support & enum validation",
44
"type": "symfony-bundle",
55
"license": "MIT",
@@ -9,7 +9,7 @@
99
"components",
1010
"html5",
1111
"aria",
12-
"symfony-ux"
12+
"ux"
1313
],
1414
"authors": [
1515
{
@@ -18,7 +18,7 @@
1818
}
1919
],
2020
"require": {
21-
"php": "^8.4",
21+
"php": "^8.2",
2222
"symfony/twig-bundle": "^6.0|^7.0",
2323
"symfony/ux-twig-component": "^2.0",
2424
"vardumper/extended-htmldocument": "^0.2"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Html\ComponentBundle;
4+
5+
use Symfony\Component\HttpKernel\Bundle\Bundle;
6+
7+
/**
8+
* HTML Component Bundle
9+
*
10+
* Provides Symfony UX Twig Components for all HTML5 elements with ARIA support.
11+
*
12+
* @author vardumper <info@erikpoehler.com>
13+
* @package Html\ComponentBundle
14+
*/
15+
class HtmlComponentBundle extends Bundle
16+
{
17+
public function getPath(): string
18+
{
19+
return \dirname(__DIR__);
20+
}
21+
}

templates/twig-component/src/Resources/block/object/object.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
@see https://symfony.com/bundles/ux-twig-component/current/index.html
88
99
Usage:
10-
<twig:Object ariaAtomic="false" ariaBusy="true">
10+
<twig:ObjectElement ariaAtomic="false" ariaBusy="true">
1111
Content goes here
12-
</twig:Object>
12+
</twig:ObjectElement>
1313
1414
@author vardumper <info@erikpoehler.com>
1515
@package vardumper/extended-htmldocument

templates/twig-component/src/Resources/inline/var/var.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
@see https://symfony.com/bundles/ux-twig-component/current/index.html
88
99
Usage:
10-
<twig:Var ariaAtomic="false" ariaBusy="true">
10+
<twig:VarElement ariaAtomic="false" ariaBusy="true">
1111
Content goes here
12-
</twig:Var>
12+
</twig:VarElement>
1313
1414
@author vardumper <info@erikpoehler.com>
1515
@package vardumper/extended-htmldocument

0 commit comments

Comments
 (0)