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