Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
StoryViewAction
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 4
30
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
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onView
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
6
 addLinkPreviewTags
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\Wikistories;
4
5use MediaWiki\Actions\FormlessAction;
6use MediaWiki\Context\IContextSource;
7use MediaWiki\Html\Html;
8use MediaWiki\Page\Article;
9use MediaWiki\Utils\UrlUtils;
10
11class StoryViewAction extends FormlessAction {
12
13    public function __construct(
14        Article $article,
15        IContextSource $context,
16        private readonly StoriesCache $storiesCache,
17        private readonly UrlUtils $urlUtils,
18    ) {
19        parent::__construct( $article, $context );
20    }
21
22    public function getName(): string {
23        return 'storyview';
24    }
25
26    /**
27     * @inheritDoc
28     */
29    public function onView(): string {
30        $out = $this->getOutput();
31        $out->setArticleBodyOnly( true );
32        $out->setPageTitle( $this->getTitle()->getText() );
33        $out->addMeta( 'viewport', 'width=device-width, initial-scale=1' );
34        $bodyHtml = '';
35
36        $storyExists = $this->getWikiPage()->getId() > 0;
37        if ( $storyExists ) {
38            $storyData = $this->storiesCache->getStory( $this->getArticle()->getPage()->getId() );
39            $this->addLinkPreviewTags( $storyData );
40            $out->addJsConfigVars( [ 'wgWikistoriesStoryContent' => $storyData ] );
41            $out->addModules( [ 'ext.wikistories.viewaction' ] );
42        } else {
43            $out->addModuleStyles( [ 'ext.wikistories.viewaction.styles' ] );
44            $bodyHtml = Html::rawElement(
45                'div',
46                [ 'class' => 'ext-wikistories-storyviewaction-notfound' ],
47                Html::element(
48                    'div',
49                    [ 'class' => 'ext-wikistories-storyviewaction-notfound-icon' ]
50                ) .
51                Html::element(
52                    'div',
53                    [ 'class' => 'ext-wikistories-storyviewaction-notfound-message' ],
54                    $this->msg( 'ext-wikistories-storyviewaction-notfound-message' )->text()
55                )
56            );
57        }
58
59        return $out->headElement( $out->getSkin() ) .
60            $bodyHtml .
61            $out->getBottomScripts() .
62            '</body></html>';
63    }
64
65    /**
66     * @param array $storyData
67     */
68    private function addLinkPreviewTags( array $storyData ): void {
69        $out = $this->getOutput();
70        // Open graph: https://ogp.me/
71        $out->addMeta( 'og:title', $storyData[ 'storyTitle' ] );
72        $out->addMeta( 'og:url', $storyData[ 'shareUrl' ] );
73        $out->addMeta( 'og:description', $storyData[ 'frames' ][ 0 ][ 'text' ] );
74        $out->addMeta( 'og:image', $storyData[ 'frames' ][ 0 ][ 'url' ] );
75
76        // Twitter: https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup
77        $out->addMeta( 'twitter:card', 'summary_large_image' );
78        $out->addMeta( 'twitter:domain', $this->urlUtils->getServer( PROTO_HTTPS ) ?? '' );
79        $out->addMeta( 'twitter:url', $storyData[ 'shareUrl' ] );
80        $out->addMeta( 'twitter:title', $storyData[ 'storyTitle' ] );
81        $out->addMeta( 'twitter:description', $storyData[ 'frames' ][ 0 ][ 'text' ] );
82        $out->addMeta( 'twitter:image', $storyData[ 'frames' ][ 0 ][ 'url' ] );
83    }
84
85}