mirror of
https://github.com/php/web-php.git
synced 2026-03-23 23:02:13 +01:00
Enhancement: Enable indentation_type fixer
Closes GH-622.
This commit is contained in:
@@ -10,6 +10,7 @@ $finder = $config->getFinder()
|
||||
->name(__FILE__);
|
||||
|
||||
$config->setRules([
|
||||
'indentation_type' => true,
|
||||
'no_trailing_whitespace' => true,
|
||||
'visibility_required' => true,
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
|
||||
@@ -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';
|
||||
|
||||
6
docs.php
6
docs.php
@@ -29,9 +29,9 @@ site_header("Documentation", array("current" => "docs"));
|
||||
// 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>"; }
|
||||
|
||||
22
eol.php
22
eol.php
@@ -7,17 +7,17 @@ include_once __DIR__ . '/include/branches.inc';
|
||||
// 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');
|
||||
|
||||
@@ -158,7 +158,7 @@ if (count($_POST) && (!isset($_POST['purpose']) || !is_array($_POST['purpose'])
|
||||
} // endif: no data or checkread not checked
|
||||
|
||||
else {
|
||||
if (count($_POST)) {
|
||||
if (count($_POST)) {
|
||||
print <<<EOT
|
||||
<div class="warning">
|
||||
<p>
|
||||
@@ -361,9 +361,9 @@ EOT;
|
||||
<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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,49 +11,49 @@ $branch_height = 30;
|
||||
$footer_height = 24;
|
||||
|
||||
function branches_to_show() {
|
||||
// Basically: show all 5.3+ branches with EOL dates > min_date().
|
||||
$branches = array();
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
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 @@ $height = $header_height + $footer_height + (count($branches) * $branch_height);
|
||||
<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 @@ $height = $header_height + $footer_height + (count($branches) * $branch_height);
|
||||
<!-- 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') ?>
|
||||
|
||||
@@ -180,7 +180,7 @@ if (is_array($CONF_TEASER)) {
|
||||
);
|
||||
$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>';
|
||||
|
||||
@@ -13,9 +13,9 @@ if (!empty($_GET['function']) && is_string($_GET['function'])) {
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ $mirror_stats = (int) (isset($_SERVER['MIRROR_STATS']) && $_SERVER['MIRROR_STATS
|
||||
$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?
|
||||
|
||||
@@ -22,7 +22,7 @@ to upgrade to this release.
|
||||
non-namespaced classes.
|
||||
|
||||
<p><?php
|
||||
highlight_string('<?php
|
||||
highlight_string('<?php
|
||||
namespace Foo;
|
||||
class Bar {
|
||||
public function Bar() {
|
||||
@@ -31,7 +31,7 @@ class 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>
|
||||
|
||||
@@ -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 的改进和修复',
|
||||
'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 函数。',
|
||||
'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> 类对象。',
|
||||
'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>
|
||||
'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> 中有变更历史记录清单。
|
||||
|
||||
@@ -4,70 +4,70 @@ include_once __DIR__ . '/../include/prepend.inc';
|
||||
include_once __DIR__ . "/../include/branches.inc";
|
||||
|
||||
if (isset($_GET["serialize"]) || isset($_GET["json"])) {
|
||||
$RELEASES = $RELEASES + $OLDRELEASES;
|
||||
$RELEASES = $RELEASES + $OLDRELEASES;
|
||||
|
||||
$machineReadable = [];
|
||||
$machineReadable = [];
|
||||
|
||||
$supportedVersions = [];
|
||||
foreach (get_active_branches(false) as $major => $releases) {
|
||||
$supportedVersions[$major] = array_keys($releases);
|
||||
}
|
||||
$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($_GET["version"])) {
|
||||
$versionArray = version_array($_GET["version"]);
|
||||
$ver = $versionArray[0];
|
||||
|
||||
if (isset($RELEASES[$ver])) {
|
||||
$combinedReleases = array_replace_recursive($RELEASES, $OLDRELEASES);
|
||||
if (isset($RELEASES[$ver])) {
|
||||
$combinedReleases = array_replace_recursive($RELEASES, $OLDRELEASES);
|
||||
|
||||
$max = (int) ($_GET['max'] ?? 1);
|
||||
if ($max == -1) {
|
||||
$max = PHP_INT_MAX;
|
||||
}
|
||||
$max = (int) ($_GET['max'] ?? 1);
|
||||
if ($max == -1) {
|
||||
$max = PHP_INT_MAX;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ($combinedReleases[$ver] as $version => $release) {
|
||||
if ($max <= $count) {
|
||||
break;
|
||||
}
|
||||
$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 (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 (!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 (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;
|
||||
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 @@ echo "<p>
|
||||
$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";
|
||||
}
|
||||
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)
|
||||
);
|
||||
}
|
||||
$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 @@ site_footer(['sidebar' =>
|
||||
']);
|
||||
|
||||
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);
|
||||
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 ($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 ($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";
|
||||
}
|
||||
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"]);
|
||||
}
|
||||
}
|
||||
} 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";
|
||||
echo "</ul>\n";
|
||||
echo "</li>\n";
|
||||
echo "</ul>\n";
|
||||
}
|
||||
|
||||
@@ -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 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;
|
||||
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 = '';
|
||||
protected $title = '';
|
||||
|
||||
public function setTitle(string $title): self {
|
||||
$this->title = $title;
|
||||
return $this;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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']);
|
||||
}
|
||||
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 $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 $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 $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));
|
||||
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;
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function save(): self {
|
||||
if (empty($this->id)) {
|
||||
$this->id = self::selectNextId();
|
||||
}
|
||||
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");
|
||||
// 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;
|
||||
$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);
|
||||
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)));
|
||||
}
|
||||
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);
|
||||
}
|
||||
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']);
|
||||
}
|
||||
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);
|
||||
$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;
|
||||
}
|
||||
// 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");
|
||||
$dom->appendChild($item);
|
||||
$dom->save(self::ARCHIVE_ENTRIES_ABS . $this->id . ".xml");
|
||||
|
||||
return $this;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function updateArchiveXML(): self {
|
||||
if (empty($this->id)) {
|
||||
throw new \Exception('Entry must be saved before updating archive XML');
|
||||
}
|
||||
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);
|
||||
$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");
|
||||
$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);
|
||||
$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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ foreach ($vars as $varname) {
|
||||
}
|
||||
}
|
||||
$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
|
||||
|
||||
@@ -50,11 +50,11 @@ $VERSION_NOTES = array(
|
||||
<?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>
|
||||
|
||||
@@ -27,7 +27,7 @@ $SIDEBAR_DATA='
|
||||
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>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user