View Issue Details

IDProjectCategoryView StatusLast Update
0007979OXID eShop (all versions)8. --- Twig engine ---public2026-08-20 12:20
ReporterLarsStegelitz Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status acknowledgedResolutionopen 
Summary0007979: smarty-to-twig-converter
DescriptionDer Smarty-to-Twig-Converter konvertiert die folgende Zeile falsch:
[{assign var="webconnectFileMTime" value=$oViewConf->getModulePath('oxps/webconnect', 'out/src/js/webconnecterp_productlists.js')|filemtime}]

Diese Zeile wird übersetzt zu:
{% set webconnectFileMTime = oViewConf.getModulePath('oxps/webconnect', %}

Erwartete Ausgabe:
{% set webconnectFileMTime = oViewConf.getModulePath('oxps/webconnect', 'out/src/js/webconnecterp_productlists.js')|filetime %}

Steps To ReproduceKonverter installieren, tpl Datei mit dieser Zeile anlegen:
[{assign var="webconnectFileMTime" value=$oViewConf->getModulePath('oxps/webconnect', 'out/src/js/webconnecterp_productlists.js')|filemtime}]

Konverter auf diese Datei loslassen, Resultat anschauen.
TagsNo tags attached.
ThemeNot defined
BrowserNot defined
PHP VersionNot defined
Database VersionNot defined

Activities

michael_keiluweit

2026-08-20 11:41

administrator   ~0018633

Subject under test: `oxid-esales/smarty-to-twig-converter` v1.0.1, run standalone on PHP 8.3. No shop
is involved: the converter rewrites template text and never renders anything, so no Smarty
installation and no specific shop version is needed to see the defect.

1. Install the converter into an empty directory. The package declares `php ^7.1`, so on PHP 8.3 the
   install needs `--ignore-platform-reqs`, and Composer refuses one of its dev dependencies over a
   security advisory, so `audit.block-insecure=false` is required as well.
   Result: `oxid-esales/smarty-to-twig-converter v1.0.1` installed.
2. Create the template from the ticket, verbatim, in a directory the converter will scan:
   `[{assign var="webconnectFileMTime" value=$oViewConf->getModulePath('oxps/webconnect', 'out/src/js/webconnecterp_productlists.js')|filemtime}]`
3. Run the converter: `vendor/bin/toTwig convert --path=<dir>`. The symfony/finder deprecation
   notices on PHP 8.3 are noise and do not affect the result.
4. Read the produced `.html.twig` file.
   Observed: `{% set webconnectFileMTime = oViewConf.getModulePath('oxps/webconnect', %}` — the second
   argument, the closing parenthesis and the filter are gone. This is exactly what the report claims.
5. Control A, same line but without the space after the comma.
   Observed: `{% set m = oViewConf.getModulePath('oxps/webconnect', 'out/src/js/webconnecterp_productlists.js')|filemtime %}`
   — correct and complete. So neither the two-argument call nor the `|filemtime` filter is the trigger.
6. Control B, space after the comma but no filter at all.
   Observed: truncated in the same way.
7. Control C, two spaces after the comma, and Control D, a different filter (`|cat:'foo'`).
   Observed: both truncated in the same way.

Conclusion from the controls: the trigger is whitespace between function arguments, not the filter.
Any Smarty call whose arguments are separated by a comma followed by a space is cut off at that comma.
Removing the space produces correct output, which is also the workaround for anyone blocked by this
during a migration.

## Root cause as located during the run

`app/toTwig/Converter/ConverterAbstract.php`, method `extractAttributes()`, the attribute regex around
lines 134-135. The value capture

```
(?:".*?"|'.*?'|(?:[$\w\->():]+))(?:[\|]?(?:'\s+'|"\s+"|[^\s}]|(}(?!])))*)
```

cannot continue across a bare space inside the expression: the alternation accepts quoted strings or
non-space characters, but nothing that allows an unquoted space to be part of the same value. The match
therefore ends right after `$oViewConf->getModulePath('oxps/webconnect',` and everything from the space
onwards, including the second argument, the closing parenthesis and any filter, is dropped.

Workaround: remove the space after the comma in the argument list. The converter then keeps the whole expression, filter included.

-QA