]> git.joonet.de Git - adminer.git/commitdiff
Select from foreign keys in Editor
authorjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 23 Jul 2009 14:42:38 +0000 (14:42 +0000)
committerjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 23 Jul 2009 14:42:38 +0000 (14:42 +0000)
git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@883 7c3ca157-0c34-0410-bff1-cbf682f78f5c

adminer/call.inc.php
adminer/edit.inc.php
adminer/include/adminer.inc.php
adminer/include/functions.inc.php
adminer/select.inc.php
changes.txt
editor/include/adminer.inc.php

index cc4666a75f2b7440c514913698af324e8c21792f..509f9f978544a758eadb82e7313581c48d0b7c9a 100644 (file)
@@ -57,7 +57,7 @@ if ($in) {
                if (strlen($value) && ($field["type"] == "enum" || $field["type"] == "set")) {
                        $value = intval($value);
                }
-               input($key, $field, $value, (string) $_POST["function"][$name]); // param name can be empty
+               input($field, $value, (string) $_POST["function"][$name]); // param name can be empty
                echo "\n";
        }
        echo "</table>\n";
index 802f8f48bb0b6d6d01bb89347b69f011babffe7c..157d5c5c892093b7d6f38461e68cea4b1d6e4c9d 100644 (file)
@@ -79,7 +79,7 @@ if ($fields) {
                        : ($_POST["clone"] && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : $field["default"]))
                );
                $function = ($_POST["save"] ? (string) $_POST["function"][$name] : ($where && $field["on_update"] == "CURRENT_TIMESTAMP" ? "now" : ($value === false ? null : (isset($value) ? '' : 'NULL'))));
-               input($name, $field, $value, $function);
+               input($field, $value, $function);
                if (isset($_GET["default"]) && $field["type"] == "timestamp") {
                        if (!isset($create) && !$_POST) {
                                //! disable sql_mode NO_FIELD_OPTIONS
index 25965c53c61f1af9e5aaccef763c24c02e582d69..d5814d44bf0da04d214d6402f9b120906480cd77 100644 (file)
@@ -90,9 +90,17 @@ function adminer_select_query($query) {
        return call_adminer('select_query', "<p><code class='jush-sql'>" . htmlspecialchars($query) . "</code> <a href='" . htmlspecialchars($SELF) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n", $query);
 }
 
-/** Descriptions of selected data
+/** Description of a row in a table
+* @param string
+* @return string SQL expression, empty string for no description
+*/
+function adminer_row_description($table) {
+       return call_adminer('row_description', "", $table);
+}
+
+/** Get descriptions of selected data
 * @param array all data to print
-* @param array foreign keys
+* @param array
 * @return array
 */
 function adminer_row_descriptions($rows, $foreign_keys) {
@@ -147,7 +155,16 @@ function adminer_edit_functions($field) {
        if ($field["null"] || isset($_GET["default"])) {
                array_unshift($return, "NULL");
        }
-       return call_adminer('edit_functions', $return, $field);
+       return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + $return, $field);
+}
+
+/** Get options to display edit field
+* @param string table name
+* @param array single field from fields()
+* @return array options for <select> or empty to display <input>
+*/
+function adminer_edit_input($table, $field) {
+       return call_adminer('edit_input', false, $table, $field);
 }
 
 /** Prints navigation after Adminer title
index ec2b46e2f2cc67a6418d5dba7822ff78ffa40614..72b1d661c1ffc418e90bd952bff832669d90c48d 100644 (file)
@@ -13,14 +13,14 @@ function bracket_escape($idf, $back = false) {
        return strtr($idf, ($back ? array_flip($trans) : $trans));
 }
 
-function optionlist($options, $selected = null) {
+function optionlist($options, $selected = null, $use_keys = false) {
        $return = "";
        foreach ($options as $k => $v) {
                if (is_array($v)) {
                        $return .= '<optgroup label="' . htmlspecialchars($k) . '">';
                }
                foreach ((is_array($v) ? $v : array($k => $v)) as $key => $val) {
-                       $return .= '<option' . (is_string($key) ? ' value="' . htmlspecialchars($key) . '"' : '') . ((is_string($key) ? $key : $val) === $selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val);
+                       $return .= '<option' . ($use_keys || is_string($key) ? ' value="' . htmlspecialchars($key) . '"' : '') . (($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val);
                }
                if (is_array($v)) {
                        $return .= '</optgroup>';
@@ -265,9 +265,19 @@ function hidden_fields($process, $ignore = array()) {
        }
 }
 
-function input($name, $field, $value, $function) {
+function column_foreign_keys($table) {
+       $return = array();
+       foreach (foreign_keys($table) as $foreign_key) {
+               foreach ($foreign_key["source"] as $val) {
+                       $return[$val][] = $foreign_key;
+               }
+       }
+       return $return;
+}
+
+function input($field, $value, $function) {
        global $types;
-       $name = htmlspecialchars(bracket_escape($name));
+       $name = htmlspecialchars(bracket_escape($field["field"]));
        echo "<td class='function'>";
        if ($field["type"] == "enum") {
                echo "&nbsp;<td>" . (isset($_GET["select"]) ? ' <label><input type="radio" name="fields[' . $name . ']" value="-1" checked="checked"><em>' . lang('original') . '</em></label>' : "");
@@ -284,11 +294,14 @@ function input($name, $field, $value, $function) {
                        echo ' <label><input type="radio" name="fields[' . $name . ']" value="' . (isset($_GET["default"]) ? (strlen($val) ? htmlspecialchars($val) : " ") : $i+1) . '"' . ($checked ? ' checked="checked"' : '') . '>' . htmlspecialchars($val) . '</label>';
                }
        } else {
-               $first = ($field["null"] || isset($_GET["default"])) + isset($_GET["select"]);
+               $functions = adminer_edit_functions($field);
+               $first = array_search("", $functions);
                $onchange = ($first ? ' onchange="var f = this.form[\'function[' . addcslashes($name, "\r\n'\\") . ']\']; if (' . $first . ' > f.selectedIndex) f.selectedIndex = ' . $first . ';"' : '');
-               $options = adminer_edit_functions($field);
-               echo (count($options) > 1 || isset($_GET["select"]) ? '<select name="function[' . $name . ']">' . (isset($_GET["select"]) ? '<option value="orig">' . lang('original') : '') . optionlist($options, $function) . '</select>' : "&nbsp;") . '<td>';
-               if ($field["type"] == "set") { //! 64 bits
+               echo (count($functions) > 1 ? '<select name="function[' . $name . ']">' . optionlist($functions, $function) . '</select>' : "&nbsp;") . '<td>';
+               $options = adminer_edit_input($_GET["edit"], $field); // usage in call is without a table
+               if (is_array($options)) {
+                       echo '<select name="fields[' . $name . ']"' . $onchange . '>' . optionlist($options, $value, true) . '</select>';
+               } elseif ($field["type"] == "set") { //! 64 bits
                        preg_match_all("~'((?:[^']+|'')*)'~", $field["length"], $matches);
                        foreach ($matches[1] as $i => $val) {
                                $val = stripcslashes(str_replace("''", "'", $val));
@@ -302,7 +315,7 @@ function input($name, $field, $value, $function) {
                } else {
                        // int(3) is only a display hint
                        $maxlength = (!ereg('int', $field["type"]) && preg_match('~^([0-9]+)(,([0-9]+))?$~', $field["length"], $match) ? ($match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
-                       echo '<input name="fields[' . $name . ']" value="' . htmlspecialchars($value) . '"' . ($maxlength ? " maxlength='$maxlength'" : "") . $onchange . '>';
+                       echo '<input name="fields[' . $name . ']" value="' . htmlspecialchars($value) . '"' . ($maxlength ? " maxlength='$maxlength'" : "") . "$onchange>";
                }
        }
 }
index 2f2987f0d98373727360319955d9d94e774703cf..745f7009d062e15fa9cb1a0378b8c5bc14a5e03d 100644 (file)
@@ -20,7 +20,7 @@ unset($text_length);
 foreach ($fields as $key => $field) {
        $name = adminer_field_name($fields, $key);
        if (isset($field["privileges"]["select"]) && strlen($name)) {
-               $columns[$key] = html_entity_decode(strip_tags($name)); //! numeric $key is problematic in optionlist()
+               $columns[$key] = html_entity_decode(strip_tags($name));
                if (ereg('text|blob', $field["type"])) {
                        $text_length = (isset($_GET["text_length"]) ? $_GET["text_length"] : "100");
                }
@@ -196,11 +196,11 @@ if (!$columns) {
        foreach ($select as $key => $val) {
                $val = $_GET["columns"][$key];
                echo "<div><select name='columns[$i][fun]'><option>" . optionlist($fun_group, $val["fun"]) . "</select>";
-               echo "<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"]) . "</select></div>\n";
+               echo "<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"], true) . "</select></div>\n";
                $i++;
        }
        echo "<div><select name='columns[$i][fun]' onchange='this.nextSibling.onchange();'><option>" . optionlist($fun_group) . "</select>";
-       echo "<select name='columns[$i][col]' onchange='select_add_row(this);'><option>" . optionlist($columns) . "</select></div>\n";
+       echo "<select name='columns[$i][col]' onchange='select_add_row(this);'><option>" . optionlist($columns, null, true) . "</select></div>\n";
        echo "</div></fieldset>\n";
        
        echo '<fieldset><legend><a href="#fieldset-search" onclick="return !toggle(\'fieldset-search\');">' . lang('Search') . "</a></legend><div id='fieldset-search'" . ($where ? "" : " class='hidden'") . ">\n";
@@ -215,13 +215,13 @@ if (!$columns) {
        $i = 0;
        foreach ((array) $_GET["where"] as $val) {
                if (strlen("$val[col]$val[val]") && in_array($val["op"], $operators)) {
-                       echo "<div><select name='where[$i][col]'><option value=''>" . lang('(anywhere)') . optionlist($columns, $val["col"]) . "</select>";
+                       echo "<div><select name='where[$i][col]'><option value=''>" . lang('(anywhere)') . optionlist($columns, $val["col"], true) . "</select>";
                        echo "<select name='where[$i][op]'>" . optionlist($operators, $val["op"]) . "</select>";
                        echo "<input name='where[$i][val]' value=\"" . htmlspecialchars($val["val"]) . "\"></div>\n";
                        $i++;
                }
        }
-       echo "<div><select name='where[$i][col]' onchange='select_add_row(this);'><option value=''>" . lang('(anywhere)') . optionlist($columns) . "</select>";
+       echo "<div><select name='where[$i][col]' onchange='select_add_row(this);'><option value=''>" . lang('(anywhere)') . optionlist($columns, null, true) . "</select>";
        echo "<select name='where[$i][op]'>" . optionlist($operators) . "</select>";
        echo "<input name='where[$i][val]'></div>\n";
        echo "</div></fieldset>\n";
@@ -230,12 +230,12 @@ if (!$columns) {
        $i = 0;
        foreach ((array) $_GET["order"] as $key => $val) {
                if (isset($columns[$val])) {
-                       echo "<div><select name='order[$i]'><option>" . optionlist($columns, $val) . "</select>";
+                       echo "<div><select name='order[$i]'><option>" . optionlist($columns, $val, true) . "</select>";
                        echo "<label><input type='checkbox' name='desc[$i]' value='1'" . (isset($_GET["desc"][$key]) ? " checked='checked'" : "") . ">" . lang('descending') . "</label></div>\n";
                        $i++;
                }
        }
-       echo "<div><select name='order[$i]' onchange='select_add_row(this);'><option>" . optionlist($columns) . "</select>";
+       echo "<div><select name='order[$i]' onchange='select_add_row(this);'><option>" . optionlist($columns, null, true) . "</select>";
        echo "<label><input type='checkbox' name='desc[$i]' value='1'>" . lang('descending') . "</label></div>\n";
        echo "</div></fieldset>\n";
        
@@ -277,12 +277,7 @@ if (!$columns) {
                                : count($rows)
                        );
                        
-                       $foreign_keys = array();
-                       foreach (foreign_keys($_GET["select"]) as $foreign_key) {
-                               foreach ($foreign_key["source"] as $val) {
-                                       $foreign_keys[$val][] = $foreign_key;
-                               }
-                       }
+                       $foreign_keys = column_foreign_keys($_GET["select"]);
                        $descriptions = adminer_row_descriptions($rows, $foreign_keys);
                        
                        $backward_keys = adminer_backward_keys($_GET["select"]);
index 13420ba6f5af6cf549714c2935670a4f6af9ce3a..cb7359809fc133553498353da47a165feb9fb363 100644 (file)
@@ -2,7 +2,7 @@ Adminer 2.0.0:
 Editor: User friendly data editor
 Customization: Adminer class
 E-mail sending
-Table relations
+Table relations (Editor)
 Create single column foreign key in table structure
 Separate types to groups in table creation
 Show type in field name title (thanks to Jakub Sochor)
index 88d61132c67b1ddf19cdcf77923440c325553001..3e33d18c27972945f374adc80a7c0ff8079b5b2d 100644 (file)
@@ -62,6 +62,18 @@ function adminer_select_query($query) {
        return call_adminer('select_query', "<!-- " . str_replace("--", "--><!--", $query) . " -->\n", $query);
 }
 
+function adminer_row_description($table) {
+       $return = "";
+       // first varchar column
+       foreach (fields($table) as $field) {
+               if ($field["type"] == "varchar") {
+                       $return = idf_escape($field["field"]);
+                       break;
+               }
+       }
+       return call_adminer('row_description', $return, $table);
+}
+
 function adminer_row_descriptions($rows, $foreign_keys) {
        global $dbh;
        $return = $rows;
@@ -69,31 +81,26 @@ function adminer_row_descriptions($rows, $foreign_keys) {
                foreach ((array) $foreign_keys[$key] as $foreign_key) {
                        if (count($foreign_key["source"]) == 1) {
                                $id = idf_escape($foreign_key["target"][0]);
-                               // find out the description column - first varchar
-                               $name = $id;
-                               foreach (fields($foreign_key["table"]) as $field) {
-                                       if ($field["type"] == "varchar") {
-                                               $name = idf_escape($field["field"]);
-                                               break;
+                               $name = adminer_row_description($foreign_key["table"]);
+                               if (strlen($name)) {
+                                       // find all used ids
+                                       $ids = array();
+                                       foreach ($rows as $row) {
+                                               $ids[$row[$key]] = $dbh->quote($row[$key]);
                                        }
+                                       // uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
+                                       $descriptions = array();
+                                       $result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
+                                       while ($row = $result->fetch_row()) {
+                                               $descriptions[$row[0]] = $row[1];
+                                       }
+                                       $result->free();
+                                       // use the descriptions
+                                       foreach ($rows as $n => $row) {
+                                               $return[$n][$key] = $descriptions[$row[$key]];
+                                       }
+                                       break;
                                }
-                               // find all used ids
-                               $ids = array();
-                               foreach ($rows as $row) {
-                                       $ids[$row[$key]] = $dbh->quote($row[$key]);
-                               }
-                               // uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
-                               $descriptions = array();
-                               $result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
-                               while ($row = $result->fetch_row()) {
-                                       $descriptions[$row[0]] = $row[1];
-                               }
-                               $result->free();
-                               // use the descriptions
-                               foreach ($rows as $n => $row) {
-                                       $return[$n][$key] = $descriptions[$row[$key]];
-                               }
-                               break;
                        }
                }
        }
@@ -108,11 +115,35 @@ function adminer_select_val($val, $link) {
 }
 
 function adminer_message_query($query) {
-       return call_adminer('message_query', "<!-- " . str_replace("--", "--><!--", $query) . " -->", $query);
+       return call_adminer('message_query', "<!--\n" . str_replace("--", "--><!--", $query) . "\n-->", $query);
 }
 
 function adminer_edit_functions($field) {
-       return call_adminer('edit_functions', array(""), $field);
+       return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + array(""), $field);
+}
+
+function adminer_edit_input($table, $field) {
+       global $dbh;
+       $return = null;
+       $foreign_keys = column_foreign_keys($table);
+       foreach ((array) $foreign_keys[$field["field"]] as $foreign_key) {
+               if (count($foreign_key["source"]) == 1) {
+                       $id = idf_escape($foreign_key["target"][0]);
+                       $name = adminer_row_description($foreign_key["table"]);
+                       if (strlen($name) && $dbh->result($dbh->query("SELECT COUNT(*) FROM " . idf_escape($foreign_key["table"]))) <= 1000) { // optionlist with more than 1000 options would be too big
+                               if ($field["null"]) {
+                                       $return[""] = "";
+                               }
+                               $result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " ORDER BY 2");
+                               while ($row = $result->fetch_row()) {
+                                       $return[$row[0]] = $row[1];
+                               }
+                               $result->free();
+                               break;
+                       }
+               }
+       }
+       return call_adminer('edit_input', $return, $table, $field);
 }
 
 function adminer_navigation($missing) {