Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
28.57% |
8 / 28 |
|
20.00% |
1 / 5 |
CRAP | |
0.00% |
0 / 1 |
| CommentItemTrait | |
28.57% |
8 / 28 |
|
20.00% |
1 / 5 |
64.48 | |
0.00% |
0 / 1 |
| getParent | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| getAuthor | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| getTimestamp | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| jsonSerialize | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| jsonSerializeForDiff | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
| getTimestampString | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
| getHeading | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
| getSubscribableHeading | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace MediaWiki\Extension\DiscussionTools\ThreadItem; |
| 4 | |
| 5 | use DateTimeImmutable; |
| 6 | use MediaWiki\MediaWikiServices; |
| 7 | use RuntimeException; |
| 8 | |
| 9 | trait CommentItemTrait { |
| 10 | // phpcs:disable Squiz.WhiteSpace, MediaWiki.Commenting |
| 11 | // Required ThreadItem methods (listed for Phan) |
| 12 | abstract public function getParent(): ?ThreadItem; |
| 13 | // Required CommentItem methods (listed for Phan) |
| 14 | abstract public function getAuthor(): string; |
| 15 | abstract public function getTimestamp(): DateTimeImmutable; |
| 16 | // phpcs:enable |
| 17 | |
| 18 | /** |
| 19 | * @inheritDoc |
| 20 | * @suppress PhanTraitParentReference |
| 21 | */ |
| 22 | public function jsonSerialize( bool $deep = false, ?callable $callback = null ): array { |
| 23 | return array_merge( [ |
| 24 | 'timestamp' => $this->getTimestampString(), |
| 25 | 'author' => $this->getAuthor(), |
| 26 | ], parent::jsonSerialize( $deep, $callback ) ); |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * @return array JSON-serializable array |
| 31 | */ |
| 32 | public function jsonSerializeForDiff(): array { |
| 33 | $data = $this->jsonSerialize(); |
| 34 | |
| 35 | $heading = $this->getHeading(); |
| 36 | $data['headingId'] = $heading->getId(); |
| 37 | $subscribableHeading = $this->getSubscribableHeading(); |
| 38 | $data['subscribableHeadingId'] = $subscribableHeading ? $subscribableHeading->getId() : null; |
| 39 | |
| 40 | return $data; |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Get the comment timestamp in the format used in IDs and names. |
| 45 | * |
| 46 | * Depending on the date of the comment, this may use one of two formats: |
| 47 | * |
| 48 | * - For dates prior to 'DiscussionToolsTimestampFormatSwitchTime' (by default 2022-07-12): |
| 49 | * Uses ISO 8601 date. Almost DateTimeInterface::RFC3339_EXTENDED, but ending with 'Z' instead |
| 50 | * of '+00:00', like Date#toISOString in JavaScript. |
| 51 | * |
| 52 | * - For dates on or after 'DiscussionToolsTimestampFormatSwitchTime' (by default 2022-07-12): |
| 53 | * Uses MediaWiki timestamp (TS_MW in MediaWiki PHP code). |
| 54 | * |
| 55 | * @return string Comment timestamp in standard format |
| 56 | */ |
| 57 | public function getTimestampString(): string { |
| 58 | $dtConfig = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'discussiontools' ); |
| 59 | $switchTime = new DateTimeImmutable( |
| 60 | $dtConfig->get( 'DiscussionToolsTimestampFormatSwitchTime' ) |
| 61 | ); |
| 62 | $timestamp = $this->getTimestamp(); |
| 63 | if ( $timestamp < $switchTime ) { |
| 64 | return $timestamp->format( 'Y-m-d\TH:i:s.v\Z' ); |
| 65 | } else { |
| 66 | return $timestamp->format( 'YmdHis' ); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * @return ContentHeadingItem Closest ancestor which is a HeadingItem |
| 72 | */ |
| 73 | public function getHeading(): HeadingItem { |
| 74 | $parent = $this; |
| 75 | while ( $parent instanceof CommentItem ) { |
| 76 | $parent = $parent->getParent(); |
| 77 | } |
| 78 | if ( !( $parent instanceof HeadingItem ) ) { |
| 79 | throw new RuntimeException( 'Heading parent not found' ); |
| 80 | } |
| 81 | return $parent; |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * @return ContentHeadingItem|null Closest heading that can be used for topic subscriptions |
| 86 | */ |
| 87 | public function getSubscribableHeading(): ?HeadingItem { |
| 88 | $heading = $this->getHeading(); |
| 89 | while ( $heading instanceof HeadingItem && !$heading->isSubscribable() ) { |
| 90 | $heading = $heading->getParent(); |
| 91 | } |
| 92 | return $heading instanceof HeadingItem ? $heading : null; |
| 93 | } |
| 94 | } |