Re: cookbooks SelectQuery and UpdateForm
Piotr Dybczyński <[email protected]>
| Newsgroups | gmane.comp.web.wiki.pmwiki.user |
|---|---|
| Message-ID | <[email protected]> |
Hi,
> If indeed you have evidence of any problems on PHP 8.2 with PmWiki core
> itself (as opposed to local customisations), I'd be *very* interested in
> tracking them and fixing them ASAP.
So far I think that now problems are caused by the updateform and recipe.
In 2017 it was rewritten by Ben Stallings on my request (PHP 7 problems)
and then I had to modify it in some details for my personal use (see the
attachment).
If I switch off the inclusion of this recipe (selectquery can remain)
pages are blank.
I do not understand why they are also blank for action=edit while the
other pages are normally editable.
Is this the case that PmWiki core includes recipies mentioned in the
page even when the page only edited?
The example of page in question is as follows:
---------------------------------------------------------------------------------------
(:selectquery
columns="s32_directory_code,s32_directory_name,s32_directory_DR2,s32_directory_sing,s32_directory_memb,s32_directory_komentarz"
tables="s32_directory" display=custom match=s32_directory_code
against=kkk type=like nodata=" ":)
(:input form:)
!!!Choose perturber:
(:update select name=kkk value=s32_directory_code from=s32_directory
method=get size=10:)
(:input submit value="Show data from the catalogue":)
(:input end:)
------------------------------------------------------------------------------------------------------------
This page normally shows a list of objects to be choosen. I can edit it
after removing "updateform" recipe.
All the best,
Piotr
--
/************************************************************************
dr Piotr A. Dybczyński
homepage: https://www.dybczynski.pl/Piotr e-mail: [email protected]
******************************************************************PAD***/
_______________________________________________
pmwiki-users mailing list
[email protected]
http://www.pmichaud.com/mailman/listinfo/pmwiki-users
updateform7c.php
(application/x-php, 19.8 KB)
<?php if (!defined('PmWiki')) exit();
/**
* Copyright 2006-05-14, 2007-02-08 Ben Stallings ([email protected])
* based on forms.php, Copyright 2005 Patrick R. Michaud ([email protected])
* updated to PHP7 by Peter Kay ([email protected]) and Ben Stallings
* This file is designed to work with PmWiki; 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. See pmwiki.php for full details.
* Database constants (DB_*) must be defined either here or in config.php.
*/
# Special handling for user info
# set this to the database field that corresponds to a user's wiki username, if any.
# SDV($UpdateUserID,'email');
# If you want to use the open-source dFilter.js script for input masks,
# download it from http://www.javascriptsource.com/forms/dfilter.html and
# uncomment the following line; otherwise comment (#) it out:
# $HTMLHeaderFmt['dFilter'] = '<script type="text/javascript" src="/dFilter.js"></script>';
# $UpdateAttrs are the attributes we allow in output tags
SDV($UpdateAttrs, array('name', 'value', 'id', 'class', 'rows', 'cols',
'size', 'maxlength', 'action', 'method', 'accesskey',
'checked', 'disabled', 'readonly', 'enctype', 'tabindex', 'onKeyDown'));
# Set up formatting for text, submit, hidden, radio, etc. types
foreach(array('text', 'submit', 'hidden', 'password', 'radio', 'checkbox',
'reset', 'file') as $t) {
SDV($UpdateTags[$t][':html'], "<input type='$t' \$UpdateFormArgs />");
}
# (:update form:)
SDVA($UpdateTags['form'], array(
':args' => array('action', 'method', 'table', 'fields', 'required', 'where', 'tabindex'),
':html' => "<form \$UpdateFormArgs>",
'action' => ($EnablePathInfo ? $ScriptUrl.'/'.$pagename : $ScriptUrl.'?n='.$pagename),
'method' => 'post',
));
# (:update end:)
SDV($UpdateTags['end'][':html'], '</form>');
# (:update textarea:)
SDVA($UpdateTags['textarea'], array(
':html' => "<textarea \$UpdateFormArgs>\$UpdateTextarea</textarea>"));
# (:update select:)
SDVA($UpdateTags['select'], array(
':args' => array('name', 'size', 'multiple', 'value', 'label', 'from', 'where', 'order', 'tabindex'),
':html' => "<select \$UpdateFormArgs>\n\$UpdateSelectOptions</select>\n"));
Markup('update', 'fulltext', //fulltext translations to be performed on the full text
'/\\(:update\\s+(\\w+)(.*?):\\)/i',
"UpdateMarkup");
# define username depending on whether we're using UserAuth or AuthUser
$UpdateUsername = (defined('USER_AUTH_VERSION') ? $_SESSION['username'] : $_SESSION['authid'][0]);
//if (!is_array($SQdata)) $SQdata = array(); //PAD - deklarujemy tablicę SQdata
$SQdata = array(); //PAD - deklarujemy tablicę SQdata
SDVA($SQdata,$_REQUEST);
// $_REQUEST is an associative array that by default contains the contents of $_GET, $_POST and $_COOKIE
// This is a 'superglobal', or automatic global, variable. This simply means that it is available in all
// scopes throughout a script. There is no need to do global $variable; to access it within functions or methods.
//The variables in $_REQUEST are provided to the script via the GET, POST, and COOKIE input mechanisms
// and therefore could be modified by the remote user and cannot be trusted.
function UpdateMarkup($m)
{
global $UpdateTags, $UpdateAttrs, $InputValues, $FmtV, $UpdateFields,
$UpdateUserID, $UpdateUsername, $Author, $UpdateDependencies, $UpdateTabIndex, $SQdata;
$pagename=$GLOBALS['MarkupToHTML']['pagename'];
$type=$m[1];
$args=$m[2];
//this preprocessing is the same as in the InputMarkup function; only the names have been changed
if (!@$UpdateTags[$type]) return "(:update $type $args:)";
$opt = array_merge($UpdateTags[$type], ParseArgs($args));
$args = @$opt[':args'];
// error control operator: the at sign (@). When prepended to an expression in PHP,
// any error messages that might be generated by that expression will be ignored.
if (!$args) $args = array('name', 'value');
while (count(@$opt['']) > 0 && count($args) > 0)
$opt[array_shift($args)] = array_shift($opt['']);
if ($type == 'form')
{
// PAD:
//$out.="Tablica opt ".print_r($opt,true);
// Connect to Database using PHP Database Objects (PDO)
$dblink = new PDO('mysql:host='. DB_SERVER. ';dbname='. DB_NAME, DB_USER, DB_PASS);
// PAD:
//$out.="Tablica POST ".print_r($_POST,true);
if (count($_POST)>0) // jeśli jest cos w _POST
{
// Check for required fields
$present = 0;
$required = explode(',', $opt['required']);
foreach ($required as $req)
{
if (($req > '') and ($_POST[$req] > '')) $present++;
}
// PAD:
//$out.="Tablica required ".print_r($required,true)."Count(required): ".count($required);
if ($present == count($required)) // process form, czyli mamy wszystkie wymagane pola zapełnione
{
$success = 0;
$timestamp = date('Y-m-d H:i:s');
// Check for a 'where' parameter
foreach (explode(',',$opt['where']) as $req)
{
if (!$_POST[$req]) $present--; // zmniejszamy jeśli brakuje wartości dla WHERE
}
if ($present == count($required)) //an existing entry has been specified.
{
unset ($where);
unset ($dependencies);
$params = array();
foreach (explode(',',$opt['where']) as $wherefield)
{
$where[] = "$wherefield = :wherefield";
$params[':wherefield'] = $_POST[$wherefield];
//prepare to delete dependent entries, if necessary
foreach (explode(',',$UpdateDependencies[$opt['table'].".$wherefield"]) as $dep)
{
list($deptable,$depfield) = explode('.',$dep);
$dependencies[] = "DELETE FROM $deptable WHERE $depfield = :wherefield";
}
}
if ($_POST[$opt['delete']]) //delete an existing entry
{
$query = "DELETE FROM ".$opt['table']." WHERE ".implode(' AND ',$where);
//$out.= "<p>$query</p>";
try {
$dblink->prepare($query)->execute($params);
foreach ($dependencies as $dep) $dblink->prepare($dep)->execute($params);
$success = 1;
$out.= "<h3 style='color:red'>Successfully deleted this record and its dependencies.</h3>";
} catch (PDOException $e) {
$out.= "<h3 style='color:red'>Unable to delete this record.</h3><p>$query</p><p>". $e->getMessage() ."</p>";
}
}
else
{ // update an existing entry
$query = "UPDATE ".$opt['table']." SET ";
$params = array();
//PAD:
foreach (explode(',',$opt['where']) as $wherefield)
{
$where[] = "$wherefield = :wherefield";
$params[':wherefield'] = $_POST[$wherefield];
}
foreach (explode(',',$opt['fields']) as $field)
{
if ((strpos(",".$opt['null'].",",",".$field.",") !== false) AND ($_POST[$field]==''))
{
$query .= "`$field` = NULL, ";
}
else
{
$query .= "`$field` = :$field, ";
$params[":$field"] = $_POST[$field];
}
}
if ($opt['timestamp']>'') $query .= $opt['timestamp']." = '$timestamp'";
$query = rtrim($query, ', ')." WHERE ".implode(' AND ',$where);
//$out.= "<p>[@$query</p>@]".print_r($params,1);
try {
$dblink->prepare($query)->execute($params);
$success = 1;
$out.= "<h3 style='color:green'>Successfully made your changes.</h3>";
} catch (PDOException $e) {
$out.= "<h3 style='color:red'>Unable to make your changes.</h3><p>$query</p><p>"
. $e->getMessage()."</p>";
}
} // end updating
} // end of "if ($present==count($required))"
else
{ // insert new entry
$queryA = "INSERT INTO ".$opt['table']." (";
$queryB = ") VALUES (";
$params = array();
foreach (explode(',',$opt['fields']) as $field)
{
//is the field listed as having a default? If not, include it.
if ((strpos(",".$opt['default'].",",",".$field.",") === false) OR ($_POST[$field]))
{
$queryA .= "`$field`,";
//if this is the UserID field and no value is given, use the UserID
if (in_array($UpdateUserID,explode(',',$opt['where'])) and ($field==$UpdateUserID) and (!$_POST[$field]))
{
$params[':UpdateUsername'] = $UpdateUsername;
$queryB .= ':UpdateUsername,';
}
else
{
$params[":$field"] = $_POST[$field];
$queryB .= ":$field,";
}
}
}
if ($opt['timestamp']>'')
{
$queryA .= $opt['timestamp'];
$queryB .= "'$timestamp'";
}
$query = rtrim($queryA, ',').rtrim($queryB, ',').")";
try {
$dblink->prepare($query)->execute($params);
$success=1;
$out.= "<h3 style='color:red'>Successfully added this information to the database.</h3>";
$wherevalue = $dblink->lastInsertId();
} catch (PDOException $e) {
$out.= "<h3 style='color:red'>Unable to add this information to the database.</h3><p>$query</p><p>"
. $e->getMessage()."</p>";
}
}
}
else
{ // missing some required values in POST
$out .= "<h3>Please fill in all <span style='color:maroon'>required fields</span> marked <span style='color:red'>*</span>.</h3>\n";
$UpdateFields = array();
$UpdateFields += $_POST;
}
} //endif $_POST
if (($success == 1) and (isset($opt['redirect'])))
{ //redirect to specified page
Redirect($opt['redirect']);
}
elseif (count($_POST)) // PAD - dodałem by strona nie gadała z bazą bezpośrenio po uruchomieniu (np. po edycji). Było "else".
{
// Get existing info from database, if any
unset ($where);
$params = array();
foreach (explode(',',$opt['where']) as $wherefield)
{
if ($wherefield == $UpdateUserID)
{
// It's not "any kind of query," Sark. It's a *User* query.
$where[] = "$UpdateUserID = :UpdateUsername";
$params[":UpdateUsername"] = $UpdateUsername;
}
else
{
$where[] = "$wherefield = :wherevalue";
$params[':wherevalue'] = ($_REQUEST[$wherefield] ? $_REQUEST[$wherefield] : $wherevalue);
SDV($SQdata[$wherefield],($_REQUEST[$wherefield] ? $_REQUEST[$wherefield] : $wherevalue));
}
}
if ((isset($opt['table'])) and (isset($opt['fields'])) and (isset($where)))
{
$query = "SELECT " . $opt['fields'] . " FROM " . $opt['table'] . " WHERE " . implode(" AND ",$where);
//$out.="$query" ."<br />". print_r($params,1);
$sth = $dblink->prepare($query);
if (is_object($sth))
{
$sth->execute($params);
$UpdateFields = $sth->fetch(PDO::FETCH_ASSOC);
// PAD:
//$out.="Tablica UpdateFields ".print_r($_UpdateFields,true);
//$out.="Tablica _POST ".print_r($_POST,true);
SDVA($UpdateFields,$_POST);
if (isset($UpdateFields) ) SDVA($SQdata,$UpdateFields);
}
}
}
$dblink = NULL;
//PAD:
//$sth = NULL;
//end of $type = 'form'
} // end of "if ($type == 'form')"
elseif (($type=='select') and (isset($opt['from'])))
{ //a little bit of magic to create drop-down menus from a query!
//if value and/or label are not provided, fill them in with what we do know
SDV($opt['value'],$opt['name']);
SDV($opt['label'],$opt['value']);
// Connect to Database
$dblink = new PDO('mysql:host='. DB_SERVER .';dbname='. DB_NAME, DB_USER, DB_PASS);
$selectq = "SELECT ". $opt['value'] .", ". $opt['label'] ." FROM ". $opt['from']
." WHERE ". ($opt['where'] ? html_entity_decode($opt['where']) : 1)
. ($opt['order'] ? " ORDER BY ".$opt['order'] : "");
// . "--PAD2";
$selectd = $dblink->query($selectq);
unset($FmtV['$UpdateSelectOptions']);
if (isset($opt['null'])) $FmtV['$UpdateSelectOptions'] = "<option value='' "
. ($UpdateFields[$opt['name']]=='' ? "selected='selected' " : "")
. ">" . $opt['null'] . "</option>\n";
foreach ($selectd as $option)
{
$FmtV['$UpdateSelectOptions'] .= "<option value='".$option[0]."' "
. ((($option[0]==$UpdateFields[$opt['name']]) or ($option[0]==$SQdata[$opt['name']])) ? "selected='selected' " : "")
. ">" . $option[1] . "</option>\n";
}
//don't display database info in HTML source
unset($opt['value']);
$dblink = NULL;
// PAD:
$selectd = NULL;
} // end if $type == select
// if given a parameter with no value, set the value to the name of the parameter
// for example, "checked" should become "checked='checked'" to be valid HTML
foreach ((array)@$opt[''] as $a)
if (!isset($opt[$a])) $opt[$a] = $a;
//insert $SQdata info into field, if value given is a parameter name in `backquotes`
if (strrpos('`',$opt['value'])!==false)
{
$opt['value'] = $SQdata[str_replace("`","",$opt['value'])];
}
if (($type=='text') or ($type=='hidden') or ($type=='password'))
{
// insert database info into field
if (isset($UpdateFields[$opt['name']])) $opt['value'] = $UpdateFields[$opt['name']];
// insert $_GET info into field, if any
if (isset($_GET[$opt['name']])) $opt['value'] = $_GET[$opt['name']];
}
// another bit of magic to allow values in textareas
if ($type=='textarea') $FmtV['$UpdateTextarea'] = $UpdateFields[$opt['name']]? $UpdateFields[$opt['name']]: "";
// auto-input user ID into text or hidden fields when no other value given
if ((($type=='text') or ($type=='hidden')) and ($opt['name']==$UpdateUserID))
SDV($opt['value'],$UpdateUsername);
//content masking with optional Javascript
unset($opt['onKeyDown']);
if ($opt['mask']>'')
$opt['onKeyDown']='javascript:return dFilter (event.keyCode, this, "'.$opt['mask'].'");';
//automatic tabindex
if ($opt['tabindex']>0)
{
$UpdateTabIndex = $opt['tabindex']+1;
}
elseif ($opt['tabindex']===0)
{
$UpdateTabIndex = 0;
}
elseif (($UpdateTabIndex > 0) and ($type!='form') and ($type != 'end') and ($type != 'hidden'))
{
$opt['tabindex'] = $UpdateTabIndex++;
}
//not sure what this little loophole is for, but it's in forms.php, so I copied it
if (!isset($opt['value']) && isset($InputValues[@$opt['name']]))
$opt['value'] = $InputValues[$opt['name']];
//put quotes around values for HTML compliance
$attr = array();
foreach ($UpdateAttrs as $a)
{
if (!isset($opt[$a])) continue;
$attr[] = "$a='".str_replace("'", ''', $opt[$a])."'";
}
// PAD:
//$out.="Tablica UpdateFields ".print_r($UpdateFields,true)."opt value" . $opt['value'];
//set radio and checkboxes to match database info
if ((($type=='radio') or ($type=='checkbox')) and ($opt['value'] == $UpdateFields[$opt['name']])) $attr[] = "checked='checked'";
//exit code copied bodily from forms.php
$FmtV['$UpdateFormArgs'] = implode(' ', $attr);
$out .= FmtPageName($opt[':html'], $pagename);
return preg_replace_callback('/<(\\w+\\s)(.*)$/s',function ($m) { return "<{$m[1]}".Keep(($m[2]));}, $out);
} //end of "function UpdateMarkup($m)"