Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
63.64% covered (warning)
63.64%
28 / 44
78.57% covered (warning)
78.57%
11 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
IncidentReport
63.64% covered (warning)
63.64%
28 / 44
78.57% covered (warning)
78.57%
11 / 14
25.82
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 behaviorTypes
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 newFromRestPayload
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 getReportingUser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIncidentType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBehaviorType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPhysicalHarmType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDetails
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionRecord
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReportedUser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSomethingElseDetails
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getThreadId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDirectReport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types=1 );
3
4namespace MediaWiki\Extension\ReportIncident;
5
6use MediaWiki\Page\PageReference;
7use MediaWiki\Revision\RevisionRecord;
8use MediaWiki\User\UserIdentity;
9use Wikimedia\Assert\Assert;
10
11/**
12 * Plain value object containing incident report data.
13 */
14class IncidentReport {
15    public const THREAT_TYPE_IMMEDIATE = 'immediate-threat-physical-harm';
16    public const THREAT_TYPE_UNACCEPTABLE_BEHAVIOR = 'unacceptable-user-behavior';
17
18    public function __construct(
19        private readonly UserIdentity $reportingUser,
20        private readonly ?UserIdentity $reportedUser,
21        private readonly ?RevisionRecord $revisionRecord,
22        private readonly PageReference $page,
23        private readonly string $incidentType,
24        private readonly ?string $behaviorType,
25        private readonly ?string $physicalHarmType,
26        private readonly ?string $somethingElseDetails = null,
27        private readonly ?string $details = null,
28        private readonly ?string $threadId = null,
29        private readonly ?string $directReport = null,
30    ) {
31        $page->assertWiki( PageReference::LOCAL );
32
33        Assert::parameter(
34            $revisionRecord === null || $revisionRecord->getPage()->isSamePageAs( $page ),
35            '$revision',
36            'The given revision must match the given page',
37        );
38    }
39
40    /**
41     * Known values for the 'behaviorType' field.
42     * This should match the list of allowed values for "unacceptable behavior" reports on the frontend.
43     *
44     * @return string[]
45     */
46    public static function behaviorTypes(): array {
47        return [
48            'doxing',
49            'hate-or-discrimination',
50            'intimidation',
51            'sexual-harassment',
52            'spam',
53            'trolling',
54            'something-else',
55            'sockpuppetry',
56            'vandalism',
57            'userdispute',
58            'disruptiveediting',
59            'other'
60        ];
61    }
62
63    public static function newFromRestPayload(
64        UserIdentity $reportingUser,
65        array $data
66    ): IncidentReport {
67        return new self(
68            $reportingUser,
69            $data['reportedUser'],
70            $data['revision'] ?? null,
71            $data['page'],
72            $data['incidentType'],
73            $data['behaviorType'] ?? null,
74            $data['physicalHarmType'] ?? null,
75            $data['somethingElseDetails'] ?? null,
76            $data['details'] ?? null,
77            $data['threadId'] ?? null,
78            $data['directReport'] ?? null
79        );
80    }
81
82    public function getReportingUser(): UserIdentity {
83        return $this->reportingUser;
84    }
85
86    public function getIncidentType(): string {
87        return $this->incidentType;
88    }
89
90    public function getBehaviorType(): ?string {
91        return $this->behaviorType;
92    }
93
94    public function getPhysicalHarmType(): ?string {
95        return $this->physicalHarmType;
96    }
97
98    public function getDetails(): ?string {
99        return $this->details;
100    }
101
102    public function getRevisionRecord(): ?RevisionRecord {
103        return $this->revisionRecord;
104    }
105
106    public function getPage(): PageReference {
107        return $this->page;
108    }
109
110    public function getReportedUser(): ?UserIdentity {
111        return $this->reportedUser;
112    }
113
114    public function getSomethingElseDetails(): ?string {
115        return $this->somethingElseDetails;
116    }
117
118    public function getThreadId(): ?string {
119        return $this->threadId;
120    }
121
122    public function getDirectReport(): ?string {
123        return $this->directReport;
124    }
125}