Add WikiPageFactory
Replace WikiPage::factory with a proper factory object with dependency injection (only for dependencies needed by the factory methods, not WikiPage itself). Change-Id: Ie7d6e40d8387d8bc4f8592a31fdd70d0aad510ae
This commit is contained in:
parent
9c6473dc1d
commit
f871f7b93e
4 changed files with 167 additions and 45 deletions
|
|
@ -50,6 +50,7 @@ use MediaWiki\Mail\IEmailer;
|
|||
use MediaWiki\Page\ContentModelChangeFactory;
|
||||
use MediaWiki\Page\MergeHistoryFactory;
|
||||
use MediaWiki\Page\MovePageFactory;
|
||||
use MediaWiki\Page\WikiPageFactory;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\Preferences\PreferencesFactory;
|
||||
use MediaWiki\Revision\ContributionsLookup;
|
||||
|
|
@ -1361,6 +1362,14 @@ class MediaWikiServices extends ServiceContainer {
|
|||
return $this->getService( 'WatchlistNotificationManager' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.36
|
||||
* @return WikiPageFactory
|
||||
*/
|
||||
public function getWikiPageFactory() : WikiPageFactory {
|
||||
return $this->getService( 'WikiPageFactory' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.31
|
||||
* @return OldRevisionImporter
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ use MediaWiki\Page\ContentModelChangeFactory;
|
|||
use MediaWiki\Page\MergeHistoryFactory;
|
||||
use MediaWiki\Page\MovePageFactory;
|
||||
use MediaWiki\Page\PageCommandFactory;
|
||||
use MediaWiki\Page\WikiPageFactory;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\Preferences\DefaultPreferencesFactory;
|
||||
use MediaWiki\Preferences\PreferencesFactory;
|
||||
|
|
@ -1363,6 +1364,14 @@ return [
|
|||
);
|
||||
},
|
||||
|
||||
'WikiPageFactory' => function ( MediaWikiServices $services ) : WikiPageFactory {
|
||||
return new WikiPageFactory(
|
||||
$services->getTitleFactory(),
|
||||
new HookRunner( $services->getHookContainer() ),
|
||||
$services->getDBLoadBalancer()
|
||||
);
|
||||
},
|
||||
|
||||
'WikiRevisionOldRevisionImporterNoUpdates' =>
|
||||
function ( MediaWikiServices $services ) : ImportableOldRevisionImporter {
|
||||
return new ImportableOldRevisionImporter(
|
||||
|
|
|
|||
|
|
@ -151,33 +151,10 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
*
|
||||
* @throws MWException
|
||||
* @return WikiPage|WikiCategoryPage|WikiFilePage
|
||||
* @deprecated since 1.36, use WikiPageFactory::newFromTitle instead
|
||||
*/
|
||||
public static function factory( Title $title ) {
|
||||
$ns = $title->getNamespace();
|
||||
|
||||
if ( $ns == NS_MEDIA ) {
|
||||
throw new MWException( "NS_MEDIA is a virtual namespace; use NS_FILE." );
|
||||
} elseif ( $ns < 0 ) {
|
||||
throw new MWException( "Invalid or virtual namespace $ns given." );
|
||||
}
|
||||
|
||||
$page = null;
|
||||
if ( !Hooks::runner()->onWikiPageFactory( $title, $page ) ) {
|
||||
return $page;
|
||||
}
|
||||
|
||||
switch ( $ns ) {
|
||||
case NS_FILE:
|
||||
$page = new WikiFilePage( $title );
|
||||
break;
|
||||
case NS_CATEGORY:
|
||||
$page = new WikiCategoryPage( $title );
|
||||
break;
|
||||
default:
|
||||
$page = new WikiPage( $title );
|
||||
}
|
||||
|
||||
return $page;
|
||||
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -189,24 +166,10 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
|
||||
*
|
||||
* @return WikiPage|null
|
||||
* @deprecated since 1.36, use WikiPageFactory::newFromID instead
|
||||
*/
|
||||
public static function newFromID( $id, $from = 'fromdb' ) {
|
||||
// page ids are never 0 or negative, see T63166
|
||||
if ( $id < 1 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$from = self::convertSelectType( $from );
|
||||
$db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_REPLICA );
|
||||
$pageQuery = self::getQueryInfo();
|
||||
$row = $db->selectRow(
|
||||
$pageQuery['tables'], $pageQuery['fields'], [ 'page_id' => $id ], __METHOD__,
|
||||
[], $pageQuery['joins']
|
||||
);
|
||||
if ( !$row ) {
|
||||
return null;
|
||||
}
|
||||
return self::newFromRow( $row, $from );
|
||||
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromID( $id, $from );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -219,11 +182,10 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
|
||||
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
|
||||
* @return WikiPage
|
||||
* @deprecated since 1.36, use WikiPageFactory::newFromRow instead
|
||||
*/
|
||||
public static function newFromRow( $row, $from = 'fromdb' ) {
|
||||
$page = self::factory( Title::newFromRow( $row ) );
|
||||
$page->loadFromRow( $row, $from );
|
||||
return $page;
|
||||
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromRow( $row, $from );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -232,7 +194,7 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
* @param object|string|int $type
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function convertSelectType( $type ) {
|
||||
public static function convertSelectType( $type ) {
|
||||
switch ( $type ) {
|
||||
case 'fromdb':
|
||||
return self::READ_NORMAL;
|
||||
|
|
|
|||
142
includes/page/WikiPageFactory.php
Normal file
142
includes/page/WikiPageFactory.php
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Page;
|
||||
|
||||
use DBAccessObjectUtils;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\Page\Hook\WikiPageFactoryHook;
|
||||
use MWException;
|
||||
use Title;
|
||||
use TitleFactory;
|
||||
use WikiCategoryPage;
|
||||
use WikiFilePage;
|
||||
use Wikimedia\Rdbms\ILoadBalancer;
|
||||
use WikiPage;
|
||||
|
||||
/**
|
||||
* @since 1.36
|
||||
*/
|
||||
class WikiPageFactory {
|
||||
|
||||
/** @var TitleFactory */
|
||||
private $titleFactory;
|
||||
|
||||
/** @var WikiPageFactoryHook */
|
||||
private $wikiPageFactoryHookRunner;
|
||||
|
||||
/** @var ILoadBalancer */
|
||||
private $loadBalancer;
|
||||
|
||||
/**
|
||||
* @param TitleFactory $titleFactory
|
||||
* @param WikiPageFactoryHook $wikiPageFactoryHookRunner
|
||||
* @param ILoadBalancer $loadBalancer
|
||||
*/
|
||||
public function __construct(
|
||||
TitleFactory $titleFactory,
|
||||
WikiPageFactoryHook $wikiPageFactoryHookRunner,
|
||||
ILoadBalancer $loadBalancer
|
||||
) {
|
||||
$this->titleFactory = $titleFactory;
|
||||
$this->wikiPageFactoryHookRunner = $wikiPageFactoryHookRunner;
|
||||
$this->loadBalancer = $loadBalancer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WikiPage object from a title.
|
||||
*
|
||||
* @param Title $title
|
||||
*
|
||||
* @return WikiPage
|
||||
* @throws MWException
|
||||
*/
|
||||
public function newFromTitle( Title $title ) {
|
||||
$ns = $title->getNamespace();
|
||||
|
||||
if ( $ns == NS_MEDIA ) {
|
||||
throw new MWException( "NS_MEDIA is a virtual namespace; use NS_FILE." );
|
||||
} elseif ( $ns < 0 ) {
|
||||
throw new MWException( "Invalid or virtual namespace $ns given." );
|
||||
}
|
||||
|
||||
$page = null;
|
||||
if ( !$this->wikiPageFactoryHookRunner->onWikiPageFactory( $title, $page ) ) {
|
||||
return $page;
|
||||
}
|
||||
|
||||
switch ( $ns ) {
|
||||
case NS_FILE:
|
||||
$page = new WikiFilePage( $title );
|
||||
break;
|
||||
case NS_CATEGORY:
|
||||
$page = new WikiCategoryPage( $title );
|
||||
break;
|
||||
default:
|
||||
$page = new WikiPage( $title );
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WikiPage object from a link target.
|
||||
*
|
||||
* @param LinkTarget $title
|
||||
*
|
||||
* @throws MWException
|
||||
* @return WikiPage
|
||||
*/
|
||||
public function newFromLinkTarget( LinkTarget $title ) {
|
||||
return $this->newFromTitle( $this->titleFactory->newFromLinkTarget( $title ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WikiPage object from a database row
|
||||
*
|
||||
* @param object $row Database row containing at least fields returned by getQueryInfo().
|
||||
* @param string|int $from Source of $data:
|
||||
* - "fromdb" or WikiPage::READ_NORMAL: from a replica DB
|
||||
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
|
||||
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
|
||||
*
|
||||
* @return WikiPage
|
||||
* @throws MWException
|
||||
*/
|
||||
public function newFromRow( $row, $from = 'fromdb' ) {
|
||||
$page = $this->newFromTitle( $this->titleFactory->newFromRow( $row ) );
|
||||
$page->loadFromRow( $row, $from );
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WikiPage object from a page ID
|
||||
*
|
||||
* @param int $id Article ID to load
|
||||
* @param string|int $from One of the following values:
|
||||
* - "fromdb" or WikiPage::READ_NORMAL to select from a replica DB
|
||||
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
|
||||
*
|
||||
* @return WikiPage|null Null when no page exists with that ID
|
||||
* @throws MWException
|
||||
*/
|
||||
public function newFromID( $id, $from = 'fromdb' ) {
|
||||
// page ids are never 0 or negative, see T63166
|
||||
if ( $id < 1 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$from = WikiPage::convertSelectType( $from );
|
||||
[ $index ] = DBAccessObjectUtils::getDBOptions( $from );
|
||||
$db = $this->loadBalancer->getMaintenanceConnectionRef( $index );
|
||||
$pageQuery = WikiPage::getQueryInfo();
|
||||
$row = $db->selectRow(
|
||||
$pageQuery['tables'], $pageQuery['fields'], [ 'page_id' => $id ], __METHOD__,
|
||||
[], $pageQuery['joins']
|
||||
);
|
||||
if ( !$row ) {
|
||||
return null;
|
||||
}
|
||||
return $this->newFromRow( $row, $from );
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue