Author: Luffy (sy-records)
Committer: GitHub (web-flow)
Pusher: sy-records
Date: 2026-07-19T14:10:24+08:00

Commit: 
https://github.com/php/web-php/commit/61a878c46f2cb37fb20e71e7791cc6f87f6d3ccc
Raw diff: 
https://github.com/php/web-php/commit/61a878c46f2cb37fb20e71e7791cc6f87f6d3ccc.diff

Add a copy function for the SHA256 checksum (#1957)

Changed paths:
  M  include/layout.inc
  M  include/version.inc
  M  js/common.js
  M  pre-release-builds.php
  M  releases/index.php
  M  styles/theme-base.css


Diff:

diff --git a/include/layout.inc b/include/layout.inc
index 30550b6a65..98f3fb095f 100644
--- a/include/layout.inc
+++ b/include/layout.inc
@@ -504,6 +504,13 @@ function site_footer(array $config = []): void
     require __DIR__ . "/footer.inc";
 }
 
+function sha256_html(string $checksum): string
+{
+    $checksum = htmlspecialchars($checksum, ENT_QUOTES, 'UTF-8');
+
+    return '<span class="sha256-row"><span class="sha256">' . $checksum . 
'</span><button type="button" class="sha256-copy" data-copy-text="' . $checksum 
. '" aria-label="Copy sha256 checksum">Copy</button></span>';
+}
+
 function get_nav_items(): array {
   return [
     new NavItem(
diff --git a/include/version.inc b/include/version.inc
index 31e4ff7a8a..65d338d94d 100644
--- a/include/version.inc
+++ b/include/version.inc
@@ -139,8 +139,9 @@ function show_source_releases()
                   <?php download_link($rel['filename'], $rel['filename']); ?>
                   <span class="releasedate"><?php echo date('d M Y', 
strtotime($rel['date'])); ?></span>
                   <?php
-                    if (isset($rel['md5']))    echo '<span class="md5sum">', 
$rel['md5'], '</span>';
-                    if (isset($rel['sha256'])) echo '<span class="sha256">', 
$rel['sha256'], '</span>';
+                    if (isset($rel['sha256'])) {
+                        echo sha256_html($rel['sha256']);
+                    }
                    ?>
                   <?php if (isset($rel['note']) && $rel['note']): ?>
                     <p>
diff --git a/js/common.js b/js/common.js
index 86b4862fd5..fe45d50041 100644
--- a/js/common.js
+++ b/js/common.js
@@ -879,3 +879,18 @@ function applyTheme(theme) {
 }
 
 applyTheme(savedTheme)
+
+const downloads = document.querySelector('.downloads');
+downloads?.addEventListener('click', function (event) {
+  var button = event.target.closest('.sha256-copy');
+  if (!button || !navigator.clipboard) {
+    return;
+  }
+
+  navigator.clipboard.writeText(button.dataset.copyText).then(function () {
+    button.textContent = 'Copied';
+    setTimeout(function () {
+      button.textContent = 'Copy';
+    }, 1500);
+  });
+});
diff --git a/pre-release-builds.php b/pre-release-builds.php
index 868ed84d50..80c9d8585c 100644
--- a/pre-release-builds.php
+++ b/pre-release-builds.php
@@ -97,9 +97,8 @@
           <a href="<?php echo $file_info['path'] ?>"><?php echo 
"php-{$info['version']}.tar.{$file_type}"; ?></a>
           <span class="releasedate"><?php echo date('d M Y', 
strtotime($info['date'])); ?></span>
             <?php foreach ($QA_CHECKSUM_TYPES as $algo): ?>
-              <span class="<?php echo $algo; ?>">
               <?php if (isset($file_info[$algo]) && strlen($file_info[$algo])) 
: ?>
-                <?php echo $file_info[$algo]; ?>
+                <?php echo sha256_html($file_info[$algo]); ?>
               <?php else: ?>
                 <em><small>No checksum value available</small></em>)&nbsp;
               <?php endif; ?>
@@ -189,7 +188,7 @@
       }
 
       if ($includeSha && $sha !== '') {
-        $parts[] = '<span class="sha256">' . htmlspecialchars($sha, 
ENT_QUOTES, 'UTF-8') . '</span>';
+        $parts[] = sha256_html($sha);
       }
 
       return '<li>' . implode(' ', $parts) . '</li>';
@@ -311,4 +310,3 @@
 
 <?php
 site_footer(['sidebar' => $SIDEBAR_DATA]);
-
diff --git a/releases/index.php b/releases/index.php
index 6044ae8a3d..b960a1127c 100644
--- a/releases/index.php
+++ b/releases/index.php
@@ -219,13 +219,8 @@ function mk_rel(int $major,
             echo " <li>\n";
             if (isset($src['filename'])) {
                 download_link($src["filename"], $src["name"]); echo "<br>\n";
-                $linebreak = '';
-                foreach (['md5', 'sha256'] as $cs) {
-                    if (isset($src[$cs])) {
-                        echo $linebreak;
-                        echo "<span class=\"{$cs}sum\">{$cs}: 
{$src[$cs]}</span>\n";
-                        $linebreak = "<br/>";
-                    }
+                if (isset($src['sha256'])) {
+                    echo sha256_html($src['sha256']), "\n";
                 }
             } else {
                 echo "<a href=\"{$src['link']}\">{$src['name']}</a>";
diff --git a/styles/theme-base.css b/styles/theme-base.css
index faeab9d6b4..cfd83fd345 100644
--- a/styles/theme-base.css
+++ b/styles/theme-base.css
@@ -783,20 +783,49 @@ fieldset {
 .content-header .changelog {
     color:#369;
 }
-.content-box .md5sum, .content-box .sha256 {
+.content-box .sha256,
+.downloads .sha256 {
     display: block;
     font: normal 0.875rem/1.5rem "Fira Mono", "Source Code Pro", monospace;
     overflow: hidden;
     text-overflow: ellipsis;
 }
-.content-box .md5sum:before {
-    content: "md5: ";
-    font-family: var(--font-family-sans-serif);
-}
-.content-box .sha256:before {
+.content-box .sha256:before,
+.downloads .sha256:before {
     content: "sha256: ";
     font-family: var(--font-family-sans-serif);
 }
+.content-box .sha256-row,
+.downloads .sha256-row {
+    display: flex;
+    align-items: center;
+    gap: 0.5rem;
+}
+.content-box .sha256-row .sha256,
+.downloads .sha256-row .sha256 {
+    min-width: 0;
+}
+.content-box .sha256-copy,
+.downloads .sha256-copy {
+    border: 1px solid var(--dark-blue-color);
+    border-radius: 30px;
+    background-color: var(--dark-blue-color);
+    color: #fff;
+    padding: 0.2rem 0.65rem;
+    font-size: 0.75rem;
+    line-height: 1rem;
+    cursor: pointer;
+    min-width: 4.25rem;
+    text-align: center;
+    white-space: nowrap;
+}
+.content-box .sha256-copy:hover,
+.content-box .sha256-copy:focus,
+.downloads .sha256-copy:hover,
+.downloads .sha256-copy:focus {
+    border-color: var(--dark-magenta-color);
+    background-color: var(--dark-magenta-color);
+}
 .content-box .releasedate {
     float: right;
     font-size: 0.9rem;

Reply via email to