rss-bridge/lib/BridgeCard.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

266 lines
10 KiB
PHP
Raw Normal View History

<?php
final class BridgeCard
{
2024-01-25 20:20:02 +03:00
public static function render(string $bridgeClassName, Request $request): string
{
$bridgeFactory = new BridgeFactory();
$bridge = $bridgeFactory->create($bridgeClassName);
$uri = $bridge->getURI();
$name = $bridge->getName();
$icon = $bridge->getIcon();
$description = $bridge->getDescription();
2024-01-25 15:03:00 +03:00
$contexts = $bridge->getParameters();
if (Configuration::getConfig('proxy', 'url') && Configuration::getConfig('proxy', 'by_bridge')) {
2024-01-25 15:03:00 +03:00
$contexts['global']['_noproxy'] = [
'name' => 'Disable proxy (' . (Configuration::getConfig('proxy', 'name') ?: Configuration::getConfig('proxy', 'url')) . ')',
'type' => 'checkbox'
];
}
if (Configuration::getConfig('cache', 'custom_timeout')) {
2024-01-25 15:03:00 +03:00
$contexts['global']['_cache_timeout'] = [
'name' => 'Cache timeout in seconds',
'type' => 'number',
'defaultValue' => $bridge->getCacheTimeout()
];
}
$shortName = $bridge->getShortName();
$card = <<<CARD
2024-01-25 15:03:00 +03:00
<section
class="bridge-card"
id="bridge-{$bridgeClassName}"
data-ref="{$name}"
data-short-name="$shortName"
>
2024-01-25 15:03:00 +03:00
<h2><a href="{$uri}">{$name}</a></h2>
<p class="description">{$description}</p>
2024-01-25 20:20:02 +03:00
2024-01-25 15:03:00 +03:00
<input type="checkbox" class="showmore-box" id="showmore-{$bridgeClassName}" />
<label class="showmore" for="showmore-{$bridgeClassName}">Show more</label>
CARD;
2024-01-25 20:20:02 +03:00
$token = $request->attribute('token');
2024-01-25 15:03:00 +03:00
if (count($contexts) === 0) {
// The bridge has zero parameters
2024-01-25 20:20:02 +03:00
$card .= self::renderForm($bridgeClassName, '', [], $token);
2024-01-25 15:03:00 +03:00
} elseif (count($contexts) === 1 && array_key_exists('global', $contexts)) {
// The bridge has a single context with key 'global'
2024-01-25 20:20:02 +03:00
$card .= self::renderForm($bridgeClassName, '', $contexts['global'], $token);
} else {
2024-01-25 15:03:00 +03:00
// The bridge has one or more contexts (named or unnamed)
foreach ($contexts as $contextName => $contextParameters) {
if ($contextName === 'global') {
continue;
}
2024-01-25 15:03:00 +03:00
if (array_key_exists('global', $contexts)) {
// Merge the global parameters into current context
$contextParameters = array_merge($contextParameters, $contexts['global']);
}
2024-01-25 15:03:00 +03:00
if (!is_numeric($contextName)) {
// This is a named context
$card .= '<h5>' . $contextName . '</h5>' . PHP_EOL;
}
2024-01-25 20:20:02 +03:00
$card .= self::renderForm($bridgeClassName, $contextName, $contextParameters, $token);
}
}
$card .= sprintf('<label class="showless" for="showmore-%s">Show less</label>', $bridgeClassName);
2024-01-25 15:03:00 +03:00
if ($bridge->getDonationURI() !== '' && Configuration::getConfig('admin', 'donations')) {
$card .= sprintf(
'<p class="maintainer">%s ~ <a href="%s">Donate</a></p>',
$bridge->getMaintainer(),
$bridge->getDonationURI()
);
} else {
$card .= sprintf('<p class="maintainer">%s</p>', $bridge->getMaintainer());
}
$card .= '</section>';
return $card;
}
private static function renderForm(
2024-01-25 15:03:00 +03:00
string $bridgeClassName,
2024-01-25 20:20:02 +03:00
string $contextName,
array $contextParameters,
?string $token
) {
2024-01-25 15:03:00 +03:00
$form = <<<EOD
2024-01-25 20:20:02 +03:00
<form method="GET" action="?" class="bridge-form">
2024-01-25 15:03:00 +03:00
<input type="hidden" name="action" value="display" />
<input type="hidden" name="bridge" value="{$bridgeClassName}" />
EOD;
2024-01-25 20:20:02 +03:00
if ($token) {
// todo: maybe escape the token?
$form .= sprintf('<input type="hidden" name="token" value="%s" />', $token);
}
2024-01-25 15:03:00 +03:00
if (!empty($contextName)) {
$form .= sprintf('<input type="hidden" name="context" value="%s" />', $contextName);
}
if (count($contextParameters) > 0) {
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
$form .= '<div class="parameters">';
2024-01-25 15:03:00 +03:00
foreach ($contextParameters as $id => $inputEntry) {
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
if (!isset($inputEntry['exampleValue'])) {
$inputEntry['exampleValue'] = '';
}
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
if (!isset($inputEntry['defaultValue'])) {
$inputEntry['defaultValue'] = '';
}
2024-01-25 15:03:00 +03:00
$idArg = 'arg-' . urlencode($bridgeClassName) . '-' . urlencode($contextName) . '-' . urlencode($id);
$inputName = filter_var($inputEntry['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$form .= '<label for="' . $idArg . '">' . $inputName . '</label>' . PHP_EOL;
2024-01-25 15:03:00 +03:00
if (
!isset($inputEntry['type'])
|| $inputEntry['type'] === 'text'
) {
$form .= self::getTextInput($inputEntry, $idArg, $id) . "\n";
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
} elseif ($inputEntry['type'] === 'number') {
$form .= self::getNumberInput($inputEntry, $idArg, $id);
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
} elseif ($inputEntry['type'] === 'list') {
2024-01-25 15:03:00 +03:00
$form .= self::getListInput($inputEntry, $idArg, $id) . "\n";
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
} elseif ($inputEntry['type'] === 'checkbox') {
$form .= self::getCheckboxInput($inputEntry, $idArg, $id);
2024-01-25 15:03:00 +03:00
} else {
$foo = 2;
// oops?
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
}
$infoText = [];
$infoTextScript = '';
if (isset($inputEntry['title'])) {
$infoText[] = filter_var($inputEntry['title'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
}
if ($inputEntry['exampleValue'] !== '') {
$infoText[] = "Example (right click to use):\n" . filter_var($inputEntry['exampleValue'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$infoTextScript = 'rssbridge_use_placeholder_value(this);';
}
if (count($infoText) > 0) {
$form .= '<i class="info" data-for="' . $idArg . '" title="' . implode("\n\n", $infoText) . '" oncontextmenu="' . $infoTextScript . 'return false">i</i>';
} else {
$form .= '<i class="no-info"></i>';
}
}
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
$form .= '</div>';
}
2024-01-25 20:20:02 +03:00
$form .= '<button type="submit" name="format" formtarget="_blank" value="Html">Generate feed</button>';
return $form . '</form>' . PHP_EOL;
}
public static function getTextInput(array $entry, string $id, string $name): string
{
$defaultValue = filter_var($entry['defaultValue'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$exampleValue = filter_var($entry['exampleValue'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$attributes = self::getInputAttributes($entry);
2024-01-25 15:03:00 +03:00
return sprintf('<input %s id="%s" type="text" value="%s" placeholder="%s" name="%s" />', $attributes, $id, $defaultValue, $exampleValue, $name);
}
public static function getNumberInput(array $entry, string $id, string $name): string
{
$defaultValue = filter_var($entry['defaultValue'], FILTER_SANITIZE_NUMBER_INT);
$exampleValue = filter_var($entry['exampleValue'], FILTER_SANITIZE_NUMBER_INT);
$attributes = self::getInputAttributes($entry);
return sprintf('<input %s id="%s" type="number" value="%s" placeholder="%s" name="%s" />' . "\n", $attributes, $id, $defaultValue, $exampleValue, $name);
}
public static function getListInput(array $entry, string $id, string $name): string
{
$required = $entry['required'] ?? null;
if ($required) {
Debug::log('The "required" attribute is not supported for lists.');
unset($entry['required']);
}
$attributes = self::getInputAttributes($entry);
2024-01-25 15:03:00 +03:00
$list = sprintf('<select %s id="%s" name="%s" >' . "\n", $attributes, $id, $name);
foreach ($entry['values'] as $name => $value) {
if (is_array($value)) {
$list .= '<optgroup label="' . htmlentities($name) . '">';
foreach ($value as $subname => $subvalue) {
if (
$entry['defaultValue'] === $subname
|| $entry['defaultValue'] === $subvalue
) {
$list .= '<option value="' . $subvalue . '" selected>' . $subname . '</option>';
} else {
$list .= '<option value="' . $subvalue . '">' . $subname . '</option>';
}
}
$list .= '</optgroup>';
} else {
if (
$entry['defaultValue'] === $name
|| $entry['defaultValue'] === $value
) {
2024-01-25 15:03:00 +03:00
$list .= '<option value="' . $value . '" selected>' . $name . '</option>' . "\n";
} else {
2024-01-25 15:03:00 +03:00
$list .= '<option value="' . $value . '">' . $name . '</option>' . "\n";
}
}
}
CSS adjustments to improve readability for bridge parameters (#763) * Group common selectors * Fix indentation using tabs * Use same styles for number and text inputs * Use grid layout for parameters Introduces the grid layout for bridge parameters. All parameters are arranged in a grid to improve readability. Read more on grid layouts at - https://www.w3schools.com/css/css_grid.asp - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout Notice: Grid layouts are not supported in very old browser versions: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement This is why @supports checks for browser support (not supported in IE) https://developer.mozilla.org/en-US/docs/Web/CSS/@supports#Browser_compatibility In case grid layout is not supported, the displayed form is usable but not very pretty due to <br> being removed by this commit for cosmetic reasons (breaks grid layout). Unfortunately it doesn't seem possible to insert line breaks manually via '::after { content: '\A' }' in cases where grid layout isn't supported. * Add padding to card parameters Adds padding to parameters to improve readability. For bridges without parameters (count($parameters) === 0), the parameter 'div' is no longer created. * Add colon ':' after label via CSS * Capitalize first letter of label for readability * Fix checkbox isn't aligned left Sets the size of the checkbox to 20x20 px for good measure. * Harmonize formatting * Add new style to number and select boxes References #797 * Add fallback solution for browsers without grid support
2018-09-15 17:39:50 +03:00
$list .= '</select>';
return $list;
}
public static function getCheckboxInput(array $entry, string $id, string $name): string
{
$required = $entry['required'] ?? null;
if ($required) {
Debug::log('The "required" attribute is not supported for checkboxes.');
unset($entry['required']);
}
$checked = $entry['defaultValue'] === 'checked' ? 'checked' : '';
$attributes = self::getInputAttributes($entry);
return sprintf('<input %s id="%s" type="checkbox" name="%s" %s />' . "\n", $attributes, $id, $name, $checked);
}
public static function getInputAttributes(array $entry): string
{
$result = '';
$required = $entry['required'] ?? null;
if ($required) {
$result .= ' required';
}
$pattern = $entry['pattern'] ?? null;
if ($pattern) {
$result .= ' pattern="' . $pattern . '"';
}
return $result;
}
}