From 2d34ba1218a8335311f3923080c78cbe2338ec96 Mon Sep 17 00:00:00 2001 From: "Guillaume (ioguix) de Rorthais" Date: Thu, 23 Sep 2010 00:28:54 +0200 Subject: [PATCH] Fix auto-complete when editing a row. Reported by Dmitry Koterov when asked on github: http://github.com/DmitryKoterov/phppgadmin/commit/89460c1557816b40311e8a344bf94c8a0f505542#commitcomment-148877 --- classes/Misc.php | 81 ++++++++++++++++++++++++++++++ classes/database/Postgres.php | 21 ++++---- display.php | 74 +++++++++++---------------- tables.php | 94 ++++++----------------------------- 4 files changed, 134 insertions(+), 136 deletions(-) diff --git a/classes/Misc.php b/classes/Misc.php index 2dc28b2a..b92e1dbf 100644 --- a/classes/Misc.php +++ b/classes/Misc.php @@ -2153,5 +2153,86 @@ echo "\n"; } + + function getAutocompleteFKProperties($table) { + global $data; + + $fksprops = array( + 'byconstr' => array(), + 'byfield' => array(), + 'code' => '' + ); + + $constrs = $data->getConstraintsWithFields($table); + + if (!$constrs->EOF) { + $conrelid = $constrs->fields['conrelid']; + while(!$constrs->EOF) { + if ($constrs->fields['contype'] == 'f') { + if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) { + $fksprops['byconstr'][$constrs->fields['conid']] = array ( + 'confrelid' => $constrs->fields['confrelid'], + 'f_table' => $constrs->fields['f_table'], + 'f_schema' => $constrs->fields['f_schema'], + 'pattnums' => array(), + 'pattnames' => array(), + 'fattnames' => array() + ); + } + + $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][] = $constrs->fields['p_attnum']; + $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field']; + $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field']; + + if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) + $fksprops['byfield'][$constrs->fields['p_attnum']] = array(); + $fksprops['byfield'][$constrs->fields['p_attnum']] = $constrs->fields['conid']; + } + $constrs->moveNext(); + } + + $fksprops['code'] = "\n"; + + $fksprops['code'] .= '
'; + $fksprops['code'] .= '
'; + $fksprops['code'] .= ''; + $fksprops['code'] .= ''; + } + + else /* we have no foreign keys on this table */ + return false; + + return $fksprops; + } } ?> diff --git a/classes/database/Postgres.php b/classes/database/Postgres.php index a0c566f1..0178e327 100755 --- a/classes/database/Postgres.php +++ b/classes/database/Postgres.php @@ -249,16 +249,15 @@ class Postgres extends ADODB_base { * @param $name The name to give the field * @param $value The value of the field. Note this could be 'numeric(7,2)' sort of thing... * @param $type The database type of the field - * @param $actions An array of javascript action name to the code to execute on that action - * @param $extra Some extra attributes to add. + * @param $extras An array of attributes name as key and attributes' values as value */ - function printField($name, $value, $type, $actions = array(), $extra='') { + function printField($name, $value, $type, $extras = array()) { global $lang; // Determine actions string - $action_str = ''; - foreach ($actions as $k => $v) { - $action_str .= " {$k}=\"" . htmlspecialchars($v) . "\""; + $extra_str = ''; + foreach ($extras as $k => $v) { + $extra_str .= " {$k}=\"" . htmlspecialchars($v) . "\""; } switch (substr($type,0,9)) { @@ -270,14 +269,14 @@ class Postgres extends ADODB_base { // If value is null, 't' or 'f'... if ($value === null || $value == 't' || $value == 'f') { - echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; } else { - echo "\n"; + echo "\n"; } break; case 'bytea': @@ -290,7 +289,7 @@ class Postgres extends ADODB_base { $n = substr_count($value, "\n"); $n = $n < 5 ? 5 : $n; $n = $n > 20 ? 20 : $n; - echo "\n"; break; @@ -299,12 +298,12 @@ class Postgres extends ADODB_base { $n = substr_count($value, "\n"); $n = $n < 5 ? 5 : $n; $n = $n > 20 ? 20 : $n; - echo "\n"; break; default: - echo "\n"; + echo "\n"; break; } } diff --git a/display.php b/display.php index 81d5aae5..2b519178 100644 --- a/display.php +++ b/display.php @@ -39,28 +39,16 @@ $misc->printTitle($lang['streditrow']); $misc->printMsg($msg); - $bAllowAC = ($conf['autocomplete'] != 'disable') ? TRUE : FALSE; - if($bAllowAC) { - $constraints = $data->getConstraints($_REQUEST['table']); - $arrayLocals = array(); - $arrayRefs = array(); - $nC = 0; - while(!$constraints->EOF) { - // The following RE will match a FK constrain with a single (quoted or not) referencing column. At the moment we don't support multicolumn FKs - preg_match('/^FOREIGN KEY \(("[^"]*"|[^\s",]*)\) REFERENCES (.*)\((.*)\)/i', $constraints->fields['consrc'], $matches); - if(!empty($matches)) { - // Strip possible quotes and save - $arrayLocals[$nC] = preg_replace('/"(.*)"/', '$1', $matches[1]); - $arrayRefs[$nC] = array(preg_replace('/"(.*)"/', '$1', $matches[2]), preg_replace('/"(.*)"/', '$1', $matches[3])); - $nC++; - } - $constraints->moveNext(); - } - } - $attrs = $data->getTableAttributes($_REQUEST['table']); $rs = $data->browseRow($_REQUEST['table'], $key); - + + if (($conf['autocomplete'] != 'disable')) { + $fksprops = $misc->getAutocompleteFKProperties($_REQUEST['table']); + if ($fksprops !== false) + echo $fksprops['code']; + } + else $fksprops = false; + echo "
\n"; $elements = 0; $error = true; @@ -74,18 +62,7 @@ $i = 0; while (!$attrs->EOF) { - $szValueName = "values[{$attrs->fields['attname']}]"; - $szEvents = ''; - $szDivPH = ''; - if($bAllowAC) { - $idxFound = array_search($attrs->fields['attname'], $arrayLocals); - // In PHP < 4.2.0 array_search returns NULL on failure - if ($idxFound !== NULL && $idxFound !== FALSE) { - $szEvent = "makeAC('{$szValueName}',{$i},'{$arrayRefs[$idxFound][0]}','{$arrayRefs[$idxFound][1]}','{$_REQUEST['server']}','{$_REQUEST['database']}');"; - $szEvents = "onfocus=\"{$szEvent}\" onblur=\"hideAC();document.getElementById('ac_form').onsubmit=function(){return true;};\" onchange=\"{$szEvent}\" id=\"{$szValueName}\" onkeyup=\"{$szEvent}\" autocomplete=\"off\" class='ac_field'"; - $szDivPH = "
"; - } - } + $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); $id = (($i % 2) == 0 ? '1' : '2'); @@ -120,18 +97,25 @@ else echo " "; - echo ""; + echo "fields['attnum']}\" style=\"white-space:nowrap;\">"; + + $extras = array(); + // If the column allows nulls, then we put a JavaScript action on the data field to unset the // NULL checkbox as soon as anything is entered in the field. We use the $elements variable to // keep track of which element offset we're up to. We can't refer to the null checkbox by name // as it contains '[' and ']' characters. if (!$attrs->fields['attnotnull']) { - echo $data->printField($szValueName, $rs->fields[$attrs->fields['attname']], $attrs->fields['type'], - array('onChange' => 'elements[' . ($elements - 1) . '].checked = false;'),$szEvents) . $szDivPH; + $extras['onChange'] = 'elements[' . ($elements - 1) . '].checked = false;'; } - else { - echo $data->printField($szValueName, $rs->fields[$attrs->fields['attname']], $attrs->fields['type'],array(),$szEvents) . $szDivPH; + + if (($fksprops !== false) && isset($fksprops['byfield'][$attrs->fields['attnum']])) { + $extras['id'] = "attr_{$attrs->fields['attnum']}"; + $extras['autocomplete'] = 'off'; } + + echo $data->printField("values[{$attrs->fields['attnum']}]", $rs->fields[$attrs->fields['attname']], $attrs->fields['type'], $extras); + echo ""; $elements++; echo "\n"; @@ -139,10 +123,7 @@ $attrs->moveNext(); } echo "\n"; - if($bAllowAC) { - echo ''; - echo "
"; - } + $error = false; } elseif ($rs->recordCount() != 1) { @@ -174,13 +155,16 @@ echo "

"; if (!$error) echo "\n"; echo "\n"; - if($bAllowAC) { - $szChecked = $conf['autocomplete'] != 'default off' ? 'checked="checked"' : ''; - echo "\n"; + + if($fksprops !== false) { + if ($conf['autocomplete'] != 'default off') + echo "\n"; + else + echo "\n"; } + echo "

\n"; echo "
\n"; - echo ""; } else { if (!isset($_POST['values'])) $_POST['values'] = array(); diff --git a/tables.php b/tables.php index 7bbb3d9f..46945719 100644 --- a/tables.php +++ b/tables.php @@ -455,84 +455,19 @@ global $data, $misc, $conf; global $lang; - $auto_complete = ($conf['autocomplete'] != 'disable'); - if ($confirm) { $misc->printTrail('table'); $misc->printTitle($lang['strinsertrow'], 'pg.sql.insert'); $misc->printMsg($msg); $attrs = $data->getTableAttributes($_REQUEST['table']); - $fksprops = array( - 'byconstr' => array(), - 'byfield' => array(), - ); - if($auto_complete) { - $constrs = $data->getConstraintsWithFields($_REQUEST['table']); - - if (!$constrs->EOF) { - $conrelid = $constrs->fields['conrelid']; - while(!$constrs->EOF) { - if ($constrs->fields['contype'] == 'f') { - if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) { - $fksprops['byconstr'][$constrs->fields['conid']] = array ( - 'confrelid' => $constrs->fields['confrelid'], - 'f_table' => $constrs->fields['f_table'], - 'f_schema' => $constrs->fields['f_schema'], - 'pattnums' => array(), - 'pattnames' => array(), - 'fattnames' => array() - ); - } - - $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][] = $constrs->fields['p_attnum']; - $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field']; - $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field']; - - if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) - $fksprops['byfield'][$constrs->fields['p_attnum']] = array(); - $fksprops['byfield'][$constrs->fields['p_attnum']] = $constrs->fields['conid']; - } - $constrs->moveNext(); - } - - echo "\n"; - echo '
'; - echo '
'; - } - else $auto_complete = false; + if (($conf['autocomplete'] != 'disable')) { + $fksprops = $misc->getAutocompleteFKProperties($_REQUEST['table']); + if ($fksprops !== false) + echo $fksprops['code']; } + else $fksprops = false; echo "
\n"; if ($attrs->recordCount() > 0) { @@ -578,13 +513,16 @@ echo " "; } echo "fields['attnum']}\" style=\"white-space:nowrap;\">"; - if ($auto_complete && isset($fksprops['byfield'][$attrs->fields['attnum']])) { - echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], - 'fktype'/*force FK*/,array(), "id=\"attr_{$attrs->fields['attnum']}\" autocomplete=\"off\""); + if (($fksprops !== false) && isset($fksprops['byfield'][$attrs->fields['attnum']])) { + echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], 'fktype'/*force FK*/, + array( + 'id' => "attr_{$attrs->fields['attnum']}", + 'autocomplete' => 'off' + ) + ); } else { - echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], - $attrs->fields['type'],array()); + echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], $attrs->fields['type']); } echo "\n"; echo "\n"; @@ -592,10 +530,6 @@ $attrs->moveNext(); } echo "\n"; - if($auto_complete) { - echo ""; - echo ""; - } if (!isset($_SESSION['counter'])) { $_SESSION['counter'] = 0; } @@ -607,7 +541,7 @@ echo "\n"; echo "\n"; - if($auto_complete) { + if($fksprops !== false) { if ($conf['autocomplete'] != 'default off') echo "\n"; else -- 2.39.5