prettier package descriptions
[pharext/replicator.pharext.org] / public / html.php
1 <?php
2 const INCLUDED = __FILE__;
3 const NCURRENT = 2;
4
5 $css = "concise/css/concise.min.css";
6 $fnt = "//fonts.googleapis.com/css?family=Droid+Sans";
7
8 require_once "index.php";
9
10 ob_start($res);
11 $res->addHeader("Link", "<" . dirname((new http\Env\Url)->path) . $css . ">; rel=preload; as=style");
12
13 ?>
14 <!doctype html>
15 <html>
16 <head>
17 <meta charset="utf-8">
18 <title>Replicator</title>
19 <link rel="stylesheet" href="<?=$css?>">
20 <link rel="stylesheet" href="<?=$fnt?>">
21 <meta name="viewport" content="width=device-width, initial-scale=1">
22 <style>
23 body {
24 padding-bottom: 2em;
25 padding-top: 7em;
26 }
27 .header {
28 top: 0;
29 width: 100%;
30 }
31 .footer {
32 bottom: 0;
33 width: 100%;
34 text-align: center;
35 font-size: .9em;
36 }
37 .header, .footer {
38 position: fixed;
39 box-shadow: 0px 0px .8em .4em #89a;
40 background: #62B3E7;
41 padding: .5em 0;
42 }
43 .header h1 {
44 font-weight: bold;
45 }
46 .header h1 a, .footer a:hover {
47 text-decoration: none;
48 }
49 .header h1 a:hover {
50 text-decoration: underline;
51 }
52 .header h1 a {
53 /* normalize browser difference */
54 font-size: 1.3em;
55 }
56 .header h1 a, .footer, .footer a {
57 color: #fdfdfd;
58 text-shadow: grey 0 0 .1em;
59 }
60 .header h1 small {
61 color: #666;
62 font-size: 1.3rem;
63 text-shadow: white 0 0 .2em;
64 }
65 li {
66 list-style-type: circle;
67 }
68 pre.publickey {
69 font-size: .8rem;
70 line-height: 1rem;
71 }
72 pre.code {
73 background: #333;
74 color: #62B3E7;
75 padding: 0 1.5em 1.5em 1em;
76 border-radius: 4px;
77 margin-right: 2em;
78 display: inline-block;
79 }
80 pre.code>code {
81 font-size: .9rem;
82 }
83 .row>h3 {
84 margin-bottom: 0;
85 }
86 @media(max-width: 80em) {
87 .column-8 {
88 float: none;
89 width: auto;
90 }
91 }
92 .old-version, #new-toggle {
93 display: none;
94 }
95 p.package-description, div.package-description p {
96 white-space: pre-line;
97 }
98 form * {
99 display: inline-block;
100 margin-right: 1em;
101 }
102 form label input{
103 margin-left: 1em;
104 vertical-align: middle;
105 }
106 form input[type=reset] {
107 padding: 0;
108 }
109 </style>
110 </head>
111 <body>
112 <div class="header">
113 <header>
114 <h1 class="container">
115 <a href="?">Replicator</a><br>
116 <small>Replicating PECL releases as pharext packages since 2015</small>
117 </h1>
118 <a href="https://github.com/m6w6/replicator"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
119 </header>
120 </div>
121 <div class="container">
122
123 <?php if (!empty($package)) : $versions = package_versions($package); $info = package_info($package); ?>
124
125 <h2><?= htmlspecialchars($package) ?></h2>
126 <?php if ($info) : ?>
127 <h3><?= htmlspecialchars($info["title"]) ?><br>
128 <small>License: <?= htmlspecialchars($info["license"]) ?><br>
129 <a href="//pecl.php.net/package/<?= htmlspecialchars($package) ?>">View at PECL</a></small></h3>
130 <?php if (extension_loaded("discount")) : ?>
131 <div class="package-description">
132 <?php
133 $md = MarkdownDocument::createFromString($info["description"]);
134 $md->compile( MarkdownDocument::AUTOLINK |
135 MarkdownDocument::ONE_COMPAT);
136 echo $md->getHtml();
137 ?>
138 </div>
139 <?php else : ?>
140 <p class="package-description">
141 <?= htmlspecialchars($info["description"]) ?>
142 </p>
143 <?php endif; ?>
144 <?php endif; ?>
145 <table class="table table-full versions">
146 <thead>
147 <tr>
148 <th class="text-left" colspan="2">Package</th>
149 <th class="text-left" colspan="<?= count(SIGS) ?>">Signatures</th>
150 <th class="text-left">Date</th>
151 <th class="text-right">Pharext</th>
152 </tr>
153 </thead>
154 <tbody>
155
156 <?php $i = 0; foreach (array_reverse($versions) as $version => $phars) : ++$i; ?>
157 <?php foreach (array_map("array_values", $phars) as $ext => list($phar, $date, $size, $pharext)) : ?>
158 <tr <?php if ($i > NCURRENT) : ?>class="old-version"<?php endif; ?> <?php if ($i === NCURRENT) : ?>id="old"<?php endif; ?>>
159 <?php if (empty($ext)) : ?>
160 <td class="text-left" rowspan="<?= count($phars) ?>">
161 <?= htmlspecialchars($package) ?>
162 <?= htmlspecialchars($version) ?>
163 </td>
164 <?php endif ?>
165
166 <td class="text-left">
167 &#10507;&nbsp;<a href="<?= htmlspecialchars($phar) ?>"
168 download>phar<?= htmlspecialchars($ext) ?></a>&nbsp;<small>(<?= human_size($size) ?>)</small><br>
169 </td>
170 <?php foreach (SIGS as $typ => $sig) : ?>
171 <td>
172 #&nbsp;<a href="<?= sigof($phar, $sig) ?>" download><?= "$typ.$sig" ?></a>
173 </td>
174 <?php endforeach; ?>
175 <td class="text-left">
176 <?= human_date($date); ?>
177
178 </td>
179 <td class="text-right <?= version_compare($pharext, "3.0.1", "<") ? "color-red":"" ?>">
180 v<?= $pharext ?>
181 </td>
182 </tr>
183 <?php endforeach; ?>
184 <?php endforeach; ?>
185
186 </tbody>
187 </table>
188 <?php if ($i >= 3) : ?>
189 <p class="small">
190 <a id="old-toggle" href="#old" onclick="toggleOldVersions(this)">Show
191 <?=count($versions)-NCURRENT?> older version(s) &raquo;</a>
192 <a id="new-toggle" href="#" onclick="toggleOldVersions(this)">Show
193 less versions &laquo;</a>
194 </p>
195 <?php endif; ?>
196 <?php else: ?>
197
198 <h2>Available Packages</h2>
199 <form name="search"></form>
200 <ul class="list-inline package-list">
201 <?php foreach (array_map("htmlspecialchars", $packages) as $index => $pkg) : ?>
202 <?php $next = strtolower($pkg[0]); ?>
203 <?php if (isset($prev) && $next != $prev) : ?>
204
205 </ul>
206 <ul class="list-inline package-list">
207 <?php endif; ?>
208
209 <li id="<?= strtolower($pkg) ?>"><a href="?<?= $pkg ?>"><?= $pkg ?></a></li>
210 <?php $prev = $next; ?>
211 <?php endforeach; ?>
212
213 </ul>
214 <?php endif; ?>
215 <hr>
216 <div class="row">
217 <?php if (empty($package)) : ?>
218 <h3>Public keys</h3>
219 <?php else : list($phar) = array_values(current(end($versions))); ?>
220 <h3>Download latest version and signatures:</h3>
221 <div class="column-16">
222 <pre class="code fit-code"><code>
223 curl -sS \
224 -O https://replicator.pharext.org/<?= htmlspecialchars($phar) ?><?php foreach (SIGS as $sig) : ?> \
225 -O https://replicator.pharext.org/<?= htmlspecialchars(sigof($phar, $sig)) ?><?php endforeach; ?></code></pre>
226 </div>
227 </div>
228 <div class="row">
229 <h3>Verify with a public key:</h3>
230 <?php endif; ?>
231
232 <div class="column-8">
233 <h4>RSA <small><a href="replicator.pub" download>replicator.pub</a></small></h4>
234 <?php if (!empty($phar)) : ?>
235 <pre class="code"><code>
236 curl -sSO https://replicator.pharext.org/replicator.pub
237
238 openssl dgst \
239 -verify replicator.pub \
240 -signature <?= htmlspecialchars(basename($phar)).".sig" ?> \
241 <?= htmlspecialchars(basename($phar)) ?></code></pre>
242 <?php endif; ?>
243 <pre class="publickey"><?php readfile("./replicator.pub") ?></pre>
244 </div>
245 <div class="column-8">
246 <h4>OpenPGP <small><a href="4093AEF6.pub" download>4093AEF6.pub</a></small></h4>
247 <?php if (!empty($phar)) : ?>
248 <pre class="code"><code>
249 curl -sSO https://replicator.pharext.org/4093AEF6.pub
250
251 gpg --import 4093AEF6.pub
252
253 gpg --verify <?= htmlspecialchars(basename($phar)).".asc" ?> \
254 <?= htmlspecialchars(basename($phar)) ?></code></pre>
255 <?php endif; ?>
256 <pre class="publickey"><?php readfile("./4093AEF6.pub") ?></pre>
257 </div>
258 </div>
259 </div>
260 <div class="footer">
261 <footer>
262 &copy; 2015 <a href="https://m6w6.name">m6w6</a>, Michael Wallner &mdash; Powered by <a href="//github.com/m6w6/pharext">pharext
263 <?php
264 require_once "../vendor/autoload.php";
265 printf("v%s\n", pharext\Metadata::version());
266 ?>
267 </a>
268 </footer>
269 </div>
270 <script type="text/javascript">
271 function searchPackages(search, regex) {
272 console.log("searchPackages", search, regex);
273 document.querySelectorAll("ul.package-list li").forEach(function(li) {
274 if (regex) {
275 if (li.id.match(search.toLowerCase())) {
276 li.style.removeProperty("display");
277 } else {
278 li.style.display = "none";
279 }
280 } else {
281 if (li.id.startsWith(search.toLowerCase())) {
282 li.style.removeProperty("display");
283 } else {
284 li.style.display = "none";
285 }
286 }
287 });
288 }
289
290 document.body.onload = function() {
291 var form = document.querySelector("form[name=search]");
292 var input = document.createElement("input");
293 var reset = document.createElement("input");
294 var prefix_label = document.createElement("label");
295 var prefix = document.createElement("input");
296 var regex_label = document.createElement("label");
297 var regex = document.createElement("input");
298
299 form.onreset = function() {
300 searchPackages("", false);
301 };
302
303 input.id = "s";
304 input.autocomplete = "off";
305 input.name = "s";
306 input.type = "search";
307 input.placeholder = "Search...";
308 input.oninput = function() {
309 searchPackages(input.value, regex.checked);
310 };
311 input.style.paddingRight = "4ch";
312 form.appendChild(input);
313
314 reset.id = "r";
315 reset.name = "r";
316 reset.type = "reset";
317 reset.value = "☒";
318 reset.title = "Reset";
319 reset.style.marginLeft = "-4ch";
320 reset.style.marginRight = "4ch";
321 reset.style.border = "none";
322 reset.style.background = "transparent";
323 form.appendChild(reset);
324
325 prefix.id = "prefix";
326 prefix.name = "by";
327 prefix.value = "prefix";
328 prefix.type = "radio";
329 prefix.defaultChecked = true;
330 prefix.checked = true;
331 prefix.onchange = function() {
332 searchPackages(input.value, regex.checked);
333 };
334 //form.appendChild(prefix);
335 prefix_label.innerText = "by Prefix";
336 prefix_label.appendChild(prefix);
337 form.appendChild(prefix_label);
338
339 regex.id = "regex";
340 regex.name = "by";
341 regex.value = "regex";
342 regex.type = "radio";
343 regex.checked = false;
344 regex.onchange = function() {
345 searchPackages(input.value, regex.checked);
346 };
347 //form.appendChild(regex);
348 regex_label.innerText = "by RegExp";
349 regex_label.appendChild(regex);
350 form.appendChild(regex_label);
351
352 input.focus();
353 };
354
355 function toggleOldVersions(a) {
356 var nodes, row_style;
357
358 if (a.hash.substring(1) === "old") {
359 row_style = "table-row";
360 document.getElementById("old-toggle").style.display = "none";
361 document.getElementById("new-toggle").style.display = "inline";
362 } else {
363 row_style = "none";
364 document.getElementById("old-toggle").style.display = "inline";
365 document.getElementById("new-toggle").style.display = "none";
366 }
367
368 nodes = document.querySelectorAll("table.versions>tbody>tr.old-version");
369
370 for (var i = 0; i < nodes.length; ++i) {
371 nodes.item(i).style.display = row_style;
372 }
373 }
374 </script>
375 </body>
376 </html>
377 <?php
378 $res->send();
379 ?>