Page MenuHomePhabricator

Edit buttons are getting cached, although their visibility depends on user rights
Closed, ResolvedPublic

Description

Title says it all: We cache the edit buttons on entity pages, although their visibility depends on user rights.

Eg. if an IP purges an edit=autoconfirmed item the edit buttons will be gone for everybody.

Event Timeline

hoo raised the priority of this task from to High.
hoo updated the task description. (Show Details)
hoo updated the task description. (Show Details)
hoo set Security to None.
hoo added subscribers: hoo, Lydia_Pintscher, daniel, aude.
hoo renamed this task from Edit buttons are getting cached, although their visibility depend on user rights to Edit buttons are getting cached, although their visibility depends on user rights.Dec 23 2014, 10:37 PM

Added wikidata-bugs as a CC as adding Wikidata as a project isn't possible for some reason (@Aklapper)

Investigating this took me deep into the wonderful land of ParserOptions, ParserOutput, ParserCache and OutputPage.

So the issue is that the parser cache should be split on whether "editsection" links are present in the output. But MediaWiki doesn't do that. So here is what I found.

  • MediaWiki core actually has provisions for it: ParserOptions::optionsHash considers a flag called "editsection".
  • But that flag is only considered if it was registered via ParserOutput::registerOption. This is where it gets arcane...
  • Parser::clearState registers ParserOutput::registerOption as a "watcher" with ParserOptions
  • ParserOptions calls back to the watcher whenever a "relevant" option is read, e.g. getUserLang() is called.

So, Parser::clearState enables the automatic splitting of the cache by registering the ParserOutput was a watcher to the ParserOptions. But Wikibase doesn't use the parser, and EntityParserOutputGerator doesn't register the watcher. So no automated splitting.

Now the splitting by user language is automatic (we do that somewhere explicitly - that's no longer needed then, I suppose). But it still doesn't work for editsection.

As it turns out, ParserOptions::getEditSection does not call $this->optionUsed( 'editsection' ), as I expected, following the example of getUserLang(), getThumbSize(), etc. The reason it doesn't is apparently another magic trick:

  • Parser emits special <mw:editsection> tags and registers a replacement token in the ParserOutput
  • These get replaced by the actual HTML for the editsection by ParserOutput::getText, using thetokens it got via ParserOutput::setEditSectionTokens.
  • ParserOutput::getText delegates the generation of the actual section link to Skin::doEditSectionLink

We could try to use that mechanism by putting an <mw:editsection> tag into the wikibase-toolbar-bracketed template, and then customizing the output via the DoEditSectionLink hook called by Skin::doEditSectionLink.

But the simples solution would be to just call $parserOutput->recordOption( 'editsection' ) in EntityParserOutputGenerator. We don't even need to set up the "split cache automatically via watcher" magic for that to work, though I think we should do that anyway.

Change 192976 had a related patch set uploaded (by Tobias Gritschacher):
Split parser cache by editsection flag

https://gerrit.wikimedia.org/r/192976

Change 192976 merged by jenkins-bot:
Split parser cache by editsection flag

https://gerrit.wikimedia.org/r/192976

aude removed a project: Patch-For-Review.
adrianheine raised the priority of this task from High to Needs Triage.Mar 4 2015, 7:49 AM
adrianheine moved this task from Review to Done on the § Wikidata-Sprint-2015-02-03 board.