<?php if (!defined('PmWiki')) exit();
/*  === EditAttributes ===
 *  Copyright 2009 Eemeli Aro <eemeli@gmail.com>
 *  Copyright 2015 Ed Wildgoose <lists@wildgooses.com>
 *
 *  Edit a page's title, description and other attributes
 *  using separate EditForm fields
 *
 *  Developed and tested using PmWiki 2.2.x,
 *  partly based on Mike Shanley's EditMore
 *
 *  To install, first add the following to your config file,
 *  adjusted for your configuration:

        $EditAttrFields = array(
            'title' => array(
                'attribute' => 1,
                'markup' => '(:title $1:)',
                'filter' => 'EditAttrAutofillTitle' ),
            'description' => array( 'attribute' => 1, 'markup' => '(:description $1:)' ),
            'keywords' => array( 'attribute' => 1, 'markup' => '(:keywords $1:)' )
        );
        include_once("$FarmD/cookbook/editattr.php");

 *  Next, add the matching input fields to your Site.EditForm,
 *  these are of the form (:input e_FIELDNAME:) -- eg. (:input e_title:)
 *
 *  For more information, please see the online documentation at
 *      http://www.pmwiki.org/wiki/Cookbook/EditAttributes
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License,
 *  Version 2, as published by the Free Software Foundation.
 *  http://www.gnu.org/copyleft/gpl.html
 *
 *  Line 59: Changed strftime -> PSFT (Siegfried Seibert 2022-03-15)
 *  Added Brackets to $t on line 54 (Siegfried Seibert 2022-03-28)
 *  There ist still the function PPRE, which is deprecated since PHP >= 7.2
 */

$RecipeInfo['EditAttributes']['Version'] = '2022-03-15';

if (!empty($EditAttrFields)) {
    $EditFields = array_merge($EditFields, array_keys($EditAttrFields));
    $SaveProperties = array_diff($SaveProperties, array_keys($EditAttrFields));
}

array_unshift($EditFunctions,'EditAttrBeforePost');
array_push($EditFunctions,'EditAttrAfterPost');

function EditFilterCtime($pagename, $fn, &$new) {
  global $Now, $MessagesFmt, $TimeFmt, $EnablePost;
  $ct = trim($new['ctime']);
  $t = ( empty($ct) ? $Now : preg_match('/^\d{9,}$/', $ct) ) ? intval($ct) : strtotime($ct);
  if (!$t) {
    $t = $Now;
    $MessagesFmt[] = "<h3 class='wikimessage'>$[Error parsing time:] $ct</h3>";
  }
  $new['ctime'] = $EnablePost ? $t : PSFT($TimeFmt, $t);
}

function EditDefaultTrue( $pagename, $fn, &$new ) {
  $rev=$new['rev'];
  if (empty( $new[$fn] ) && empty( $rev) ) {
    $new[$fn] = 1;
  }
}

function EditAttrAutofillTitle( $pagename, $fn, &$new ) {
    global $SearchPatterns, $EditAttrAutofillTitlePatterns;

    if ( ($fn!='title') || @$new['title'] || isset($_POST['title']) || isset($_REQUEST['template']) ) return;

    SDVA( $EditAttrAutofillTitlePatterns, array(
        'recent' => $SearchPatterns['normal']['recent'],
        'group' => $SearchPatterns['normal']['group'],
        'admin' => '!^(Site|SiteAdmin|PmWiki)\.!',
        'nonbase' => '!\b(SideBar|Draft)$!' ));

    if ( MatchPageNames( $pagename, $EditAttrAutofillTitlePatterns ) )
        $new['title'] = FmtPageName('$Title',$pagename);
}

function EditAttrRequireNotEmpty( $pagename, $fn, &$new ) {
    global $MessagesFmt, $EnablePost;
    if (empty( $new[$fn] )) {
        $MessagesFmt[] = "<h3 class='wikimessage'>$[$fn is required.]</h3>";
        $EnablePost = 0;
    }
}

function EditAttrBeforePost( $pagename, &$page, &$new ) {
    global $EnablePost, $PageAttributes, $HandleAuth, $Now, $EditAttrFields;

    foreach( $EditAttrFields as $fn => $fa ) {
        ## require attr level authentication to edit password fields
        if ( isset( $PageAttributes[$fn] ) || !strncmp($fn,'passwd',6) ) $fa['auth'] = 'postattr';

        if ( @$fa['auth'] && ( $fa['auth'] != 'edit' )
            && !RetrieveAuthPage( $pagename, $HandleAuth[ $fa['auth'] ], FALSE, READPAGE_CURRENT )
        ) $new[$fn] = @$page[$fn];

        if ( is_callable(@$fa['filter']) ) $fa['filter']( $pagename, $fn, $new );

        ## save history
        if ( (@$fa['attribute'] > 1)
            && ( ( @$new[$fn] != @$page[$fn] )
                || ( !empty($new[$fn]) && !preg_grep("/^$fn:/", array_keys($page)) )
            ) ) $new["$fn:$Now"] = @$new[$fn];

        ## add page text markup
        if ( @$fa['markup'] && !empty( $new[$fn] ) ) {
            $fm = is_array($fa['markup']) ? reset($fa['markup']) : $fa['markup'];
            if ( strlen($fm) > 0 ) {
                $repl = array(
                    '$0' => $new[$fn],
                    '$1' => str_replace(
                        array(  ':)', "\n", "\r", "\x0B" ),
                        array( ': )',  ' ',  ' ',    ' ' ), $new[$fn] ) );
                $new['text'] .= "\n" . str_replace( array_keys($repl), array_values($repl), $fm );
            }
        }

        ## cache attribute values for page preview
        if ( !$EnablePost && isset($new[$fn]) && @$fa['attribute'] ) PCache( $pagename, array( $fn => $new[$fn] ) );

        ## remove blanks & markup-only fields
        if ( ( empty($new[$fn]) || empty($fa['attribute']) ) && ( $fn != 'text' ) ) unset($new[$fn]);
    }
}

function EditAttrKeep($x) {
    global $KeepToken, $KPV, $KPCount;
    $x = PPRE("/$KeepToken(EA\\d.*?)$KeepToken/", '$GLOBALS[\'KPV\'][$m[1]]', $x);
    $KPV['EA'.(++$KPCount)] = $x;
    return $KeepToken.'EA'.$KPCount.$KeepToken;
}

function EditAttrAfterPost( $pagename, &$page, &$new ) {
    global
        $PageAttributes, $HandleAuth, $InputTags, $CondTextPattern, $KPV, $KeepToken,
        $EditAttrPreserve, $EditAttrFields;

    SDVA( $EditAttrPreserve, array( 'if' => $CondTextPattern ) );
    foreach ( $EditAttrPreserve as $p ) if (!empty($p))
        $new['text'] = PPRE($p, 'EditAttrKeep($m[0])', $new['text']);

    foreach( $EditAttrFields as $fn => $fa ) {
        $pat = empty($fa['markup'])
            ? FALSE
            : ( is_array($fa['markup'])
                ? reset(array_keys( $fa['markup'] ))
                : str_replace( array('\$0','\$1'), '(.*?)', preg_quote($fa['markup'],'/') ) );

        if ( $pat && preg_match("/$pat/i", $new['text'], $matches) ) {
            $new[$fn] = $matches[1];
            $new['text'] = preg_replace("/\\n?$pat/i", '', $new['text']);
        }

        if ( @$fa['auth'] && ( $fa['auth'] != 'edit' )
            && !RetrieveAuthPage( $pagename, $HandleAuth[ $fa['auth'] ], FALSE, READPAGE_CURRENT )
        ) {
            $new[$fn] = '(protected)';
            SDV( $InputTags["e_$fn"]['disabled'], 'disabled' );
        }

        if ( @$fa['input'] && is_array($fa['input']) ) SDVA( $InputTags["e_$fn"], $fa['input'] );

        SDVA( $InputTags["e_$fn"], array(
            ':html' => "<input type='text' \$InputFormArgs />",
            'name' => $fn, 'size' => '60', 'title' =>'Title',
            'value' => str_replace('$','&#036;',htmlspecialchars(@$new[$fn],ENT_NOQUOTES)) ));
        if (preg_match('/\stype=([\'"]?)checkbox\1/', $InputTags["e_$fn"][':html'])) {
            $InputTags["e_$fn"]['value'] = '1';
            if (!empty($new[$fn])) $InputTags["e_$fn"]['checked'] = '1';
        } elseif (preg_match('/<textarea\s/', $InputTags["e_$fn"][':html'])) {
            $InputTags["e_$fn"][':content'] = array('value');
        } elseif (preg_match('/<select/', $InputTags["e_$fn"][':html'])) {
            if(empty($new[$fn])) $new[$fn] = '';

            $InputTags["e_$fn"][':html'] = preg_replace(
                "/value=\'".$new[$fn]."\'/",
                "value='".$new[$fn]."' selected='selected'",
                $InputTags["e_$fn"][':html'],
                1
            );
        }
    }

    $new['text'] = PPRE("/$KeepToken(EA\\d.*?)$KeepToken/", '$GLOBALS[\'KPV\'][$m[1]]', $new['text']);
}