nette / forms

📝 Generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.
https://doc.nette.org/forms
Other
497 stars 147 forks source link

Cannot call method startTag() / endTag() on string #308

Open lulco opened 1 year ago

lulco commented 1 year ago

Version: all (I use 3.1.1, but it is present in master too)

Bug Description

Found by https://github.com/efabrica-team/phpstan-latte/issues/399

BaseControl::getLabel() has return type Html|string|null, but in compiled template ->getLabel())?->startTag() is used, so it always acts like there is Html or null. No string.

Steps To Reproduce

Create some custom Form Control with method getLabel() returning string and use it in form:

protected function createComponentForm(): Form
{
    $form = new Form();
    $form->addText('title', 'Title');

    $customCheckbox = new class extends Checkbox
    {
        public function getLabel($caption = null)
        {
            return 'this is just string';
        }
    };
    $form->addComponent(new $customCheckbox('Is hidden'), 'is_hidden');
    return $form;
}

In latte:

{form form}
    {input title}
    {label is_hidden}{input is_hidden}{/label}
{/form}

You will get error Call to a member function startTag() on string

Expected Behavior

No error.

Possible Solution

1) Simple: Remove string as possible return type of method getLabel() (BC break? Probably, but does somebody use it?) 2) Harder: Change compiled code to check if string is used. But how it will be rendered if it is just string?