/**
  * Tests for PMA_generateRelationalDropdown() method.
  *
  * @return void
  * @test
  */
 public function testGenerateRelationalDropdown()
 {
     // test for start tag
     $this->assertStringStartsWith('<select', PMA_generateRelationalDropdown('name'));
     // test for end tag
     $this->assertStringEndsWith('</select>', PMA_generateRelationalDropdown('name'));
     // test for name
     $this->assertStringStartsWith('<select name="name"', PMA_generateRelationalDropdown('name'));
     // test for title
     $this->assertStringStartsWith('<select name="name" title="title"', PMA_generateRelationalDropdown('name', array(), false, 'title'));
     $values = array('value1', '<alue2', 'value3');
     // test for empty option
     $this->assertContains('<option value=""></option>', PMA_generateRelationalDropdown('name', $values));
     // test for options and escaping
     $this->assertContains('<option value="&lt;alue2">&lt;alue2</option>', PMA_generateRelationalDropdown('name', $values));
     // test for selected option
     $this->assertContains('<option value="value1" selected="selected">value1</option>', PMA_generateRelationalDropdown('name', $values, 'value1'));
     // test for selected value not found in values array and its escaping
     $this->assertContains('<option value="valu&lt;4" selected="selected">valu&lt;4' . '</option></select>', PMA_generateRelationalDropdown('name', $values, 'valu<4'));
 }
/**
 * Function to get html for the foreign key
 *
 * @param array  $save_row           save row
 * @param int    $i                  counter
 * @param array  $existrel_foreign   db, table, columns
 * @param string $myfield            my field
 * @param string $db                 current database
 * @param string $myfield_md5        my field md5
 * @param string $tbl_storage_engine table storage engine
 * @param array  $options_array      options array
 *
 * @return string
 */
function PMA_getHtmlForForeignKey($save_row, $i, $existrel_foreign, $myfield, $db, $myfield_md5, $tbl_storage_engine, $options_array)
{
    $html_output = '<td>';
    if (!empty($save_row[$i]['Key'])) {
        $foreign_db = false;
        $foreign_table = false;
        $foreign_column = false;
        // foreign database dropdown
        if (isset($existrel_foreign[$myfield])) {
            $foreign_db = $existrel_foreign[$myfield]['foreign_db'];
        } else {
            $foreign_db = $db;
        }
        $html_output .= '<span class="formelement clearfloat">';
        $html_output .= PMA_generateRelationalDropdown('destination_foreign_db[' . $myfield_md5 . ']', $GLOBALS['pma']->databases, $foreign_db, __('Database'));
        // end of foreign database dropdown
        // foreign table dropdown
        $tables = array();
        if ($foreign_db) {
            if (isset($existrel_foreign[$myfield])) {
                $foreign_table = $existrel_foreign[$myfield]['foreign_table'];
            }
            // In Drizzle, 'SHOW TABLE STATUS' will show status only for the tables
            // which are currently in the table cache. Hence we have to use
            // 'SHOW TABLES' and manully retrieve table engine values.
            if (PMA_DRIZZLE) {
                $tables_rs = $GLOBALS['dbi']->query('SHOW TABLES FROM ' . PMA_Util::backquote($foreign_db), null, PMA_DatabaseInterface::QUERY_STORE);
                while ($row = $GLOBALS['dbi']->fetchArray($tables_rs)) {
                    $engine = PMA_Table::sGetStatusInfo($foreign_db, $row[0], 'Engine');
                    if (isset($engine) && strtoupper($engine) == $tbl_storage_engine) {
                        $tables[] = $row[0];
                    }
                }
            } else {
                $tables_rs = $GLOBALS['dbi']->query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($foreign_db), null, PMA_DatabaseInterface::QUERY_STORE);
                while ($row = $GLOBALS['dbi']->fetchRow($tables_rs)) {
                    if (isset($row[1]) && strtoupper($row[1]) == $tbl_storage_engine) {
                        $tables[] = $row[0];
                    }
                }
            }
        }
        $html_output .= PMA_generateRelationalDropdown('destination_foreign_table[' . $myfield_md5 . ']', $tables, $foreign_table, __('Table'));
        // end of foreign table dropdown
        // foreign column dropdown
        $columns = array();
        if ($foreign_db && $foreign_table) {
            if (isset($existrel_foreign[$myfield])) {
                $foreign_column = $existrel_foreign[$myfield]['foreign_field'];
            }
            $table_obj = new PMA_Table($foreign_table, $foreign_db);
            $columns = $table_obj->getUniqueColumns(false, false);
        }
        $html_output .= PMA_generateRelationalDropdown('destination_foreign_column[' . $myfield_md5 . ']', $columns, $foreign_column, __('Column'));
        $html_output .= '</span>';
        // end of foreign column dropdown
        // For constraint name
        $html_output .= '<span class="formelement clearfloat">';
        $constraint_name = isset($existrel_foreign[$myfield]['constraint']) ? $existrel_foreign[$myfield]['constraint'] : '';
        $html_output .= __('Constraint name');
        $html_output .= '<input type="text" name="constraint_name[' . $myfield_md5 . ']"' . ' value="' . htmlspecialchars($constraint_name) . '"/>';
        $html_output .= '</span>' . "\n";
        $html_output .= '<span class="formelement clearfloat">';
        // For ON DELETE and ON UPDATE, the default action
        // is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE
        // won't display the clause if it's set as RESTRICT.
        $on_delete = isset($existrel_foreign[$myfield]['on_delete']) ? $existrel_foreign[$myfield]['on_delete'] : 'RESTRICT';
        $html_output .= PMA_generateDropdown('ON DELETE', 'on_delete[' . $myfield_md5 . ']', $options_array, $on_delete);
        $html_output .= '</span>' . "\n";
        $html_output .= '<span class="formelement clearfloat">' . "\n";
        $on_update = isset($existrel_foreign[$myfield]['on_update']) ? $existrel_foreign[$myfield]['on_update'] : 'RESTRICT';
        $html_output .= PMA_generateDropdown('ON UPDATE', 'on_update[' . $myfield_md5 . ']', $options_array, $on_update);
        $html_output .= '</span>' . "\n";
    } else {
        $html_output .= __('No index defined! Create one below');
    }
    // end if (a key exists)
    $html_output .= '</td>';
    return $html_output;
}
/**
 * Function to get html for an entire row in foreign key form
 *
 * @param array  $one_key            Single foreign key constraint
 * @param bool   $odd_row            whether odd or even row
 * @param array  $columns            Array of table columns
 * @param int    $i                  Row number
 * @param array  $options_array      Options array
 * @param string $tbl_storage_engine table storage engine
 * @param string $db                 Database
 *
 * @return string html
 */
function PMA_getHtmlForForeignKeyRow($one_key, $odd_row, $columns, $i, $options_array, $tbl_storage_engine, $db)
{
    $html_output = '<tr class="' . ($odd_row ? 'odd' : 'even') . '">';
    // Drop key anchor.
    $html_output .= '<td>';
    if (isset($one_key['constraint'])) {
        $drop_fk_query = 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table']) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($one_key['constraint']) . ';';
        $this_params = $GLOBALS['url_params'];
        $this_params['goto'] = 'tbl_relation.php';
        $this_params['back'] = 'tbl_relation.php';
        $this_params['sql_query'] = $drop_fk_query;
        $this_params['message_to_show'] = sprintf(__('Foreign key constraint %s has been dropped'), $one_key['constraint']);
        $js_msg = PMA_jsFormat('ALTER TABLE ' . $GLOBALS['table'] . ' DROP FOREIGN KEY ' . $one_key['constraint'] . ';');
        $html_output .= '<input type="hidden" class="drop_foreign_key_msg"' . ' value="' . $js_msg . '" />';
        $html_output .= '    <a class="drop_foreign_key_anchor';
        $html_output .= ' ajax';
        $html_output .= '" href="sql.php' . PMA_URL_getCommon($this_params) . '" >' . PMA_Util::getIcon('b_drop.png', __('Drop')) . '</a>';
    }
    $html_output .= '</td>';
    $html_output .= '<td>';
    $html_output .= '<span class="formelement clearfloat">';
    $constraint_name = isset($one_key['constraint']) ? $one_key['constraint'] : '';
    $html_output .= '<input type="text" name="constraint_name[' . $i . ']"' . ' value="' . htmlspecialchars($constraint_name) . '"' . ' placeholder="' . __('Constraint name') . '" />';
    $html_output .= '</span>' . "\n";
    $html_output .= '<div class="floatleft">';
    $html_output .= '<span class="formelement">';
    // For ON DELETE and ON UPDATE, the default action
    // is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE
    // won't display the clause if it's set as RESTRICT.
    $on_delete = isset($one_key['on_delete']) ? $one_key['on_delete'] : 'RESTRICT';
    $html_output .= PMA_generateDropdown('ON DELETE', 'on_delete[' . $i . ']', $options_array, $on_delete);
    $html_output .= '</span>' . "\n";
    $html_output .= '<span class="formelement">' . "\n";
    $on_update = isset($one_key['on_update']) ? $one_key['on_update'] : 'RESTRICT';
    $html_output .= PMA_generateDropdown('ON UPDATE', 'on_update[' . $i . ']', $options_array, $on_update);
    $html_output .= '</span>';
    $html_output .= '</div>';
    $column_array = array();
    $column_array[''] = '';
    foreach ($columns as $column) {
        if (!empty($column['Key'])) {
            $column_array[$column['Field']] = $column['Field'];
        }
    }
    $html_output .= '</span>' . "\n";
    $html_output .= '</td>';
    $html_output .= '<td>';
    if (isset($one_key['index_list'])) {
        foreach ($one_key['index_list'] as $key => $column) {
            $html_output .= '<span class="formelement clearfloat">';
            $html_output .= PMA_generateDropdown('', 'foreign_key_fields_name[' . $i . '][]', $column_array, $column);
            $html_output .= '</span>';
        }
    } else {
        $html_output .= '<span class="formelement clearfloat">';
        $html_output .= PMA_generateDropdown('', 'foreign_key_fields_name[' . $i . '][]', $column_array, '');
        $html_output .= '</span>';
    }
    $html_output .= '<a class="formelement clearfloat add_foreign_key_field"' . ' href="" data-index="' . $i . '">' . __('+ Add column') . '</a>';
    $html_output .= '</td>';
    $html_output .= '<td>';
    $foreign_table = false;
    // foreign database dropdown
    $foreign_db = isset($one_key['ref_db_name']) ? $one_key['ref_db_name'] : $db;
    $html_output .= '<span class="formelement clearfloat">';
    $html_output .= PMA_generateRelationalDropdown('destination_foreign_db[' . $i . ']', $GLOBALS['pma']->databases, $foreign_db, __('Database'));
    // end of foreign database dropdown
    $html_output .= '</td>';
    $html_output .= '<td>';
    // foreign table dropdown
    $tables = array();
    if ($foreign_db) {
        $foreign_table = isset($one_key['ref_table_name']) ? $one_key['ref_table_name'] : '';
        // In Drizzle, 'SHOW TABLE STATUS' will show status only for the tables
        // which are currently in the table cache. Hence we have to use
        // 'SHOW TABLES' and manualy retrieve table engine values.
        if (PMA_DRIZZLE) {
            $tables_rs = $GLOBALS['dbi']->query('SHOW TABLES FROM ' . PMA_Util::backquote($foreign_db), null, PMA_DatabaseInterface::QUERY_STORE);
            while ($row = $GLOBALS['dbi']->fetchArray($tables_rs)) {
                $engine = PMA_Table::sGetStatusInfo($foreign_db, $row[0], 'Engine');
                if (isset($engine) && mb_strtoupper($engine) == $tbl_storage_engine) {
                    $tables[] = $row[0];
                }
            }
        } else {
            $tables_rs = $GLOBALS['dbi']->query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($foreign_db), null, PMA_DatabaseInterface::QUERY_STORE);
            while ($row = $GLOBALS['dbi']->fetchRow($tables_rs)) {
                if (isset($row[1]) && mb_strtoupper($row[1]) == $tbl_storage_engine) {
                    $tables[] = $row[0];
                }
            }
        }
    }
    $html_output .= '<span class="formelement clearfloat">';
    $html_output .= PMA_generateRelationalDropdown('destination_foreign_table[' . $i . ']', $tables, $foreign_table, __('Table'));
    $html_output .= '</span>';
    // end of foreign table dropdown
    $html_output .= '</td>';
    $html_output .= '<td>';
    // foreign column dropdown
    if ($foreign_db && $foreign_table) {
        foreach ($one_key['ref_index_list'] as $foreign_column) {
            $table_obj = new PMA_Table($foreign_table, $foreign_db);
            $columns = $table_obj->getUniqueColumns(false, false);
            $html_output .= '<span class="formelement clearfloat">';
            $html_output .= PMA_generateRelationalDropdown('destination_foreign_column[' . $i . '][]', $columns, $foreign_column, __('Column'));
            $html_output .= '</span>';
        }
    } else {
        $html_output .= '<span class="formelement clearfloat">';
        $html_output .= PMA_generateRelationalDropdown('destination_foreign_column[' . $i . '][]', array(), '', __('Column'));
        $html_output .= '</span>';
    }
    // end of foreign column dropdown
    $html_output .= '</td>';
    $html_output .= '</tr>';
    return $html_output;
}