[Scummvm-git-logs] scummvm-web master -> d76478f1e6f1f22e69bed53d0c57b67208e18938
lephilousophe
noreply at scummvm.org
Sun Aug 24 10:33:34 UTC 2025
This automated email contains information about 23 new commits which have been
pushed to the 'scummvm-web' repo located at https://api.github.com/repos/scummvm/scummvm-web .
Summary:
8c2e6ab345 WEB: Remove obsolete file
1c9380ef3e JANITORIAL: Fix code style
649ade2977 WEB: Make index a void function
261cca2dc3 WEB: Cleanup logic of exception handler
c743cc2187 WEB: Properly initialize the files array
d8ff9c3c75 WEB: Remove useless check
3d37c952a8 WEB: Use null instead of false when no data is available
d7c3bd0528 WEB: Various small fixes
51ce727edd WEB: Simplify subsections construction
cc9fa80181 WEB: Add typing
d2e028140b BUILD: Check codestyle after fixing trivial errors
271f169928 BUILD: Increase PHPStan level
710b95a5f4 WEB: Better error handling
7b0a2033de WEB: Gracefully handle cases when there are no extension in files
a1afb8a64d WEB: Handle cases when WebLink are mixed with Files
e2f72c8d8b WEB: Modify all extra attributes at once
d74cb92ec2 WEB: Make sure the Page object provides an index function
9a59454525 BUILD: Increase PHPStan level
93d3aa56a1 WEB: Handle null cases
f28c5198f4 WEB: Avoid returning null when there is no screenshot
a04dab5f7e BUILD: Increase PHPStan level
7f6baf107a BUILD: Add license in composer
d76478f1e6 WEB: Add a Github Actions CI check
Commit: 8c2e6ab3456d49d9128e3fd58443381db279ff52
https://github.com/scummvm/scummvm-web/commit/8c2e6ab3456d49d9128e3fd58443381db279ff52
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Remove obsolete file
Changed paths:
R include/Objects/DataObject.php
diff --git a/include/Objects/DataObject.php b/include/Objects/DataObject.php
deleted file mode 100644
index f9b1cdf1..00000000
--- a/include/Objects/DataObject.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-namespace ScummVM\Objects;
-
-/**
- * The DataObject class is inherited by all other new data objects
- * and houses all common functions.
- */
-abstract class DataObject
-{
- protected $id;
- const NO_ID = 'Data object %s is missing an ID field';
- const BAD_KEY = 'Field %s is required and cannot be empty for %s';
- const NO_KEY = "Key is required and can not be blank";
-
- public function __construct($data)
- {
- try {
- $this->id = $this->assignFromArray('id', $data);
- } catch (\ErrorException $ex) {
- throw new \ErrorException(\sprintf(self::NO_ID, \get_class($this)));
- }
- }
-
- /* Get the ID. */
- public function getId()
- {
- return $this->id;
- }
-
- public function __toString()
- {
- return $this->id;
- }
-
- /**
- * Helper method to safely retrieve an object
- * from an array.
- */
- protected function assignFromArray($key, $array, $required = false)
- {
- if ($required) {
- if ($key === '') {
- throw new \ErrorException(self::NO_KEY);
- }
-
- if (!isset($array[$key]) || $array[$key] === '') {
- throw new \ErrorException(\sprintf(self::BAD_KEY, $key, \get_class($this)));
- }
- }
- return $array[$key];
- }
-}
Commit: 1c9380ef3ebf852f959f0ac2d00416727c2773de
https://github.com/scummvm/scummvm-web/commit/1c9380ef3ebf852f959f0ac2d00416727c2773de
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
JANITORIAL: Fix code style
This should not have any behavioral changes
Changed paths:
include/Constants.php
include/DataUtils.php
include/LocalizationUtils.php
include/Models/DirectorDemosModel.php
include/Models/DownloadsModel.php
include/Models/NewsModel.php
include/Models/ScreenshotsModel.php
include/Objects/File.php
include/Objects/News.php
include/OrmObjects/Compatibility.php
include/OrmObjects/ScreenshotQuery.php
public_html/index.php
diff --git a/include/Constants.php b/include/Constants.php
index c145e70b..dd2ac078 100644
--- a/include/Constants.php
+++ b/include/Constants.php
@@ -1,4 +1,4 @@
-<?php
+<?php // phpcs:ignore PSR1.Files.SideEffects.FoundWithSymbols
namespace ScummVM;
class Constants
diff --git a/include/DataUtils.php b/include/DataUtils.php
index 3b5128a1..27be50b0 100644
--- a/include/DataUtils.php
+++ b/include/DataUtils.php
@@ -1,4 +1,4 @@
-<?php
+<?php // phpcs:ignore PSR1.Files.SideEffects.FoundWithSymbols -- Script directly executed
namespace ScummVM;
require_once __DIR__ . '/../vendor/autoload.php';
@@ -21,6 +21,7 @@ use Propel\Runtime\Map\TableMap;
*/
class DataUtils
{
+ // phpcs:ignore Generic.Files.LineLength
const SHEET_URL = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vQamumX0p-DYQa5Umi3RxX-pHM6RZhAj1qvUP0jTmaqutN9FwzyriRSXlO9rq6kR60pGIuPvCDzZL3s/pub?output=tsv';
// filename => sheet id
const SHEET_IDS = [
diff --git a/include/LocalizationUtils.php b/include/LocalizationUtils.php
index b668d5f1..3c23863d 100644
--- a/include/LocalizationUtils.php
+++ b/include/LocalizationUtils.php
@@ -1,4 +1,4 @@
-<?php
+<?php // phpcs:ignore PSR1.Files.SideEffects.FoundWithSymbols -- Script directly executed
namespace ScummVM;
require_once __DIR__ . '/../vendor/autoload.php';
@@ -58,7 +58,9 @@ class LocalizationUtils
$l10n = json_decode(file_get_contents($newsFile));
foreach ($l10n as $key => $translatedArticle) {
- $englishArticle = YamlFrontMatter::parse(file_get_contents(join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news', "{$key}.markdown"])));
+ $englishArticle = YamlFrontMatter::parse(file_get_contents(
+ join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news', "{$key}.markdown"])
+ ));
$date = self::$purifier->purify($englishArticle->date);
$author = self::$purifier->purify($englishArticle->author);
@@ -103,7 +105,11 @@ class LocalizationUtils
file_put_contents(
$newsFile,
- \str_replace('\r\n', '\n', json_encode($news, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n")
+ \str_replace(
+ '\r\n',
+ '\n',
+ json_encode($news, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n"
+ )
);
}
}
diff --git a/include/Models/DirectorDemosModel.php b/include/Models/DirectorDemosModel.php
index 735eeb38..f967b727 100644
--- a/include/Models/DirectorDemosModel.php
+++ b/include/Models/DirectorDemosModel.php
@@ -16,7 +16,7 @@ class DirectorDemosModel extends BasicModel
$demos = DirectorDemoQuery::create()
->orderByVersion()
->orderByTitle()
- ->find();
+ ->find();
$groupedData = $this->createGroups($demos);
$this->saveToCache($groupedData);
}
diff --git a/include/Models/DownloadsModel.php b/include/Models/DownloadsModel.php
index 2d73aa0f..6df855af 100644
--- a/include/Models/DownloadsModel.php
+++ b/include/Models/DownloadsModel.php
@@ -18,7 +18,7 @@ class DownloadsModel extends BasicModel
$sections = $this->getFromCache();
if (is_null($sections)) {
$parsedData = DownloadQuery::create()
- ->findByEnabled(true);
+ ->findByEnabled(true);
$sections = [];
$sectionsData = $this->getSectionData();
foreach ($parsedData as $data) {
@@ -75,13 +75,21 @@ class DownloadsModel extends BasicModel
{
return [
"current"=>["title"=>"{#downloadsXMLTitle#} {#downloadsXMLVersion#}"],
- "release"=>["title"=>"{#downloadsBinaries#}","notes"=>"{#downloadsBinariesNote1#} <a href='https://downloads.scummvm.org/frs/scummvm/{ldelim}release{rdelim}/ReleaseNotes.html'>{#downloadsBinariesNote2#}</a>.<p>{#downloadsBinariesNote3#}</p>"],
+ "release"=>["title"=>"{#downloadsBinaries#}",
+ "notes"=>"{#downloadsBinariesNote1#} <a href='https://downloads.scummvm.org/frs/scummvm/" .
+ "{ldelim}release{rdelim}/ReleaseNotes.html'>{#downloadsBinariesNote2#}</a>." .
+ "<p>{#downloadsBinariesNote3#}</p>"],
"source"=>["title"=>"{#downloadsSourceCode#}"],
"scummvm-tools"=>["title"=>"{#downloadsTools#}"],
"legacy"=>["title"=>"{#downloadsOldBinaries#}"],
- "old"=>["title"=>"{#downloadsOld#}","notes"=>"{#downloadsOldBinariesNote#} {#downloadsOldBinariesFrsNote1#} <a href='https://downloads.scummvm.org/frs/scummvm/'>{#downloadsOldBinariesFrsNote2#}</a> {#downloadsOldBinariesFrsNote3#}"],
+ "old"=>["title"=>"{#downloadsOld#}",
+ "notes"=>"{#downloadsOldBinariesNote#} {#downloadsOldBinariesFrsNote1#} " .
+ "<a href='https://downloads.scummvm.org/frs/scummvm/'>{#downloadsOldBinariesFrsNote2#}</a> " .
+ "{#downloadsOldBinariesFrsNote3#}"],
"daily"=>["title"=>"{#downloadsDailyBuilds#}"],
- "daily_downloads"=>["title"=>"{#downloadsDailyBuilds#}","notes"=>"<strong>{#downloadsDailyNote1#}</strong> {#downloadsDailyNote2#}<p>{#downloadsDailyNote3#}</p>"],
+ "daily_downloads"=>["title"=>"{#downloadsDailyBuilds#}",
+ "notes"=>"<strong>{#downloadsDailyNote1#}</strong> {#downloadsDailyNote2#}" .
+ "<p>{#downloadsDailyNote3#}</p>"],
"libs"=>["title"=>"{#downloadsLibraries#}"],
"required"=>["title"=>"{#downloadsRequiredLibraries#}"],
"optional"=>["title"=>"{#downloadsOptionalLibraries#}"]
diff --git a/include/Models/NewsModel.php b/include/Models/NewsModel.php
index 94e58114..945d2596 100644
--- a/include/Models/NewsModel.php
+++ b/include/Models/NewsModel.php
@@ -46,7 +46,10 @@ class NewsModel extends BasicModel
if (!is_file(($fname = join(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, 'news', basename($filename)])))
|| !is_readable($fname) || !($data = @file_get_contents($fname))
) {
- if (!($data = @file_get_contents(join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news', $filename])))) {
+ if (!($data = @file_get_contents(join(
+ DIRECTORY_SEPARATOR,
+ [DIR_DATA, DEFAULT_LOCALE, 'news', $filename]
+ )))) {
continue;
}
}
diff --git a/include/Models/ScreenshotsModel.php b/include/Models/ScreenshotsModel.php
index 3481367f..8696cd60 100644
--- a/include/Models/ScreenshotsModel.php
+++ b/include/Models/ScreenshotsModel.php
@@ -152,7 +152,8 @@ class ScreenshotsModel extends BasicModel
$count = 0;
// Iterate over each game and count the number of screenshot files
foreach ($games as $game) {
- $count += count(glob(DIR_STATIC . DIR_SCREENSHOTS . '/' . str_replace(':', '/', $game->getId()) . '/*_full.png'));
+ $count += count(glob(DIR_STATIC . DIR_SCREENSHOTS . '/' .
+ str_replace(':', '/', $game->getId()) . '/*_full.png'));
}
return $count;
}
diff --git a/include/Objects/File.php b/include/Objects/File.php
index 4eaf40e9..a9697846 100644
--- a/include/Objects/File.php
+++ b/include/Objects/File.php
@@ -14,7 +14,6 @@ class File extends BasicObject
private $url;
private $extra_info;
private $notes;
- //private $subcategory;
private $user_agent;
private $version;
@@ -25,7 +24,6 @@ class File extends BasicObject
$this->category = $data['category'];
$this->category_icon = $data['category_icon'];
$this->notes = isset($data['notes']) ? $data['notes'] : '';
- //$this->subcategory = $data['subcategory'] ?? null;
$this->user_agent = isset($data["user_agent"]) ? $data["user_agent"] : "";
$this->version = isset($data['version']) ? strtolower($data['version']) : null;
diff --git a/include/Objects/News.php b/include/Objects/News.php
index 31676542..ebbd230f 100644
--- a/include/Objects/News.php
+++ b/include/Objects/News.php
@@ -24,7 +24,8 @@ class News
$object = YamlFrontMatter::parse($data);
$Parsedown = new \Parsedown();
- $this->title = $processContent ? $this->processText($Parsedown->line($object->title)) : $Parsedown->line($object->title);
+ $this->title = $processContent ? $this->processText($Parsedown->line($object->title)) :
+ $Parsedown->line($object->title);
$this->date = $object->date;
$this->author = $object->author;
$body = $this->localizeLinks($object->body());
diff --git a/include/OrmObjects/Compatibility.php b/include/OrmObjects/Compatibility.php
index 585d4101..95b86457 100644
--- a/include/OrmObjects/Compatibility.php
+++ b/include/OrmObjects/Compatibility.php
@@ -68,7 +68,8 @@ class Compatibility extends BaseCompatibility
if (str_starts_with($dataFiles, "https://")) {
$wikiLink = "- [ScummVM Wiki]({$this->getGame()->getDataFiles()})";
} else {
- $wikiLink = "- [ScummVM Wiki](https://wiki.scummvm.org/index.php?title={$this->getGame()->getDataFiles()})";
+ $wikiLink = "- [ScummVM Wiki](https://wiki.scummvm.org/index.php?" .
+ "title={$this->getGame()->getDataFiles()})";
}
$links[] = $wikiLink . " (includes list of required data files)";
}
@@ -98,7 +99,8 @@ class Compatibility extends BaseCompatibility
}
$zoomId = $this->getGame()->getZoomId();
if ($zoomId) {
- $availableSites[] = "- [ZOOM Platform](" . ZOOM_URL_PREFIX . $zoomId . ZOOM_URL_SUFFIX . ") (affiliate link)";
+ $availableSites[] = "- [ZOOM Platform](" . ZOOM_URL_PREFIX . $zoomId .
+ ZOOM_URL_SUFFIX . ") (affiliate link)";
}
// Additional stores could include the ScummVM Freeware Games page
$additionalStores = $this->getGame()->getAdditionalStores();
@@ -107,7 +109,8 @@ class Compatibility extends BaseCompatibility
}
if ($availableSites) {
$notes .= "\n\n### Available At\n";
- $notes .= "The ScummVM project does not endorse any individual supplier of games. This list is for reference purposes only.\n";
+ $notes .= "The ScummVM project does not endorse any individual supplier of games. " .
+ "This list is for reference purposes only.\n";
$notes .= join("\n", $availableSites);
}
diff --git a/include/OrmObjects/ScreenshotQuery.php b/include/OrmObjects/ScreenshotQuery.php
index f62fbb9a..a28b305f 100644
--- a/include/OrmObjects/ScreenshotQuery.php
+++ b/include/OrmObjects/ScreenshotQuery.php
@@ -27,7 +27,8 @@ class ScreenshotQuery extends BaseScreenshotQuery
$con = Propel::getServiceContainer()->getReadConnection(ScreenshotTableMap::DATABASE_NAME);
}
- $sql = 'SELECT id, variant, platform_id, language, variant_id, auto_id FROM screenshot ORDER BY RANDOM() LIMIT 1';
+ $sql = "SELECT id, variant, platform_id, language, variant_id, auto_id
+ FROM screenshot ORDER BY RANDOM() LIMIT 1";
try {
$stmt = $con->prepare($sql);
$stmt->execute();
diff --git a/public_html/index.php b/public_html/index.php
index a8d8ec29..46931353 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -1,4 +1,4 @@
-<?php
+<?php // phpcs:ignore PSR1.Files.SideEffects.FoundWithSymbols -- Script directly executed
namespace ScummVM;
/**
@@ -10,12 +10,12 @@ namespace ScummVM;
* if the DEV_SERVER environment variable is set to 1
*/
if (isset($_SERVER['SERVER_SOFTWARE']) &&
- \preg_match("/PHP [\d\.]+ Development Server/",$_SERVER['SERVER_SOFTWARE'])) {
+ \preg_match("/PHP [\d\.]+ Development Server/", $_SERVER['SERVER_SOFTWARE'])) {
if (\is_file(__DIR__ . '/' . strtok($_SERVER["REQUEST_URI"], '?'))) {
return false;
}
define('DEV_SERVER', true);
-} else if (getenv('DEV_SERVER') === "1") {
+} elseif (getenv('DEV_SERVER') === "1") {
define('DEV_SERVER', true);
} else {
define('DEV_SERVER', false);
@@ -30,11 +30,11 @@ require_once __DIR__ . '/../include/SiteUtils.php';
* Multilingual support
*/
global $lang, $available_languages;
-$languages = array_slice(scandir(DIR_DATA),2);
+$languages = array_slice(scandir(DIR_DATA), 2);
$available_languages = [];
foreach ($languages as $l) {
if (!\is_dir(DIR_DATA . "/$l")) {
- continue;
+ continue;
}
$available_languages[$l] = \locale_get_display_name($l, $l);
}
@@ -53,30 +53,30 @@ $oldLangs = [
"ru_RU" => "ru"
];
if (!empty($_GET['lang'])) {
- $lang = $_GET['lang'];
- $uri = \preg_replace("/[?&]lang=$lang/i", "", $_SERVER['REQUEST_URI']);
- if (array_key_exists($lang, $available_languages)) {
- header("Location: " . "/$lang" . $uri);
- } elseif (array_key_exists($lang, $oldLangs)) {
- header("Location: /" . $oldLangs[$lang] . $uri);
- }
+ $lang = $_GET['lang'];
+ $uri = \preg_replace("/[?&]lang=$lang/i", "", $_SERVER['REQUEST_URI']);
+ if (array_key_exists($lang, $available_languages)) {
+ header("Location: " . "/$lang" . $uri);
+ } elseif (array_key_exists($lang, $oldLangs)) {
+ header("Location: /" . $oldLangs[$lang] . $uri);
+ }
} elseif (!empty($_COOKIE['lang'])) {
- $lang = $_COOKIE['lang'];
- $cookie_options = [
+ $lang = $_COOKIE['lang'];
+ $cookie_options = [
'expires' => time()-86400,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'secure' => true,
'samesite' => 'None'
- ];
- if (\strpos($_SERVER['REQUEST_URI'], "/$lang/") === false) {
- if (array_key_exists($lang, $available_languages)) {
- header("Location: " . "/$lang" . $_SERVER['REQUEST_URI']);
- } elseif (array_key_exists($lang, $oldLangs)) {
- header("Location: /" . $oldLangs[$lang] . $_SERVER['REQUEST_URI']);
+ ];
+ if (\strpos($_SERVER['REQUEST_URI'], "/$lang/") === false) {
+ if (array_key_exists($lang, $available_languages)) {
+ header("Location: " . "/$lang" . $_SERVER['REQUEST_URI']);
+ } elseif (array_key_exists($lang, $oldLangs)) {
+ header("Location: /" . $oldLangs[$lang] . $_SERVER['REQUEST_URI']);
+ }
}
- }
- setcookie("lang", "", $cookie_options);
+ setcookie("lang", "", $cookie_options);
}
$langs = join("|", array_keys($available_languages));
@@ -102,7 +102,7 @@ if (!is_writeable(SMARTY_DIR_COMPILE)) {
}
/* Exception handling. */
-set_exception_handler(array('ScummVM\ExceptionHandler', 'handleException'));
+set_exception_handler(array('\ScummVM\ExceptionHandler', 'handleException'));
/* Page mapping. */
$pages = array(
Commit: 649ade2977d853436721149c899bee57022d934c
https://github.com/scummvm/scummvm-web/commit/649ade2977d853436721149c899bee57022d934c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Make index a void function
It's used with Smarty::display which is void so there is never anything
to return and the return value was never checked.
Propagate this change everywhere.
Changed paths:
include/Controller.php
include/ExceptionHandler.php
include/Pages/ArticlePage.php
include/Pages/CompatibilityPage.php
include/Pages/DemosPage.php
include/Pages/DirectorDemosPage.php
include/Pages/DownloadsPage.php
include/Pages/FeedsPage.php
include/Pages/GamesPage.php
include/Pages/LinksPage.php
include/Pages/NewsPage.php
include/Pages/ScreenshotsPage.php
include/Pages/SimplePage.php
public_html/index.php
diff --git a/include/Controller.php b/include/Controller.php
index d513a5ce..fa1f8338 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -164,7 +164,7 @@ class Controller
'content' => $content,
);
$this->smarty->assign($vars);
- return $this->smarty->display('pages/index.tpl');
+ $this->smarty->display('pages/index.tpl');
}
/* Render the HTML using the template and any set variables and returns it. */
@@ -179,7 +179,7 @@ class Controller
/* Set up the variables used by the template and render the page. */
public function renderPage($vars)
{
- return $this->display($this->fetch($this->template, $vars));
+ $this->display($this->fetch($this->template, $vars));
}
/* Assign extra CSS files needed by the different pages/templates. */
diff --git a/include/ExceptionHandler.php b/include/ExceptionHandler.php
index fddcc21d..c0c7d18e 100644
--- a/include/ExceptionHandler.php
+++ b/include/ExceptionHandler.php
@@ -38,6 +38,6 @@ abstract class ExceptionHandler
self::$exception = $e;
$ep = new SimplePage('exception');
- return $ep->index($e);
+ $ep->index($e);
}
}
diff --git a/include/Pages/ArticlePage.php b/include/Pages/ArticlePage.php
index ba13672b..0803d739 100644
--- a/include/Pages/ArticlePage.php
+++ b/include/Pages/ArticlePage.php
@@ -55,7 +55,7 @@ class ArticlePage extends Controller
$author = $purifier->purify($article->author);
$content = $purifier->purify($Parsedown->text($article->body()));
- return $this->renderPage([
+ $this->renderPage([
'title' => $title,
'description' => htmlentities($this->getHeadline($content)),
'content_title' => $title,
diff --git a/include/Pages/CompatibilityPage.php b/include/Pages/CompatibilityPage.php
index 1bda80c7..79b146a5 100644
--- a/include/Pages/CompatibilityPage.php
+++ b/include/Pages/CompatibilityPage.php
@@ -68,9 +68,9 @@ class CompatibilityPage extends Controller
}
if (!empty($target)) {
- return $this->getGame($target, $version);
+ $this->getGame($target, $version);
} else {
- return $this->getAll($version, $versions);
+ $this->getAll($version, $versions);
}
}
@@ -87,7 +87,7 @@ class CompatibilityPage extends Controller
$this->template = 'components/compatibility_details.tpl';
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle')),
'subtitle' => $game->getGame()->getName(),
@@ -115,7 +115,7 @@ class CompatibilityPage extends Controller
$last_updated = $this->compatibilityModel->getLastUpdated();
$this->template = 'pages/compatibility.tpl';
- return $this->renderPage(
+ $this->renderPage(
[
'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle')),
'description' => $this->getConfigVars('compatibilityIntro'),
diff --git a/include/Pages/DemosPage.php b/include/Pages/DemosPage.php
index d80599a0..4899aa56 100644
--- a/include/Pages/DemosPage.php
+++ b/include/Pages/DemosPage.php
@@ -20,7 +20,7 @@ class DemosPage extends Controller
public function index()
{
$demos = $this->gameDemosModel->getAllGroupsAndDemos();
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('demosTitle'),
'description' => $this->getConfigVars('gamesDemosContentP1'),
diff --git a/include/Pages/DirectorDemosPage.php b/include/Pages/DirectorDemosPage.php
index 62bc08c3..016259a9 100644
--- a/include/Pages/DirectorDemosPage.php
+++ b/include/Pages/DirectorDemosPage.php
@@ -20,7 +20,7 @@ class DirectorDemosPage extends Controller
public function index()
{
$demos = $this->gameDemosModel->getAllGroupsAndDemos();
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('directorDemosTitle'),
'description' => $this->getConfigVars('gamesDemosContentP1'),
diff --git a/include/Pages/DownloadsPage.php b/include/Pages/DownloadsPage.php
index 33086f12..823b9f15 100644
--- a/include/Pages/DownloadsPage.php
+++ b/include/Pages/DownloadsPage.php
@@ -20,7 +20,7 @@ class DownloadsPage extends Controller
{
$downloads = $this->downloadsModel->getAllDownloads();
$recommendedDownload = $this->downloadsModel->getRecommendedDownload();
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('downloadsTitle'),
'description' => \strip_tags($this->getConfigVars('downloadsContentP1')),
diff --git a/include/Pages/FeedsPage.php b/include/Pages/FeedsPage.php
index a97215d4..20114a6f 100644
--- a/include/Pages/FeedsPage.php
+++ b/include/Pages/FeedsPage.php
@@ -38,6 +38,5 @@ class FeedsPage extends Controller
'news' => $news_items,
)
);
- return true;
}
}
diff --git a/include/Pages/GamesPage.php b/include/Pages/GamesPage.php
index cf4757e5..74c8dc9e 100644
--- a/include/Pages/GamesPage.php
+++ b/include/Pages/GamesPage.php
@@ -20,7 +20,7 @@ class GamesPage extends Controller
public function index()
{
$downloads = $this->gameDownloadsModel->getAllDownloads();
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('gamesTitle'),
'description' => strip_tags($this->getConfigVars('gamesContentP1')),
diff --git a/include/Pages/LinksPage.php b/include/Pages/LinksPage.php
index ef0d8f86..7765e6db 100644
--- a/include/Pages/LinksPage.php
+++ b/include/Pages/LinksPage.php
@@ -21,7 +21,7 @@ class LinksPage extends Controller
public function index()
{
$links = $this->linksModel->getAllGroupsAndLinks();
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('linksTitle'),
// TODO: add a description
diff --git a/include/Pages/NewsPage.php b/include/Pages/NewsPage.php
index 27100f09..d0f3e16b 100644
--- a/include/Pages/NewsPage.php
+++ b/include/Pages/NewsPage.php
@@ -24,13 +24,15 @@ class NewsPage extends Controller
{
$filename = $args['date'] ?? null;
- if ($filename != null) {
- if (strtolower($filename) == 'archive' || $filename == '') {
- $filename = null;
- }
- return $this->getNews($filename);
+ if ($filename === null) {
+ $this->getNewsIntro();
+ return;
}
- return $this->getNewsIntro();
+
+ if (strtolower($filename) == 'archive' || $filename == '') {
+ $filename = null;
+ }
+ $this->getNews($filename);
}
/* Display a specific news item, or all news items. */
@@ -46,7 +48,7 @@ class NewsPage extends Controller
$description = htmlentities($this->getHeadline($news_items[0]->getContent()));
}
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('newsTitle'),
'subtitle' => $subtitle,
@@ -71,7 +73,7 @@ class NewsPage extends Controller
)
);
- return $this->renderPage(
+ $this->renderPage(
array(
'title' => $this->getConfigVars('homeTitle'),
'description' => $this->getConfigVars('introHeaderContentP1'),
diff --git a/include/Pages/ScreenshotsPage.php b/include/Pages/ScreenshotsPage.php
index 8f6b7878..54c10754 100644
--- a/include/Pages/ScreenshotsPage.php
+++ b/include/Pages/ScreenshotsPage.php
@@ -28,7 +28,8 @@ class ScreenshotsPage extends Controller
);
if ($category) {
- return $this->getCategory($category, $game);
+ $this->getCategory($category, $game);
+ return;
}
$screenshot = $this->screenshotsModel->getAllCategories();
@@ -36,7 +37,7 @@ class ScreenshotsPage extends Controller
$this->template = 'pages/screenshots.tpl';
- return $this->renderPage(
+ $this->renderPage(
[
'title' => $this->getConfigVars('screenshotsTitle'),
// TODO: Add a description
@@ -62,7 +63,7 @@ class ScreenshotsPage extends Controller
}
$this->template = 'pages/screenshots_category.tpl';
- return $this->renderPage(
+ $this->renderPage(
[
'title' => $this->getConfigVars('screenshotsTitle'),
// TODO: Add a description
diff --git a/include/Pages/SimplePage.php b/include/Pages/SimplePage.php
index ab4797c2..9ab5f4d6 100644
--- a/include/Pages/SimplePage.php
+++ b/include/Pages/SimplePage.php
@@ -40,7 +40,7 @@ class SimplePage extends Controller
$data = $this->model->getAllData();
}
- return $this->renderPage([
+ $this->renderPage([
'title' => $this->getConfigVars("{$this->key}Title"),
'description' => $this->getConfigVars("{$this->key}Description"),
'content_title' => $this->getConfigVars("{$this->key}ContentTitle"),
diff --git a/public_html/index.php b/public_html/index.php
index 46931353..5099ad26 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -146,19 +146,18 @@ foreach ($pages as $key => $value) {
$match = $router->match(strtolower($_SERVER['REQUEST_URI']));
-if ($match) {
- if ($match['target'] === '\ScummVM\Pages\SimplePage' || $match['target'] === '\ScummVM\Pages\StaticPage') {
- $page = new $match['target']($match['name']);
- } else if (strpos($match['target'],"http") === 0) {
- header("Location: {$match['target']}");
- return;
- } else {
- $page = new $match['target']();
- }
- return $page->index($match['params']);
-} else {
- $page = new \ScummVM\Pages\NewsPage();
- return $page->index(array());
+if (!$match) {
+ $page = new \ScummVM\Pages\NewsPage();
+ $page->index(array());
+ return;
}
-
+if ($match['target'] === '\ScummVM\Pages\SimplePage' || $match['target'] === '\ScummVM\Pages\StaticPage') {
+ $page = new $match['target']($match['name']);
+} elseif (strpos($match['target'], "http") === 0) {
+ header("Location: {$match['target']}");
+ return;
+} else {
+ $page = new $match['target']();
+}
+$page->index($match['params']);
Commit: 261cca2dc3b83d669f3490af6ce0f47a4338b120
https://github.com/scummvm/scummvm-web/commit/261cca2dc3b83d669f3490af6ce0f47a4338b120
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Cleanup logic of exception handler
Also use isset to check if the Exception has been set.
Changed paths:
include/ExceptionHandler.php
diff --git a/include/ExceptionHandler.php b/include/ExceptionHandler.php
index c0c7d18e..523057be 100644
--- a/include/ExceptionHandler.php
+++ b/include/ExceptionHandler.php
@@ -13,23 +13,23 @@ abstract class ExceptionHandler
/* If the MenuModel cause the exception we need to skip them. */
public static function skipMenus()
{
- $skip_menus = false;
+ if (!isset(self::$exception)) {
+ return false;
+ }
+
$e = self::$exception;
- if (!is_null($e)) {
- if (basename($e->getFile()) == 'MenuModel.php') {
- $skip_menus = true;
- } else {
- foreach ($e->getTrace() as $t) {
- if (basename($t['file'] ?? '') == 'MenuModel.php') {
- $skip_menus = true;
- break;
- }
- }
+ if (basename($e->getFile()) == 'MenuModel.php') {
+ return true;
+ }
+
+ foreach ($e->getTrace() as $t) {
+ if (basename($t['file'] ?? '') == 'MenuModel.php') {
+ return true;
}
}
- return $skip_menus;
+ return false;
}
/* Handle exceptions. */
Commit: c743cc2187cad1e8ecf4026f034e7b8f527741c2
https://github.com/scummvm/scummvm-web/commit/c743cc2187cad1e8ecf4026f034e7b8f527741c2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Properly initialize the files array
Creating an array using the [] operator is allowed but not recommended.
Also check if it exists using isset.
Changed paths:
include/OrmObjects/Screenshot.php
diff --git a/include/OrmObjects/Screenshot.php b/include/OrmObjects/Screenshot.php
index 990f6642..5f78967e 100644
--- a/include/OrmObjects/Screenshot.php
+++ b/include/OrmObjects/Screenshot.php
@@ -19,7 +19,8 @@ class Screenshot extends BaseScreenshot
public function getFiles()
{
- if (!$this->files) {
+ if (!isset($this->files)) {
+ $this->files = [];
$gameId = str_replace(':', '/', $this->getGame()->getId());
foreach (glob(DIR_STATIC . DIR_SCREENSHOTS . '/' . $gameId . '/' . $this->getFileMask()) as $file) {
// Remove the base folder
@@ -38,7 +39,7 @@ class Screenshot extends BaseScreenshot
public function addFiles($files)
{
- if (is_array($this->files)) {
+ if (isset($this->files)) {
$this->files = array_merge($this->files, $files);
} else {
$this->files = $files;
Commit: d8ff9c3c753450e3f3149be6663b333581b1212b
https://github.com/scummvm/scummvm-web/commit/d8ff9c3c753450e3f3149be6663b333581b1212b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Remove useless check
The function is expected to take an array or a string.
Array is checked above so what remains is a string.
Any other use is an error that should be reported (strlen will fail).
Changed paths:
include/Controller.php
diff --git a/include/Controller.php b/include/Controller.php
index fa1f8338..bb580344 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -190,7 +190,7 @@ class Controller
$this->css_files,
$extra_css
);
- } elseif (is_string($extra_css) && strlen($extra_css) > 0) {
+ } elseif (strlen($extra_css) > 0) {
$this->css_files[] = $extra_css;
}
}
@@ -203,7 +203,7 @@ class Controller
$this->js_files,
$extra_js
);
- } elseif (is_string($extra_js) && strlen($extra_js) > 0) {
+ } elseif (strlen($extra_js) > 0) {
$this->js_files[] = $extra_js;
}
}
Commit: 3d37c952a8ba38f6d5a53b7bad756db172b19e6f
https://github.com/scummvm/scummvm-web/commit/3d37c952a8ba38f6d5a53b7bad756db172b19e6f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:46+02:00
Commit Message:
WEB: Use null instead of false when no data is available
This allows to use the ? type prefix.
Changed paths:
include/Models/DownloadsModel.php
include/Models/ScreenshotsModel.php
diff --git a/include/Models/DownloadsModel.php b/include/Models/DownloadsModel.php
index 6df855af..2283248a 100644
--- a/include/Models/DownloadsModel.php
+++ b/include/Models/DownloadsModel.php
@@ -100,7 +100,7 @@ class DownloadsModel extends BasicModel
public function getRecommendedDownload()
{
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
- return false;
+ return null;
}
$osParser = new OsParser();
@@ -140,6 +140,6 @@ class DownloadsModel extends BasicModel
'url' => $url,
];
}
- return false;
+ return null;
}
}
diff --git a/include/Models/ScreenshotsModel.php b/include/Models/ScreenshotsModel.php
index 8696cd60..b666184c 100644
--- a/include/Models/ScreenshotsModel.php
+++ b/include/Models/ScreenshotsModel.php
@@ -78,7 +78,7 @@ class ScreenshotsModel extends BasicModel
->find();
$combinedScreenshot = $this->combineScreenshots($screenshots);
- if (!$combinedScreenshot) {
+ if (is_null($combinedScreenshot)) {
throw new \ErrorException(self::INVALID_TARGET);
}
@@ -92,13 +92,13 @@ class ScreenshotsModel extends BasicModel
* Combines multiple screenshots into a single screenshot
*
* @param Collection $screenshots
- * @return Screenshot|bool
+ * @return ?Screenshot
*/
private function combineScreenshots(iterable $screenshots)
{
$count = $screenshots->count();
if ($count === 0) {
- return false;
+ return null;
} elseif ($count === 1) {
$screenshots[0]->getFiles();
return $screenshots[0];
Commit: d7c3bd0528f28ca4108f2ac62f8ad06fcaa93f62
https://github.com/scummvm/scummvm-web/commit/d7c3bd0528f28ca4108f2ac62f8ad06fcaa93f62
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Various small fixes
These are either cosmetic or spotted by PHPStan
Changed paths:
include/Controller.php
include/FileUtils.php
include/Models/BasicModel.php
include/Models/GameDownloadsModel.php
include/Models/ScreenshotsModel.php
include/Objects/BasicObject.php
include/Objects/File.php
include/Pages/ArticlePage.php
include/Pages/SimplePage.php
diff --git a/include/Controller.php b/include/Controller.php
index bb580344..30c8addc 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -105,7 +105,7 @@ class Controller
private function isRtl($localeName)
{
$rtl_chars_pattern = '/[\x{0590}-\x{05ff}\x{0600}-\x{06ff}]/u';
- return preg_match($rtl_chars_pattern, $localeName);
+ return preg_match($rtl_chars_pattern, $localeName) === 1;
}
/**
diff --git a/include/FileUtils.php b/include/FileUtils.php
index b5afe195..0fe870a1 100644
--- a/include/FileUtils.php
+++ b/include/FileUtils.php
@@ -8,6 +8,8 @@ use DateTime;
*/
class FileUtils
{
+ private const DOUBLE_EXTENSIONS = ['.bz2', '.gz', '.lz', '.xz', '.7z'];
+
/**
* Returns whether or not the file exists and is readable
*
@@ -60,7 +62,7 @@ class FileUtils
$extension = substr($path, (strrpos($path, '.')));
// For certain extensions, check for another extension (e.g. foo.tar.gz => tar.gz)
- if ($extension == '.bz2' || $extension == '.gz' || $extension == '.lz' || $extension == '.xz' || $extension == '.7z') {
+ if (in_array($extension, self::DOUBLE_EXTENSIONS)) {
$extension = substr($path, strrpos($path, '.', -(strlen($path) - strrpos($path, '.') + 1)));
}
return $extension;
diff --git a/include/Models/BasicModel.php b/include/Models/BasicModel.php
index 2dbfe8a1..02edc29e 100644
--- a/include/Models/BasicModel.php
+++ b/include/Models/BasicModel.php
@@ -14,7 +14,7 @@ abstract class BasicModel
public function __construct()
{
- if (is_null(self::$cache)) {
+ if (!isset(self::$cache)) {
try {
$driver = extension_loaded('redis') ? 'redis' : 'predis';
$database = DEV_SERVER ? 7 : 8;
diff --git a/include/Models/GameDownloadsModel.php b/include/Models/GameDownloadsModel.php
index c986c911..2fc83c6a 100644
--- a/include/Models/GameDownloadsModel.php
+++ b/include/Models/GameDownloadsModel.php
@@ -24,7 +24,7 @@ class GameDownloadsModel extends BasicModel
foreach ($categories as $category) {
$sections[$category] = new DownloadsSection([
'anchor' => $category,
- 'title' => $sectionsData[$category]['title'],
+ 'title' => $sectionsData[$category]['title'] ?? null,
'notes' => $sectionsData[$category]['notes'] ?? null
]);
}
diff --git a/include/Models/ScreenshotsModel.php b/include/Models/ScreenshotsModel.php
index b666184c..0a9db4fe 100644
--- a/include/Models/ScreenshotsModel.php
+++ b/include/Models/ScreenshotsModel.php
@@ -131,7 +131,7 @@ class ScreenshotsModel extends BasicModel
$combined[$subcategory] = $screenshot;
}
}
- \sort($combined, SORT_STRING);
+ \ksort($combined, SORT_STRING);
return $combined;
}
diff --git a/include/Objects/BasicObject.php b/include/Objects/BasicObject.php
index 8ae77ae4..aa41d792 100644
--- a/include/Objects/BasicObject.php
+++ b/include/Objects/BasicObject.php
@@ -18,7 +18,7 @@ abstract class BasicObject
public function __toString()
{
- return $this->getName();
+ return $this->getName() ?? '';
}
/* Get the name. */
diff --git a/include/Objects/File.php b/include/Objects/File.php
index a9697846..6a2d54ff 100644
--- a/include/Objects/File.php
+++ b/include/Objects/File.php
@@ -23,8 +23,8 @@ class File extends BasicObject
$this->autoId = $data['auto_id'] ?? null;
$this->category = $data['category'];
$this->category_icon = $data['category_icon'];
- $this->notes = isset($data['notes']) ? $data['notes'] : '';
- $this->user_agent = isset($data["user_agent"]) ? $data["user_agent"] : "";
+ $this->notes = $data['notes'] ?? '';
+ $this->user_agent = $data['user_agent'] ?? '';
$this->version = isset($data['version']) ? strtolower($data['version']) : null;
/* If it's not an array, we didn't get any attributes. */
diff --git a/include/Pages/ArticlePage.php b/include/Pages/ArticlePage.php
index 0803d739..dd9efab9 100644
--- a/include/Pages/ArticlePage.php
+++ b/include/Pages/ArticlePage.php
@@ -39,7 +39,7 @@ class ArticlePage extends Controller
/* Display the index page. */
public function index($params)
{
- if (!$params['article']) {
+ if (empty($params['article'])) {
throw new \ErrorException(self::ARTICLE_NAME_MISSING);
}
$filename = $params['article'] . '.markdown';
diff --git a/include/Pages/SimplePage.php b/include/Pages/SimplePage.php
index 9ab5f4d6..582ab14b 100644
--- a/include/Pages/SimplePage.php
+++ b/include/Pages/SimplePage.php
@@ -28,7 +28,7 @@ class SimplePage extends Controller
throw new \ErrorException(\sprintf(self::FILE_NOT_FOUND, $templateFile));
}
if (array_key_exists($key, self::PAGE_MODELS)) {
- [$model, $data] = self::PAGE_MODELS[$key];
+ list($model, $data) = self::PAGE_MODELS[$key];
$this->model = new SimpleYamlModel($model, $data);
}
}
@@ -36,7 +36,7 @@ class SimplePage extends Controller
/* Display the index page. */
public function index($data = null)
{
- if ($this->model) {
+ if (isset($this->model)) {
$data = $this->model->getAllData();
}
Commit: 51ce727edd063019e7d277a74a22139e7ea5d944
https://github.com/scummvm/scummvm-web/commit/51ce727edd063019e7d277a74a22139e7ea5d944
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Simplify subsections construction
This will ease typing
Changed paths:
include/Objects/BasicSection.php
diff --git a/include/Objects/BasicSection.php b/include/Objects/BasicSection.php
index 7b097500..2559a64d 100644
--- a/include/Objects/BasicSection.php
+++ b/include/Objects/BasicSection.php
@@ -4,25 +4,25 @@ namespace ScummVM\Objects;
/**
* The BasicSection class is inherited by all other Sections and houses all common
* functions.
+ *
+ * @phpstan-consistent-constructor
*/
abstract class BasicSection extends BasicObject
{
protected $title;
protected $anchor;
protected $subsections;
- private $className;
public function __construct($data)
{
parent::__construct($data);
$this->title = $data['title'];
$this->anchor = $data['anchor'];
- $this->className = static::class;
$this->subsections = array();
if (isset($data['subsection'])) {
parent::toArray($data['subsection']);
foreach ($data['subsection'] as $value) {
- $this->subsections[] = new $this->className($value);
+ $this->subsections[] = new static($value);
}
}
}
Commit: cc9fa801811cc344e4ab86b0a6f0552d20055460
https://github.com/scummvm/scummvm-web/commit/cc9fa801811cc344e4ab86b0a6f0552d20055460
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Add typing
Changed paths:
include/Controller.php
include/DataUtils.php
include/ExceptionHandler.php
include/FileUtils.php
include/LocalizationUtils.php
include/Models/BasicModel.php
include/Models/CompatibilityModel.php
include/Models/DirectorDemosModel.php
include/Models/DownloadsModel.php
include/Models/GameDemosModel.php
include/Models/GameDownloadsModel.php
include/Models/GameModel.php
include/Models/LinksModel.php
include/Models/NewsModel.php
include/Models/ScreenshotsModel.php
include/Models/SimpleYamlModel.php
include/Models/VersionsModel.php
include/Objects/Article.php
include/Objects/BasicObject.php
include/Objects/BasicSection.php
include/Objects/CreditsSection.php
include/Objects/DownloadsSection.php
include/Objects/File.php
include/Objects/MenuItem.php
include/Objects/News.php
include/Objects/Person.php
include/Objects/Sponsor.php
include/Objects/WebLink.php
include/OrmObjects/Compatibility.php
include/OrmObjects/Demo.php
include/OrmObjects/Screenshot.php
include/OrmObjects/ScreenshotQuery.php
include/Pages/ArticlePage.php
include/Pages/CompatibilityPage.php
include/Pages/DemosPage.php
include/Pages/DirectorDemosPage.php
include/Pages/DownloadsPage.php
include/Pages/FeedsPage.php
include/Pages/GamesPage.php
include/Pages/LinksPage.php
include/Pages/NewsPage.php
include/Pages/ScreenshotsPage.php
include/Pages/SimplePage.php
include/Pages/StaticPage.php
include/SiteUtils.php
diff --git a/include/Controller.php b/include/Controller.php
index 30c8addc..308cd678 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -2,6 +2,7 @@
namespace ScummVM;
use Smarty\Smarty;
+use Smarty\Template;
use ScummVM\Models\SimpleYamlModel;
use ScummVM\SiteUtils;
@@ -12,11 +13,13 @@ use ScummVM\SiteUtils;
*/
class Controller
{
- protected $template;
- private $smarty;
- private $css_files;
- private $js_files;
- private $menuModel;
+ protected string $template;
+ private Smarty $smarty;
+ /** @var string[] */
+ private array $css_files;
+ /** @var string[] */
+ private array $js_files;
+ private SimpleYamlModel $menuModel;
/**
* Constructor that will create a Smarty object and configure it according
@@ -102,7 +105,7 @@ class Controller
/**
* Checks whether a locale string is RTL or LTR
*/
- private function isRtl($localeName)
+ private function isRtl(string $localeName): bool
{
$rtl_chars_pattern = '/[\x{0590}-\x{05ff}\x{0600}-\x{06ff}]/u';
return preg_match($rtl_chars_pattern, $localeName) === 1;
@@ -111,7 +114,7 @@ class Controller
/**
* Smarty outputfilter, run just before displaying.
*/
- public function outputFilter($string, $smarty)
+ public function outputFilter(string $string, Template $smarty): string
{
/* Properly encode all ampersands as "&". */
$string = preg_replace('/&(?!([a-z]+|(#\d+));)/i', '&', $string);
@@ -122,7 +125,7 @@ class Controller
/**
* Formating of dateAs, registered as a modifier for Smarty templates.
*/
- public function dateLocalizedSmartyModifier($timestamp)
+ public function dateLocalizedSmartyModifier(int $timestamp): string
{
global $lang;
$formatter = datefmt_create($lang, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE);
@@ -132,7 +135,7 @@ class Controller
/**
* Formating of download URLs, registered as a modifier for Smarty templates.
*/
- public function downloadsSmartyModifier($path)
+ public function downloadsSmartyModifier(string $path): string
{
if (\strpos($path, "http") === 0) {
return $path;
@@ -148,7 +151,7 @@ class Controller
/**
* Formating of version, registered as a modifier for Smarty templates.
*/
- public function releaseSmartyModifier($string)
+ public function releaseSmartyModifier(string $string): string
{
$string = preg_replace("/\{[$]?release\}/", RELEASE, $string);
$string = preg_replace("/\{[$]?release_tools\}/", RELEASE_TOOLS, $string);
@@ -156,7 +159,7 @@ class Controller
}
/* Render the HTML using the template and any set variables and displays it. */
- public function display($content)
+ public function display(string $content): void
{
$vars = array(
'css_files' => $this->css_files,
@@ -168,7 +171,10 @@ class Controller
}
/* Render the HTML using the template and any set variables and returns it. */
- public function fetch($template, $vars = null)
+ /**
+ * @param ?array<string, mixed> $vars
+ */
+ public function fetch(string $template, ?array $vars = null): string
{
if (!is_null($vars)) {
$this->smarty->assign($vars);
@@ -177,13 +183,19 @@ class Controller
}
/* Set up the variables used by the template and render the page. */
- public function renderPage($vars)
+ /**
+ * @param ?array<string, mixed> $vars
+ */
+ public function renderPage(?array $vars): void
{
$this->display($this->fetch($this->template, $vars));
}
/* Assign extra CSS files needed by the different pages/templates. */
- public function addCSSFiles($extra_css)
+ /**
+ * @param string|string[] $extra_css
+ */
+ public function addCSSFiles(string|array $extra_css): void
{
if (is_array($extra_css)) {
$this->css_files = array_merge(
@@ -196,7 +208,10 @@ class Controller
}
/* Assign javascripts files needed by the different pages/templates. */
- public function addJSFiles($extra_js)
+ /**
+ * @param string|string[] $extra_js
+ */
+ public function addJSFiles(string|array $extra_js): void
{
if (is_array($extra_js)) {
$this->js_files = array_merge(
@@ -208,12 +223,12 @@ class Controller
}
}
- protected function getConfigVars($title)
+ protected function getConfigVars(string $title): ?string
{
return $this->smarty->getConfigVars($title);
}
- protected function getHeadline($body)
+ protected function getHeadline(string $body): string
{
$headline = '';
for ($line = \strtok($body, PHP_EOL); $line !== false; $line = \strtok(PHP_EOL)) {
diff --git a/include/DataUtils.php b/include/DataUtils.php
index 27be50b0..2b35d9ae 100644
--- a/include/DataUtils.php
+++ b/include/DataUtils.php
@@ -10,6 +10,7 @@ use League\Csv\Statement;
use Symfony\Component\Yaml\Yaml;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
+use GuzzleHttp\Psr7\Response;
use Propel\Runtime\Propel;
use Propel\Runtime\Connection\Exception\RollbackException;
use Propel\Runtime\Map\TableMap;
@@ -59,7 +60,7 @@ class DataUtils
*
* @return void
*/
- public static function updateData()
+ public static function updateData(): void
{
$client = new Client();
$promises = [];
@@ -78,7 +79,7 @@ class DataUtils
\file_put_contents('.clear-cache', '');
}
- private static function doUpdateData($name, $response)
+ private static function doUpdateData(string $name, Response $response): void
{
$tsv = $response->getBody();
$reader = Reader::createFromString($tsv);
@@ -111,7 +112,7 @@ class DataUtils
\file_put_contents($outFile, $yaml);
}
- private static function convertYamlToOrm()
+ private static function convertYamlToOrm(): void
{
foreach (self::OBJECT_NAMES as $name => $object) {
$failures = array();
diff --git a/include/ExceptionHandler.php b/include/ExceptionHandler.php
index 523057be..0ebf0dcd 100644
--- a/include/ExceptionHandler.php
+++ b/include/ExceptionHandler.php
@@ -8,10 +8,10 @@ use ScummVM\Pages\SimplePage;
*/
abstract class ExceptionHandler
{
- private static $exception;
+ private static \Throwable $exception;
/* If the MenuModel cause the exception we need to skip them. */
- public static function skipMenus()
+ public static function skipMenus(): bool
{
if (!isset(self::$exception)) {
return false;
@@ -33,7 +33,7 @@ abstract class ExceptionHandler
}
/* Handle exceptions. */
- public static function handleException($e)
+ public static function handleException(\Throwable $e): void
{
self::$exception = $e;
diff --git a/include/FileUtils.php b/include/FileUtils.php
index 0fe870a1..eeab5c89 100644
--- a/include/FileUtils.php
+++ b/include/FileUtils.php
@@ -16,7 +16,7 @@ class FileUtils
* @param $path the path to the file that will be analyzed
* @return bool whether or not the file exists
*/
- public static function exists($path)
+ public static function exists(string $path): bool
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
return is_file($path) && is_readable($path);
@@ -28,7 +28,7 @@ class FileUtils
* @param $path the path to the file that will be analyzed
* @return string the file size in a human-readable form
*/
- public static function getFileSize($path)
+ public static function getFileSize(string $path): string
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
// Get the file size, rounded to the nearest kilobyte
@@ -55,7 +55,7 @@ class FileUtils
* @param $path the path to the file that will be analyzed
* @return string the extension
*/
- public static function getExtension($path)
+ public static function getExtension(string $path): string
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
// Get everything to the right of the last period
@@ -74,7 +74,7 @@ class FileUtils
* @param $path the path to the file that will be analyzed
* @return string the SHA-256 hash
*/
- public static function getSha256($path)
+ public static function getSha256(string $path): string
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
// Check if we already have a generated hash file
@@ -97,7 +97,7 @@ class FileUtils
* @param $path the path to the file that will be analyzed
* @return string the date
*/
- public static function getLastModified($path)
+ public static function getLastModified(string $path): string
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
$date = new DateTime();
@@ -116,7 +116,7 @@ class FileUtils
* @param $path the relative path to the file that will be analyzed
* @return string the path of the file, either relative or absolute
*/
- private static function toAbsolutePathIfOnServer($relativePath)
+ private static function toAbsolutePathIfOnServer(string $relativePath): string
{
return is_file(DIR_SERVER_ROOT . '/'. $relativePath) ? DIR_SERVER_ROOT . '/'. $relativePath : $relativePath;
}
diff --git a/include/LocalizationUtils.php b/include/LocalizationUtils.php
index 3c23863d..20cc00ad 100644
--- a/include/LocalizationUtils.php
+++ b/include/LocalizationUtils.php
@@ -9,11 +9,11 @@ use Erusev\Parsedown;
class LocalizationUtils
{
- private static $purifier;
+ private static \HTMLPurifier $purifier;
const NO_FILES = 'No Localization Files Found';
- public static function localize()
+ public static function localize(): void
{
$config = \HTMLPurifier_Config::createDefault();
self::$purifier = new \HTMLPurifier($config);
@@ -27,7 +27,7 @@ class LocalizationUtils
}
}
- private static function convertLanguageJsonToSmartyIni($lang)
+ private static function convertLanguageJsonToSmartyIni(string $lang): void
{
$Parsedown = new \Parsedown();
$Parsedown->setBreaksEnabled(true);
@@ -46,7 +46,7 @@ class LocalizationUtils
file_put_contents(join(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, "strings.ini"]), $output);
}
- private static function updateNewsL10n($lang)
+ private static function updateNewsL10n(string $lang): void
{
$newsFile = join(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, "news.json"]);
// For non-english, create/overwrite JSON files from our l10n file
@@ -79,7 +79,7 @@ class LocalizationUtils
if ($lang === 'fr') {
$content = preg_replace_callback(
"/(?<=\(http)(.*?)(?=\))/u",
- function ($matches) {
+ function (array $matches): string {
return preg_replace("/\x{202f}/u", "", $matches[1]);
},
$content
@@ -114,7 +114,10 @@ class LocalizationUtils
}
}
- private static function getAllNews($lang)
+ /**
+ * @return array<string, array{'title': string, 'content': string}>
+ */
+ private static function getAllNews(string $lang): array
{
$dir = join(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, 'news']);
diff --git a/include/Models/BasicModel.php b/include/Models/BasicModel.php
index 02edc29e..d084a825 100644
--- a/include/Models/BasicModel.php
+++ b/include/Models/BasicModel.php
@@ -10,7 +10,7 @@ abstract class BasicModel
{
const FILE_NOT_FOUND = 'The filename %s could not be found';
- protected static $cache;
+ protected static Psr16Adapter $cache;
public function __construct()
{
@@ -34,7 +34,7 @@ abstract class BasicModel
}
}
- protected function getLocalizedFile($filename)
+ protected function getLocalizedFile(string $filename): string
{
global $lang;
if (!$lang) {
@@ -51,7 +51,7 @@ abstract class BasicModel
}
}
- protected function saveToCache($data, $key = '')
+ protected function saveToCache(mixed $data, string $key = ''): void
{
if ($key) {
$key = "_$key";
@@ -62,7 +62,7 @@ abstract class BasicModel
self::$cache->set($cacheKey, $data, 3600);
}
- protected function getFromCache($key = '')
+ protected function getFromCache(string $key = ''): mixed
{
if (\file_exists(DIR_BASE . '/.no-cache')) {
return null;
diff --git a/include/Models/CompatibilityModel.php b/include/Models/CompatibilityModel.php
index 4150707f..16165d3d 100644
--- a/include/Models/CompatibilityModel.php
+++ b/include/Models/CompatibilityModel.php
@@ -2,6 +2,9 @@
namespace ScummVM\Models;
use Propel\Runtime\ActiveQuery\Criteria;
+use Propel\Runtime\Collection\Collection;
+
+use ScummVM\OrmObjects\Compatibility;
use ScummVM\OrmObjects\CompatibilityQuery;
use ScummVM\OrmObjects\VersionQuery;
@@ -14,13 +17,13 @@ class CompatibilityModel extends BasicModel
const NO_VERSION_TARGET = 'No version and/or target specified.';
const NOT_FOUND = 'Did not find any games for the specified version.';
- public function getLastUpdated()
+ public function getLastUpdated(): int|false
{
return filemtime($this->getLocalizedFile("compatibility.yaml"));
}
/* Get all the groups and the respectively demos for the specified ScummVM version. */
- public function getAllData($version)
+ public function getAllData(string $version): Collection
{
$data = $this->getFromCache($version);
if (\is_null($data)) {
@@ -51,7 +54,7 @@ class CompatibilityModel extends BasicModel
}
/* Get a specific CompatGame-object for the requested version. */
- public function getGameData($version, $target)
+ public function getGameData(?string $version, ?string $target): Compatibility
{
if (!is_string($version) || !is_string($target)) {
throw new \ErrorException(self::NO_VERSION_TARGET);
@@ -78,7 +81,10 @@ class CompatibilityModel extends BasicModel
return $gameData;
}
- public function getAllDataGroups($version)
+ /**
+ * @return array<string, array<Compatibility>>
+ */
+ public function getAllDataGroups(string $version): array
{
$data = $this->getAllData($version);
$compat_data = [];
diff --git a/include/Models/DirectorDemosModel.php b/include/Models/DirectorDemosModel.php
index f967b727..e2084943 100644
--- a/include/Models/DirectorDemosModel.php
+++ b/include/Models/DirectorDemosModel.php
@@ -1,15 +1,22 @@
<?php
namespace ScummVM\Models;
+use ScummVM\OrmObjects\DirectorDemo;
use ScummVM\OrmObjects\DirectorDemoQuery;
+use Propel\Runtime\Collection\Collection;
+
/**
* The DirectorDemosModel class will generate DirectorDemos objects.
*/
class DirectorDemosModel extends BasicModel
{
- /* Get all the groups and their respective demos. */
- public function getAllGroupsAndDemos()
+ /**
+ * Get all the groups and their respective demos.
+ *
+ * @return array<?int, array{'name': string, 'href': ?int, 'demos': DirectorDemo[]}>
+ */
+ public function getAllGroupsAndDemos(): array
{
$groupedData = $this->getFromCache();
if (is_null($groupedData)) {
@@ -23,7 +30,10 @@ class DirectorDemosModel extends BasicModel
return $groupedData;
}
- private function createGroups($demos)
+ /**
+ * @return array<?int, array{'name': string, 'href': ?int, 'demos': DirectorDemo[]}>
+ */
+ private function createGroups(Collection $demos): array
{
$groups = [];
foreach ($demos as $demo) {
diff --git a/include/Models/DownloadsModel.php b/include/Models/DownloadsModel.php
index 2283248a..5ae2b420 100644
--- a/include/Models/DownloadsModel.php
+++ b/include/Models/DownloadsModel.php
@@ -13,7 +13,10 @@ use ScummVM\OrmObjects\DownloadQuery;
class DownloadsModel extends BasicModel
{
/* Get all download entries. */
- public function getAllDownloads()
+ /**
+ * @return array<string, DownloadsSection>
+ */
+ public function getAllDownloads(): array
{
$sections = $this->getFromCache();
if (is_null($sections)) {
@@ -71,7 +74,10 @@ class DownloadsModel extends BasicModel
return $sections;
}
- private function getSectionData()
+ /**
+ * @return array<string, array{'title': string, 'notes'?: string}>
+ */
+ private function getSectionData(): array
{
return [
"current"=>["title"=>"{#downloadsXMLTitle#} {#downloadsXMLVersion#}"],
@@ -97,7 +103,10 @@ class DownloadsModel extends BasicModel
}
/* Get the recommended download */
- public function getRecommendedDownload()
+ /**
+ * @return ?array{'os': string, 'version': string, 'extra_text': string, 'url': string}
+ */
+ public function getRecommendedDownload(): ?array
{
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
return null;
diff --git a/include/Models/GameDemosModel.php b/include/Models/GameDemosModel.php
index a78d60bd..605d6c00 100644
--- a/include/Models/GameDemosModel.php
+++ b/include/Models/GameDemosModel.php
@@ -1,15 +1,22 @@
<?php
namespace ScummVM\Models;
+use ScummVM\OrmObjects\Demo;
use ScummVM\OrmObjects\DemoQuery;
+use Propel\Runtime\Collection\Collection;
+
/**
- * The GameDemosModel class will generate GameDemo objects.
+ * The GameDemosModel class will generate Demo objects.
*/
class GameDemosModel extends BasicModel
{
- /* Get all the groups and their respective demos. */
- public function getAllGroupsAndDemos()
+ /**
+ * Get all the groups and their respective demos.
+ *
+ * @return array<?int, array{'name': string, 'href': ?int, 'demos': Demo[]}>
+ */
+ public function getAllGroupsAndDemos(): array
{
$groupedData = $this->getFromCache();
if (is_null($groupedData)) {
@@ -24,7 +31,10 @@ class GameDemosModel extends BasicModel
return $groupedData;
}
- private function createGroups($demos)
+ /**
+ * @return array<?int, array{'name': string, 'href': ?int, 'demos': Demo[]}>
+ */
+ private function createGroups(Collection $demos): array
{
$groups = [];
foreach ($demos as $demo) {
diff --git a/include/Models/GameDownloadsModel.php b/include/Models/GameDownloadsModel.php
index 2fc83c6a..66fb72f7 100644
--- a/include/Models/GameDownloadsModel.php
+++ b/include/Models/GameDownloadsModel.php
@@ -2,6 +2,7 @@
namespace ScummVM\Models;
use ScummVM\Objects\DownloadsSection;
+use ScummVM\OrmObjects\GameDownload;
use ScummVM\OrmObjects\GameDownloadQuery;
/**
@@ -9,7 +10,11 @@ use ScummVM\OrmObjects\GameDownloadQuery;
*/
class GameDownloadsModel extends BasicModel
{
- /* Get all download entries. */
+ /**
+ * Get all download entries.
+ *
+ * @return array<string, DownloadsSection>
+ */
public function getAllDownloads()
{
$sections = $this->getFromCache();
@@ -56,6 +61,9 @@ class GameDownloadsModel extends BasicModel
return $sections;
}
+ /**
+ * @return array<string, array{'title'?: string, 'notes'?: string}>
+ */
private function getSectionData()
{
return [
diff --git a/include/Models/GameModel.php b/include/Models/GameModel.php
index 35022046..d0bebae9 100644
--- a/include/Models/GameModel.php
+++ b/include/Models/GameModel.php
@@ -1,6 +1,7 @@
<?php
namespace ScummVM\Models;
+use ScummVM\OrmObjects\Game;
use ScummVM\OrmObjects\GameQuery;
/**
@@ -8,8 +9,12 @@ use ScummVM\OrmObjects\GameQuery;
*/
class GameModel extends BasicModel
{
- /* Get all Games from YAML */
- public function getAllGames()
+ /**
+ * Get all Games from YAML
+ *
+ * @return Game[]
+ */
+ public function getAllGames(): array
{
$data = $this->getFromCache();
if (is_null($data)) {
diff --git a/include/Models/LinksModel.php b/include/Models/LinksModel.php
index d9a600e8..c0ff5ca3 100644
--- a/include/Models/LinksModel.php
+++ b/include/Models/LinksModel.php
@@ -10,8 +10,12 @@ use Symfony\Component\Yaml\Yaml;
*/
class LinksModel extends BasicModel
{
- /* Get all the groups and the respectively demos. */
- public function getAllGroupsAndLinks()
+ /**
+ * Get all the groups and the respectively demos.
+ *
+ * @return array<array{'name': string, 'notes': string, 'links': array<WebLink>}>
+ */
+ public function getAllGroupsAndLinks(): array
{
$entries = $this->getFromCache();
if (is_null($entries)) {
diff --git a/include/Models/NewsModel.php b/include/Models/NewsModel.php
index 945d2596..7ea9947c 100644
--- a/include/Models/NewsModel.php
+++ b/include/Models/NewsModel.php
@@ -12,8 +12,12 @@ class NewsModel extends BasicModel
const INVALID_DATE = 'Invalid date, use yyyyMMdd. or yyyyMMddHHmm';
const FILE_NOT_FOUND = 'The requested news file doesn\'t exist.';
- /* Get a list of all the available news files. */
- private function getListOfNewsFilenames()
+ /**
+ * Get a list of all the available news files.
+ *
+ * @return string[]
+ */
+ private function getListOfNewsFilenames(): array
{
if (!($files = scandir(join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news'])))) {
throw new \ErrorException(self::NO_FILES);
@@ -29,8 +33,12 @@ class NewsModel extends BasicModel
return $filenames;
}
- /* Get all news items ordered by date, descending. */
- public function getAllNews($processContent = false)
+ /**
+ * Get all news items ordered by date, descending.
+ *
+ * @return News[]
+ */
+ public function getAllNews(bool $processContent = false): array
{
$news = $this->getFromCache();
if (is_null($news)) {
@@ -61,8 +69,12 @@ class NewsModel extends BasicModel
return $news;
}
- /* Get the latest number of news items, or if no number is specified get all news items. */
- public function getLatestNews($num = -1, $processContent = false)
+ /**
+ * Get the latest number of news items, or if no number is specified get all news items.
+ *
+ * @return News[]
+ */
+ public function getLatestNews(int $num = -1, bool $processContent = false): array
{
if ($num == -1) {
return $this->getAllNews($processContent);
@@ -81,7 +93,7 @@ class NewsModel extends BasicModel
}
/* Get the news item that was posted on a specific date. */
- public function getOneByFilename($filename, $processContent = false)
+ public function getOneByFilename(?string $filename, bool $processContent = false): News
{
if (is_null($filename) || !preg_match('/^\d{8,12}[a-z]?$/', $filename)) {
throw new \ErrorException(self::INVALID_DATE);
diff --git a/include/Models/ScreenshotsModel.php b/include/Models/ScreenshotsModel.php
index 0a9db4fe..8a207ff2 100644
--- a/include/Models/ScreenshotsModel.php
+++ b/include/Models/ScreenshotsModel.php
@@ -5,7 +5,6 @@ use ScummVM\OrmObjects\GameQuery;
use ScummVM\OrmObjects\Screenshot;
use ScummVM\OrmObjects\ScreenshotQuery;
use Propel\Runtime\Collection\Collection;
-use Propel\Runtime\Collection\ObjectCollection;
/**
* The ScreenshotsModel will generate Screenshot objects.
@@ -16,7 +15,11 @@ class ScreenshotsModel extends BasicModel
const INVALID_CATEGORY = 'Invalid category specified.';
const SUBCATEGORY_COLUMN = '(case when game.series_id is null then screenshot.id else game.series_id end)';
- public function getAllCategories()
+ /**
+ * @return array<string, array{'title': string, 'category': string,
+ * 'games': array<string, array{'name': string, 'count': int}>}>
+ */
+ public function getAllCategories(): array
{
$categories = ScreenshotQuery::create()->findCategories();
$data = [];
@@ -40,8 +43,12 @@ class ScreenshotsModel extends BasicModel
return $data;
}
- /* Get all screenshots in one category. */
- public function getScreenshotsByCompanyId($companyId)
+ /**
+ * Get all screenshots in one category.
+ *
+ * @return array{'title': string, 'category': string, 'games': array<string, Screenshot>}
+ */
+ public function getScreenshotsByCompanyId(string $companyId): array
{
$cache_key = "c_{$companyId}";
$data = $this->getFromCache($cache_key);
@@ -65,8 +72,12 @@ class ScreenshotsModel extends BasicModel
return $data;
}
- /* Get screenshots for a specific target. */
- public function getScreenshotsBySubcategory($target)
+ /**
+ * Get screenshots for a specific target.
+ *
+ * @return Screenshot[]
+ */
+ public function getScreenshotsBySubcategory(string $target)
{
$cache_key = "s_{$target}";
$data = $this->getFromCache($cache_key);
@@ -92,9 +103,8 @@ class ScreenshotsModel extends BasicModel
* Combines multiple screenshots into a single screenshot
*
* @param Collection $screenshots
- * @return ?Screenshot
*/
- private function combineScreenshots(iterable $screenshots)
+ private function combineScreenshots(iterable $screenshots): ?Screenshot
{
$count = $screenshots->count();
if ($count === 0) {
@@ -116,7 +126,7 @@ class ScreenshotsModel extends BasicModel
* combineSubcategories
*
* @param Collection $screenshots
- * @return Screenshot[]
+ * @return array<string, Screenshot>
*/
private function combineSubcategories(iterable $screenshots)
{
@@ -158,8 +168,10 @@ class ScreenshotsModel extends BasicModel
return $count;
}
- /* Get a random screenshot (an object and not a filename) .*/
- public function getRandomScreenshot()
+ /**
+ * Get a random screenshot (an object and not a filename).
+ */
+ public function getRandomScreenshot(): Screenshot
{
return ScreenshotQuery::create()->findRandom();
}
diff --git a/include/Models/SimpleYamlModel.php b/include/Models/SimpleYamlModel.php
index a9d80404..770957ec 100644
--- a/include/Models/SimpleYamlModel.php
+++ b/include/Models/SimpleYamlModel.php
@@ -9,20 +9,23 @@ use Symfony\Component\Yaml\Yaml;
*/
class SimpleYamlModel extends BasicModel
{
- private $filename;
- private $type;
+ private string $filename;
+ private string $type;
const FILE_NOT_FOUND = 'The filename %s could not be found';
const YAML_PARSE_FAILED = 'Unable to parse the contents of the file %s';
- public function __construct($type, $filename)
+ public function __construct(string $type, string $filename)
{
parent::__construct();
$this->filename = $this->getLocalizedFile($filename);
$this->type = "ScummVM\Objects\\$type";
}
- public function getAllData($assignIdsToArray = true)
+ /**
+ * @return array<string|int, mixed>
+ */
+ public function getAllData(bool $assignIdsToArray = true) : array
{
$objects = $this->getFromCache();
if (is_null($objects)) {
diff --git a/include/Models/VersionsModel.php b/include/Models/VersionsModel.php
index 83ea72b4..1a165620 100644
--- a/include/Models/VersionsModel.php
+++ b/include/Models/VersionsModel.php
@@ -1,6 +1,7 @@
<?php
namespace ScummVM\Models;
+use ScummVM\OrmObjects\Version;
use ScummVM\OrmObjects\VersionQuery;
/**
@@ -8,8 +9,12 @@ use ScummVM\OrmObjects\VersionQuery;
*/
class VersionsModel extends BasicModel
{
- /* Get all versions from YAML */
- public function getAllVersions()
+ /**
+ * Get all versions from YAML
+ *
+ * @return Version[]
+ */
+ public function getAllVersions(): array
{
$data = $this->getFromCache();
if (is_null($data)) {
diff --git a/include/Objects/Article.php b/include/Objects/Article.php
index e7df7e87..0a14aef0 100644
--- a/include/Objects/Article.php
+++ b/include/Objects/Article.php
@@ -7,13 +7,16 @@ namespace ScummVM\Objects;
*/
class Article extends BasicObject
{
- private $url;
- private $language;
- private $source;
- private $date;
+ private ?string $url;
+ private ?string $language;
+ private ?string $source;
+ private ?string $date;
- /* Article object constructor. */
- public function __construct($data)
+ /**
+ * Article object constructor.
+ * @param array{'url'?: string, 'language'?: string, 'source'?: string, 'date'?: string} $data
+ */
+ public function __construct(array $data)
{
parent::__construct($data);
$this->url = $data['url'] ?? null;
@@ -23,25 +26,25 @@ class Article extends BasicObject
}
/* Get the URL. */
- public function getURL()
+ public function getURL(): ?string
{
return $this->url;
}
/* Get the language. */
- public function getLanguage()
+ public function getLanguage(): ?string
{
return $this->language;
}
/* Get the source that published it. */
- public function getSource()
+ public function getSource(): ?string
{
return $this->source;
}
/* Get the date it was posted. */
- public function getDate()
+ public function getDate(): ?string
{
return $this->date;
}
diff --git a/include/Objects/BasicObject.php b/include/Objects/BasicObject.php
index aa41d792..2adba544 100644
--- a/include/Objects/BasicObject.php
+++ b/include/Objects/BasicObject.php
@@ -7,27 +7,30 @@ namespace ScummVM\Objects;
*/
abstract class BasicObject
{
- protected $name;
- protected $description;
+ protected ?string $name;
+ protected ?string $description;
- public function __construct($data)
+ /**
+ * @param array{'description'?: string, 'name'?: string} $data
+ */
+ public function __construct(array $data)
{
$this->description = $data['description'] ?? null;
$this->name = $data['name'] ?? null;
}
- public function __toString()
+ public function __toString(): string
{
return $this->getName() ?? '';
}
/* Get the name. */
- public function getName()
+ public function getName(): ?string
{
return $this->name;
}
- public function getDescription()
+ public function getDescription(): ?string
{
return $this->description;
}
@@ -36,9 +39,10 @@ abstract class BasicObject
* If the input array doesn't contain the numerical key 0, wrap it inside
* an array. This functions operates on the data directly.
*
- * @param mixed $data the input
+ * @param $data the input
+ * @param-out mixed[] $data
*/
- public function toArray(&$data)
+ public function toArray(mixed &$data): void
{
if (!is_array($data) || !array_key_exists(0, $data)) {
$data = array($data);
diff --git a/include/Objects/BasicSection.php b/include/Objects/BasicSection.php
index 2559a64d..3f61c5e9 100644
--- a/include/Objects/BasicSection.php
+++ b/include/Objects/BasicSection.php
@@ -9,11 +9,15 @@ namespace ScummVM\Objects;
*/
abstract class BasicSection extends BasicObject
{
- protected $title;
- protected $anchor;
- protected $subsections;
+ protected string $title;
+ protected string $anchor;
+ /** @var array<static> */
+ protected array $subsections;
- public function __construct($data)
+ /**
+ * @param array{'title': string, 'anchor': string, 'subsection'?: array<mixed>, ...} $data
+ */
+ public function __construct(array $data)
{
parent::__construct($data);
$this->title = $data['title'];
@@ -28,19 +32,23 @@ abstract class BasicSection extends BasicObject
}
/* Get the title. */
- public function getTitle()
+ public function getTitle(): string
{
return $this->title;
}
/* Get the anchor. */
- public function getAnchor()
+ public function getAnchor(): string
{
return $this->anchor;
}
- /* Get the optional list of subsections. */
- public function getSubSections()
+ /**
+ * Get the optional list of subsections.
+ *
+ * @return array<static>
+ */
+ public function getSubSections(): array
{
return $this->subsections;
}
diff --git a/include/Objects/CreditsSection.php b/include/Objects/CreditsSection.php
index 7b01b44b..e4da70b2 100644
--- a/include/Objects/CreditsSection.php
+++ b/include/Objects/CreditsSection.php
@@ -7,11 +7,21 @@ namespace ScummVM\Objects;
*/
class CreditsSection extends BasicSection
{
- private $groups;
- private $paragraphs;
+ /** @var array<array{'name': string, 'persons': array<Person>}> */
+ private array $groups;
+ /** @var string[] */
+ private array $paragraphs;
- /* CreditsSection object constructor. */
- public function __construct($data)
+ /**
+ * CreditsSection object constructor.
+ *
+ * @param array{'title': string, 'anchor': string, 'subsection'?: array<mixed>,
+ * 'group'?: array<array{
+ * 'person': array<array{'description'?: string, 'name'?: string, 'alias': string}>,
+ * 'name': string}>,
+ * 'paragraph'?: string[]} $data
+ */
+ public function __construct(array $data)
{
parent::__construct($data);
$this->groups = [];
@@ -36,14 +46,22 @@ class CreditsSection extends BasicSection
}
}
- /* Get the optional list of groups. */
- public function getGroups()
+ /**
+ * Get the optional list of groups.
+ *
+ * @return array<array{'name': string, 'persons': array<Person>}>
+ */
+ public function getGroups(): array
{
return $this->groups;
}
- /* Get the optional list of paragraphs. */
- public function getParagraphs()
+ /**
+ * Get the optional list of paragraphs.
+ *
+ * @return string[]
+ */
+ public function getParagraphs(): array
{
return $this->paragraphs;
}
diff --git a/include/Objects/DownloadsSection.php b/include/Objects/DownloadsSection.php
index 3173a9e9..038b81e4 100644
--- a/include/Objects/DownloadsSection.php
+++ b/include/Objects/DownloadsSection.php
@@ -1,6 +1,9 @@
<?php
namespace ScummVM\Objects;
+use ScummVM\OrmObjects\Download;
+use ScummVM\OrmObjects\GameDownload;
+
use Propel\Runtime\Map\TableMap;
/**
@@ -8,23 +11,24 @@ use Propel\Runtime\Map\TableMap;
*/
class DownloadsSection extends BasicSection
{
- private $notes;
- private $items;
+ private string $notes;
+ /** @var array<WebLink|File> */
+ private array $items;
/**
- * __construct
- *
- * @param mixed $data [id, notes, anchor, title]
- * @return void
+ * @param array{'title': string, 'anchor': string, 'subsection'?: array<mixed>, 'notes': string} $data
*/
- public function __construct($data)
+ public function __construct(array $data)
{
parent::__construct($data);
$this->notes = $data['notes'];
$this->items = [];
}
- public function addItem($item)
+ /**
+ * @param Download|GameDownload $item
+ */
+ public function addItem(object $item): void
{
if ($item->getCategoryIcon()) {
$this->items[] = new File($item->toArray(TableMap::TYPE_FIELDNAME));
@@ -46,24 +50,36 @@ class DownloadsSection extends BasicSection
}
}
- /* Get the optional notes. */
- public function getNotes()
+ /**
+ * Get the optional notes.
+ */
+ public function getNotes(): ?string
{
return $this->notes;
}
- /* Get the list of items. */
- public function getItems()
+ /**
+ * Get the list of items.
+ *
+ * @return array<WebLink|File>
+ */
+ public function getItems(): array
{
return $this->items;
}
- public function addSubsection($section)
+ /**
+ * @param static $section
+ */
+ public function addSubsection(DownloadsSection $section): void
{
$this->subsections[$section->getAnchor()] = $section;
}
- private function hasOldVersion($item)
+ /**
+ * @param Download|GameDownload $item
+ */
+ private function hasOldVersion(object $item): bool
{
return method_exists($item, 'getVersion') && $item->getVersion() !== RELEASE && $item->getVersion() !== 'Daily';
}
diff --git a/include/Objects/File.php b/include/Objects/File.php
index 6a2d54ff..a77086b4 100644
--- a/include/Objects/File.php
+++ b/include/Objects/File.php
@@ -8,15 +8,21 @@ use ScummVM\FileUtils;
*/
class File extends BasicObject
{
- private $autoId;
- private $category;
- private $category_icon;
- private $url;
- private $extra_info;
- private $notes;
- private $user_agent;
- private $version;
+ private ?int $autoId;
+ private string $category;
+ private string $category_icon;
+ private string $url;
+ /** @var array{'size': string, 'sha256': string, 'ext': string, 'date': string}|array{} */
+ private array $extra_info;
+ private string $notes;
+ private string $user_agent;
+ private ?string $version;
+ /**
+ * @param array{'description'?: string, 'name'?: string, 'auto_id'?: int, 'category': string,
+ * 'category_icon': string, 'notes'?: string, 'user_agent'?: string, 'version'?: string,
+ * 'url': string|array{0: string, '@attributes': array<mixed>}} $data
+ */
public function __construct($data)
{
parent::__construct($data);
@@ -64,30 +70,34 @@ class File extends BasicObject
}
/* Get the category icon. */
- public function getCategoryIcon()
+ public function getCategoryIcon(): string
{
return $this->category_icon;
}
/* Get the URL. */
- public function getURL()
+ public function getURL(): string
{
return $this->url;
}
- /* Get the extra information. */
- public function getExtraInfo()
+ /**
+ * Get the extra information.
+ *
+ * @return array{'size': string, 'sha256': string, 'ext': string, 'date': string}|array{}
+ */
+ public function getExtraInfo(): array
{
return $this->extra_info;
}
- public function getNotes()
+ public function getNotes(): string
{
return $this->notes;
}
/* Get the user-agent. */
- public function getUserAgent()
+ public function getUserAgent(): string
{
return $this->user_agent;
}
diff --git a/include/Objects/MenuItem.php b/include/Objects/MenuItem.php
index abf4ac1c..200beff6 100644
--- a/include/Objects/MenuItem.php
+++ b/include/Objects/MenuItem.php
@@ -7,10 +7,15 @@ namespace ScummVM\Objects;
class MenuItem extends BasicObject
{
- private $class;
- private $entries;
+ private string $class;
+ /** @var array<string, string> */
+ private array $entries;
- /* Menu object constructor. */
+ /**
+ * Menu object constructor.
+ * @param array{'description'?: string, 'name'?: string, 'class': string,
+ * 'links': array<array{'name': string, 'href': string}>} $data
+ */
public function __construct($data)
{
parent::__construct($data);
@@ -22,13 +27,17 @@ class MenuItem extends BasicObject
}
/* Get the CSS class. */
- public function getClass()
+ public function getClass(): string
{
return $this->class;
}
- /* Get the list of links, with the name as key and URL as value. */
- public function getEntries()
+ /**
+ * Get the list of links, with the name as key and URL as value.
+ *
+ * @return array<string, string>
+ */
+ public function getEntries(): array
{
return $this->entries;
}
diff --git a/include/Objects/News.php b/include/Objects/News.php
index ebbd230f..65b28205 100644
--- a/include/Objects/News.php
+++ b/include/Objects/News.php
@@ -10,16 +10,16 @@ use Erusev\Parsedown;
*/
class News
{
- private $title;
- private $date;
- private $author;
- private $content;
- private $filename;
+ private string $title;
+ private string $date;
+ private string $author;
+ private string $content;
+ private string $filename;
/**
* News object constructor that extracts the data from the YAML frontmatter.
*/
- public function __construct($data, $filename, $processContent = false)
+ public function __construct(string $data, string $filename, bool $processContent = false)
{
$object = YamlFrontMatter::parse($data);
$Parsedown = new \Parsedown();
@@ -42,12 +42,12 @@ class News
* http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
* for a list of valid entities for both XML and HTML
*/
- public function processText($text)
+ public function processText(string $text): string
{
return html_entity_decode($text, ENT_COMPAT, 'UTF-8');
}
- private function localizeLinks($body)
+ private function localizeLinks(string $body): string
{
global $lang;
if ($lang == DEFAULT_LOCALE || !$lang) {
@@ -70,37 +70,37 @@ class News
}
/* Get the title. */
- public function getTitle()
+ public function getTitle(): string
{
return $this->title;
}
/* Get the date. */
- public function getDate()
+ public function getDate(): string
{
return $this->date;
}
/* Get the author. */
- public function getAuthor()
+ public function getAuthor(): string
{
return $this->author;
}
/* Get the content. */
- public function getContent()
+ public function getContent(): string
{
return $this->content;
}
/* Get the filename. */
- public function getFilename()
+ public function getFilename(): string
{
return $this->filename;
}
/* Get the News link. */
- public function getLink()
+ public function getLink(): string
{
return URL_BASE . 'news/' . substr($this->filename, 0, -9);
}
diff --git a/include/Objects/Person.php b/include/Objects/Person.php
index c35a5781..5bd0038d 100644
--- a/include/Objects/Person.php
+++ b/include/Objects/Person.php
@@ -7,9 +7,12 @@ namespace ScummVM\Objects;
*/
class Person extends BasicObject
{
- private $alias;
+ private string $alias;
- /* Person object constructor. */
+ /**
+ * Person object constructor.
+ * @param array{'description'?: string, 'name'?: string, 'alias': string} $data
+ */
public function __construct($data)
{
parent::__construct($data);
@@ -17,7 +20,7 @@ class Person extends BasicObject
}
/* Get the alias. */
- public function getAlias()
+ public function getAlias(): string
{
return $this->alias;
}
diff --git a/include/Objects/Sponsor.php b/include/Objects/Sponsor.php
index 96b46b1c..24c4d508 100644
--- a/include/Objects/Sponsor.php
+++ b/include/Objects/Sponsor.php
@@ -2,15 +2,18 @@
namespace ScummVM\Objects;
/**
- * The article class represents a link on the website to an article covering
+ * The sponsor class represents a link on the website to a sponsor and its logo and supporting
* ScummVM in some way.
*/
class Sponsor extends BasicObject
{
- private $link;
- private $image;
+ private string $link;
+ private string $image;
- /* Article object constructor. */
+ /**
+ * Sponsor object constructor.
+ * @param array{'description'?: string, 'name'?: string, 'link': string, 'image': string} $data
+ */
public function __construct($data)
{
parent::__construct($data);
@@ -19,13 +22,13 @@ class Sponsor extends BasicObject
}
/* Get the sponsor link. */
- public function getLink()
+ public function getLink(): string
{
return $this->link;
}
/* Get the sponsor image */
- public function getImage()
+ public function getImage(): string
{
return $this->image;
}
diff --git a/include/Objects/WebLink.php b/include/Objects/WebLink.php
index 3e4b0f1a..43b1b12e 100644
--- a/include/Objects/WebLink.php
+++ b/include/Objects/WebLink.php
@@ -6,10 +6,13 @@ namespace ScummVM\Objects;
*/
class WebLink extends BasicObject
{
- private $notes;
- private $url;
+ private string $notes;
+ private string $url;
- /* WebLink object constructor. */
+ /**
+ * WebLink object constructor.
+ * @param array{'description'?: string, 'name'?: string, 'notes': string, 'url': string} $data
+ */
public function __construct($data)
{
parent::__construct($data);
@@ -17,19 +20,19 @@ class WebLink extends BasicObject
$this->url = $data['url'];
}
- public function getNotes()
+ public function getNotes(): string
{
return $this->notes;
}
/* Get the URL of the link. */
- public function getURL()
+ public function getURL(): string
{
return $this->url;
}
/* Get the user-agent. */
- public function getUserAgent()
+ public function getUserAgent(): string
{
return "";
}
diff --git a/include/OrmObjects/Compatibility.php b/include/OrmObjects/Compatibility.php
index 95b86457..4cb991e7 100644
--- a/include/OrmObjects/Compatibility.php
+++ b/include/OrmObjects/Compatibility.php
@@ -15,7 +15,7 @@ use ScummVM\OrmObjects\Base\Compatibility as BaseCompatibility;
*/
class Compatibility extends BaseCompatibility
{
- private function processPlatforms($values)
+ private function processPlatforms(string $values): string
{
$platforms = \explode(",", $values);
@@ -27,7 +27,7 @@ class Compatibility extends BaseCompatibility
return $retVal;
}
- public function getScummVmId($version)
+ public function getScummVmId(string $version): string
{
$gameId = $this->getGame()->getId();
if ($version == "DEV" || version_compare($version, "2.2.0") > 0) {
@@ -39,7 +39,7 @@ class Compatibility extends BaseCompatibility
}
}
- public function getNotes()
+ public function getNotes(): string
{
$notes = "### Support Level\n\n";
$notes .= "[[support_description]]\n\n";
diff --git a/include/OrmObjects/Demo.php b/include/OrmObjects/Demo.php
index 6ff7e11b..9c5d5d6b 100644
--- a/include/OrmObjects/Demo.php
+++ b/include/OrmObjects/Demo.php
@@ -15,7 +15,7 @@ use ScummVM\OrmObjects\Base\Demo as BaseDemo;
*/
class Demo extends BaseDemo
{
- public function getName()
+ public function getName(): string
{
$gameName = $this->getGame()->getName();
$platformName = $this->getPlatform()->getName();
@@ -23,7 +23,7 @@ class Demo extends BaseDemo
return "$gameName ($platformName $category Demo)";
}
- public function __toString()
+ public function __toString(): string
{
return $this->getName();
}
diff --git a/include/OrmObjects/Screenshot.php b/include/OrmObjects/Screenshot.php
index 5f78967e..942ce872 100644
--- a/include/OrmObjects/Screenshot.php
+++ b/include/OrmObjects/Screenshot.php
@@ -15,9 +15,15 @@ use ScummVM\OrmObjects\Base\Screenshot as BaseScreenshot;
*/
class Screenshot extends BaseScreenshot
{
- private $files;
+ /**
+ * @var array<array{'filename': string, 'caption': string, 'url': string}>
+ */
+ private array $files;
- public function getFiles()
+ /**
+ * @return array<array{'filename': string, 'caption': string, 'url': string}>
+ */
+ public function getFiles(): array
{
if (!isset($this->files)) {
$this->files = [];
@@ -37,7 +43,10 @@ class Screenshot extends BaseScreenshot
return $this->files;
}
- public function addFiles($files)
+ /**
+ * @param array<array{'filename': string, 'caption': string, 'url': string}> $files
+ */
+ public function addFiles(array $files): void
{
if (isset($this->files)) {
$this->files = array_merge($this->files, $files);
@@ -46,7 +55,7 @@ class Screenshot extends BaseScreenshot
}
}
- public function getCategory()
+ public function getCategory(): string
{
$series = $this->getGame()->getSeries();
if ($series) {
@@ -57,7 +66,7 @@ class Screenshot extends BaseScreenshot
}
}
- public function getName()
+ public function getName(): string
{
$series = $this->getGame()->getSeries();
if ($series) {
@@ -67,7 +76,7 @@ class Screenshot extends BaseScreenshot
}
}
- public function getCaption()
+ public function getCaption(): string
{
$name = $this->getGame()->getName();
$extras = [];
@@ -90,7 +99,7 @@ class Screenshot extends BaseScreenshot
return htmlspecialchars($name);
}
- public function getFileMask()
+ public function getFileMask(): string
{
// Remove engine prefix
$game_short_id = substr($this->getGame()->getId(), strpos($this->getGame()->getId(), ':') + 1);
@@ -106,7 +115,7 @@ class Screenshot extends BaseScreenshot
return $mask;
}
- public function __toString()
+ public function __toString(): string
{
return $this->getCaption();
}
diff --git a/include/OrmObjects/ScreenshotQuery.php b/include/OrmObjects/ScreenshotQuery.php
index a28b305f..62818696 100644
--- a/include/OrmObjects/ScreenshotQuery.php
+++ b/include/OrmObjects/ScreenshotQuery.php
@@ -21,7 +21,7 @@ use ScummVM\OrmObjects\Map\ScreenshotTableMap;
*/
class ScreenshotQuery extends BaseScreenshotQuery
{
- public function findRandom(ConnectionInterface $con = null)
+ public function findRandom(ConnectionInterface $con = null): ChildScreenshot
{
if ($con === null) {
$con = Propel::getServiceContainer()->getReadConnection(ScreenshotTableMap::DATABASE_NAME);
@@ -48,7 +48,11 @@ class ScreenshotQuery extends BaseScreenshotQuery
return $obj;
}
- public function findCategories(ConnectionInterface $con = null)
+ /**
+ * @return array<array{'category_key': string, 'category_name': string, 'subcategory_key': string,
+ * 'subcategory_name': string}>
+ */
+ public function findCategories(ConnectionInterface $con = null): array
{
if ($con === null) {
$con = Propel::getServiceContainer()->getReadConnection(ScreenshotTableMap::DATABASE_NAME);
@@ -99,7 +103,7 @@ class ScreenshotQuery extends BaseScreenshotQuery
return $obj;
}
- public function filterByCompanyId($companyId, ConnectionInterface $con = null)
+ public function filterByCompanyId(string $companyId, ConnectionInterface $con = null): self
{
if ($companyId !== 'other') {
return $this->useGameQuery()
diff --git a/include/Pages/ArticlePage.php b/include/Pages/ArticlePage.php
index dd9efab9..9ee5d349 100644
--- a/include/Pages/ArticlePage.php
+++ b/include/Pages/ArticlePage.php
@@ -2,6 +2,7 @@
namespace ScummVM\Pages;
use ScummVM\Controller;
+use Spatie\YamlFrontMatter\Document;
use Spatie\YamlFrontMatter\YamlFrontMatter;
use Erusev\Parsedown;
@@ -17,7 +18,7 @@ class ArticlePage extends Controller
$this->template = 'pages/article.tpl';
}
- private function getArticle($filename)
+ private function getArticle(string $filename): Document
{
global $lang;
if (!$lang) {
@@ -36,8 +37,12 @@ class ArticlePage extends Controller
return YamlFrontMatter::parse(file_get_contents($fname));
}
- /* Display the index page. */
- public function index($params)
+ /**
+ * Display the index page.
+ *
+ * @param array{'article'?: string} $params
+ */
+ public function index(array $params): void
{
if (empty($params['article'])) {
throw new \ErrorException(self::ARTICLE_NAME_MISSING);
diff --git a/include/Pages/CompatibilityPage.php b/include/Pages/CompatibilityPage.php
index 79b146a5..d5de41ed 100644
--- a/include/Pages/CompatibilityPage.php
+++ b/include/Pages/CompatibilityPage.php
@@ -12,10 +12,16 @@ use ScummVM\OrmObjects\VersionQuery;
*/
class CompatibilityPage extends Controller
{
- private $supportLevel;
- private $supportLevelDescriptions;
- private $supportLevelClass;
- private $compatibilityModel;
+ // Would be useful for PHPStan
+ //private const LEVELS = ['untested', 'broken', 'bugged', 'good', 'excellent'];
+
+ /** @var array<value-of<self::LEVELS>, ?string> */
+ private array $supportLevel;
+ /** @var array<value-of<self::LEVELS>, ?string> */
+ private array $supportLevelDescriptions;
+ /** @var array<value-of<self::LEVELS>, ?string> */
+ private array $supportLevelClass;
+ private CompatibilityModel $compatibilityModel;
/* Constructor. */
public function __construct()
@@ -49,8 +55,12 @@ class CompatibilityPage extends Controller
$this->compatibilityModel = new CompatibilityModel();
}
- /* Display the index page. */
- public function index($args)
+ /**
+ * Display the index page.
+ *
+ * @param array{'version'?: string, 'game'?: string} $args
+ */
+ public function index($args): void
{
$version = $args['version'] ?? null;
$target = $args['game'] ?? null;
@@ -75,7 +85,7 @@ class CompatibilityPage extends Controller
}
/* We should show detailed information for a specific target. */
- public function getGame($target, $version)
+ public function getGame(string $target, string $version): void
{
$game = $this->compatibilityModel->getGameData($version, $target);
// Redirect to main compatibility page if the requested game doesn't exist
@@ -107,7 +117,10 @@ class CompatibilityPage extends Controller
}
/* We should show all the compatibility stats for a specific version. */
- public function getAll($version, $versions)
+ /**
+ * @param string[] $versions
+ */
+ public function getAll(string $version, array $versions): void
{
$compat_data = $this->compatibilityModel->getAllDataGroups($version);
diff --git a/include/Pages/DemosPage.php b/include/Pages/DemosPage.php
index 4899aa56..db3cb77f 100644
--- a/include/Pages/DemosPage.php
+++ b/include/Pages/DemosPage.php
@@ -6,7 +6,7 @@ use ScummVM\Models\GameDemosModel;
class DemosPage extends Controller
{
- private $gameDemosModel;
+ private GameDemosModel $gameDemosModel;
/* Constructor. */
public function __construct()
@@ -17,7 +17,7 @@ class DemosPage extends Controller
}
/* Display the index page. */
- public function index()
+ public function index(): void
{
$demos = $this->gameDemosModel->getAllGroupsAndDemos();
$this->renderPage(
diff --git a/include/Pages/DirectorDemosPage.php b/include/Pages/DirectorDemosPage.php
index 016259a9..2f0db58b 100644
--- a/include/Pages/DirectorDemosPage.php
+++ b/include/Pages/DirectorDemosPage.php
@@ -6,7 +6,7 @@ use ScummVM\Models\DirectorDemosModel;
class DirectorDemosPage extends Controller
{
- private $gameDemosModel;
+ private DirectorDemosModel $gameDemosModel;
/* Constructor. */
public function __construct()
@@ -17,7 +17,7 @@ class DirectorDemosPage extends Controller
}
/* Display the index page. */
- public function index()
+ public function index(): void
{
$demos = $this->gameDemosModel->getAllGroupsAndDemos();
$this->renderPage(
diff --git a/include/Pages/DownloadsPage.php b/include/Pages/DownloadsPage.php
index 823b9f15..6c864a4c 100644
--- a/include/Pages/DownloadsPage.php
+++ b/include/Pages/DownloadsPage.php
@@ -6,7 +6,7 @@ use ScummVM\Models\DownloadsModel;
class DownloadsPage extends Controller
{
- private $downloadsModel;
+ private DownloadsModel $downloadsModel;
/* Constructor. */
public function __construct()
{
@@ -16,7 +16,7 @@ class DownloadsPage extends Controller
}
/* Display the index page. */
- public function index()
+ public function index(): void
{
$downloads = $this->downloadsModel->getAllDownloads();
$recommendedDownload = $this->downloadsModel->getRecommendedDownload();
diff --git a/include/Pages/FeedsPage.php b/include/Pages/FeedsPage.php
index 20114a6f..d1e3cfa2 100644
--- a/include/Pages/FeedsPage.php
+++ b/include/Pages/FeedsPage.php
@@ -6,9 +6,9 @@ use ScummVM\Models\NewsModel;
class FeedsPage extends Controller
{
- private $template_rss;
- private $template_atom;
- private $newsModel;
+ private string $template_rss;
+ private string $template_atom;
+ private NewsModel $newsModel;
/* Constructor. */
public function __construct()
@@ -19,8 +19,12 @@ class FeedsPage extends Controller
$this->newsModel = new NewsModel();
}
- /* Display the index page. */
- public function index($args)
+ /**
+ * Display the index page.
+ *
+ * @param array{'type'?: string} $args
+ */
+ public function index(array $args): void
{
$feed = isset($args['type']) ? $args['type'] : '';
if ($feed == 'atom') {
diff --git a/include/Pages/GamesPage.php b/include/Pages/GamesPage.php
index 74c8dc9e..ebf4aed3 100644
--- a/include/Pages/GamesPage.php
+++ b/include/Pages/GamesPage.php
@@ -6,7 +6,7 @@ use ScummVM\Models\GameDownloadsModel;
class GamesPage extends Controller
{
- private $gameDownloadsModel;
+ private GameDownloadsModel $gameDownloadsModel;
/* Constructor. */
public function __construct()
@@ -17,7 +17,7 @@ class GamesPage extends Controller
}
/* Display the index page. */
- public function index()
+ public function index(): void
{
$downloads = $this->gameDownloadsModel->getAllDownloads();
$this->renderPage(
diff --git a/include/Pages/LinksPage.php b/include/Pages/LinksPage.php
index 7765e6db..fa0c3973 100644
--- a/include/Pages/LinksPage.php
+++ b/include/Pages/LinksPage.php
@@ -7,7 +7,7 @@ use ScummVM\Models\LinksModel;
class LinksPage extends Controller
{
- private $linksModel;
+ private LinksModel $linksModel;
/* Constructor. */
public function __construct()
@@ -18,7 +18,7 @@ class LinksPage extends Controller
}
/* Display the index page. */
- public function index()
+ public function index(): void
{
$links = $this->linksModel->getAllGroupsAndLinks();
$this->renderPage(
diff --git a/include/Pages/NewsPage.php b/include/Pages/NewsPage.php
index d0f3e16b..9f26ff48 100644
--- a/include/Pages/NewsPage.php
+++ b/include/Pages/NewsPage.php
@@ -7,8 +7,8 @@ use ScummVM\Models\ScreenshotsModel;
class NewsPage extends Controller
{
- private $newsModel;
- private $screenshotModels;
+ private NewsModel $newsModel;
+ private ScreenshotsModel $screenshotModels;
/* Constructor. */
public function __construct()
@@ -19,8 +19,12 @@ class NewsPage extends Controller
$this->screenshotModels = new ScreenshotsModel();
}
- /* Display the index page. */
- public function index($args)
+ /**
+ * Display the index page.
+ *
+ * @param array{'date'?: string} $args
+ */
+ public function index(array $args): void
{
$filename = $args['date'] ?? null;
@@ -36,7 +40,7 @@ class NewsPage extends Controller
}
/* Display a specific news item, or all news items. */
- public function getNews($filename = null)
+ public function getNews(?string $filename = null): void
{
if ($filename == null) {
$news_items = $this->newsModel->getAllNews();
@@ -62,7 +66,7 @@ class NewsPage extends Controller
}
/* Display the main page with limited news items and intro text. */
- public function getNewsIntro()
+ public function getNewsIntro(): void
{
$news_items = $this->newsModel->getLatestNews(NEWS_ITEMS);
$random_shot = $this->screenshotModels->getRandomScreenshot();
diff --git a/include/Pages/ScreenshotsPage.php b/include/Pages/ScreenshotsPage.php
index 54c10754..4fbe18bd 100644
--- a/include/Pages/ScreenshotsPage.php
+++ b/include/Pages/ScreenshotsPage.php
@@ -6,7 +6,7 @@ use ScummVM\Models\ScreenshotsModel;
class ScreenshotsPage extends Controller
{
- private $screenshotsModel;
+ private ScreenshotsModel $screenshotsModel;
/* Constructor. */
public function __construct()
@@ -15,8 +15,12 @@ class ScreenshotsPage extends Controller
$this->screenshotsModel = new ScreenshotsModel();
}
- /* Display the index page. */
- public function index($args)
+ /**
+ * Display the index page.
+ *
+ * @param array{'category'?: string, 'game'?: string} $args
+ */
+ public function index(array $args): void
{
$category = $args['category'] ?? null;
$game = $args['game'] ?? null;
@@ -49,7 +53,7 @@ class ScreenshotsPage extends Controller
}
/* Display the selected category. */
- public function getCategory($category, $game)
+ public function getCategory(string $category, ?string $game): void
{
if (empty($game)) {
$screenshots = $this->screenshotsModel->getScreenshotsByCompanyId($category);
diff --git a/include/Pages/SimplePage.php b/include/Pages/SimplePage.php
index 582ab14b..23fde5e2 100644
--- a/include/Pages/SimplePage.php
+++ b/include/Pages/SimplePage.php
@@ -2,6 +2,7 @@
namespace ScummVM\Pages;
use ScummVM\Controller;
+use ScummVM\Models\BasicModel;
use ScummVM\Models\SimpleYamlModel;
class SimplePage extends Controller
@@ -14,11 +15,11 @@ class SimplePage extends Controller
'credits' => ['CreditsSection', 'credits.yaml'],
];
- private $model;
- private $key;
+ private SimpleYamlModel $model;
+ private string $key;
/* Constructor. */
- public function __construct($key)
+ public function __construct(string $key)
{
parent::__construct();
$this->template = "pages/$key.tpl";
@@ -34,7 +35,7 @@ class SimplePage extends Controller
}
/* Display the index page. */
- public function index($data = null)
+ public function index(mixed $data = null): void
{
if (isset($this->model)) {
$data = $this->model->getAllData();
diff --git a/include/Pages/StaticPage.php b/include/Pages/StaticPage.php
index 0eba0673..f5216fd4 100644
--- a/include/Pages/StaticPage.php
+++ b/include/Pages/StaticPage.php
@@ -6,9 +6,9 @@ use ScummVM\Controller;
class StaticPage extends Controller
{
const FILE_NOT_FOUND = 'The filename %s could not be found';
- private $filename;
+ private string $filename;
- public function __construct($key)
+ public function __construct(string $key)
{
parent::__construct();
@@ -19,7 +19,7 @@ class StaticPage extends Controller
}
/* Display the index page. */
- public function index($data = null)
+ public function index(): void
{
readfile($this->filename);
}
diff --git a/include/SiteUtils.php b/include/SiteUtils.php
index d726bc0a..b95b73fe 100644
--- a/include/SiteUtils.php
+++ b/include/SiteUtils.php
@@ -3,7 +3,7 @@ namespace ScummVM;
class SiteUtils
{
- public static function localizePath($path, $checkStaticFiles = false)
+ public static function localizePath(string $path, bool $checkStaticFiles = false): string
{
global $lang;
// No lang needed
Commit: d2e028140b432c14561ca7da96ec1276364ac78a
https://github.com/scummvm/scummvm-web/commit/d2e028140b432c14561ca7da96ec1276364ac78a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
BUILD: Check codestyle after fixing trivial errors
Also check index.php
Changed paths:
composer.json
diff --git a/composer.json b/composer.json
index 7a5cbc2c..3b8af907 100644
--- a/composer.json
+++ b/composer.json
@@ -57,7 +57,8 @@
"@start"
],
"lint": [
- "phpcbf --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include",
+ "phpcbf --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include public_html/index.php",
+ "phpcs --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include public_html/index.php",
"phpstan"
],
"update-data": [
Commit: 271f169928ddc83217b784209d14d9aeeb96e959
https://github.com/scummvm/scummvm-web/commit/271f169928ddc83217b784209d14d9aeeb96e959
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
BUILD: Increase PHPStan level
Changed paths:
phpstan.neon
diff --git a/phpstan.neon b/phpstan.neon
index 6e52cd2c..61af394b 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,5 +1,5 @@
parameters:
- level: 5
+ level: 6
treatPhpDocTypesAsCertain: false
bootstrapFiles:
- include/Constants.php
Commit: 710b95a5f41de6e5ed630dff181a04d9c633a42f
https://github.com/scummvm/scummvm-web/commit/710b95a5f41de6e5ed630dff181a04d9c633a42f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Better error handling
When PHP functions fail they often return false instead of the expected
object type.
CHeck for this value and fail properly.
Changed paths:
include/Controller.php
include/DataUtils.php
include/FileUtils.php
include/LocalizationUtils.php
include/Models/NewsModel.php
include/Models/ScreenshotsModel.php
include/OrmObjects/Screenshot.php
include/OrmObjects/ScreenshotQuery.php
include/Pages/ArticlePage.php
public_html/index.php
diff --git a/include/Controller.php b/include/Controller.php
index 308cd678..8b335a11 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -128,8 +128,12 @@ class Controller
public function dateLocalizedSmartyModifier(int $timestamp): string
{
global $lang;
- $formatter = datefmt_create($lang, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE);
- return $formatter->format($timestamp);
+ $formatter = new \IntlDateFormatter($lang, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE);
+ $ret = $formatter->format($timestamp);
+ if ($ret === false) {
+ $ret = '';
+ }
+ return $ret;
}
/**
diff --git a/include/DataUtils.php b/include/DataUtils.php
index 2b35d9ae..a9befb68 100644
--- a/include/DataUtils.php
+++ b/include/DataUtils.php
@@ -91,6 +91,9 @@ class DataUtils
// Convert to JSON because records are serializable
// and cannot be converted directly to yaml
$json = \json_encode($records);
+ if ($json === false) {
+ throw new \Exception("Can't encode data as JSON");
+ }
$data = \json_decode($json, true);
// Convert TRUE/FALSE strings to Booleans
diff --git a/include/FileUtils.php b/include/FileUtils.php
index eeab5c89..c555d0f0 100644
--- a/include/FileUtils.php
+++ b/include/FileUtils.php
@@ -82,13 +82,18 @@ class FileUtils
&& (@filemtime($path . '.sha256') > @filemtime($path))
) {
// Read the file and return the included hash
- return file_get_contents($path . '.sha256');
- } else {
- // Generate a SHA-256 hash, save it to a file for later, then return the hash
- $hash = hash_file('sha256', $path);
- file_put_contents($path . '.sha256', $hash);
- return $hash;
+ $contents = file_get_contents($path . '.sha256');
+ if ($contents !== false) {
+ return $contents;
+ }
}
+ // Generate a SHA-256 hash, save it to a file for later, then return the hash
+ $hash = hash_file('sha256', $path);
+ if ($hash === false) {
+ return '';
+ }
+ file_put_contents($path . '.sha256', $hash);
+ return $hash;
}
/**
@@ -100,8 +105,12 @@ class FileUtils
public static function getLastModified(string $path): string
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
+ $mtime = @filemtime($path);
+ if ($mtime === false) {
+ return '';
+ }
$date = new DateTime();
- return $date->setTimestamp(@filemtime($path))->format("Y-m-d");
+ return $date->setTimestamp($mtime)->format("Y-m-d");
}
/**
diff --git a/include/LocalizationUtils.php b/include/LocalizationUtils.php
index 20cc00ad..632c11c3 100644
--- a/include/LocalizationUtils.php
+++ b/include/LocalizationUtils.php
@@ -34,6 +34,9 @@ class LocalizationUtils
$filename = JOIN(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, "strings.json"]);
echo("Converting {$filename} from JSON to INI\n");
$jsonString = file_get_contents($filename);
+ if ($jsonString === false) {
+ throw new \Exception("Can't read file $filename");
+ }
$json = json_decode($jsonString);
$output = "";
@@ -55,12 +58,19 @@ class LocalizationUtils
return;
}
echo("Converting " . $newsFile . " to individual Markdown files\n");
- $l10n = json_decode(file_get_contents($newsFile));
+ $jsonString = file_get_contents($newsFile);
+ if ($jsonString === false) {
+ throw new \Exception("Can't read news JSON $newsFile");
+ }
+ $l10n = json_decode($jsonString);
foreach ($l10n as $key => $translatedArticle) {
- $englishArticle = YamlFrontMatter::parse(file_get_contents(
- join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news', "{$key}.markdown"])
- ));
+ $newsFile = join(DIRECTORY_SEPARATOR, [DIR_DATA, DEFAULT_LOCALE, 'news', "{$key}.markdown"]);
+ $englishContents = file_get_contents($newsFile);
+ if ($englishContents === false) {
+ throw new \Exception("Can't read news file $newsFile");
+ }
+ $englishArticle = YamlFrontMatter::parse($englishContents);
$date = self::$purifier->purify($englishArticle->date);
$author = self::$purifier->purify($englishArticle->author);
diff --git a/include/Models/NewsModel.php b/include/Models/NewsModel.php
index 7ea9947c..aac21131 100644
--- a/include/Models/NewsModel.php
+++ b/include/Models/NewsModel.php
@@ -54,10 +54,10 @@ class NewsModel extends BasicModel
if (!is_file(($fname = join(DIRECTORY_SEPARATOR, [DIR_DATA, $lang, 'news', basename($filename)])))
|| !is_readable($fname) || !($data = @file_get_contents($fname))
) {
- if (!($data = @file_get_contents(join(
+ if (($data = @file_get_contents(join(
DIRECTORY_SEPARATOR,
[DIR_DATA, DEFAULT_LOCALE, 'news', $filename]
- )))) {
+ ))) === false) {
continue;
}
}
@@ -100,6 +100,9 @@ class NewsModel extends BasicModel
}
$fname = $this->getLocalizedFile("news/$filename.markdown");
$data = @file_get_contents($fname);
+ if ($data === false) {
+ throw new \ErrorException(self::FILE_NOT_FOUND);
+ }
return new News($data, $fname, $processContent);
}
diff --git a/include/Models/ScreenshotsModel.php b/include/Models/ScreenshotsModel.php
index 8a207ff2..0a5a246a 100644
--- a/include/Models/ScreenshotsModel.php
+++ b/include/Models/ScreenshotsModel.php
@@ -162,8 +162,12 @@ class ScreenshotsModel extends BasicModel
$count = 0;
// Iterate over each game and count the number of screenshot files
foreach ($games as $game) {
- $count += count(glob(DIR_STATIC . DIR_SCREENSHOTS . '/' .
- str_replace(':', '/', $game->getId()) . '/*_full.png'));
+ $list = glob(DIR_STATIC . DIR_SCREENSHOTS . '/' .
+ str_replace(':', '/', $game->getId()) . '/*_full.png');
+ if ($list === false) {
+ continue;
+ }
+ $count += count($list);
}
return $count;
}
diff --git a/include/OrmObjects/Screenshot.php b/include/OrmObjects/Screenshot.php
index 942ce872..4d6f3aa4 100644
--- a/include/OrmObjects/Screenshot.php
+++ b/include/OrmObjects/Screenshot.php
@@ -28,7 +28,11 @@ class Screenshot extends BaseScreenshot
if (!isset($this->files)) {
$this->files = [];
$gameId = str_replace(':', '/', $this->getGame()->getId());
- foreach (glob(DIR_STATIC . DIR_SCREENSHOTS . '/' . $gameId . '/' . $this->getFileMask()) as $file) {
+ $screenshots = glob(DIR_STATIC . DIR_SCREENSHOTS . '/' . $gameId . '/' . $this->getFileMask());
+ if ($screenshots === false) {
+ $screenshots = array();
+ }
+ foreach ($screenshots as $file) {
// Remove the base folder
$name = str_replace(DIR_STATIC . DIR_SCREENSHOTS . '/', '', $file);
// Remove the suffix, eg. "_full.png"
diff --git a/include/OrmObjects/ScreenshotQuery.php b/include/OrmObjects/ScreenshotQuery.php
index 62818696..463e978f 100644
--- a/include/OrmObjects/ScreenshotQuery.php
+++ b/include/OrmObjects/ScreenshotQuery.php
@@ -31,6 +31,7 @@ class ScreenshotQuery extends BaseScreenshotQuery
FROM screenshot ORDER BY RANDOM() LIMIT 1";
try {
$stmt = $con->prepare($sql);
+ \assert($stmt !== false);
$stmt->execute();
} catch (\Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
@@ -92,6 +93,7 @@ class ScreenshotQuery extends BaseScreenshotQuery
subcategory_name";
try {
$stmt = $con->prepare($sql);
+ \assert($stmt !== false);
$stmt->execute();
} catch (\Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
diff --git a/include/Pages/ArticlePage.php b/include/Pages/ArticlePage.php
index 9ee5d349..b766e39d 100644
--- a/include/Pages/ArticlePage.php
+++ b/include/Pages/ArticlePage.php
@@ -34,7 +34,11 @@ class ArticlePage extends Controller
throw new \ErrorException(\sprintf(self::FILE_NOT_FOUND, $filename));
}
- return YamlFrontMatter::parse(file_get_contents($fname));
+ $article = @file_get_contents($fname);
+ if ($article === false) {
+ throw new \ErrorException(\sprintf(self::FILE_NOT_FOUND, $filename));
+ }
+ return YamlFrontMatter::parse($article);
}
/**
diff --git a/public_html/index.php b/public_html/index.php
index 5099ad26..800b3358 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -146,7 +146,7 @@ foreach ($pages as $key => $value) {
$match = $router->match(strtolower($_SERVER['REQUEST_URI']));
-if (!$match) {
+if ($match === false) {
$page = new \ScummVM\Pages\NewsPage();
$page->index(array());
return;
Commit: 7b0a2033dea421aa40152640bfb083f77744075b
https://github.com/scummvm/scummvm-web/commit/7b0a2033dea421aa40152640bfb083f77744075b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Gracefully handle cases when there are no extension in files
Changed paths:
include/FileUtils.php
diff --git a/include/FileUtils.php b/include/FileUtils.php
index c555d0f0..30fe5b82 100644
--- a/include/FileUtils.php
+++ b/include/FileUtils.php
@@ -59,11 +59,16 @@ class FileUtils
{
$path = FileUtils::toAbsolutePathIfOnServer($path);
// Get everything to the right of the last period
- $extension = substr($path, (strrpos($path, '.')));
+ if (($pos = strrpos($path, '.')) !== false) {
+ $extension = substr($path, (strrpos($path, '.')));
+ } else {
+ $extension = '';
+ }
// For certain extensions, check for another extension (e.g. foo.tar.gz => tar.gz)
- if (in_array($extension, self::DOUBLE_EXTENSIONS)) {
- $extension = substr($path, strrpos($path, '.', -(strlen($path) - strrpos($path, '.') + 1)));
+ if (in_array($extension, self::DOUBLE_EXTENSIONS) &&
+ ($pos = strrpos($path, '.', -(strlen($path) - $pos + 1))) !== false) {
+ $extension = substr($path, $pos);
}
return $extension;
}
Commit: a1afb8a64d3d5f72623cb2656a6f4153866f8007
https://github.com/scummvm/scummvm-web/commit/a1afb8a64d3d5f72623cb2656a6f4153866f8007
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Handle cases when WebLink are mixed with Files
Also make hasOldVersion static as it doesn't need access to the
instance.
Changed paths:
include/Objects/DownloadsSection.php
diff --git a/include/Objects/DownloadsSection.php b/include/Objects/DownloadsSection.php
index 038b81e4..4516296a 100644
--- a/include/Objects/DownloadsSection.php
+++ b/include/Objects/DownloadsSection.php
@@ -33,8 +33,19 @@ class DownloadsSection extends BasicSection
if ($item->getCategoryIcon()) {
$this->items[] = new File($item->toArray(TableMap::TYPE_FIELDNAME));
// If this item is for an old version, sort all items by version, descending, then by autoId
- if ($this->hasOldVersion($item)) {
+ if (self::hasOldVersion($item)) {
usort($this->items, function ($a, $b) {
+ $aFile = $a instanceof File;
+ $bFile = $b instanceof File;
+
+ if (!$aFile && !$bFile) {
+ return strcmp($a->getURL(), $b->getURL());
+ } elseif (!$aFile) {
+ return 1;
+ } elseif (!$bFile) {
+ return -1;
+ }
+
// Return 0 if equal, -1 if $a->getVersion() is larger, 1 if $b->getVersion() is larger
$versionSortResult = -version_compare($a->getVersion(), $b->getVersion());
if ($versionSortResult == 0) {
@@ -79,7 +90,7 @@ class DownloadsSection extends BasicSection
/**
* @param Download|GameDownload $item
*/
- private function hasOldVersion(object $item): bool
+ private static function hasOldVersion(object $item): bool
{
return method_exists($item, 'getVersion') && $item->getVersion() !== RELEASE && $item->getVersion() !== 'Daily';
}
Commit: e2f72c8d8b25b5edeb8b9a3506cd6aada451ac39
https://github.com/scummvm/scummvm-web/commit/e2f72c8d8b25b5edeb8b9a3506cd6aada451ac39
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Modify all extra attributes at once
This makes PHPStan happy (because the array type is expected to be
either empty or full).
Changed paths:
include/Objects/File.php
diff --git a/include/Objects/File.php b/include/Objects/File.php
index a77086b4..677d83a3 100644
--- a/include/Objects/File.php
+++ b/include/Objects/File.php
@@ -60,10 +60,12 @@ class File extends BasicObject
$fname = str_replace('{$version}', "$this->version", $fname);
if (FileUtils::exists($fname)) {
- $this->extra_info['size'] = FileUtils::getFileSize($fname);
- $this->extra_info['sha256'] = FileUtils::getSha256($fname);
- $this->extra_info['ext'] = FileUtils::getExtension($fname);
- $this->extra_info['date'] = FileUtils::getLastModified($fname);
+ $extra_info = [];
+ $extra_info['size'] = FileUtils::getFileSize($fname);
+ $extra_info['sha256'] = FileUtils::getSha256($fname);
+ $extra_info['ext'] = FileUtils::getExtension($fname);
+ $extra_info['date'] = FileUtils::getLastModified($fname);
+ $this->extra_info = $extra_info;
}
$this->url = $fname;
}
Commit: d74cb92ec2c6ea6bc1e43875462c78280ea023f5
https://github.com/scummvm/scummvm-web/commit/d74cb92ec2c6ea6bc1e43875462c78280ea023f5
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Make sure the Page object provides an index function
Changed paths:
public_html/index.php
diff --git a/public_html/index.php b/public_html/index.php
index 800b3358..1a4ff68b 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -160,4 +160,6 @@ if ($match['target'] === '\ScummVM\Pages\SimplePage' || $match['target'] === '\S
} else {
$page = new $match['target']();
}
+
+assert(method_exists($page, 'index'));
$page->index($match['params']);
Commit: 9a594545250715b54929c445947d5b7488c2888a
https://github.com/scummvm/scummvm-web/commit/9a594545250715b54929c445947d5b7488c2888a
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
BUILD: Increase PHPStan level
The AltoRouter::match function has a bad signature: fix it using a stub.
Changed paths:
A stubs/altorouter.stub
composer.json
include/Models/CompatibilityModel.php
include/Objects/DownloadsSection.php
include/OrmObjects/ScreenshotQuery.php
phpstan.neon
diff --git a/composer.json b/composer.json
index 3b8af907..41df5fcd 100644
--- a/composer.json
+++ b/composer.json
@@ -57,8 +57,8 @@
"@start"
],
"lint": [
- "phpcbf --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include public_html/index.php",
- "phpcs --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include public_html/index.php",
+ "phpcbf --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include ./stubs public_html/index.php",
+ "phpcs --standard=psr2 --ignore=./include/OrmObjects/Base,./include/OrmObjects/Map ./include ./stubs public_html/index.php",
"phpstan"
],
"update-data": [
diff --git a/include/Models/CompatibilityModel.php b/include/Models/CompatibilityModel.php
index 16165d3d..dc61d41f 100644
--- a/include/Models/CompatibilityModel.php
+++ b/include/Models/CompatibilityModel.php
@@ -34,6 +34,7 @@ class CompatibilityModel extends BasicModel
}
$cachekey = $version;
$version = \explode('.', $version);
+ /** @phpstan-ignore method.notFound */
$data = CompatibilityQuery::create()
->withColumn("max(release_date)")
->groupById()
diff --git a/include/Objects/DownloadsSection.php b/include/Objects/DownloadsSection.php
index 4516296a..c9ffb764 100644
--- a/include/Objects/DownloadsSection.php
+++ b/include/Objects/DownloadsSection.php
@@ -31,6 +31,7 @@ class DownloadsSection extends BasicSection
public function addItem(object $item): void
{
if ($item->getCategoryIcon()) {
+ /** @phpstan-ignore argument.type */
$this->items[] = new File($item->toArray(TableMap::TYPE_FIELDNAME));
// If this item is for an old version, sort all items by version, descending, then by autoId
if (self::hasOldVersion($item)) {
@@ -57,6 +58,7 @@ class DownloadsSection extends BasicSection
});
}
} else {
+ /** @phpstan-ignore argument.type */
$this->items[] = new WebLink($item->toArray(TableMap::TYPE_FIELDNAME));
}
}
diff --git a/include/OrmObjects/ScreenshotQuery.php b/include/OrmObjects/ScreenshotQuery.php
index 463e978f..18025909 100644
--- a/include/OrmObjects/ScreenshotQuery.php
+++ b/include/OrmObjects/ScreenshotQuery.php
@@ -108,6 +108,7 @@ class ScreenshotQuery extends BaseScreenshotQuery
public function filterByCompanyId(string $companyId, ConnectionInterface $con = null): self
{
if ($companyId !== 'other') {
+ /** @phpstan-ignore return.type */
return $this->useGameQuery()
->filterByCompanyId($companyId)
->endUse();
diff --git a/phpstan.neon b/phpstan.neon
index 61af394b..8e67eaa3 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,6 +1,8 @@
parameters:
- level: 6
+ level: 7
treatPhpDocTypesAsCertain: false
+ stubFiles:
+ - stubs/altorouter.stub
bootstrapFiles:
- include/Constants.php
paths:
diff --git a/stubs/altorouter.stub b/stubs/altorouter.stub
new file mode 100644
index 00000000..ea43ecc9
--- /dev/null
+++ b/stubs/altorouter.stub
@@ -0,0 +1,12 @@
+<?php
+
+class AltoRouter
+{
+
+ /**
+ * @param string $requestUrl
+ * @param string $requestMethod
+ * @return array{'target': mixed, 'params': string[], 'name': ?string}|false
+ */
+ public function match(?string $requestUrl = null, ?string $requestMethod = null);
+}
Commit: 93d3aa56a1e0824db219707c2cc2fe4e902e4f1b
https://github.com/scummvm/scummvm-web/commit/93d3aa56a1e0824db219707c2cc2fe4e902e4f1b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Handle null cases
Sometimes variables may be null. Handle the cases when passing to
functions expecting something non-null.
Changed paths:
include/Controller.php
include/LocalizationUtils.php
include/Models/DownloadsModel.php
include/Models/GameDownloadsModel.php
include/Objects/DownloadsSection.php
include/Objects/News.php
include/OrmObjects/Compatibility.php
include/Pages/CompatibilityPage.php
include/Pages/DownloadsPage.php
include/Pages/GamesPage.php
public_html/index.php
diff --git a/include/Controller.php b/include/Controller.php
index 8b335a11..043c0b55 100644
--- a/include/Controller.php
+++ b/include/Controller.php
@@ -118,6 +118,7 @@ class Controller
{
/* Properly encode all ampersands as "&". */
$string = preg_replace('/&(?!([a-z]+|(#\d+));)/i', '&', $string);
+ assert($string !== null);
/* Replace weird characters that appears in some of the data. */
return $string;
}
@@ -158,7 +159,9 @@ class Controller
public function releaseSmartyModifier(string $string): string
{
$string = preg_replace("/\{[$]?release\}/", RELEASE, $string);
+ assert($string !== null);
$string = preg_replace("/\{[$]?release_tools\}/", RELEASE_TOOLS, $string);
+ assert($string !== null);
return $string;
}
diff --git a/include/LocalizationUtils.php b/include/LocalizationUtils.php
index 632c11c3..45e46a06 100644
--- a/include/LocalizationUtils.php
+++ b/include/LocalizationUtils.php
@@ -90,7 +90,9 @@ class LocalizationUtils
$content = preg_replace_callback(
"/(?<=\(http)(.*?)(?=\))/u",
function (array $matches): string {
- return preg_replace("/\x{202f}/u", "", $matches[1]);
+ $ret = preg_replace("/\x{202f}/u", "", $matches[1]);
+ assert($ret !== null);
+ return $ret;
},
$content
);
diff --git a/include/Models/DownloadsModel.php b/include/Models/DownloadsModel.php
index 5ae2b420..cd33c485 100644
--- a/include/Models/DownloadsModel.php
+++ b/include/Models/DownloadsModel.php
@@ -53,7 +53,7 @@ class DownloadsModel extends BasicModel
$sections[$category] = new DownloadsSection([
'anchor' => $category,
'title' => $sectionsData[$category]['title'],
- 'notes' => $sectionsData[$category]['notes'] ?? null
+ 'notes' => $sectionsData[$category]['notes'] ?? ''
]);
}
@@ -62,7 +62,7 @@ class DownloadsModel extends BasicModel
$sections[$category]->addSubsection(new DownloadsSection([
'anchor' => $subCategory,
'title' => $sectionsData[$subCategory]['title'],
- 'notes' => $sectionsData[$subCategory]['notes'] ?? null
+ 'notes' => $sectionsData[$subCategory]['notes'] ?? ''
]));
}
@@ -115,6 +115,8 @@ class DownloadsModel extends BasicModel
$osParser = new OsParser();
$osParser->setUserAgent($_SERVER['HTTP_USER_AGENT']);
$os = $osParser->parse();
+ // Should never happen: the DeviceDetector signature seems wrong
+ assert($os !== null);
$downloads = DownloadQuery::create()
->setIgnoreCase(true)
diff --git a/include/Models/GameDownloadsModel.php b/include/Models/GameDownloadsModel.php
index 66fb72f7..ba857efb 100644
--- a/include/Models/GameDownloadsModel.php
+++ b/include/Models/GameDownloadsModel.php
@@ -29,8 +29,8 @@ class GameDownloadsModel extends BasicModel
foreach ($categories as $category) {
$sections[$category] = new DownloadsSection([
'anchor' => $category,
- 'title' => $sectionsData[$category]['title'] ?? null,
- 'notes' => $sectionsData[$category]['notes'] ?? null
+ 'title' => $sectionsData[$category]['title'] ?? '',
+ 'notes' => $sectionsData[$category]['notes'] ?? ''
]);
}
@@ -48,7 +48,7 @@ class GameDownloadsModel extends BasicModel
$sections[$category]->addSubsection(new DownloadsSection([
'anchor' => $gameId,
'title' => $gameName,
- 'notes' => $sectionsData[$gameId]['notes'] ?? null
+ 'notes' => $sectionsData[$gameId]['notes'] ?? ''
]));
}
diff --git a/include/Objects/DownloadsSection.php b/include/Objects/DownloadsSection.php
index c9ffb764..dc295ce4 100644
--- a/include/Objects/DownloadsSection.php
+++ b/include/Objects/DownloadsSection.php
@@ -48,7 +48,7 @@ class DownloadsSection extends BasicSection
}
// Return 0 if equal, -1 if $a->getVersion() is larger, 1 if $b->getVersion() is larger
- $versionSortResult = -version_compare($a->getVersion(), $b->getVersion());
+ $versionSortResult = -version_compare($a->getVersion() ?? '', $b->getVersion() ?? '');
if ($versionSortResult == 0) {
// Return 0 if equal, -1 if $a->getAutoId() is smaller, 1 if $b->getAutoId() is smaller
return $a->getAutoId() <=> $b->getAutoId();
diff --git a/include/Objects/News.php b/include/Objects/News.php
index 65b28205..ccd68785 100644
--- a/include/Objects/News.php
+++ b/include/Objects/News.php
@@ -66,6 +66,7 @@ class News
return substr_replace($full, $lurl, $urlOffset, strlen($url));
}, $body, flags: PREG_OFFSET_CAPTURE);
+ assert($body !== null);
return $body;
}
diff --git a/include/OrmObjects/Compatibility.php b/include/OrmObjects/Compatibility.php
index 4cb991e7..9f670f06 100644
--- a/include/OrmObjects/Compatibility.php
+++ b/include/OrmObjects/Compatibility.php
@@ -56,7 +56,7 @@ class Compatibility extends BaseCompatibility
if ($this->notes) {
$notes .= "### Additional Notes\n";
- $notes .= str_replace("- ", "\n- ", parent::getNotes()) . "\n";
+ $notes .= str_replace("- ", "\n- ", parent::getNotes() ?? '') . "\n";
}
$links = [];
diff --git a/include/Pages/CompatibilityPage.php b/include/Pages/CompatibilityPage.php
index d5de41ed..dc196684 100644
--- a/include/Pages/CompatibilityPage.php
+++ b/include/Pages/CompatibilityPage.php
@@ -73,7 +73,7 @@ class CompatibilityPage extends Controller
->find()->toArray();
/* Default to DEV */
- if (!in_array($version, $versions)) {
+ if (empty($version) || !in_array($version, $versions)) {
$version = 'DEV';
}
@@ -99,13 +99,13 @@ class CompatibilityPage extends Controller
$this->renderPage(
array(
- 'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle')),
+ 'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle') ?? ''),
'subtitle' => $game->getGame()->getName(),
'description' => $this->supportLevelDescriptions[$game->getSupport()],
'content_title' => preg_replace(
'/{version}/',
$version,
- $this->getConfigVars('compatibilityContentTitle')
+ $this->getConfigVars('compatibilityContentTitle') ?? ''
),
'version' => $version,
'game' => $game,
@@ -130,12 +130,12 @@ class CompatibilityPage extends Controller
$this->renderPage(
[
- 'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle')),
+ 'title' => preg_replace('/{version}/', $version, $this->getConfigVars('compatibilityTitle') ?? ''),
'description' => $this->getConfigVars('compatibilityIntro'),
'content_title' => preg_replace(
'/{version}/',
$version,
- $this->getConfigVars('compatibilityContentTitle')
+ $this->getConfigVars('compatibilityContentTitle') ?? ''
),
'version' => $version,
'compat_data' => $compat_data,
diff --git a/include/Pages/DownloadsPage.php b/include/Pages/DownloadsPage.php
index 6c864a4c..a5ee54e3 100644
--- a/include/Pages/DownloadsPage.php
+++ b/include/Pages/DownloadsPage.php
@@ -23,7 +23,7 @@ class DownloadsPage extends Controller
$this->renderPage(
array(
'title' => $this->getConfigVars('downloadsTitle'),
- 'description' => \strip_tags($this->getConfigVars('downloadsContentP1')),
+ 'description' => \strip_tags($this->getConfigVars('downloadsContentP1') ?? ''),
'content_title' => $this->getConfigVars('downloadsContentTitle'),
'downloads' => $downloads,
'recommendedDownload' => $recommendedDownload
diff --git a/include/Pages/GamesPage.php b/include/Pages/GamesPage.php
index ebf4aed3..88d546ed 100644
--- a/include/Pages/GamesPage.php
+++ b/include/Pages/GamesPage.php
@@ -23,7 +23,7 @@ class GamesPage extends Controller
$this->renderPage(
array(
'title' => $this->getConfigVars('gamesTitle'),
- 'description' => strip_tags($this->getConfigVars('gamesContentP1')),
+ 'description' => strip_tags($this->getConfigVars('gamesContentP1') ?? ''),
'content_title' => $this->getConfigVars('gamesContentTitle'),
'downloads' => $downloads,
)
diff --git a/public_html/index.php b/public_html/index.php
index 1a4ff68b..82097ed0 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -153,6 +153,7 @@ if ($match === false) {
}
if ($match['target'] === '\ScummVM\Pages\SimplePage' || $match['target'] === '\ScummVM\Pages\StaticPage') {
+ assert($match['name'] !== null);
$page = new $match['target']($match['name']);
} elseif (strpos($match['target'], "http") === 0) {
header("Location: {$match['target']}");
Commit: f28c5198f4b774e9faaaf02772d6b74fa0b314af
https://github.com/scummvm/scummvm-web/commit/f28c5198f4b774e9faaaf02772d6b74fa0b314af
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Avoid returning null when there is no screenshot
Instead, return an empty screenshot object.
Changed paths:
include/OrmObjects/Screenshot.php
include/OrmObjects/ScreenshotQuery.php
diff --git a/include/OrmObjects/Screenshot.php b/include/OrmObjects/Screenshot.php
index 4d6f3aa4..a02d915b 100644
--- a/include/OrmObjects/Screenshot.php
+++ b/include/OrmObjects/Screenshot.php
@@ -27,6 +27,11 @@ class Screenshot extends BaseScreenshot
{
if (!isset($this->files)) {
$this->files = [];
+
+ if ($this->isNew()) {
+ return $this->files;
+ }
+
$gameId = str_replace(':', '/', $this->getGame()->getId());
$screenshots = glob(DIR_STATIC . DIR_SCREENSHOTS . '/' . $gameId . '/' . $this->getFileMask());
if ($screenshots === false) {
diff --git a/include/OrmObjects/ScreenshotQuery.php b/include/OrmObjects/ScreenshotQuery.php
index 18025909..99f513a2 100644
--- a/include/OrmObjects/ScreenshotQuery.php
+++ b/include/OrmObjects/ScreenshotQuery.php
@@ -37,10 +37,9 @@ class ScreenshotQuery extends BaseScreenshotQuery
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e);
}
- $obj = null;
+ $obj = new ChildScreenshot();
if ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
/** @var ChildScreenshot $obj */
- $obj = new ChildScreenshot();
$obj->hydrate($row);
ScreenshotTableMap::addInstanceToPool($obj, null);
}
Commit: a04dab5f7ec5b6bbea70ac075c097f48dd8e3ea1
https://github.com/scummvm/scummvm-web/commit/a04dab5f7ec5b6bbea70ac075c097f48dd8e3ea1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
BUILD: Increase PHPStan level
Changed paths:
phpstan.neon
diff --git a/phpstan.neon b/phpstan.neon
index 8e67eaa3..9f2a8423 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,5 +1,5 @@
parameters:
- level: 7
+ level: 8
treatPhpDocTypesAsCertain: false
stubFiles:
- stubs/altorouter.stub
Commit: 7f6baf107a6a991318a77e5235fea4cab6af6959
https://github.com/scummvm/scummvm-web/commit/7f6baf107a6a991318a77e5235fea4cab6af6959
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
BUILD: Add license in composer
Changed paths:
composer.json
diff --git a/composer.json b/composer.json
index 41df5fcd..99d578d0 100644
--- a/composer.json
+++ b/composer.json
@@ -8,6 +8,7 @@
"email": "mataniko at scummvm.org"
}
],
+ "license": "GPL-3.0-or-later",
"require": {
"php": ">=8.2.0",
"ext-intl": "*",
Commit: d76478f1e6f1f22e69bed53d0c57b67208e18938
https://github.com/scummvm/scummvm-web/commit/d76478f1e6f1f22e69bed53d0c57b67208e18938
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-08-24T12:32:47+02:00
Commit Message:
WEB: Add a Github Actions CI check
Changed paths:
A .github/workflows/ci.yml
composer.json
package.json
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..6709a0e8
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,36 @@
+name: Web CI
+on: [push, pull_request]
+permissions:
+ contents: read
+jobs:
+ build:
+ name: Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install glue
+ # Patch Glue to let it run on modern OS
+ run: |
+ sudo apt install -y glue-sprite && \
+ sudo ln -s glue-sprite /usr/bin/glue && \
+ sudo sed -i -e 's/PILImage\.ANTIALIAS/PILImage.LANCZOS/' /usr/lib/python3/dist-packages/glue/formats/img.py && \
+ sudo sed -i -e 's/re\.compile(/re.compile(r/' /usr/lib/python3/dist-packages/glue/core.py && \
+ sudo sed -i -e 's/PImage\.VERSION/PImage.__version__/' /usr/lib/python3/dist-packages/glue/bin.py
+ - uses: actions/checkout at v4
+ - name: Validate composer.json and composer.lock
+ run: composer validate --strict
+ - name: Setup
+ uses: actions/setup-node at v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Cache Composer packages
+ id: packages-cache
+ uses: actions/cache at v4
+ with:
+ path: "vendor\nnode_modules\ndumper-companion/node_modules"
+ key: ${{ runner.os }}-phpjs-${{ hashFiles('**/composer.lock', '**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-phpjs-
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+ - name: Run CI checks
+ run: composer run-script ci
diff --git a/composer.json b/composer.json
index 99d578d0..a9b59801 100644
--- a/composer.json
+++ b/composer.json
@@ -49,6 +49,13 @@
"@build-common",
"npm install"
],
+ "ci": [
+ "composer install",
+ "@build-common",
+ "@lint",
+ "npm ci",
+ "npm run lint"
+ ],
"start": [
"Composer\\Config::disableProcessTimeout",
"php -S localhost:8000 -t ./public_html ./public_html/index.php"
diff --git a/package.json b/package.json
index 4cbcf8ce..34117d60 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
},
"scripts": {
"postinstall": "(cd dumper-companion && npm ci --omit=dev && npm run build) && node build.js",
- "scss:watch": "sass --watch ./scss:./public_html/css"
+ "scss:watch": "sass --watch ./scss:./public_html/css",
+ "lint": "(cd dumper-companion && npm ci && npm run lint)"
}
}
More information about the Scummvm-git-logs
mailing list