[PHP-WEBMASTER] [web-php] redesign-downloads-page-prototype: Should work with disabled js

Author: Sergey Panteleev (saundefined)
Date: 2025-07-03T13:24:24+03:00

Commit: Should work with disabled js · php/web-php@ba53c4e · GitHub
Raw diff: https://github.com/php/web-php/commit/ba53c4eb10fbcd750c91b99def65ab9d20615cd3.diff

Should work with disabled js

Changed paths:
  D js/version-choice.js
  M downloads-get-instructions.php
  M downloads.php

Diff:

diff --git a/downloads-get-instructions.php b/downloads-get-instructions.php
index ac232001ed..e8149d3196 100644
--- a/downloads-get-instructions.php
+++ b/downloads-get-instructions.php
@@ -1,11 +1,11 @@
<?php
-if ($_GET['os'] === 'windows' && $_GET['osvariant'] === 'windows-wsl') {
- $_GET['os'] = 'linux';
- $_GET['osvariant'] = 'linux-deb-bookworm';
- $_GET['multiversion'] = 'true';
+if ($options['os'] === 'windows' && $options['osvariant'] === 'windows-wsl') {
+ $options['os'] = 'linux';
+ $options['osvariant'] = 'linux-deb-bookworm';
+ $options['multiversion'] = 'true';
}
-if ($_GET['os'] === 'osx') {
- $version = match($_GET['version']) {
+if ($options['os'] === 'osx') {
+ $version = match($options['version']) {
         'php84' => '@8.4',
         'php83' => '@8.3',
         'php82' => '@8.2',
@@ -13,7 +13,7 @@
         default => ''
     };

- $versionDir = match($_GET['version']) {
+ $versionDir = match($options['version']) {
         'php84' => '8.4',
         'php83' => '8.3',
         'php82' => '8.2',
@@ -56,8 +56,8 @@
}
?>
<?php
-if ($_GET['os'] === 'linux' && str_starts_with($_GET['osvariant'], 'linux-deb')) {
- if ($_GET['version'] === 'default' && $_GET['multiversion'] != 'true') {
+if ($options['os'] === 'linux' && str_starts_with($options['osvariant'], 'linux-deb')) {
+ if ($options['version'] === 'default' && $options['multiversion'] != 'true') {
     echo <<<ENDAPT
<p>
     On the command line shell, enter:
@@ -68,7 +68,7 @@
</pre></div>
ENDAPT;
     } else {
- $version = match($_GET['version']) {
+ $version = match($options['version']) {
             'php84' => '8.4',
             'php83' => '8.3',
             'php82' => '8.2',
@@ -94,4 +94,4 @@
There are no instructions yet.
</p>

-<?php var_dump($_GET); ?>
+<?php var_dump($options); ?>
diff --git a/downloads.php b/downloads.php
index 241644b9e6..6b8d3f46e8 100644
--- a/downloads.php
+++ b/downloads.php
@@ -35,82 +35,116 @@
             ],
         ],
         "current" => "downloads",
- "js_files" => [
- "/js/version-choice.js",
- ],
     ],
);

-function option(string $id, string $value, string $desc)
+function option(string $value, string $desc, $attributes = ): string
{
- $selected = '';
- if (array_key_exists($id, $_GET) && $_GET[$id] === $value) {
- $selected = ' selected';
- }
+ return '<option value="' . $value . '"' . implode(' ', array_keys(array_filter($attributes))) . '>' . $desc . '</option>';
+}

- echo <<<ENDOPT
- <option value="{$value}"{$selected}>{$desc}</option>
+$usage = [
+ 'web' => 'Web Development',
+ 'cli' => 'Command Line Libraries',
+ 'fw-drupal' => 'Drupal',
+ 'fw-laravel' => 'Laravel',
+ 'fw-symfony' => 'Symfony',
+];
+
+$os = [
+ 'linux' => [
+ 'name' => 'Linux',
+ 'variants' => [
+ 'linux-deb-buster' => 'Debian Buster',
+ 'linux-deb-bullseye' => 'Debian Bullseye',
+ 'linux-deb-bookworm' => 'Debian Bookworm',
+ 'linux-rpm-fedora41' => 'Fedora 41',
+ 'linux-rpm-fedora42' => 'Fedora 42',
+ 'linux-rpm-redhat' => 'RedHat',
+ ],
+ ],
+ 'osx' => [
+ 'name' => 'macOS',
+ 'variants' => [
+ 'osx-latest' => 'macOS Latest',
+ ],
+ ],
+ 'windows' => [
+ 'name' => 'Windows',
+ 'variants' => [
+ 'windows-wsl' => 'Windows with WSL',
+ 'windows-normal' => 'Windows without WSL',
+ ],
+ ],
+];
+
+$defaults = [
+ 'os' => 'linux',
+ 'version' => 'php84',
+ 'usage' => 'web',
+];

-ENDOPT;
+$options = array_merge($defaults, $_GET);
+if (!array_key_exists('osvariant', $options) || !array_key_exists($options['osvariant'], $os[$options['os']]['variants'])) {
+ $options['osvariant'] = array_key_first($os[$options['os']]['variants']);
}
?>
<h1>Downloads &amp; Installation Instructions</h1>

-<form class="instructions-form">
+ <form class="instructions-form" id="instructions-form">
     <div class="instructions-row">
         I want to use PHP for
         <select id="usage" name="usage">
- <?= option('usage', 'web', 'Web Development'); ?>
- <?= option('usage', 'cli', 'Command Line Libraries'); ?>
- <?= option('usage', 'fw-drupal', 'Drupal'); ?>
- <?= option('usage', 'fw-laravel', 'Laravel'); ?>
- <?= option('usage', 'fw-symfony', 'Symfony'); ?>
+ <?php foreach ($usage as $value => $description) { ?>
+ <?= option($value, $description); ?>
+ <?php } ?>
         </select>.
     </div>

     <div class="instructions-row">
         I work with
         <select id="os" name="os">
- <?= option('os', 'linux', 'Linux'); ?>
- <?= option('os', 'osx', 'OSX'); ?>
- <?= option('os', 'windows', 'Windows'); ?>
+ <?php foreach ($os as $value => $item) { ?>
+ <?= option($value, $item['name'], [
+ 'selected' => array_key_exists('os', $options) && $options['os'] === $value,
+ ]); ?>
+ <?php } ?>
         </select>
- <select id="osvariant" name="osvariant">
- <?= option('osvariant', 'linux-deb-buster', 'Debian Buster'); ?>
- <?= option('osvariant', 'linux-deb-bullseye', 'Debian Bullseye'); ?>
- <?= option('osvariant', 'linux-deb-bookworm', 'Debian Bookworm'); ?>
- <?= option('osvariant', 'linux-rpm-fedora41', 'Fedora 41'); ?>
- <?= option('osvariant', 'linux-rpm-fedora42', 'Fedora 42'); ?>
- <?= option('osvariant', 'linux-rpm-redhat', 'RedHat'); ?>
- <?= option('osvariant', 'osx-latest', 'Latest'); ?>
- <?= option('osvariant', 'windows-wsl', 'with WSL'); ?>
- <?= option('osvariant', 'windows-normal', 'without WSL'); ?>
- </select>,
+
+ <?php if (array_key_exists('os', $options) && array_key_exists('osvariant', $options)) { ?>
+ <select id="osvariant" name="osvariant">
+ <?php foreach ($os[$options['os']]['variants'] as $value => $description) { ?>
+ <?= option($value, $description, [
+ 'selected' => $options['osvariant'] === $value,
+ ]); ?>
+ <?php } ?>
+ </select>
+ <?php } ?>,
         and use
         <select id="version" name="version">
- <?= option('version', 'php84', 'version 8.4'); ?>
- <?= option('version', 'php83', 'version 8.3'); ?>
- <?= option('version', 'php82', 'version 8.2'); ?>
- <?= option('version', 'php81', 'version 8.1'); ?>
- <?= option('version', 'default', 'OS default version'); ?>
+ <?= option('php84', 'version 8.4'); ?>
+ <?= option('php83', 'version 8.3'); ?>
+ <?= option('php82', 'version 8.2'); ?>
+ <?= option('php81', 'version 8.1'); ?>
+ <?= option('default', 'OS default version'); ?>
         </select>
     </div>

     <label for="multiversion" class="instructions-label">
         I want to be able to use multiple PHP versions:
         <input type="checkbox" id="multiversion" name="multiversion" value="Y"
- <?= array_key_exists('multiversion', $_GET) && $_GET['multiversion'] === 'Y' ? 'checked' : '' ?>/>
+ <?= array_key_exists('multiversion', $options) && $options['multiversion'] === 'Y' ? 'checked' : '' ?>/>
     </label>

     <label for="source" class="instructions-label">
         I want to compile everything from source:
         <input type="checkbox" id="source" name="source" value="Y"
- <?= array_key_exists('source', $_GET) && $_GET['source'] === 'Y' ? 'checked' : '' ?>/>
+ <?= array_key_exists('source', $options) && $options['source'] === 'Y' ? 'checked' : '' ?>/>
     </label>

- <div>
- <button type="submit" class="button">Get Instructions</button>
- </div>
+ <noscript>
+ <button type="submit" class="button">Update Instructions</button>
+ </noscript>
</form>

<h2>Instructions</h2>
@@ -156,5 +190,15 @@ function option(string $id, string $value, string $desc)
   </a>
</p>

+ <script>
+ window.onload = function () {
+ let form = document.getElementById("instructions-form")
+
+ form.addEventListener('change', function () {
+ form.submit();
+ });
+ }
+ </script>
+
<?php
site_footer(['sidebar' => $SIDEBAR_DATA]);
diff --git a/js/version-choice.js b/js/version-choice.js
deleted file mode 100644
index 142a4065b4..0000000000
--- a/js/version-choice.js
+++ /dev/null
@@ -1,60 +0,0 @@
-function setSelectBoxes() {
- let instructionsDiv = document.getElementById("instructions")
- let osSelector = document.getElementById("os")
- let variantSelector = document.getElementById("osvariant")
- let usageSelector = document.getElementById("usage")
- let versionSelector = document.getElementById("version")
- let multiversionBox = document.getElementById("multiversion")
-
- const url = '/downloads-get-instructions.php' +
- '?os=' + osSelector.options[osSelector.selectedIndex].value +
- '&osvariant=' + variantSelector.options[variantSelector.selectedIndex].value +
- '&usage=' + usageSelector.options[usageSelector.selectedIndex].value +
- '&version=' + versionSelector.options[versionSelector.selectedIndex].value +
- '&multiversion=' + multiversionBox.checked
-
- fetch(url)
- .then(response => {
- if (response.ok) {
- return response.text()
- } else {
- throw new Error("Couldn't fetch instructions");
- }
- })
- .then(data => {
- instructionsDiv.innerHTML = data
- })
- .catch(error => console.error("Couldn't fetch instructions: ", error));
-}
-
-function setSelectOsBoxes() {
- let osSelector = document.getElementById("os")
- let variantSelector = document.getElementById("osvariant")
-
- for (var i = variantSelector.length - 1; i >= 0; i--) {
- if (!variantSelector.options[i].value.startsWith(osSelector.options[osSelector.selectedIndex].value + "-")) {
- variantSelector.options[i].disabled = true
- } else {
- variantSelector.options[i].disabled = false
- variantSelector.selectedIndex = i
- }
- }
-
- setSelectBoxes();
-}
-
-window.onload = function() {
- let osSelector = document.getElementById("os")
- let variantSelector = document.getElementById("osvariant")
- let usageSelector = document.getElementById("usage")
- let versionSelector = document.getElementById("version")
- let multiversionBox = document.getElementById("multiversion")
-
- osSelector.addEventListener("change", setSelectOsBoxes)
- variantSelector.addEventListener("change", setSelectBoxes)
- usageSelector.addEventListener("change", setSelectBoxes)
- versionSelector.addEventListener("change", setSelectBoxes)
- multiversionBox.addEventListener("change", setSelectBoxes)
-
- setSelectOsBoxes()
-}