2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Set of functions used to build LaTeX dumps of tables
6 * @package phpMyAdmin-Export
9 if (! defined('PHPMYADMIN')) {
13 /* Messages used in default captions */
14 $GLOBALS['strLatexContent'] = __('Content of table @TABLE@');
15 $GLOBALS['strLatexContinued'] = __('(continued)');
16 $GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@');
21 if (isset($plugin_list)) {
22 $hide_structure = false;
23 if ($plugin_param['export_type'] == 'table' && !$plugin_param['single_table']) {
24 $hide_structure = true;
26 $plugin_list['latex'] = array(
27 'text' => __('LaTeX'),
29 'mime_type' => 'application/x-tex',
31 array('type' => 'begin_group', 'name' => 'general_opts'),
32 array('type' => 'bool', 'name' => 'caption', 'text' => __('Include table caption')),
33 array('type' => 'end_group')
35 'options_text' => __('Options'),
38 /* what to dump (structure/data/both) */
39 $plugin_list['latex']['options'][] =
40 array('type' => 'begin_group', 'name' => 'dump_what', 'text' => __('Dump table'));
41 $plugin_list['latex']['options'][] =
42 array('type' => 'radio', 'name' => 'structure_or_data', 'values' => array('structure' => __('structure'), 'data' => __('data'), 'structure_and_data' => __('structure and data')));
43 $plugin_list['latex']['options'][] = array('type' => 'end_group');
45 /* Structure options */
46 if (!$hide_structure) {
47 $plugin_list['latex']['options'][] =
48 array('type' => 'begin_group', 'name' => 'structure', 'text' => __('Object creation options'), 'force' => 'data');
49 $plugin_list['latex']['options'][] =
50 array('type' => 'text', 'name' => 'structure_caption', 'text' => __('Table caption'), 'doc' => 'faq6_27');
51 $plugin_list['latex']['options'][] =
52 array('type' => 'text', 'name' => 'structure_continued_caption', 'text' => __('Table caption (continued)'), 'doc' => 'faq6_27');
53 $plugin_list['latex']['options'][] =
54 array('type' => 'text', 'name' => 'structure_label', 'text' => __('Label key'), 'doc' => 'faq6_27');
55 if (!empty($GLOBALS['cfgRelation']['relation'])) {
56 $plugin_list['latex']['options'][] =
57 array('type' => 'bool', 'name' => 'relation', 'text' => __('Display foreign key relationships'));
59 $plugin_list['latex']['options'][] =
60 array('type' => 'bool', 'name' => 'comments', 'text' => __('Display comments'));
61 if (!empty($GLOBALS['cfgRelation']['mimework'])) {
62 $plugin_list['latex']['options'][] =
63 array('type' => 'bool', 'name' => 'mime', 'text' => __('Display MIME types'));
65 $plugin_list['latex']['options'][] =
66 array('type' => 'end_group');
69 $plugin_list['latex']['options'][] =
70 array('type' => 'begin_group', 'name' => 'data', 'text' => __('Data dump options'), 'force' => 'structure');
71 $plugin_list['latex']['options'][] =
72 array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row'));
73 $plugin_list['latex']['options'][] =
74 array('type' => 'text', 'name' => 'data_caption', 'text' => __('Table caption'), 'doc' => 'faq6_27');
75 $plugin_list['latex']['options'][] =
76 array('type' => 'text', 'name' => 'data_continued_caption', 'text' => __('Table caption (continued)'), 'doc' => 'faq6_27');
77 $plugin_list['latex']['options'][] =
78 array('type' => 'text', 'name' => 'data_label', 'text' => __('Label key'), 'doc' => 'faq6_27');
79 $plugin_list['latex']['options'][] =
80 array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:'));
81 $plugin_list['latex']['options'][] =
82 array('type' => 'end_group');
86 * Escapes some special characters for use in TeX/LaTeX
88 * @param string the string to convert
90 * @return string the converted string with escape codes
94 function PMA_texEscape($string) {
95 $escape = array('$', '%', '{', '}', '&', '#', '_', '^');
96 $cnt_escape = count($escape);
97 for ($k=0; $k < $cnt_escape; $k++
) {
98 $string = str_replace($escape[$k], '\\' . $escape[$k], $string);
104 * Outputs export footer
106 * @return bool Whether it suceeded
110 function PMA_exportFooter() {
115 * Outputs export header
117 * @return bool Whether it suceeded
121 function PMA_exportHeader() {
125 $head = '% phpMyAdmin LaTeX Dump' . $crlf
126 . '% version ' . PMA_VERSION
. $crlf
127 . '% http://www.phpmyadmin.net' . $crlf
129 . '% ' . __('Host') . ': ' . $cfg['Server']['host'];
130 if (!empty($cfg['Server']['port'])) {
131 $head .= ':' . $cfg['Server']['port'];
134 . '% ' . __('Generation Time') . ': ' . PMA_localisedDate() . $crlf
135 . '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION
. $crlf
136 . '% ' . __('PHP Version') . ': ' . phpversion() . $crlf;
137 return PMA_exportOutputHandler($head);
141 * Outputs database header
143 * @param string $db Database name
144 * @return bool Whether it suceeded
148 function PMA_exportDBHeader($db) {
151 . '% ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
153 return PMA_exportOutputHandler($head);
157 * Outputs database footer
159 * @param string $db Database name
160 * @return bool Whether it suceeded
164 function PMA_exportDBFooter($db) {
169 * Outputs CREATE DATABASE statement
171 * @param string $db Database name
172 * @return bool Whether it suceeded
176 function PMA_exportDBCreate($db) {
181 * Outputs the content of a table in LaTeX table/sideways table environment
183 * @param string $db database name
184 * @param string $table table name
185 * @param string $crlf the end of line sequence
186 * @param string $error_url the url to go back in case of error
187 * @param string $sql_query SQL query for obtaining data
188 * @return bool Whether it suceeded
192 function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) {
193 $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED
);
195 $columns_cnt = PMA_DBI_num_fields($result);
196 for ($i = 0; $i < $columns_cnt; $i++
) {
197 $columns[$i] = PMA_DBI_field_name($result, $i);
201 $buffer = $crlf . '%' . $crlf . '% ' . __('Data') . ': ' . $table . $crlf . '%' . $crlf
202 . ' \\begin{longtable}{|';
204 for ($index=0;$index<$columns_cnt;$index++
) {
207 $buffer .= '} ' . $crlf ;
209 $buffer .= ' \\hline \\endhead \\hline \\endfoot \\hline ' . $crlf;
210 if (isset($GLOBALS['latex_caption'])) {
211 $buffer .= ' \\caption{' . PMA_expandUserString($GLOBALS['latex_data_caption'], 'PMA_texEscape', array('table' => $table, 'database' => $db))
212 . '} \\label{' . PMA_expandUserString($GLOBALS['latex_data_label'], NULL, array('table' => $table, 'database' => $db)) . '} \\\\';
214 if (!PMA_exportOutputHandler($buffer)) {
219 if (isset($GLOBALS['latex_columns'])) {
220 $buffer = '\\hline ';
221 for ($i = 0; $i < $columns_cnt; $i++
) {
222 $buffer .= '\\multicolumn{1}{|c|}{\\textbf{' . PMA_texEscape(stripslashes($columns[$i])) . '}} & ';
225 $buffer = substr($buffer, 0, -2) . '\\\\ \\hline \hline ';
226 if (!PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) {
229 if (isset($GLOBALS['latex_caption'])) {
230 if (!PMA_exportOutputHandler('\\caption{' . PMA_expandUserString($GLOBALS['latex_data_continued_caption'], 'PMA_texEscape', array('table' => $table, 'database' => $db)) . '} \\\\ ')) return false;
232 if (!PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) {
236 if (!PMA_exportOutputHandler('\\\\ \hline')) {
241 // print the whole table
242 while ($record = PMA_DBI_fetch_assoc($result)) {
246 for ($i = 0; $i < $columns_cnt; $i++
) {
247 if (isset($record[$columns[$i]])
248 && (! function_exists('is_null') ||
!is_null($record[$columns[$i]]))) {
249 $column_value = PMA_texEscape(stripslashes($record[$columns[$i]]));
251 $column_value = $GLOBALS['latex_null'];
254 // last column ... no need for & character
255 if ($i == ($columns_cnt - 1)) {
256 $buffer .= $column_value;
258 $buffer .= $column_value . " & ";
261 $buffer .= ' \\\\ \\hline ' . $crlf;
262 if (!PMA_exportOutputHandler($buffer)) {
267 $buffer = ' \\end{longtable}' . $crlf;
268 if (!PMA_exportOutputHandler($buffer)) {
272 PMA_DBI_free_result($result);
275 } // end getTableLaTeX
278 * Outputs table's structure
280 * @param string $db database name
281 * @param string $table table name
282 * @param string $crlf the end of line sequence
283 * @param string $error_url the url to go back in case of error
284 * @param bool $do_relation whether to include relation comments
285 * @param bool $do_comments whether to include the pmadb-style column comments
286 * as comments in the structure; this is deprecated
287 * but the parameter is left here because export.php
288 * calls PMA_exportStructure() also for other export
289 * types which use this parameter
290 * @param bool $do_mime whether to include mime comments
291 * @param bool $dates whether to include creation/update/check dates
292 * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in'
293 * @param string $export_type 'server', 'database', 'table'
294 * @return bool Whether it suceeded
298 function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type)
303 * Get the unique keys in the table
305 $keys_query = 'SHOW KEYS FROM ' . PMA_backquote($table) . ' FROM '. PMA_backquote($db);
306 $keys_result = PMA_DBI_query($keys_query);
307 $unique_keys = array();
308 while ($key = PMA_DBI_fetch_assoc($keys_result)) {
309 if ($key['Non_unique'] == 0) {
310 $unique_keys[] = $key['Column_name'];
313 PMA_DBI_free_result($keys_result);
316 * Gets fields properties
318 PMA_DBI_select_db($db);
320 // Check if we can use Relations
321 if ($do_relation && !empty($cfgRelation['relation'])) {
322 // Find which tables are related with the current one and write it in
324 $res_rel = PMA_getForeigners($db, $table);
326 if ($res_rel && count($res_rel) > 0) {
336 * Displays the table structure
338 $buffer = $crlf . '%' . $crlf . '% ' . __('Structure') . ': ' . $table . $crlf . '%' . $crlf
339 . ' \\begin{longtable}{';
340 if (!PMA_exportOutputHandler($buffer)) {
345 $alignment = '|l|c|c|c|';
346 if ($do_relation && $have_rel) {
354 if ($do_mime && $cfgRelation['mimework']) {
358 $buffer = $alignment . '} ' . $crlf ;
360 $header = ' \\hline ';
361 $header .= '\\multicolumn{1}{|c|}{\\textbf{' . __('Column') . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Type') . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Null') . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Default') . '}}';
362 if ($do_relation && $have_rel) {
363 $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Links to') . '}}';
366 $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Comments') . '}}';
367 $comments = PMA_getComments($db, $table);
369 if ($do_mime && $cfgRelation['mimework']) {
370 $header .= ' & \\multicolumn{1}{|c|}{\\textbf{MIME}}';
371 $mime_map = PMA_getMIME($db, $table, true);
374 // Table caption for first page and label
375 if (isset($GLOBALS['latex_caption'])) {
376 $buffer .= ' \\caption{'. PMA_expandUserString($GLOBALS['latex_structure_caption'], 'PMA_texEscape', array('table' => $table, 'database' => $db))
377 . '} \\label{' . PMA_expandUserString($GLOBALS['latex_structure_label'], NULL, array('table' => $table, 'database' => $db))
380 $buffer .= $header . ' \\\\ \\hline \\hline' . $crlf . '\\endfirsthead' . $crlf;
381 // Table caption on next pages
382 if (isset($GLOBALS['latex_caption'])) {
383 $buffer .= ' \\caption{'. PMA_expandUserString($GLOBALS['latex_structure_continued_caption'], 'PMA_texEscape', array('table' => $table, 'database' => $db))
386 $buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf;
388 if (!PMA_exportOutputHandler($buffer)) {
392 $fields = PMA_DBI_get_columns($db, $table);
393 foreach ($fields as $row) {
394 $extracted_fieldspec = PMA_extractFieldSpec($row['Type']);
395 $type = $extracted_fieldspec['print_type'];
400 if (!isset($row['Default'])) {
401 if ($row['Null'] != 'NO') {
402 $row['Default'] = 'NULL';
406 $field_name = $row['Field'];
408 $local_buffer = $field_name . "\000" . $type . "\000"
409 . (($row['Null'] == '' ||
$row['Null'] == 'NO') ?
__('No') : __('Yes'))
410 . "\000" . (isset($row['Default']) ?
$row['Default'] : '');
412 if ($do_relation && $have_rel) {
413 $local_buffer .= "\000";
414 if (isset($res_rel[$field_name])) {
415 $local_buffer .= $res_rel[$field_name]['foreign_table'] . ' (' . $res_rel[$field_name]['foreign_field'] . ')';
418 if ($do_comments && $cfgRelation['commwork']) {
419 $local_buffer .= "\000";
420 if (isset($comments[$field_name])) {
421 $local_buffer .= $comments[$field_name];
424 if ($do_mime && $cfgRelation['mimework']) {
425 $local_buffer .= "\000";
426 if (isset($mime_map[$field_name])) {
427 $local_buffer .= str_replace('_', '/', $mime_map[$field_name]['mimetype']);
430 $local_buffer = PMA_texEscape($local_buffer);
431 if ($row['Key']=='PRI') {
432 $pos=strpos($local_buffer, "\000");
433 $local_buffer = '\\textit{' . substr($local_buffer, 0, $pos) . '}' . substr($local_buffer, $pos);
435 if (in_array($field_name, $unique_keys)) {
436 $pos=strpos($local_buffer, "\000");
437 $local_buffer = '\\textbf{' . substr($local_buffer, 0, $pos) . '}' . substr($local_buffer, $pos);
439 $buffer = str_replace("\000", ' & ', $local_buffer);
440 $buffer .= ' \\\\ \\hline ' . $crlf;
442 if (!PMA_exportOutputHandler($buffer)) {
447 $buffer = ' \\end{longtable}' . $crlf;
448 return PMA_exportOutputHandler($buffer);
449 } // end of the 'PMA_exportStructure' function