/**
 * return html for Print View Columns
 *
 * @param bool   $tbl_is_view  whether table is a view
 * @param array  $columns      columns list
 * @param array  $analyzed_sql analyzed sql
 * @param bool   $have_rel     have relation?
 * @param array  $res_rel      relations array
 * @param string $db           database name
 * @param string $table        table name
 * @param array  $cfgRelation  config from PMA_getRelationsParam
 *
 * @return string
 */
function PMA_getHtmlForPrintViewColumns($tbl_is_view, $columns, $analyzed_sql, $have_rel, $res_rel, $db, $table, $cfgRelation)
{
    $html = '';
    $primary = PMA_Index::getPrimary($table, $db);
    foreach ($columns as $row) {
        $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
        $type = $extracted_columnspec['print_type'];
        if (!isset($row['Default'])) {
            if ($row['Null'] != '' && $row['Null'] != 'NO') {
                $row['Default'] = '<i>NULL</i>';
            }
        } else {
            $row['Default'] = htmlspecialchars($row['Default']);
        }
        $field_name = htmlspecialchars($row['Field']);
        if (!$tbl_is_view) {
            // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having
            // the NULL attribute, but SHOW CREATE TABLE says the contrary.
            // Believe the latter.
            /**
             * @todo merge this logic with the one in tbl_structure.php
             * or move it in a function similar to $GLOBALS['dbi']->getColumnsFull()
             * but based on SHOW CREATE TABLE because information_schema
             * cannot be trusted in this case (MySQL bug)
             */
            $analyzed_for_field = $analyzed_sql[0]['create_table_fields'][$field_name];
            if (!empty($analyzed_for_field['type']) && $analyzed_for_field['type'] == 'TIMESTAMP' && $analyzed_for_field['timestamp_not_null']) {
                $row['Null'] = '';
            }
        }
        $html .= "\n";
        $html .= '<tr><td>';
        $html .= '    ' . $field_name . "\n";
        if ($primary && $primary->hasColumn($field_name)) {
            $html .= '    <em>(' . __('Primary') . ')</em>';
        }
        $html .= "\n";
        $html .= '</td>';
        $html .= '<td>' . htmlspecialchars($type) . '<bdo dir="ltr"></bdo></td>';
        $html .= '<td>';
        $html .= $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes');
        $html .= '&nbsp;</td>';
        $html .= '<td>';
        if (isset($row['Default'])) {
            $html .= $row['Default'];
        }
        $html .= '&nbsp;</td>';
        if ($have_rel) {
            $html .= '    <td>';
            $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
            if ($foreigner) {
                $html .= htmlspecialchars($foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field']);
            }
            $html .= '&nbsp;</td>' . "\n";
        }
        $html .= '    <td>';
        $comments = PMA_getComments($db, $table);
        if (isset($comments[$field_name])) {
            $html .= htmlspecialchars($comments[$field_name]);
        }
        $html .= '&nbsp;</td>' . "\n";
        if ($cfgRelation['mimework']) {
            $mime_map = PMA_getMIME($db, $table, true);
            $html .= '    <td>';
            if (isset($mime_map[$field_name])) {
                $html .= htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype']));
            }
            $html .= '&nbsp;</td>' . "\n";
        }
        $html .= '</tr>';
    }
    // end foreach
    return $html;
}
Exemple #2
0
/**
 * Removes a foreign relation
 *
 * @param string $T1 foreign db.table
 * @param string $F1 foreign field
 * @param string $T2 master db.table
 * @param string $F2 master field
 *
 * @return array array of success/failure and message
 */
function PMA_removeRelation($T1, $F1, $T2, $F2)
{
    list($DB1, $T1) = explode(".", $T1);
    list($DB2, $T2) = explode(".", $T2);
    $tables = $GLOBALS['dbi']->getTablesFull($DB1, $T1);
    $type_T1 = mb_strtoupper($tables[$T1]['ENGINE']);
    $tables = $GLOBALS['dbi']->getTablesFull($DB2, $T2);
    $type_T2 = mb_strtoupper($tables[$T2]['ENGINE']);
    if (PMA_Util::isForeignKeySupported($type_T1) && PMA_Util::isForeignKeySupported($type_T2) && $type_T1 == $type_T2) {
        // InnoDB
        $existrel_foreign = PMA_getForeigners($DB2, $T2, '', 'foreign');
        $foreigner = PMA_searchColumnInForeigners($existrel_foreign, $F2);
        if (isset($foreigner['constraint'])) {
            $upd_query = 'ALTER TABLE ' . PMA_Util::backquote($DB2) . '.' . PMA_Util::backquote($T2) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($foreigner['constraint']) . ';';
            if ($GLOBALS['dbi']->query($upd_query)) {
                return array(true, __('FOREIGN KEY relation has been removed.'));
            }
            $error = $GLOBALS['dbi']->getError();
            return array(false, __('Error: FOREIGN KEY relation could not be removed!') . "<br/>" . $error);
        }
    }
    // internal relations
    $delete_query = "DELETE FROM " . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . "." . $GLOBALS['cfgRelation']['relation'] . " WHERE " . "master_db = '" . PMA_Util::sqlAddSlashes($DB2) . "'" . " AND master_table = '" . PMA_Util::sqlAddSlashes($T2) . "'" . " AND master_field = '" . PMA_Util::sqlAddSlashes($F2) . "'" . " AND foreign_db = '" . PMA_Util::sqlAddSlashes($DB1) . "'" . " AND foreign_table = '" . PMA_Util::sqlAddSlashes($T1) . "'" . " AND foreign_field = '" . PMA_Util::sqlAddSlashes($F1) . "'";
    $result = PMA_queryAsControlUser($delete_query, false, PMA_DatabaseInterface::QUERY_STORE);
    if (!$result) {
        $error = $GLOBALS['dbi']->getError($GLOBALS['controllink']);
        return array(false, __('Error: Internal relation could not be removed!') . "<br/>" . $error);
    }
    return array(true, __('Internal relation has been removed.'));
}
Exemple #3
0
/**
 * Check child table references and foreign key for a table column.
 *
 * @param string $db                    name of master table db.
 * @param string $table                 name of master table.
 * @param string $column                name of master table column.
 * @param array  $foreigners_full       foreiners array for the whole table.
 * @param array  $child_references_full child references for the whole table.
 *
 * @return array $column_status telling about references if foreign key.
 */
function PMA_checkChildForeignReferences($db, $table, $column, $foreigners_full = null, $child_references_full = null)
{
    $column_status = array();
    $column_status['isEditable'] = false;
    $column_status['isReferenced'] = false;
    $column_status['isForeignKey'] = false;
    $column_status['references'] = array();
    $foreigners = array();
    if ($foreigners_full !== null) {
        if (isset($foreigners_full[$column])) {
            $foreigners[$column] = $foreigners_full[$column];
        }
        if (isset($foreigners_full['foreign_keys_data'])) {
            $foreigners['foreign_keys_data'] = $foreigners_full['foreign_keys_data'];
        }
    } else {
        $foreigners = PMA_getForeigners($db, $table, $column, 'foreign');
    }
    $foreigner = PMA_searchColumnInForeigners($foreigners, $column);
    $child_references = array();
    if ($child_references_full !== null) {
        if (isset($child_references_full[$column])) {
            $child_references = $child_references_full[$column];
        }
    } else {
        $child_references = PMA_getChildReferences($db, $table, $column);
    }
    if (sizeof($child_references, 0) > 0 || $foreigner) {
        if (sizeof($child_references, 0) > 0) {
            $column_status['isReferenced'] = true;
            foreach ($child_references as $row => $columns) {
                array_push($column_status['references'], PMA_Util::backquote($columns['table_schema']) . '.' . PMA_Util::backquote($columns['table_name']));
            }
        }
        if ($foreigner) {
            $column_status['isForeignKey'] = true;
        }
    } else {
        $column_status['isEditable'] = true;
    }
    return $column_status;
}
/**
 * Display option in the cell according to user choices
 *
 * @param array  $map                  all Relations to foreign tables for a given
 *                                     table or optionally a given column in a table
 * @param string $relation_field       relation field
 * @param string $where_comparison     string that contain relation field value
 * @param string $dispval              display value from the foreign table
 * @param string $relation_field_value relation field value
 *
 * @return string $output HTML <a> tag
 */
function PMA_getLinkForRelationalDisplayField($map, $relation_field, $where_comparison, $dispval, $relation_field_value)
{
    $foreigner = PMA_searchColumnInForeigners($map, $relation_field);
    if ('K' == $_SESSION['tmpval']['relational_display']) {
        // user chose "relational key" in the display options, so
        // the title contains the display field
        $title = !empty($dispval) ? ' title="' . htmlspecialchars($dispval) . '"' : '';
    } else {
        $title = ' title="' . htmlspecialchars($relation_field_value) . '"';
    }
    $_url_params = array('db' => $foreigner['foreign_db'], 'table' => $foreigner['foreign_table'], 'pos' => '0', 'sql_query' => 'SELECT * FROM ' . PMA_Util::backquote($foreigner['foreign_db']) . '.' . PMA_Util::backquote($foreigner['foreign_table']) . ' WHERE ' . PMA_Util::backquote($foreigner['foreign_field']) . $where_comparison);
    $output = '<a href="sql.php' . PMA_URL_getCommon($_url_params) . '"' . $title . '>';
    if ('D' == $_SESSION['tmpval']['relational_display']) {
        // user chose "relational display field" in the
        // display options, so show display field in the cell
        $output .= !empty($dispval) ? htmlspecialchars($dispval) : '';
    } else {
        // otherwise display data in the cell
        $output .= htmlspecialchars($relation_field_value);
    }
    $output .= '</a>';
    return $output;
}
Exemple #5
0
 if (isset($pk_array[$row['Field']])) {
     echo ' <em>(', __('Primary'), ')</em>';
 }
 echo '</td>';
 echo '<td', PMA\libraries\Util::getClassForType($extracted_columnspec['type']), ' lang="en" dir="ltr">', $type, '</td>';
 echo '<td>';
 echo $row['Null'] == 'NO' ? __('No') : __('Yes');
 echo '</td>';
 echo '<td class="nowrap">';
 if (isset($row['Default'])) {
     echo $row['Default'];
 }
 echo '</td>';
 if ($have_rel) {
     echo '    <td>';
     if ($foreigner = PMA_searchColumnInForeigners($res_rel, $column_name)) {
         echo htmlspecialchars($foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field']);
     }
     echo '</td>', "\n";
 }
 echo '    <td>';
 if (isset($comments[$column_name])) {
     echo htmlspecialchars($comments[$column_name]);
 }
 echo '</td>', "\n";
 if ($cfgRelation['mimework']) {
     $mime_map = PMA_getMIME($db, $table, true);
     echo '    <td>';
     if (isset($mime_map[$column_name])) {
         echo htmlspecialchars(str_replace('_', '/', $mime_map[$column_name]['mimetype']));
     }
 /**
  * Returns $table's CREATE definition
  *
  * @param string $db            the database name
  * @param string $table         the table name
  * @param string $crlf          the end of line sequence
  * @param string $error_url     the url to go back in case of error
  * @param bool   $do_relation   whether to include relation comments
  * @param bool   $do_comments   whether to include the pmadb-style column
  *                                comments as comments in the structure;
  *                                this is deprecated but the parameter is
  *                                left here because export.php calls
  *                                PMA_exportStructure() also for other
  * @param bool   $do_mime       whether to include mime comments
  * @param bool   $show_dates    whether to include creation/update/check dates
  * @param bool   $add_semicolon whether to add semicolon and end-of-line at
  *                              the end
  * @param bool   $view          whether we're handling a view
  * @param array  $aliases       Aliases of db/table/columns
  *
  * @return bool true
  */
 public function getTableDef($db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, $show_dates = false, $add_semicolon = true, $view = false, $aliases = array())
 {
     global $cfgRelation;
     $db_alias = $db;
     $table_alias = $table;
     $this->initAlias($aliases, $db_alias, $table_alias);
     /**
      * Gets fields properties
      */
     $GLOBALS['dbi']->selectDb($db);
     // Check if we can use Relations
     list($res_rel, $have_rel) = PMA_getRelationsAndStatus($do_relation && !empty($cfgRelation['relation']), $db, $table);
     /**
      * Displays the table structure
      */
     $GLOBALS['odt_buffer'] .= '<table:table table:name="' . htmlspecialchars($table_alias) . '_structure">';
     $columns_cnt = 4;
     if ($do_relation && $have_rel) {
         $columns_cnt++;
     }
     if ($do_comments) {
         $columns_cnt++;
     }
     if ($do_mime && $cfgRelation['mimework']) {
         $columns_cnt++;
     }
     $GLOBALS['odt_buffer'] .= '<table:table-column' . ' table:number-columns-repeated="' . $columns_cnt . '"/>';
     /* Header */
     $GLOBALS['odt_buffer'] .= '<table:table-row>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Column') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Type') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Null') . '</text:p>' . '</table:table-cell>' . '<table:table-cell office:value-type="string">' . '<text:p>' . __('Default') . '</text:p>' . '</table:table-cell>';
     if ($do_relation && $have_rel) {
         $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('Links to') . '</text:p>' . '</table:table-cell>';
     }
     if ($do_comments) {
         $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('Comments') . '</text:p>' . '</table:table-cell>';
         $comments = PMA_getComments($db, $table);
     }
     if ($do_mime && $cfgRelation['mimework']) {
         $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . __('MIME type') . '</text:p>' . '</table:table-cell>';
         $mime_map = PMA_getMIME($db, $table, true);
     }
     $GLOBALS['odt_buffer'] .= '</table:table-row>';
     $columns = $GLOBALS['dbi']->getColumns($db, $table);
     foreach ($columns as $column) {
         $col_as = $field_name = $column['Field'];
         if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
             $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
         }
         $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column, $col_as);
         if ($do_relation && $have_rel) {
             $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
             if ($foreigner) {
                 $rtable = $foreigner['foreign_table'];
                 $rfield = $foreigner['foreign_field'];
                 if (!empty($aliases[$db]['tables'][$rtable]['columns'][$rfield])) {
                     $rfield = $aliases[$db]['tables'][$rtable]['columns'][$rfield];
                 }
                 if (!empty($aliases[$db]['tables'][$rtable]['alias'])) {
                     $rtable = $aliases[$db]['tables'][$rtable]['alias'];
                 }
                 $relation = htmlspecialchars($rtable . ' (' . $rfield . ')');
                 $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($relation) . '</text:p>' . '</table:table-cell>';
             }
         }
         if ($do_comments) {
             if (isset($comments[$field_name])) {
                 $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($comments[$field_name]) . '</text:p>' . '</table:table-cell>';
             } else {
                 $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>';
             }
         }
         if ($do_mime && $cfgRelation['mimework']) {
             if (isset($mime_map[$field_name])) {
                 $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])) . '</text:p>' . '</table:table-cell>';
             } else {
                 $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>';
             }
         }
         $GLOBALS['odt_buffer'] .= '</table:table-row>';
     }
     // end foreach
     $GLOBALS['odt_buffer'] .= '</table:table>';
     return true;
 }
 /**
  * Generates data dictionary pages.
  *
  * @param array $alltables Tables to document.
  *
  * @return void
  */
 public function dataDictionaryDoc($alltables)
 {
     // TOC
     $this->diagram->addpage($this->orientation);
     $this->diagram->Cell(0, 9, __('Table of contents'), 1, 0, 'C');
     $this->diagram->Ln(15);
     $i = 1;
     foreach ($alltables as $table) {
         $this->diagram->PMA_links['doc'][$table]['-'] = $this->diagram->AddLink();
         $this->diagram->SetX(10);
         // $this->diagram->Ln(1);
         $this->diagram->Cell(0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0, 'R', 0, $this->diagram->PMA_links['doc'][$table]['-']);
         $this->diagram->SetX(10);
         $this->diagram->Cell(0, 6, $i . ' ' . $table, 0, 1, 'L', 0, $this->diagram->PMA_links['doc'][$table]['-']);
         // $this->diagram->Ln(1);
         $fields = $GLOBALS['dbi']->getColumns($this->db, $table);
         foreach ($fields as $row) {
             $this->diagram->SetX(20);
             $field_name = $row['Field'];
             $this->diagram->PMA_links['doc'][$table][$field_name] = $this->diagram->AddLink();
             //$this->diagram->Cell(
             //    0, 6, $field_name, 0, 1,
             //    'L', 0, $this->diagram->PMA_links['doc'][$table][$field_name]
             //);
         }
         $i++;
     }
     $this->diagram->PMA_links['RT']['-'] = $this->diagram->AddLink();
     $this->diagram->SetX(10);
     $this->diagram->Cell(0, 6, __('Page number:') . ' {00}', 0, 0, 'R', 0, $this->diagram->PMA_links['RT']['-']);
     $this->diagram->SetX(10);
     $this->diagram->Cell(0, 6, $i . ' ' . __('Relational schema'), 0, 1, 'L', 0, $this->diagram->PMA_links['RT']['-']);
     $z = 0;
     foreach ($alltables as $table) {
         $z++;
         $this->diagram->SetAutoPageBreak(true, 15);
         $this->diagram->addpage($this->orientation);
         $this->diagram->Bookmark($table);
         $this->diagram->SetAlias('{' . sprintf("%02d", $z) . '}', $this->diagram->PageNo());
         $this->diagram->PMA_links['RT'][$table]['-'] = $this->diagram->AddLink();
         $this->diagram->SetLink($this->diagram->PMA_links['doc'][$table]['-'], -1);
         $this->diagram->SetFont($this->_ff, 'B', 18);
         $this->diagram->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $this->diagram->PMA_links['RT'][$table]['-']);
         $this->diagram->SetFont($this->_ff, '', 8);
         $this->diagram->ln();
         $cfgRelation = PMA_getRelationsParam();
         $comments = PMA_getComments($this->db, $table);
         if ($cfgRelation['mimework']) {
             $mime_map = PMA_getMIME($this->db, $table, true);
         }
         /**
          * Gets table information
          */
         $showtable = $GLOBALS['dbi']->getTable($this->db, $table)->getStatusInfo();
         $show_comment = isset($showtable['Comment']) ? $showtable['Comment'] : '';
         $create_time = isset($showtable['Create_time']) ? PMA_Util::localisedDate(strtotime($showtable['Create_time'])) : '';
         $update_time = isset($showtable['Update_time']) ? PMA_Util::localisedDate(strtotime($showtable['Update_time'])) : '';
         $check_time = isset($showtable['Check_time']) ? PMA_Util::localisedDate(strtotime($showtable['Check_time'])) : '';
         /**
          * Gets fields properties
          */
         $columns = $GLOBALS['dbi']->getColumns($this->db, $table);
         // Check if we can use Relations
         if (!empty($cfgRelation['relation'])) {
             // Find which tables are related with the current one and write it in
             // an array
             $res_rel = PMA_getForeigners($this->db, $table);
         }
         // end if
         /**
          * Displays the comments of the table if MySQL >= 3.23
          */
         $break = false;
         if (!empty($show_comment)) {
             $this->diagram->Cell(0, 3, __('Table comments:') . ' ' . $show_comment, 0, 1);
             $break = true;
         }
         if (!empty($create_time)) {
             $this->diagram->Cell(0, 3, __('Creation:') . ' ' . $create_time, 0, 1);
             $break = true;
         }
         if (!empty($update_time)) {
             $this->diagram->Cell(0, 3, __('Last update:') . ' ' . $update_time, 0, 1);
             $break = true;
         }
         if (!empty($check_time)) {
             $this->diagram->Cell(0, 3, __('Last check:') . ' ' . $check_time, 0, 1);
             $break = true;
         }
         if ($break == true) {
             $this->diagram->Cell(0, 3, '', 0, 1);
             $this->diagram->Ln();
         }
         $this->diagram->SetFont($this->_ff, 'B');
         if (isset($this->orientation) && $this->orientation == 'L') {
             $this->diagram->Cell(25, 8, __('Column'), 1, 0, 'C');
             $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C');
             $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C');
             $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C');
             $this->diagram->Cell(20, 8, __('Default'), 1, 0, 'C');
             $this->diagram->Cell(25, 8, __('Extra'), 1, 0, 'C');
             $this->diagram->Cell(45, 8, __('Links to'), 1, 0, 'C');
             if ($this->paper == 'A4') {
                 $comments_width = 67;
             } else {
                 // this is really intended for 'letter'
                 /**
                  * @todo find optimal width for all formats
                  */
                 $comments_width = 50;
             }
             $this->diagram->Cell($comments_width, 8, __('Comments'), 1, 0, 'C');
             $this->diagram->Cell(45, 8, 'MIME', 1, 1, 'C');
             $this->diagram->SetWidths(array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45));
         } else {
             $this->diagram->Cell(20, 8, __('Column'), 1, 0, 'C');
             $this->diagram->Cell(20, 8, __('Type'), 1, 0, 'C');
             $this->diagram->Cell(20, 8, __('Attributes'), 1, 0, 'C');
             $this->diagram->Cell(10, 8, __('Null'), 1, 0, 'C');
             $this->diagram->Cell(15, 8, __('Default'), 1, 0, 'C');
             $this->diagram->Cell(15, 8, __('Extra'), 1, 0, 'C');
             $this->diagram->Cell(30, 8, __('Links to'), 1, 0, 'C');
             $this->diagram->Cell(30, 8, __('Comments'), 1, 0, 'C');
             $this->diagram->Cell(30, 8, 'MIME', 1, 1, 'C');
             $this->diagram->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
         }
         $this->diagram->SetFont($this->_ff, '');
         foreach ($columns as $row) {
             $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
             $type = $extracted_columnspec['print_type'];
             $attribute = $extracted_columnspec['attribute'];
             if (!isset($row['Default'])) {
                 if ($row['Null'] != '' && $row['Null'] != 'NO') {
                     $row['Default'] = 'NULL';
                 }
             }
             $field_name = $row['Field'];
             // $this->diagram->Ln();
             $this->diagram->PMA_links['RT'][$table][$field_name] = $this->diagram->AddLink();
             $this->diagram->Bookmark($field_name, 1, -1);
             $this->diagram->SetLink($this->diagram->PMA_links['doc'][$table][$field_name], -1);
             $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
             $linksTo = '';
             if ($foreigner) {
                 $linksTo = '-> ';
                 if ($foreigner['foreign_db'] != $this->db) {
                     $linksTo .= $foreigner['foreign_db'] . '.';
                 }
                 $linksTo .= $foreigner['foreign_table'] . '.' . $foreigner['foreign_field'];
                 if (isset($foreigner['on_update'])) {
                     // not set for internal
                     $linksTo .= "\n" . 'ON UPDATE ' . $foreigner['on_update'];
                     $linksTo .= "\n" . 'ON DELETE ' . $foreigner['on_delete'];
                 }
             }
             $this->diagram_row = array($field_name, $type, $attribute, $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes'), isset($row['Default']) ? $row['Default'] : '', $row['Extra'], $linksTo, isset($comments[$field_name]) ? $comments[$field_name] : '', isset($mime_map) && isset($mime_map[$field_name]) ? str_replace('_', '/', $mime_map[$field_name]['mimetype']) : '');
             $links = array();
             $links[0] = $this->diagram->PMA_links['RT'][$table][$field_name];
             if ($foreigner && isset($this->diagram->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']])) {
                 $links[6] = $this->diagram->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']];
             } else {
                 unset($links[6]);
             }
             $this->diagram->Row($this->diagram_row, $links);
         }
         // end foreach
         $this->diagram->SetFont($this->_ff, '', 14);
     }
     //end each
 }
 /**
  * Gives the relation string and
  * also substitutes with alias if required
  * in this format:
  * [Foreign Table] ([Foreign Field])
  *
  * @param array  $res_rel    the foreigners array
  * @param string $field_name the field name
  * @param string $db         the field name
  * @param array  $aliases    Alias information for db/table/column
  *
  * @return string the Relation string
  */
 public function getRelationString($res_rel, $field_name, $db, $aliases = array())
 {
     $relation = '';
     $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
     if ($foreigner) {
         $ftable = $foreigner['foreign_table'];
         $ffield = $foreigner['foreign_field'];
         if (!empty($aliases[$db]['tables'][$ftable]['columns'][$ffield])) {
             $ffield = $aliases[$db]['tables'][$ftable]['columns'][$ffield];
         }
         if (!empty($aliases[$db]['tables'][$ftable]['alias'])) {
             $ftable = $aliases[$db]['tables'][$ftable]['alias'];
         }
         $relation = $ftable . ' (' . $ffield . ')';
     }
     return $relation;
 }
 /**
  * Creates the HTML content for:
  * 1) Browsing foreign data for a column.
  * 2) Creating elements for search criteria input on columns.
  *
  * @param array  $foreignData         Foreign keys data
  * @param string $column_name         Column name
  * @param string $column_type         Column type
  * @param int    $column_index        Column index
  * @param array  $titles              Selected title
  * @param int    $foreignMaxLimit     Max limit of displaying foreign elements
  * @param array  $criteriaValues      Array of search criteria inputs
  * @param bool   $in_fbs              Whether we are in 'function based search'
  * @param bool   $in_zoom_search_edit Whether we are in zoom search edit
  *
  * @return string HTML content for viewing foreign data and elements
  * for search criteria input.
  */
 private function _getInputbox($foreignData, $column_name, $column_type, $column_index, $titles, $foreignMaxLimit, $criteriaValues, $in_fbs = false, $in_zoom_search_edit = false)
 {
     $str = '';
     $column_type = (string) $column_type;
     $column_id = $in_zoom_search_edit ? 'edit_fieldID_' : 'fieldID_';
     // Get inputbox based on different column types
     // (Foreign key, geometrical, enum)
     if ($this->_foreigners && PMA_searchColumnInForeigners($this->_foreigners, $column_name)) {
         $str .= $this->_getForeignKeyInputBox($foreignData, $column_name, $column_index, $titles, $foreignMaxLimit, $criteriaValues, $column_id);
     } elseif (in_array($column_type, PMA_Util::getGISDatatypes())) {
         $str .= $this->_getGeometricalInputBox($column_index, $in_fbs);
     } elseif (strncasecmp($column_type, 'enum', 4) == 0 || strncasecmp($column_type, 'set', 3) == 0 && $in_zoom_search_edit) {
         $str .= $this->_getEnumSetInputBox($column_index, $criteriaValues, $column_type, $column_id, $in_zoom_search_edit = false);
     } else {
         // other cases
         $the_class = 'textfield';
         /** @var PMA_String $pmaString */
         $pmaString = $GLOBALS['PMA_String'];
         if ($column_type == 'date') {
             $the_class .= ' datefield';
         } elseif ($column_type == 'datetime' || $pmaString->substr($column_type, 0, 9) == 'timestamp') {
             $the_class .= ' datetimefield';
         } elseif ($pmaString->substr($column_type, 0, 3) == 'bit') {
             $the_class .= ' bit';
         }
         $str .= '<input type="text" name="criteriaValues[' . $column_index . ']"' . ' size="40" class="' . $the_class . '" id="' . $column_id . $column_index . '"' . (isset($criteriaValues[$column_index]) && is_string($criteriaValues[$column_index]) ? ' value="' . $criteriaValues[$column_index] . '"' : '') . ' />';
     }
     return $str;
 }
 /**
  * Test for PMA_searchColumnInForeigners
  *
  * @return void
  */
 public function testPMASearchColumnInForeigners()
 {
     $foreigners = array('value' => array('master_field' => 'value', 'foreign_db' => 'GSoC14', 'foreign_table' => 'test', 'foreign_field' => 'value'), 'foreign_keys_data' => array(0 => array('constraint' => 'ad', 'index_list' => array('id', 'value'), 'ref_db_name' => 'GSoC14', 'ref_table_name' => 'table_1', 'ref_index_list' => array('id', 'value'), 'on_delete' => 'CASCADE', 'on_update' => 'CASCADE')));
     $foreigner = PMA_searchColumnInForeigners($foreigners, 'id');
     $expected = array();
     $expected['foreign_field'] = 'id';
     $expected['foreign_db'] = 'GSoC14';
     $expected['foreign_table'] = 'table_1';
     $expected['constraint'] = 'ad';
     $expected['on_delete'] = 'CASCADE';
     $expected['on_update'] = 'CASCADE';
     $this->assertEquals($expected, $foreigner);
 }
 /**
  * Generates data dictionary pages.
  *
  * @param array $alltables Tables to document.
  *
  * @return void
  */
 public function dataDictionaryDoc($alltables)
 {
     global $pdf;
     // TOC
     $pdf->addpage($this->orientation);
     $pdf->Cell(0, 9, __('Table of contents'), 1, 0, 'C');
     $pdf->Ln(15);
     $i = 1;
     foreach ($alltables as $table) {
         $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink();
         $pdf->SetX(10);
         // $pdf->Ln(1);
         $pdf->Cell(0, 6, __('Page number:') . ' {' . sprintf("%02d", $i) . '}', 0, 0, 'R', 0, $pdf->PMA_links['doc'][$table]['-']);
         $pdf->SetX(10);
         $pdf->Cell(0, 6, $i . ' ' . $table, 0, 1, 'L', 0, $pdf->PMA_links['doc'][$table]['-']);
         // $pdf->Ln(1);
         $fields = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $table);
         foreach ($fields as $row) {
             $pdf->SetX(20);
             $field_name = $row['Field'];
             $pdf->PMA_links['doc'][$table][$field_name] = $pdf->AddLink();
             //$pdf->Cell(
             //    0, 6, $field_name, 0, 1,
             //    'L', 0, $pdf->PMA_links['doc'][$table][$field_name]
             //);
         }
         $i++;
     }
     $pdf->PMA_links['RT']['-'] = $pdf->AddLink();
     $pdf->SetX(10);
     $pdf->Cell(0, 6, __('Page number:') . ' {00}', 0, 0, 'R', 0, $pdf->PMA_links['RT']['-']);
     $pdf->SetX(10);
     $pdf->Cell(0, 6, $i . ' ' . __('Relational schema'), 0, 1, 'L', 0, $pdf->PMA_links['RT']['-']);
     $z = 0;
     foreach ($alltables as $table) {
         $z++;
         $pdf->SetAutoPageBreak(true, 15);
         $pdf->addpage($this->orientation);
         $pdf->Bookmark($table);
         $pdf->SetAlias('{' . sprintf("%02d", $z) . '}', $pdf->PageNo());
         $pdf->PMA_links['RT'][$table]['-'] = $pdf->AddLink();
         $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'], -1);
         $pdf->SetFont($this->_ff, 'B', 18);
         $pdf->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $pdf->PMA_links['RT'][$table]['-']);
         $pdf->SetFont($this->_ff, '', 8);
         $pdf->ln();
         $cfgRelation = PMA_getRelationsParam();
         $comments = PMA_getComments($GLOBALS['db'], $table);
         if ($cfgRelation['mimework']) {
             $mime_map = PMA_getMIME($GLOBALS['db'], $table, true);
         }
         /**
          * Gets table informations
          */
         $showtable = PMA_Table::sGetStatusInfo($GLOBALS['db'], $table);
         $show_comment = isset($showtable['Comment']) ? $showtable['Comment'] : '';
         $create_time = isset($showtable['Create_time']) ? PMA_Util::localisedDate(strtotime($showtable['Create_time'])) : '';
         $update_time = isset($showtable['Update_time']) ? PMA_Util::localisedDate(strtotime($showtable['Update_time'])) : '';
         $check_time = isset($showtable['Check_time']) ? PMA_Util::localisedDate(strtotime($showtable['Check_time'])) : '';
         /**
          * Gets table keys and retains them
          */
         $result = $GLOBALS['dbi']->query('SHOW KEYS FROM ' . PMA_Util::backquote($table) . ';');
         $primary = '';
         $indexes = array();
         $lastIndex = '';
         $indexes_info = array();
         $indexes_data = array();
         $pk_array = array();
         // will be use to emphasis prim. keys in the table
         // view
         while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
             // Backups the list of primary keys
             if ($row['Key_name'] == 'PRIMARY') {
                 $primary .= $row['Column_name'] . ', ';
                 $pk_array[$row['Column_name']] = 1;
             }
             // Retains keys informations
             if ($row['Key_name'] != $lastIndex) {
                 $indexes[] = $row['Key_name'];
                 $lastIndex = $row['Key_name'];
             }
             $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
             $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
             if (isset($row['Cardinality'])) {
                 $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
             }
             // I don't know what does following column mean....
             // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
             $indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
             $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
             if (isset($row['Sub_part'])) {
                 $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
             }
         }
         // end while
         if ($result) {
             $GLOBALS['dbi']->freeResult($result);
         }
         /**
          * Gets fields properties
          */
         $columns = $GLOBALS['dbi']->getColumns($GLOBALS['db'], $table);
         // Check if we can use Relations
         if (!empty($cfgRelation['relation'])) {
             // Find which tables are related with the current one and write it in
             // an array
             $res_rel = PMA_getForeigners($GLOBALS['db'], $table);
         }
         // end if
         /**
          * Displays the comments of the table if MySQL >= 3.23
          */
         $break = false;
         if (!empty($show_comment)) {
             $pdf->Cell(0, 3, __('Table comments:') . ' ' . $show_comment, 0, 1);
             $break = true;
         }
         if (!empty($create_time)) {
             $pdf->Cell(0, 3, __('Creation:') . ' ' . $create_time, 0, 1);
             $break = true;
         }
         if (!empty($update_time)) {
             $pdf->Cell(0, 3, __('Last update:') . ' ' . $update_time, 0, 1);
             $break = true;
         }
         if (!empty($check_time)) {
             $pdf->Cell(0, 3, __('Last check:') . ' ' . $check_time, 0, 1);
             $break = true;
         }
         if ($break == true) {
             $pdf->Cell(0, 3, '', 0, 1);
             $pdf->Ln();
         }
         $pdf->SetFont($this->_ff, 'B');
         if (isset($this->orientation) && $this->orientation == 'L') {
             $pdf->Cell(25, 8, __('Column'), 1, 0, 'C');
             $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
             $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
             $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
             $pdf->Cell(20, 8, __('Default'), 1, 0, 'C');
             $pdf->Cell(25, 8, __('Extra'), 1, 0, 'C');
             $pdf->Cell(45, 8, __('Links to'), 1, 0, 'C');
             if ($this->paper == 'A4') {
                 $comments_width = 67;
             } else {
                 // this is really intended for 'letter'
                 /**
                  * @todo find optimal width for all formats
                  */
                 $comments_width = 50;
             }
             $pdf->Cell($comments_width, 8, __('Comments'), 1, 0, 'C');
             $pdf->Cell(45, 8, 'MIME', 1, 1, 'C');
             $pdf->SetWidths(array(25, 20, 20, 10, 20, 25, 45, $comments_width, 45));
         } else {
             $pdf->Cell(20, 8, __('Column'), 1, 0, 'C');
             $pdf->Cell(20, 8, __('Type'), 1, 0, 'C');
             $pdf->Cell(20, 8, __('Attributes'), 1, 0, 'C');
             $pdf->Cell(10, 8, __('Null'), 1, 0, 'C');
             $pdf->Cell(15, 8, __('Default'), 1, 0, 'C');
             $pdf->Cell(15, 8, __('Extra'), 1, 0, 'C');
             $pdf->Cell(30, 8, __('Links to'), 1, 0, 'C');
             $pdf->Cell(30, 8, __('Comments'), 1, 0, 'C');
             $pdf->Cell(30, 8, 'MIME', 1, 1, 'C');
             $pdf->SetWidths(array(20, 20, 20, 10, 15, 15, 30, 30, 30));
         }
         $pdf->SetFont($this->_ff, '');
         foreach ($columns as $row) {
             $extracted_columnspec = PMA_Util::extractColumnSpec($row['Type']);
             $type = $extracted_columnspec['print_type'];
             $attribute = $extracted_columnspec['attribute'];
             if (!isset($row['Default'])) {
                 if ($row['Null'] != '' && $row['Null'] != 'NO') {
                     $row['Default'] = 'NULL';
                 }
             }
             $field_name = $row['Field'];
             // $pdf->Ln();
             $pdf->PMA_links['RT'][$table][$field_name] = $pdf->AddLink();
             $pdf->Bookmark($field_name, 1, -1);
             $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name], -1);
             $foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
             $pdf_row = array($field_name, $type, $attribute, $row['Null'] == '' || $row['Null'] == 'NO' ? __('No') : __('Yes'), isset($row['Default']) ? $row['Default'] : '', $row['Extra'], $foreigner ? $foreigner['foreign_table'] . ' -> ' . $foreigner['foreign_field'] : '', isset($comments[$field_name]) ? $comments[$field_name] : '', isset($mime_map) && isset($mime_map[$field_name]) ? str_replace('_', '/', $mime_map[$field_name]['mimetype']) : '');
             $links = array();
             $links[0] = $pdf->PMA_links['RT'][$table][$field_name];
             if ($foreigner && isset($pdf->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']])) {
                 $links[6] = $pdf->PMA_links['doc'][$foreigner['foreign_table']][$foreigner['foreign_field']];
             } else {
                 unset($links[6]);
             }
             $pdf->Row($pdf_row, $links);
         }
         // end foreach
         $pdf->SetFont($this->_ff, '', 14);
     }
     //end each
 }
/**
 * Removes a foreign relation
 *
 * @param string $T1 foreign db.table
 * @param string $F1 foreign field
 * @param string $T2 master db.table
 * @param string $F2 master field
 *
 * @return void
 */
function PMA_removeRelation($T1, $F1, $T2, $F2)
{
    /** @var PMA_String $pmaString */
    $pmaString = $GLOBALS['PMA_String'];
    list($DB1, $T1) = explode(".", $T1);
    list($DB2, $T2) = explode(".", $T2);
    $tables = $GLOBALS['dbi']->getTablesFull($DB1, $T1);
    $type_T1 = $pmaString->strtoupper($tables[$T1]['ENGINE']);
    $tables = $GLOBALS['dbi']->getTablesFull($DB2, $T2);
    $type_T2 = $pmaString->strtoupper($tables[$T2]['ENGINE']);
    $try_to_delete_internal_relation = false;
    if (PMA_Util::isForeignKeySupported($type_T1) && PMA_Util::isForeignKeySupported($type_T2) && $type_T1 == $type_T2) {
        // InnoDB
        $existrel_foreign = PMA_getForeigners($DB2, $T2, '', 'foreign');
        $foreigner = PMA_searchColumnInForeigners($existrel_foreign, $F2);
        if (isset($foreigner['constraint'])) {
            $upd_query = 'ALTER TABLE ' . PMA_Util::backquote($DB2) . '.' . PMA_Util::backquote($T2) . ' DROP FOREIGN KEY ' . PMA_Util::backquote($foreigner['constraint']) . ';';
            $upd_rs = $GLOBALS['dbi']->query($upd_query);
        } else {
            // there can be an internal relation even if InnoDB
            $try_to_delete_internal_relation = true;
        }
    } else {
        $try_to_delete_internal_relation = true;
    }
    if ($try_to_delete_internal_relation) {
        // internal relations
        PMA_queryAsControlUser('DELETE FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' . $GLOBALS['cfgRelation']['relation'] . ' WHERE ' . 'master_db = \'' . PMA_Util::sqlAddSlashes($DB2) . '\'' . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($T2) . '\'' . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($F2) . '\'' . ' AND foreign_db = \'' . PMA_Util::sqlAddSlashes($DB1) . '\'' . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($T1) . '\'' . ' AND foreign_field = \'' . PMA_Util::sqlAddSlashes($F1) . '\'', false, PMA_DatabaseInterface::QUERY_STORE);
    }
}