Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

raffelustig's avatar

Function results in infinitive loop

In my pistol competition system upgraded to Laravel 8 I have a function that should present some text in a blade based upon wether late signups (after closing date) is allowed or not. This function works well in Laravel 5.3 but gets the system into an infinitive loop in Laravel 8. Here is the function:

public function getAllowSignupsAfterClosingDateHumanAttribute()
    {
        if(!$this->allow_signups_after_closing_date):
            return _('Not allowed');
        elseif($this->allow_signups_after_closing_date && $this->approval_signups_after_closing_date):
            return _('Needs approval. %s kr fee', $this->price_signups_after_closing_date);
        elseif($this->allow_signups_after_closing_date && !$this->approval_signups_after_closing_date):
            return _('Late signup possible. %s kr fee', $this->price_signups_after_closing_date)
        endif;
    }

It sits in app/Models/Competition.php

Wonder how to modify to working order?

0 likes
23 replies
tykus's avatar

I don't see anything immediately in the function to cause infinite loop (there is no loop) or infinite recursion.

Generally, with Accessor methods we would use raw attributes (the column values) rather that model properties. So whichever of the properties are actually columns:

  • allow_signups_after_closing_date
  • approval_signups_after_closing_date
  • price_signups_after_closing_date

would be accessed through the attributes array, e.g. $this->attributes['allow_signups_after_closing_date']

Using the attributes array mean you bypass accessors; and therefore mitigate potential recursion.

Snapey's avatar

what makes you think this code causes an infinite loop?

raffelustig's avatar

I'll try to explain. Here in the blade for information is the checkbox for late signups

        <tr>
            <td>{{_('Allow late signup')}}</td>
            <td>
                <label for="allow_signups_after_closing_date">
                    <input type="checkbox" ng-model="competitions.competition.allow_signups_after_closing_date" id="allow_signups_after_closing_date" ng-true-value="1" ng-false-value="0"> {{_('Tillåt anmälan efter sista-HÄR anmälningsdag')}}</a>
                </label>
            </td>
        </tr>

So if that box is checked the system comes into a loop when being in the competition blade where you can see the competitions.

If I do this:

    public function getAllowSignupsAfterClosingDateHumanAttribute()
    {
        if(!$this->allow_signups_after_closing_date):
            return _('Not allowed');
/*        elseif($this->allow_signups_after_closing_date && $this->approval_signups_after_closing_date):
            return _('Needs approval. %s kr fee', $this->price_signups_after_closing_date);
        elseif($this->allow_signups_after_closing_date && !$this->approval_signups_after_closing_date):
            return _('Late signup possible. %s kr fee', $this->price_signups_after_closing_date).   
*/
        endif;
    }

I can see the competitions. So something in these statements are causing error. . I got an error also in laravel.log:

[2022-04-22 23:45:01] local.ERROR: _() expects exactly 1 parameter, 2 given {"userId":7,"exception":"[object] (ErrorException(code: 0): _() expects exactly 1 parameter, 2 given at /Users/ralph/laravel8/webshooter_web/app/Models/Competition.php:284)
[stacktrace]
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, '_() expects exa...', '/Users/ralph/la...', 284, Array)
#1 /Users/ralph/laravel8/webshooter_web/app/Models/Competition.php(284): _('Needs approval....', 100)
tykus's avatar

It should be __() - two underscores for translations

return __('Not allowed');

or

return trans('Not allowed');
Snapey's avatar

@raffelustig Angular?

The error in log file is due to using two parameters in the _() function (a separate error)

return _('Needs approval. %s kr fee', $this->price_signups_after_closing_date);

Laravel does not have a _() function, perhaps this is a helper added to your project?

Snapey's avatar

@tykus translation helper does not use %s ? that looks more like a sprintf() string ?

tykus's avatar

@Snapey yeah, true. Who fucking knows - gettext doesn't take a second argument 🤷‍♂️

raffelustig's avatar
raffelustig
OP
Best Answer
Level 2

Got it! Here:

           return sprintf('Not allowed');
        elseif($this->allow_signups_after_closing_date && $this->approval_signups_after_closing_date):
            return sprintf('Needs approval. %s kr fee', $this->price_signups_after_closing_date);
        elseif($this->allow_signups_after_closing_date && !$this->approval_signups_after_closing_date):
            return sprintf('Late signup possible. %s kr fee', $this->price_signups_after_closing_date);

so sprintf was needed after all. Thank you guys!

Snapey's avatar

best I can suggest, but it really makes no sense, and probably breaks translations (if you have a language switcher)

public function getAllowSignupsAfterClosingDateHumanAttribute()
    {
        if(!$this->allow_signups_after_closing_date) {
            return _('Not allowed');
        } elseif($this->allow_signups_after_closing_date && $this->approval_signups_after_closing_date) {
            return _(sprintf('Needs approval. %s kr fee', $this->price_signups_after_closing_date));
        } elseif($this->allow_signups_after_closing_date && !$this->approval_signups_after_closing_date) {
            return _(sprintf('Late signup possible. %s kr fee', $this->price_signups_after_closing_date));
        }
    }
Snapey's avatar

What about your infinitive loop problem ;-)

raffelustig's avatar

@Snapey not anymore due to the sprinf-s Everything here about late signups and competitions works perfectly!

1 like
raffelustig's avatar

@Snapey No, I was only translated manually to make it easier for you to understand the text, maybe not necessary though :-)

if(!$this->allow_signups_after_closing_date):
            return sprintf('Tillåts ej');
        elseif($this->allow_signups_after_closing_date && $this->approval_signups_after_closing_date):
            return sprintf('Behöver godkännas. %s kr avgift', $this->price_signups_after_closing_date);
        elseif($this->allow_signups_after_closing_date && !$this->approval_signups_after_closing_date):
            return sprintf('Efteranmälan möjlig. %s kr avgift', $this->price_signups_after_closing_date);

Swedish.

raffelustig's avatar

@Snapey Do you know how to check if it translates into english works?? I can't travel abroad for that. Can you check here: https://test.webshooter.se

I have seen something from someone in another country who showed me some screenshots

Snapey's avatar

@raffelustig Well I hope you know if it is translated or not? Which country you are in should not make it switch automatically?

Its just that the _() is used in applications that use translation files (.mo) and you have removed that now.

raffelustig's avatar

@Snapey Ok, but it's not that important, we only use the system here in Sweden after all. Most important.

Please or to participate in this conversation.