<?php if (!defined('PmWiki')) exit();
/*
    wikiforms script, version 2.1.1
    Copyright 2005-2014 John Rankin (john.rankin@affinity.co.nz)
    works with PmWiki 2.2.56 or above
    requires php 5.3 or above and is compatible with php 5.5
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published
    by the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.    
*/
$HTMLStylesFmt['wikiform'] = "
table th.prompt { text-align: right; vertical-align: top; font-size: smaller; 
	width:20%; color: #333333;
}
table th.divide { text-align:left; padding-top:0.75em; }
table td.note { font-size: smaller; color: #333333; padding-bottom:1.0em; }
span.prompt { cursor: help; }
td textarea { font-size: smaller; }
table.wikilist { font-size: smaller; 
    border: 1px solid #600;
    border-collapse: collapse;
}
table.wikilist th { background-color: #eeeeee; padding: 2px; 
    border: 1px dotted #600;
}
table.wikilist td { vertical-align: top; padding: 2px; 
    border: 1px dotted #600;
}";

function includefHelper($m) {
  return '(:include '.$m[1].$m[2].':)(:nl:)'.
      '=&gt;[['.$m[1].'?action=editeform | '. $GLOBALS['wikiform_editform'] .']]';
}
Markup_e('wform','inline','/^\(:wikiform(?:\s+(.*?))?:\)/',
"'<:block>'.Keep(EntryForm(\$pagename,'posteform','post',\$GLOBALS['WikiFormPageFmt'],ParseArgs(\$m[1])))");
Markup('wsubmit','directives','/^\(:submit\s+(post|preview):\)/',
    "On submit: ''$1''");
Markup_e('wlist','directives','/^\(:wikilist\s*(.*?):\)/',
    "'<:block>'.FmtEntryList('',\$pagename,array('q'=>\$m[1]))");
Markup('includef','<include',
    "/\(:includeform\s+($GroupPattern(?:[\/.])$NamePattern)(.*?):\)/",
    "includefHelper");
Markup_e('fpara','directives','/\(:fpara\s*([^=]+)=([^\s:]+)\s*:\)/',
    "FormParagraph(\$pagename,\$m[1],\$m[2])");
Markup_e('wnew','>{$fmt}',"/(($GroupPattern)(?:[.\/]))?{\\\$Newest}/",
    "\$m[1].NewestEntry(\$pagename,\$m[2])");
SDV($FormsGroup,'Forms');
SDV($FormTemplatePage,'FormTemplate');
SDV($DefaultWikiFormPageFmt,"\$Group.$FormTemplatePage");
SDVA($WikiFormPageFmt,array($DefaultWikiFormPageFmt,
            "$FormsGroup.\$Group",
            "\$Suffix.$FormTemplatePage",
            "$FormsGroup.\$Suffix"));
SDVA($WikiFormGroupFmt,array('$Group','$Name','$Prefix-$Group','$Prefix-$Name'));
$FmtPV['$Suffix'] = 'preg_replace("/^(.+-)?/","",$group)';

// Form elements in chosen language
SDV($language,'en');
SDV($scriptlocation,'scripts');
SDV($wikiformi18n,"wikiform-i18n-$language.php");
if (file_exists("$FarmD/cookbook/$wikiformi18n"))
    include_once("$FarmD/cookbook/$wikiformi18n");
elseif (file_exists("$FarmD/cookbook/$scriptlocation/$wikiformi18n"))
    include_once("$FarmD/cookbook/$scriptlocation/$wikiformi18n");
elseif (file_exists("$FarmD/local/$wikiformi18n"))
    include_once("$FarmD/local/$wikiformi18n");
elseif (file_exists("$FarmD/local/$scriptlocation/$wikiformi18n"))
    include_once("$FarmD/local/$scriptlocation/$wikiformi18n");
elseif (file_exists("$FarmD/local/$scriptlocation/wikiform-i18n-en.php"))
    include_once("$FarmD/local/$scriptlocation/wikiform-i18n-en.php");
else include_once("$FarmD/cookbook/$scriptlocation/wikiform-i18n-en.php");

// Publish button format
SDV($PublishForm,false);
if ($PublishForm) 
    SDV($PublishWikiFormFmt,(($action=='print'||$action=='publish') ? '' :
    "<form class='publish' action='\$ScriptUrl' method='get'>
    <input type='hidden' name='n' value='\$FullName' />
    <input type='hidden' name='action' value='publish' />
    <input type='hidden' name='ptype' value='search' />
    <input type='hidden' name='pages' value='\$Pages' />
    <input type='hidden' name='psort' value='\$PSort' />
    $PDFCheckboxFmt$PDFTypesetVFmt$PDFOptionsFmt</form>"));
else
    $PublishWikiFormFmt = '';

// String comparison function
SDV($CollateFunction, 'str' . ((@$EnableCollate) ? 'coll' : 'casecmp'));

if ($action=='posteform' || $action=='saveeform') {
    Lock(2);
    if ($action=='posteform') {
        $g = SetFormGroup($_REQUEST['n'],$WikiFormPageFmt,$WikiFormGroupFmt);
        SDV($RecordStartingNumber,0);
        $record = $RecordStartingNumber;
        foreach(ListPages("/^$g\\.\\d/") as $i)
            $record = max(@$record,substr($i,strlen($g)+1));
        $pagename = sprintf("$g.%05d",@$record+1);
    }
    $action = 'edit';
    if (isset($_REQUEST['onsubmit'])) $WikiFormSubmit = $_REQUEST['onsubmit'];
    else SDV($WikiFormSubmit,'preview');
    $_POST[$WikiFormSubmit] = 1;
    $EditMessageFmt = "<p class='vspace'>$wikiform_editmessage</p>";
    $_POST['text'] = FormData($pagename,$WikiFormPageFmt);
} elseif ($action=='vieweform') {
    $FmtPV['$LastModified'] = '$GLOBALS["CurrentTime"]';
    $action = 'editeform';
    $EformAction = 'neweform';
} elseif ($action=='browse') {
    SDV($FormNavFooter,true);
    if (preg_match('/[.\\/]\\d{5}$/',$pagename)) {
        $HandleActions['browse'] = 'HandleBrowseEform';
        if ($FormNavFooter)
            $GroupFooterFmt.= '(:nl:)=&gt;'.FormNavigation($pagename);
        else
            $GroupHeaderFmt = '=&gt;'.FormNavigation($pagename).'(:nl:)'.
                $GroupHeaderFmt;
    } elseif (str_replace('/','.',$pagename)==FmtPageName($DefaultWikiFormPageFmt,$pagename))
        if ($FormNavFooter)
            $GroupFooterFmt.= "(:nl:)=&gt;[[$pagename?action=vieweform | $wikiform_viewform]]";
        else
            $GroupHeaderFmt = "=&gt;[[$pagename?action=vieweform | $wikiform_viewform]]".
                "(:nl:)$GroupHeaderFmt";
} elseif ($action=='print') {
    if (preg_match('/[.\\/]\\d{5}$/',$pagename))
        $HandleActions['print'] = 'HandleBrowseEform';
}

SDV($HandleActions['editeform'],'HandleUseEform');

function HandleUseEform($pagename) {
  global $HandleEformFmt,$EformAction,$PageStartFmt,$PageEformFmt,$PageEndFmt,
    $WikiFormPageFmt;
  SDV($HandleEformFmt,array(&$PageStartFmt, &$PageEformFmt, &$PageEndFmt));
  SDV($EformAction,'saveeform');
  $PageEformFmt = MarkupToHTML($pagename,'(:groupheader:)') . 
    EntryForm($pagename,$EformAction,'post',$WikiFormPageFmt) . 
    MarkupToHTML($pagename,'(:groupfooter:)');
  PrintFmt($pagename,$HandleEformFmt);
}

function FormNavigation($pagename) {
    global $wikiform_editform;
    $r = array();
    preg_match('/^([^.\\/]+)[.\\/](\\d+)$/',$pagename,$m);
    $g = $m[1];
    $prev = sprintf("%05d",$m[2]-1);
    if (PageExists("$g.$prev")) $r[] = "&laquo; [[($g.)$prev]]";
    $r[] = "[[$pagename?action=editeform | $wikiform_editform]]";
    $next = sprintf("%05d",$m[2]+1);
    if (PageExists("$g.$next")) $r[] = "[[($g.)$next]] &raquo;";
    return implode(' &middot; ',$r);
}

function SetFormGroup($pagename,$FormPageFmt,$FormGroupFmt) {
  $i = 0; $prefix = preg_replace("/-.+$/",'',FmtPageName('$Group',$pagename));
  foreach ($FormPageFmt as $p) {
    $pg = FmtPageName($p,$pagename);
    if (PageExists($pg)) 
    return str_replace('$Prefix',$prefix,FmtPageName($FormGroupFmt[$i],$pg));
    $i++;
  }
  return '';
}

function SetFormTemplate($pagename,$FormPageFmt) {
  foreach ($FormPageFmt as $p) {
    $pg = FmtPageName($p,$pagename);
    if (PageExists($pg)) return $pg;
  }
  return '';
}

function FormFields($pagename,$FormPageFmt) {
    global $FormTitleFmt;
    $formname = SetFormTemplate($pagename,$FormPageFmt);
    if (!$formname) Abort("cannot associate a form with '$pagename'");
    $formpage = ReadPage($formname);
    $f = array(); $FormTitleFmt = array();
    $n = 0;
    $formpage['text'] = preg_replace_callback(
                            '/\\(:include\\s+(\\S.*?):\\)/',
                            function ($m) use ($pagename) {
                              return IncludeText($pagename,$m[1]);
                            },
                            @$formpage['text']);
    foreach(explode("\n",$formpage['text']) as $x) {
        if (preg_match("/^:([^:]+?):(\\*)?([[:alnum:]]*?)(?:\\s+([^-+\\(]+?))?(?:\\s*\\(([^\\)]*?)\\))?(?:\\s*([-+]\\*?)?)(?:\\s+(\\d[-+]))?$/",
            $x,$match)) {
            $f[$n]['eprompt'] = trim($match[1]);
            $f[$n]['element'] = ($match[3]) ? strtolower($match[3]) : 
                preg_replace('/[^[:alnum:]]/','',strtolower($match[1]));
            if ($match[2]=='*')
                SDV($FormTitleFmt['csum'], $f[$n]['element']);
            $f[$n]['etitle']  = 
                str_replace(array('"',"'"),array('&#34;','&#39;'),$match[4]);
            $f[$n]['etype']   = $match[5];
            $f[$n]['elist']   = $match[6];
            $f[$n]['esum']    = $match[7];
            $n++;
        } elseif (preg_match("/^!+\\s*(.*?)$/",$x,$match)) {
            if (isset($FormTitleFmt['title']))
                $FormTitleFmt['th'][$n] = $match[1];
            else
                $FormTitleFmt['title']  = $match[1];
        } elseif (preg_match("/^\\(:submit\\s+(post|preview):\\)/",$x,$match)) 
            SDV($FormTitleFmt['submit'], $match[1]);
        elseif (preg_match('/^::(.*?)("(.*)")?$/',$x,$match))
            $FormTitleFmt[$n-1] = array('help' => $match[1], 'prompt' => $match[3]);
    }
    return $f;
}

function FormValues($pagename,$fields,$auth='read') {
    global $Charset;
    $fvals = array(); $ferrs = array(); $n = 0;
    $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
    foreach (explode("\n\n:",substr($page['text'],1)) as $p) {
        preg_match('/^([^:]+):/',$p,$m);
        $fvals[$fields[$n]['element']] = str_replace('$','&#036;',
            htmlspecialchars(preg_replace('/^[^:]+:\s*/','',$p),ENT_QUOTES,$Charset));
        $ferrs[$fields[$n]['element']] = ($fields[$n]['eprompt']==$m[1]) ? '' :
            $m[1];
        $n++;
    }
    PCache($pagename, $page);
    return array('fv' => $fvals, 'fe' => $ferrs);
}

function EntryForm($pagename,$action,$method,$FormPageFmt,$opt=NULL) {
    global $FormTitleFmt, $FmtPV, $Now, $FormValuesFunction, $SaveEformAction, $Charset;
    SDV($SaveEformAction, 'saveeform');
    if (@$opt['formtemplate']) $FormPageFmt = array(MakePageName($pagename, $opt['formtemplate']));
    $f = FormFields($pagename, $FormPageFmt);
    if (@$FormTitleFmt['title']) $out[] = 
        MarkupToHTML($pagename, '!%block class=wikiaction%' . $FormTitleFmt['title']);
    if (@$opt['action']) {
        $action = $opt['action'];
        $pageaction = FmtPageName("action='\$PageUrl'", $pagename);
    } else
        $pageaction = "action='\$ScriptUrl'";
    if ($action=='posteform') $pageaction = '';
    elseif ($action==$SaveEformAction) {
        $pageaction = "action='\$PageUrl'";
        if (PageExists($pagename)) {
            $editing = true; SDV($FormValuesFunction, 'FormValues');
            $fve = $FormValuesFunction($pagename,$f,'edit');
            foreach ($fve as $k => $v) $$k = $v;
        } else $FmtPV['$LastModified'] = '$GLOBALS["CurrentTime"]';
    } elseif ($action=='neweform') $action = 'posteform';
    $FmtPV['$PatchTitle'] = 
        'str_replace("&","&amp;",FmtPageTitle(@$page["title"], $name, 0))';
    $FmtPV['$PatchTitlespaced'] = 
        'str_replace("&","&amp;",FmtPageTitle(@$page["title"], $name, 1))';
    $opt = array_merge(@$_REQUEST, (array)$opt);
    $out[] = "<form method='$method' $pageaction>
        <input type='hidden' name='n' value='$pagename' />
        <input type='hidden' name='action' value='$action' />
        ".(($editing) ? "<input type='hidden' name='basetime' value='$Now' />" : '')."<table>";
    for($i=0;$i<count($f);$i++) {
        if (@$FormTitleFmt['th'][$i]) $out[] = 
           "<tr><th colspan='2' class='divide'>".$FormTitleFmt['th'][$i]."</th></tr>";
        $p = @$FormTitleFmt[$i]['prompt'] ? @$FormTitleFmt[$i]['prompt'] : $f[$i]['eprompt'];
        if ($f[$i]['etitle']) 
            $p = "<span class='prompt' title='".$f[$i]['etitle']."'>$p</span>";
        if (@$fe[$f[$i]['element']]) $p.= ' ('.$fe[$f[$i]['element']].')';
        $out[] = "<tr><th class='prompt'>$p:</th><td>";
        if ($f[$i]['etype']=='' || preg_match('/^".*?"$/',$f[$i]['etype']))
            $f[$i]['etype'] .= '=54';
        elseif (preg_match('/^(".*?"|title)?!(=\\d+)?$/',$f[$i]['etype'],$m)) {
            if ($editing) 
                SDV($opt[$f[$i]['element']],
                   (($m[1]=='title') ? DeTitle($fv[$f[$i]['element']]) : $fv[$f[$i]['element']]));
            else 
                $f[$i]['etype'] = $m[1].($m[2] ? $m[2] : '=54');
        }
        if (preg_match('/^(\\*)?author(plain)?(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
            $col = ($m[3]) ? $m[3] : 32;
            if ($editing) 
                $author = ($m[2]) ? $fv[$f[$i]['element']] : DeLink($fv[$f[$i]['element']]);
            elseif ($m[1]=='*') $author = FmtPageName('$Author',$pagename);
            else $author = '';
            $out[] = "<input type='text' size='$col' name='".$f[$i]['element'].
                    "' value='$author' />";
        } elseif (isset($opt[$f[$i]['element']])) {
            $v = $opt[$f[$i]['element']];
            if (preg_match('/^([^\\|]+)\\|(.*?)$/',$v,$m)) {
               $vv = $m[1]; $vp = $m[2];
            } else {
               $vp = $v; $vv = $v;
            }
           $vv = str_replace("'",'&#39;',$vv);
           $out[] = "$vp<input type='hidden' name='".
                    $f[$i]['element']."' value='$vv' />";
        } elseif (preg_match('/^(?:"(.*?)")?=(\\d+)$/',$f[$i]['etype'],$m)) {
            $default = str_replace(array("'",'$Title'),array('&#39;','$PatchTitle'),$m[1]); 
            $col = $m[2];
            $out[] = "<input type='text' size='$col' name='".
                    $f[$i]['element']."' value='".
                    (($editing) ? $fv[$f[$i]['element']] : $default)."' />";
        } elseif (preg_match('/^title(?:=(\\d+))?$/', $f[$i]['etype'], $m)) {
            $default = (isset($_REQUEST['title'])) ? 
                    str_replace("'",'&#39;',$_REQUEST['title']) : '';
            $col = ($m[1]) ? $m[1] : 54;
            $out[] = "<input type='text' size='$col' name='".
                    $f[$i]['element']."' value='".
                    (($editing) ? DeTitle($fv[$f[$i]['element']]) : $default).
                    "' />";
        } elseif (preg_match('/^text(?:=(\\d+)(?:\\*(\\d+))?)?\\s*(.*?)$/', $f[$i]['etype'], $m)) {
            $row = ($m[1]) ? $m[1] : 10;
            $col = ($m[2]) ? $m[2] : 54;
            $out[] = "<textarea cols='$col' rows='$row' name='".
                    $f[$i]['element']."'>".
                    (($editing) ? $fv[$f[$i]['element']] : $m[3])."</textarea>";
        } elseif (preg_match('/^(\\d+)(?:\\*(\\d+))?$/',$f[$i]['etype'],$m)) {
            $col = ($m[2]) ? $m[2] : 40;
            $rows = ($editing) ? explode("\\\\\n",$fv[$f[$i]['element']]) :
                array();
            for($j=0;$j<$m[1];$j++) {
                $rows[$j] = (isset($rows[$j])) ? " value='".$rows[$j]."'" : '';
                $out[] = "<input type='text' size='$col' name='".
                    $f[$i]['element']."[]'".$rows[$j]." />";
            }
        } elseif (preg_match('/^group(?:=(\\d+))?(?:\\s+`?(.*?))$/',$f[$i]['etype'],$m)) {
            $col = ($m[1]) ? $m[1] : 32;
            $out[] = "$m[2] <input type='text' size='$col' name='".
                    $f[$i]['element']."' value='".
                    (($editing) ? DeLink($fv[$f[$i]['element']]) :'')."' />";
        } elseif (preg_match('/^email(?:"(.*?)")?(?:=(\\d+)(?:\\s+(\\d+))?)?$/',$f[$i]['etype'],$m)) {
            $col = ($m[2]) ? $m[2] : 40;
            $col2= ($m[3]) ? $m[3] : 16;
            $em = ($editing) ? DeMail($fv[$f[$i]['element']]) : 
                               array('','',($m[1] ? " value='".$m[1]."'" : ''));
            $out[] = "<input type='text' size='$col' name='".
                    $f[$i]['element']."name'".$em[0]." /><br />".
                    "<input type='text' size='$col2' name='".
                    $f[$i]['element']."[]'".$em[1]." />@".
                    "<input type='text' size='$col2' name='".
                    $f[$i]['element']."[]'".$em[2]." />";
        } elseif (preg_match('/^(\\*)?date$/',$f[$i]['etype'],$m)) {
            if ($editing)
                $date = ($fv[$f[$i]['element']]) ? $fv[$f[$i]['element']] : 'yyyy-mm-dd';
            elseif ($m[1]=='*')
                $date = strftime('%Y-%m-%d',time());
            else
                $date = 'yyyy-mm-dd';
            if ($date == 'yyyy-mm-dd') {
                $v    = strftime('%Y-%m-%d',time());
                $check= " &nbsp;<input type='checkbox' name='".
                    $f[$i]['element']."-x' value='$v' /> $v";
            } else
                $check = '';
            $y = substr($date,0,4);
            $m = substr($date,5,2);
            $d = substr($date,8,2);
            $out[] = "<input type='text' size='5' maxlength='4' name='".
                    $f[$i]['element']."[]' value='$y' /> - ".
                    "<input type='text' size='3' maxlength='2' name='".
                    $f[$i]['element']."[]' value='$m' /> - ".
                    "<input type='text' size='3' maxlength='2' name='".
                    $f[$i]['element']."[]' value='$d' />$check";
        } elseif (preg_match('/^category(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
            $col = ($m[1]) ? $m[1] : 54;
            if ($editing) $category = DeLink($fv[$f[$i]['element']]);
            else $category = '';
            $out[] = "<input type='text' size='$col' name='".$f[$i]['element'].
                    "' value='$category' />";
        } elseif (preg_match('/^caption(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
            $col = ($m[1]) ? $m[1] : 32;
            $cap = ($editing) ? DeCaption($fv[$f[$i]['element']]) : array('','');
            $out[] = "<input type='text' size='$col' name='".$f[$i]['element'].
                    "' value='$cap[0]' />".' "'.
                    "<input type='text' size='$col' name='".$f[$i]['element'].
                    "-cap' value='$cap[1]' />".'"';
        } elseif (preg_match('/^(\\*)?attach\\s*(.*?)$/',$f[$i]['etype'],$m)) {
            $col = 32;
            $out[] = "Attach: <input type='text' size='$col' name='".
                    $f[$i]['element']."' value='".
                    (($editing) ? DeAttach($fv[$f[$i]['element']],$m[1],$m[2]) : '').
                    "' /> <strong>.</strong> ";
            if ($m[2]) {
                if (strstr($m[2],'|')) {
                    $checked = false; 
                    $cv = $editing ? DeAttachExt($fv[$f[$i]['element']],$m[2]) : '';
                    foreach(explode('|',$m[2]) as $c) {
                        $s=''; $c = trim($c);
                        if ($c[0]=='*') {
                            $c = substr($c,1);
                            if (!$checked) $s = " checked='checked'";
                            $checked = true;
                        }
                        if ($editing) $s = ($c==$cv) ? " checked='checked'" : ''; 
                        $out[] = "<input type='radio' name='".$f[$i]['element']. 
                            "-ext' value='$c'$s />$c ";
                    }
                } else $out[] = $m[2];
            }
        } elseif (preg_match('/^(\\*)?check\\s*(.*?)$/',$f[$i]['etype'],$m)) {
            $v = ($m[2]=='') ? 'Yes' : $m[2];
            $s = ($m[1]=='*') ? " checked='checked'" : '';
            if ($editing) $s =
                    ($v==$fv[$f[$i]['element']]) ? " checked='checked'" : ''; 
            $out[] = "<input type='checkbox' name='".
                    $f[$i]['element']."' value='$v'$s />";
        } elseif (preg_match('/^hide\\s*\\*?(.*?)$/',$f[$i]['etype'],$m)) {
            $v = ($m[1]=='') ? $f[$i]['element'] : $m[1];
            if (preg_match('/\\$[[:upper:]]/',$m[1]))
              $v = ($action=='posteform') ? str_replace('$Name','{$Name}',$m[1])
                    : FmtPageName($m[1],$pagename);
            $v = preg_replace('/(:f?para\s[^:]+:)/', '($1)', $v);
            if (preg_match('/^([^\\|]*)\\|(.*?)$/',$v,$m)) {
               $vv = $m[1]; $vp = $m[2];
            } else {
               $vp = $v; $vv = $v;
            }
            $out[] = ($v) ? "$vp<input type='hidden' name='".
                    $f[$i]['element']."' value='$vv' />" : '<em>none</em>';
        } elseif (strstr($f[$i]['etype'],',')) {
            $out[] = "<select name='".$f[$i]['element']."'>";
            $selected = false;
            foreach(explode(',',$f[$i]['etype']) as $c) {
                $s=''; $c = htmlspecialchars(trim($c),ENT_QUOTES,$Charset);
                if ($c[0]=='*') {
                    $c = substr($c,1);
                    if (!$selected) $s = " selected='selected'";
                    $selected = true;
                }
                if (preg_match('/^([^\\|]*)\\|(.*?)$/',$c,$m)) {
                    $cv = trim($m[1]); $cp = trim($m[2]);
                } else {
                    $cv = trim($c); $cp = $cv;
                }
                if ($editing) $s =
                    ($cv==$fv[$f[$i]['element']]) ? " selected='selected'" : ''; 
                $out[] = "<option value='$cv'$s>$cp</option>";
            }
            $out[] = "</select>";
        } elseif (strstr($f[$i]['etype'],';')) {
            $checked = false;
            foreach(explode(';',$f[$i]['etype']) as $c) {
                $s=''; $c = htmlspecialchars(trim($c),ENT_QUOTES,$Charset);
                if ($c[0]=='*') {
                    $c = substr($c,1);
                    if (!$checked) $s = " checked='checked'";
                    $checked = true;
                }
                if (preg_match('/^([^\\|]*)\\|(.*?)$/',$c,$m)) {
                    $cv = trim($m[1]); $cp = trim($m[2]);
                } else {
                    $cv = trim($c); $cp = $cv;
                }
                if ($editing) $s =
                    ($cv==$fv[$f[$i]['element']]) ? " checked='checked'" : ''; 
                $out[] = "<input type='radio' name='".$f[$i]['element']. 
                    "' value='$cv'$s />$cp ";
            }
        } elseif (strstr($f[$i]['etype'],':')) {
            if ($f[$i]['etype'][0]=='!') {
                $f[$i]['etype'] = substr($f[$i]['etype'],1);
                if ($editing) 
                    $fv[$f[$i]['element']] = DeLink($fv[$f[$i]['element']]);
            }
            foreach(explode(':',$f[$i]['etype']) as $c) {
                $s=''; $c = htmlspecialchars(trim($c),ENT_QUOTES,$Charset);
                if ($c[0]=='*') {
                    $c = substr($c,1);
                    $s = " checked='checked'";
                }
                if ($editing) $s =
                    (strstr($fv[$f[$i]['element']],$c))?" checked='checked'":'';
                $out[] = "<input type='checkbox' name='".$f[$i]['element']. 
                    "[]' value='$c'$s />$c ";
            }
        }
        $out[] = "</td></tr>";
        if (@$FormTitleFmt[$i]['help']) $out[] = 
           "<tr><td>&nbsp;</td><td class='note'>{$FormTitleFmt[$i]['help']}</td></tr>";
    }
    $out[] = "<tr><td>&nbsp;</td><td align='right'>";
    if (@$FormTitleFmt['submit']) $out[] = 
    "<input type='hidden' name='onsubmit' value='{$FormTitleFmt['submit']}' />";
    $out[] = 
        FmtPageName("<input type='submit' value='$[Submit]' accesskey='s' />",
            $pagename);
    if ($action!='posteform') $out[] = 
        FmtPageName("<input type='submit' name='cancel' value='$[Cancel]' />",
            $pagename);
    $out[] = "</td></tr></table></form>";
    return implode("\n",$out);
}

function DeTitle($text) {
    return preg_replace("/\\n\\(:title.*?:\\)/",'',$text);
}

function DeLink($text) {
    return preg_replace('/\\[\\[([!~]|.*?\\/)/','',str_replace(']]','',$text));
}

function DeMail($text) {
    if ($text[0]=='[')
        preg_match('/^\\[\\[(.*?)\\s-&gt;\\smailto:([^@]+)@([^\\]]+)\\]\\]$/',
            $text, $m);
    else
        preg_match('/^(.*?)\\s\\(([^@]*)@([^\\)]*)\\)$/',$text,$m);
    for ($j=1;$j<4;$j++)
        $r[] = " value='".$m[$j]."'";
    return $r;
}

function DeAttach($text,$star,$ext) {
    $bra = 'Attach:';  $ket = ($ext ? '.('. str_replace('*','',$ext).')' : '');
    if ($star) { $bra = "[[($bra)"; $ket = $ket . ']]'; }
    return str_replace($bra,'',preg_replace("/$ket$/",'',$text));
}

function DeAttachExt($text,$ext) {
    $ket = str_replace('*','',$ext);
    if (preg_match("/\\.($ket)(\\]\\])?$/",$text,$m)) return $m[1]; else return '';
}

function DeCaption($text) {
    return preg_match('/^(.*?)(?:"(.*?)")?$/',$text,$m) ? array(trim($m[1]), $m[2]) : 
                                                          array('', '');
}

function FormData($pagename,$FormPageFmt) {
    global $UrlExcludeChars, $FormTitleFmt, $ChangeSummary;
    $f = FormFields($pagename,$FormPageFmt);
    for($i=0;$i<count($f);$i++) {
        if (preg_match('/^\\*?author(?:=(\\d+))?$/',$f[$i]['etype'])) {
            $v = $_REQUEST[$f[$i]['element']];
            if ($v) $v = "[[~$v]]";
        } elseif (preg_match('/^title!?(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
            $v = $_REQUEST[$f[$i]['element']];
            if ($v) {
                $v .= "\n(:title $v:)";
                SDV($FormTitleFmt['csum'], $f[$i]['element']);
            }
        } elseif (preg_match('/^group(?:=(\\d+))?\\s+`?(.*?)$/',$f[$i]['etype'],$m)) {
            $v = $_REQUEST[$f[$i]['element']];
            if ($v) $v = "[[$m[2]/$v]]";
        } elseif (preg_match('/^\\*?date$/',$f[$i]['etype'])) {
            $e = $f[$i]['element'].'-x';
            $v = @$_REQUEST[$e] ? $_REQUEST[$e] : str_replace('yyyy-mm-dd','',
                implode('-',$_REQUEST[$f[$i]['element']]));
        } elseif (preg_match('/^category(?:=(\\d+))?$/',$f[$i]['etype'],$m))
            $v = str_replace('[[!]]','',
    '[[!'.preg_replace('/,\\s*/',']], [[!',$_REQUEST[$f[$i]['element']]).']]');
        elseif (preg_match('/^(\\d+)(?:\\*(\\d+))?$/',$f[$i]['etype'],$m))
            $v = preg_replace("/([\\\]+\\n)+$/",'',
                implode("\\\\\\\\\n",$_REQUEST[$f[$i]['element']]));
        elseif (preg_match('/^email/',$f[$i]['etype'])) {
            $em = implode('@',$_REQUEST[$f[$i]['element']]);
            $v = (preg_match("/^[[:alnum:]][^$UrlExcludeChars]+[[:alnum:]]$/",$em)) ?
                '[['.$_REQUEST[$f[$i]['element'].'name']." -> mailto:$em]]" :
                $_REQUEST[$f[$i]['element'].'name']." ($em)";
        } elseif (preg_match('/^caption(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
            $v = trim($_REQUEST[$f[$i]['element']]);
            $cap = trim($_REQUEST[$f[$i]['element'].'-cap']);
            if ($v) $v .= ($cap ? ' "'.$cap.'"' : '');
            elseif ($cap) $v = '"'.$cap.'"';
        } elseif (preg_match('/^(\\*)?attach\\s*(.*?)$/',$f[$i]['etype'],$m)) {
            $v = preg_replace('/\\s+/','_',trim($_REQUEST[$f[$i]['element']]));
            if ($v) {
                $bra = 'Attach:';  $ext = $_REQUEST[$f[$i]['element'].'-ext'];
                $ket = ($ext ? '.' . $ext : ($m[2] ? '.' . $m[2] : ''));
                if ($m[1]) { $bra = "[[($bra)"; $ket = $ket . ']]'; }
                $v = "$bra$v$ket";
            }
        } elseif (preg_match('/^hide/',$f[$i]['etype'])) {
            $v = $_REQUEST[$f[$i]['element']];
        } elseif (strstr($f[$i]['etype'],':')) 
            @$v = ($f[$i]['etype'][0]=='!') ? str_replace('[[!]]','',
                '[[!'.implode(']], [[!',$_REQUEST[$f[$i]['element']]).']]') :
                implode(', ',$_REQUEST[$f[$i]['element']]);
        else $v = $_REQUEST[$f[$i]['element']];
        $text[] = ':'.$f[$i]['eprompt'].':'.$v;
    }
    if (isset($FormTitleFmt['csum'])) {
        $_POST['csum'] = $_REQUEST[$FormTitleFmt['csum']];
        $ChangeSummary = stripmagic($_REQUEST[$FormTitleFmt['csum']]);
    }
    return implode("\n\n",$text);
}

function WikiformPrompt($f,$element) {
    for($i=0;$i<count($f);$i++)
        if ($element==$f[$i]['element']) return $f[$i]['eprompt'];
    return $element;
}

function EntryListEquals($haystack, $needle) {
    foreach(explode('|',$needle) as $n)
      if (strtolower($haystack)==strtolower($n)) return true;
    return false;
}

function EntryListContains($haystack, $needle) {
    if (!$needle) return ($needle==$haystack);
    foreach(explode('|',$needle) as $n)
      if (strpos(strtolower($haystack), strtolower($n))!==false) return true;
    return false;
}

function EntryListLessThan($haystack, $needle) {
    return (preg_match('/^(.*?)&gt;(.*?)$/',$needle,$n)) ?
        (strcasecmp($haystack, $n[2]) > 0 && strcasecmp($haystack, $n[1]) < 0) :
        (strcasecmp($haystack, $needle) < 0);
}

function EntryListGreaterThan($haystack, $needle) {
    return (preg_match('/^(.*?)&lt;(.*?)$/',$needle,$n)) ?
        (strcasecmp($haystack, $n[1]) > 0 && strcasecmp($haystack, $n[2]) < 0) :
        (strcasecmp($haystack, $needle) > 0);
}

function FmtEntryList($fmt,$pagename,$opt) {
    global $WikiFormPageFmt,$PublishWikiFormFmt,$PublishForm,$HTMLVSpace,
        $FmtV,$PCache,$AsSpacedFunction,$EntryListOperatorPattern,
        $EntryListOperatorFunction, $Charset;
    global $wikiform_select,$wikiform_page,$wikiform_score,$wikiform_allitems,
      $wikiform_lastmod,$wikiform_nomatches,$wikiform_matches,$wikiform_typeset;
    SDV($EntryListOperatorPattern, '[=~]|&[gl]t;');
    $EntryListOperatorFunction = array(
      '='    => 'EntryListEquals',
      '~'    => 'EntryListContains',
      '&lt;' => 'EntryListLessThan',
      '&gt;' => 'EntryListGreaterThan'
      );
    $u = FmtPageName('$PageUrl',$pagename);
    $opt = array_merge($opt, @$_REQUEST);
    $terms = preg_split('/((?:[-+]\\*?|!|\\w+[:=])?(?:"[^"]*"|\'[^\']*\'|\\S+))/',
        $opt['q'],-1,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
    foreach($terms as $t) { 
        if (trim($t)=='') continue;
        if (preg_match('/^([^\'":=]*)[:=]([\'"]?)(.*?)\\2$/',$t,$m)) 
            SDV($opt[strtolower($m[1])], $m[3]);
        elseif (preg_match('/^([-+]\\*?|!)([[:alnum:]]+)$/',$t,$m))
            $elist[strtolower($m[2])] = $m[1]; 
    }
    $g = (@$opt['group']) ? $opt['group'] : FmtPageName('$Group',$pagename);
    $f = FormFields("$g.$g",$WikiFormPageFmt);
    
    if (@$opt['search']) { 
        if (@$opt['value']) {
           if (strstr($opt['value'],',')) {
              $selected = false;
              foreach(explode(',',$opt['value']) as $c) {
                $s=''; $c = trim($c);
                if ($c[0]=='*') {
                    $c = substr($c,1);
                    if (!$selected) {
                        $s = " selected='selected'";
                        if (!isset($_REQUEST[$opt['search']])) 
                            $_REQUEST[$opt['search']] = $opt[$opt['search']] = $c;
                    }
                    $selected = true;
                }
                $sel[] = "<option value='$c'$s>$c</option>";
              }
              $searchfor = "<select name='{$opt['search']}'>".implode("\n",$sel)."</select>";
           } else {
              $searchfor = "<input class='wikisearchbox' type='text' name='{$opt['search']}'".
                  " value='".$AsSpacedFunction($opt['value'])."' size='40' />";
           }
        } else 
           $searchfor = "<input class='wikisearchbox' type='text' name='{$opt['search']}'".
                  " value='' size='40' />";
        $SearchBoxFmt = "<form class='wikisearch' action='\$PageUrl' method='get'>
    <input type='hidden' name='n' value='\$FullName' />
    <input type='hidden' name='action' value='browse' />\$SearchPrompt:
    ".$searchfor."
    <input class='wikisearchbutton' type='submit' value='$[Search]' /></form>";
        $FmtV['$SearchPrompt'] = WikiformPrompt($f,$opt['search']);
        $search = Keep(FmtPageName($SearchBoxFmt,$pagename));
        if (isset($_REQUEST[$opt['search']])) 
            $sv = $opt['search'].'='.$_REQUEST[$opt['search']].'&amp;';
        else return $search;
    } else $search = '';
    
    $entrylist = ListPages("/^$g\\.\\d+$/");
    $out[] = "<table cellspacing='0' class='wikilist'>";
    $out[] = "<caption>\$Caption</caption>";
    $n = 0; $cols = array(); $order = @$opt['order']; $caption = '';
    $s = 0; $scols= array(); $tcol = '';
    $score = false; $lastmodified = false; $pagenumber = true;
    if ($order[0]=='-') {
        $otoggle = '';
        $oelement = substr($order,1);
    } else {
        $otoggle = '-';
        $oelement = $order;
    }
    $o = ($oelement=='name') ? $otoggle : '-';
    $oeprompt = $wikiform_page;
    if (@$elist['page']=='!') $pagenumber = false;
    $out[] = Keep("<tr>" . (($pagenumber) ? "<th class='wikilist'>".
        "<a href='$u?$sv"."order=$o"."name'>$wikiform_page</a></th>" : ''));
    for($i=0;$i<count($f);$i++) {
        if (@$opt[$f[$i]['element']]) {
            $opt[$f[$i]['element']] = 
                htmlspecialchars(stripmagic($opt[$f[$i]['element']]),ENT_NOQUOTES,$Charset);
            $caption.= $f[$i]['eprompt']."=''".$opt[$f[$i]['element']]."'' ";
            
            if (preg_match("/^([-!])?($EntryListOperatorPattern)(.*?)$/",
                    $opt[$f[$i]['element']],$m)) {
                $optfnc[$f[$i]['element']]   = $EntryListOperatorFunction[$m[2]];
                $optvar[$f[$i]['element']][] = $m[1].$m[3];
            } else {
                $optfnc[$f[$i]['element']]   = $EntryListOperatorFunction['~'];
                preg_match_all('/([-!])?("[^"]*"|\'[^\']*\'|\\S+)/',
                    $opt[$f[$i]['element']],$terms,PREG_SET_ORDER);
                foreach($terms as $t) 
                    $optvar[$f[$i]['element']][] = 
                    (preg_match('/^([\'"])(.*?)\\1$/',$t[2],$m)) ? $t[1].$m[2] : $t[0];
            }
            
            $scols[$s] = $f[$i]['element'];
            $s++;
            if ($f[$i]['elist']=='') $f[$i]['elist'] = 's';
        }
        if ($f[$i]['esum']) $score = true;
        if (@$elist[$f[$i]['element']])
            $f[$i]['elist'] = $elist[$f[$i]['element']];
        if (preg_match('/^([-+])(\\*)?$/',$f[$i]['elist'],$m)) {
            $cols[$n] = $f[$i]['element'];
            $n++;
            $o = ($m[1]=='-') ? '-' : '';
            if ($oelement==$f[$i]['element']) {
                $o = $otoggle;
                $oeprompt = $f[$i]['eprompt'];
            }
            if ($m[2]) $order .= ','.$o.$f[$i]['element'];
            if (preg_match('/^title/',$f[$i]['etype'])) $tcol=$f[$i]['element'];
            $out[] = Keep("<th class='wikilist'><a href='$u?$sv"."order=$o".
                    $f[$i]['element']."'>".$f[$i]['eprompt'].'</a></th>');
        }
    }
    if (@$elist['lastmodified']) {
        $lastmodified = true;
        if (preg_match('/^([-+])(\\*)$/',$elist['lastmodified'],$m))
            $elist['lastmodified'] = $m[1];
        $o = ($elist['lastmodified']=='-') ? '-' : '';
        if ($oelement=='lastmodified') {
            $o = $otoggle;
            $oeprompt = $wikiform_lastmod;
        }
        if ($m[2]) $order .= ','.$o.'lastmodified';
        $out[] = Keep("<th class='wikilist'><a href='$u?$sv"."order=$o".
            "lastmodified'>$wikiform_lastmod</a></th>");
    }
    if ($score) {
        $o = ($oelement=='score') ? $otoggle : '-';
        if ($oelement=='score') $oeprompt = $wikiform_score;
        $out[] = Keep("<th class='wikilist'><a href='$u?$sv"."order=$o".
            "score'>$wikiform_score</a></th>");
    }
    $order.= ',name';
    $out[] = '</tr>';
    if ($caption=='') $caption =  $wikiform_allitems;
    $out[1] = str_replace('$Caption',"$wikiform_select $caption",$out[1]);
    $n = 0; $elist = array();
    foreach($entrylist as $e) {
        $page = ReadPage($e);
        preg_match_all("/\n:([^:]+):([^\n\\\\]*)/","\n".$page['text'],$match);
        $fields = array(); $sum = 0;
        for($i=0;$i<count($match[1]);$i++) {
            if ($f[$i]['eprompt']==$match[1][$i] && $f[$i]['elist'])
                $fields[$f[$i]['element']] = 
                    htmlspecialchars($match[2][$i],ENT_QUOTES,$Charset);
            if ($f[$i]['esum'][1]=='+')
                $sum = $sum + FirstDigit($match[2][$i],$f[$i]['esum'][0]);
            elseif ($f[$i]['esum'][1]=='-') 
                $sum = $sum - FirstDigit($match[2][$i],$f[$i]['esum'][0]);
        }
        foreach($scols as $c) {
            if (!$opt[$c]) continue;
            foreach($optvar[$c] as $t)
                if ($t[0]=='-' || $t[0]=='!') {
                    if ($optfnc[$c](@$fields[$c],substr($t,1))) continue 3;
                } else {
                    if (!$optfnc[$c](@$fields[$c],$t))          continue 3;
                }
        }
        $elist[$n] = $fields;
        $elist[$n]['name'] = FmtPageName('$Group/$Name',$e);
        if ($lastmodified) {
            PCache($e,$page);
            $elist[$n]['lastmodified'] = $PCache[$e]["time"];
            $elist[$n]['lastmodfmt']   = 
                preg_replace('/,[^,]*$/','',FmtPageName('$LastModified',$e));
        }
        if ($score) $elist[$n]['score'] = ($sum<10) ? "0$sum" : $sum;
        $n++;
    }
    usort($elist,CreateOrderFunction($order));
    $matches = array();
    $PageActions = array('edit' => 'edit', 'form' => 'editeform');
    $a = (@$opt['page']) ? '(?action='.$PageActions[$opt['page']].')' : '';
    foreach($elist as $e) {
        $out[] = '<tr>'.(($pagenumber) ? '<td>[['.$e['name']."$a]]</td>" : '');
        foreach($cols as $c) {
            $cell = (@$e[$c]) ? $e[$c] : '&nbsp;';
            if ($c==$tcol) $cell = "[[{$e['name']} | $cell]]";
            $out[] = "<td>$cell</td>";
        }
        if ($lastmodified) $out[] = '<td>'.$e['lastmodfmt'].'</td>';
        if ($score) $out[] = '<td align=\'right\'>'.$e['score'].'</td>';
        $out[] = '</tr>';
        $matches[] = $e['name'];
    }
    $out[] = '</table>';
    if (count($matches)) $out[]='<p>'.count($matches)." $wikiform_matches</p>";
    if (@$opt['include']) $oeprompt .= '*'.MakePageName("$g.$g",$opt['include']);
    $FmtV['$Pages'] = implode('+',$matches); $FmtV['$PSort'] = $oeprompt;
    $FmtV['$Typeset'] = $wikiform_typeset;
    $pbutton = Keep(FmtPageName($PublishWikiFormFmt,$pagename));
    if ($PublishForm==2) array_unshift($out,$pbutton);
    elseif ($PublishForm) $out[] = "$HTMLVSpace\n$pbutton";
    return $search . 
        ((count($matches)) ? implode("\n",$out) : "<p>$wikiform_nomatches ($caption)</p>");
}

function FirstDigit($value,$shift) {
    return (preg_match('/^(\\d)/',$value,$m)) ? $m[1] - $shift : 0;
}

# this is a piece of incomprehensible Pm code for more efficient sorting
function CreateOrderFunction($order) {
    global $CollateFunction;
    $code = '';
    foreach(preg_split('/[\\s,|]+/',$order,-1,PREG_SPLIT_NO_EMPTY) as $o) {
        $r = '';
        if ($o[0]=='-') { $r = '-'; $o = substr($o,1); }
        if (preg_match('/\\W/',$o)) continue;
        $code .= "\$c=$CollateFunction(@\$x['$o'],@\$y['$o']); if (\$c!=0) return $r\$c;\n";
    }
    $code .= "return 0;\n";
    return create_function('$x,$y',$code);
}

function FormParaText($prompts, $values, $prompt) {
    for($i=0;$i<count($prompts);$i++)
        if ($prompt==$prompts[$i]) return $values[$i];
    return $prompt;
}

function FormParagraph($pagename, $field, $page) {
    global $WikiFormPageFmt, $PCache, $wikiform_nomatches, $wikiform_newentry;
    $f = FormFields($page,$WikiFormPageFmt);
    $m = WikiformPrompt($f, $field);
    if (PageExists($page)) {
        $p = ReadPage($page);
        PCache($page, $p);
        $r = FmtPageName('$LastModified', $page);
        preg_match_all("/\n:([^:]+):([^\n\\\\]*)/","\n".$p['text'],$match);
        $t = FormParaText($match[1], $match[2], $m);
        return "[[$page | $t]] ($r)";
    } else
        return "[[$page?action=editeform | $m]] ($wikiform_newentry)";
}

function NewestEntry($pagename, $group=NULL) {
    global $RecordStartingNmuber;
    $g = ($group) ? ($group) : FmtPageName('$Group',$pagename);
    SDV($RecordStartingNumber,0);
    $record = $RecordStartingNumber;
    foreach(ListPages("/^$g\\.\\d/") as $i)
        $record = max(@$record,substr($i,strlen($g)+1));
    return sprintf("%05d",@$record);
}

function HandleBrowseEform($pagename, $auth='read') {
  # handle display of a page using a view template
  global $WikiFormViewFmt, $WikiFormPageFmt,
    $FmtV, $HandleBrowseFmt, $PageStartFmt, $PageEndFmt;
  if (isset($_REQUEST['template'])) $WikiFormViewFmt = $_REQUEST['template'];
  else SDV($WikiFormViewFmt, 'ViewTemplate');
  $ViewTemplate = MakePageName($pagename, $WikiFormViewFmt);
  if (PageExists($pagename) && PageExists($ViewTemplate)) {
     $f = FormFields($pagename,$WikiFormPageFmt);
     $fve = FormValues($pagename,$f,$auth);
     foreach ($fve as $k => $v) $$k = $v;
     $template = RetrieveAuthPage($ViewTemplate, $auth, true, READPAGE_CURRENT);
     $text = $template['text'];
     for($i=0;$i<count($f);$i++) $text = str_replace('<'.$f[$i]['element'].'>',
        str_replace(array('&amp;','&quot;','&#034;','&#036;','&#039;'), 
                    array('&','"','"','$',"'"), $fv[$f[$i]['element']]), $text);
     $text = '(:groupheader:)'.@$text.'(:groupfooter:)';
     $FmtV['$PageText'] = str_replace(array('&amp;lt;','&amp;gt;'),
        array('&lt;','&gt;'), MarkupToHTML($pagename,$text));
     SDV($HandleBrowseFmt,array(&$PageStartFmt,'$PageText',&$PageEndFmt));
     PrintFmt($pagename,$HandleBrowseFmt);
  } else
    HandleBrowse($pagename, $auth);
}

?>