Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Lookup
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 3
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isDisambiguationPage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 filterDisambiguationPageIds
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3namespace MediaWiki\Extension\Disambiguator;
4
5use MediaWiki\Title\Title;
6use Wikimedia\Rdbms\IConnectionProvider;
7
8class Lookup {
9
10    public function __construct(
11        private readonly IConnectionProvider $dbProvider,
12    ) {
13    }
14
15    /**
16     * Convenience function for testing whether or not a page is a disambiguation page
17     *
18     * @param Title $title object of a page
19     * @return bool
20     */
21    public function isDisambiguationPage( Title $title ) {
22        $res = $this->filterDisambiguationPageIds( [ $title->getArticleID() ] );
23        return (bool)count( $res );
24    }
25
26    /**
27     * Convenience function for testing whether or not pages are disambiguation pages
28     *
29     * @param int[] $pageIds
30     * @return int[] The page ids corresponding to pages that are disambiguations
31     */
32    public function filterDisambiguationPageIds( array $pageIds ) {
33        // Don't needlessly check non-existent and special pages
34        $pageIds = array_filter(
35            $pageIds,
36            static function ( $id ) {
37                return $id > 0;
38            }
39        );
40
41        $output = [];
42        if ( $pageIds ) {
43            $dbr = $this->dbProvider->getReplicaDatabase();
44
45            $redirects = [];
46            /** @var array<int,int[]> $redirectsMap */
47            $redirectsMap = [];
48            // resolve redirects
49            $res = $dbr->newSelectQueryBuilder()
50                ->select( [ 'page_id', 'rd_from' ] )
51                ->from( 'page' )
52                ->join( 'redirect', null, [
53                    'rd_namespace=page_namespace',
54                    'rd_title=page_title',
55                    'rd_interwiki' => '',
56                ] )
57                ->where( [ 'rd_from' => $pageIds ] )
58                ->caller( __METHOD__ )
59                ->fetchResultSet();
60            foreach ( $res as $row ) {
61                $redirects[] = $row->rd_from;
62                // Key is the destination page ID, values are the source page IDs
63                $redirectsMap[$row->page_id][] = $row->rd_from;
64            }
65
66            $pageIdsWithRedirects = array_merge( array_keys( $redirectsMap ),
67                array_diff( $pageIds, $redirects ) );
68            $res = $dbr->newSelectQueryBuilder()
69                ->select( 'pp_page' )
70                ->from( 'page_props' )
71                ->where( [ 'pp_page' => $pageIdsWithRedirects, 'pp_propname' => 'disambiguation' ] )
72                ->caller( __METHOD__ )
73                ->fetchResultSet();
74
75            foreach ( $res as $row ) {
76                $disambiguationPageId = $row->pp_page;
77                if ( array_key_exists( $disambiguationPageId, $redirectsMap ) ) {
78                    $output = array_merge( $output, $redirectsMap[$disambiguationPageId] );
79                }
80                if ( in_array( $disambiguationPageId, $pageIds ) ) {
81                    $output[] = $disambiguationPageId;
82                }
83            }
84        }
85
86        return $output;
87    }
88}