2019-08-15 17:40:13 +00:00
|
|
|
<?php
|
2020-06-17 02:56:19 +00:00
|
|
|
/**
|
|
|
|
* Citizen - A responsive skin developed for the Star Citizen Wiki
|
|
|
|
*
|
|
|
|
* This file is part of Citizen.
|
|
|
|
*
|
|
|
|
* Citizen is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Citizen is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Citizen. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
*/
|
2019-08-15 17:40:13 +00:00
|
|
|
|
2022-05-26 20:54:52 +00:00
|
|
|
namespace MediaWiki\Skins\Citizen\Api;
|
2019-12-25 23:12:14 +00:00
|
|
|
|
|
|
|
use ApiBase;
|
2024-11-13 03:03:45 +00:00
|
|
|
use ApiMain;
|
2024-11-13 03:38:18 +00:00
|
|
|
use Exception;
|
2024-05-07 20:21:01 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2020-07-05 12:36:31 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2023-08-25 00:56:42 +00:00
|
|
|
use MediaWiki\Title\Title;
|
2023-08-25 00:57:30 +00:00
|
|
|
use SpecialPage;
|
2019-12-25 23:12:14 +00:00
|
|
|
|
2019-08-15 17:40:13 +00:00
|
|
|
/**
|
2022-10-22 21:05:19 +00:00
|
|
|
* Based on the MobileFrontend extension
|
2019-08-15 17:40:13 +00:00
|
|
|
* Return the webapp manifest for this wiki
|
2023-01-17 19:43:57 +00:00
|
|
|
*
|
2023-01-17 19:42:49 +00:00
|
|
|
* T282500
|
|
|
|
* TODO: This should be merged to core
|
2019-08-15 17:40:13 +00:00
|
|
|
*/
|
|
|
|
class ApiWebappManifest extends ApiBase {
|
2024-11-04 23:26:04 +00:00
|
|
|
/* 1 week */
|
|
|
|
private const CACHE_MAX_AGE = 604800;
|
|
|
|
|
2024-11-13 03:03:45 +00:00
|
|
|
/** @var ApiMain */
|
|
|
|
private $main;
|
|
|
|
|
|
|
|
/** @var Config */
|
|
|
|
private $config;
|
|
|
|
|
|
|
|
/** @var MediaWikiServices */
|
|
|
|
private $services;
|
|
|
|
|
2024-11-13 23:17:17 +00:00
|
|
|
/** @var array */
|
|
|
|
private $options;
|
|
|
|
|
2024-11-13 03:03:45 +00:00
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public function __construct(
|
|
|
|
ApiMain $main,
|
|
|
|
$moduleName
|
|
|
|
) {
|
|
|
|
parent::__construct( $main, $moduleName );
|
|
|
|
$this->main = $main;
|
|
|
|
$this->config = $this->getConfig();
|
|
|
|
$this->services = MediaWikiServices::getInstance();
|
2024-11-13 23:17:17 +00:00
|
|
|
$this->options = $this->config->get( 'CitizenManifestOptions' );
|
2024-11-13 03:03:45 +00:00
|
|
|
}
|
|
|
|
|
2019-08-15 17:40:13 +00:00
|
|
|
/**
|
|
|
|
* Execute the requested Api actions.
|
|
|
|
*/
|
2024-11-04 23:26:04 +00:00
|
|
|
public function execute(): void {
|
2024-11-13 03:03:45 +00:00
|
|
|
$config = $this->config;
|
|
|
|
$services = $this->services;
|
2020-08-09 18:41:01 +00:00
|
|
|
$resultObj = $this->getResult();
|
2024-11-13 03:03:45 +00:00
|
|
|
$main = $this->main;
|
2024-11-13 23:17:17 +00:00
|
|
|
$options = $this->options;
|
2024-11-13 03:03:45 +00:00
|
|
|
|
2020-08-09 18:41:01 +00:00
|
|
|
$resultObj->addValue( null, 'dir', $services->getContentLanguage()->getDir() );
|
2024-05-07 20:21:01 +00:00
|
|
|
$resultObj->addValue( null, 'lang', $config->get( MainConfigNames::LanguageCode ) );
|
|
|
|
$resultObj->addValue( null, 'name', $config->get( MainConfigNames::Sitename ) );
|
2022-10-22 20:49:56 +00:00
|
|
|
// Need to set it manually because the default from start_url does not include script namespace
|
|
|
|
// E.g. index.php URLs will be thrown out of the PWA
|
2024-05-07 20:21:01 +00:00
|
|
|
$resultObj->addValue( null, 'scope', $config->get( MainConfigNames::Server ) . '/' );
|
2024-11-13 23:17:17 +00:00
|
|
|
$resultObj->addValue( null, 'icons', $this->getIcons() );
|
2022-10-23 18:00:51 +00:00
|
|
|
$resultObj->addValue( null, 'display', 'standalone' );
|
2024-07-06 22:10:26 +00:00
|
|
|
$resultObj->addValue( null, 'orientation', 'natural' );
|
2022-10-22 21:05:19 +00:00
|
|
|
$resultObj->addValue( null, 'start_url', Title::newMainPage()->getLocalURL() );
|
2024-11-13 23:17:17 +00:00
|
|
|
$resultObj->addValue( null, 'theme_color', $options['theme_color'] );
|
|
|
|
$resultObj->addValue( null, 'background_color', $options['background_color'] );
|
2022-10-22 21:36:58 +00:00
|
|
|
$resultObj->addValue( null, 'shortcuts', $this->getShortcuts() );
|
2024-11-13 02:14:34 +00:00
|
|
|
|
2024-11-13 23:20:54 +00:00
|
|
|
if ( $options['short_name'] !== '' ) {
|
|
|
|
$resultObj->addValue( null, 'short_name', $options['short_name'] );
|
|
|
|
}
|
|
|
|
|
2024-11-13 23:23:40 +00:00
|
|
|
if ( $options['description'] !== '' ) {
|
|
|
|
$resultObj->addValue( null, 'description', $options['description'] );
|
|
|
|
}
|
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
$main->setCacheMaxAge( self::CACHE_MAX_AGE );
|
|
|
|
$main->setCacheMode( 'public' );
|
2022-10-22 21:05:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get icons for manifest
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2024-11-13 23:17:17 +00:00
|
|
|
private function getIcons(): array {
|
|
|
|
$iconsConfig = $this->options['icons'];
|
2024-11-13 03:03:45 +00:00
|
|
|
if ( !$iconsConfig || $iconsConfig === [] ) {
|
2024-11-13 23:17:17 +00:00
|
|
|
return $this->getIconsFromLogos();
|
2024-11-13 03:03:45 +00:00
|
|
|
}
|
2019-08-15 17:40:13 +00:00
|
|
|
$icons = [];
|
2024-11-13 03:03:45 +00:00
|
|
|
$allowedKeys = [ 'src', 'sizes', 'type', 'purpose' ];
|
|
|
|
foreach ( $iconsConfig as $iconConfig ) {
|
|
|
|
$icon = array_intersect_key( $iconConfig, array_flip( $allowedKeys ) );
|
|
|
|
if ( !is_array( $icon ) || empty( $icon ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
array_push( $icons, $icon );
|
|
|
|
}
|
|
|
|
return $icons;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get icons from wgLogos
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private function getIconsFromLogos(): array {
|
|
|
|
$services = $this->services;
|
|
|
|
|
|
|
|
$icons = [];
|
|
|
|
$logos = $this->config->get( MainConfigNames::Logos );
|
2022-10-23 17:38:49 +00:00
|
|
|
|
2024-11-04 23:26:04 +00:00
|
|
|
if ( !$logos ) {
|
|
|
|
return $icons;
|
|
|
|
}
|
|
|
|
|
|
|
|
$logoKeys = [
|
|
|
|
'1x',
|
|
|
|
'1.5x',
|
|
|
|
'2x',
|
|
|
|
'icon',
|
|
|
|
'svg'
|
|
|
|
];
|
|
|
|
|
|
|
|
foreach ( $logoKeys as $logoKey ) {
|
|
|
|
// Avoid undefined index
|
|
|
|
if ( !isset( $logos[$logoKey] ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$logoPath = (string)$logos[$logoKey];
|
|
|
|
|
2024-11-13 03:03:45 +00:00
|
|
|
try {
|
|
|
|
$logoUrl = $services->getUrlUtils()->expand( $logoPath, PROTO_CURRENT ) ?? '';
|
|
|
|
$request = $services->getHttpRequestFactory()->create( $logoUrl, [], __METHOD__ );
|
|
|
|
$request->execute();
|
|
|
|
$logoContent = $request->getContent();
|
|
|
|
} catch ( Exception $e ) {
|
|
|
|
// Log the exception or handle it accordingly
|
|
|
|
$logoContent = '';
|
|
|
|
}
|
2022-10-23 17:38:05 +00:00
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
if ( !empty( $logoContent ) ) {
|
|
|
|
$logoSize = getimagesizefromstring( $logoContent );
|
2019-08-15 17:40:13 +00:00
|
|
|
}
|
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
$icon = [
|
|
|
|
'src' => $logoPath
|
2024-11-04 23:26:04 +00:00
|
|
|
];
|
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
if ( isset( $logoSize ) && $logoSize !== false ) {
|
|
|
|
$icon['sizes'] = $logoSize[0] . 'x' . $logoSize[1];
|
|
|
|
$icon['type'] = $logoSize['mime'];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set sizes to any if it is a SVG
|
|
|
|
if ( substr( $logoPath, -3 ) === 'svg' ) {
|
|
|
|
$icon['sizes'] = 'any';
|
|
|
|
$icon['type'] = 'image/svg+xml';
|
|
|
|
}
|
|
|
|
|
2024-11-13 22:59:13 +00:00
|
|
|
// Exit if not sizes are detected
|
|
|
|
if ( !$icon['sizes'] ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
$icons[] = $icon;
|
2024-11-04 23:26:04 +00:00
|
|
|
}
|
|
|
|
|
2024-11-13 02:14:34 +00:00
|
|
|
return $icons;
|
2024-11-04 23:26:04 +00:00
|
|
|
}
|
|
|
|
|
2022-10-22 21:36:58 +00:00
|
|
|
/**
|
|
|
|
* Get shortcuts for manifest
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2024-11-04 23:26:04 +00:00
|
|
|
private function getShortcuts(): array {
|
2022-10-22 21:36:58 +00:00
|
|
|
$specialPages = [ 'Search', 'Randompage', 'RecentChanges' ];
|
|
|
|
|
2024-11-04 23:26:40 +00:00
|
|
|
return array_map( static function ( $specialPage ) {
|
2022-10-22 21:36:58 +00:00
|
|
|
$title = SpecialPage::getSafeTitleFor( $specialPage );
|
2024-11-04 23:26:04 +00:00
|
|
|
return [
|
|
|
|
'name' => $title->getBaseText(),
|
|
|
|
'url' => $title->getLocalURL()
|
|
|
|
];
|
|
|
|
}, $specialPages );
|
2022-10-22 21:36:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-15 17:40:13 +00:00
|
|
|
/**
|
|
|
|
* Get the JSON printer
|
|
|
|
*
|
2023-01-18 03:47:37 +00:00
|
|
|
* @return ApiWebappManifestFormatJson
|
2019-08-15 17:40:13 +00:00
|
|
|
*/
|
|
|
|
public function getCustomPrinter() {
|
2024-11-13 03:03:45 +00:00
|
|
|
return new ApiWebappManifestFormatJson( $this->main, 'webmanifest' );
|
2019-08-15 17:40:13 +00:00
|
|
|
}
|
|
|
|
}
|