infograf768 / j4localise

developing a version of com_localise adapted to Joomla 4
GNU General Public License v2.0
3 stars 1 forks source link

PHP8 error when saving some ini files #42

Closed fontanil closed 2 years ago

fontanil commented 3 years ago

Hi I'm trying to translate Akeeba Tickets System (com_ats.ini admin side) and I can't save the file, I get this message: 0 The arguments array must contain 2 items, 1 given Debug and error reporting to maximum, there is one error when I open the list of files administrator/components/com_localise/Model/TranslationModel.php on line 317 (and line 321) I had no error with com_ats.sys.ini file. Regards, fontanil

Localise 5.0.0 beta 5 PHP 8.0.10

Bakual commented 3 years ago

Sorry, I missed the error log. The thing is that for some reason you apparently pass an XML object into Text::_() instead of the language KEY. Also, it contains already the translated value, which at this point shouldn't be there. So the question is how that Text::_() is called. Instead of passing just a single LANGUAGE_KEY (eg COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED), it gets passed a lot more.

Bakual commented 3 years ago

Btw, simple_xml does behave a bit different in PHP 8 as well. So it may be that you need to better pass a simpleXML string.

Valc commented 3 years ago

@Bakual

Previously from the other coment you say "The comma is only used as a separator from the KEY to the values."

I does not understand why is used a comma as separator, but this one now have sense with the code line: $first_part = array_shift($string_parts);

Than "eat" the first element from the array, and leave only "string parts".

If it is used to separate the key from the string (no idea due i have not a general knowledge of the whole cycle, only the part that I see fail), note than that "comma" is not present at "var_dump".

Second stuff to take in mind is than comlocalise code is not trying to "prerender" or "preprocess" the Text::() or Text::sprintf() outputs in any way. As all others extensions we simply call:

use Joomla\CMS\Language\Text;

And is the "Text" function who is calling the:

        if (self::passSprintf($string, $jsSafe, $interpretBackSlashes, $script))
        {
            return $string;
        }

and then frompassSprintfis loading a language

        $lang = Factory::getLanguage();
        $string_parts = explode(',', $string);

And trying to precheck each string as valid or not vallidText::sprintf()

Finallly note than the code for the key COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED is at /administrator/components/com_localise/Helper/LocaliseHelper.php path, and is not showed the time the warning log is tiggered, the syntax is right and the amount of placeholders and placeholdrs format is exactly the required by code and by language string.

So the question is how that Text::_() is called. Instead of passing just a single LANGUAGE_KEY (eg COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED), it gets passed a lot more.

Text::_() i think is calling it, loading the language file and then evaulating key by key the strings, without success sometimes due is bugged.

fontanil commented 3 years ago

For the other error (Warning: Trying to access array offset on value of type bool in /home/www/sitestests/admtools/administrator/components/com_localise/Model/TranslationModel.php on line 317) PHP 8 doesn't allow empty line[0] so we need to use `if(empty($line[0])) {

} elseif ($line[0] == '#') { $this->item->error[] = $lineNumber; } elseif ($line[0] == ';') `

infograf768 commented 3 years ago

@fontanil Have you installed the beta6 pack I provided above? https://github.com/infograf768/j4localise/issues/42#issuecomment-950283532 I do not get that error here with php8.

Valc commented 3 years ago

For the other error (Warning: Trying to access array offset on value of type bool in /home/www/sitestests/admtools/administrator/components/com_localise/Model/TranslationModel.php on line 317) PHP 8 doesn't allow empty line[0] so we need to use `if(empty($line[0])) {

} elseif ($line[0] == '#') { $this->item->error[] = $lineNumber; } elseif ($line[0] == ';') `

I can not test at PHP 8.0, maybe JM can. We need simply be sure than your suggestion also is working on PHP 7

fontanil commented 3 years ago

@fontanil Have you installed the beta6 pack I provided above? #42 (comment) I do not get that error here with php8.

Yes, JM

Valc commented 3 years ago

@fontanil In the end we are going to get your part of a born coder!! :D

fontanil commented 3 years ago

I don't understand why the strings in Text.php are in English, as I am trying to translate into French. I deleted all commas from the French string and get the error (for com_ats.ini) @Valc No, I'm just tenacious. ;)

Valc commented 3 years ago

No, I'm just tenacious. ;)

I don't understand why the strings in Text.php are in English, as I am trying to translate into French. I deleted all commas from the French string and get the error (for com_ats.ini)

That is not the problem, is "API maters", so, no worry.

Bakual sure bring light due he have the knowknowledge of the whole cycle, or very close to the whole cycle.

fontanil commented 3 years ago

I tried with PHP 7.4, no error for the "line[0]" correction

fontanil commented 3 years ago

Why is it the reference value, in English, that causes an error when recording this translated value?

Valc commented 3 years ago

Why is it the reference value, in English, that causes an error when recording this translated value?

Due the language loaded by "use Text", at the moment, is in English. So, the parse is on en-GB strings.

Bakual commented 3 years ago

The error message that was posted was

Warning: vsprintf(): Too few arguments in /var/www/html/ft/libraries/src/Language/Text.php on line 123
object(SimpleXMLElement)#8090 (1) { [0]=> string(193) "COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED
A new file <strong>%1$s</strong> present in the Github %2$s branch, has been added to the local %3$s/language/en-GB folder." }

As you see, there was a SimpleXMLElement object here, containing a string COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED A new file <strong>%1$s</strong> present in the Github %2$s branch, has been added to the local %3$s/language/en-GB folder. But Text::_() never expects such a string or object. It only expects COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED as string. So for something in comlocalise does call `Text::()` with a SimpleXMLElement instead of the language key. That is your issue.

The error you then see is just a symptom of it. Text::_() can handle a special case where you would call it like Text::_('SOME_KEY, value1, value2') and it would then run a sprintf with those values. This is no issue if you only pass the language key, as that one never has a comma in it. But if you as well pass the language source string, then it of course may contain a comma and it tries to run it through sprintf which then fails.

As I don't know how com_localise works in detail, I can't say where that happens. I did some searching through the code but couldn't find an obvious place. So you need so look at the stacktrace where your error happens. That will give you a clue.

Valc commented 3 years ago

Ok, Thank you @Bakual :)

i have changed a bit more the passSprintf code to help to understand what is happening:

    /**
     * Checks the string if it should be interpreted as sprintf and runs sprintf over it.
     *
     * @param   string   &$string               The string to translate.
     * @param   mixed    $jsSafe                Boolean: Make the result javascript safe.
     * @param   boolean  $interpretBackSlashes  To interpret backslashes (\\=\, \n=carriage return, \t=tabulation)
     * @param   boolean  $script                To indicate that the string will be push in the javascript language store
     *
     * @return  boolean  Whether the string be interpreted as sprintf
     *
     * @since   3.4.4
     */
    private static function passSprintf(&$string, $jsSafe = false, $interpretBackSlashes = true, $script = false)
    {
        // Check if $string is comming as html output
        if (preg_match("'<strong>(.*?)</strong><br>'", $string, $matches))
        {
            // Uncomment to test the case tiggering system messages without call Text::_()
            $message = 'passSprintf as HTML output catched<br>' . htmlspecialchars($string);
            Factory::getApplication()->enqueueMessage($message, 'warning');

            $string = str_replace($matches[0], '', $string);
            $issued_input = true;
        }
        else
        {
            $issued_input = false;
        }

        // Check if string contains a comma
        if (strpos($string, ',') === false)
        {
            return false;
        }

        $lang = Factory::getLanguage();
        $string_parts = explode(',', $string);

        // Pass all parts through the Text translator
        foreach ($string_parts as $i => $str)
        {
            $string_parts[$i] = $lang->_($str, $jsSafe, $interpretBackSlashes);
        }

        if ($issued_input)
        {
            // Trying to emulate than we take off "the key" when realy we now here there was not a key before the first comma.
            $first_part = $string_parts[0];
            array_shift($string_parts);
        }
        else
        {
            $first_part = array_shift($string_parts);
        }

        // Replace custom named placeholders with sprintf style placeholders
        $first_part = preg_replace('/\[\[%([0-9]+):[^\]]*\]\]/', '%\1$s', $first_part);

        // Check if string contains sprintf placeholders
        if (!preg_match('/%([0-9]+\$)?s/', $first_part))
        {
            return false;
        }

        $final_string = vsprintf($first_part, $string_parts);

        if (!$final_string && $issued_input)
        {
            $message = 'passSprintf returning false <b>with</b> the issued HTML input<br>'
                        . $string
                        . '<br>String parts= '
                        . count($string_parts)
                        . '<br>First part= '
                        . $first_part;

            Factory::getApplication()->enqueueMessage($message, 'error');
        }
        else if (!$final_string && !$issued_input)
        {
            $message = 'passSprintf returning false <b>without</b> the issued HTML input<br>' . $string;
            Factory::getApplication()->enqueueMessage($message, 'error');
        }

        // Return false if string hasn't changed
        if ($first_part === $final_string)
        {
            return false;
        }

        $string = $final_string;

        if ($script)
        {
            foreach ($string_parts as $i => $str)
            {
                static::$strings[$str] = $string_parts[$i];
            }
        }

        return true;
    }

Now can display this output when "save"

issued

In our case is passing a full HTML output for all keys within the language file to save.

I has been also searching through the code but couldn't find an obvious place to allow this one. I will continue searching a bit more tomorrow. If you think is at com_localise code, i belive you XD

The "preprocessForm" at our TranslationModel.php file is adding the "strong" HTML tags to the keys and the "br" and handling a simple XML object there..

but how is posible than doing that to show the view with the required style can to end mixing calls to language files to load by the system with forms to display within a view??, in our case, of course, a form with language keys and strings to handle.

infograf768 commented 3 years ago

Found when this code was implemented for 3.4.4 (September 2015). The reason was totally different than what I thought.

https://github.com/joomla/joomla-cms/pull/6581

It looks legit to me, at least for php <=7.x

@regularlabs Could it be that this code has to be modified for php 8 as it is more strict?

Bakual commented 3 years ago

Again: This code is not the reason for the error. You're chasing a ghost 😄

You need to find out why on eart the english sourcestring appears at that point. It should only be the language key, no real text.

The language strings are loaded after that part, so translations and english fallback are not yet available at this point. Which means they are passed into Text::_() which is completely wrong and the reason for your issue.

A Stacktrace would help here.

Bakual commented 3 years ago

Ok, I found the issue. The source is the "Strings" tab in the edit view image Note that the english sourcetext is part of the label (and may contain commas).

Now when you save the form, Joomla will try to translate the field label within Form::validate() and there this breaks as that label contains a comma.

Valc commented 3 years ago

Note that the english sourcetext is part of the label (and may contain commas).

Hi, @Bakual:

That one is our label, and the "field" is at the right side. Our label html output is "<strong>key</strong><br>string"

We are not calling from our code "Text::_($label)" or similar cases in any way.

If we separare the "string" from the key, then our label will be: "<strong>A_KEY_TO_SHOW_AS_REFERENCE</strong><br>"

And in this way, if is as you say, Form::validate() will try to validate the label again, of course, this time without error due no "commas"...

.. but HTML? Is required attempt to "Text::(<strong>A_KEY_TO_SHOW_AS_REFERENCE</strong><br>)" and then passSprintf under "fake keys" or "key to no call" or "keys than need to be displayed without apply JText there"?

Did you mean than if we use as label only "A_KEY_TO_SHOW_AS_REFERENCE", without string, without html, etc.. it will be translated at our translation view? due this one is not the expected result we have programed.

So, again and thank you for your patience :) :

If you don't want to call it a failure in the current code to try to translate things that should not be translated, could we agree that "returning false" for things that obviously are not a key to translate could be improved from that code?

For example, from passSprintf:

$the_case = "THIS_ONE_IS_A_VALID_KEY_THAN_WE_CALL_BY_VAR_NAME_STRING";

if (htmlspecialchars($the_case) !== $the_case)
{
 return false;
}
else if (!is_string($the_case))
{
 return false;
}
elseif (preg_match('/^*=(\s*(("[^"]*")|(_QQ_)))+))\s*(;.*)?$/', $the_case))
{
return false;
}
else if (strpos($string, ',') === false)
{
return false;
}

Also, some fields can have the param "transladable" or not, and no idea if is posible add there something by xml declaration similar to transladable="false"; to help avoiding this cases. Or maybe already exists a label or description class type "ignore-me-please" to use.

Valc commented 3 years ago

@infograf768 @Bakual

Now with a bit more modified Text file i have moved the body by:

/administrator/index.php?option=com_installer&view=updatesites

And those also does not seems single keys 8) ( i think there was an issue opened about it, not remember were, so, maybe can help there) It is our<description><![CDATA[text here as detail]]></description>

issue2

Used code

    private static function passSprintf(&$string, $jsSafe = false, $interpretBackSlashes = true, $script = false)
    {
        if (htmlspecialchars($string) !== $string)
        {
             $message = 'passSprintf as HTML output catched and returning false<br>' . htmlspecialchars($string);
             Factory::getApplication()->enqueueMessage($message, 'notice');
             return false;
        }

        // Check if $string is comming as html output
        if (preg_match("'<strong>(.*?)</strong><br>'", $string, $matches))
        {
            // Uncomment to test the case tiggering system messages without call Text::_()
            $message = 'passSprintf as HTML output catched<br>' . htmlspecialchars($string);
            Factory::getApplication()->enqueueMessage($message, 'warning');

            $string = str_replace($matches[0], '', $string);
            $issued_input = true;
        }
        else
        {
            $issued_input = false;
        }

        // Check if string contains a comma
        if (strpos($string, ',') === false)
        {
            return false;
        }

        $lang = Factory::getLanguage();

        if ($issued_input)
        {
            //die(var_dump($lang));
        }

        $string_parts = explode(',', $string);

        // Pass all parts through the Text translator
        foreach ($string_parts as $i => $str)
        {
            $string_parts[$i] = $lang->_($str, $jsSafe, $interpretBackSlashes);
        }

        if ($issued_input)
        {
            // Trying to emulate than we take off "the key" when realy we now here there was not a key before the first comma.
            $first_part = $string_parts[0];
            array_shift($string_parts);
        }
        else
        {
            $first_part = array_shift($string_parts);
        }

        // Replace custom named placeholders with sprintf style placeholders
        $first_part = preg_replace('/\[\[%([0-9]+):[^\]]*\]\]/', '%\1$s', $first_part);

        // Check if string contains sprintf placeholders
        if (!preg_match('/%([0-9]+\$)?s/', $first_part))
        {
            return false;
        }

        $final_string = vsprintf($first_part, $string_parts);

        if (!$final_string && $issued_input)
        {
            $message = 'passSprintf returning false <b>with</b> the issued HTML input<br>'
                        . $string
                        . '<br>String parts= '
                        . count($string_parts)
                        . '<br>First part= '
                        . $first_part;

            Factory::getApplication()->enqueueMessage($message, 'error');
        }
        else if (!$final_string && !$issued_input)
        {
            $message = 'passSprintf returning false <b>without</b> the issued HTML input<br>' . $string;
            Factory::getApplication()->enqueueMessage($message, 'error');
        }

        // Return false if string hasn't changed
        if ($first_part === $final_string)
        {
            return false;
        }

        $string = $final_string;

        if ($script)
        {
            foreach ($string_parts as $i => $str)
            {
                static::$strings[$str] = $string_parts[$i];
            }
        }

        return true;
    }
Bakual commented 3 years ago

I've created a PR for core which allows to disable the translating of the field label. Same as we already can when displaying the field label.

If that PR is accepted, you can add the line $field->addAttribute('translateLabel', 'false'); after https://github.com/infograf768/j4localise/blob/68201ae84d8005c1b43e2abc9acfd9004acd6efd/administrator/components/com_localise/Model/TranslationModel.php#L985

That should do the trick as the form no longer uselessly tries to translate each field label.

Valc commented 3 years ago

I've created a PR for core which allows to disable the translating of the field label. Same as we already can when displaying the field label.

If that PR is accepted, you can add the line $field->addAttribute('translateLabel', 'false'); after

https://github.com/infograf768/j4localise/blob/68201ae84d8005c1b43e2abc9acfd9004acd6efd/administrator/components/com_localise/Model/TranslationModel.php#L985

That should do the trick as the form no longer uselessly tries to translate each field label.

You rocks! :P

Bakual commented 3 years ago

Another approach would be to add the english sourcetext only during display (eg by using a custom formfield or layout override) instead of polluting the whole formfield label with it. If the text is not part of the field label, it would fix things as well.

infograf768 commented 3 years ago

The core PR by @Bakual is here: https://github.com/joomla/joomla-cms/pull/35900

infograf768 commented 3 years ago

@Bakual PR (which is anyway a nice improvement to core), combined with using translateLabel in com_localise works great.

@Valc If you see a way to implement https://github.com/infograf768/j4localise/issues/42#issuecomment-951206525 then we would be even more independent.

Valc commented 3 years ago

@Bakual PR (which is anyway a nice improvement to core), combined with using translateLabel in com_localise works great.

@Valc If you see a way to implement #42 (comment) then we would be even more independent.

@Bakual Thank you!

@infograf768

Note than that #42 (comment) i think is a workarround that surely no log errors but that does not skip "check unrequired fake html encoded keys to display".

The Bakuals' PR is a direct core solution to the issue that does not lost time processing that ones (all our "labels" when we edit: imagine the joomla.ini file).

infograf768 commented 3 years ago

As Thomas patch is likely not to be added in next J4 release. I guess we would have until then to limit com_localise use to php < 8 .

BTW, we have evidently the same problem with php8 and the com_localise 4.0.38-dev version. (Forget the 4.10 version which is a fake...)

Valc commented 3 years ago

@infograf768 also, about the @fontanil issue with PHP 8, maybe we need to open a new PR based on the code he suggest as first comment, due i am a bit lost with this large issue XD

https://github.com/infograf768/j4localise/issues/42#issuecomment-950346165

Valc commented 3 years ago

As Thomas patch is likely not to be added in next J4 release. I guess we would have until then to limit com_localise use to php < 8 .

It seems the right option at the moment.

Job time now :)

infograf768 commented 3 years ago

I can't reproduce @fontanil issue at all in php 7.4 or php 8. In any browser. Also our code does take into account any other value than # and ; and absence of value for $line[0] line 484 by

}
else
{
break;
}

I'm lost about that.

Valc commented 3 years ago

I can't reproduce @fontanil issue at all in php 7.4 or php 8. In any browser. Also our code does take into account any other value than # and ; and absence of value for $line[0] line 484 by

}
else
{
break;
}

I'm lost about that.

I think that part of the code is only focused to get the header data about "Author", "Copyright", etc than later is used to create or display that info when we load a language file "Details" tab:

If present there, is used and if not we get the configured by "Options".

The code is expecting found a ";" as char 0 of the $line

So $line[0] is catching the firts char from the actual line and if the line start by ";" then search "Details", and if not, "break" to continue to the next line.

Seems than "#" is not an invalid char to use to comment lines, and simply seems is not suggested use it as a right formated "commented" ini files. So, If catched, is handled as "error".

About the @fontanil issue if is just at PHP 8 i think the Joomla Project will apply some changes when required to adjust the stuff to the "news", due maybe now is due the core is still not ready to PHP 8.

I can not reproduce the issue and i can not understand why is required call to the "char 0" by "var name", before, from PHP, was allowed do $line{0} and today is depeciated.. so, no idea. If not now sure we catch later :)

infograf768 commented 2 years ago

Note: for #, it is a legacy thing. it just deals with 1.5 language files which were starting with # and with a different format;) Example:

# $Id: fr-FR.com_banners.ini 1.5.10 2009-03-14 12:55:10 humvee ~3 $
# author French translation team : Joomla!fr
# copyright (C) 2005 - 2010 Joomla.fr & Open Source Matters. All rights reserved.
# license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL

# Note : All ini files need to be saved as UTF-8

BANNER=Bannière
BANNER CLIENT=Client de la bannière
Valc commented 2 years ago

Note: for #, it is a legacy thing. it just deals with 1.5 language files which were starting with # and with a different format;) Example:

# $Id: fr-FR.com_banners.ini 1.5.10 2009-03-14 12:55:10 humvee ~3 $
# author French translation team : Joomla!fr
# copyright (C) 2005 - 2010 Joomla.fr & Open Source Matters. All rights reserved.
# license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL

# Note : All ini files need to be saved as UTF-8

BANNER=Bannière
BANNER CLIENT=Client de la bannière

So, seems than actualy the code if catch the symbol "#" as first char will be triggered as "error". Maybe we can test what happens adding some of them at the header lines as first char.

If not mandatory trigger it as errors, so, can to be removed try to catch it as wrong from the code.

fontanil commented 2 years ago

As I said previously, PHP 8 returns an error with line[0] when the line is empty, and the error displays the first text I reported. I don't think there is any link to the other problem with commas.

Valc commented 2 years ago

Empty lines i think are handled from other code lines block below, so, i think we can not skip them.

But you can try the next one than i think can not crash next code matching with empty lines if present:

                    while (!$stream->eof())
                    {
                        $line = $stream->gets();
                        $lineNumber++;

                        if (!empty($line) && $line[0] == '#')
                        {
                            $this->item->error[] = $lineNumber;
                        }
                        elseif (!empty($line) && $line[0] == ';')
                        {
fontanil commented 2 years ago

I'm speaking about this error message in the listing page of translation files administrator/components/com_localise/Model/TranslationModel.php on line 317 (and line 321)

Valc commented 2 years ago

I'm speaking about this error message in the listing page of translation files administrator/components/com_localise/Model/TranslationModel.php on line 317 (and line 321)

Yes. What code lines have you there?

fontanil commented 2 years ago
                    if ($line[0] == '#')
                    {
                        $this->item->error[] = $lineNumber;
                    }
                    elseif ($line[0] == ';')

I proposed to check if line[0] is empty and you added it in the code you quoted there__ Sorry, I wasn't very well awake earlier

infograf768 commented 2 years ago

As @Bakual PR has been merged I will now directly add the $field->addAttribute('translateLabel', 'false'); line in com_localise. It will not break php7 and will solve php8 for J4 next version.

@fontanil line[0] is never empty. If there are no comments starting with ; then there are 2 possibilities (let's forget '#'), both are not boolean.

  1. The first line of the file is blank, i.e. a return In this case line[0] is equal to a space, i.e. " "

2 . The first line is a string line[0] = the first letter of the line constant i.e. "A" for example.

It is possible though that there is a problem with the end of file (eof) of one of your inis. In this case we could get a NULL because $stream would be wrong.

The only way to test is to edit one ini at a time after adding a var_dump line 316:

                    while (!$stream->eof())
                    {
                        $line = $stream->gets();
                        $lineNumber++;
                    var_dump($line[0]);  //add this line
                        if ($line[0] == '#')
                        {
                            $this->item->error[] = $lineNumber;
                        }
                        elseif ($line[0] == ';')
                        {
infograf768 commented 2 years ago

Commit is here: https://github.com/infograf768/j4localise/commit/d88c552009f258a80efa253e20c7140ba74d663c

Thanks @Bakual

fontanil commented 2 years ago

Sorry JM, but line[0] is empty on some lines and then an error occurs with PHP 8

Valc commented 2 years ago

@infograf768

https://downloads.joomla.org/technical-requirements

Seem Joomla 4 is PHP 8 Recommended

I will take a look to mount at my descktop PC a test server this weekend if i have time.

Also a link about PHP 8 issues comming from previous versions.

https://www.php.net/manual/es/migration80.incompatible.php

Valc commented 2 years ago

@infograf768 @fontanil

Now i am testing on PHP 8.0.12 with debug and error reporting to maximum using the beta 6 package than JM have here:

https://github.com/infograf768/j4localise/issues/42#issuecomment-950283532

With the last one added to our pack:

https://github.com/infograf768/j4localise/issues/42#issuecomment-955159282

Also with the Bakuals' PR added to Joomla core files:

https://github.com/joomla/joomla-cms/pull/35900.

Due if not, the same issue that at PHP 7 was simply triggering a log warning, at PHP 8 make a crash than is not possible continue working with com_localise files edition in normal mode.

But, one time the previous issue due "blindly try to translate the formfield label" is solved, i can not reproduce the issue related with $line[0]: no warnings, no log messages, nothing.

I think we need more testers due surely the issue is there, but if it is invisible for us seems there is no way to continue.

fontanil commented 2 years ago

Please try this code ` while (!$stream->eof()) { $line = $stream->gets(); $lineNumber++; if(empty($line[0])) {

                    } else
                    if ($line[0] == '#')
                    {
                        $this->item->error[] = $lineNumber;
                    }
                    elseif ($line[0] == ';')`

On my test site, PHP 8.0.8, no more error for line[0]

Valc commented 2 years ago

@fontanil I think we can solve adding that patch, but also is possible than this one is a PHP 8 bug than they have solved at the PHP released version i have installed. Note than they also have bugs to fix:

https://www.php.net/ChangeLog-8.php

It is possible you test under the last PHP 8 version?

Share the block of code, please. Due does not have to many sense try an "if (empty($line[0]))" to do nothing.

fontanil commented 2 years ago

With PHP 8.0.12 on Wampserver 64, without my changes: "Warning: Trying to access array offset on value of type bool in D:\wamp64\www\admtools\administrator\components\com_localise\Model\TranslationModel.php on line 319" No more error with the code I quoted.

Valc commented 2 years ago

And with the next code lines you have the warning??

                    while (!$stream->eof())
                    {
                        $line = $stream->gets();
                        $lineNumber++;

                        if (!empty($line) && $line[0] == '#')
                        {
                            $this->item->error[] = $lineNumber;
                        }
                        elseif (!empty($line) && $line[0] == ';')
                        {
fontanil commented 2 years ago

No error with this code, as it is quite the same of mine. ;) As I said some comments higher: "I proposed to check if line[0] is empty and you added it in the code you quoted there__"

Valc commented 2 years ago

Please, also test the next code than have an "if empty" doing something :D

                    while (!$stream->eof())
                    {
                        $line = $stream->gets();
                        $lineNumber++;

                        if (empty($line))
                        {
                            die("The line number $lineNumber is empty and the line[0] have the $line[0] value");
                        }
                        elseif ($line[0] == '#')
                        {
                            $this->item->error[] = $lineNumber;
                        }
                        elseif ($line[0] == ';')
                        {
fontanil commented 2 years ago

Warning: Trying to access array offset on value of type bool in D:\wamp64\www\admtools\administrator\components\com_localise\Model\TranslationModel.php on line 319

"The line number 1 is empty and the line[0] have the value

line[0] is empty so you can't display "the $line[0] value"