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 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ArticleCompileAfcTag
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 3
132
0.00% covered (danger)
0.00%
0 / 1
 getAfcCategories
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 compile
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
56
 loadPreviousAfcStates
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace MediaWiki\Extension\PageTriage\ArticleCompile;
4
5/**
6 * Tags for AfC submission state.
7 */
8class ArticleCompileAfcTag extends ArticleCompile {
9
10    public const UNSUBMITTED = 1;
11    public const PENDING = 2;
12    public const UNDER_REVIEW = 3;
13    public const DECLINED = 4;
14
15    /**
16     * @var array Associative array of page id to afc state. e.g. [ '123' => 2, '124' => 4 ]
17     */
18    private $previousAfcStates;
19
20    /**
21     * AFC categories in priority order (i.e. the first found will be used if a page is in more
22     * than one of these categories). UNSUBMITTED is not actually a category, rather the absence
23     * of the other categories.
24     * @return string[]
25     */
26    public static function getAfcCategories() {
27        return [
28            self::UNDER_REVIEW => 'Pending_AfC_submissions_being_reviewed_now',
29            self::PENDING => 'Pending_AfC_submissions',
30            self::DECLINED => 'Declined_AfC_submissions',
31        ];
32    }
33
34    /**
35     * Implements ArticleCompileInterface::compile(), called when generating tags.
36     * @return bool
37     */
38    public function compile() {
39        $this->previousAfcStates = $this->loadPreviousAfcStates( $this->mPageId );
40        foreach ( $this->mPageId as $pageId ) {
41            // Default to unsubmitted state; will be overridden if relevant category is present.
42            $this->metadata[$pageId]['afc_state'] = self::UNSUBMITTED;
43
44            $parserOutput = $this->getParserOutputByPageId( $pageId );
45            if ( !$parserOutput ) {
46                continue;
47            }
48
49            $previousState = $this->previousAfcStates[ $pageId ] ?? self::UNSUBMITTED;
50
51            // Try to identify the current afc_state of the page
52            // and request updating of 'update_reviewed_timestamp'
53            // if the state has changed.
54            $categories = $parserOutput->getCategoryNames();
55            foreach ( self::getAfcCategories() as $afcStateValue => $afcCategory ) {
56                if ( in_array( $afcCategory, $categories ) ) {
57                    $this->metadata[$pageId]['afc_state'] = $afcStateValue;
58
59                    // Drafts re-use the ptrp_reviewed_updated to serve as the time of the last
60                    // submission or last decline. See T195547
61                    if (
62                        in_array( $afcStateValue, [ self::PENDING, self::DECLINED ] ) &&
63                        $afcStateValue !== $previousState
64                    ) {
65                        $this->metadata[$pageId]['update_reviewed_timestamp'] = true;
66                    }
67
68                    // Only set the first found category (highest priority one).
69                    break;
70                }
71            }
72        }
73
74        return true;
75    }
76
77    /**
78     * @param int[] $pageIds
79     *
80     * @return int[]
81     */
82    private function loadPreviousAfcStates( $pageIds ) {
83        $states = [];
84        $afcStateTagId = $this->db->newSelectQueryBuilder()
85            ->select( 'ptrt_tag_id' )
86            ->from( 'pagetriage_tags' )
87            ->where( [ 'ptrt_tag_name' => 'afc_state' ] )
88            ->caller( __METHOD__ )
89            ->fetchField();
90        if ( $afcStateTagId ) {
91            $result = $this->db->newSelectQueryBuilder()
92                ->select( [ 'pageId' => 'ptrpt_page_id', 'afcState' => 'ptrpt_value' ] )
93                ->from( 'pagetriage_page_tags' )
94                ->where( [ 'ptrpt_page_id' => $pageIds, 'ptrpt_tag_id' => $afcStateTagId ] )
95                ->caller( __METHOD__ )
96                ->fetchResultSet();
97
98            foreach ( $result as $row ) {
99                $states[$row->pageId] = intval( $row->afcState );
100            }
101        }
102        return $states;
103    }
104
105}