mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-12-23 21:00:24 +03:00
58544cd61a
* refactor: introduce DI container * add bin/test
268 lines
10 KiB
PHP
268 lines
10 KiB
PHP
<?php
|
|
|
|
final class BridgeCard
|
|
{
|
|
public static function render(
|
|
BridgeFactory $bridgeFactory,
|
|
string $bridgeClassName,
|
|
?string $token
|
|
): string {
|
|
$bridge = $bridgeFactory->create($bridgeClassName);
|
|
|
|
$uri = $bridge->getURI();
|
|
$name = $bridge->getName();
|
|
$icon = $bridge->getIcon();
|
|
$description = $bridge->getDescription();
|
|
$contexts = $bridge->getParameters();
|
|
|
|
// Checkbox for disabling of proxy (if enabled)
|
|
if (
|
|
Configuration::getConfig('proxy', 'url')
|
|
&& Configuration::getConfig('proxy', 'by_bridge')
|
|
) {
|
|
$proxyName = Configuration::getConfig('proxy', 'name') ?: Configuration::getConfig('proxy', 'url');
|
|
$contexts['global']['_noproxy'] = [
|
|
'name' => sprintf('Disable proxy (%s)', $proxyName),
|
|
'type' => 'checkbox',
|
|
];
|
|
}
|
|
|
|
if (Configuration::getConfig('cache', 'custom_timeout')) {
|
|
$contexts['global']['_cache_timeout'] = [
|
|
'name' => 'Cache timeout in seconds',
|
|
'type' => 'number',
|
|
'defaultValue' => $bridge->getCacheTimeout()
|
|
];
|
|
}
|
|
|
|
$shortName = $bridge->getShortName();
|
|
$card = <<<CARD
|
|
<section
|
|
class="bridge-card"
|
|
id="bridge-{$bridgeClassName}"
|
|
data-ref="{$name}"
|
|
data-short-name="$shortName"
|
|
>
|
|
|
|
<h2><a href="{$uri}">{$name}</a></h2>
|
|
<p class="description">{$description}</p>
|
|
|
|
<input type="checkbox" class="showmore-box" id="showmore-{$bridgeClassName}" />
|
|
<label class="showmore" for="showmore-{$bridgeClassName}">Show more</label>
|
|
|
|
|
|
CARD;
|
|
|
|
if (count($contexts) === 0) {
|
|
// The bridge has zero parameters
|
|
$card .= self::renderForm($bridgeClassName, '', [], $token);
|
|
} elseif (count($contexts) === 1 && array_key_exists('global', $contexts)) {
|
|
// The bridge has a single context with key 'global'
|
|
$card .= self::renderForm($bridgeClassName, '', $contexts['global'], $token);
|
|
} else {
|
|
// The bridge has one or more contexts (named or unnamed)
|
|
foreach ($contexts as $contextName => $contextParameters) {
|
|
if ($contextName === 'global') {
|
|
continue;
|
|
}
|
|
|
|
if (array_key_exists('global', $contexts)) {
|
|
// Merge the global parameters into current context
|
|
$contextParameters = array_merge($contextParameters, $contexts['global']);
|
|
}
|
|
|
|
if (!is_numeric($contextName)) {
|
|
// This is a named context
|
|
$card .= '<h5>' . $contextName . '</h5>' . PHP_EOL;
|
|
}
|
|
|
|
$card .= self::renderForm($bridgeClassName, $contextName, $contextParameters, $token);
|
|
}
|
|
}
|
|
|
|
$card .= sprintf('<label class="showless" for="showmore-%s">Show less</label>', $bridgeClassName);
|
|
|
|
if (Configuration::getConfig('admin', 'donations') && $bridge->getDonationURI()) {
|
|
$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(
|
|
string $bridgeClassName,
|
|
string $contextName,
|
|
array $contextParameters,
|
|
?string $token
|
|
) {
|
|
$form = <<<EOD
|
|
<form method="GET" action="?" class="bridge-form">
|
|
<input type="hidden" name="action" value="display" />
|
|
<input type="hidden" name="bridge" value="{$bridgeClassName}" />
|
|
EOD;
|
|
|
|
if (Configuration::getConfig('authentication', 'token') && $token) {
|
|
$form .= sprintf('<input type="hidden" name="token" value="%s" />', e($token));
|
|
}
|
|
|
|
if (!empty($contextName)) {
|
|
$form .= sprintf('<input type="hidden" name="context" value="%s" />', $contextName);
|
|
}
|
|
|
|
if (count($contextParameters) > 0) {
|
|
$form .= '<div class="parameters">';
|
|
|
|
foreach ($contextParameters as $id => $inputEntry) {
|
|
if (!isset($inputEntry['exampleValue'])) {
|
|
$inputEntry['exampleValue'] = '';
|
|
}
|
|
|
|
if (!isset($inputEntry['defaultValue'])) {
|
|
$inputEntry['defaultValue'] = '';
|
|
}
|
|
|
|
$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;
|
|
|
|
if (
|
|
!isset($inputEntry['type'])
|
|
|| $inputEntry['type'] === 'text'
|
|
) {
|
|
$form .= self::getTextInput($inputEntry, $idArg, $id) . "\n";
|
|
} elseif ($inputEntry['type'] === 'number') {
|
|
$form .= self::getNumberInput($inputEntry, $idArg, $id);
|
|
} elseif ($inputEntry['type'] === 'list') {
|
|
$form .= self::getListInput($inputEntry, $idArg, $id) . "\n";
|
|
} elseif ($inputEntry['type'] === 'checkbox') {
|
|
$form .= self::getCheckboxInput($inputEntry, $idArg, $id);
|
|
} else {
|
|
$foo = 2;
|
|
// oops?
|
|
}
|
|
|
|
$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>';
|
|
}
|
|
}
|
|
|
|
$form .= '</div>';
|
|
}
|
|
|
|
$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);
|
|
|
|
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) {
|
|
trigger_error('The required attribute is not supported for lists');
|
|
unset($entry['required']);
|
|
}
|
|
|
|
$attributes = self::getInputAttributes($entry);
|
|
$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
|
|
) {
|
|
$list .= '<option value="' . $value . '" selected>' . $name . '</option>' . "\n";
|
|
} else {
|
|
$list .= '<option value="' . $value . '">' . $name . '</option>' . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
$list .= '</select>';
|
|
|
|
return $list;
|
|
}
|
|
|
|
|
|
public static function getCheckboxInput(array $entry, string $id, string $name): string
|
|
{
|
|
$required = $entry['required'] ?? null;
|
|
if ($required) {
|
|
trigger_error('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;
|
|
}
|
|
}
|