mirror of
git://f0xx.org/android_cast
synced 2026-07-29 04:38:53 +03:00
footer changes, remote access changes
This commit is contained in:
@@ -2,17 +2,46 @@
|
||||
|
||||
## Footer (`footer.php`)
|
||||
|
||||
Single copyright footer for hub, crashes, tickets, graphs, and builder consoles.
|
||||
Flexible site-wide footer for hub, crashes, tickets, graphs, and builder consoles.
|
||||
|
||||
**Configure:** edit `footer.config.php` (copy from `footer.config.example.php`).
|
||||
|
||||
### Layout
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ top (optional, full width) │
|
||||
├──────────────────────────┬──────────────────┤
|
||||
│ left (optional / auto) │ right (optional) │
|
||||
├──────────────────────────┴──────────────────┤
|
||||
│ bottom (optional, full width) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
When `left` is null, the left column is built from `copyright_symbol`, `holder`, and year settings.
|
||||
|
||||
| Key | Purpose |
|
||||
|-----|---------|
|
||||
| `holder` | Copyright name |
|
||||
| `copyright_symbol` | `(c)` or `©` |
|
||||
| `show_year` | Append year |
|
||||
| `year` | Fixed year, or `null` for current |
|
||||
| `use_i18n` | `data-i18n` for consoles with `i18n.js` |
|
||||
| `top` | Full-width line above main row (`null` = hidden) |
|
||||
| `left` | Main left text; `null` = auto copyright line |
|
||||
| `right` | Main right text (e.g. build id, links) |
|
||||
| `bottom` | Full-width line below main row |
|
||||
| `holder` | Copyright name (default left) |
|
||||
| `copyright_symbol` | `©` (U+00A9) or empty |
|
||||
| `show_year` | Append year / range on default left |
|
||||
| `year` | Fixed end year, or `null` for current |
|
||||
| `year_start` | If set (e.g. `2026`), shows `2026–{current}` |
|
||||
| `use_i18n` | `data-i18n` on auto-built left column |
|
||||
| `footer_class` | Extra CSS class (always adds `platform-footer`) |
|
||||
|
||||
**Per-page override** when rendering:
|
||||
|
||||
```php
|
||||
platform_render_footer([
|
||||
'right' => 'OTA: staging',
|
||||
'bottom' => 'Internal only',
|
||||
]);
|
||||
```
|
||||
|
||||
**In PHP views:** `<?php platform_render_footer(); ?>` (loaded via each app `bootstrap.php`).
|
||||
|
||||
|
||||
@@ -4,19 +4,34 @@ declare(strict_types=1);
|
||||
/**
|
||||
* Site-wide footer (hub, crashes, tickets, graphs, builder).
|
||||
* Copy to footer.config.php and edit; footer.config.php is optional (defaults apply).
|
||||
*
|
||||
* Layout (empty/null row = hidden):
|
||||
* top — full-width line above main row
|
||||
* main — left | right (flex); invisible gap between columns
|
||||
* bottom — full-width line below main row
|
||||
*
|
||||
* Left column: set `left` to a custom string, or leave null to build from holder + year below.
|
||||
*/
|
||||
return [
|
||||
// Visible copyright holder (also used in i18n {holder} if you customize strings).
|
||||
// --- Optional rows (static or PHP-dynamic strings) ---
|
||||
'top' => null,
|
||||
'left' => null,
|
||||
'right' => null,
|
||||
'bottom' => null,
|
||||
|
||||
// --- Default left column when `left` is null ---
|
||||
'holder' => 'Anton Afanaasyeu',
|
||||
// Prefix before the name: "(c)", "©", or "".
|
||||
'copyright_symbol' => '(c)',
|
||||
// Append current calendar year (or fixed year below).
|
||||
'copyright_symbol' => "\u{00A9}",
|
||||
'show_year' => true,
|
||||
// null = (int) date('Y') at render time.
|
||||
// null = current calendar year at render time (end of range).
|
||||
'year' => null,
|
||||
// CSS class on <footer>.
|
||||
// Set e.g. 2026 for "2026–{current}" (en dash). Omit for single year only.
|
||||
'year_start' => "2026 - current",
|
||||
# 'year_start' => null,
|
||||
|
||||
// CSS class on <footer> (platform-footer layout classes are always added).
|
||||
'footer_class' => 'bottom-bar',
|
||||
// When true, consoles with i18n.js replace text via data-i18n / data-year.
|
||||
// When true, consoles with i18n.js replace default left text via data-i18n / data-year.
|
||||
'use_i18n' => true,
|
||||
'i18n_key' => 'footer.copyright',
|
||||
];
|
||||
|
||||
@@ -6,6 +6,11 @@ declare(strict_types=1);
|
||||
*
|
||||
* Configure: examples/platform/footer.config.php (see footer.config.example.php).
|
||||
* Usage: <?php platform_render_footer(); ?> or platform_render_footer(['use_i18n' => false]);
|
||||
*
|
||||
* Layout (each row omitted when empty):
|
||||
* [ top — full width ]
|
||||
* [ left | right ] — main row (copyright defaults on left when left unset)
|
||||
* [ bottom — full width ]
|
||||
*/
|
||||
|
||||
function platform_footer_h(mixed $value): string
|
||||
@@ -28,7 +33,8 @@ function platform_footer_config(): array
|
||||
return is_array($loaded) ? $loaded : [];
|
||||
}
|
||||
|
||||
function platform_footer_year(array $cfg): int
|
||||
/** @param array<string, mixed> $cfg */
|
||||
function platform_footer_year_end(array $cfg): int
|
||||
{
|
||||
if (array_key_exists('year', $cfg) && $cfg['year'] !== null) {
|
||||
return (int) $cfg['year'];
|
||||
@@ -37,9 +43,34 @@ function platform_footer_year(array $cfg): int
|
||||
return (int) date('Y');
|
||||
}
|
||||
|
||||
function platform_footer_plain_text(array $cfg, int $year): string
|
||||
/**
|
||||
* Year label: single year or range (e.g. 2026–2026) when year_start is set.
|
||||
*
|
||||
* @param array<string, mixed> $cfg
|
||||
*/
|
||||
function platform_footer_year_label(array $cfg): string
|
||||
{
|
||||
$symbol = trim((string) ($cfg['copyright_symbol'] ?? '(c)'));
|
||||
$end = platform_footer_year_end($cfg);
|
||||
$start = isset($cfg['year_start']) ? (int) $cfg['year_start'] : 0;
|
||||
if ($start > 0) {
|
||||
if ($start === $end) {
|
||||
return (string) $start;
|
||||
}
|
||||
|
||||
return $start . "\u{2013}" . $end;
|
||||
}
|
||||
|
||||
return (string) $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default left line: © holder[, year|year-range].
|
||||
*
|
||||
* @param array<string, mixed> $cfg
|
||||
*/
|
||||
function platform_footer_default_left(array $cfg): string
|
||||
{
|
||||
$symbol = trim((string) ($cfg['copyright_symbol'] ?? "\u{00A9}"));
|
||||
$holder = trim((string) ($cfg['holder'] ?? ''));
|
||||
$showYear = (bool) ($cfg['show_year'] ?? true);
|
||||
$parts = [];
|
||||
@@ -50,36 +81,117 @@ function platform_footer_plain_text(array $cfg, int $year): string
|
||||
$parts[] = $holder;
|
||||
}
|
||||
$line = implode(' ', $parts);
|
||||
if ($showYear && $line !== '') {
|
||||
return $line . ', ' . $year;
|
||||
if (!$showYear) {
|
||||
return $line;
|
||||
}
|
||||
if ($showYear && $line === '') {
|
||||
return (string) $year;
|
||||
$yearLabel = platform_footer_year_label($cfg);
|
||||
if ($line === '') {
|
||||
return $yearLabel;
|
||||
}
|
||||
|
||||
return $line;
|
||||
return $line . ', ' . $yearLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{use_i18n?: bool, extra_class?: string} $opts
|
||||
* Resolve optional row text (null/empty = omit row). Supports per-render overrides in $opts.
|
||||
*
|
||||
* @param array<string, mixed> $cfg
|
||||
* @param array<string, mixed> $opts
|
||||
*/
|
||||
function platform_footer_field(array $cfg, array $opts, string $key): ?string
|
||||
{
|
||||
if (array_key_exists($key, $opts)) {
|
||||
$v = $opts[$key];
|
||||
if ($v === null || $v === false) {
|
||||
return null;
|
||||
}
|
||||
$t = trim((string) $v);
|
||||
|
||||
return $t === '' ? null : $t;
|
||||
}
|
||||
if (!array_key_exists($key, $cfg)) {
|
||||
return null;
|
||||
}
|
||||
$v = $cfg[$key];
|
||||
if ($v === null || $v === false) {
|
||||
return null;
|
||||
}
|
||||
$t = trim((string) $v);
|
||||
|
||||
return $t === '' ? null : $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $cfg
|
||||
* @param array<string, mixed> $opts
|
||||
*/
|
||||
function platform_footer_resolve_left(array $cfg, array $opts): ?string
|
||||
{
|
||||
$custom = platform_footer_field($cfg, $opts, 'left');
|
||||
if ($custom !== null) {
|
||||
return $custom;
|
||||
}
|
||||
$built = platform_footer_default_left($cfg);
|
||||
|
||||
return $built === '' ? null : $built;
|
||||
}
|
||||
|
||||
/** @deprecated Use platform_footer_default_left(); kept for scripts/tests. */
|
||||
function platform_footer_plain_text(array $cfg, int $year): string
|
||||
{
|
||||
$cfg = array_merge($cfg, ['year' => $year]);
|
||||
|
||||
return platform_footer_default_left($cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{use_i18n?: bool, extra_class?: string, top?: ?string, left?: ?string, right?: ?string, bottom?: ?string} $opts
|
||||
*/
|
||||
function platform_render_footer(array $opts = []): void
|
||||
{
|
||||
$cfg = platform_footer_config();
|
||||
$year = platform_footer_year($cfg);
|
||||
$text = platform_footer_plain_text($cfg, $year);
|
||||
$class = (string) ($opts['extra_class'] ?? ($cfg['footer_class'] ?? 'bottom-bar'));
|
||||
$useI18n = $opts['use_i18n'] ?? (bool) ($cfg['use_i18n'] ?? true);
|
||||
$i18nKey = (string) ($cfg['i18n_key'] ?? 'footer.copyright');
|
||||
$top = platform_footer_field($cfg, $opts, 'top');
|
||||
$left = platform_footer_resolve_left($cfg, $opts);
|
||||
$right = platform_footer_field($cfg, $opts, 'right');
|
||||
$bottom = platform_footer_field($cfg, $opts, 'bottom');
|
||||
|
||||
if ($useI18n && $i18nKey !== '') {
|
||||
echo '<footer class="' . platform_footer_h($class) . '"'
|
||||
. ' data-i18n="' . platform_footer_h($i18nKey) . '"'
|
||||
. ' data-year="' . $year . '">'
|
||||
. platform_footer_h($text)
|
||||
. '</footer>';
|
||||
return;
|
||||
$baseClass = (string) ($opts['extra_class'] ?? ($cfg['footer_class'] ?? 'bottom-bar'));
|
||||
$classes = trim($baseClass . ' platform-footer');
|
||||
if ($top === null && $bottom === null && $right === null) {
|
||||
$classes .= ' platform-footer--single-row';
|
||||
}
|
||||
|
||||
echo '<footer class="' . platform_footer_h($class) . '">' . platform_footer_h($text) . '</footer>';
|
||||
$useI18n = $opts['use_i18n'] ?? (bool) ($cfg['use_i18n'] ?? true);
|
||||
$i18nKey = (string) ($cfg['i18n_key'] ?? 'footer.copyright');
|
||||
$leftUsesDefault = platform_footer_field($cfg, $opts, 'left') === null;
|
||||
$yearEnd = platform_footer_year_end($cfg);
|
||||
|
||||
echo '<footer class="' . platform_footer_h($classes) . '">';
|
||||
|
||||
if ($top !== null) {
|
||||
echo '<div class="platform-footer__top">' . platform_footer_h($top) . '</div>';
|
||||
}
|
||||
|
||||
if ($left !== null || $right !== null) {
|
||||
echo '<div class="platform-footer__main">';
|
||||
if ($left !== null) {
|
||||
echo '<div class="platform-footer__left"';
|
||||
if ($useI18n && $i18nKey !== '' && $leftUsesDefault) {
|
||||
echo ' data-i18n="' . platform_footer_h($i18nKey) . '"'
|
||||
. ' data-year="' . platform_footer_h(platform_footer_year_label($cfg)) . '"'
|
||||
. ' data-year-end="' . $yearEnd . '"';
|
||||
}
|
||||
echo '>' . platform_footer_h($left) . '</div>';
|
||||
}
|
||||
if ($right !== null) {
|
||||
echo '<div class="platform-footer__right">' . platform_footer_h($right) . '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if ($bottom !== null) {
|
||||
echo '<div class="platform-footer__bottom">' . platform_footer_h($bottom) . '</div>';
|
||||
}
|
||||
|
||||
echo '</footer>';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user