Updated: Comment #3
Problem/Motivation
When more than one language is configured and path-based language negotiation is enabled, node hit data collection was broken but fixed in #2364157: Replace most existing _url calls with Url objects. The underlying cause was that the data collection callback, a simple PHP script located at the root directory of the Statistics module, was run through url() before being added to drupalSettings. When that URL was hit asynchronously for languages with a configured language prefix, no data is collected and a 404 results.
This problem was also introduced in Drupal 7.25 and, as such, needs backport.
There is no tests for this to prevent it happening again in the future.
Proposed resolution
Add test to test node hit counter when path-based language negotiation is used
Remaining tasks
Review, commit
User interface changes
n/a
API changes
n/a
| Comment | File | Size | Author |
|---|---|---|---|
| #55 | drupal-ajax_node_counter_lang_path_prefix-2172871-55.patch | 5.86 KB | iamEAP |
| #48 | async_node_hit_counter-2172871-48.patch | 5.55 KB | timmillwood |
| #34 | 2172871-34.patch | 5.14 KB | iamEAP |
| #2 | drupal-ajax_node_counter_lang_path_prefix-2172871-2.d7-do-not-test.patch | 5.86 KB | iamEAP |
Comments
Comment #1
iamEAP commentedThis issue depends on #2172859: Statistics JS and settings are not included on node pages, because the Statistics module is completely broken, regardless of the multilingual bug.
Comment #2
iamEAP commentedHere's a patch for D7, with tests. D8 is still dependent on #2172859: Statistics JS and settings are not included on node pages, but the relevant test modifications are below:
The actual fix, very straightforward.
Modifications necessary to enable path prefix based language negotiation.
The only additional tests needed for D8. The rest are backports of D8 tests for D7.
Comment #3
iamEAP commentedPatch attached. As illustrated above, the issue is that url() takes path-based language negotiation into account when generating aliases, which we don't want (because
/core/modules/statistics/statistics.jswill always be at the Drupal root, not at a language path-prefixed location).In addition to the fix and tests for that change, I'm being more explicit in the check for the script/settings on-page by:
<script src="[/path/to/statistics.js]">Also tagging D8MI to put it on the multilingual initiative's radar.
Comment #6
iamEAP commented3: drupal8-ajax_node_counter_lang_path_prefix-2172871-3.tests-only.patch queued for re-testing.
Comment #7
iamEAP commented3: drupal8-ajax_node_counter_lang_path_prefix-2172871-3.patch queued for re-testing.
Comment #10
anybodyConfirming this major problem in our multilingual D7.25 environment.
Comment #11
iamEAP commented3: drupal8-ajax_node_counter_lang_path_prefix-2172871-3.patch queued for re-testing.
Comment #13
iamEAP commentedRebasing #3...
Comment #15
iamEAP commentedAh. $base_url includes the path. Just need to use $base_root in the test.
Comment #17
iamEAP commented15: drupal8-ajax_node_counter_lang_path_prefix-2172871-15.patch queued for re-testing.
Comment #19
iamEAP commented15: drupal8-ajax_node_counter_lang_path_prefix-2172871-15.patch queued for re-testing.
Comment #21
iamEAP commented15: drupal8-ajax_node_counter_lang_path_prefix-2172871-15.patch queued for re-testing.
Comment #22
iamEAP commented^^ Head was broken. Looking good now.
Comment #25
iamEAP commentedRe-roll of #15.
Comment #27
anybodyHow can we get this issue forward? It exists on every multilang Drupal 7 website using statistics and a current Drupal 7 version, which is represended by major state.
Does someone know where the error in the last patch comes from?
The test did not complete due to a fatal error. Completion check StatisticsLoggingTest.php 85 Drupal\statistics\Tests\StatisticsLoggingTest->testLogging()
Comment #28
David_Rothstein commented#2236165: Ajax POST to statistics.php fails when using i18n with path prefix language code is a possible duplicate (which also suggests that the issue is already fixed in Drupal 8).
Comment #29
effulgentsia commentedYes, it was fixed for D8 as a side effect of #2364157: Replace most existing _url calls with Url objects. However, I don't think test coverage was added there. Posting this patch to revert the side-effect fix and see if any test catches it. If not, we should reroll #25's test coverage and get that in.
Comment #30
iamEAP commentedUpdating displayed patches to only those that are currently relevant.
Comment #31
iamEAP commentedPer #29, this needs work... Will be back shortly with two patches:
Comment #32
iamEAP commentedComment #34
iamEAP commentedComment #35
iamEAP commented#34 with regression from #29.
Comment #37
effulgentsia commentedCore moves fast. _url() is gone. So here's #35 with a different regression. We still need #34 to pass.
Comment #39
iamEAP commentedThanks @effulgentsia.
I had to add a new #cache key of
cache_context.languageto the build array to get the drupalSettings to actually reflect the language. Without it, the drupalSettings attached to the node were being stored in render cache globally for all languages and thus, hook_node_view was never being triggered after initial load.That behavior seems like a bug to me, but I don't really have time personally to investigate whether or not that's true, nor whether or not an issue already exists for that bug.
In any event, here's a patch with a working test that should pass. I'll follow-up with an updated regression.
Comment #40
iamEAP commentedAnd here's #39 + a tweaked regression based on #37. It should fail. #39 should be reviewed/committed.
Comment #41
iamEAP commentedHiding regression from issue summary...
Comment #43
iamEAP commentedSee #39.
Comment #44
timmillwood#39 looks good.
Comment #45
alexpottThis is unnecessary - you can just make an assertion on $this->getDrupalSettings() - then you don't have to muck around with json encoding and trimming.
Comment #46
timmillwoodJust a reroll of #39 still need to add suggestions from #45.
Comment #48
timmillwoodFixed issue in #46 and used getDrupalSettings() as suggested in #45.
Comment #49
iamEAP commentedLooks good! #45 is addressed.
Comment #50
wim leersAn associative array representing a language?
That sounds a bit mysterious. Can't this add an
@seeto a place that explains this format?More importantly: this adds a test, without a fix. That's … quite confusing. Was it fixed in another issue in the mean time?
Comment #51
timmillwood@wim - As mentioned in #29, "Yes, it was fixed for D8 as a side effect of #2364157: Replace most existing _url calls with Url objects"
Also the $language array is "posted" to admin/config/regional/language/add, does this not make it obvious what it's doing and the format needed?
Comment #52
wim leersThanks, all much clearer now!
Comment #53
alexpottMoar test coverage. Nice one eveyone. Committed 525d8e6 and pushed to 8.0.x. Thanks!
Comment #55
iamEAP commentedReverting name change so this makes more sense for D7.
Here's #2 verbatim, but renamed so that it will be tested.
Should probably be updated to use DrupalWebTestCase::drupalGetSettings(), per #45.
Comment #57
digitaldonkey commentedA simple workaround for people who can't change core to fix this:
Comment #58
leofishman commented#57 simple work around from @digitaldonkey works fine!
Comment #60
frodeste commentedWere are we on this issue for Drupal7?
Comment #65
anybodyComment #66
alexpottIf someone does decide to port this patch note that the backport policy has changed (https://www.drupal.org/core/backport-policy). A new issue should be created and once it is - this issue should be then set to closed (fixed) with a link to the D7 issue.
Comment #67
anybodyThanks @alexpott, in that case I'd like to revive the Drupal 7 issue containing a working patch, see #2236165: Ajax POST to statistics.php fails when using i18n with path prefix language code which is then the new follow-up. It would be nice if someone could have a look at this quite old issue then.
Comment #68
berdirClosing this then.