* Copyright 2015 Ed Wildgoose * * 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 61: Changed strftime -> PSFT (Siegfried Seibert 2022-03-15) */ $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[] = "

$[Error parsing time:] $ct

"; } $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[] = "

$[$fn is required.]

"; $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' => "", 'name' => $fn, 'size' => '60', 'title' =>'Title', 'value' => str_replace('$','$',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('/