Author: Andreas Möller (localheinz)
Committer: GitHub (web-flow)
Pusher: cmb69
Date: 2022-07-11T20:34:20+02:00

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

Enhancement: Enable `indentation_type` fixer

Closes GH-622.

Changed paths:
  M  .php-cs-fixer.php
  M  archive/index.php
  M  docs.php
  M  eol.php
  M  git-php.php
  M  images/logo.php
  M  images/supported-versions.php
  M  index.php
  M  manual-lookup.php
  M  manual/spam_challenge.php
  M  mirror-info.php
  M  releases/5_3_3.php
  M  releases/8.1/languages/zh.php
  M  releases/index.php
  M  src/News/Entry.php
  M  submit-event.php
  M  supported-versions.php
  M  urlhowto.php


Diff:

diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index 113bfaa433..f9d0db2599 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -10,6 +10,7 @@
     ->name(__FILE__);
 
 $config->setRules([
+    'indentation_type' => true,
     'no_trailing_whitespace' => true,
     'visibility_required' => true,
     'whitespace_after_comma_in_array' => true,
diff --git a/archive/index.php b/archive/index.php
index 95d28ea765..7b5aab024b 100644
--- a/archive/index.php
+++ b/archive/index.php
@@ -2,11 +2,11 @@
 include_once __DIR__ . '/../include/prepend.inc';
 $i = 0;
 do {
-       $y = date("Y")-$i;
-       if (file_exists("./$y.php")) {
-               mirror_redirect("/archive/$y.php");
-               break;
-       }
+    $y = date("Y")-$i;
+    if (file_exists("./$y.php")) {
+        mirror_redirect("/archive/$y.php");
+        break;
+    }
 } while(++$i<3);
 
 include_once __DIR__ . '/../include/errors.inc';
diff --git a/docs.php b/docs.php
index f48e7f342e..6b9adcbde0 100644
--- a/docs.php
+++ b/docs.php
@@ -29,9 +29,9 @@
 // List all manual languages viewable online
 $lastlang = end($ACTIVE_ONLINE_LANGUAGES);
 foreach ($ACTIVE_ONLINE_LANGUAGES as $langcode => $langname) {
-       if (!file_exists($_SERVER["DOCUMENT_ROOT"] . 
"/manual/{$langcode}/index.php")) {
-               continue;
-       }
+    if (!file_exists($_SERVER["DOCUMENT_ROOT"] . 
"/manual/{$langcode}/index.php")) {
+        continue;
+    }
 
     // Make preferred language bold
     if ($langcode == $LANG) { echo "<strong>"; }
diff --git a/eol.php b/eol.php
index af505916f7..5d6b0b130c 100644
--- a/eol.php
+++ b/eol.php
@@ -7,17 +7,17 @@
 // Notes for specific branches can be added here, and will appear in the table.
 $BRANCH_NOTES = array(
     '7.3' => '<a href="/migration74">A guide is available for migrating from 
PHP 7.3 to 7.4.</a>',
-       '7.2' => '<a href="/migration73">A guide is available for migrating 
from PHP 7.2 to 7.3.</a>',
-       '7.1' => '<a href="/migration72">A guide is available for migrating 
from PHP 7.1 to 7.2.</a>',
-       '7.0' => '<a href="/migration71">A guide is available for migrating 
from PHP 7.0 to 7.1.</a>',
-       '5.6' => '<a href="/migration70">A guide is available for migrating 
from PHP 5.6 to 7.0.</a>',
-       '5.5' => '<a href="/migration56">A guide is available for migrating 
from PHP 5.5 to 5.6.</a>',
-       '5.4' => '<a href="/migration55">A guide is available for migrating 
from PHP 5.4 to 5.5.</a>',
-       '5.3' => '<a href="/migration54">A guide is available for migrating 
from PHP 5.3 to 5.4.</a>',
-       '5.2' => '<a href="/migration53">A guide is available for migrating 
from PHP 5.2 to 5.3.</a>',
-       '5.1' => '<a href="/migration52">A guide is available for migrating 
from PHP 5.1 to 5.2.</a>',
-       '5.0' => '<a href="/migration51">A guide is available for migrating 
from PHP 5.0 to 5.1.</a>',
-       '4.4' => '<a href="/migration5">A guide is available for migrating from 
PHP 4 to PHP 5.0.</a>',
+    '7.2' => '<a href="/migration73">A guide is available for migrating from 
PHP 7.2 to 7.3.</a>',
+    '7.1' => '<a href="/migration72">A guide is available for migrating from 
PHP 7.1 to 7.2.</a>',
+    '7.0' => '<a href="/migration71">A guide is available for migrating from 
PHP 7.0 to 7.1.</a>',
+    '5.6' => '<a href="/migration70">A guide is available for migrating from 
PHP 5.6 to 7.0.</a>',
+    '5.5' => '<a href="/migration56">A guide is available for migrating from 
PHP 5.5 to 5.6.</a>',
+    '5.4' => '<a href="/migration55">A guide is available for migrating from 
PHP 5.4 to 5.5.</a>',
+    '5.3' => '<a href="/migration54">A guide is available for migrating from 
PHP 5.3 to 5.4.</a>',
+    '5.2' => '<a href="/migration53">A guide is available for migrating from 
PHP 5.2 to 5.3.</a>',
+    '5.1' => '<a href="/migration52">A guide is available for migrating from 
PHP 5.1 to 5.2.</a>',
+    '5.0' => '<a href="/migration51">A guide is available for migrating from 
PHP 5.0 to 5.1.</a>',
+    '4.4' => '<a href="/migration5">A guide is available for migrating from 
PHP 4 to PHP 5.0.</a>',
 );
 
 site_header('Unsupported Branches');
diff --git a/git-php.php b/git-php.php
index 2451831d85..2da36b0b99 100644
--- a/git-php.php
+++ b/git-php.php
@@ -158,7 +158,7 @@
 } // endif: no data or checkread not checked
 
 else {
-       if (count($_POST)) {
+    if (count($_POST)) {
         print <<<EOT
 <div class="warning">
 <p>
@@ -361,9 +361,9 @@ class="max" value="<?php if (isset($_POST['email'])) echo 
clean($_POST['email'])
  <td>
 <?php
 $purposes = array("Learning PHP", "Coding in PHP", "Reading the PHP source",
-       "Using PHP extensions", "Creating experimental PHP extensions",
-       "Submitting a patch to PHP", "Adding notes to the documentation",
-       "Writing web pages with PHP");
+    "Using PHP extensions", "Creating experimental PHP extensions",
+    "Submitting a patch to PHP", "Adding notes to the documentation",
+    "Writing web pages with PHP");
 
 foreach ($purposes as $i => $p) { ?>
   <input type="checkbox" name="purpose[<?php echo $i?>]" value="1"
diff --git a/images/logo.php b/images/logo.php
index 70b433710b..394e4e9737 100644
--- a/images/logo.php
+++ b/images/logo.php
@@ -72,12 +72,12 @@ function serve_compressed_if_available($logo): void {
 
 $logo = './logos/php-logo.svg';
 if (isset($_SERVER['QUERY_STRING'])) {
-       switch ($_SERVER['QUERY_STRING']) {
-               case 'QA':
-               case 'qa':
-                   $logo = './logos/qa.jpg';
-                   break;
-       }
+    switch ($_SERVER['QUERY_STRING']) {
+        case 'QA':
+        case 'qa':
+            $logo = './logos/qa.jpg';
+            break;
+    }
 }
 
 // xmas season, december and the first week of January
diff --git a/images/supported-versions.php b/images/supported-versions.php
index dc15d43b74..9fbe87ad6c 100644
--- a/images/supported-versions.php
+++ b/images/supported-versions.php
@@ -11,49 +11,49 @@
 $footer_height = 24;
 
 function branches_to_show() {
-       // Basically: show all 5.3+ branches with EOL dates > min_date().
-       $branches = array();
-
-       // Flatten out the majors.
-       foreach (get_all_branches() as $major_branches) {
-               foreach ($major_branches as $branch => $version) {
-                       if (version_compare($branch, '5.3', 'ge') && 
get_branch_security_eol_date($branch) > min_date()) {
-                               $branches[$branch] = $version;
-                       }
-               }
-       }
-
-       ksort($branches);
-       return $branches;
+    // Basically: show all 5.3+ branches with EOL dates > min_date().
+    $branches = array();
+
+    // Flatten out the majors.
+    foreach (get_all_branches() as $major_branches) {
+        foreach ($major_branches as $branch => $version) {
+            if (version_compare($branch, '5.3', 'ge') && 
get_branch_security_eol_date($branch) > min_date()) {
+                $branches[$branch] = $version;
+            }
+        }
+    }
+
+    ksort($branches);
+    return $branches;
 }
 
 function min_date() {
-       $now = new DateTime('January 1');
-       return $now->sub(new DateInterval('P3Y'));
+    $now = new DateTime('January 1');
+    return $now->sub(new DateInterval('P3Y'));
 }
 
 function max_date() {
-       $now = new DateTime('January 1');
-       return $now->add(new DateInterval('P5Y'));
+    $now = new DateTime('January 1');
+    return $now->add(new DateInterval('P5Y'));
 }
 
 function date_horiz_coord(DateTime $date) {
-       $diff = $date->diff(min_date());
-       if (!$diff->invert) {
-               return $GLOBALS['margin_left'];
-       }
-       return $GLOBALS['margin_left'] + ($diff->days / (365.24 / 
$GLOBALS['year_width']));
+    $diff = $date->diff(min_date());
+    if (!$diff->invert) {
+        return $GLOBALS['margin_left'];
+    }
+    return $GLOBALS['margin_left'] + ($diff->days / (365.24 / 
$GLOBALS['year_width']));
 }
 
 $branches = branches_to_show();
 $i = 0;
 foreach ($branches as $branch => $version) {
-       $branches[$branch]['top'] = $header_height + ($branch_height * $i++);
+    $branches[$branch]['top'] = $header_height + ($branch_height * $i++);
 }
 
 if (!isset($non_standalone)) {
-       header('Content-Type: image/svg+xml');
-       echo '<?xml version="1.0"?>';
+    header('Content-Type: image/svg+xml');
+    echo '<?xml version="1.0"?>';
 }
 
 $years = iterator_to_array(new DatePeriod(min_date(), new DateInterval('P1Y'), 
max_date()));
@@ -132,10 +132,10 @@ function date_horiz_coord(DateTime $date) {
        <g class="branches">
                <?php foreach ($branches as $branch => $version): ?>
                        <?php
-                       $x_release = 
date_horiz_coord(get_branch_release_date($branch));
-                       $x_bug = 
date_horiz_coord(get_branch_bug_eol_date($branch));
-                       $x_eol = 
date_horiz_coord(get_branch_security_eol_date($branch));
-                       ?>
+            $x_release = date_horiz_coord(get_branch_release_date($branch));
+            $x_bug = date_horiz_coord(get_branch_bug_eol_date($branch));
+            $x_eol = date_horiz_coord(get_branch_security_eol_date($branch));
+            ?>
                        <rect class="stable" x="<?php echo $x_release ?>" 
y="<?php echo $version['top'] ?>" width="<?php echo $x_bug - $x_release ?>" 
height="<?php echo $branch_height ?>" />
                        <rect class="security" x="<?php echo $x_bug ?>" 
y="<?php echo $version['top'] ?>" width="<?php echo $x_eol - $x_bug ?>" 
height="<?php echo $branch_height ?>" />
                <?php endforeach ?>
@@ -154,9 +154,9 @@ function date_horiz_coord(DateTime $date) {
        <!-- Today -->
        <g class="today">
                <?php
-               $now = new DateTime;
-               $x = date_horiz_coord($now);
-               ?>
+        $now = new DateTime;
+        $x = date_horiz_coord($now);
+        ?>
                <line x1="<?php echo $x ?>" y1="<?php echo $header_height ?>" 
x2="<?php echo $x ?>" y2="<?php echo $header_height + (count($branches) * 
$branch_height) ?>" />
                <text x="<?php echo $x ?>" y="<?php echo $header_height + 
(count($branches) * $branch_height) + (0.8 * $footer_height) ?>">
                        <?php echo 'Today: '.$now->format('j M Y') ?>
diff --git a/index.php b/index.php
index fdc460c86a..5e4abfc5ca 100644
--- a/index.php
+++ b/index.php
@@ -180,7 +180,7 @@
     );
     $announcements = "";
     foreach($CONF_TEASER as $category => $entries) {
-               if ($entries) {
+        if ($entries) {
             $announcements .= '<div class="panel">';
             $announcements .= '  <a href="/conferences" class="headline" 
title="' . $conftype[$category] . '">' . $conftype[$category] .'</a>';
             $announcements .= '<div class="body"><ul>';
diff --git a/manual-lookup.php b/manual-lookup.php
index 3715fef43e..446df1fa2d 100644
--- a/manual-lookup.php
+++ b/manual-lookup.php
@@ -13,9 +13,9 @@
 }
 
 if(!empty($_GET['scope']) && is_string($_GET['scope'])) {
-       $scope = htmlspecialchars($_GET['scope'], ENT_QUOTES, 'UTF-8');
+    $scope = htmlspecialchars($_GET['scope'], ENT_QUOTES, 'UTF-8');
 } else {
-       $scope = '';
+    $scope = '';
 }
 
 // Prepare data for search
diff --git a/manual/spam_challenge.php b/manual/spam_challenge.php
index 2bba1b0562..7466d8d84f 100644
--- a/manual/spam_challenge.php
+++ b/manual/spam_challenge.php
@@ -4,63 +4,63 @@
 const NUMS = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 
'seven', 'eight', 'nine');
 
 function plus($a, $b) {
-       return $a + $b;
+    return $a + $b;
 }
 
 function gen_plus($a) {
-       return rand(0, 9 - $a);
+    return rand(0, 9 - $a);
 }
 
 function minus($a, $b) {
-       return $a - $b;
+    return $a - $b;
 }
 
 function gen_minus($a) {
-       return rand(0, $a);
+    return rand(0, $a);
 }
 
 function print_infix($name, $a, $b) {
-       return "$a $name $b";
+    return "$a $name $b";
 }
 
 function print_prefix($name, $a, $b) {
-       return "$name($a, $b)";
+    return "$name($a, $b)";
 }
 
 const CHALLENGES = array(
-       // name, print, generator
-       array('max',   'print_prefix'),
-       array('min',   'print_prefix'),
-       array('minus', 'print_infix', 'gen_minus'),
-       array('plus',  'print_infix', 'gen_plus'),
+    // name, print, generator
+    array('max',   'print_prefix'),
+    array('min',   'print_prefix'),
+    array('minus', 'print_infix', 'gen_minus'),
+    array('plus',  'print_infix', 'gen_plus'),
 );
 
 // generate a challenge
 function gen_challenge() {
-       $c = CHALLENGES[rand(0, count(CHALLENGES)-1)];
+    $c = CHALLENGES[rand(0, count(CHALLENGES)-1)];
 
-       $a  = rand(0, 9);
-       $an = NUMS[$a];
-       $b  = isset($c[2]) ? $c[2]($a) : rand(0, 9);
-       $bn = NUMS[$b];
+    $a  = rand(0, 9);
+    $an = NUMS[$a];
+    $b  = isset($c[2]) ? $c[2]($a) : rand(0, 9);
+    $bn = NUMS[$b];
 
-       return array($c[0], $an, $bn, $c[1]($c[0], $an, $bn));
+    return array($c[0], $an, $bn, $c[1]($c[0], $an, $bn));
 }
 
 
 // test an answer for validity
 function test_answer($name, $an, $bn, $answer) {
-       foreach (CHALLENGES as $x) {
-               if ($x[0] === $name) {
-                       $c = $x;
-                       break;
-               }
-       }
+    foreach (CHALLENGES as $x) {
+        if ($x[0] === $name) {
+            $c = $x;
+            break;
+        }
+    }
 
-       $a = array_search($an, NUMS);
-       $b = array_search($bn, NUMS);
+    $a = array_search($an, NUMS);
+    $b = array_search($bn, NUMS);
 
-       if (empty($c) || $a === false || $b === false) return false;
+    if (empty($c) || $a === false || $b === false) return false;
 
-       return (NUMS[$c[0]($a, $b)] === $answer);
+    return (NUMS[$c[0]($a, $b)] === $answer);
 }
diff --git a/mirror-info.php b/mirror-info.php
index f687f5fca6..4148dc0797 100644
--- a/mirror-info.php
+++ b/mirror-info.php
@@ -16,13 +16,13 @@
 $dist = $latest['source'][0];
 $filename = __DIR__ . "/distributions/{$dist['filename']}";
 if (!file_exists($filename)) {
-       $hash_ok = 0;
+    $hash_ok = 0;
 } elseif (isset($dist['sha256']) &&
-               function_exists('hash_file') &&
-               in_array('sha256', hash_algos(), true)) {
-       $hash_ok = (int)(hash_file('sha256', $filename) === $dist['sha256']);
+        function_exists('hash_file') &&
+        in_array('sha256', hash_algos(), true)) {
+    $hash_ok = (int)(hash_file('sha256', $filename) === $dist['sha256']);
 } else {
-       $hash_ok = 0;
+    $hash_ok = 0;
 }
 
 // Does this mirror have sqlite?
diff --git a/releases/5_3_3.php b/releases/5_3_3.php
index bd9c9ea56a..516ddd3762 100644
--- a/releases/5_3_3.php
+++ b/releases/5_3_3.php
@@ -22,7 +22,7 @@
        non-namespaced classes.
 
        <p><?php
-       highlight_string('<?php
+    highlight_string('<?php
 namespace Foo;
 class Bar {
     public function Bar() {
@@ -31,7 +31,7 @@ public function Bar() {
     }
 }
 ?>');
-       ?></p>
+    ?></p>
        <p>There is no impact on migration from 5.2.x because namespaces were 
only introduced in PHP 5.3.</p></li>
 </ul>
 <p>
diff --git a/releases/8.1/languages/zh.php b/releases/8.1/languages/zh.php
index cd62e01cd9..676b949545 100644
--- a/releases/8.1/languages/zh.php
+++ b/releases/8.1/languages/zh.php
@@ -5,85 +5,85 @@
  */
 
 return [
-       'common_header' => 'PHP 8.1 是 PHP 
语言的一个主版本更新。它包含了许多新功能,包括枚举、只读属性、First-class 可调用语法、纤程、交集类型和性能改进等。',
-       'main_title' => '已发布!',
-       'main_subtitle' => 'PHP 8.1 是 PHP 语言的一个主版本更新。<br 
class="display-none-md"> 它包含了许多新功能,包括枚举、只读属性、First-class 可调用语法、纤程、交集类型和性能改进等。',
-       'upgrade_now' => '更新到 PHP 8.1 !',
-       'documentation' => '文档',
+    'common_header' => 'PHP 8.1 是 PHP 
语言的一个主版本更新。它包含了许多新功能,包括枚举、只读属性、First-class 可调用语法、纤程、交集类型和性能改进等。',
+    'main_title' => '已发布!',
+    'main_subtitle' => 'PHP 8.1 是 PHP 语言的一个主版本更新。<br class="display-none-md"> 
它包含了许多新功能,包括枚举、只读属性、First-class 可调用语法、纤程、交集类型和性能改进等。',
+    'upgrade_now' => '更新到 PHP 8.1 !',
+    'documentation' => '文档',
 
-       'enumerations_title' => '枚举',
-       'enumerations_content' => '使用枚举而不是一组常量并立即进行验证。',
+    'enumerations_title' => '枚举',
+    'enumerations_content' => '使用枚举而不是一组常量并立即进行验证。',
 
-       'readonly_properties_title' => '只读属性',
-       'readonly_properties_content' => 
'<p>只读属性不能在初始化后更改,即在为它们分配值后。它们可以用于对值对象和数据传输对象建模。</p>',
+    'readonly_properties_title' => '只读属性',
+    'readonly_properties_content' => 
'<p>只读属性不能在初始化后更改,即在为它们分配值后。它们可以用于对值对象和数据传输对象建模。</p>',
 
-       'first_class_callable_syntax_title' => 'First-class 可调用语法',
-       'first_class_callable_syntax_content' => '<p>现在可以获得对任何函数的引用。这统称为 
First-class 可调用语法。</p>',
+    'first_class_callable_syntax_title' => 'First-class 可调用语法',
+    'first_class_callable_syntax_content' => '<p>现在可以获得对任何函数的引用。这统称为 
First-class 可调用语法。</p>',
 
-       'new_in_initializers_title' => '新的初始化器',
-       'new_in_initializers_content' => '<p>对象现在可以用作默认参数值、静态变量和全局常量,以及属性参数。</p>
+    'new_in_initializers_title' => '新的初始化器',
+    'new_in_initializers_content' => '<p>对象现在可以用作默认参数值、静态变量和全局常量,以及属性参数。</p>
             <p>这有效地使使用 <strong>嵌套属性</strong> 成为可能。</p>',
 
-       'pure_intersection_types_title' => '纯交集类型',
-       'pure_intersection_types_content' => '<p>当一个值需要同时满足多个类型约束时,使用交集类型。</p>
+    'pure_intersection_types_title' => '纯交集类型',
+    'pure_intersection_types_content' => '<p>当一个值需要同时满足多个类型约束时,使用交集类型。</p>
             <p>注意,目前无法将交集和联合类型混合在一起,例如 <code>A&B|C</code>。</p>',
 
-       'never_return_type_title' => 'Never 返回类型',
-       'never_return_type_content' => '<p>使用 <code>never</code> 
类型声明的函数或方法表示它不会返回值,并且会抛出异常或通过调用 
<code>die()</code>、<code>exit()</code>、<code>trigger_error()</code> 
或类似的东西来结束脚本的执行。</p>',
+    'never_return_type_title' => 'Never 返回类型',
+    'never_return_type_content' => '<p>使用 <code>never</code> 
类型声明的函数或方法表示它不会返回值,并且会抛出异常或通过调用 
<code>die()</code>、<code>exit()</code>、<code>trigger_error()</code> 
或类似的东西来结束脚本的执行。</p>',
 
-       'final_class_constants_title' => 'Final 类常量',
-       'final_class_constants_content' => '<p>可以声明 final 
类常量,以禁止它们在子类中被重写。</p>',
+    'final_class_constants_title' => 'Final 类常量',
+    'final_class_constants_content' => '<p>可以声明 final 类常量,以禁止它们在子类中被重写。</p>',
 
-       'octal_numeral_notation_title' => '显式八进制数字表示法',
-       'octal_numeral_notation_content' => '<p>现在可以使用显式 <code>0o</code> 
前缀表示八进制数。</p>',
+    'octal_numeral_notation_title' => '显式八进制数字表示法',
+    'octal_numeral_notation_content' => '<p>现在可以使用显式 <code>0o</code> 
前缀表示八进制数。</p>',
 
-       'fibers_title' => '纤程',
-       'fibers_content' => '<p>Fibers 
是用于实现轻量级协作并发的基础类型。它们是一种创建可以像生成器一样暂停和恢复的代码块的方法,但可以从堆栈中的任何位置进行。Fibers 
本身并没有提供并发性,仍然需要一个事件循环。但是,它们允许通过阻塞和非阻塞实现共享相同的 API。</p><p>Fibers 允许摆脱以前在 
<code>Promise::then()</code> 或基于生成器的协程中看到的样板代码。库通常会围绕 Fiber 
构建进一步的抽象,因此无需直接与它们交互。</p>',
+    'fibers_title' => '纤程',
+    'fibers_content' => '<p>Fibers 
是用于实现轻量级协作并发的基础类型。它们是一种创建可以像生成器一样暂停和恢复的代码块的方法,但可以从堆栈中的任何位置进行。Fibers 
本身并没有提供并发性,仍然需要一个事件循环。但是,它们允许通过阻塞和非阻塞实现共享相同的 API。</p><p>Fibers 允许摆脱以前在 
<code>Promise::then()</code> 或基于生成器的协程中看到的样板代码。库通常会围绕 Fiber 
构建进一步的抽象,因此无需直接与它们交互。</p>',
 
-       'array_unpacking_title' => '对字符串键控数组的数组解包支持',
-       'array_unpacking_content' => '<p>PHP 
以前支持通过扩展运算符在数组内部解包,但前提是数组具有整数键。现在也可以使用字符串键解包数组。</p>',
+    'array_unpacking_title' => '对字符串键控数组的数组解包支持',
+    'array_unpacking_content' => '<p>PHP 
以前支持通过扩展运算符在数组内部解包,但前提是数组具有整数键。现在也可以使用字符串键解包数组。</p>',
 
-       'performance_title' => '性能改进',
-       'performance_chart' => '<strong>Symfony Demo App 请求时间</strong><br>
+    'performance_title' => '性能改进',
+    'performance_chart' => '<strong>Symfony Demo App 请求时间</strong><br>
                 25 次连续运行,250 次请求(秒)<br>
                 (越少越好)<br>',
-       'performance_results_title' => '结果(相对于 PHP 8.0):',
-       'performance_results_symfony' => 'Symfony Demo 有 23.0% 的提升',
-       'performance_results_wordpress' => 'WordPress 有 3.5% 的提升',
-       'performance_related_functions_title' => 'PHP 8.1 中与性能相关的特性:',
-       'performance_jit_arm64' => 'ARM64 的 JIT 后端 (AArch64)',
-       'performance_inheritance_cache' => '继承缓存(避免在每个请求中重新链接类)',
-       'performance_fast_class_name_resolution' => '快速解析类名(避免小写和哈希查找)',
-       'performance_timelib_date_improvements' => 'timelib 和 ext/date 性能改进',
-       'performance_spl' => 'SPL 文件系统迭代器改进',
-       'performance_serialize_unserialize' => 'serialize/unserialize 优化',
-       'performance_internal_functions' => 
'一些内部函数优化(get_declared_classes()、explode()、strtr()、strnatcmp() 和 dechex())',
-       'performance_jit' => 'JIT 的改进和修复',
-
-       'other_new_title' => '新的类、接口和函数',
-       'other_new_returntypewillchange' => 
'<code>#[ReturnTypeWillChange]</code> 属性。',
-       'other_new_fsync_fdatasync' => '<code>fsync</code> 和 
<code>fdatasync</code> 函数。',
-       'other_new_array_is_list' => '<code>array_is_list</code> 函数。',
-       'other_new_sodium_xchacha20' => 'Sodium XChaCha20 函数。',
-
-       'bc_title' => '弃用和向后不兼容',
-       'bc_null_to_not_nullable' => '向非空值的内部函数参数传递空值的做法已被弃用。',
-       'bc_return_types' => 'PHP 内置类方法中的暂定返回类型',
-       'bc_serializable_deprecated' => '<code>Serializable</code> 接口已弃用。',
-       'bc_html_entity_encode_decode' => 
'html_entity_encode/html_entity_decode 函数默认处理单引号和用 Unicode 替换字符来替换无效字符。',
-       'bc_globals_restrictions' => '<code>$GLOBALS</code> 变量限制。',
-       'bc_mysqli_exceptions' => 'MySQLi:默认错误模式设置为异常。',
-       'bc_float_to_int_conversion' => '隐式不兼容的 float 到 int 转换已被弃用。',
-       'bc_finfo_objects' => 'finfo 扩展:<code>file_info</code> 资源迁移到现有的 finfo 
对象。',
-       'bc_imap_objects' => 'IMAP:imap 资源迁移到 <code>IMAP\Connection</code> 
类对象。',
-       'bc_ftp_objects' => 'FTP 扩展:连接资源迁移到 <code>FTP\Connection</code> 类对象。',
-       'bc_gd_objects' => 'GD 扩展:字体标识符迁移到 <code>GdFont</code> 类对象。',
-       'bc_ldap_objects' => 'LDAP:资源类型迁移到 
<code>LDAP\Connection</code>、<code>LDAP\Result</code> 和 
<code>LDAP\ResultEntry</code> 对象。',
-       'bc_postgresql_objects' => 'PostgreSQL:资源类型迁移到 
<code>PgSql\Connection</code>、<code>PgSql\Result</code> 和 
<code>PgSql\Lob</code> 对象。',
-       'bc_pspell_objects' => 'Pspell:pspell 和 pspell config 资源类型迁移到 
<code>PSpell\Dictionary</code>、<code>PSpell\Config</code> 类对象。',
-
-       'footer_title' => '更好的性能、更好的语法、改进类型安全。',
-       'footer_content' => '<p>
+    'performance_results_title' => '结果(相对于 PHP 8.0):',
+    'performance_results_symfony' => 'Symfony Demo 有 23.0% 的提升',
+    'performance_results_wordpress' => 'WordPress 有 3.5% 的提升',
+    'performance_related_functions_title' => 'PHP 8.1 中与性能相关的特性:',
+    'performance_jit_arm64' => 'ARM64 的 JIT 后端 (AArch64)',
+    'performance_inheritance_cache' => '继承缓存(避免在每个请求中重新链接类)',
+    'performance_fast_class_name_resolution' => '快速解析类名(避免小写和哈希查找)',
+    'performance_timelib_date_improvements' => 'timelib 和 ext/date 性能改进',
+    'performance_spl' => 'SPL 文件系统迭代器改进',
+    'performance_serialize_unserialize' => 'serialize/unserialize 优化',
+    'performance_internal_functions' => 
'一些内部函数优化(get_declared_classes()、explode()、strtr()、strnatcmp() 和 dechex())',
+    'performance_jit' => 'JIT 的改进和修复',
+
+    'other_new_title' => '新的类、接口和函数',
+    'other_new_returntypewillchange' => '<code>#[ReturnTypeWillChange]</code> 
属性。',
+    'other_new_fsync_fdatasync' => '<code>fsync</code> 和 
<code>fdatasync</code> 函数。',
+    'other_new_array_is_list' => '<code>array_is_list</code> 函数。',
+    'other_new_sodium_xchacha20' => 'Sodium XChaCha20 函数。',
+
+    'bc_title' => '弃用和向后不兼容',
+    'bc_null_to_not_nullable' => '向非空值的内部函数参数传递空值的做法已被弃用。',
+    'bc_return_types' => 'PHP 内置类方法中的暂定返回类型',
+    'bc_serializable_deprecated' => '<code>Serializable</code> 接口已弃用。',
+    'bc_html_entity_encode_decode' => 'html_entity_encode/html_entity_decode 
函数默认处理单引号和用 Unicode 替换字符来替换无效字符。',
+    'bc_globals_restrictions' => '<code>$GLOBALS</code> 变量限制。',
+    'bc_mysqli_exceptions' => 'MySQLi:默认错误模式设置为异常。',
+    'bc_float_to_int_conversion' => '隐式不兼容的 float 到 int 转换已被弃用。',
+    'bc_finfo_objects' => 'finfo 扩展:<code>file_info</code> 资源迁移到现有的 finfo 对象。',
+    'bc_imap_objects' => 'IMAP:imap 资源迁移到 <code>IMAP\Connection</code> 类对象。',
+    'bc_ftp_objects' => 'FTP 扩展:连接资源迁移到 <code>FTP\Connection</code> 类对象。',
+    'bc_gd_objects' => 'GD 扩展:字体标识符迁移到 <code>GdFont</code> 类对象。',
+    'bc_ldap_objects' => 'LDAP:资源类型迁移到 
<code>LDAP\Connection</code>、<code>LDAP\Result</code> 和 
<code>LDAP\ResultEntry</code> 对象。',
+    'bc_postgresql_objects' => 'PostgreSQL:资源类型迁移到 
<code>PgSql\Connection</code>、<code>PgSql\Result</code> 和 
<code>PgSql\Lob</code> 对象。',
+    'bc_pspell_objects' => 'Pspell:pspell 和 pspell config 资源类型迁移到 
<code>PSpell\Dictionary</code>、<code>PSpell\Config</code> 类对象。',
+
+    'footer_title' => '更好的性能、更好的语法、改进类型安全。',
+    'footer_content' => '<p>
         请访问 <a href="http://www.php.net/downloads";>下载</a> 页面下载 PHP 8.1 源代码。
         在 <a href="http://windows.php.net/download";>PHP for Windows</a> 站点中可找到 
Windows 二进制文件。
         <a href="https://www.php.net/ChangeLog-8.php#PHP_8_1";>ChangeLog</a> 
中有变更历史记录清单。
diff --git a/releases/index.php b/releases/index.php
index e60e36eabe..ce2526e0ed 100644
--- a/releases/index.php
+++ b/releases/index.php
@@ -4,70 +4,70 @@
 include_once __DIR__ . "/../include/branches.inc";
 
 if (isset($_GET["serialize"]) || isset($_GET["json"])) {
-       $RELEASES = $RELEASES + $OLDRELEASES;
-
-       $machineReadable = [];
-
-       $supportedVersions = [];
-       foreach (get_active_branches(false) as $major => $releases) {
-               $supportedVersions[$major] = array_keys($releases);
-       }
-
-       if (isset($_GET["version"])) {
-               $versionArray = version_array($_GET["version"]);
-               $ver = $versionArray[0];
-
-               if (isset($RELEASES[$ver])) {
-                       $combinedReleases = array_replace_recursive($RELEASES, 
$OLDRELEASES);
-
-                       $max = (int) ($_GET['max'] ?? 1);
-                       if ($max == -1) {
-                               $max = PHP_INT_MAX;
-                       }
-
-                       $count = 0;
-                       foreach ($combinedReleases[$ver] as $version => 
$release) {
-                               if ($max <= $count) {
-                                       break;
-                               }
-
-                               if (compare_version($versionArray, $version) == 
0) {
-                                       if (!isset($_GET['max'])) {
-                                               $release['supported_versions'] 
= $supportedVersions[$ver] ?? [];
-                                       }
-                                       $machineReadable[$version] = $release;
-                                       $count++;
-                               }
-                       }
-
-                       if (!isset($_GET['max']) && !empty($machineReadable)) {
-                               $version = key($machineReadable);
-                               $machineReadable = current($machineReadable);
-                               $machineReadable["version"] = $version;
-                       }
-               }
-
-               if (empty($machineReadable)) {
-                       $machineReadable = array("error" => "Unknown version");
-               }
-       } else {
-               foreach($RELEASES as $major => $release) {
-                       $version = key($release);
-                       $r = current($release);
-                       $r["version"] = $version;
-                       $r['supported_versions'] = $supportedVersions[$major] 
?? [];
-                       $machineReadable[$major] = $r;
-               }
-       }
-
-       if (isset($_GET["serialize"])) {
-               header('Content-type: text/plain');
-               echo serialize($machineReadable);
-       } elseif (isset($_GET["json"])) {
-               header('Content-Type: application/json');
-               echo json_encode($machineReadable);
-       }
-       return;
+    $RELEASES = $RELEASES + $OLDRELEASES;
+
+    $machineReadable = [];
+
+    $supportedVersions = [];
+    foreach (get_active_branches(false) as $major => $releases) {
+        $supportedVersions[$major] = array_keys($releases);
+    }
+
+    if (isset($_GET["version"])) {
+        $versionArray = version_array($_GET["version"]);
+        $ver = $versionArray[0];
+
+        if (isset($RELEASES[$ver])) {
+            $combinedReleases = array_replace_recursive($RELEASES, 
$OLDRELEASES);
+
+            $max = (int) ($_GET['max'] ?? 1);
+            if ($max == -1) {
+                $max = PHP_INT_MAX;
+            }
+
+            $count = 0;
+            foreach ($combinedReleases[$ver] as $version => $release) {
+                if ($max <= $count) {
+                    break;
+                }
+
+                if (compare_version($versionArray, $version) == 0) {
+                    if (!isset($_GET['max'])) {
+                        $release['supported_versions'] = 
$supportedVersions[$ver] ?? [];
+                    }
+                    $machineReadable[$version] = $release;
+                    $count++;
+                }
+            }
+
+            if (!isset($_GET['max']) && !empty($machineReadable)) {
+                $version = key($machineReadable);
+                $machineReadable = current($machineReadable);
+                $machineReadable["version"] = $version;
+            }
+        }
+
+        if (empty($machineReadable)) {
+            $machineReadable = array("error" => "Unknown version");
+        }
+    } else {
+        foreach($RELEASES as $major => $release) {
+            $version = key($release);
+            $r = current($release);
+            $r["version"] = $version;
+            $r['supported_versions'] = $supportedVersions[$major] ?? [];
+            $machineReadable[$major] = $r;
+        }
+    }
+
+    if (isset($_GET["serialize"])) {
+        header('Content-type: text/plain');
+        echo serialize($machineReadable);
+    } elseif (isset($_GET["json"])) {
+        header('Content-Type: application/json');
+        echo json_encode($machineReadable);
+    }
+    return;
 }
 
 
@@ -90,27 +90,27 @@
 $active_majors = array_keys($RELEASES);
 $latest = max($active_majors);
 foreach($OLDRELEASES as $major => $a) {
-       echo '<a id="v' .$major. '"></a>';
-       if (!in_array($major, $active_majors)) {
-               echo "\n<br>\n";
-               echo "<p>Support for PHP $major has been <b style=\"color: 
red;\">discontinued</b> ";
-               echo "since <b>" . current($a)['date'] . '</b>.';
-               echo "Please consider upgrading to $latest.</p>\n";
-       }
-
-       $i = 0;
-       foreach($a as $ver => $release) {
-               $i++;
-               mk_rel(
-                       $major,
-                       $ver,
-                       $release["date"],
-                       $release["announcement"] ?? false,
-                       $release["source"] ?? [],
-                       $release["windows"] ?? [],
-                       $release["museum"] ?? ($i >= 3)
-               );
-       }
+    echo '<a id="v' .$major. '"></a>';
+    if (!in_array($major, $active_majors)) {
+        echo "\n<br>\n";
+        echo "<p>Support for PHP $major has been <b style=\"color: 
red;\">discontinued</b> ";
+        echo "since <b>" . current($a)['date'] . '</b>.';
+        echo "Please consider upgrading to $latest.</p>\n";
+    }
+
+    $i = 0;
+    foreach($a as $ver => $release) {
+        $i++;
+        mk_rel(
+            $major,
+            $ver,
+            $release["date"],
+            $release["announcement"] ?? false,
+            $release["source"] ?? [],
+            $release["windows"] ?? [],
+            $release["museum"] ?? ($i >= 3)
+        );
+    }
 }
 
 site_footer(['sidebar' =>
@@ -168,83 +168,83 @@
 ']);
 
 function recentEOLBranchesHTML(): string {
-       $eol = array();
-       foreach (get_eol_branches() as $branches) {
-               foreach ($branches as $branch => $detail) {
-                       $detail_date = $detail['date'];
-                       while (isset($eol[$detail_date])) $detail_date++;
-                       $eol[$detail_date] = sprintf('<li>%s: %s</li>', 
$branch, date('j M Y', $detail_date));
-               }
-       }
-       krsort($eol);
-       return implode('', array_slice($eol, 0, 2));
+    $eol = array();
+    foreach (get_eol_branches() as $branches) {
+        foreach ($branches as $branch => $detail) {
+            $detail_date = $detail['date'];
+            while (isset($eol[$detail_date])) $detail_date++;
+            $eol[$detail_date] = sprintf('<li>%s: %s</li>', $branch, date('j M 
Y', $detail_date));
+        }
+    }
+    krsort($eol);
+    return implode('', array_slice($eol, 0, 2));
 }
 
 function mk_rel(int $major,
-                               string $ver,
-                               string $date,
-                               /* bool | array */ $announcement,
-                               array $source,
-                               array $windows,
-                               bool $museum): void {
-       printf("<a id=\"%s\"></a>\n<h2>%1\$s</h2>\n<ul>\n <li>Released: 
%s</li>\n <li>Announcement: ",
-              ($pos = strpos($ver, " ")) ? substr($ver, 0, $pos) : $ver,
-              $date);
-
-       if ($announcement) {
-               if (is_array($announcement)) {
-                       foreach($announcement as $ann => $url) {
-                               echo "<a href=\"$url\">$ann</a> ";
-                       }
-               } else {
-                       $url = str_replace(".", "_", $ver);
-                       echo "<a href=\"/releases/{$url}.php\">English</a>";
-               }
-       } else {
-               echo "None";
-       }
-       echo "</li>\n";
-
-       if ($major > 3) {
-               echo " <li><a 
href=\"/ChangeLog-{$major}.php#{$ver}\">ChangeLog</a></li>";
-       }
-       echo "\n <li>\n  Download:\n";
-       echo "<ul>\n";
-
-       if (!$museum) {
-               foreach(array_merge($source, $windows) as $src) {
-                       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/>";
-                                       }
-                               }
-                       } else {
-                               echo "<a 
href=\"{$src['link']}\">{$src['name']}</a>";
-                       }
-                       echo " </li>\n";
-               }
-
-       } else { /* $museum */
-               foreach($source as $src) {
-                       if (!isset($src["filename"])) {
-                               continue;
-                       }
-                       printf('<li><a 
href="http://museum.php.net/php%d/%s";>%s</a></li>',
-                              $major, $src["filename"], $src["name"]);
-               }
-               foreach($windows as $src) {
-                       printf('<li><a 
href="http://museum.php.net/%s/%s";>%s</a></li>',
-                              ($major == 5 ? "php5" : "win32"), 
$src["filename"], $src["name"]);
-               }
-       }
-
-       echo "</ul>\n";
-       echo "</li>\n";
-       echo "</ul>\n";
+                string $ver,
+                string $date,
+                /* bool | array */ $announcement,
+                array $source,
+                array $windows,
+                bool $museum): void {
+    printf("<a id=\"%s\"></a>\n<h2>%1\$s</h2>\n<ul>\n <li>Released: %s</li>\n 
<li>Announcement: ",
+           ($pos = strpos($ver, " ")) ? substr($ver, 0, $pos) : $ver,
+           $date);
+
+    if ($announcement) {
+        if (is_array($announcement)) {
+            foreach($announcement as $ann => $url) {
+                echo "<a href=\"$url\">$ann</a> ";
+            }
+        } else {
+            $url = str_replace(".", "_", $ver);
+            echo "<a href=\"/releases/{$url}.php\">English</a>";
+        }
+    } else {
+        echo "None";
+    }
+    echo "</li>\n";
+
+    if ($major > 3) {
+        echo " <li><a 
href=\"/ChangeLog-{$major}.php#{$ver}\">ChangeLog</a></li>";
+    }
+    echo "\n <li>\n  Download:\n";
+    echo "<ul>\n";
+
+    if (!$museum) {
+        foreach(array_merge($source, $windows) as $src) {
+            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/>";
+                    }
+                }
+            } else {
+                echo "<a href=\"{$src['link']}\">{$src['name']}</a>";
+            }
+            echo " </li>\n";
+        }
+
+    } else { /* $museum */
+        foreach($source as $src) {
+            if (!isset($src["filename"])) {
+                continue;
+            }
+            printf('<li><a href="http://museum.php.net/php%d/%s";>%s</a></li>',
+                   $major, $src["filename"], $src["name"]);
+        }
+        foreach($windows as $src) {
+            printf('<li><a href="http://museum.php.net/%s/%s";>%s</a></li>',
+                   ($major == 5 ? "php5" : "win32"), $src["filename"], 
$src["name"]);
+        }
+    }
+
+    echo "</ul>\n";
+    echo "</li>\n";
+    echo "</ul>\n";
 }
diff --git a/src/News/Entry.php b/src/News/Entry.php
index c650125dd1..a106278c3d 100755
--- a/src/News/Entry.php
+++ b/src/News/Entry.php
@@ -3,194 +3,194 @@
 namespace phpweb\News;
 
 class Entry {
-       public const CATEGORIES = [
-               'frontpage'   => 'PHP.net frontpage news',
-               'releases'    => 'New PHP release',
-               'conferences' => 'Conference announcement',
-               'cfp'         => 'Call for Papers',
-       ];
-
-       public const WEBROOT = "https://www.php.net";;
-       public const PHPWEB = __DIR__ . '/../../';
-       public const ARCHIVE_FILE_REL = 'archive/archive.xml';
-       public const ARCHIVE_FILE_ABS = self::PHPWEB . self::ARCHIVE_FILE_REL;
-       public const ARCHIVE_ENTRIES_REL = 'archive/entries/';
-       public const ARCHIVE_ENTRIES_ABS = self::PHPWEB . 
self::ARCHIVE_ENTRIES_REL;
-       public const IMAGE_PATH_REL = 'images/news/';
-       public const IMAGE_PATH_ABS = self::PHPWEB . self::IMAGE_PATH_REL;
-
-
-       protected $title = '';
-
-       public function setTitle(string $title): self {
-               $this->title = $title;
-               return $this;
-       }
-
-       protected $categories = [];
-       public function setCategories(array $cats): self {
-               foreach ($cats as $cat) {
-                       if (!isset(self::CATEGORIES[$cat])) {
-                               throw new \Exception("Unknown category: $cat");
-                       }
-               }
-               $this->categories = $cats;
-               return $this;
-       }
-       public function addCategory(string $cat): self {
-               if (!isset(self::CATEGORIES[$cat])) {
-                       throw new \Exception("Unknown category: $cat");
-               }
-               if (!in_array($cat, $this->categories)) {
-                       $this->categories[] = $cat;
-               }
-               return $this;
-       }
-
-       public function isConference(): bool {
-               return (bool)array_intersect($this->categories, ['cfp', 
'conferences']);
-       }
-
-       protected $conf_time = 0;
-       public function setConfTime(int $time): self {
-               $this->conf_time = $time;
-               return $this;
-       }
-
-       protected $image = [];
-       public function setImage(string $path, string $title, ?string $link): 
self {
-               if (basename($path) !== $path) {
-                       throw new \Exception('path must be a simple file name 
under ' . self::IMAGE_PATH_REL);
-               }
-               if (!file_exists(self::IMAGE_PATH_ABS . $path)) {
-                       throw new \Exception('Image not found at web-php/' . 
self::IMAGE_PATH_REL . $path);
-               }
-               $this->image = [
-                       'path' => $path,
-                       'title' => $title,
-                       'link' => $link,
-               ];
-               return $this;
-       }
-
-       protected $content = '';
-       public function setContent(string $content): self {
-               if (empty($content)) {
-                       throw new \Exception('Content must not be empty');
-               }
-               $this->content = $content;
-               return $this;
-       }
-
-       protected $id = '';
-       private static function selectNextId(): string {
-               $filename = date("Y-m-d", $_SERVER["REQUEST_TIME"]);
-               $count = 0;
-               do {
-                       ++$count;
-                       $id = $filename . "-" . $count;
-                       $basename  = "{$id}.xml";
-               } while (file_exists(self::ARCHIVE_ENTRIES_ABS . $basename));
-
-               return $id;
-       }
-       public function getId(): string {
-               return $this->id;
-       }
-
-       public function save(): self {
-               if (empty($this->id)) {
-                       $this->id = self::selectNextId();
-               }
-
-               // Create the XML document.
-               $dom = new \DOMDocument("1.0", "utf-8");
-               $dom->formatOutput = true;
-               $dom->preserveWhiteSpace = false;
-               $item = $dom->createElementNs("http://www.w3.org/2005/Atom";, 
"entry");
-
-               $href = self::WEBROOT . ($this->isConference() ? 
'/conferences/index.php' : '/index.php');
-               $archive = self::WEBROOT . "/archive/" . date('Y', 
$_SERVER['REQUEST_TIME']) . ".php#{$this->id}";
-               $link = ($this->image['link'] ?? null) ?: $archive;
-
-               self::ce($dom, "title", $this->title, [], $item);
-               self::ce($dom, "id", $archive, [], $item);
-               self::ce($dom, "published", date(DATE_ATOM), [], $item);
-               self::ce($dom, "updated", date(DATE_ATOM), [], $item);
-               self::ce($dom, "link", null, ['href' => "{$href}#{$this->id}", 
"rel"  => "alternate", "type" => "text/html"], $item);
-               self::ce($dom, "link", null, ['href' => $link, 'rel'  => 'via', 
'type' => 'text/html'], $item);
-
-               if (!empty($this->conf_time)) {
-                       
$item->appendChild($dom->createElementNs("http://php.net/ns/news";, 
"finalTeaserDate", date("Y-m-d", $this->conf_time)));
-               }
-
-               foreach ($this->categories as $cat) {
-                       self::ce($dom, "category", null, ['term' => $cat, 
"label" => self::CATEGORIES[$cat]], $item);
-               }
-
-               if ($this->image['path'] ?? '') {
-                       $image = 
$item->appendChild($dom->createElementNs("http://php.net/ns/news";, "newsImage", 
$this->image['path']));
-                       $image->setAttribute("link", $this->image['link']);
-                       $image->setAttribute("title", $this->image['title']);
-               }
-
-               $content = self::ce($dom, "content", null, [], $item);
-
-               // Slurp content into our DOM.
-               $tdoc = new \DOMDocument("1.0", "utf-8");
-               $tdoc->formatOutput = true;
-               if ($tdoc->loadXML("<div>{$this->content}    </div>")) {
-                       $content->setAttribute("type", "xhtml");
-                       $div = 
$content->appendChild($dom->createElement("div"));
-                       $div->setAttribute("xmlns", 
"http://www.w3.org/1999/xhtml";);
-                       foreach($tdoc->firstChild->childNodes as $node) {
-                               $div->appendChild($dom->importNode($node, 
true));
-                       }
-               } else {
-                       fwrite(STDERR, "There is something wrong with your 
xhtml, falling back to html");
-                       $content->setAttribute("type", "html");
-                       $content->nodeValue = $this->content;
-               }
-
-               $dom->appendChild($item);
-               $dom->save(self::ARCHIVE_ENTRIES_ABS . $this->id . ".xml");
-
-               return $this;
-       }
-
-       public function updateArchiveXML(): self {
-               if (empty($this->id)) {
-                       throw new \Exception('Entry must be saved before 
updating archive XML');
-               }
-
-               $arch = new \DOMDocument("1.0", "utf-8");
-               $arch->formatOutput = true;
-               $arch->preserveWhiteSpace = false;
-               $arch->load(self::ARCHIVE_FILE_ABS);
-
-               $first = 
$arch->createElementNs("http://www.w3.org/2001/XInclude";, "xi:include");
-               $first->setAttribute("href", "entries/{$this->id}.xml");
-
-               $second = 
$arch->getElementsByTagNameNs("http://www.w3.org/2001/XInclude";, 
"include")->item(0);
-               $arch->documentElement->insertBefore($first, $second);
-               $arch->save(self::ARCHIVE_FILE_ABS);
-
-               return $this;
-       }
-
-       private static function ce(\DOMDocument $d, string $name, $value, array 
$attrs = [], ?\DOMNode $to = null) {
-               if ($value) {
-                       $n = $d->createElement($name, $value);
-               } else {
-                       $n = $d->createElement($name);
-               }
-               foreach($attrs as $k => $v) {
-                       $n->setAttribute($k, $v);
-               }
-               if ($to) {
-                       return $to->appendChild($n);
-               }
-               return $n;
-       }
+    public const CATEGORIES = [
+        'frontpage'   => 'PHP.net frontpage news',
+        'releases'    => 'New PHP release',
+        'conferences' => 'Conference announcement',
+        'cfp'         => 'Call for Papers',
+    ];
+
+    public const WEBROOT = "https://www.php.net";;
+    public const PHPWEB = __DIR__ . '/../../';
+    public const ARCHIVE_FILE_REL = 'archive/archive.xml';
+    public const ARCHIVE_FILE_ABS = self::PHPWEB . self::ARCHIVE_FILE_REL;
+    public const ARCHIVE_ENTRIES_REL = 'archive/entries/';
+    public const ARCHIVE_ENTRIES_ABS = self::PHPWEB . 
self::ARCHIVE_ENTRIES_REL;
+    public const IMAGE_PATH_REL = 'images/news/';
+    public const IMAGE_PATH_ABS = self::PHPWEB . self::IMAGE_PATH_REL;
+
+
+    protected $title = '';
+
+    public function setTitle(string $title): self {
+        $this->title = $title;
+        return $this;
+    }
+
+    protected $categories = [];
+    public function setCategories(array $cats): self {
+        foreach ($cats as $cat) {
+            if (!isset(self::CATEGORIES[$cat])) {
+                throw new \Exception("Unknown category: $cat");
+            }
+        }
+        $this->categories = $cats;
+        return $this;
+    }
+    public function addCategory(string $cat): self {
+        if (!isset(self::CATEGORIES[$cat])) {
+            throw new \Exception("Unknown category: $cat");
+        }
+        if (!in_array($cat, $this->categories)) {
+            $this->categories[] = $cat;
+        }
+        return $this;
+    }
+
+    public function isConference(): bool {
+        return (bool)array_intersect($this->categories, ['cfp', 
'conferences']);
+    }
+
+    protected $conf_time = 0;
+    public function setConfTime(int $time): self {
+        $this->conf_time = $time;
+        return $this;
+    }
+
+    protected $image = [];
+    public function setImage(string $path, string $title, ?string $link): self 
{
+        if (basename($path) !== $path) {
+            throw new \Exception('path must be a simple file name under ' . 
self::IMAGE_PATH_REL);
+        }
+        if (!file_exists(self::IMAGE_PATH_ABS . $path)) {
+            throw new \Exception('Image not found at web-php/' . 
self::IMAGE_PATH_REL . $path);
+        }
+        $this->image = [
+            'path' => $path,
+            'title' => $title,
+            'link' => $link,
+        ];
+        return $this;
+    }
+
+    protected $content = '';
+    public function setContent(string $content): self {
+        if (empty($content)) {
+            throw new \Exception('Content must not be empty');
+        }
+        $this->content = $content;
+        return $this;
+    }
+
+    protected $id = '';
+    private static function selectNextId(): string {
+        $filename = date("Y-m-d", $_SERVER["REQUEST_TIME"]);
+        $count = 0;
+        do {
+            ++$count;
+            $id = $filename . "-" . $count;
+            $basename  = "{$id}.xml";
+        } while (file_exists(self::ARCHIVE_ENTRIES_ABS . $basename));
+
+        return $id;
+    }
+    public function getId(): string {
+        return $this->id;
+    }
+
+    public function save(): self {
+        if (empty($this->id)) {
+            $this->id = self::selectNextId();
+        }
+
+        // Create the XML document.
+        $dom = new \DOMDocument("1.0", "utf-8");
+        $dom->formatOutput = true;
+        $dom->preserveWhiteSpace = false;
+        $item = $dom->createElementNs("http://www.w3.org/2005/Atom";, "entry");
+
+        $href = self::WEBROOT . ($this->isConference() ? 
'/conferences/index.php' : '/index.php');
+        $archive = self::WEBROOT . "/archive/" . date('Y', 
$_SERVER['REQUEST_TIME']) . ".php#{$this->id}";
+        $link = ($this->image['link'] ?? null) ?: $archive;
+
+        self::ce($dom, "title", $this->title, [], $item);
+        self::ce($dom, "id", $archive, [], $item);
+        self::ce($dom, "published", date(DATE_ATOM), [], $item);
+        self::ce($dom, "updated", date(DATE_ATOM), [], $item);
+        self::ce($dom, "link", null, ['href' => "{$href}#{$this->id}", "rel"  
=> "alternate", "type" => "text/html"], $item);
+        self::ce($dom, "link", null, ['href' => $link, 'rel'  => 'via', 'type' 
=> 'text/html'], $item);
+
+        if (!empty($this->conf_time)) {
+            $item->appendChild($dom->createElementNs("http://php.net/ns/news";, 
"finalTeaserDate", date("Y-m-d", $this->conf_time)));
+        }
+
+        foreach ($this->categories as $cat) {
+            self::ce($dom, "category", null, ['term' => $cat, "label" => 
self::CATEGORIES[$cat]], $item);
+        }
+
+        if ($this->image['path'] ?? '') {
+            $image = 
$item->appendChild($dom->createElementNs("http://php.net/ns/news";, "newsImage", 
$this->image['path']));
+            $image->setAttribute("link", $this->image['link']);
+            $image->setAttribute("title", $this->image['title']);
+        }
+
+        $content = self::ce($dom, "content", null, [], $item);
+
+        // Slurp content into our DOM.
+        $tdoc = new \DOMDocument("1.0", "utf-8");
+        $tdoc->formatOutput = true;
+        if ($tdoc->loadXML("<div>{$this->content}    </div>")) {
+            $content->setAttribute("type", "xhtml");
+            $div = $content->appendChild($dom->createElement("div"));
+            $div->setAttribute("xmlns", "http://www.w3.org/1999/xhtml";);
+            foreach($tdoc->firstChild->childNodes as $node) {
+                $div->appendChild($dom->importNode($node, true));
+            }
+        } else {
+            fwrite(STDERR, "There is something wrong with your xhtml, falling 
back to html");
+            $content->setAttribute("type", "html");
+            $content->nodeValue = $this->content;
+        }
+
+        $dom->appendChild($item);
+        $dom->save(self::ARCHIVE_ENTRIES_ABS . $this->id . ".xml");
+
+        return $this;
+    }
+
+    public function updateArchiveXML(): self {
+        if (empty($this->id)) {
+            throw new \Exception('Entry must be saved before updating archive 
XML');
+        }
+
+        $arch = new \DOMDocument("1.0", "utf-8");
+        $arch->formatOutput = true;
+        $arch->preserveWhiteSpace = false;
+        $arch->load(self::ARCHIVE_FILE_ABS);
+
+        $first = $arch->createElementNs("http://www.w3.org/2001/XInclude";, 
"xi:include");
+        $first->setAttribute("href", "entries/{$this->id}.xml");
+
+        $second = 
$arch->getElementsByTagNameNs("http://www.w3.org/2001/XInclude";, 
"include")->item(0);
+        $arch->documentElement->insertBefore($first, $second);
+        $arch->save(self::ARCHIVE_FILE_ABS);
+
+        return $this;
+    }
+
+    private static function ce(\DOMDocument $d, string $name, $value, array 
$attrs = [], ?\DOMNode $to = null) {
+        if ($value) {
+            $n = $d->createElement($name, $value);
+        } else {
+            $n = $d->createElement($name);
+        }
+        foreach($attrs as $k => $v) {
+            $n->setAttribute($k, $v);
+        }
+        if ($to) {
+            return $to->appendChild($n);
+        }
+        return $n;
+    }
 }
 
diff --git a/submit-event.php b/submit-event.php
index 18d1f56305..4937c027bf 100644
--- a/submit-event.php
+++ b/submit-event.php
@@ -20,12 +20,12 @@
     }
 }
 $vars = array(
-       'type', 'country', 'category', 'email', 'url', 'ldesc', 'sdesc'
+    'type', 'country', 'category', 'email', 'url', 'ldesc', 'sdesc'
 );
 foreach($vars as $varname) {
-       if (!isset($_POST[$varname])) {
-               $_POST[$varname] = "";
-       }
+    if (!isset($_POST[$varname])) {
+        $_POST[$varname] = "";
+    }
 }
 
 // We need to process some form data
diff --git a/supported-versions.php b/supported-versions.php
index 8608886d2d..d0df826e45 100644
--- a/supported-versions.php
+++ b/supported-versions.php
@@ -50,11 +50,11 @@
                        <?php ksort($releases) ?>
                        <?php foreach ($releases as $branch => $release): ?>
                                <?php
-                               $state = get_branch_support_state($branch);
-                               $initial = get_branch_release_date($branch);
-                               $until = get_branch_bug_eol_date($branch);
-                               $eol = get_branch_security_eol_date($branch);
-                               ?>
+                $state = get_branch_support_state($branch);
+                $initial = get_branch_release_date($branch);
+                $until = get_branch_bug_eol_date($branch);
+                $eol = get_branch_security_eol_date($branch);
+                ?>
                                <tr class="<?php echo $state ?>">
                                        <td>
                                                <a href="/downloads.php#v<?php 
echo htmlspecialchars($release['version']) ?>"><?php echo 
htmlspecialchars($branch) ?></a>
diff --git a/urlhowto.php b/urlhowto.php
index 0ea3c03291..6cc075c0a3 100644
--- a/urlhowto.php
+++ b/urlhowto.php
@@ -27,7 +27,7 @@
 site_header("URL Howto", array("current" => "help"));
 function a($href): void {
     global $MYSITE;
-       echo '<a href="' . $MYSITE . $href . '">' . $MYSITE . $href . '</a>';
+    echo '<a href="' . $MYSITE . $href . '">' . $MYSITE . $href . '</a>';
 }
 
 ?>

-- 
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to