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\ContentModelChangeFactory;
|
||||||
use MediaWiki\Page\MergeHistoryFactory;
|
use MediaWiki\Page\MergeHistoryFactory;
|
||||||
use MediaWiki\Page\MovePageFactory;
|
use MediaWiki\Page\MovePageFactory;
|
||||||
|
use MediaWiki\Page\WikiPageFactory;
|
||||||
use MediaWiki\Permissions\PermissionManager;
|
use MediaWiki\Permissions\PermissionManager;
|
||||||
use MediaWiki\Preferences\PreferencesFactory;
|
use MediaWiki\Preferences\PreferencesFactory;
|
||||||
use MediaWiki\Revision\ContributionsLookup;
|
use MediaWiki\Revision\ContributionsLookup;
|
||||||
|
|
@ -1361,6 +1362,14 @@ class MediaWikiServices extends ServiceContainer {
|
||||||
return $this->getService( 'WatchlistNotificationManager' );
|
return $this->getService( 'WatchlistNotificationManager' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.36
|
||||||
|
* @return WikiPageFactory
|
||||||
|
*/
|
||||||
|
public function getWikiPageFactory() : WikiPageFactory {
|
||||||
|
return $this->getService( 'WikiPageFactory' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 1.31
|
* @since 1.31
|
||||||
* @return OldRevisionImporter
|
* @return OldRevisionImporter
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ use MediaWiki\Page\ContentModelChangeFactory;
|
||||||
use MediaWiki\Page\MergeHistoryFactory;
|
use MediaWiki\Page\MergeHistoryFactory;
|
||||||
use MediaWiki\Page\MovePageFactory;
|
use MediaWiki\Page\MovePageFactory;
|
||||||
use MediaWiki\Page\PageCommandFactory;
|
use MediaWiki\Page\PageCommandFactory;
|
||||||
|
use MediaWiki\Page\WikiPageFactory;
|
||||||
use MediaWiki\Permissions\PermissionManager;
|
use MediaWiki\Permissions\PermissionManager;
|
||||||
use MediaWiki\Preferences\DefaultPreferencesFactory;
|
use MediaWiki\Preferences\DefaultPreferencesFactory;
|
||||||
use MediaWiki\Preferences\PreferencesFactory;
|
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' =>
|
'WikiRevisionOldRevisionImporterNoUpdates' =>
|
||||||
function ( MediaWikiServices $services ) : ImportableOldRevisionImporter {
|
function ( MediaWikiServices $services ) : ImportableOldRevisionImporter {
|
||||||
return new ImportableOldRevisionImporter(
|
return new ImportableOldRevisionImporter(
|
||||||
|
|
|
||||||
|
|
@ -151,33 +151,10 @@ class WikiPage implements Page, IDBAccessObject {
|
||||||
*
|
*
|
||||||
* @throws MWException
|
* @throws MWException
|
||||||
* @return WikiPage|WikiCategoryPage|WikiFilePage
|
* @return WikiPage|WikiCategoryPage|WikiFilePage
|
||||||
|
* @deprecated since 1.36, use WikiPageFactory::newFromTitle instead
|
||||||
*/
|
*/
|
||||||
public static function factory( Title $title ) {
|
public static function factory( Title $title ) {
|
||||||
$ns = $title->getNamespace();
|
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -189,24 +166,10 @@ class WikiPage implements Page, IDBAccessObject {
|
||||||
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
|
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
|
||||||
*
|
*
|
||||||
* @return WikiPage|null
|
* @return WikiPage|null
|
||||||
|
* @deprecated since 1.36, use WikiPageFactory::newFromID instead
|
||||||
*/
|
*/
|
||||||
public static function newFromID( $id, $from = 'fromdb' ) {
|
public static function newFromID( $id, $from = 'fromdb' ) {
|
||||||
// page ids are never 0 or negative, see T63166
|
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromID( $id, $from );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -219,11 +182,10 @@ class WikiPage implements Page, IDBAccessObject {
|
||||||
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
|
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
|
||||||
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
|
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
|
||||||
* @return WikiPage
|
* @return WikiPage
|
||||||
|
* @deprecated since 1.36, use WikiPageFactory::newFromRow instead
|
||||||
*/
|
*/
|
||||||
public static function newFromRow( $row, $from = 'fromdb' ) {
|
public static function newFromRow( $row, $from = 'fromdb' ) {
|
||||||
$page = self::factory( Title::newFromRow( $row ) );
|
return MediaWikiServices::getInstance()->getWikiPageFactory()->newFromRow( $row, $from );
|
||||||
$page->loadFromRow( $row, $from );
|
|
||||||
return $page;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -232,7 +194,7 @@ class WikiPage implements Page, IDBAccessObject {
|
||||||
* @param object|string|int $type
|
* @param object|string|int $type
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected static function convertSelectType( $type ) {
|
public static function convertSelectType( $type ) {
|
||||||
switch ( $type ) {
|
switch ( $type ) {
|
||||||
case 'fromdb':
|
case 'fromdb':
|
||||||
return self::READ_NORMAL;
|
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