1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
<?php
namespace MediaWiki\Page;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Page\Hook\WikiPageFactoryHook;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleFactory;
use stdClass;
use WikiCategoryPage;
use WikiFilePage;
use Wikimedia\Rdbms\DBAccessObjectUtils;
use Wikimedia\Rdbms\IConnectionProvider;
use WikiPage;
/**
* Service for creating WikiPage objects.
*
* @since 1.36
*/
class WikiPageFactory {
private TitleFactory $titleFactory;
private WikiPageFactoryHook $wikiPageFactoryHookRunner;
private IConnectionProvider $dbProvider;
public function __construct(
TitleFactory $titleFactory,
WikiPageFactoryHook $wikiPageFactoryHookRunner,
IConnectionProvider $dbProvider
) {
$this->titleFactory = $titleFactory;
$this->wikiPageFactoryHookRunner = $wikiPageFactoryHookRunner;
$this->dbProvider = $dbProvider;
}
/**
* Create a WikiPage object from a title.
*
* @param PageIdentity $pageIdentity
* @return WikiPage
*/
public function newFromTitle( PageIdentity $pageIdentity ): WikiPage {
if ( $pageIdentity instanceof WikiPage ) {
return $pageIdentity;
}
if ( !$pageIdentity->canExist() ) {
// BC with the Title class
throw new PageAssertionException(
'The given PageIdentity {pageIdentity} does not represent a proper page',
[ 'pageIdentity' => $pageIdentity ]
);
}
$ns = $pageIdentity->getNamespace();
// TODO: remove the need for casting to Title. We'll have to create a new hook to
// replace the WikiPageFactory hook.
$title = Title::newFromPageIdentity( $pageIdentity );
$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
* @return WikiPage
*/
public function newFromLinkTarget( LinkTarget $title ): WikiPage {
return $this->newFromTitle( $this->titleFactory->newFromLinkTarget( $title ) );
}
/**
* Create a WikiPage object from a database row
*
* @param stdClass $row Database row containing at least fields returned by getQueryInfo().
* @param string|int $from Source of $data:
* - "fromdb" or IDBAccessObject::READ_NORMAL: from a replica DB
* - "fromdbmaster" or IDBAccessObject::READ_LATEST: from the primary DB
* - "forupdate" or IDBAccessObject::READ_LOCKING: from the primary DB using SELECT FOR UPDATE
*
* @return WikiPage
*/
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 IDBAccessObject::READ_NORMAL to select from a replica DB
* - "fromdbmaster" or IDBAccessObject::READ_LATEST to select from the primary database
*
* @return WikiPage|null Null when no page exists with that ID
*/
public function newFromID( $id, $from = 'fromdb' ) {
// page ids are never 0 or negative, see T63166
if ( $id < 1 ) {
return null;
}
$db = DBAccessObjectUtils::getDBFromRecency( $this->dbProvider, WikiPage::convertSelectType( $from ) );
$pageQuery = WikiPage::getQueryInfo();
$row = $db->newSelectQueryBuilder()
->queryInfo( $pageQuery )
->where( [ 'page_id' => $id ] )
->caller( __METHOD__ )
->fetchRow();
if ( !$row ) {
return null;
}
return $this->newFromRow( $row, $from );
}
}
|