#!/usr/bin/php-cgi -dcgi.force_redirect=0
<?php
# encoding: utf-8
# api: cgi
# type: edit
# title: User editing
# description: Provides an editing interface to user fields (info)
# version: 0.2
# state: alpha
# depends: php:sqlite
# config: -
#
# Fairly simple editing UI for user.info table, and possibly some
# new fields. This is basically an addition to the IndieAuth plugin,
# so users can actually update their contact information etc.
#
# New fields must be added in $fields[] atop.
#

if ($_REQUEST["dbg"]) {
    error_reporting(E_ALL); ini_set("display_errors", 1);
}

#-- allowed/new fields
$fields = [
    "info" => [
        "title" => "Contact info",
        "desc" => "This is usually just an email address. For using git-fast-export this must be a single line.",
    ],
    "homepage" => [
        "title" => "Homepage URLs",
        "desc" => "This will create a new column for listing user urls. Which is used by the IndieAuth plugin to verify authorization requests.",
    ],
];


#-- database (== fossil repo)
function db($sql="", $params=[]) {
    static $db;
    if (empty($db)) {
        $db = new PDO("sqlite:$_SERVER[FOSSIL_REPOSITORY]");
    }
    if ($params) {
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    else {
        return $db->query($sql);
    }
}

#-- fossil HTML output
function page_html($html) {
    header("Content-Type: text/html; encoding=utf-8");
    $html = <<<HTML
        <div class='fossil-doc' data-title='User config'>
        <svg style="float:left; margin-right:30pt;" width="150" height="937" version="1.1" viewBox="0 0 15.635 93.735" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
         <defs>
          <linearGradient id="linearGradient938" x1="48.584" x2="64.881" y1="88.509" y2="86.525" gradientUnits="userSpaceOnUse">
           <stop stop-color="#5f9320" offset="0"/>
           <stop stop-color="#bbb700" offset="1"/>
          </linearGradient>
         </defs>
         <g transform="translate(-48.584 -41.642)">
          <path d="m52.253 41.642c-2.0326 0-3.669 1.6359-3.669 3.6685v8.6589h2.8009c1.1504 0 2.0769 0.92645 2.0769 2.0769v1.8914a3.7084 3.675 0 0 1 3.5745-2.6985 3.7084 3.675 0 0 1 3.7083 3.6752 3.7084 3.675 0 0 1-3.7083 3.6747 3.7084 3.675 0 0 1-3.5745-2.713v2.2402c0 1.1504-0.92645 2.0764-2.0769 2.0764h-2.8009v13.23h2.9347c1.1504 0 2.0769 0.92645 2.0769 2.0769v1.8914a3.7084 3.675 0 0 1 3.5745-2.6985 3.7084 3.675 0 0 1 3.7083 3.6752 3.7084 3.675 0 0 1-3.7083 3.6747 3.7084 3.675 0 0 1-3.5745-2.713v2.2402c0 1.1504-0.92645 2.0764-2.0769 2.0764h-2.9347v11.61h2.9011c1.1504 0 2.0769 0.92644 2.0769 2.0769v1.8914a3.7084 3.675 0 0 1 3.5745-2.6985 3.7084 3.675 0 0 1 3.7083 3.6752 3.7084 3.675 0 0 1-3.7083 3.6747 3.7084 3.675 0 0 1-3.5745-2.713v2.2402c0 1.1504-0.92645 2.0764-2.0769 2.0764h-2.9011v13.23h3.035c1.1504 0 2.0769 0.92645 2.0769 2.0769v1.8914a3.7084 3.675 0 0 1 3.5745-2.6985 3.7084 3.675 0 0 1 3.7083 3.6752 3.7084 3.675 0 0 1-3.7083 3.6747 3.7084 3.675 0 0 1-3.5745-2.713v2.2402c0 1.1504-0.92645 2.0764-2.0769 2.0764h-2.8236c0.50205 1.4268 1.855 2.4458 3.4577 2.4458h8.2972c2.0326 0 3.669-1.6364 3.669-3.669v-10.269h-2.9011c-1.1504 0-2.0769-0.92594-2.0769-2.0764v-2.2402a3.7084 3.675 0 0 1-3.5745 2.713 3.7084 3.675 0 0 1-3.7083-3.6747 3.7084 3.675 0 0 1 3.7083-3.6752 3.7084 3.675 0 0 1 3.5745 2.6985v-1.8914c0-1.1504 0.92645-2.0769 2.0769-2.0769h2.9011v-12.328h-2.9011c-1.1504 0-2.0769-0.92594-2.0769-2.0764v-2.2402a3.7084 3.675 0 0 1-3.5745 2.713 3.7084 3.675 0 0 1-3.7083-3.6747 3.7084 3.675 0 0 1 3.7083-3.6752 3.7084 3.675 0 0 1 3.5745 2.6985v-1.8914c0-1.1504 0.92645-2.0769 2.0769-2.0769h2.9011v-12.511h-3.0014c-1.1504 0-2.0769-0.92594-2.0769-2.0764v-2.2402a3.7084 3.675 0 0 1-3.5745 2.713 3.7084 3.675 0 0 1-3.7083-3.6747 3.7084 3.675 0 0 1 3.7083-3.6752 3.7084 3.675 0 0 1 3.5745 2.6985v-1.8914c0-1.1504 0.92645-2.0769 2.0769-2.0769h3.0014v-12.328h-3.0014c-1.1504 0-2.0769-0.92594-2.0769-2.0764v-2.2402a3.7084 3.675 0 0 1-3.5745 2.713 3.7084 3.675 0 0 1-3.7083-3.6747 3.7084 3.675 0 0 1 3.7083-3.6752 3.7084 3.675 0 0 1 3.5745 2.6985v-1.8914c0-1.1504 0.92645-2.0769 2.0769-2.0769h2.451c-0.64562-1.0429-1.7969-1.7368-3.1187-1.7368z" fill="url(#linearGradient938)" stroke-width="0"/>
         </g>
        </svg>
        \n$html\n
        </div>
HTML;
    print($html);
}
function missing_param($name) {
    die(page_html("<h2>Missing input</h2><p>URL lacks <code>&$name=</code> parameter."));
}
function page_md($text) {
    header("Content-Type: text/x-markdown; encoding=utf-8");
    print($text);
}
function h($s) {
    return htmlspecialchars($s, ENT_QUOTES|ENT_HTML5, "UTF-8");
}


#-- show available fields
function field_inputs($user, $names="info,homepage") {
    global $fields;

    // get existing columns
    $values = db("SELECT $names FROM user WHERE login=?", [$user])[0];
    
    // output form
    $html = ""; $h = "h";
    foreach ($fields as $name=>$props) {
        extract($props);
        $html .= <<<HTML
          <p>
             <h4>{$h($title ?: $name)}</h4>
             <textarea name='{$h($name)}' rows=3 cols=80>{$h($values[$name])}</textarea>
             <br>\n<small>{$desc}</small>
          </p>\n
HTML;
    }
    return $html;
}

#-- store them back.
function save_fields($user) {
    global $fields;
    $allowed = array_keys($fields);
    $existing_columns = array_keys(
        db("SELECT * FROM user WHERE login=?", [$user])[0]
    );
    
    foreach ($fields as $name=>$value) {
        if (!in_array($name, $allowed)) {
            continue;
        }
        if (!in_array($name, $existing_columns)) {
            db("
                ALTER TABLE `user`
                ADD `$name` TEXT DEFAULT ''
            ");
        }
        db("UPDATE user SET `$name`=? WHERE login=?", [$value, $user]);
    }
    page_html("User infos updated");
}

#-- run
$h = "h";
if (empty($user = $_SERVER["FOSSIL_USER"]) or in_array($user, ["anonymous", "nobody", "developer", "reader"])) {
    page_html("<h2>Not logged in</h2><p>Edit contact infos requires an active <a href='../login'>login</a>.");
}
elseif (!empty($_POST["save"])) {
    unset($_POST["save"]);
    save_fields($user, $_POST);
}
else {
    $html = field_inputs($user);
    $html = <<<HTML
     <h2>Edit user details</h2>
     <form action="" method=POST>
        {$html}
        <p><input type=submit name=save value=Apply></p>
     </form>
HTML;
    page_html($html);
}


?>