Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.00% covered (warning)
80.00%
44 / 55
84.21% covered (warning)
84.21%
16 / 19
CRAP
0.00% covered (danger)
0.00%
0 / 1
QuestionRecord
80.00% covered (warning)
80.00%
44 / 55
84.21% covered (warning)
84.21%
16 / 19
34.27
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 isArchived
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setArchived
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getQuestionText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSectionHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getResultUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 jsonSerialize
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 newFromArray
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
6
 ensureValidBoolean
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 ensureValidTimestamp
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getArchiveUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setArchiveUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setQuestionText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isVisible
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setVisible
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentModel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare( strict_types = 1 );
4
5namespace GrowthExperiments\HelpPanel;
6
7use JsonSerializable;
8
9class QuestionRecord implements JsonSerializable {
10
11    private string $questionText;
12    private string $sectionHeader;
13    /** @var string|int|null */
14    private $revId;
15    private string $resultUrl;
16    private string $archiveUrl;
17    private int $timestamp;
18    private bool $isArchived;
19    private bool $isVisible;
20    private string $contentModel;
21
22    /**
23     * @param string $questionText
24     * @param string $sectionHeader
25     * @param string|int|null $revId
26     * @param int $timestamp
27     * @param string $resultUrl
28     * @param string $contentModel
29     * @param string $archiveUrl
30     * @param bool $isArchived
31     * @param bool $isVisible
32     */
33    public function __construct(
34        string $questionText,
35        string $sectionHeader,
36        $revId,
37        int $timestamp,
38        string $resultUrl,
39        string $contentModel,
40        string $archiveUrl = '',
41        bool $isArchived = false,
42        bool $isVisible = true
43    ) {
44        $this->questionText = $questionText;
45        $this->sectionHeader = $sectionHeader;
46        $this->revId = $revId;
47        $this->resultUrl = $resultUrl;
48        $this->contentModel = $contentModel;
49        $this->timestamp = $timestamp;
50        $this->isArchived = $isArchived;
51        $this->isVisible = $isVisible;
52        $this->archiveUrl = $archiveUrl;
53    }
54
55    public function isArchived(): bool {
56        return $this->isArchived;
57    }
58
59    public function setArchived( bool $isArchived ): void {
60        $this->isArchived = $isArchived;
61    }
62
63    public function getQuestionText(): string {
64        return $this->questionText;
65    }
66
67    public function getSectionHeader(): string {
68        return $this->sectionHeader;
69    }
70
71    /**
72     * @return string|int|null
73     */
74    public function getRevId() {
75        return $this->revId;
76    }
77
78    public function getResultUrl(): string {
79        return $this->resultUrl;
80    }
81
82    public function getTimestamp(): int {
83        return $this->timestamp;
84    }
85
86    public function jsonSerialize(): array {
87        return [
88            'questionText' => $this->getQuestionText(),
89            'sectionHeader' => $this->getSectionHeader(),
90            'revId' => $this->getRevId(),
91            'resultUrl' => $this->getResultUrl(),
92            'contentModel' => $this->getContentModel(),
93            'archiveUrl' => $this->getArchiveUrl(),
94            'timestamp' => $this->getTimestamp(),
95            'isArchived' => $this->isArchived(),
96            'isVisible' => $this->isVisible(),
97        ];
98    }
99
100    public static function newFromArray( array $content ): self {
101        return new self(
102            is_string( $content['questionText'] ?? null ) ? $content['questionText'] : '',
103            is_string( $content['sectionHeader'] ?? null ) ? $content['sectionHeader'] : '',
104            $content['revId'] ?? 0,
105            self::ensureValidTimestamp( $content['timestamp'] ?? null ),
106            is_string( $content['resultUrl'] ?? null ) ? $content['resultUrl'] : '',
107            is_string( $content['contentModel'] ?? null ) ? $content['contentModel'] : CONTENT_MODEL_WIKITEXT,
108            is_string( $content['archiveUrl'] ?? null ) ? $content['archiveUrl'] : '',
109            self::ensureValidBoolean( $content['isArchived'] ?? null, false ),
110            self::ensureValidBoolean( $content['isVisible'] ?? null, true ),
111        );
112    }
113
114    /**
115     * Returns its first argument as a bool if reasonably possible, returns the provided default argument otherwise.
116     *
117     * @param mixed $value
118     * @param bool $default
119     */
120    private static function ensureValidBoolean( $value, bool $default ): bool {
121        if ( is_bool( $value ) ) {
122            return $value;
123        }
124        if ( is_numeric( $value ) ) {
125            return (bool)$value;
126        }
127        return $default;
128    }
129
130    /**
131     * Returns its argument as an int if reasonably possible, assuming it to be a unix timestamp.
132     * Returns the current unix timestamp otherwise.
133     *
134     * @param mixed $timestamp
135     */
136    private static function ensureValidTimestamp( $timestamp ): int {
137        if ( is_int( $timestamp ) ) {
138            return $timestamp;
139        }
140        if ( is_numeric( $timestamp ) ) {
141            return (int)$timestamp;
142        }
143        return (int)wfTimestamp();
144    }
145
146    public function getArchiveUrl(): string {
147        return $this->archiveUrl;
148    }
149
150    public function setArchiveUrl( string $archiveUrl ): void {
151        $this->archiveUrl = $archiveUrl;
152    }
153
154    public function setQuestionText( string $questionText ): void {
155        $this->questionText = $questionText;
156    }
157
158    public function isVisible(): bool {
159        return $this->isVisible;
160    }
161
162    public function setVisible( bool $isVisible ): void {
163        $this->isVisible = $isVisible;
164    }
165
166    public function setTimestamp( int $timestamp ): void {
167        $this->timestamp = $timestamp;
168    }
169
170    public function getContentModel(): string {
171        return $this->contentModel;
172    }
173
174}