Fix multi bug in auto-complete value on insert/update
authorGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Tue, 28 Sep 2010 00:02:04 +0000 (02:02 +0200)
committerGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Tue, 28 Sep 2010 00:02:04 +0000 (02:02 +0200)
* explicitly not support multi FK constr, only deal
  with the first one. marked as FIXME
* some bad escaped vars were failing the auto-complete
  on very weird table/field names
* some cleanup

ajax-ac-insert.php
classes/Misc.php
js/ac_insert_row.js

index ee338688bfe35c68b7075a5cef125df4442953d4..49144a97bd54da6537245205fb8572dcfdf37db8 100644 (file)
@@ -7,13 +7,25 @@
                $_POST['offset'] = 0;
                $offset = " OFFSET 0";
        }
-       $keyspos = array_combine($_POST['fkeynames'], $_POST['keys']);
-       $keysnames = array_combine($_POST['fkeynames'], $_POST['keynames']);
+
+       $keynames = array();
+       foreach ($_POST['fkeynames'] as $k => $v) {
+               $fkeynames[$k] = html_entity_decode($v, ENT_QUOTES);
+       }
+
+       $keyspos = array_combine($fkeynames, $_POST['keys']);
+
+       $f_schema = html_entity_decode($_POST['f_schema'], ENT_QUOTES);
+       $data->fieldClean($f_schema);
+       $f_table = html_entity_decode($_POST['f_table'], ENT_QUOTES);
+       $data->fieldClean($f_table);
+       $f_attname = $fkeynames[$_POST['fattpos'][0]];
+       $data->fieldClean($f_attname);
 
        $q = "SELECT *
-               FROM \"{$_POST['f_schema']}\".\"{$_POST['f_table']}\"
-               WHERE \"{$_POST['fkeynames'][$_POST['fattpos']]}\"::text LIKE '{$_POST['fvalue']}%'
-               ORDER BY \"{$_POST['fkeynames'][$_POST['fattpos']]}\" LIMIT 12 {$offset};";
+               FROM \"{$f_schema}\".\"{$f_table}\"
+               WHERE \"{$f_attname}\"::text LIKE '{$_POST['fvalue']}%'
+               ORDER BY \"{$f_attname}\" LIMIT 12 {$offset};";
 
        $res = $data->selectSet($q);
 
@@ -23,7 +35,7 @@
                foreach (array_keys($res->fields) as $h) {
                        echo '<th>';
 
-                       if (in_array($h,$_POST['fkeynames']))
+                       if (in_array($h, $fkeynames))
                                echo '<img src="'. $misc->icon('ForeignKey') .'" alt="[referenced key]" />';
 
                        echo htmlentities($h), '</th>';
@@ -34,7 +46,7 @@
                while ((!$res->EOF) && ($i < 11)) {
                        echo "<tr class=\"acline\">";
                        foreach ($res->fields as $n => $v) {
-                               if (in_array($n,$_POST['fkeynames']))
+                               if (in_array($n, $fkeynames))
                                        echo "<td><a href=\"javascript:void(0)\" class=\"fkval\" name=\"{$keyspos[$n]}\">",htmlentities($v), "</a></td>";
                                else
                                        echo "<td><a href=\"javascript:void(0)\">", htmlentities($v), "</a></td>";
@@ -66,7 +78,7 @@
                echo $js ."</script>";
        }
        else {
-               printf("<p>{$lang['strnofkref']}</p>", "\"{$_POST['f_schema']}\".\"{$_POST['f_table']}\".\"{$_POST['fkeynames'][$_POST['fattpos']]}\"");
+               printf("<p>{$lang['strnofkref']}</p>", "\"{$_POST['f_schema']}\".\"{$_POST['f_table']}\".\"{$fkeynames[$_POST['fattpos']]}\"");
 
                if ($_POST['offset'])
                        echo "<a href=\"javascript:void(0)\" class=\"fkprev\">Prev &lt;&lt;</a>";
index b92e1dbf1213de3c9e981fbd4c8d2b16167fafc1..b9bf917fc14c760c249aaff3e459fb60e816d05b 100644 (file)
                        echo "</td></tr></table>\n";
                }
 
+               /**
+                * returns an array representing FKs definition for a table, sorted by fields
+                * or by constraint.
+                * @param $table The table to retrieve FK contraints from
+                * @returns the array of FK definition:
+                *   array(
+                *     'byconstr' => array(
+                *       constrain id => array(
+                *         confrelid => foreign relation oid
+                *         f_schema => foreign schema name
+                *         f_table => foreign table name
+                *         pattnums => array of parent's fields nums
+                *         pattnames => array of parent's fields names
+                *         fattnames => array of foreign attributes names
+                *       )
+                *     ),
+                *     'byfield' => array(
+                *       attribute num => array (constraint id, ...)
+                *     ),
+                *     'code' => HTML/js code to include in the page for auto-completion
+                *   )
+                **/
                function getAutocompleteFKProperties($table) {
                        global $data;
 
 
                                                if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']]))
                                                        $fksprops['byfield'][$constrs->fields['p_attnum']] = array();
-                                               $fksprops['byfield'][$constrs->fields['p_attnum']] = $constrs->fields['conid'];
+                                               $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid'];
                                        }
                                        $constrs->moveNext();
                                }
                                foreach ($fksprops['byconstr'] as $conid => $props) {
                                        $fksprops['code'] .= "constrs.constr_{$conid} = {\n";
                                        $fksprops['code'] .= 'pattnums: ['. implode(',',$props['pattnums']) ."],\n";
-                                       $fksprops['code'] .= "f_table:\"". htmlentities($props['f_table']) ."\",\n";
-                                       $fksprops['code'] .= "f_schema:\"". htmlentities($props['f_schema']) ."\",\n";
+                                       $fksprops['code'] .= "f_table:'". addslashes(htmlentities($props['f_table'], ENT_QUOTES)) ."',\n";
+                                       $fksprops['code'] .= "f_schema:'". addslashes(htmlentities($props['f_schema'], ENT_QUOTES)) ."',\n";
                                        $_ = '';
                                        foreach ($props['pattnames'] as $n) {
                                                $_ .= ",'". htmlentities($n, ENT_QUOTES) ."'";
 
                                $fksprops['code'] .= "var attrs = {};\n";
                                foreach ($fksprops['byfield'] as $attnum => $cstrs ) {
-                                       $fksprops['code'] .= "attrs.attr_{$attnum} = {$fksprops['byfield'][$attnum]};\n";
+                                       $fksprops['code'] .= "attrs.attr_{$attnum} = [". implode(',', $fksprops['byfield'][$attnum]) ."];\n";
                                }
 
-                               $fksprops['code'] .= "var table='". htmlentities($_REQUEST['table']) ."';";
+                               $fksprops['code'] .= "var table='". addslashes(htmlentities($table, ENT_QUOTES)) ."';";
                                $fksprops['code'] .= "var server='". htmlentities($_REQUEST['server']) ."';";
-                               $fksprops['code'] .= "var database='". htmlentities($_REQUEST['database']) ."';";
+                               $fksprops['code'] .= "var database='". addslashes(htmlentities($_REQUEST['database'], ENT_QUOTES)) ."';";
                                $fksprops['code'] .= "</script>\n";
 
                                $fksprops['code'] .= '<div id="fkbg"></div>';
index cd59e2c5f62f67c8f0c3b8bd820cc1ad4a8db9c3..5ca85efa3fa187a7ad3e8f4848918d5dd2b95bf2 100644 (file)
@@ -53,7 +53,8 @@ function selectVal(index) {
 function openlist(e) {
        var elt = jQuery(e);
        var attnum = elt.attr('id').match(/\d+/)[0];
-       var conid = attrs['attr_'+attnum];
+       /* FIXME we only support the first FK constraint of the field */
+       var conid = attrs['attr_'+attnum][0];
 
        var constr = constrs["constr_" + conid];