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