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