|
| 1 | +<?php |
| 2 | +$_SERVER['BASE_PAGE'] = 'qa.php'; |
| 3 | +include_once __DIR__ . '/include/prepend.inc'; |
| 4 | +include_once __DIR__ . '/include/release-qa.php'; |
| 5 | + |
| 6 | +if (isset($_GET["format"])) { |
| 7 | + $output = $QA_RELEASES; |
| 8 | + |
| 9 | + if (($_GET['only'] ?? null) === 'dev_versions') { |
| 10 | + $output = $output['reported']; |
| 11 | + } |
| 12 | + |
| 13 | + switch ($_GET['format'] ?? null) { |
| 14 | + case 'json': |
| 15 | + header('Content-Type: application/json; charset=UTF-8'); |
| 16 | + echo json_encode($output); |
| 17 | + exit; |
| 18 | + case 'serialize': |
| 19 | + default: |
| 20 | + header('Content-Type: text/plain; charset=UTF-8'); |
| 21 | + echo serialize($output); |
| 22 | + exit; |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +$SITE_UPDATE = date("D M d H:i:s Y T", filectime(__FILE__)); |
| 27 | + |
| 28 | +$SIDEBAR_DATA = ' |
| 29 | +<div class="panel"> |
| 30 | + Test Releases |
| 31 | + <div class="body"> |
| 32 | + The downloads on this page are not meant to be run in production. They are |
| 33 | + for testing only. |
| 34 | + </div> |
| 35 | +
|
| 36 | + <div class="body"> |
| 37 | + If you find a problem when running your library or application with these |
| 38 | + builds, please file a report on |
| 39 | + <a href="https://github.com/php/php-src/issues/">GitHub Issues</a>. |
| 40 | + </div> |
| 41 | + <br/> |
| 42 | + QA Releases API |
| 43 | + <div class="body"> |
| 44 | + <p> |
| 45 | + The QA API is based on the query string. |
| 46 | + </p> |
| 47 | + <p> |
| 48 | + Pass in the <code>format</code> parameter, with <code>serialize</code> or |
| 49 | + <code>json</code> as value to obtain all information: |
| 50 | + </p> |
| 51 | + <ul> |
| 52 | + <li><a href="https://php.net/pre-release-builds.php?format=json">/pre-release-builds.php?format=json</a></li> |
| 53 | + <li><a href="https://php.net/pre-release-builds.php?format=serialize">/pre-release-builds.php?format=serialize</a></li> |
| 54 | + </ul> |
| 55 | + <p> |
| 56 | + To only try dev version numbers, add <code>only=dev_versions</code>: |
| 57 | + </p> |
| 58 | + <ul> |
| 59 | + <li><a href="https://php.net/pre-release-builds.php?format=json&only=dev_versions">/pre-release-builds.php?format=json&only=dev_versions</a></li> |
| 60 | + </ul> |
| 61 | + </div> |
| 62 | +</div> |
| 63 | +'; |
| 64 | + |
| 65 | +site_header("Pre-Release Builds", [ |
| 66 | + 'current' => 'downloads', |
| 67 | +]); |
| 68 | + |
| 69 | +?> |
| 70 | +<h1>Pre-Release Builds</h1> |
| 71 | +<p> |
| 72 | +This page contains links to the Pre-release builds that the release |
| 73 | +managers create before each actual release. These builds are meant for the |
| 74 | +community to test whether no inadvertent changes have been made, and |
| 75 | +whether no regressions have been introduced. |
| 76 | +</p> |
| 77 | + |
| 78 | +<h3>Source Builds:</h3> |
| 79 | +<?php if (!empty($QA_RELEASES['releases'])) : ?> |
| 80 | + <?php $plural = count($QA_RELEASES['releases']) > 1 ? 's' : ''; ?> |
| 81 | + |
| 82 | + <?php foreach ($QA_RELEASES['releases'] as $pversion => $info) : ?> |
| 83 | + <h3 class="title"> |
| 84 | + PHP <?php echo $info['version']; ?> |
| 85 | + </h3> |
| 86 | + <div class="content-box"> |
| 87 | + |
| 88 | + <ul> |
| 89 | + <?php foreach ($info['files'] as $file_type => $file_info) : ?> |
| 90 | + <li> |
| 91 | + <a href="<?php echo $file_info['path'] ?>"><?php echo "php-{$info['version']}.tar.{$file_type}"; ?></a> |
| 92 | + <span class="releasedate"><?php echo date('d M Y', strtotime($info['date'])); ?></span> |
| 93 | + <?php foreach ($QA_CHECKSUM_TYPES as $algo): ?> |
| 94 | + <span class="<?php echo $algo; ?>"> |
| 95 | + <?php if (isset($file_info[$algo]) && strlen($file_info[$algo])) : ?> |
| 96 | + <?php echo $file_info[$algo]; ?> |
| 97 | + <?php else: ?> |
| 98 | + <em><small>No checksum value available</small></em>) |
| 99 | + <?php endif; ?> |
| 100 | + <?php endforeach; ?> |
| 101 | + </li> |
| 102 | + <?php endforeach; ?> |
| 103 | + </ul> |
| 104 | + <?php endforeach; ?> |
| 105 | +<?php else: ?> |
| 106 | + <span class='lihack'>There are no QA releases available at the moment to test.</span> |
| 107 | +<?php endif; ?> |
| 108 | + |
| 109 | +<h3>Windows Builds:</h3> |
| 110 | +<?php |
| 111 | +$winQaFile = __DIR__ . '/backend/win-qa-releases.json'; |
| 112 | +$winQaBase = 'https://downloads.php.net/~windows/qa/'; |
| 113 | +$winQaMessage = ''; |
| 114 | +$winQaReleases = []; |
| 115 | + |
| 116 | +if (is_readable($winQaFile)) { |
| 117 | + $raw = @file_get_contents($winQaFile); |
| 118 | + $decoded = $raw ? json_decode($raw, true) : null; |
| 119 | + if (is_array($decoded)) { |
| 120 | + $allowedBranches = []; |
| 121 | + if (!empty($QA_RELEASES['releases'])) { |
| 122 | + foreach (array_keys($QA_RELEASES['releases']) as $pversion) { |
| 123 | + $parts = explode('.', (string) $pversion); |
| 124 | + if (count($parts) >= 2) { |
| 125 | + $branchKey = $parts[0] . '.' . $parts[1]; |
| 126 | + $allowedBranches[$branchKey] = true; |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + $buildLabel = static function (string $key, array $entry): string { |
| 132 | + $tool = 'VS'; |
| 133 | + if (strpos($key, 'vs17') !== false) { |
| 134 | + $tool .= '17'; |
| 135 | + } elseif (strpos($key, 'vs16') !== false) { |
| 136 | + $tool .= '16'; |
| 137 | + } elseif (strpos($key, 'vc15') !== false) { |
| 138 | + $tool = 'VC15'; |
| 139 | + } |
| 140 | + |
| 141 | + $arch = (strpos($key, 'x64') !== false) ? 'x64' : ((strpos($key, 'x86') !== false) ? 'x86' : ''); |
| 142 | + $ts = (strpos($key, 'nts') !== false) ? 'Non Thread Safe' : 'Thread Safe'; |
| 143 | + |
| 144 | + if (strncmp($key, 'nts-', 4) === 0) { |
| 145 | + $ts = 'Non Thread Safe'; |
| 146 | + } elseif (strncmp($key, 'ts-', 3) === 0) { |
| 147 | + $ts = 'Thread Safe'; |
| 148 | + } |
| 149 | + |
| 150 | + return trim(($tool ? $tool . ' ' : '') . ($arch ? $arch . ' ' : '') . $ts); |
| 151 | + }; |
| 152 | + |
| 153 | + $packageNames = [ |
| 154 | + 'zip' => 'Zip', |
| 155 | + 'debug_pack' => 'Debug Pack', |
| 156 | + 'devel_pack' => 'Development package (SDK to develop PHP extensions)', |
| 157 | + ]; |
| 158 | + |
| 159 | + $makeListItem = static function (string $label, array $fileInfo, ?string $mtime, bool $includeSha) use ($winQaBase): ?string { |
| 160 | + $path = $fileInfo['path'] ?? ''; |
| 161 | + if ($path === '') { |
| 162 | + return null; |
| 163 | + } |
| 164 | + |
| 165 | + $href = $winQaBase . ltrim($path, '/'); |
| 166 | + $size = $fileInfo['size'] ?? ''; |
| 167 | + $sha = $fileInfo['sha256'] ?? ''; |
| 168 | + $hrefAttr = htmlspecialchars($href, ENT_QUOTES, 'UTF-8'); |
| 169 | + $labelText = htmlspecialchars($label, ENT_QUOTES, 'UTF-8'); |
| 170 | + |
| 171 | + $parts = ['<a href="' . $hrefAttr . '">' . $labelText . '</a>']; |
| 172 | + if ($size !== '') { |
| 173 | + $parts[] = '<span class="size">' . htmlspecialchars($size, ENT_QUOTES, 'UTF-8') . '</span>'; |
| 174 | + } |
| 175 | + |
| 176 | + if ($mtime) { |
| 177 | + $timestamp = strtotime($mtime); |
| 178 | + if ($timestamp) { |
| 179 | + $parts[] = '<span class="releasedate">' . gmdate('d M Y', $timestamp) . '</span>'; |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + if ($includeSha && $sha !== '') { |
| 184 | + $parts[] = '<span class="sha256">' . htmlspecialchars($sha, ENT_QUOTES, 'UTF-8') . '</span>'; |
| 185 | + } |
| 186 | + |
| 187 | + return '<li>' . implode(' ', $parts) . '</li>'; |
| 188 | + }; |
| 189 | + |
| 190 | + foreach ($decoded as $branch => $info) { |
| 191 | + if (!is_array($info) || empty($info['version'])) { |
| 192 | + continue; |
| 193 | + } |
| 194 | + |
| 195 | + if ($branch === 'comment') { |
| 196 | + continue; |
| 197 | + } |
| 198 | + |
| 199 | + if (!empty($allowedBranches) && empty($allowedBranches[$branch])) { |
| 200 | + continue; |
| 201 | + } |
| 202 | + |
| 203 | + $topItems = []; |
| 204 | + if (!empty($info['source']) && is_array($info['source'])) { |
| 205 | + $item = $makeListItem('Download source code', $info['source'], $info['source']['mtime'] ?? null, false); |
| 206 | + if ($item !== null) { |
| 207 | + $topItems[] = $item; |
| 208 | + } |
| 209 | + } |
| 210 | + |
| 211 | + if (!empty($info['test_pack']) && is_array($info['test_pack'])) { |
| 212 | + $item = $makeListItem('Download tests package (phpt)', $info['test_pack'], $info['test_pack']['mtime'] ?? null, false); |
| 213 | + if ($item !== null) { |
| 214 | + $topItems[] = $item; |
| 215 | + } |
| 216 | + } |
| 217 | + |
| 218 | + $builds = []; |
| 219 | + foreach ($info as $buildKey => $entry) { |
| 220 | + if (!is_array($entry) || in_array($buildKey, ['version', 'source', 'test_pack'], true)) { |
| 221 | + continue; |
| 222 | + } |
| 223 | + |
| 224 | + $label = $buildLabel($buildKey, $entry); |
| 225 | + if ($label === '') { |
| 226 | + continue; |
| 227 | + } |
| 228 | + |
| 229 | + $packageItems = []; |
| 230 | + foreach ($packageNames as $pkgKey => $pkgLabel) { |
| 231 | + if (empty($entry[$pkgKey]) || !is_array($entry[$pkgKey])) { |
| 232 | + continue; |
| 233 | + } |
| 234 | + |
| 235 | + $rendered = $makeListItem($pkgLabel, $entry[$pkgKey], $entry['mtime'] ?? null, true); |
| 236 | + if ($rendered !== null) { |
| 237 | + $packageItems[] = $rendered; |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + if (empty($packageItems)) { |
| 242 | + continue; |
| 243 | + } |
| 244 | + |
| 245 | + $builds[] = [ |
| 246 | + 'label' => $label, |
| 247 | + 'items' => $packageItems, |
| 248 | + ]; |
| 249 | + } |
| 250 | + |
| 251 | + if (empty($topItems) && empty($builds)) { |
| 252 | + continue; |
| 253 | + } |
| 254 | + |
| 255 | + $winQaReleases[] = [ |
| 256 | + 'version_label' => $info['version'], |
| 257 | + 'top_items' => $topItems, |
| 258 | + 'builds' => $builds, |
| 259 | + ]; |
| 260 | + } |
| 261 | + } else { |
| 262 | + $winQaMessage = 'Windows QA release index could not be parsed.'; |
| 263 | + } |
| 264 | +} else { |
| 265 | + $winQaMessage = 'Windows QA release index is unavailable.'; |
| 266 | +} |
| 267 | + |
| 268 | +if ($winQaMessage !== '') { |
| 269 | + echo '<p>', htmlspecialchars($winQaMessage), '</p>'; |
| 270 | +} elseif (empty($winQaReleases)) { |
| 271 | + echo "<p>No Windows QA builds match the currently active QA releases.</p>"; |
| 272 | +} else { |
| 273 | + foreach ($winQaReleases as $release) { |
| 274 | + $versionLabel = $release['version_label']; |
| 275 | + |
| 276 | + echo '<h3 class="title">PHP ', htmlspecialchars($versionLabel), '</h3>'; |
| 277 | + echo '<div class="content-box windows-qa">'; |
| 278 | + if (!empty($release['top_items'])) { |
| 279 | + echo '<ul class="windows-qa-list">'; |
| 280 | + foreach ($release['top_items'] as $item) { |
| 281 | + echo $item; |
| 282 | + } |
| 283 | + echo '</ul>'; |
| 284 | + } |
| 285 | + |
| 286 | + foreach ($release['builds'] as $build) { |
| 287 | + echo '<h5 style="margin:-10px 0 0 10px;">' . $build['label'] . '</h5>'; |
| 288 | + echo '<ul class="windows-qa-list">'; |
| 289 | + foreach ($build['items'] as $item) { |
| 290 | + echo $item; |
| 291 | + } |
| 292 | + echo '</ul>'; |
| 293 | + } |
| 294 | + echo '</div>'; |
| 295 | + } |
| 296 | +} |
| 297 | +?> |
| 298 | + |
| 299 | +<?php |
| 300 | +site_footer(['sidebar' => $SIDEBAR_DATA]); |
| 301 | + |
0 commit comments