Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
MobilePage
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
7 / 7
18
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevision
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getLatestTimestamp
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getLatestEdit
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 getTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSmallThumbnailHtml
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageImageHtml
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
7
1<?php
2
3namespace MobileFrontend\Models;
4
5use MediaWiki\FileRepo\File\File;
6use MediaWiki\Html\Html;
7use MediaWiki\MediaWikiServices;
8use MediaWiki\Revision\RevisionRecord;
9use MediaWiki\Title\Title;
10
11/**
12 * Retrieves information specific to a mobile page
13 * Currently this only provides helper functions for creating Page Thumbnail
14 * @todo FIXME: Rename this class when its purpose becomes clearer
15 */
16class MobilePage {
17    public const SMALL_IMAGE_WIDTH = 220;
18    public const TINY_IMAGE_WIDTH = 120;
19
20    /**
21     * @var RevisionRecord|bool|null
22     */
23    private $rev = false;
24    /**
25     * @var string|bool
26     */
27    private $revisionTimestamp;
28    /**
29     * @var File|false Associated page image file (see PageImages extension)
30     */
31    private $file;
32
33    /**
34     * @param Title $title Page title
35     * @param File|false $file Page image file
36     */
37    public function __construct(
38        private readonly Title $title,
39        $file = false,
40    ) {
41        $this->file = $file;
42    }
43
44    /**
45     * @return RevisionRecord|null
46     */
47    private function getRevision() {
48        if ( $this->rev === false ) {
49            $this->rev = MediaWikiServices::getInstance()->getRevisionStore()
50                ->getRevisionByTitle( $this->title );
51        }
52        return $this->rev;
53    }
54
55    /**
56     * Retrieve timestamp when the page content was last modified. Does not reflect null edits.
57     * @return string|bool Timestamp (MW format) or false
58     */
59    public function getLatestTimestamp() {
60        if ( $this->revisionTimestamp === null ) {
61            $rev = $this->getRevision();
62            $this->revisionTimestamp = $rev ? $rev->getTimestamp() : false;
63        }
64        return $this->revisionTimestamp;
65    }
66
67    /**
68     * Retrieve the last edit to this page.
69     * @return array defining edit with keys:
70     * - string name
71     * - string timestamp (Unix format)
72     * - string gender
73     */
74    public function getLatestEdit() {
75        $rev = $this->getRevision();
76        $edit = [
77            'timestamp' => false,
78            'name' => '',
79            'gender' => '',
80        ];
81        if ( $rev ) {
82            $edit['timestamp'] = wfTimestamp( TS_UNIX, $rev->getTimestamp() );
83            $userIdentity = $rev->getUser();
84            if ( $userIdentity ) {
85                $userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
86                $edit['name'] = $userIdentity->getName();
87                $edit['gender'] = $userOptionsLookup->getOption( $userIdentity, 'gender' );
88            }
89        }
90        return $edit;
91    }
92
93    /**
94     * Get the title of the page
95     *
96     * @return Title
97     */
98    public function getTitle() {
99        return $this->title;
100    }
101
102    /**
103     * Get a small sized thumbnail in div container.
104     *
105     * @param bool $useBackgroundImage Whether the thumbnail should have a background image
106     * @return string
107     */
108    public function getSmallThumbnailHtml( $useBackgroundImage = false ) {
109        return $this->getPageImageHtml( self::SMALL_IMAGE_WIDTH, $useBackgroundImage );
110    }
111
112    /**
113     * Get the thumbnail container for getMediumThumbnailHtml() and getSmallThumbnailHtml().
114     *
115     * @param int $size the width of the thumbnail
116     * @param bool $useBackgroundImage Whether the thumbnail should have a background image
117     * @return string
118     */
119    private function getPageImageHtml( $size, $useBackgroundImage = false ) {
120        if ( !$this->file ) {
121            return '';
122        }
123        // FIXME: Use more generic classes - no longer restricted to lists
124        $thumb = $this->file->transform( [ 'width' => $size ] );
125        if ( $thumb && $thumb->getUrl() ) {
126            $className = 'list-thumb ';
127            $className .= $thumb->getWidth() > $thumb->getHeight()
128                ? 'list-thumb-y'
129                : 'list-thumb-x';
130            $props = [
131                'class' => $className,
132            ];
133
134            $urlUtils = MediaWikiServices::getInstance()->getUrlUtils();
135            $imgUrl = $urlUtils->expand( (string)$thumb->getUrl(), PROTO_CURRENT ) ?? '';
136            if ( $useBackgroundImage ) {
137                $props['style'] = 'background-image: url("' . $urlUtils->expand( $imgUrl, PROTO_CURRENT ) . '")';
138                $text = '';
139            } else {
140                $props['src'] = $imgUrl;
141                $text = $this->title->getText();
142            }
143            return Html::element( $useBackgroundImage ? 'div' : 'img', $props, $text );
144        }
145        return '';
146    }
147}