Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
17.39% covered (danger)
17.39%
12 / 69
27.27% covered (danger)
27.27%
3 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
StoryContent
17.39% covered (danger)
17.39%
12 / 69
27.27% covered (danger)
27.27%
3 / 11
407.09
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFrames
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getFromArticle
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 getArticleId
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getArticleTitle
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
72
 getCategories
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getWikitextForTransclusion
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 getTextForDiff
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getTextForSummary
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 isLatestVersion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSchemaVersion
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\Wikistories;
4
5use MediaWiki\Content\JsonContent;
6use MediaWiki\Html\Html;
7use MediaWiki\MediaWikiServices;
8use MediaWiki\Page\PageIdentityValue;
9use MediaWiki\Title\Title;
10use Wikimedia\Rdbms\IDBAccessObject;
11
12class StoryContent extends JsonContent {
13
14    public const SCHEMA_VERSION = 1;
15
16    public function __construct( string $text ) {
17        parent::__construct( $text, 'story' );
18    }
19
20    public function getFrames(): array {
21        $story = $this->getData()->getValue();
22        return $story->frames ?? [];
23    }
24
25    /**
26     * @return string The title of the article this story was created from
27     */
28    public function getFromArticle(): string {
29        $story = $this->getData()->getValue();
30
31        if ( isset( $story->articleId ) ) {
32            $title = Title::newFromId( $story->articleId );
33            if ( $title ) {
34                return $title->getDBkey();
35            }
36        }
37
38        return $story->fromArticle ?? '';
39    }
40
41    /**
42     * @return int The page id of the article this story was created from
43     */
44    public function getArticleId(): int {
45        $story = $this->getData()->getValue();
46
47        if ( !isset( $story->articleId ) && isset( $story->fromArticle ) ) {
48            $articleTitle = Title::newFromText( $story->fromArticle );
49            return $articleTitle->getArticleID( IDBAccessObject::READ_LATEST );
50        }
51
52        return $story->articleId ?? -1;
53    }
54
55    public function getArticleTitle(): ?Title {
56        $services = MediaWikiServices::getInstance();
57        $pageLookup = $services->getPageStore();
58        $story = $this->getData()->getValue();
59
60        if ( isset( $story->articleId ) && $story->articleId > 0 ) {
61            $pageRecord = $pageLookup->getPageById( $story->articleId );
62        } elseif ( isset( $story->fromArticle ) && $story->fromArticle !== '' ) {
63            $pageRecord = $pageLookup->getExistingPageByText( $story->fromArticle );
64        } else {
65            return null;
66        }
67        if ( $pageRecord === null ) {
68            return null;
69        }
70        if ( $pageRecord->isRedirect() ) {
71            $identity = PageIdentityValue::localIdentity(
72                $pageRecord->getId(), $pageRecord->getNamespace(), $pageRecord->getDBkey()
73            );
74            $linkTarget = $services->getRedirectLookup()->getRedirectTarget( $identity );
75            if ( $linkTarget !== null ) {
76                return Title::newFromLinkTarget( $linkTarget );
77            }
78        } else {
79            return Title::newFromPageIdentity( $pageRecord );
80        }
81    }
82
83    /**
84     * @return string[]
85     */
86    public function getCategories(): array {
87        $story = $this->getData()->getValue();
88        return $story->categories ?? [];
89    }
90
91    /**
92     * Return a single image or a gallery in wikitext
93     *
94     * @return bool|string
95     */
96    public function getWikitextForTransclusion() {
97        if ( !$this->isValid() ) {
98            return false;
99        }
100
101        $length = count( $this->getFrames() );
102        if ( $length === 1 ) {
103            // Single image
104            $img = $this->getFrames()[0]->img;
105            $path = parse_url( $img, PHP_URL_PATH );
106            $pathFragments = explode( '/', $path );
107            $file = end( $pathFragments );
108            $text = $this->getFrames()[0]->text;
109            return "[[Image:$file|$text]]";
110        } elseif ( $length > 1 ) {
111            // Gallery
112            return Html::element(
113                'gallery',
114                [],
115                implode( "\n", array_map( static function ( $frame ) {
116                    $path = parse_url( $frame->img, PHP_URL_PATH );
117                    $pathFragments = explode( '/', $path );
118                    $file = end( $pathFragments );
119                    return $file . '|' . $frame->text;
120                }, $this->getFrames() ) )
121            );
122        }
123    }
124
125    /**
126     * @return string A simple version of the story frames and categories as text for diff
127     */
128    public function getTextForDiff(): string {
129        // story frames
130        $text = implode( "\n\n", array_map( static function ( $frame ) {
131            return $frame->image->filename . "\n" . $frame->text->value;
132        }, $this->getFrames() ) );
133
134        // categories
135        $categories = $this->getCategories();
136        if ( $categories ) {
137            $text .= "\n\n" . implode( "\n", $categories );
138        }
139
140        return $text;
141    }
142
143    /**
144     * @inheritDoc
145     */
146    public function getTextForSummary( $maxlength = 250 ) {
147        $framesText = implode( "\n", array_map( static function ( $frame ) {
148            return $frame->text->value;
149        }, $this->getFrames() ) );
150        return mb_substr( $framesText, 0, $maxlength );
151    }
152
153    /**
154     * @return bool This story is using the latest schema version
155     */
156    public function isLatestVersion(): bool {
157        return $this->getSchemaVersion() === self::SCHEMA_VERSION;
158    }
159
160    /**
161     * @return int Schema version used by this story
162     */
163    public function getSchemaVersion(): int {
164        $content = $this->getData()->getValue();
165        return $content->schemaVersion ?? 0;
166    }
167}