Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SubpageSortkey
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 2
156
0.00% covered (danger)
0.00%
0 / 1
 onGetDefaultSortkey
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
72
 getSubpage
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\Extension\SubpageSortkey;
4
5use MediaWiki\Hook\GetDefaultSortkeyHook;
6use MediaWiki\MediaWikiServices;
7use MediaWiki\Title\Title;
8
9class SubpageSortkey implements GetDefaultSortkeyHook {
10    /**
11     * The GetDefaultSortkey hook.
12     * Basically prefixes the normal sortkey with some of the subpage
13     * parts of the current title.
14     *
15     * Example, if configured with "1,3..5,7" and given the
16     * page 0/1/2/3/4/5/6/7/8 it would prefix the sortkey with
17     * 1/3/4/5/7. Adding it to the normal sortkey,
18     * resulting in "0/1/3/4/5/7\n0/1/2/3/4/5/6/7/8".
19     * From there it might be further prefixed with whatever the
20     * {{DEFAULTSORT for a page is.
21     *
22     * Another example: Configuration -3..-1 turns 1/2/3/4/5 -> 3/4
23     * and -3.. turns 1/2/3/4/5 -> 3/4/5
24     * @param Title $title
25     * @param string &$unprefixed
26     */
27    public function onGetDefaultSortkey( $title, &$unprefixed ) {
28        global $wgSubpageSortkeyDefault,
29            $wgSubpageSortkeyByNamespace,
30            $wgSubpageSortkeyIfNoSubpageUseFullName;
31
32        $newSortkey = [];
33
34        $ns = $title->getNamespace();
35        if ( !MediaWikiServices::getInstance()->getNamespaceInfo()->hasSubpages( $ns ) ) {
36            // Do nothing
37            return;
38        }
39
40        if ( isset( $wgSubpageSortkeyByNamespace[$ns] ) ) {
41            $descript = $wgSubpageSortkeyByNamespace[$ns];
42        } else {
43            $descript = $wgSubpageSortkeyDefault;
44        }
45
46        $elms = explode( ',', $descript );
47        foreach ( $elms as $item ) {
48            $ranges = explode( '..', $item, 2 );
49            $start = intval( $ranges[0] );
50            if ( count( $ranges ) === 1 ) {
51                $count = 1;
52            } elseif ( $ranges[1] === '' ) {
53                $count = false;
54            } else {
55                $count = intval( $ranges[1] );
56            }
57            $newSortkey = array_merge( $newSortkey,
58                self::getSubpage( $start, $count, $title ) );
59        }
60        $newPrefix = implode( '/', $newSortkey );
61
62        // Don't prefix an extra \n if the prefix is empty.
63        if ( $newPrefix !== ''
64            || !$wgSubpageSortkeyIfNoSubpageUseFullName
65        ) {
66            $unprefixed = $newPrefix . "\n" . $unprefixed;
67        }
68    }
69
70    /**
71     * @param int $index starting index of subpage.
72     * @param int $count how many elements, or false to denote all
73     * @param Title $title
74     * @return string[] array of subpages
75     */
76    private static function getSubpage( $index, $count, $title ) {
77        $subpages = explode( '/', $title->getText() );
78        $numb = count( $subpages );
79
80        if ( $index > $numb ) {
81            return [];
82        }
83
84        if ( $count === false || $index + $count > $numb + 1 ) {
85            $count = $numb + 1 - $index;
86        }
87        return array_slice( $subpages, $index, $count );
88    }
89}