Page MenuHomePhabricator

LocalFileDeleteBatch accepts an optional user, falls back to $wgUser
Closed, ResolvedPublic

Description

Rather than a cop-out of using RequestContext::getMain()->getUser(), this is going to be a larger project to ensure that a user is always passed when constructing a LocalfileDeleteBatch. The plan:


LocalFileDeleteBatch

Currently, LocalFileDeleteBatch has the following constructor:

LocalFileDeleteBatch constructor
public function __construct( File $file, $reason = '', $suppress = false, $user = null ) {
	$this->file = $file;
	$this->reason = $reason;
	$this->suppress = $suppress;
	global $wgUser;
	$this->user = $user ?: $wgUser;
	$this->status = $file->repo->newGood();
}

In order to reduce the usage of the global $wgUser variable, the $user must become required. Since it is impossible for a required variable to come after optional ones, the eventual signature will be:

public function __construct( File $file, User $user, $reason = '', $suppress = false ) {

However, the constructor will need to be backwards compatible. Since the only documented calls to create a new LocalFileDeleteBatch are in core, and will be updated alongside this change[1], using the old format for parameters will be immediately hard deprecated

[1] See https://codesearch.wmflabs.org/search/?q=LocalFileDeleteBatch&i=nope&files=&repos=


Callers

The 2 core callers are in LocalFile::deleteOld and LocalFile::delete

Both of these take an optional user parameter:

LocalFile::deleteOld
function deleteOld( $archiveName, $reason, $suppress = false, $user = null ) {
LocalFile::delete
function delete( $reason, $suppress = false, $user = null ) {

Both of those will be updated to call new methods, ::deleteFile and ::deleteOldFile, which switch the user parameter to be required. The old methods will be soft deprecated, and will include temporary fallbacks to $wgUser to ensure a user is always passed to the new methods.


Summary

  1. 1.35: Update constructor of LocalFileDeleteBatch which maintaining backwards compatibility, immediately hard deprecate old signature, update core calls, update LocalFile::delete and LocalFile::deleteOld to call ::deleteFile and ::deleteOldFile, which have the user earlier and required, immediately soft deprecate old functions
  2. After step 1 is merged: update extensions to pass a user to ::deleteFile and ::deleteOldFile
  3. 1.35 or 1.36: Update LocalFile::delete and LocalFile::deleteOld to hard deprecated
  4. 1.36: Remove support for old construction of LocalFileDeleteBatch, as well as fallback to $wgUser within that class.
  5. 1.36 or 1.37: Remove support for LocalFile::delete and LocalFile::deleteOld

This task will be resolved when the direct callers to LocalFileDeleteBatch's constructor all hard deprecate the old code paths. All that remains is updating calls to LocalFile::delete to use ::deleteFile

Event Timeline

DannyS712 added subscribers: Anomie, Krinkle, Daimona and 3 others.

Before I start this, I want to make sure I'm going about it in a sane way. Feedback is appreciated on the proposal above.

Tagging CPT so that we could provide the review for the plan.

As long as back-compat is maintained in step 1, seems ok.

I see no need to wait for 1.36 to do the hard-deprecation of the $wgUser fallback in LocalFile::delete and LocalFile::deleteOld though. The only blocker to that is completing step 2 for Wikimedia-deployed extensions. If you get that deprecation into 1.35, then you can remove all three at the same time in 1.36.

As long as back-compat is maintained in step 1, seems ok.

I see no need to wait for 1.36 to do the hard-deprecation of the $wgUser fallback in LocalFile::delete and LocalFile::deleteOld though. The only blocker to that is completing step 2 for Wikimedia-deployed extensions. If you get that deprecation into 1.35, then you can remove all three at the same time in 1.36.

I'll send patches for the deployed extensions and try to make it in before 1.35 is done

Actually, I realized when looking through the code search results that there are a lot of methods named just delete. While we're at it, can I rename LocalFile::delete to LocalFile::deleteFile? It'll be simpler than supporting 2 signatures in the transition, and make any future changes a bit simpler

Or perhaps also rename ::deleteOld to ::deleteOldFile - its a lot easier to transition from one function to another than one signature to another

Change 574882 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] LocalFileDeleteBatch: Migrate to new signature requiring a user

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

There is only 1 known caller of deleteOld, within core, so it should be pretty easy

DannyS712 triaged this task as Medium priority.Mar 13 2020, 3:42 AM

There is only 1 known caller of deleteOld, within core, so it should be pretty easy

Doing as part of the main patch:

  • Hard deprecate old constructor
  • Hard deprecate deleteOld
  • Soft deprecate delete

Release notes will be added once this is ready for +2, to avoid merge conflicts

Moving to review column, since I think everything that needed to be discussed has been

Per T193613: RFC: Establish stable interface policy for PHP code and https://www.mediawiki.org/wiki/Stable_interface_policy

It's generally unsafe to directly instantiate (using new) classes defined by MediaWiki core, unless that class is marked as @newable.

Is backwards compatibility for the LocalFileDeleteBatch needed in this case? It has no known callers outside of core.

The policy doesn't really apply yet, since we didn't yet put all the annotations in place (actually, none of the annotations). This class probably should all be marked as internal.

So here, we should still follow an old 'common sense' policy. Given that this is not used anywhere else, I think we can skip b/c step here if needed. However, the patch referenced does provide b/c with instant hard-deprecation and it looks ok to me. What does dropping b/c with no deprecation buy us here? If we can cut the proposed migraration plan by 1 release - let's do it, if not - the proposed patch with b/c would be beneficial.

The policy doesn't really apply yet, since we didn't yet put all the annotations in place (actually, none of the annotations). This class probably should all be marked as internal.

So here, we should still follow an old 'common sense' policy. Given that this is not used anywhere else, I think we can skip b/c step here if needed. However, the patch referenced does provide b/c with instant hard-deprecation and it looks ok to me. What does dropping b/c with no deprecation buy us here? If we can cut the proposed migraration plan by 1 release - let's do it, if not - the proposed patch with b/c would be beneficial.

Since the callers are being deprecated normally, the overall migration won't be quickened, so I'll just leave it with backwards compatibility but mark it as internal

but mark it as internal

That's not really a part of this project and will be dealt with when all the annotations are put in place.. So maybe don't

Change 574882 merged by jenkins-bot:
[mediawiki/core@master] LocalFileDeleteBatch: Migrate to new signature requiring a user

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

Change 580378 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/extensions/GraphViz@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582174 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] FileDeleteForm: Use LocalFile::deleteFile

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

Change 582175 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/extensions/FileImporter@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582176 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/extensions/DeleteBatch@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582174 merged by jenkins-bot:
[mediawiki/core@master] FileDeleteForm: Use LocalFile::deleteFile

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

Change 582176 merged by jenkins-bot:
[mediawiki/extensions/DeleteBatch@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582175 merged by jenkins-bot:
[mediawiki/extensions/FileImporter@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 580378 merged by jenkins-bot:
[mediawiki/extensions/GraphViz@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582305 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] deleteBatch: Use LocalFile::deleteFile

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

Change 582314 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/extensions/WebDAV@master] Use LocalFile::deleteFile in MW 1.35+

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

Change 582305 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] deleteBatch: Use LocalFile::deleteFile

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

Patch updated to include also SpecialMovePage, meaning it handles the last 2 uses in core. Some of the extensions haven't been updated yet, but none of those are deployed by WMF, and so we don't need to wait and can go ahead with hard deprecating the methods

Change 582315 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] Hard deprecate File::delete methods

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

Change 582305 merged by jenkins-bot:
[mediawiki/core@master] DeleteBatch and SpecialMovepage: Use LocalFile::deleteFile

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

Change 582315 merged by jenkins-bot:
[mediawiki/core@master] Hard deprecate File::delete methods

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

@Pchelolo can you take a look at https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/WebDAV/+/582314/ ? Its the last remaining unconditional call to LocalFile::delete

Change 582314 merged by jenkins-bot:
[mediawiki/extensions/WebDAV@master] Use LocalFile::deleteFile in MW 1.35+

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