/** * This function must be named "Footer" to work with the TCPDF library * * @return void */ public function Footer() { // Check if footer for this page already exists if (!isset($this->footerset[$this->page])) { $this->SetY(-15); $this->SetFont(PMA_PDF_FONT, '', 14); $this->Cell(0, 6, __('Page number:') . ' ' . $this->getAliasNumPage() . '/' . $this->getAliasNbPages(), 'T', 0, 'C'); $this->Cell(0, 6, Util::localisedDate(), 0, 1, 'R'); $this->SetY(20); // set footerset $this->footerset[$this->page] = 1; } }
/** * Does the actual work of each specific transformations plugin. * * @param string $buffer text to be transformed * @param array $options transformation options * @param string $meta meta information * * @return string */ public function applyTransformation($buffer, $options = array(), $meta = '') { // possibly use a global transform and feed it with special options // further operations on $buffer using the $options[] array. if (empty($options[0])) { $options[0] = 0; } if (empty($options[2])) { $options[2] = 'local'; } else { $options[2] = mb_strtolower($options[2]); } if (empty($options[1])) { if ($options[2] == 'local') { $options[1] = __('%B %d, %Y at %I:%M %p'); } else { $options[1] = 'Y-m-d H:i:s'; } } $timestamp = -1; // INT columns will be treated as UNIX timestamps // and need to be detected before the verification for // MySQL TIMESTAMP if ($meta->type == 'int') { $timestamp = $buffer; // Detect TIMESTAMP(6 | 8 | 10 | 12 | 14) // TIMESTAMP (2 | 4) not supported here. // (Note: prior to MySQL 4.1, TIMESTAMP has a display size // for example TIMESTAMP(8) means YYYYMMDD) } else { if (preg_match('/^(\\d{2}){3,7}$/', $buffer)) { if (mb_strlen($buffer) == 14 || mb_strlen($buffer) == 8) { $offset = 4; } else { $offset = 2; } $aDate = array(); $aDate['year'] = (int) mb_substr($buffer, 0, $offset); $aDate['month'] = (int) mb_substr($buffer, $offset, 2); $aDate['day'] = (int) mb_substr($buffer, $offset + 2, 2); $aDate['hour'] = (int) mb_substr($buffer, $offset + 4, 2); $aDate['minute'] = (int) mb_substr($buffer, $offset + 6, 2); $aDate['second'] = (int) mb_substr($buffer, $offset + 8, 2); if (checkdate($aDate['month'], $aDate['day'], $aDate['year'])) { $timestamp = mktime($aDate['hour'], $aDate['minute'], $aDate['second'], $aDate['month'], $aDate['day'], $aDate['year']); } // If all fails, assume one of the dozens of valid strtime() syntaxes // (http://www.gnu.org/manual/tar-1.12/html_chapter/tar_7.html) } else { if (preg_match('/^[0-9]\\d{1,9}$/', $buffer)) { $timestamp = (int) $buffer; } else { $timestamp = strtotime($buffer); } } } // If all above failed, maybe it's a Unix timestamp already? if ($timestamp < 0 && preg_match('/^[1-9]\\d{1,9}$/', $buffer)) { $timestamp = $buffer; } // Reformat a valid timestamp if ($timestamp >= 0) { $timestamp -= $options[0] * 60 * 60; $source = $buffer; if ($options[2] == 'local') { $text = PMA\libraries\Util::localisedDate($timestamp, $options[1]); } elseif ($options[2] == 'utc') { $text = gmdate($options[1], $timestamp); } else { $text = 'INVALID DATE TYPE'; } $buffer = '<dfn onclick="alert(\'' . $source . '\');" title="' . $source . '">' . $text . '</dfn>'; } return $buffer; }
/** * Outputs export header * * @return bool Whether it succeeded */ public function exportHeader() { global $crlf; global $cfg; $head = '% phpMyAdmin LaTeX Dump' . $crlf . '% version ' . PMA_VERSION . $crlf . '% http://www.phpmyadmin.net' . $crlf . '%' . $crlf . '% ' . __('Host:') . ' ' . $cfg['Server']['host']; if (!empty($cfg['Server']['port'])) { $head .= ':' . $cfg['Server']['port']; } $head .= $crlf . '% ' . __('Generation Time:') . ' ' . Util::localisedDate() . $crlf . '% ' . __('Server version:') . ' ' . PMA_MYSQL_STR_VERSION . $crlf . '% ' . __('PHP Version:') . ' ' . phpversion() . $crlf; return PMA_exportOutputHandler($head); }
/** * 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 $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 bool $update_indexes_increments whether we need to update * two global variables * @param array $aliases Aliases of db/table/columns * * @return string resulting schema */ public function getTableDef($db, $table, $crlf, $error_url, $show_dates = false, $add_semicolon = true, $view = false, $update_indexes_increments = true, $aliases = array()) { global $sql_drop_table, $sql_backquotes, $sql_constraints, $sql_constraints_query, $sql_indexes, $sql_indexes_query, $sql_auto_increments, $sql_drop_foreign_keys; $db_alias = $db; $table_alias = $table; $this->initAlias($aliases, $db_alias, $table_alias); $schema_create = ''; $auto_increment = ''; $new_crlf = $crlf; if (isset($GLOBALS['sql_compatibility'])) { $compat = $GLOBALS['sql_compatibility']; } else { $compat = 'NONE'; } // need to use PMA\libraries\DatabaseInterface::QUERY_STORE // with $GLOBALS['dbi']->numRows() in mysqli $result = $GLOBALS['dbi']->query('SHOW TABLE STATUS FROM ' . Util::backquote($db) . ' WHERE Name = \'' . Util::sqlAddSlashes($table) . '\'', null, DatabaseInterface::QUERY_STORE); if ($result != false) { if ($GLOBALS['dbi']->numRows($result) > 0) { $tmpres = $GLOBALS['dbi']->fetchAssoc($result); // Here we optionally add the AUTO_INCREMENT next value, // but starting with MySQL 5.0.24, the clause is already included // in SHOW CREATE TABLE so we'll remove it below if (isset($GLOBALS['sql_auto_increment']) && !empty($tmpres['Auto_increment'])) { $auto_increment .= ' AUTO_INCREMENT=' . $tmpres['Auto_increment'] . ' '; } if ($show_dates && isset($tmpres['Create_time']) && !empty($tmpres['Create_time'])) { $schema_create .= $this->_exportComment(__('Creation:') . ' ' . Util::localisedDate(strtotime($tmpres['Create_time']))); $new_crlf = $this->_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Update_time']) && !empty($tmpres['Update_time'])) { $schema_create .= $this->_exportComment(__('Last update:') . ' ' . Util::localisedDate(strtotime($tmpres['Update_time']))); $new_crlf = $this->_exportComment() . $crlf; } if ($show_dates && isset($tmpres['Check_time']) && !empty($tmpres['Check_time'])) { $schema_create .= $this->_exportComment(__('Last check:') . ' ' . Util::localisedDate(strtotime($tmpres['Check_time']))); $new_crlf = $this->_exportComment() . $crlf; } } $GLOBALS['dbi']->freeResult($result); } $schema_create .= $new_crlf; // no need to generate a DROP VIEW here, it was done earlier if (!empty($sql_drop_table) && !$GLOBALS['dbi']->getTable($db, $table)->isView()) { $schema_create .= 'DROP TABLE IF EXISTS ' . Util::backquote($table_alias, $sql_backquotes) . ';' . $crlf; } // Complete table dump, // Whether to quote table and column names or not if ($sql_backquotes) { $GLOBALS['dbi']->query('SET SQL_QUOTE_SHOW_CREATE = 1'); } else { $GLOBALS['dbi']->query('SET SQL_QUOTE_SHOW_CREATE = 0'); } // I don't see the reason why this unbuffered query could cause problems, // because SHOW CREATE TABLE returns only one row, and we free the // results below. Nonetheless, we got 2 user reports about this // (see bug 1562533) so I removed the unbuffered mode. // $result = $GLOBALS['dbi']->query('SHOW CREATE TABLE ' . backquote($db) // . '.' . backquote($table), null, DatabaseInterface::QUERY_UNBUFFERED); // // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not // produce a displayable result for the default value of a BIT // column, nor does the mysqldump command. See MySQL bug 35796 $result = $GLOBALS['dbi']->tryQuery('SHOW CREATE TABLE ' . Util::backquote($db) . '.' . Util::backquote($table)); // an error can happen, for example the table is crashed $tmp_error = $GLOBALS['dbi']->getError(); if ($tmp_error) { return $this->_exportComment(__('in use') . '(' . $tmp_error . ')'); } // Old mode is stored so it can be restored once exporting is done. $old_mode = Context::$MODE; $warning = ''; if ($result != false && ($row = $GLOBALS['dbi']->fetchRow($result))) { $create_query = $row[1]; unset($row); // Convert end of line chars to one that we want (note that MySQL // doesn't return query it will accept in all cases) if (mb_strpos($create_query, "(\r\n ")) { $create_query = str_replace("\r\n", $crlf, $create_query); } elseif (mb_strpos($create_query, "(\n ")) { $create_query = str_replace("\n", $crlf, $create_query); } elseif (mb_strpos($create_query, "(\r ")) { $create_query = str_replace("\r", $crlf, $create_query); } /* * Drop database name from VIEW creation. * * This is a bit tricky, but we need to issue SHOW CREATE TABLE with * database name, but we don't want name to show up in CREATE VIEW * statement. */ if ($view) { $create_query = preg_replace('/' . preg_quote(Util::backquote($db)) . '\\./', '', $create_query); } // Substitute aliases in `CREATE` query. $create_query = $this->replaceWithAliases($create_query, $aliases, $db, $table, $flag); // One warning per view. if ($flag && $view) { $warning = $this->_exportComment() . $this->_exportComment(__('It appears your database uses views;')) . $this->_exportComment(__('alias export may not work reliably in all cases.')) . $this->_exportComment(); } // Adding IF NOT EXISTS, if required. if (isset($GLOBALS['sql_if_not_exists'])) { $create_query = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $create_query); } // Making the query MSSQL compatible. if ($compat == 'MSSQL') { $create_query = $this->_makeCreateTableMSSQLCompatible($create_query); } // Views have no constraints, indexes, etc. They do not require any // analysis. if (!$view) { // Using appropriate quotes. if ($compat === 'MSSQL' || $sql_backquotes === '"') { Context::$MODE |= Context::ANSI_QUOTES; } /** * Parser used for analysis. * * @var Parser */ $parser = new Parser($create_query); } if (!empty($parser->statements[0]->fields)) { /** * `CREATE TABLE` statement. * * @var SelectStatement */ $statement = $parser->statements[0]; /** * Fragments containining definition of each constraint. * * @var array */ $constraints = array(); /** * Fragments containining definition of each index. * * @var array */ $indexes = array(); /** * Fragments containining definition of each FULLTEXT index. * * @var array */ $indexes_fulltext = array(); /** * Fragments containining definition of each foreign key that will * be dropped. * * @var array */ $dropped = array(); /** * Fragment containining definition of the `AUTO_INCREMENT`. * * @var array */ $auto_increment = array(); // Scanning each field of the `CREATE` statement to fill the arrays // above. // If the field is used in any of the arrays above, it is removed // from the original definition. // Also, AUTO_INCREMENT attribute is removed. /** @var CreateDefinition $field */ foreach ($statement->fields as $key => $field) { if ($field->isConstraint) { // Creating the parts that add constraints. $constraints[] = $field::build($field); unset($statement->fields[$key]); } elseif (!empty($field->key)) { // Creating the parts that add indexes (must not be // constraints). if ($field->key->type === 'FULLTEXT KEY') { $indexes_fulltext[] = $field->build($field); unset($statement->fields[$key]); } else { if (empty($GLOBALS['sql_if_not_exists'])) { $indexes[] = $field->build($field); unset($statement->fields[$key]); } } } // Creating the parts that drop foreign keys. if (!empty($field->key)) { if ($field->key->type === 'FOREIGN KEY') { $dropped[] = 'FOREIGN KEY ' . Context::escape($field->name); unset($statement->fields[$key]); } } // Dropping AUTO_INCREMENT. if (!empty($field->options)) { if ($field->options->has('AUTO_INCREMENT') && empty($GLOBALS['sql_if_not_exists'])) { $auto_increment[] = $field::build($field); $field->options->remove('AUTO_INCREMENT'); } } } /** * The header of the `ALTER` statement (`ALTER TABLE tbl`). * * @var string */ $alter_header = 'ALTER TABLE ' . Util::backquoteCompat($table_alias, $compat, $sql_backquotes); /** * The footer of the `ALTER` statement (usually ';') * * @var string */ $alter_footer = ';' . $crlf; // Generating constraints-related query. if (!empty($constraints)) { $sql_constraints_query = $alter_header . $crlf . ' ADD ' . implode(',' . $crlf . ' ADD ', $constraints) . $alter_footer; $sql_constraints = $this->generateComment($crlf, $sql_constraints, __('Constraints for dumped tables'), __('Constraints for table'), $table_alias, $compat) . $sql_constraints_query; } // Generating indexes-related query. $sql_indexes_query = ''; if (!empty($indexes)) { $sql_indexes_query .= $alter_header . $crlf . ' ADD ' . implode(',' . $crlf . ' ADD ', $indexes) . $alter_footer; } if (!empty($indexes_fulltext)) { // InnoDB supports one FULLTEXT index creation at a time. // So FULLTEXT indexes are created one-by-one after other // indexes where created. $sql_indexes_query .= $alter_header . ' ADD ' . implode($alter_footer . $alter_header . ' ADD ', $indexes_fulltext) . $alter_footer; } if (!empty($indexes) || !empty($indexes_fulltext)) { $sql_indexes = $this->generateComment($crlf, $sql_indexes, __('Indexes for dumped tables'), __('Indexes for table'), $table_alias, $compat) . $sql_indexes_query; } // Generating drop foreign keys-related query. if (!empty($dropped)) { $sql_drop_foreign_keys = $alter_header . $crlf . ' DROP ' . implode(',' . $crlf . ' DROP ', $dropped) . $alter_footer; } // Generating auto-increment-related query. if (!empty($auto_increment) && $update_indexes_increments) { $sql_auto_increments_query = $alter_header . $crlf . ' MODIFY ' . implode(',' . $crlf . ' MODIFY ', $auto_increment); if (isset($GLOBALS['sql_auto_increment']) && $statement->entityOptions->has('AUTO_INCREMENT') !== false) { $sql_auto_increments_query .= ', AUTO_INCREMENT=' . $statement->entityOptions->has('AUTO_INCREMENT'); } $sql_auto_increments_query .= ';'; $sql_auto_increments = $this->generateComment($crlf, $sql_auto_increments, __('AUTO_INCREMENT for dumped tables'), __('AUTO_INCREMENT for table'), $table_alias, $compat) . $sql_auto_increments_query; } // Removing the `AUTO_INCREMENT` attribute from the `CREATE TABLE` // too. if (!empty($statement->entityOptions) && (empty($GLOBALS['sql_if_not_exists']) || empty($GLOBALS['sql_auto_increment']))) { $statement->entityOptions->remove('AUTO_INCREMENT'); } // Rebuilding the query. $create_query = $statement->build(); } $schema_create .= $create_query; } $GLOBALS['dbi']->freeResult($result); // Restoring old mode. Context::$MODE = $old_mode; return $warning . $schema_create . ($add_semicolon ? ';' . $crlf : ''); }
/** * Outputs export header. It is the first method to be called, so all * the required variables are initialized here. * * @return bool Whether it succeeded */ public function exportHeader() { $this->initSpecificVariables(); global $crlf, $cfg, $db; $table = $this->_getTable(); $tables = $this->_getTables(); $export_struct = isset($GLOBALS['xml_export_functions']) || isset($GLOBALS['xml_export_procedures']) || isset($GLOBALS['xml_export_tables']) || isset($GLOBALS['xml_export_triggers']) || isset($GLOBALS['xml_export_views']); $export_data = isset($GLOBALS['xml_export_contents']) ? true : false; if ($GLOBALS['output_charset_conversion']) { $charset = $GLOBALS['charset']; } else { $charset = 'utf-8'; } $head = '<?xml version="1.0" encoding="' . $charset . '"?>' . $crlf . '<!--' . $crlf . '- phpMyAdmin XML Dump' . $crlf . '- version ' . PMA_VERSION . $crlf . '- https://www.phpmyadmin.net' . $crlf . '-' . $crlf . '- ' . __('Host:') . ' ' . $cfg['Server']['host']; if (!empty($cfg['Server']['port'])) { $head .= ':' . $cfg['Server']['port']; } $head .= $crlf . '- ' . __('Generation Time:') . ' ' . Util::localisedDate() . $crlf . '- ' . __('Server version:') . ' ' . PMA_MYSQL_STR_VERSION . $crlf . '- ' . __('PHP Version:') . ' ' . phpversion() . $crlf . '-->' . $crlf . $crlf; $head .= '<pma_xml_export version="1.0"' . ($export_struct ? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"' : '') . '>' . $crlf; if ($export_struct) { $result = $GLOBALS['dbi']->fetchResult('SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`' . ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`' . ' = \'' . Util::sqlAddSlashes($db) . '\' LIMIT 1'); $db_collation = $result[0]['DEFAULT_COLLATION_NAME']; $db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME']; $head .= ' <!--' . $crlf; $head .= ' - Structure schemas' . $crlf; $head .= ' -->' . $crlf; $head .= ' <pma:structure_schemas>' . $crlf; $head .= ' <pma:database name="' . htmlspecialchars($db) . '" collation="' . $db_collation . '" charset="' . $db_charset . '">' . $crlf; if (count($tables) == 0) { $tables[] = $table; } foreach ($tables as $table) { // Export tables and views $result = $GLOBALS['dbi']->fetchResult('SHOW CREATE TABLE ' . Util::backquote($db) . '.' . Util::backquote($table), 0); $tbl = $result[$table][1]; $is_view = $GLOBALS['dbi']->getTable($db, $table)->isView(); if ($is_view) { $type = 'view'; } else { $type = 'table'; } if ($is_view && !isset($GLOBALS['xml_export_views'])) { continue; } if (!$is_view && !isset($GLOBALS['xml_export_tables'])) { continue; } $head .= ' <pma:' . $type . ' name="' . $table . '">' . $crlf; $tbl = " " . htmlspecialchars($tbl); $tbl = str_replace("\n", "\n ", $tbl); $head .= $tbl . ';' . $crlf; $head .= ' </pma:' . $type . '>' . $crlf; if (isset($GLOBALS['xml_export_triggers']) && $GLOBALS['xml_export_triggers']) { // Export triggers $triggers = $GLOBALS['dbi']->getTriggers($db, $table); if ($triggers) { foreach ($triggers as $trigger) { $code = $trigger['create']; $head .= ' <pma:trigger name="' . $trigger['name'] . '">' . $crlf; // Do some formatting $code = mb_substr(rtrim($code), 0, -3); $code = " " . htmlspecialchars($code); $code = str_replace("\n", "\n ", $code); $head .= $code . $crlf; $head .= ' </pma:trigger>' . $crlf; } unset($trigger); unset($triggers); } } } if (isset($GLOBALS['xml_export_functions']) && $GLOBALS['xml_export_functions']) { // Export functions $functions = $GLOBALS['dbi']->getProceduresOrFunctions($db, 'FUNCTION'); if ($functions) { foreach ($functions as $function) { $head .= ' <pma:function name="' . $function . '">' . $crlf; // Do some formatting $sql = $GLOBALS['dbi']->getDefinition($db, 'FUNCTION', $function); $sql = rtrim($sql); $sql = " " . htmlspecialchars($sql); $sql = str_replace("\n", "\n ", $sql); $head .= $sql . $crlf; $head .= ' </pma:function>' . $crlf; } unset($function); unset($functions); } } if (isset($GLOBALS['xml_export_procedures']) && $GLOBALS['xml_export_procedures']) { // Export procedures $procedures = $GLOBALS['dbi']->getProceduresOrFunctions($db, 'PROCEDURE'); if ($procedures) { foreach ($procedures as $procedure) { $head .= ' <pma:procedure name="' . $procedure . '">' . $crlf; // Do some formatting $sql = $GLOBALS['dbi']->getDefinition($db, 'PROCEDURE', $procedure); $sql = rtrim($sql); $sql = " " . htmlspecialchars($sql); $sql = str_replace("\n", "\n ", $sql); $head .= $sql . $crlf; $head .= ' </pma:procedure>' . $crlf; } unset($procedure); unset($procedures); } } if (isset($GLOBALS['xml_export_events']) && $GLOBALS['xml_export_events']) { // Export events $events = $GLOBALS['dbi']->fetchResult("SELECT EVENT_NAME FROM information_schema.EVENTS " . "WHERE EVENT_SCHEMA='" . Util::sqlAddslashes($db) . "'"); if ($events) { foreach ($events as $event) { $head .= ' <pma:event name="' . $event . '">' . $crlf; $sql = $GLOBALS['dbi']->getDefinition($db, 'EVENT', $event); $sql = rtrim($sql); $sql = " " . htmlspecialchars($sql); $sql = str_replace("\n", "\n ", $sql); $head .= $sql . $crlf; $head .= ' </pma:event>' . $crlf; } unset($event); unset($events); } } unset($result); $head .= ' </pma:database>' . $crlf; $head .= ' </pma:structure_schemas>' . $crlf; if ($export_data) { $head .= $crlf; } } return PMA_exportOutputHandler($head); }
/** * 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']) ? Util::localisedDate(strtotime($showtable['Create_time'])) : ''; $update_time = isset($showtable['Update_time']) ? Util::localisedDate(strtotime($showtable['Update_time'])) : ''; $check_time = isset($showtable['Check_time']) ? Util::localisedDate(strtotime($showtable['Check_time'])) : ''; /** * Gets fields properties */ $columns = $GLOBALS['dbi']->getColumns($this->db, $table); // Find which tables are related with the current one and write it in // an array $res_rel = PMA_getForeigners($this->db, $table); /** * 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 = 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 }