The Article class was a problem we've been trying to fix.
Article basically was 3 things rolled all into one:
1) A page generation class that when run would fill up OutputPage
2) A context that references a Title, of course using the global $wg
context for the rest at the time
3) A glorified Title, containing helpers for doing article related things
Taking the place of 1) we have things like SpecialPage, Action, and some
things that are still left inside Article. (I'm hoping to eliminate Action
and Article with the pageoutput branch though.)
Taking the place of 2) we have a RequestContext system. Instead of
hoarding information to itself the classes that fill up OutputPage make
use of a context.
Taking the place of 3) we have WikiPage.
However, I'm starting to see a new pattern in the quest to eliminate
Article that's making a brand new mistake.
function __constructor( Page $page, IContextSource $context = null ) { ...
}
People seam to be changing constructors for (1) type things that fill up
OutputPage that once took an Article into one that takes a WikiPage and a
RequestContext, in situations where a Context should be enough information.
WikiPage is basically a glorified title. It takes a single title, and
provides access to a number of helpers for that title, such as fetching
content, and other information.
Anyone with a title can get a WikiPage perfectly usable for their purposes
by calling WikiPage::factory( $title );
WikiPage has ABSOLUTELY no user state to it. There is no setXYZ on
WikiPage that would make one WikiPage unique from another WikiPage
obtained from the same title and warrant keeping WikiPage around. The only
/state/ WikiPage has is a few member variables to cache information about
the title it's fetched from the database, such as the contents of the
revision so that it doesn't keep re-fetching them.
The ONLY reason I see to pass a WikiPage when you already have a Title is
so that the WikiPage instance you have doesn't lose the cached stuff like
revision that it already fetched from the database.
----
I'd like to propose a different pattern.
Because WikiPage is basically a glorified Title we move our pattern for
getting ahold of a WikiPage to where we get our title. In other words, we
add RequestContext::getWikiPage which will run WikiPage::factory(
$this->getTitle() ); to get the WikiPage relevant to a Title. If setTitle
is used on that RequestContext we unset the WikiPage we have on
RequestContext since the title has changed.
((Unless someone thinks that it would be a better idea for
WikiPage::factory or whatever we call it to only create a singleton
instance per-title. ie: `WikiPage::factory( Title::newFromText( 'Asdf' )
=== WikiPage::factory( Title::newFromText( 'Asdf' );`))
Our page generation classes like Action, etc... accept a Context. If they
need a WikiPage to access the Title helpers they use getWikiPage on the
context they are working in.
In the case where we need to tell a output page generating class to use a
different title than the one we have in our context, we make use of a
proper DerivativeContext instead of handing it a WikiPage for a different
title than the context and utterly confusing it.
For example, if we had Special:History/Foo as our title and wanted to run
HistoryPage with a context of "Foo" as a title:
$pageContext = new DerivativeContext( $context );
$pageContext->setTitle( Title::newFromText( 'Foo' ) );
$... = new HistoryPage( $pageContext );
--
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [
http://daniel.friesen.name]