Wikia/app — pull request #4345 by drsnyder (2014-07-31 21:37:21+00:00)
Title: POC Wrap global state: Not because you want to, but because sometimes you have to

There is a common pattern in the code that violates the [principle of least surprise](http://en.wikipedia.org/wiki/Principle_of_least_astonishment) and breaks encapsulation. It goes something like this:

```PHP
global $wgUser;
$saveWgUser = $wgUser;
$wgUser = $theUserIWantItToBe.

// do something (sometimes lots of things), that has side effects using
// $wgUser but doesn't take a $user parameter in MediaWiki core or pass
// it down the call stack

$wgUser = $saveWgUser;
```

Generally this is a terrible practice but has been accommodated in the MediaWiki code base for various reasons. Some of those reasons may be legitimate such as not wanting to modify or alter a heavily used core component that has little or no testing. We do this not because we want to, but because sometimes we have to.

This save/restore pattern also creates an additional plane of state that the code reader (and author) has to mentally track. The code base is large and complex enough that we don't need these distractions.

This pull request attempts to address this by adding a global state wrapper. This may best be illustrated by an example. The example above using the wrapper would look like this:

```PHP
$wrapper = new GlobalStateWrapper(array('wgUser' => $$theUserIWantItToBe));
$result = $wrapper->wrap(function () {
// do something (hopefully one thing) that has side effects using $wgUser but doesn't take a $user
// parameter in MediaWiki core
});
```

This has three benefits. First, it gives a very clear signal to the reader of the code what is happening which should free them to focus on more important details. Second, it handles all of the boilerplate of saving and restoring the `$wgUser` variable. And finally, if something goes wrong, you don't have to litter your code with `try/catch` statements that restore the state of `$wgUser` should something go wrong.

The inspiration came from [here](https://github.com/Wikia/app/pull/4336) and [here](https://github.com/Wikia/app/pull/4319#discussion-diff-15655235R46). Feedback is welcome.

@Wikia/platform-team @garthwebb @inez