diff --git a/export_relation_schema.php b/export_relation_schema.php
new file mode 100644
index 000000000..9c35609e2
--- /dev/null
+++ b/export_relation_schema.php
@@ -0,0 +1,124 @@
+%s table not found or not set in %s'), 'relation', 'config.inc.php') . '
' . "\n"
+ . PMA_showDocu('relation') . "\n";
+ require_once './libraries/footer.inc.php';
+}
+
+if (!$cfgRelation['displaywork']) {
+ echo sprintf(__('%s table not found or not set in %s'), 'table_info', 'config.inc.php') . '
' . "\n"
+ . PMA_showDocu('table_info') . "\n";
+ require_once './libraries/footer.inc.php';
+}
+
+if (!isset($cfgRelation['table_coords'])){
+ echo sprintf(__('%s table not found or not set in %s'), 'table_coords', 'config.inc.php') . '
' . "\n"
+ . PMA_showDocu('table_coords') . "\n";
+ require_once './libraries/footer.inc.php';
+}
+if (!isset($cfgRelation['pdf_pages'])) {
+ echo sprintf(__('%s table not found or not set in %s'), 'pdf_page', 'config.inc.php') . '
' . "\n"
+ . PMA_showDocu('pdf_pages') . "\n";
+ require_once './libraries/footer.inc.php';
+}
+
+if ($cfgRelation['pdfwork']) {
+
+ /**
+ * User Object Created for displaying the HTML options
+ * so, user can play with it and perform export of relations schema
+ */
+
+ require_once './libraries/schema/user_schema.php';
+ $user_schema = new PMA_USER_SCHEMA();
+
+ /**
+ * This function will process the user input
+ *
+ */
+ $user_schema->userInputProcess($do);
+
+ /**
+ * Now first show some possibility to select a page for the export of relation schema
+ */
+ $user_schema->selectPage();
+
+ /**
+ * Possibility to create a new page:
+ */
+ $user_schema->createPage();
+
+ /**
+ * After selection of page or creating a page
+ * It will show you the list of tables
+ * A dashboard will also be shown where you can position the tables
+ */
+ $user_schema->showTableDashBoard();
+
+ if (isset($do)
+ && ($do == 'edcoord'
+ || ($do == 'selectpage' && isset($chpage))
+ || ($do == 'createpage' && isset($chpage)))) {
+ /**
+ * show Export schema generation options
+ */
+ $user_schema->displaySchemaGenerationOptions();
+
+ if ((isset($showwysiwyg) && $showwysiwyg == '1')) {
+ ?>
+
+
\ No newline at end of file
diff --git a/libraries/schema/dia_relation_schema.php b/libraries/schema/dia_relation_schema.php
new file mode 100644
index 000000000..f7567ebde
--- /dev/null
+++ b/libraries/schema/dia_relation_schema.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/libraries/schema/eps_relation_chema.php b/libraries/schema/eps_relation_chema.php
new file mode 100644
index 000000000..d188304b9
--- /dev/null
+++ b/libraries/schema/eps_relation_chema.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/libraries/schema/pdf_relation_schema.php b/libraries/schema/pdf_relation_schema.php
new file mode 100644
index 000000000..5fc107826
--- /dev/null
+++ b/libraries/schema/pdf_relation_schema.php
@@ -0,0 +1,1338 @@
+fh;
+ }
+
+ public function getFw()
+ {
+ return $this->fw;
+ }
+
+ public function setCMargin($c_margin)
+ {
+ $this->cMargin = $c_margin;
+ }
+
+ function SetAlias($name, $value)
+ {
+ $this->Alias[$name] = $value ;
+ }
+
+ function _putpages()
+ {
+ if (count($this->Alias) > 0) {
+ $nb = $this->page;
+ foreach ($this->Alias as $alias => $value) {
+ for ($n = 1;$n <= $nb;$n++)
+ $this->pages[$n]=str_replace($alias, $value, $this->pages[$n]);
+ }
+ }
+ parent::_putpages();
+ }
+
+ /**
+ * Sets the scaling factor, defines minimum coordinates and margins
+ *
+ * @param float scale The scaling factor
+ * @param float x_min The minimum X coordinate
+ * @param float y_min The minimum Y coordinate
+ * @param float l_marg The left margin
+ * @param float t_marg The top margin
+ * @access public
+ */
+ function PMA_PDF_setScale($scale = 1, $x_min = 0, $y_min = 0, $l_marg = -1, $t_marg = -1)
+ {
+ $this->scale = $scale;
+ $this->x_min = $x_min;
+ $this->y_min = $y_min;
+ if ($this->l_marg != -1) {
+ $this->l_marg = $l_marg;
+ }
+ if ($this->t_marg != -1) {
+ $this->t_marg = $t_marg;
+ }
+ } // end of the "PMA_PDF_setScale" function
+ /**
+ * Outputs a scaled cell
+ *
+ * @param float w The cell width
+ * @param float h The cell height
+ * @param string txt The text to output
+ * @param mixed border Whether to add borders or not
+ * @param integer ln Where to put the cursor once the output is done
+ * @param string align Align mode
+ * @param integer fill Whether to fill the cell with a color or not
+ * @access public
+ * @see FPDF::Cell()
+ */
+ function PMA_PDF_cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '')
+ {
+ $h = $h / $this->scale;
+ $w = $w / $this->scale;
+ $this->Cell($w, $h, $txt, $border, $ln, $align, $fill, $link);
+ } // end of the "PMA_PDF_cellScale" function
+ /**
+ * Draws a scaled line
+ *
+ * @param float x1 The horizontal position of the starting point
+ * @param float y1 The vertical position of the starting point
+ * @param float x2 The horizontal position of the ending point
+ * @param float y2 The vertical position of the ending point
+ * @access public
+ * @see FPDF::Line()
+ */
+ function PMA_PDF_lineScale($x1, $y1, $x2, $y2)
+ {
+ $x1 = ($x1 - $this->x_min) / $this->scale + $this->l_marg;
+ $y1 = ($y1 - $this->y_min) / $this->scale + $this->t_marg;
+ $x2 = ($x2 - $this->x_min) / $this->scale + $this->l_marg;
+ $y2 = ($y2 - $this->y_min) / $this->scale + $this->t_marg;
+ $this->Line($x1, $y1, $x2, $y2);
+ } // end of the "PMA_PDF_lineScale" function
+ /**
+ * Sets x and y scaled positions
+ *
+ * @param float x The x position
+ * @param float y The y position
+ * @access public
+ * @see FPDF::SetXY()
+ */
+ function PMA_PDF_setXyScale($x, $y)
+ {
+ $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
+ $y = ($y - $this->y_min) / $this->scale + $this->t_marg;
+ $this->SetXY($x, $y);
+ } // end of the "PMA_PDF_setXyScale" function
+ /**
+ * Sets the X scaled positions
+ *
+ * @param float x The x position
+ * @access public
+ * @see FPDF::SetX()
+ */
+ function PMA_PDF_setXScale($x)
+ {
+ $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
+ $this->SetX($x);
+ } // end of the "PMA_PDF_setXScale" function
+ /**
+ * Sets the scaled font size
+ *
+ * @param float size The font size (in points)
+ * @access public
+ * @see FPDF::SetFontSize()
+ */
+ function PMA_PDF_setFontSizeScale($size)
+ {
+ // Set font size in points
+ $size = $size / $this->scale;
+ $this->SetFontSize($size);
+ } // end of the "PMA_PDF_setFontSizeScale" function
+ /**
+ * Sets the scaled line width
+ *
+ * @param float width The line width
+ * @access public
+ * @see FPDF::SetLineWidth()
+ */
+ function PMA_PDF_setLineWidthScale($width)
+ {
+ $width = $width / $this->scale;
+ $this->SetLineWidth($width);
+ } // end of the "PMA_PDF_setLineWidthScale" function
+ /**
+ * Displays an error message
+ *
+ * @param string error_message the error mesage
+ * @global array the PMA configuration array
+ * @global integer the current server id
+ * @global string the current language
+ * @global string the charset to convert to
+ * @global string the current database name
+ * @global string the current charset
+ * @global string the current text direction
+ * @global string a localized string
+ * @global string an other localized string
+ * @access public
+ */
+/* function PMA_PDF_die($error_message = '')
+ {
+ global $cfg;
+ global $server, $lang, $convcharset, $db;
+ global $charset, $text_dir;
+
+ require_once './libraries/header.inc.php';
+
+ echo '
PDF - ' . __('Error') . '
' . "\n"; + if (!empty($error_message)) { + $error_message = htmlspecialchars($error_message); + } + echo '' . "\n"; + echo ' ' . $error_message . "\n"; + echo '
' . "\n"; + + echo '' . __('Back') . ''; + echo "\n"; + + require_once './libraries/footer.inc.php'; + }*/ // end of the "PMA_PDF_die()" function + /** + * Aliases the "Error()" function from the FPDF class to the + * "PMA_PDF_die()" one + * + * @param string error_message the error mesage + * @access public + * @see PMA_PDF_die + */ + function Error($error_message = '') + { + PMA_Relation_Schema::PMA_Schema_die($error_message); + } // end of the "Error()" method + function Header() + { + // We only show this if we find something in the new pdf_pages table + + // This function must be named "Header" to work with the FPDF library + global $cfgRelation, $db, $pdf_page_number, $with_doc; + if ($with_doc) { + $test_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND page_nr = \'' . $pdf_page_number . '\''; + $test_rs = PMA_query_as_controluser($test_query); + $pages = @PMA_DBI_fetch_assoc($test_rs); + $this->SetFont('', 'B', 14); + $this->Cell(0, 6, ucfirst($pages['page_descr']), 'B', 1, 'C'); + $this->SetFont('', ''); + $this->Ln(); + } + } + function Footer() + { + // This function must be named "Footer" to work with the FPDF library + global $with_doc; + if ($with_doc) { + $this->SetY(-15); + $this->SetFont('', '', 14); + $this->Cell(0, 6, __('Page number:') . ' ' . $this->PageNo() . '/{nb}', 'T', 0, 'C'); + $this->Cell(0, 6, PMA_localisedDate(), 0, 1, 'R'); + $this->SetY(20); + } + } + function Bookmark($txt, $level = 0, $y = 0) + { + // Add a bookmark + $this->Outlines[0][] = $level; + $this->Outlines[1][] = $txt; + $this->Outlines[2][] = $this->page; + if ($y == -1) { + $y = $this->GetY(); + } + $this->Outlines[3][] = round($this->hPt - $y * $this->k, 2); + } + + function _putbookmarks() + { + if (count($this->Outlines) > 0) { + // Save object number + $memo_n = $this->n; + // Take the number of sub elements for an outline + $nb_outlines = sizeof($this->Outlines[0]); + $first_level = array(); + $parent = array(); + $parent[0] = 1; + for ($i = 0; $i < $nb_outlines; $i++) { + $level = $this->Outlines[0][$i]; + $kids = 0; + $last = -1; + $prev = -1; + $next = -1; + if ($i > 0) { + $cursor = $i-1; + // Take the previous outline in the same level + while ($this->Outlines[0][$cursor] > $level && $cursor > 0) + $cursor--; + if ($this->Outlines[0][$cursor] == $level) { + $prev = $cursor; + } + } + if ($i < $nb_outlines-1) { + $cursor = $i + 1; + while (isset($this->Outlines[0][$cursor]) && $this->Outlines[0][$cursor] > $level) { + // Take the immediate kid in level + 1 + if ($this->Outlines[0][$cursor] == $level + 1) { + $kids++; + $last = $cursor; + } + $cursor++; + } + $cursor = $i + 1; + // Take the next outline in the same level + while ($this->Outlines[0][$cursor] > $level && ($cursor + 1 < sizeof($this->Outlines[0]))) + $cursor++; + if ($this->Outlines[0][$cursor] == $level) { + $next = $cursor; + } + } + $this->_newobj(); + $parent[$level + 1] = $this->n; + if ($level == 0) { + $first_level[] = $this->n; + } + $this->_out('<<'); + $this->_out('/Title (' . $this->Outlines[1][$i] . ')'); + $this->_out('/Parent ' . $parent[$level] . ' 0 R'); + if ($prev != -1) { + $this->_out('/Prev ' . ($memo_n + $prev + 1) . ' 0 R'); + } + if ($next != -1) { + $this->_out('/Next ' . ($this->n + $next - $i) . ' 0 R'); + } + $this->_out('/Dest [' . (1 + (2 * $this->Outlines[2][$i])) . ' 0 R /XYZ null ' . $this->Outlines[3][$i] . ' null]'); + if ($kids > 0) { + $this->_out('/First ' . ($this->n + 1) . ' 0 R'); + $this->_out('/Last ' . ($this->n + $last - $i) . ' 0 R'); + $this->_out('/Count -' . $kids); + } + $this->_out('>>'); + $this->_out('endobj'); + } + // First page of outlines + $this->_newobj(); + $this->def_outlines = $this->n; + $this->_out('<<'); + $this->_out('/Type'); + $this->_out('/Outlines'); + $this->_out('/First ' . $first_level[0] . ' 0 R'); + $this->_out('/Last ' . $first_level[sizeof($first_level)-1] . ' 0 R'); + $this->_out('/Count ' . sizeof($first_level)); + $this->_out('>>'); + $this->_out('endobj'); + } + } + + function _putresources() + { + parent::_putresources(); + $this->_putbookmarks(); + } + + function _putcatalog() + { + parent::_putcatalog(); + if (count($this->Outlines) > 0) { + $this->_out('/Outlines ' . $this->def_outlines . ' 0 R'); + $this->_out('/PageMode /UseOutlines'); + } + } + function SetWidths($w) + { + // column widths + $this->widths = $w; + } + + function Row($data, $links) + { + // line height + $nb = 0; + $data_cnt = count($data); + for ($i = 0;$i < $data_cnt;$i++) + $nb = max($nb, $this->NbLines($this->widths[$i], $data[$i])); + $il = $this->FontSize; + $h = ($il + 1) * $nb; + // page break if necessary + $this->CheckPageBreak($h); + // draw the cells + $data_cnt = count($data); + for ($i = 0;$i < $data_cnt;$i++) { + $w = $this->widths[$i]; + // save current position + $x = $this->GetX(); + $y = $this->GetY(); + // draw the border + $this->Rect($x, $y, $w, $h); + if (isset($links[$i])) { + $this->Link($x, $y, $w, $h, $links[$i]); + } + // print text + $this->MultiCell($w, $il + 1, $data[$i], 0, 'L'); + // go to right side + $this->SetXY($x + $w, $y); + } + // go to line + $this->Ln($h); + } + + function CheckPageBreak($h) + { + // if height h overflows, manual page break + if ($this->GetY() + $h > $this->PageBreakTrigger) { + $this->AddPage($this->CurOrientation); + } + } + + function NbLines($w, $txt) + { + // compute number of lines used by a multicell of width w + $cw = &$this->CurrentFont['cw']; + if ($w == 0) { + $w = $this->w - $this->rMargin - $this->x; + } + $wmax = ($w-2 * $this->cMargin) * 1000 / $this->FontSize; + $s = str_replace("\r", '', $txt); + $nb = strlen($s); + if ($nb > 0 and $s[$nb-1] == "\n") { + $nb--; + } + $sep = -1; + $i = 0; + $j = 0; + $l = 0; + $nl = 1; + while ($i < $nb) { + $c = $s[$i]; + if ($c == "\n") { + $i++; + $sep = -1; + $j = $i; + $l = 0; + $nl++; + continue; + } + if ($c == ' ') { + $sep = $i; + } + $l += isset($cw[ord($c)])?$cw[ord($c)]:0 ; + if ($l > $wmax) { + if ($sep == -1) { + if ($i == $j) { + $i++; + } + } else { + $i = $sep + 1; + } + $sep = -1; + $j = $i; + $l = 0; + $nl++; + } else { + $i++; + } + } + return $nl; + } +} // end of the "PMA_PDF" class + +/** + * Draws tables schema + * + * @access private + * @see PMA_RT + * @package phpMyAdmin + */ +class PMA_RT_Table { + /** + * Defines private properties + */ + var $nb_fiels; + var $table_name; + var $width = 0; + var $height; + var $fields = array(); + var $height_cell = 6; + var $x, $y; + var $primary = array(); + var $show_info = false; + + /** + * Returns title of the current table, + * title can have the dimensions of the table + * + * @access private + */ + function getTitle() + { + return ($this->show_info ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->height) : '') . ' ' . $this->table_name; + } // end of the "getTitle" function + /** + * Sets the width of the table + * + * @param integer ff The font size + * @global object The current PDF document + * @access private + * @see PMA_PDF + */ + function PMA_RT_Table_setWidth($ff) + { + global $pdf; + + foreach ($this->fields as $field) { + $this->width = max($this->width, $pdf->GetStringWidth($field)); + } + //echo $this->width.''; + print_r(get_object_vars($this)); + print ''; + exit();*/ + + if ($seen_a_relation) { + $this->PMA_RT_drawRelations($change_color); + } + + $this->PMA_RT_drawTables($change_color); + + $this->PMA_RT_showRt(); + } // end of the "PMA_RT()" Constructor method + /** + * Sets X and Y minimum and maximum for a table cell + * + * @param string table The table name + * @access private + */ + function PMA_RT_setMinMax($table) + { + $this->x_max = max($this->x_max, $table->x + $table->width); + $this->y_max = max($this->y_max, $table->y + $table->height); + $this->x_min = min($this->x_min, $table->x); + $this->y_min = min($this->y_min, $table->y); + } // end of the "PMA_RT_setMinMax()" method + /** + * Defines relation objects + * + * @param string master_table The master table name + * @param string master_field The relation field in the master table + * @param string foreign_table The foreign table name + * @param string foreign_field The relation field in the foreign table + * @param boolean show_info Whether to display table position or not + * @access private + * @see PMA_RT_setMinMax + */ + function PMA_RT_addRelation($master_table, $master_field, $foreign_table, $foreign_field, $show_info) + { + if (!isset($this->tables[$master_table])) { + $this->tables[$master_table] = new PMA_RT_Table($master_table, $this->ff, $this->_tablewidth, false, $show_info); + $this->PMA_RT_setMinMax($this->tables[$master_table]); + } + if (!isset($this->tables[$foreign_table])) { + $this->tables[$foreign_table] = new PMA_RT_Table($foreign_table, $this->ff, $this->_tablewidth, false, $show_info); + $this->PMA_RT_setMinMax($this->tables[$foreign_table]); + } + $this->relations[] = new PMA_RT_Relation($this->tables[$master_table], $master_field, $this->tables[$foreign_table], $foreign_field); + } // end of the "PMA_RT_addRelation()" method + /** + * Draws the grid + * + * @global object the current PMA_PDF instance + * @access private + * @see PMA_PDF + */ + function PMA_RT_strokeGrid() + { + global $pdf; + + $pdf->SetMargins(0, 0); + $pdf->SetDrawColor(200, 200, 200); + // Draws horizontal lines + for ($l = 0; $l < 21; $l++) { + $pdf->line(0, $l * 10, $pdf->getFh(), $l * 10); + // Avoid duplicates + if ($l > 0) { + $pdf->SetXY(0, $l * 10); + $label = (string) sprintf('%.0f', ($l * 10 - $this->t_marg) * $this->scale + $this->y_min); + $pdf->Cell(5, 5, ' ' . $label); + } // end if + } // end for + // Draws vertical lines + for ($j = 0; $j < 30 ;$j++) { + $pdf->line($j * 10, 0, $j * 10, $pdf->getFw()); + $pdf->SetXY($j * 10, 0); + $label = (string) sprintf('%.0f', ($j * 10 - $this->l_marg) * $this->scale + $this->x_min); + $pdf->Cell(5, 7, $label); + } // end for + } // end of the "PMA_RT_strokeGrid()" method + /** + * Draws relation arrows + * + * @param boolean change_color Whether to use one color per relation or not + * @access private + * @see PMA_RT_Relation::PMA_RT_Relation_draw() + */ + function PMA_RT_drawRelations($change_color) + { + $i = 0; + foreach ($this->relations as $relation) { + $relation->PMA_RT_Relation_draw($change_color, $i); + $i++; + } // end while + } // end of the "PMA_RT_drawRelations()" method + /** + * Draws tables + * + * @param boolean draw_color Whether to display table position or not + * @access private + * @see PMA_RT_Table::PMA_RT_Table_draw() + */ + function PMA_RT_drawTables($draw_color = 0) + { + foreach ($this->tables as $table) { + $table->PMA_RT_Table_draw($this->ff, $draw_color); + } + } // end of the "PMA_RT_drawTables()" method + /** + * Ouputs the PDF document to a file + * + * @global object The current PDF document + * @global string The current database name + * @global integer The current page number (from the + * $cfg['Servers'][$i]['table_coords'] table) + * @access private + * @see PMA_PDF + */ + function PMA_RT_showRt() + { + global $pdf, $db, $pdf_page_number, $cfgRelation; + + $pdf->SetFontSize(14); + $pdf->SetLineWidth(0.2); + $pdf->SetDisplayMode('fullpage'); + // Get the name of this pdfpage to use as filename (Mike Beck) + $_name_sql = 'SELECT page_descr FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages']) + . ' WHERE page_nr = ' . $pdf_page_number; + $_name_rs = PMA_query_as_controluser($_name_sql); + if ($_name_rs) { + $_name_row = PMA_DBI_fetch_row($_name_rs); + $filename = $_name_row[0] . '.pdf'; + } + // i don't know if there is a chance for this to happen, but rather be on the safe side: + if (empty($filename)) { + $filename = $pdf_page_number . '.pdf'; + } + // $pdf->Output($db . '_' . $filename, TRUE); + $pdf->Output($db . '_' . $filename, 'I'); // destination: Inline + } // end of the "PMA_RT_showRt()" method + + function PMA_RT_DOC($alltables) +{ + global $db, $pdf, $orientation, $paper; + // TOC + $pdf->addpage($GLOBALS['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 + 1) . '}', 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); + $result = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';'); + while ($row = PMA_DBI_fetch_assoc($result)) { + $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]); + } + $lasttable = $table; + $i++; + } + $pdf->PMA_links['RT']['-'] = $pdf->AddLink(); + $pdf->SetX(10); + $pdf->Cell(0, 6, __('Page number:') . ' {' . sprintf("%02d", $i + 1) . '}', 0, 0, 'R', 0, $pdf->PMA_links['doc'][$lasttable]['-']); + $pdf->SetX(10); + $pdf->Cell(0, 6, $i + 1 . ' ' . __('Relational schema'), 0, 1, 'L', 0, $pdf->PMA_links['RT']['-']); + $z = 0; + foreach ($alltables as $table) { + $z++; + $pdf->addpage($GLOBALS['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('', 'B', 18); + $pdf->Cell(0, 8, $z . ' ' . $table, 1, 1, 'C', 0, $pdf->PMA_links['RT'][$table]['-']); + $pdf->SetFont('', '', 8); + $pdf->ln(); + + $cfgRelation = PMA_getRelationsParam(); + $comments = PMA_getComments($db, $table); + if ($cfgRelation['mimework']) { + $mime_map = PMA_getMIME($db, $table, true); + } + + /** + * Gets table informations + */ + $showtable = PMA_Table::sGetStatusInfo($db, $table); + $num_rows = (isset($showtable['Rows']) ? $showtable['Rows'] : 0); + $show_comment = (isset($showtable['Comment']) ? $showtable['Comment'] : ''); + $create_time = (isset($showtable['Create_time']) ? PMA_localisedDate(strtotime($showtable['Create_time'])) : ''); + $update_time = (isset($showtable['Update_time']) ? PMA_localisedDate(strtotime($showtable['Update_time'])) : ''); + $check_time = (isset($showtable['Check_time']) ? PMA_localisedDate(strtotime($showtable['Check_time'])) : ''); + + /** + * Gets table keys and retains them + */ + $result = PMA_DBI_query('SHOW KEYS FROM ' . PMA_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 = PMA_DBI_fetch_assoc($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) { + PMA_DBI_free_result($result); + } + + /** + * Gets fields properties + */ + $result = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';', null, PMA_DBI_QUERY_STORE); + $fields_cnt = PMA_DBI_num_rows($result); + // Check if we can use Relations (Mike Beck) + if (!empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if (count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // 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('', 'B'); + if (isset($orientation) && $orientation == 'L') { + $pdf->Cell(25, 8, ucfirst(__('Column')), 1, 0, 'C'); + $pdf->Cell(20, 8, ucfirst(__('Type')), 1, 0, 'C'); + $pdf->Cell(20, 8, ucfirst(__('Attributes')), 1, 0, 'C'); + $pdf->Cell(10, 8, ucfirst(__('Null')), 1, 0, 'C'); + $pdf->Cell(20, 8, ucfirst(__('Default')), 1, 0, 'C'); + $pdf->Cell(25, 8, ucfirst(__('Extra')), 1, 0, 'C'); + $pdf->Cell(45, 8, ucfirst(__('Links to')), 1, 0, 'C'); + + if ($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, ucfirst(__('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, ucfirst(__('Column')), 1, 0, 'C'); + $pdf->Cell(20, 8, ucfirst(__('Type')), 1, 0, 'C'); + $pdf->Cell(20, 8, ucfirst(__('Attributes')), 1, 0, 'C'); + $pdf->Cell(10, 8, ucfirst(__('Null')), 1, 0, 'C'); + $pdf->Cell(15, 8, ucfirst(__('Default')), 1, 0, 'C'); + $pdf->Cell(15, 8, ucfirst(__('Extra')), 1, 0, 'C'); + $pdf->Cell(30, 8, ucfirst(__('Links to')), 1, 0, 'C'); + $pdf->Cell(30, 8, ucfirst(__('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('', ''); + + while ($row = PMA_DBI_fetch_assoc($result)) { + $type = $row['Type']; + // reformat mysql query output + // set or enum types: slashes single quotes inside options + if (preg_match('@^(set|enum)\((.+)\)$@i', $type, $tmp)) { + $tmp[2] = substr(preg_replace("@([^,])''@", "\\1\\'", ',' . $tmp[2]), 1); + $type = $tmp[1] . '(' . str_replace(',', ', ', $tmp[2]) . ')'; + $type_nowrap = ''; + + $binary = 0; + $unsigned = 0; + $zerofill = 0; + } else { + $type_nowrap = ' nowrap="nowrap"'; + $type = preg_replace('@BINARY@i', '', $type); + $type = preg_replace('@ZEROFILL@i', '', $type); + $type = preg_replace('@UNSIGNED@i', '', $type); + if (empty($type)) { + $type = ' '; + } + + $binary = stristr($row['Type'], 'BINARY'); + $unsigned = stristr($row['Type'], 'UNSIGNED'); + $zerofill = stristr($row['Type'], 'ZEROFILL'); + } + $attribute = ' '; + if ($binary) { + $attribute = 'BINARY'; + } + if ($unsigned) { + $attribute = 'UNSIGNED'; + } + if ($zerofill) { + $attribute = 'UNSIGNED ZEROFILL'; + } + 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); + $pdf_row = array($field_name, + $type, + $attribute, + ($row['Null'] == '' || $row['Null'] == 'NO') ? __('No') : __('Yes'), + ((isset($row['Default'])) ? $row['Default'] : ''), + $row['Extra'], + ((isset($res_rel[$field_name])) ? $res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['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[0] = $pdf->PMA_links['RT'][$table][$field_name]; + if (isset($res_rel[$field_name]['foreign_table']) AND + isset($res_rel[$field_name]['foreign_field']) AND + isset($pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']]) + ) + { + $links[6] = $pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']]; + } else { + unset($links[6]); + } + $pdf->Row($pdf_row, $links); + } // end while + $pdf->SetFont('', '', 14); + PMA_DBI_free_result($result); + } //end each + } +} +?> \ No newline at end of file diff --git a/libraries/schema/relation_schema.php b/libraries/schema/relation_schema.php new file mode 100644 index 000000000..e0df5935c --- /dev/null +++ b/libraries/schema/relation_schema.php @@ -0,0 +1,71 @@ +_pageTitle=$title; + } + + public function setExportType($type) + { + $this->_pageTitle=$title; + } + + public function setSameWidthTables($width) + { + $this->same_wide=$width; + } + + public function getAllTables($db,$page_number) + { + global $cfgRelation; + // Get All tables + $tab_sql = 'SELECT table_name FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND pdf_page_number = ' . $page_number; + // echo $tab_sql; + $tab_rs = PMA_query_as_controluser($tab_sql, null, PMA_DBI_QUERY_STORE); + if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) { + $this->PMA_SCHEMA_die('',__('No tables')); + } while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) { + $alltables[] = PMA_sqlAddslashes($curr_table['table_name']); + } + return $alltables; + } + + public function initTable() + { + + } + + + /** + * Displays an error message + */ + function PMA_Schema_die($type = '',$error_message = '') + { + global $db; + + require_once './libraries/header.inc.php'; + + echo "
{$type} " . __("SCHEMA ERROR") . "
" . "\n"; + if (!empty($error_message)) { + $error_message = htmlspecialchars($error_message); + } + echo '' . "\n"; + echo ' ' . $error_message . "\n"; + echo '
' . "\n"; + + echo '' . __('Back') . ''; + echo "\n"; + + require_once './libraries/footer.inc.php'; + } // end of the "PMA_PDF_die()" function +} +?> \ No newline at end of file diff --git a/libraries/schema/svg_relation_schema.php b/libraries/schema/svg_relation_schema.php new file mode 100644 index 000000000..e9a57efec --- /dev/null +++ b/libraries/schema/svg_relation_schema.php @@ -0,0 +1,127 @@ +openMemory(); + /* Set indenting using three spaces, so output is formatted */ + $this->setIndent(TRUE); + $this->setIndentString(' '); + /* Create the XML document */ + $this->startDocument('1.0','UTF-8'); + $this->startDtd('svg','-//W3C//DTD SVG 1.1//EN','http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'); + $this->endDtd(); + } + + function setTitle($title) + { + $this->title=$title; + } + + function setAuthor($author) + { + $this->author=$author; + } + + function setFont($font) + { + $this->font=$font; + } + function setFontSize($fontSize) + { + $this->fontSize=$fontSize; + } + + function startSvgDoc($width,$height) + { + + $this->startElement('svg'); + $this->writeAttribute('width', $width); + $this->writeAttribute('height', $height); + $this->writeAttribute('xmlns', 'http://www.w3.org/2000/svg'); + $this->writeAttribute('version', '1.1'); + } + + function endSvgDoc() + { + + $this->endElement(); + $this->endDocument(); + } + + function showOutput() + { + + header('Content-type: image/svg+xml'); + $output = $this->flush(); + print $output; + } + + function printElement($name,$x,$y,$width='',$height='',$text='',$styles='') + { + + $this->startElement($name); + $this->writeAttribute('width',$width); + $this->writeAttribute('height',$height); + $this->writeAttribute('x', $x); + $this->writeAttribute('y', $y); + $this->writeAttribute('style', $styles); + if(isset($text)){ + $this->writeAttribute('font-family', $this->font); + $this->writeAttribute('font-size', $this->fontSize); + $this->text($text); + } + $this->endElement(); + } +} + +class PMA_SVG_RELAION_SCHEMA extends PMA_Relation_Schema +{ + + function __construct($page_number, $show_info = 0, $change_color = 0, $all_table_same_wide = 0, $show_keys = 0) + { + //global $pdf, $db, $cfgRelation, $with_doc; + global $db,$writer; + + $svg = new PMA_SVG(); + $this->setSameWidthTables($all_table_same_wide); + + $svg->setTitle(sprintf(__('Schema of the %s database - Page %s'), $db, $page_number)); + $svg->SetAuthor('phpMyAdmin ' . PMA_VERSION); + $svg->setFont('Arial'); + $svg->setFontSize('16px'); + $svg->startSvgDoc('500px','500px'); + $svg->printElement('rect',0,0,'100','100',NULL,'fill:none;stroke:black;'); + $svg->printElement('text',100,100,'100','100','this is just a test'); + $svg->endSvgDoc(); + $svg->showOutput(); + //echo $svg->getTitle(); + /* $alltables=$this->getAllTables($db,$page_number); + foreach ($alltables AS $table) { + if (!isset($this->tables[$table])) { + $this->tables[$table] = new PMA_RT_Table($table, $this->ff, $this->_tablewidth, $show_keys, $show_info); + // $this->tables[$table]=$table; + } + + if ($this->same_wide) { + $this->tables[$table]->width = $this->_tablewidth; + } + $this->PMA_RT_setMinMax($this->tables[$table]); + }*/ + + +/* print ''; + print_r(get_object_vars($svg)); + print_r($this); + print ''; + exit();*/ + } +} +?> \ No newline at end of file diff --git a/libraries/schema/user_schema.php b/libraries/schema/user_schema.php new file mode 100644 index 000000000..af86e9117 --- /dev/null +++ b/libraries/schema/user_schema.php @@ -0,0 +1,636 @@ +_exportType='pdf'; // default export type + } + + public function setExportType($type) + { + $this->_exportType=$type; + } + + public function getExportType() + { + return $this->_exportType; + }*/ + + /** + * This function will process the user input + * + */ + public function userInputProcess($do) + { + global $action_choose,$chpage,$db,$cfgRelation,$cfg,$auto_layout_foreign,$auto_layout_internal,$newpage,$c_table_rows,$query_default_option; + // Now is the time to work on all changes + //echo $do; + if (isset($do)) { + switch ($do) { + case 'selectpage': + if ($action_choose=="1") { + $ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\''; + PMA_query_as_controluser($ch_query, FALSE, $query_default_option); + + $ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND page_nr = \'' . PMA_sqlAddslashes($chpage) . '\''; + PMA_query_as_controluser($ch_query, FALSE, $query_default_option); + + unset($chpage); + } + break; + case 'createpage': + + $pdf_page_number = PMA_REL_create_page($newpage, $cfgRelation, $db, $query_default_option); + + // A u t o m a t i c l a y o u t + // ================================ + if (isset($auto_layout_internal) || isset($auto_layout_foreign)) { + $all_tables = array(); + } + + if (isset($auto_layout_foreign)) { + // get the tables list + $tables = PMA_DBI_get_tables_full($db); + // find the ones who support FOREIGN KEY; it's not + // important that we group together InnoDB tables + // and PBXT tables, as this logic is just to put + // the tables on the layout, not to determine relations + $foreignkey_tables = array(); + foreach($tables as $table_name => $table_properties) { + if (PMA_foreignkey_supported($table_properties['ENGINE'])) { + $foreignkey_tables[] = $table_name; + } + } + $all_tables = $foreignkey_tables; + // could be improved by finding the tables which have the + // most references keys and placing them at the beginning + // of the array (so that they are all center of schema) + unset($tables, $foreignkey_tables); + } // endif auto_layout_foreign + + if (isset($auto_layout_internal)) { + // get the tables that have relations, by descending + // number of links + $master_tables = 'SELECT COUNT(master_table), master_table' + . ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation']) + . ' WHERE master_db = \'' . $db . '\'' + . ' GROUP BY master_table' + . ' ORDER BY ' . PMA_backquote('COUNT(master_table)') . ' DESC '; + $master_tables_rs = PMA_query_as_controluser($master_tables, FALSE, $query_default_option); + if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) { + // first put all the master tables at beginning + // of the list, so they are near the center of + // the schema + while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) { + $all_tables[] = $master_table; + } + + // then for each master, add its foreigns into an array + // of foreign tables, if not already there + // (a foreign might be foreign for more than + // one table, and might be a master itself) + + $foreign_tables = array(); + foreach ($all_tables as $master_table) { + $foreigners = PMA_getForeigners($db, $master_table); + foreach ($foreigners as $foreigner) { + if (!in_array($foreigner['foreign_table'], $foreign_tables)) { + $foreign_tables[] = $foreigner['foreign_table']; + } + } + } + + // then merge the arrays + foreach ($foreign_tables as $foreign_table) { + if (!in_array($foreign_table, $all_tables)) { + $all_tables[] = $foreign_table; + } + } + } // endif there are master tables + } // endif auto_layout_internal + + if (isset($auto_layout_internal) || isset($auto_layout_foreign)) { + // now generate the coordinates for the schema, + // in a clockwise spiral + + $pos_x = 300; + $pos_y = 300; + $delta = 110; + $delta_mult = 1.10; + $direction = "right"; + foreach ($all_tables as $current_table) { + + // save current table's coordinates + $insert_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' + . '(db_name, table_name, pdf_page_number, x, y) ' + . 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($current_table) . '\',' . $pdf_page_number . ',' . $pos_x . ',' . $pos_y . ')'; + PMA_query_as_controluser($insert_query, FALSE, $query_default_option); + + // compute for the next table + switch ($direction) { + case 'right': + $pos_x += $delta; + $direction = "down"; + $delta *= $delta_mult; + break; + case 'down': + $pos_y += $delta; + $direction = "left"; + $delta *= $delta_mult; + break; + case 'left': + $pos_x -= $delta; + $direction = "up"; + $delta *= $delta_mult; + break; + case 'up': + $pos_y -= $delta; + $direction = "right"; + $delta *= $delta_mult; + break; + } // end switch + } // end foreach + } // end if some auto-layout to do + + $chpage = $pdf_page_number; + + break; + + case 'edcoord': + for ($i = 0; $i < $c_table_rows; $i++) { + $arrvalue = 'c_table_' . $i; + global $$arrvalue; + $arrvalue = $$arrvalue; + if (!isset($arrvalue['x']) || $arrvalue['x'] == '') { + $arrvalue['x'] = 0; + } + if (!isset($arrvalue['y']) || $arrvalue['y'] == '') { + $arrvalue['y'] = 0; + } + if (isset($arrvalue['name']) && $arrvalue['name'] != '--') { + $test_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\'' + . ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\''; + // echo $test_query; + $test_rs = PMA_query_as_controluser($test_query, FALSE, $query_default_option); + if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) { + if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') { + $ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\'' + . ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\''; + } else { + $ch_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' + . 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y'] + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' + . ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\'' + . ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\''; + } + } else { + $ch_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' + . '(db_name, table_name, pdf_page_number, x, y) ' + . 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($arrvalue['name']) . '\', \'' . PMA_sqlAddslashes($chpage) . '\',' . $arrvalue['x'] . ',' . $arrvalue['y'] . ')'; + } + //echo $ch_query; + PMA_query_as_controluser($ch_query, FALSE, $query_default_option); + } // end if + } // end for + break; + case 'deleteCrap': + foreach ($delrow as $current_row) { + $d_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' . "\n" + . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' . "\n" + . ' AND table_name = \'' . PMA_sqlAddslashes($current_row) . '\'' . "\n" + . ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\''; + PMA_query_as_controluser($d_query, FALSE, $query_default_option); + } + break; + } // end switch + } // end if (isset($do)) + + } + + /** + * This function shows/displays the HTML FORM to create the page + * + */ + public function createPage() + { + global $db,$table; + ?> + + 0) { + ?> + + 0) { + echo "\n"; + ?> + + + + + +
'); + print_r($e); + print(''); +} +?> \ No newline at end of file