Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.98% covered (warning)
82.98%
39 / 47
37.50% covered (danger)
37.50%
3 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractZObjectPager
82.98% covered (warning)
82.98%
39 / 47
37.50% covered (danger)
37.50%
3 / 8
18.43
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getZObjectStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQueryInfo
95.24% covered (success)
95.24%
20 / 21
0.00% covered (danger)
0.00%
0 / 1
2
 getIndexField
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
5.93
 getDefaultDirections
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
5.93
 getEmptyBody
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBottomLinks
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 formatRow
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * WikiLambda AbstractZObjectPager extends AlphabeticPager
4 *
5 * @file
6 * @ingroup Extensions
7 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
8 * @license MIT
9 */
10
11namespace MediaWiki\Extension\WikiLambda\Pagers;
12
13use MediaWiki\Context\IContextSource;
14use MediaWiki\Extension\WikiLambda\ZObjectStore;
15use MediaWiki\Pager\AlphabeticPager;
16use Wikimedia\Rdbms\RawSQLValue;
17use Wikimedia\Rdbms\Subquery;
18
19abstract class AbstractZObjectPager extends AlphabeticPager {
20
21    public const ORDER_BY_NAME = 'name';
22    public const ORDER_BY_OLDEST = 'oldest';
23    public const ORDER_BY_LATEST = 'latest';
24    public const ORDER_BY_OPTIONS = [ self::ORDER_BY_NAME, self::ORDER_BY_OLDEST, self::ORDER_BY_LATEST ];
25
26    private array $languageZids;
27    private string $orderby;
28    private bool $excludePreDefined;
29
30    /**
31     * @param IContextSource|null $context Context.
32     * @param ZObjectStore $zObjectStore
33     * @param array $languageZids
34     * @param string|null $orderby
35     * @param bool|null $excludePreDefined
36     */
37    public function __construct(
38        $context,
39        private readonly ZObjectStore $zObjectStore,
40        $languageZids,
41        $orderby = null,
42        $excludePreDefined = null
43    ) {
44        $this->languageZids = $languageZids;
45        $this->orderby = $orderby ?? self::ORDER_BY_NAME;
46        $this->excludePreDefined = $excludePreDefined ?? false;
47
48        parent::__construct( $context );
49    }
50
51    /**
52     * Get the ZObjectStore object
53     *
54     * @return ZObjectStore
55     */
56    public function getZObjectStore() {
57        return $this->zObjectStore;
58    }
59
60    /**
61     * Provides all parameters needed for the main paged query. It returns
62     * an associative array with the following elements:
63     *    tables => Table(s) for passing to Database::select()
64     *    fields => Field(s) for passing to Database::select(), may be *
65     *    conds => WHERE conditions
66     *    options => option array
67     *    join_conds => JOIN conditions
68     *
69     * For Wikilambda ZObjects:
70     * * Fetches from labels table
71     * * Uses the normalised primary label for alphabetic pagination
72     *
73     * @return array
74     */
75    public function getQueryInfo() {
76        // Returns table with unique zids and the most preferred primary label
77        $subquery = $this->zObjectStore->getPreferredLabelsQuery( $this->languageZids )->getSQL();
78
79        $tables = [ 'preferred_labels' => new Subquery( $subquery ) ];
80        $fields = [
81            'page_id',
82            'wlzl_zobject_zid',
83            'wlzl_label',
84            'wlzl_label_normalised',
85            'wlzl_language',
86            'wlzl_label_primary'
87        ];
88        $conds = [];
89        if ( $this->excludePreDefined ) {
90            $conds[] = ( new RawSQLValue( 'LENGTH( wlzl_zobject_zid ) > 5' ) )->toSQL();
91        }
92
93        $queryInfo = [
94            'tables' => $tables,
95            'fields' => $fields,
96            'conds' => $conds,
97            'join_conds' => [],
98            'options' => []
99        ];
100
101        return $queryInfo;
102    }
103
104    /**
105     * Return the name of the field that is used for alphabetic sorting.
106     *
107     * @return string
108     */
109    public function getIndexField() {
110        switch ( $this->orderby ) {
111            case self::ORDER_BY_NAME:
112                return 'wlzl_label_normalised';
113            case self::ORDER_BY_LATEST:
114            case self::ORDER_BY_OLDEST:
115            default:
116                return 'page_id';
117        }
118    }
119
120    /**
121     * Return the direction or order results in
122     *
123     * @return bool
124     */
125    public function getDefaultDirections() {
126        switch ( $this->orderby ) {
127            case self::ORDER_BY_LATEST:
128                return self::DIR_DESCENDING;
129            case self::ORDER_BY_NAME:
130            case self::ORDER_BY_OLDEST:
131            default:
132                return self::DIR_ASCENDING;
133        }
134    }
135
136    /**
137     * @return string
138     */
139    public function getEmptyBody() {
140        return $this->msg( 'wikilambda-special-list-empty' )->parse();
141    }
142
143    /**
144     * @return string
145     */
146    public function getBottomLinks() {
147        $wikitext = "\n== " . $this->msg( 'wikilambda-special-list-all-pages' )->text() . " ==\n";
148
149        $wikitext .= "\n* [[Special:ListObjectsByType|" .
150            $this->msg( 'wikilambda-special-objectsbytype-link' )->text() . "]]\n";
151
152        $wikitext .= "\n* [[Special:ListDuplicateObjectNames|" .
153            $this->msg( 'wikilambda-special-listduplicateobjectlabels-link' )->text() . "]]\n";
154
155        $wikitext .= "\n* [[Special:ListMissingLabels|" .
156            $this->msg( 'wikilambda-special-missinglabels' )->text() . "]]\n";
157
158        $wikitext .= "\n* [[Special:ListFunctionsByTests|" .
159            $this->msg( 'wikilambda-special-functionsbytests' )->text() . "]]\n";
160
161        return $wikitext;
162    }
163
164    /**
165     * Process each row returned from the query.
166     * This is where we build up the list of ZObjects.
167     *
168     * @param \stdClass $row
169     * @return string
170     */
171    public function formatRow( $row ) {
172        $zid = $row->wlzl_zobject_zid;
173        $label = $row->wlzl_label;
174        // Wrap the label in <nowiki> to escape all wikitext syntax
175        $escapedLabel = "<nowiki>$label</nowiki>";
176        return "# [[$zid|$escapedLabel]] ($zid)\n";
177    }
178}