Skip to content

HTML minification breaks PHP code #32153

Open
@jtomaszewski

Description

After upgrading from Magento 2.4.1 to 2.4.2 we started getting such an error:

ParseError: syntax error, unexpected '<', expecting elseif (T_ELSEIF) or else (T_ELSE) or endif (T_ENDIF) in /app/m/var/view_preprocessed/pub/static/app/design/frontend/creativestyle/theme-creativeshop/Magento_Catalog/templates/addtocart/button.phtml:1
Stack trace:
#0 /app/m/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\Framework\View\Element\Template\Interceptor), '/app/m/var/view...', Array)

It happens only when html minification is enabled.

This happens for the following file:

<?php
    $buttonType = $block->getButtonType() ?? 'submit';
    $buttonLabel = $block->getAddtocartLabel() ?? __($block->getVar('ajax_addtocart/labels/default', 'Magento_Catalog'));
    $canBeConfigured = $block->getCanBeConfigured();
?>

<div class="cs-addtocart__wrapper">
<button type="<?= $buttonType ?>" title="<?= $buttonLabel ?>"
        class="tocart primary <?= $block->getButtonClass() ?? $block->getVar('ajax_addtocart/css_classes/default_button', 'Magento_Catalog') ?>"
        <?= $block->getButtonParams() ?>
>
    <?php if(!empty($block->getVar('ajax_addtocart/icons/default/path', 'Magento_Catalog'))): ?>
        <?php $variablesPath = 'ajax_addtocart/icons/' . ($canBeConfigured ? 'configure' : 'default'); ?>
        <?= $this->getLayout()
               ->createBlock('MageSuite\ThemeHelpers\Block\Icon')
               ->setIconUrl($block->getVar($variablesPath . '/path', 'Magento_Catalog'))
               ->setCssClass($block->getVar($variablesPath . '/css_class', 'Magento_Catalog'))
               ->setInlined($block->getVar($variablesPath . '/inlined', 'Magento_Catalog'))
               ->setLazyLoaded($block->getVar($variablesPath . '/lazy_loaded', 'Magento_Catalog'))
               ->toHtml();
        ?>
    <?php endif; ?>

    <?php if(!empty($buttonLabel)): ?>
        <strong class="<?= $block->getButtonLabelClass() ?? $block->getVar('ajax_addtocart/css_classes/default_label', 'Magento_Catalog') ?>"><?= $buttonLabel ?></strong>
    <?php endif; ?>

    <?php if($block->getVar('ajax_addtocart/enabled', 'Magento_Catalog')): ?>
        <?php // If you use ajax method for adding products to cart, don't use <span> inside button because Magento will replace its contents with "Adding..." and "Added". Use <strong> instead. ?>
        <?php
            $processingLabel = __($block->getVar('ajax_addtocart/labels/processing', 'Magento_Catalog'));
            $successLabel = __($block->getVar('ajax_addtocart/labels/success', 'Magento_Catalog'));
            $failLabel = __($block->getVar('ajax_addtocart/labels/fail', 'Magento_Catalog'));
        ?>

        <?php // Processing ?>
        <?php include ($block->getTemplateFile('Magento_Catalog::addtocart/loading-indicator.phtml')); ?>
        <?php if(!empty($processingLabel)): ?>
            <strong class="<?= $block->getVar('ajax_addtocart/css_classes/processing_label', 'Magento_Catalog') ?>"><?= $processingLabel ?></strong>
        <?php endif; ?>

        <?php // Done ?>
        <strong class="<?= $block->getVar('ajax_addtocart/css_classes/success_overlay', 'Magento_Catalog') ?>"></strong>
        <?php if(!empty($block->getVar('ajax_addtocart/icons/success/path', 'Magento_Catalog'))): ?>
            <?= $this->getLayout()
                   ->createBlock('MageSuite\ThemeHelpers\Block\Icon')
                   ->setIconUrl($block->getVar('ajax_addtocart/icons/success/path', 'Magento_Catalog'))
                   ->setCssClass($block->getVar('ajax_addtocart/icons/success/css_class', 'Magento_Catalog'))
                   ->setInlined($block->getVar('ajax_addtocart/icons/success/inlined', 'Magento_Catalog'))
                   ->setLazyLoaded($block->getVar('ajax_addtocart/icons/success/lazy_loaded', 'Magento_Catalog'))
                   ->toHtml();
            ?>
        <?php endif; ?>
        <?php if(!empty($successLabel)): ?>
            <strong class="<?= $block->getVar('ajax_addtocart/css_classes/success_label', 'Magento_Catalog') ?>"><?= $successLabel ?></strong>
        <?php endif; ?>

        <?php // Done but failed ?>
        <?php if(!empty($block->getVar('ajax_addtocart/icons/fail/path', 'Magento_Catalog'))): ?>
            <?= $this->getLayout()
                   ->createBlock('MageSuite\ThemeHelpers\Block\Icon')
                   ->setIconUrl($block->getVar('ajax_addtocart/icons/fail/path', 'Magento_Catalog'))
                   ->setCssClass($block->getVar('ajax_addtocart/icons/fail/css_class', 'Magento_Catalog'))
                   ->setInlined($block->getVar('ajax_addtocart/icons/fail/inlined', 'Magento_Catalog'))
                   ->setLazyLoaded($block->getVar('ajax_addtocart/icons/fail/lazy_loaded', 'Magento_Catalog'))
                   ->toHtml();
            ?>
        <?php endif; ?>
        <?php if(!empty($failLabel)): ?>
            <strong class="<?= $block->getVar('ajax_addtocart/css_classes/fail_label', 'Magento_Catalog') ?>"><?= $failLabel ?></strong>
        <?php endif; ?>
    <?php endif; ?>
</button>
</div>

It gets minified to this:

<?php $buttonType = $block->getButtonType() ?? 'submit'; $buttonLabel = $block->getAddtocartLabel() ?? __($block->getVar('ajax_addtocart/labels/default', 'Magento_Catalog')); $canBeConfigured = $block->getCanBeConfigured(); ?> <div class="cs-addtocart__wrapper"><button type="<?= $buttonType ?>" title="<?= $buttonLabel ?>" class="tocart primary <?= $block->getButtonClass() ?? $block->getVar('ajax_addtocart/css_classes/default_button', 'Magento_Catalog') ?>" <?= $block->getButtonParams() ?> ><?php if(!empty($block->getVar('ajax_addtocart/icons/default/path', 'Magento_Catalog'))): ?> <?php $variablesPath = 'ajax_addtocart/icons/' . ($canBeConfigured ? 'configure' : 'default'); ?> <?= $this->getLayout() ->createBlock('MageSuite\ThemeHelpers\Block\Icon') ->setIconUrl($block->getVar($variablesPath . '/path', 'Magento_Catalog')) ->setCssClass($block->getVar($variablesPath . '/css_class', 'Magento_Catalog')) ->setInlined($block->getVar($variablesPath . '/inlined', 'Magento_Catalog')) ->setLazyLoaded($block->getVar($variablesPath . '/lazy_loaded', 'Magento_Catalog')) ->toHtml(); ?> <?php endif; ?> <?php if(!empty($buttonLabel)): ?> <strong class="<?= $block->getButtonLabelClass() ?? $block->getVar('ajax_addtocart/css_classes/default_label', 'Magento_Catalog') ?>"><?= $buttonLabel ?></strong> <?php endif; ?> <?php if($block->getVar('ajax_addtocart/enabled', 'Magento_Catalog')): ?> <?php <?php $processingLabel = __($block->getVar('ajax_addtocart/labels/processing', 'Magento_Catalog')); $successLabel = __($block->getVar('ajax_addtocart/labels/success', 'Magento_Catalog')); $failLabel = __($block->getVar('ajax_addtocart/labels/fail', 'Magento_Catalog')); ?> <?php ?> <?php include ($block->getTemplateFile('Magento_Catalog::addtocart/loading-indicator.phtml')); ?> <?php if(!empty($processingLabel)): ?> <strong class="<?= $block->getVar('ajax_addtocart/css_classes/processing_label', 'Magento_Catalog') ?>"><?= $processingLabel ?></strong> <?php endif; ?> <?php ?> <strong class="<?= $block->getVar('ajax_addtocart/css_classes/success_overlay', 'Magento_Catalog') ?>"></strong> <?php if(!empty($block->getVar('ajax_addtocart/icons/success/path', 'Magento_Catalog'))): ?> <?= $this->getLayout() ->createBlock('MageSuite\ThemeHelpers\Block\Icon') ->setIconUrl($block->getVar('ajax_addtocart/icons/success/path', 'Magento_Catalog')) ->setCssClass($block->getVar('ajax_addtocart/icons/success/css_class', 'Magento_Catalog')) ->setInlined($block->getVar('ajax_addtocart/icons/success/inlined', 'Magento_Catalog')) ->setLazyLoaded($block->getVar('ajax_addtocart/icons/success/lazy_loaded', 'Magento_Catalog')) ->toHtml(); ?> <?php endif; ?> <?php if(!empty($successLabel)): ?> <strong class="<?= $block->getVar('ajax_addtocart/css_classes/success_label', 'Magento_Catalog') ?>"><?= $successLabel ?></strong> <?php endif; ?> <?php ?> <?php if(!empty($block->getVar('ajax_addtocart/icons/fail/path', 'Magento_Catalog'))): ?> <?= $this->getLayout() ->createBlock('MageSuite\ThemeHelpers\Block\Icon') ->setIconUrl($block->getVar('ajax_addtocart/icons/fail/path', 'Magento_Catalog')) ->setCssClass($block->getVar('ajax_addtocart/icons/fail/css_class', 'Magento_Catalog')) ->setInlined($block->getVar('ajax_addtocart/icons/fail/inlined', 'Magento_Catalog')) ->setLazyLoaded($block->getVar('ajax_addtocart/icons/fail/lazy_loaded', 'Magento_Catalog')) ->toHtml(); ?> <?php endif; ?> <?php if(!empty($failLabel)): ?> <strong class="<?= $block->getVar('ajax_addtocart/css_classes/fail_label', 'Magento_Catalog') ?>"><?= $failLabel ?></strong> <?php endif; ?> <?php endif; ?></button></div>

After we've split the minified file into several lines, we found that the error comes down to this part:

<?php <?php $processingLabel = __($block->getVar('ajax_addtocart/labels/processing', 'Magento_Catalog'));

The original code for this looks like this:

<?php // If you use ajax method for adding products to cart, don't use <span> inside button because Magento will replace its contents with "Adding..." and "Added". Use <strong> instead. ?>
        <?php
            $processingLabel = __($block->getVar('ajax_addtocart/labels/processing', 'Magento_Catalog'));

So as you can see, it incorrectly replaces <?php // ... ?> <?php with <?php <?php .

It should either drop the php comment line completely, or leave it untouched with its' closing ?> php tag, which it currently "swallows".

Preconditions (*)

  1. Magento 2.4.2
  2. Theme that is based on https://github.com/magesuite/theme-creativeshop/blob/106aeb7/src/Magento_Catalog/templates/addtocart/button.phtml .

Steps to reproduce (*)

Run magento with that file in a html minification mode.

Current workarounds

Change your .phtml files so that they do not contain <?php // ... ?> lines at all, or at least, change their comment format to a different one (e.g. /* ... */ asterisk one).

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Component: Framework/ViewIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedPriority: P3May be fixed according to the position in the backlog.Progress: PR in progressReproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branchSeverity: S2Major restrictions or short-term circumventions are required until a fix is available.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions