Problem/Motivation

Installing fresh in a foreign language today I got these errors:

  • Notice: Undefined index: und in Drupal\Core\Entity\ContentEntityBase->language() (line 547 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).
  • Notice: Trying to get property of non-object in Drupal\Core\Entity\FieldableDatabaseStorageController->doLoadFieldItems() (line 842 of core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php).
  • Notice: Undefined index: und in Drupal\Core\Entity\ContentEntityBase->language() (line 547 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).
  • Notice: Trying to get property of non-object in Drupal\Core\Entity\FieldableDatabaseStorageController->doSaveFieldItems() (line 905 of core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php).

And then under that:

Invalid translation language () specified.

With no way to go forward. Suspected this is caused by #2076445: Make sure language codes for original field values always match entity language regardless of field translatability.

Proposed resolution

TBD.

Remaining tasks

TBD.

User interface changes

None.

API changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Gábor Hojtsy’s picture

Issue summary: View changes
Gábor Hojtsy’s picture

Probably evident, since this is the only "content" entity related task in the installer, but this is related to this code block. Commenting out makes it pass.

  // We precreated user 1 with placeholder values. Let's save the real values.
  $account = user_load(1);
  $account->init = $account->mail = $form_state['values']['account']['mail'];
  $account->roles = $account->getRoles();
  $account->activate();
  $account->timezone = $form_state['values']['date_default_timezone'];
  $account->pass = $form_state['values']['account']['pass'];
  $account->name = $form_state['values']['account']['name'];
  $account->save();

Not sure where would this hit 'und'.

philipz’s picture

Gábor Hojtsy’s picture

Status: Active » Needs review
FileSize
613 bytes

This is pretty easy actually. So the new/current entity API expects that entities are available in languages that are valid. The default admin user is saved (in user.install) with an empty langcode. Then trying to save values into the entity with an empty langcode does not work. Once you set a langcode proper based on the site default, it all works fine. Not sure if we can effectively write tests for this?!

philipz’s picture

This fix did help but still looks like something is not right. The installation completed but this notice was still visible during configuration translations updating.

Notice during configuration translations update

The last submitted patch, 4: install-foreign-language-fix.patch, failed testing.

BarisW’s picture

BarisW’s picture

Same here, I am able to install Drupal now, but I also get two notices:

Notice: Undefined index: und in Drupal\Core\Entity\ContentEntityBase->language() (line 547 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).
Notice: Trying to get property of non-object in Drupal\Core\Entity\FieldableDatabaseStorageController->doLoadFieldItems() (line 842 of core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php).

Gábor Hojtsy’s picture

Yeah I can reproduce that now. I thought this would be due to the language of the entity being '' (empty string) originally, and tried specifying 'langcode' => Language::LANGCODE_NOT_SPECIFIED for both the anonymous and the admin user in user_install() but that did not help. Further debugging/help welcome :)

webchick’s picture

Priority: Major » Critical
Issue tags: +Needs tests

Not being able to install at all sounds critical.

I would *love* to see if there's a possible way we can write tests for this (a multilingual-enabled test profile..?), though I suspect not.

philipz’s picture

I've found so far that the notices are caused by first user_load(1) in install_configure_form_submit function.
I tried adding 'langcode' => Language::LANGCODE_DEFAULT, in user_install for user 1 but that didn't help.
Finally I hardcoded 'langcode' => 'pl', in user_install and installed in Polish - the notices were gone.

Now I don't know if somehow there should be langcode of selected language passed to user_install or the problem lies in ContentEntityBase->language which tries to load wrong language in this case and should check that better.

philipz’s picture

This fixed it for me.

jdanthinne’s picture

#12 works for me as well (french install).

Gábor Hojtsy’s picture

@philipz: Ok looks like your fix is better and does not need my fix, since the user will already be in the right language. I think the change needs to extend to the anonymous user account created a few lines up though.

Gábor Hojtsy’s picture

I also attempted to give test coverage for this. Sounded like it would be simplest to do a non-interactive test that installs in a foreign language, since it is easiest to code and would make the error show up equally well. My non-interactive test is a direct clone of Drupal\system\Tests\Installer\SiteNameTest but does not run with proper db prefix locally. So I went to look at whether I can make the existing interactive foreign language test (Drupal\system\Tests\Installer\InstallerTranslationTest) to move forward into after the site configuration step (it does not go as far yet). However that also fails with improper db setup for me (classic semaphore table error). That even without any modifications from the core state. So I think its more likely something is fubar locally, so I'm posting my try at the non-interactive test so it may or may not work on testbot :D

philipz’s picture

Status: Needs review » Reviewed & tested by the community

You're right I forgot about anonymous user account and it probably would result in some problems somewhere else :)
Patch #14 works for me so maybe we can mark it as reviewed?

The last submitted patch, 14: install-foreign-language-fix-2148071-14.patch, failed testing.

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs review

That test fail was random (key value table missing), but let's keep this needs review until the test stuff runs as well, and see if it makes sense or not. I'm all for fixing this ASAP, but @webchick asked for tests, which makes total sense *if* we can make them work in a reasonable timeframe :)

Status: Needs review » Needs work

The last submitted patch, 15: install-foreign-language-fix-2148071-15.patch, failed testing.

Gábor Hojtsy’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 15: install-foreign-language-fix-2148071-15.patch, failed testing.

Gábor Hojtsy’s picture

Status: Needs work » Needs review
webchick’s picture

Issue tags: +alpha target

It would highly suck to ship an alpha with multilingual installs broken, so tagging.

BarisW’s picture

I can confirm that this patch works. All notices are now gone.

Kartagis’s picture

This issue exists for me as well. The 2.04kb patch from #15 works for me.

Regards,

Gábor Hojtsy’s picture

Any bright ideas to make the tests work? :) That the test only patch passes is quite puzzling and I have issues running the tests locally as explained above :/

philipz’s picture

I'm confused why #15 says both passed but #19 and #21 say it didn't? :)

Gábor Hojtsy’s picture

Sent for a retest in #22 which passed.

penyaskito’s picture

Maybe it is a problem with the profile itself?

The last submitted patch, 29: install-foreign-language-fix-2148071-29-test-only.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 29: install-foreign-language-fix-2148071-29.patch, failed testing.

Gábor Hojtsy’s picture

So I spent several hours to try and figure out why Drupal\system\Tests\Installer\InstallerTranslationTest does not even pass (unmodified without any of this patch applied) on my machine. That would be the test to modify to get to and past the configure page. However, I always get Base table or view not found: 1146 Table '....semaphore' doesn't exist: INSERT INTO {semaphore} when running the test. The reason is the DB setup screen does not move forward because the DB port is not picked up properly. My local port is 33066, but the installer DB settings screen appears with 3306 as the default setting. Even though when stepping into / debugging the DB code, it sets a default of 33066 clearly.

I'm not sure it is fruitful for me to keep debugging installer testing, so I'd welcome if someone could step in and work on this. Does Drupal\system\Tests\Installer\InstallerTranslationTest pass for you locally? You are a good candidate to do this task.

BTW I also found that Drupal\system\Tests\Installer\InstallerTranslationTest attempts to set the installation directory to be local but it does not really succeed in that and the German translation is set to be downloaded from the internet in the test. So running the test locally without internet connection would probably not even work. That is quite a fail in itself on our part :/

penyaskito’s picture

Assigned: Unassigned » penyaskito

I'll try to take a look tonight.

penyaskito’s picture

InstallerTranslationTest pass for me.

marthinal’s picture

Missing Curly Brackets.

marthinal’s picture

penyaskito’s picture

#29 review:

+++ b/core/modules/system/lib/Drupal/system/Tests/Installer/InstallerTranslationNonInteractive.php
@@ -43 +43,0 @@
-}

The "interdiff" between marthinal patches and mine is that I dropped accidentally a bracket on my patch, and he restored that.

penyaskito’s picture

Assigned: penyaskito » Unassigned

Locally I get, in both cases, with HEAD and with the patch attached:

3 passes, 0 fails, 2 exceptions, and 1 debug message

Trying to get property of non-object
_install_prepare_import('de')
install_import_translations(Array)
install_run_task(Array, Array)
install_run_tasks(Array)
install_drupal(Array)
Drupal\simpletest\WebTestBase->setUp()
Drupal\simpletest\TestBase->run()
_simpletest_batch_operation(Array, '5', Array)
call_user_func_array('_simpletest_batch_operation', Array)
_batch_process()
_batch_do()
_batch_page(Object)
Drupal\system\Controller\BatchController->batchPage(Object)
call_user_func_array(Array, Array)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\HttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
drupal_handle_request()
Notice	install.core.inc	2066	_install_prepare_import()	Exception

Undefined offset: 1
_install_prepare_import('de')
install_import_translations(Array)
install_run_task(Array, Array)
install_run_tasks(Array)
install_drupal(Array)
Drupal\simpletest\WebTestBase->setUp()
Drupal\simpletest\TestBase->run()
_simpletest_batch_operation(Array, '5', Array)
call_user_func_array('_simpletest_batch_operation', Array)
_batch_process()
_batch_do()
_batch_page(Object)
Drupal\system\Controller\BatchController->batchPage(Object)
call_user_func_array(Array, Array)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\HttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
drupal_handle_request()
Notice	install.core.inc	2069	_install_prepare_import()	Exception

and no idea what's going on.

Will continue trying to guess the problem, but anyone can feel free to work on this one.

philipz’s picture

I want to test it but running

$ ./vendor/bin/phpunit --group Installer

gives me only

PHPUnit 3.7.21 by Sebastian Bergmann.
Configuration read from /var/www/core/phpunit.xml.dist
Time: 2 seconds, Memory: 30.75Mb
No tests executed!

Is this test in other group or do I run it somehow wrong? Sorry for newbie question :)

Gábor Hojtsy’s picture

@philipz: this is not a phpunit test, it needs to run through the Drupal installer, so not possible in phpunit.

penyaskito’s picture

Hi @philipz, thanks for trying!

This test is not a phpunit test but a simpletest. You can run it by:

php ./core/scripts/run-tests.sh --url http://d8.local --class "Drupal\system\Tests\Installer\InstallerTranslationNonInteractive"

philipz’s picture

Drupal\system\Tests\Installer\InstallerTranslationTest passes for me locally too.

Now I'm trying to understand the problem in InstallerTranslationNonInteractive. This is what is blocking RTBC?

penyaskito’s picture

Yes, that's it. We need to convert that into a test that fails with the current HEAD but passes with the attached fix.

philipz’s picture

This is my try on this. Worked for me locally so I hope it's ok.

The last submitted patch, 44: install-foreign-language-fix-2148071-44-test-only.patch, failed testing.

penyaskito’s picture

Thanks philipz!

Looks like the desired behavior. If Gábor agrees this is RTBC.

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Indeed, yay!

philipz’s picture

I'm very happy, yesterday I started learning how to write and run tests in Drupal and today success :)
Thanks for quick replies and all the insight in this issue!

philipz’s picture

Added comment and removed unnecessary second $submit_value xpath fetch.

The last submitted patch, 49: install-foreign-language-fix-2148071-49-test-only.patch, failed testing.

penyaskito’s picture

Still RTBC.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Yay! Great work, filling in this missing test coverage!

Committed and pushed to 8.x. WOOT!

penyaskito’s picture

Awesome! Welcome to core development, philipz!

plach’s picture

Awesome work, guys!

webchick’s picture

Just wanted to point out that this new test caught its first critical regression within 24 hours: #2021779-83: Decouple shortcuts from menu links Great job, phillipz! :D

philipz’s picture

Sweet :D Thank's for the link and for the welcoming!

Berdir’s picture

Unfortunately I think the fix here was just a workaround (with helpful test coverage!), I'm trying to find and fix the underlying problem in #2156945: Clean up installer entity defaults following bugfix. See you there :)

Gábor Hojtsy’s picture

@Berdir: I'd argue the fix here was not at all a workaround, since user_install() does not use the entity API to create the initial users. It uses two direct SQL queries. So the default values from the entity fields will naturally not be applied. One might argue this should use direct entity API, I'm not sure if there are good reasons not to. That was not in scope for this issue (and due to the other issue in #2156945: Clean up installer entity defaults following bugfix it would not have worked yet either).

Gábor Hojtsy’s picture

Issue tags: -sprint

Huh, I'm glad this got in for the alpha :)

Berdir’s picture

Right sorry, misread that. Although that makes we wonder a bit if users should really be by language by default, on most sites, that is not going to be language-specific data. Because now they're always a specific language.

Gábor Hojtsy’s picture

I think as soon as they get a field on the user (eg. comment signature) that will contain text in some language. For every other type of entity, we create them in the site default language by default until language module is enabled and some other configuration is not picked explicitly.

Gábor Hojtsy’s picture

To be more precise we do this for all content entities, and I think it perfectly applies to user entities (and we already do it for them :).

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.