xref: /web-php/index.php (revision c89bec8f)
1<?php
2
3(function ($uri): void {
4    // Special redirect cases not able to be captured in error.php
5    $shortcuts = [
6        '/?:' => '/language.operators.comparison#language.operators.comparison.ternary',
7        '/??' => '/language.operators.comparison#language.operators.comparison.coalesce',
8        '/??=' => '/language.operators.assignment#language.operators.assignment.other',
9    ];
10    if (isset($shortcuts[$uri])) {
11        header("Location: {$shortcuts[$uri]}");
12        exit;
13    }
14})($_SERVER['REQUEST_URI'] ?? '');
15
16// Get the modification date of this PHP file
17$timestamps = [@getlastmod()];
18
19/*
20   The date of prepend.inc represents the age of ALL
21   included files. Please touch it if you modify any
22   other include file (and the modification affects
23   the display of the index page). The cost of stat'ing
24   them all is prohibitive.
25*/
26$timestamps[] = @filemtime("include/prepend.inc");
27
28// These are the only dynamic parts of the frontpage
29$timestamps[] = @filemtime("include/pregen-confs.inc");
30$timestamps[] = @filemtime("include/pregen-news.inc");
31$timestamps[] = @filemtime("include/version.inc");
32$timestamps[] = @filemtime("js/common.js");
33
34// The latest of these modification dates is our real Last-Modified date
35$timestamp = max($timestamps);
36
37// Note that this is not a RFC 822 date (the tz is always GMT)
38$tsstring = gmdate("D, d M Y H:i:s ", $timestamp) . "GMT";
39
40// Check if the client has the same page cached
41if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) &&
42    ($_SERVER["HTTP_IF_MODIFIED_SINCE"] == $tsstring)) {
43    header("HTTP/1.1 304 Not Modified");
44    exit();
45}
46
47// Inform the user agent what is our last modification date
48header("Last-Modified: " . $tsstring);
49
50$_SERVER['BASE_PAGE'] = 'index.php';
51include_once 'include/prepend.inc';
52include_once 'include/branches.inc';
53include_once 'include/pregen-confs.inc';
54include_once 'include/pregen-news.inc';
55include_once 'include/version.inc';
56
57mirror_setcookie("LAST_NEWS", $_SERVER["REQUEST_TIME"], 60 * 60 * 24 * 365);
58
59$content = "<div class='home-content'>";
60$frontpage = [];
61foreach ($NEWS_ENTRIES as $entry) {
62    foreach ($entry["category"] as $category) {
63        if ($category["term"] == "frontpage") {
64            $frontpage[] = $entry;
65            if (count($frontpage) >= 25) {
66                break 2;
67            }
68        }
69    }
70}
71foreach ($frontpage as $entry) {
72    $link = preg_replace('~^(http://php.net/|https://www.php.net/)~', '', $entry["id"]);
73    $id = parse_url($entry["id"], PHP_URL_FRAGMENT);
74    $date = date_create($entry['updated']);
75    $date_human = date_format($date, 'd M Y');
76    $date_w3c = date_format($date, DATE_W3C);
77    $content .= <<<NEWSENTRY
78<article class="newsentry">
79  <header class="title">
80    <time datetime="$date_w3c">$date_human</time>
81    <h2 class="newstitle">
82      <a href="{$MYSITE}{$link}" id="{$id}">{$entry["title"]}</a>
83    </h2>
84  </header>
85  <div class="newscontent">
86    {$entry["content"]}
87  </div>
88</article>
89NEWSENTRY;
90}
91$content .= '<p class="archive"><a href="/archive/">Older News Entries</a></p>';
92$content .= "</div>";
93
94$intro = <<<EOF
95  <div class="hero">
96    <img class="hero-logo" src="/images/logos/php-logo-white.svg" alt="php" width="240" height="120">
97    <p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p>
98    <div class="hero-actions">
99      <a href="/releases/8.3/index.php" class="hero-btn hero-btn-primary">What's new in 8.3</a>
100      <a href="/downloads.php" class="hero-btn hero-btn-secondary">Download</a>
101    </div>
102EOF;
103
104$intro .= "<ul class='hero-versions'>\n";
105$active_branches = get_active_branches();
106krsort($active_branches);
107foreach ($active_branches as $major => $releases) {
108    krsort($releases);
109    foreach ((array)$releases as $release) {
110        $version = $release['version'];
111        [$major, $minor, $_] = explode('.', $version);
112        $intro .= "
113            <li class='hero-version'><a class='hero-version-link' href='/downloads.php#v$version'>$version</a> &middot; <a class='notes' href='/ChangeLog-$major.php#$version'>Changelog</a> &middot; <a class='notes' href='/migration$major$minor'>Upgrading</a></li>\n";
114    }
115}
116$intro .= "</ul>\n";
117$intro .= <<<EOF
118  </div>
119EOF;
120
121// Write out common header
122$meta_image_path = $MYSITE . 'images/meta-image.png';
123$meta_description = "PHP is a popular general-purpose scripting language that powers everything from your blog to the most popular websites in the world.";
124
125site_header("Hypertext Preprocessor",
126    [
127        'current' => 'home',
128        'headtags' => [
129            '<link rel="alternate" type="application/atom+xml" title="PHP: Hypertext Preprocessor" href="' . $MYSITE . 'feed.atom">',
130            '<script>',
131            "function okc(f){var c=[38,38,40,40,37,39,37,39,66,65,13],x=function(){x.c=x.c||Array.apply({},c);x.r=function(){x.c=null};return x.c},h=function(e){if(x()[0]==(e||window.event).keyCode){x().shift();if(!x().length){x.r();f()}}else{x.r()}};window.addEventListener?window.addEventListener('keydown',h,false):document.attachEvent('onkeydown',h)}",
132            "okc(function(){if(document.getElementById){i=document.getElementById('phplogo');i.src='" . $MYSITE . "images/php_konami.gif'}});",
133            '</script>',
134        ],
135        'link' => [
136            [
137                "rel" => "search",
138                "type" => "application/opensearchdescription+xml",
139                "href" => $MYSITE . "phpnetimprovedsearch.src",
140                "title" => "Add PHP.net search",
141            ],
142            [
143                "rel" => "alternate",
144                "type" => "application/atom+xml",
145                "href" => $MYSITE . "releases/feed.php",
146                "title" => "PHP Release feed",
147            ],
148
149        ],
150        'css' => ['home.css'],
151        'intro' => $intro,
152        'meta_tags' => <<<META
153<meta name="Description" content="{$meta_description}" />
154
155<meta name="twitter:card" content="summary_large_image" />
156<meta name="twitter:site" content="@official_php" />
157<meta name="twitter:title" content="PHP: Hypertext Preprocessor" />
158<meta name="twitter:description" content="{$meta_description}" />
159<meta name="twitter:creator" content="@official_php" />
160<meta name="twitter:image:src" content="{$meta_image_path}" />
161
162<meta itemprop="name" content="PHP: Hypertext Preprocessor" />
163<meta itemprop="description" content="$meta_description" />
164<meta itemprop="image" content="{$meta_image_path}" />
165
166<meta property="og:image" content="{$meta_image_path}" />
167<meta property="og:description" content="$meta_description" />
168
169<link href="https://fosstodon.org/@php" rel="me" />
170META
171    ],
172);
173
174// Print body of home page.
175echo $content;
176
177// Prepare announcements.
178if (is_array($CONF_TEASER)) {
179    $conftype = [
180        'conference' => 'Upcoming conferences',
181        'cfp' => 'Conferences calling for papers',
182    ];
183    $announcements = "";
184    foreach ($CONF_TEASER as $category => $entries) {
185        if ($entries) {
186            $announcements .= '<div class="panel">';
187            $announcements .= '  <a href="/conferences" class="headline" title="' . $conftype[$category] . '">' . $conftype[$category] . '</a>';
188            $announcements .= '<div class="body"><ul>';
189            foreach (array_slice($entries, 0, 4) as $url => $title) {
190                $title = preg_replace("'([A-Za-z0-9])([\s:\-,]*?)call for(.*?)$'i", "$1", $title);
191                $announcements .= "<li><a href='$url' title='$title'>$title</a></li>";
192            }
193            $announcements .= '</ul></div>';
194            $announcements .= '</div>';
195        }
196    }
197} else {
198    $announcements = '';
199}
200
201$SIDEBAR = <<<SIDEBAR_DATA
202
203    <div class='panel'>
204      <a href='https://thephp.foundation/' class='headline'>The PHP Foundation</a>
205      <div class='body'>
206        <p>The PHP Foundation is a collective of people and organizations, united in the mission to ensure the long-term prosperity of the PHP language.
207        <p><a href='https://thephp.foundation/donate/' class='btn btn-primary'>Donate</a></p>
208      </div>
209    </div>
210$announcements
211    <p class='panel'><a href='/cal.php'>User Group Events</a></p>
212    <p class='panel'><a href='/thanks.php'>Special Thanks</a></p>
213    <div class='panel social-media'>
214      <span class='headline'>Social media</span>
215      <div class='body'>
216        <ul>
217          <li>
218            <a href="https://twitter.com/official_php">
219              <i class="icon-x-twitter"></i>
220              @official_php
221            </a>
222          </li>
223          <li>
224            <a href="https://fosstodon.org/@php">
225              <i class="icon-mastodon"></i>
226              @php@fosstodon.org
227            </a>
228          </li>
229        </ul>
230      </div>
231    </div>
232
233SIDEBAR_DATA;
234
235// Print the common footer.
236site_footer([
237    "atom" => "/feed.atom", // Add a link to the feed at the bottom
238    'elephpants' => true,
239    'sidebar' => $SIDEBAR,
240]);
241