Collection of themes/skins for the Fossil SCM

⌈⌋ ⎇ branch:  Fossil Skins Extra


Artifact [24ffa8c57c]

Artifact 24ffa8c57c123bfe3e47080bebb58c06d6432a2e:

  • Executable file extroot/config — part of check-in [3fd7f87ed2] at 2021-10-20 05:58:34 on branch trunk — restructure form field output (user: mario size: 5336)

#!/usr/bin/php-cgi -dcgi.force_redirect=0
<?php
# encoding: utf-8
# api: cgi
# type: config
# category: admin
# title: Extra config
# description: Additional list of options to configure, read from ext/* PMD
# version: 0.4
# state: beta
# config:
#    { name: project-license, type: select, select: "0BSD|AAL|ADSL|AFL-3.0|AGPL-1.0|AGPL-3.0|AGPL-3.0-or-later|Apache-2.0|APSL-2.0|Artistic-1.0|Artistic-2.0|BSD-1-Clause|BSD-2-Clause|BSD-2-Clause-FreeBSD|BSD-2-Clause-NetBSD|BSD-2-Clause-Patent|BSD-3-Clause|BSD-3-Clause-Attribution|BSD-3-Clause-Clear|BSD-3-Clause-Modification|BSD-4-Clause|BSD-4-Clause-Shortened|BSL-1.0|CAL-1.0|CC0-1.0|CC-BY-2.0|CC-BY-3.0|CC-BY-4.0|CC-BY-NC-2.0|CC-BY-NC-4.0|CC-BY-NC-ND-2.0|CC-BY-NC-ND-3.0|CC-BY-NC-ND-4.0|CC-BY-NC-SA-2.0|CC-BY-NC-SA-3.0|CC-BY-NC-SA-4.0|CC-BY-ND-4.0|CC-BY-SA-2.0|CC-BY-SA-4.0|CDDL-1.1|CPL-1.0|ECL-2.0|EFL-2.0|EPL-2.0|EUPL-1.2|GFDL-1.1|GFDL-1.3-only|GFDL-1.3-or-later|GPL-1.0|GPL-1.0+|GPL-2.0|GPL-2.0+|GPL-2.0-only|GPL-3.0|GPL-3.0+|IPL-1.0|ISC|LGPL-2.0|LGPL-2.1|LGPL-2.1+|LGPL-3.0|LGPL-3.0+|MIT|MIT-0|MIT-Modern-Variant|MPL-1.0|MPL-1.1|MPL-2.0|MS-PL|MS-RL|NPL-1.1|OFL-1.0|OSL-2.0|OSL-3.0|PSF-2.0|Python-2.0|SPL-1.0|TCL|Unlicense|W3C|WTFPL|X11|Zend-2.0|ZPL-2.1", value: "", description: "Source code license (SPDX identifier)" }
#    { name: project-tags,    type: str, value: "", description: Additional tags for project.json listing, comma-separated list }
#    { name: project-homepage, type: str, value: "", description: Alternative project homepage, help: If the repository is not the primary/user homepage. }
#    { name: project-description, type: text, value: "", description: "Fossil repository and project description" }
#    [ name: timeline-plaintext, type: bool, value: 1, description: "No markup in timeline displays", help: Check-in comments are displayed literally - without any wiki or HTML interpretation. ]
# access: admin
#
# Reads the #config:{} fields, and updates fossils’ config table.
# Allows extroot scripts to provide additional options, or just
# an alternative to the builtin settings.
#

#-- init
include("./fossil_common.php");   # db() etc.
if (!is_admin()) {
    die("Admin-only");
}
error_reporting(E_ALL);

#-- fossil HTML output
function page_md($text) {
    header("Content-Type: text/html; charset=utf-8");
    print <<<EOF
<div class='fossil-doc' data-title='Extra configuration'>
<style>
 .config-list label {
    display: block;
    margin-bottom: 10pt;
    border-left: 3pt #ddd solid;
    border-radius: 5pt 0 0 5pt;
    padding-left: 10pt;
 }
</style>
$text
EOF;
}


#-- filtered file list
function ls($dir) {
    $ls = [];
    foreach (glob("$dir/*") as $fn) {
        if (is_file($fn) and is_executable($fn) and is_readable($fn)) {
            $ls[] = basename($fn);
        }
    }
    return $ls;
}

#-- store received blobs back
if (count($_POST)) {
    foreach ($_POST as $key=>$value) {
        if (get_config($key, "") != $value) {
            db("REPLACE INTO config (name,mtime,value) VALUES (?,?,?)", [$key, time(), $value]);
        }
    }
}

#-- print option blocks
function option($opt, $h="h") {
    if (empty($opt["name"])) {
        return;
    }
    $name = $opt["name"];
    $type = $opt["type"] ?: "str";
    $value = get_config($name, empty($opt["value"]) ? "" : $opt["value"]);
    $help = empty($opt["help"]) ? "" : $opt["help"];
    # output
    print "<label title=\"{$h($help)}\">\n";
    field($name, $type, $value, $opt);
    print "<br>\n<small>{$h($opt['description'])}</small></label>\n\n";
}

#-- output <input> depending on type
function field($name, $type, $value, $opt, $h="h") {
    # handle only str, text or select fields
    switch ($type) {
        case "long":
        case "text":
            print "<b>{$h($name)}</b><br>\n";
            print "<textarea name={$h($name)} rows=4 cols=70>{$h($value)}</textarea>";
            break;
        case "boolean":
        case "bool":
            $checked = $value ? " checked" : "";
            print "<input type=hidden name={$h($name)} value=0>";
            print "<input type=checkbox name={$h($name)} value=1$checked>";
            print "<b>{$h($name)}</b>\n";
            break;
        case "choose":
        case "select":
            print "<b>{$h($name)}</b><br>\n";
            print "<select name={$h($name)}>\n";
            $opts = preg_split("~[|;,]~", $opt["select"]);
            if (!in_array($value, $opts)) {
                $opts[-1] = $value;
            }
            foreach ($opts as $o) {
                $selected = $o == $value ? " selected" : "";
                print "<option value=\"{$h($o)}\"$selected>{$h($o)}</option>\n";
            }
            print "</select>";
            break;
        default:
            print "<b>{$h($name)}</b><br>\n";
            print "<input type=\"{$h($type)}\" name={$h($name)} value=\"{$h($value)}\" size=60>";
    }
}

#-- iterate over scripts for display
page_md("<div class=config-list>\n<form method=POST enctype='multipart/form-data'>");
foreach (ls(__DIR__) as $fn) {
    $meta = meta($fn);
    $h = "h";
    # look for config: options
    if ($config = config($meta)) {
        $title = $meta["title"] ?: $fn;
        print "<h3>$title</h3>\n";  # title='{$h($meta['__doc__'])}'
        array_map("option", $config);
    }
}
?>
<input type=submit value="Save">
</form>
</div>