Refactor Display\Export class

- Uses template inheritance for the export templates.
- Renames Display\Export to Export\Options.

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
Maurício Meneghini Fauth 2020-08-03 23:56:20 -03:00
parent 4cbf018db3
commit 75397c913d
17 changed files with 374 additions and 401 deletions

View File

@ -7,13 +7,16 @@ namespace PhpMyAdmin\Controllers\Database;
use PhpMyAdmin\Common;
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export as DisplayExport;
use PhpMyAdmin\Export;
use PhpMyAdmin\Export\Options;
use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
use function array_merge;
use function is_array;
final class ExportController extends AbstractController
@ -121,11 +124,6 @@ final class ExportController extends AbstractController
];
}
$multi_values = $this->template->render('database/export/multi_values', [
'structure_or_data_forced' => $_POST['structure_or_data_forced'] ?? 0,
'tables' => $tablesForMultiValues,
]);
if (! isset($sql_query)) {
$sql_query = '';
}
@ -143,21 +141,38 @@ final class ExportController extends AbstractController
$export_type = 'database';
}
$displayExport = new DisplayExport();
$display = $displayExport->getDisplay(
$GLOBALS['single_table'] = $_POST['single_table'] ?? $_GET['single_table'] ?? null;
/** @var ExportPlugin[] $exportList */
$exportList = Plugins::getPlugins('export', 'libraries/classes/Plugins/Export/', [
'export_type' => $export_type,
'single_table' => isset($GLOBALS['single_table']),
]);
if (empty($exportList)) {
$this->response->addHTML(Message::error(
__('Could not load export plugins, please check your installation!')
)->getDisplay());
return;
}
$displayExport = new Options();
$options = $displayExport->getOptions(
$export_type,
$db,
$table,
$sql_query,
$num_tables,
$unlim_num_rows,
$multi_values
$exportList
);
$this->render('database/export/index', [
$this->render('database/export/index', array_merge($options, [
'page_settings_error_html' => $pageSettingsErrorHtml,
'page_settings_html' => $pageSettingsHtml,
'display' => $display,
]);
'structure_or_data_forced' => $_POST['structure_or_data_forced'] ?? 0,
'tables' => $tablesForMultiValues,
]));
}
}

View File

@ -72,7 +72,7 @@ final class ExportTemplateController extends AbstractController
$this->response->setRequestStatus(true);
$this->response->addJSON(
'data',
$this->template->render('display/export/template_options', [
$this->template->render('export/template_options', [
'templates' => is_array($templates) ? $templates : [],
'selected_template' => $_POST['template_id'] ?? null,
])

View File

@ -8,22 +8,26 @@ use PhpMyAdmin\Common;
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\Controllers\AbstractController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export;
use PhpMyAdmin\Export\Options;
use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use function array_merge;
final class ExportController extends AbstractController
{
/** @var Export */
/** @var Options */
private $export;
/**
* @param Response $response A Response instance.
* @param DatabaseInterface $dbi A DatabaseInterface instance.
* @param Template $template A Template instance.
* @param Export $export A Export instance.
* @param Options $export A Export instance.
*/
public function __construct($response, $dbi, Template $template, Export $export)
public function __construct($response, $dbi, Template $template, Options $export)
{
parent::__construct($response, $dbi, $template);
$this->export = $export;
@ -43,7 +47,7 @@ final class ExportController extends AbstractController
$this->addScriptFiles(['export.js']);
$select_item = $tmp_select ?? '';
$multi_values = $this->export->getHtmlForSelectOptions($select_item);
$databases = $this->export->getDatabasesForSelectOptions($select_item);
if (! isset($sql_query)) {
$sql_query = '';
@ -55,20 +59,36 @@ final class ExportController extends AbstractController
$unlim_num_rows = 0;
}
$display = $this->export->getDisplay(
$GLOBALS['single_table'] = $_POST['single_table'] ?? $_GET['single_table'] ?? null;
/** @var ExportPlugin[] $exportList */
$exportList = Plugins::getPlugins('export', 'libraries/classes/Plugins/Export/', [
'export_type' => 'server',
'single_table' => isset($GLOBALS['single_table']),
]);
if (empty($exportList)) {
$this->response->addHTML(Message::error(
__('Could not load export plugins, please check your installation!')
)->getDisplay());
return;
}
$options = $this->export->getOptions(
'server',
$db,
$table,
$sql_query,
$num_tables,
$unlim_num_rows,
$multi_values
$exportList
);
$this->render('server/export/index', [
$this->render('server/export/index', array_merge($options, [
'page_settings_error_html' => $pageSettingsErrorHtml,
'page_settings_html' => $pageSettingsHtml,
'display' => $display,
]);
'databases' => $databases,
]));
}
}

View File

@ -7,21 +7,24 @@ namespace PhpMyAdmin\Controllers\Table;
use PhpMyAdmin\Common;
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export;
use PhpMyAdmin\Export\Options;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Response;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\SelectStatement;
use PhpMyAdmin\SqlParser\Utils\Query;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use function array_merge;
use function implode;
use function is_array;
class ExportController extends AbstractController
{
/** @var Export */
/** @var Options */
private $export;
/**
@ -30,7 +33,7 @@ class ExportController extends AbstractController
* @param Template $template A Template instance.
* @param string $db Database name.
* @param string $table Table name.
* @param Export $export An Export instance.
* @param Options $export An Export instance.
*/
public function __construct(
$response,
@ -38,7 +41,7 @@ class ExportController extends AbstractController
Template $template,
$db,
$table,
Export $export
Options $export
) {
parent::__construct($response, $dbi, $template, $db, $table);
$this->export = $export;
@ -112,22 +115,37 @@ class ExportController extends AbstractController
$unlim_num_rows = 0;
}
$display = $this->export->getDisplay(
$GLOBALS['single_table'] = $_POST['single_table'] ?? $_GET['single_table'] ?? null;
/** @var ExportPlugin[] $exportList */
$exportList = Plugins::getPlugins('export', 'libraries/classes/Plugins/Export/', [
'export_type' => 'table',
'single_table' => isset($GLOBALS['single_table']),
]);
if (empty($exportList)) {
$this->response->addHTML(Message::error(
__('Could not load export plugins, please check your installation!')
)->getDisplay());
return;
}
$options = $this->export->getOptions(
'table',
$db,
$table,
$sql_query,
$num_tables,
$unlim_num_rows,
''
$exportList
);
$this->render('table/export/index', [
$this->render('table/export/index', array_merge($options, [
'page_settings_error_html' => $pageSettingsErrorHtml,
'page_settings_html' => $pageSettingsHtml,
'message' => $message,
'display' => $display,
]);
]));
}
public function rows(): void

View File

@ -1,22 +1,16 @@
<?php
/**
* functions for displaying server, database and table export
*/
declare(strict_types=1);
namespace PhpMyAdmin\Display;
namespace PhpMyAdmin\Export;
use PhpMyAdmin\Core;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\Export\TemplateModel;
use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Query\Utilities;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Table;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
use function explode;
use function function_exists;
@ -26,24 +20,17 @@ use function mb_strpos;
use function strlen;
use function urldecode;
/**
* PhpMyAdmin\Display\Export class
*/
class Export
final class Options
{
/** @var Relation */
private $relation;
/** @var Template */
public $template;
/** @var TemplateModel */
private $templateModel;
public function __construct()
{
$this->relation = new Relation($GLOBALS['dbi']);
$this->template = new Template();
$this->templateModel = new TemplateModel($GLOBALS['dbi']);
}
@ -65,9 +52,9 @@ class Export
*
* @param string $tmpSelect Tmp selected method of export
*
* @return string
* @return array
*/
public function getHtmlForSelectOptions($tmpSelect = '')
public function getDatabasesForSelectOptions($tmpSelect = '')
{
// Check if the selected databases are defined in $_POST
// (from clicking Back button on /export page)
@ -102,62 +89,33 @@ class Export
];
}
return $this->template->render('display/export/select_options', ['databases' => $databases]);
return $databases;
}
/**
* Gets HTML to display export dialogs
* @param string $exportType export type: server|database|table
* @param string $db selected DB
* @param string $table selected table
* @param string $sqlQuery SQL query
* @param int|string $numTables number of tables
* @param int|string $unlimNumRows unlimited number of rows
* @param ExportPlugin[] $exportList
*
* @param string $exportType export type: server|database|table
* @param string $db selected DB
* @param string $table selected table
* @param string $sqlQuery SQL query
* @param int|string $numTables number of tables
* @param int|string $unlimNumRows unlimited number of rows
* @param string $multiValues selector options
*
* @return string
* @return array<string, mixed>
*/
public function getDisplay(
public function getOptions(
$exportType,
$db,
$table,
$sqlQuery,
$numTables,
$unlimNumRows,
$multiValues
array $exportList
) {
global $cfg;
$cfgRelation = $this->relation->getRelationsParam();
if (isset($_POST['single_table'])) {
$GLOBALS['single_table'] = $_POST['single_table'];
}
// Export a single table
if (isset($_GET['single_table'])) {
$GLOBALS['single_table'] = $_GET['single_table'];
}
/* Scan for plugins */
/** @var ExportPlugin[] $exportList */
$exportList = Plugins::getPlugins(
'export',
'libraries/classes/Plugins/Export/',
[
'export_type' => $exportType,
'single_table' => isset($GLOBALS['single_table']),
]
);
/* Fail if we didn't find any plugin */
if (empty($exportList)) {
return Message::error(
__('Could not load export plugins, please check your installation!')
)->getDisplay();
}
$templates = [];
if ($cfgRelation['exporttemplateswork']) {
@ -212,7 +170,7 @@ class Export
$hiddenInputs['sql_query'] = $sqlQuery;
}
return $this->template->render('display/export/display', [
return [
'export_type' => $exportType,
'db' => $db,
'table' => $table,
@ -225,7 +183,6 @@ class Export
'hidden_inputs' => $hiddenInputs,
'export_method' => $_POST['quick_or_custom'] ?? $cfg['Export']['method'] ?? '',
'dropdown' => $dropdown,
'multi_values' => $multiValues,
'options' => Plugins::getOptions('Export', $exportList),
'can_convert_kanji' => Encoding::canConvertKanji(),
'exec_time_limit' => $cfg['ExecTimeLimit'],
@ -252,7 +209,7 @@ class Export
'has_gzip' => $cfg['GZipDump'] && function_exists('gzencode'),
'selected_compression' => $selectedCompression,
'filename_template' => $filenameTemplate,
]);
];
}
private function getFileNameTemplate(string $exportType, ?string $filename = null): string

View File

@ -63,10 +63,6 @@ return [
'relation' => '@relation',
],
],
'display_export' =>
[
'class' => PhpMyAdmin\Display\Export::class,
],
'error_handler' =>
[
'class' => PhpMyAdmin\ErrorHandler::class,
@ -97,6 +93,10 @@ return [
'arguments' =>
['@dbi'],
],
'export_options' =>
[
'class' => PhpMyAdmin\Export\Options::class,
],
'export_template_model' =>
[
'class' => PhpMyAdmin\Export\TemplateModel::class,

View File

@ -558,7 +558,7 @@ return [
'response' => '@response',
'dbi' => '@dbi',
'template' => '@template',
'export' => '@display_export',
'export' => '@export_options',
],
],
PhpMyAdmin\Controllers\Server\ImportController::class =>
@ -795,7 +795,7 @@ return [
'template' => '@template',
'db' => '%db%',
'table' => '%table%',
'export' => '@display_export',
'export' => '@export_options',
],
],
PhpMyAdmin\Controllers\Table\FindReplaceController::class =>

View File

@ -1,4 +1,63 @@
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
{% extends 'export.twig' %}
{{ display|raw }}
{% block title %}
{% if export_type == 'raw' %}
{% trans %}Exporting a raw query{% notes %}A query that the user has written freely{% endtrans %}
{% else %}
{{ 'Exporting tables from "%s" database'|trans|format(db) }}
{% endif %}
{% endblock %}
{% block selection_options %}
{% if export_type != 'raw' %}
<div class="exportoptions" id="databases_and_tables">
<h3>{% trans 'Tables:' %}</h3>
<div class="export_table_list_container">
<input type="hidden" name="structure_or_data_forced" value="{{ structure_or_data_forced }}">
<table class="export_table_select">
<thead>
<tr>
<th></th>
<th>{% trans 'Tables' %}</th>
<th class="export_structure">{% trans 'Structure' %}</th>
<th class="export_data">{% trans 'Data' %}</th>
</tr>
<tr>
<td></td>
<td class="export_table_name all">{% trans 'Select all' %}</td>
<td class="export_structure all">
<input type="checkbox" id="table_structure_all">
</td>
<td class="export_data all">
<input type="checkbox" id="table_data_all">
</td>
</tr>
</thead>
<tbody>
{% for each_table in tables %}
<tr class="marked">
<td>
<input class="checkall" type="checkbox" name="table_select[]" value="{{ each_table.name }}"{{ each_table.is_checked_select ? ' checked' }}>
</td>
<td class="export_table_name text-nowrap">{{ each_table.name }}</td>
<td class="export_structure">
<input type="checkbox" name="table_structure[]" value="{{ each_table.name }}"{{ each_table.is_checked_structure ? ' checked' }}>
</td>
<td class="export_data">
<input type="checkbox" name="table_data[]" value="{{ each_table.name }}"{{ each_table.is_checked_data ? ' checked' }}>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
{% endblock %}
{% set filename_hint %}
{% trans '@SERVER@ will become the server name and @DATABASE@ will become the database name.' %}
{% endset %}

View File

@ -1,41 +0,0 @@
<div class="export_table_list_container">
<input type="hidden" name="structure_or_data_forced" value="{{ structure_or_data_forced }}">
<table class="export_table_select">
<thead>
<tr>
<th></th>
<th>{% trans 'Tables' %}</th>
<th class="export_structure">{% trans 'Structure' %}</th>
<th class="export_data">{% trans 'Data' %}</th>
</tr>
<tr>
<td></td>
<td class="export_table_name all">{% trans 'Select all' %}</td>
<td class="export_structure all">
<input type="checkbox" id="table_structure_all">
</td>
<td class="export_data all">
<input type="checkbox" id="table_data_all">
</td>
</tr>
</thead>
<tbody>
{% for table in tables %}
<tr class="marked">
<td>
<input class="checkall" type="checkbox" name="table_select[]" value="{{ table.name }}"{{ table.is_checked_select ? ' checked' }}>
</td>
<td class="export_table_name text-nowrap">{{ table.name }}</td>
<td class="export_structure">
<input type="checkbox" name="table_structure[]" value="{{ table.name }}"{{ table.is_checked_structure ? ' checked' }}>
</td>
<td class="export_data">
<input type="checkbox" name="table_data[]" value="{{ table.name }}"{{ table.is_checked_data ? ' checked' }}>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

View File

@ -1,19 +0,0 @@
<div>
<p>
<a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', true); return false;">
{% trans 'Select all' %}
</a>
/
<a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', false); return false;">
{% trans 'Unselect all' %}
</a>
</p>
<select name="db_select[]" id="db_select" size="10" multiple>
{% for database in databases %}
<option value="{{ database.name }}"{{ database.is_selected ? ' selected' }}>
{{ database.name }}
</option>
{% endfor %}
</select>
</div>

View File

@ -1,15 +1,12 @@
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
{% block message %}{% endblock %}
<div class="exportoptions row" id="header">
<h2>
{{ get_image('b_export', 'Export'|trans) }}
{% if export_type == 'server' %}
{% trans 'Exporting databases from the current server' %}
{% elseif export_type == 'database' %}
{{ 'Exporting tables from "%s" database'|trans|format(db) }}
{% elseif export_type == 'raw' %}
{% trans %}Exporting a raw query{% notes %}A query that the user has written freely{% endtrans %}
{% else %}
{{ 'Exporting rows from "%s" table'|trans|format(table) }}
{% endif %}
{% block title %}{% endblock %}
</h2>
</div>
@ -30,10 +27,12 @@
<h4>{% trans 'Existing templates:' %}</h4>
<label for="template">{% trans 'Template:' %}</label>
<select name="template" id="template" required>
{% include 'display/export/template_options.twig' with {
'templates': templates.templates,
'selected_template': templates.selected
} only %}
<option value="">-- {% trans 'Select a template' %} --</option>
{% for template in templates.templates %}
<option value="{{ template.getId() }}"{{ template.getId() == templates.selected ? ' selected' }}>
{{ template.getName() }}
</option>
{% endfor %}
</select>
<input class="btn btn-secondary" type="submit" formaction="{{ url('/export/template/update') }}" name="updateTemplate" id="updateTemplate" value="{% trans 'Update' %}">
<input class="btn btn-secondary" type="submit" formaction="{{ url('/export/template/delete') }}" name="deleteTemplate" id="deleteTemplate" value="{% trans 'Delete' %}">
@ -96,16 +95,7 @@
{{ dropdown|raw }}
</div>
<div class="exportoptions" id="databases_and_tables">
{% if export_type == 'server' %}
<h3>{% trans 'Databases:' %}</h3>
{% elseif export_type == 'database' %}
<h3>{% trans 'Tables:' %}</h3>
{% endif %}
{% if multi_values is not empty %}
{{ multi_values|raw }}
{% endif %}
</div>
{% block selection_options %}{% endblock %}
{% if rows is not empty %}
<div class="exportoptions" id="rows">
@ -331,18 +321,7 @@
<li>
<label for="filename_template" class="desc">
{% trans 'File name template:' %}
{% set filename_hint %}
{% trans 'This value is interpreted using the \'strftime\' function, so you can use time formatting strings. Additionally the following transformations will happen:' %}
{% if export_type == 'server' %}
{% trans '@SERVER@ will become the server name.' %}
{% elseif export_type == 'database' %}
{% trans '@SERVER@ will become the server name, @DATABASE@ will become the database name.' %}
{% elseif export_type == 'table' %}
{% trans '@SERVER@ will become the server name, @DATABASE@ will become the database name, @TABLE@ will become the table name.' %}
{% endif %}
{% trans 'Other text will be kept as is. See the FAQ 6.27 for details.' %}
{% endset %}
{{ show_hint(filename_hint) }}
{{ show_hint('This value is interpreted using the \'strftime\' function, so you can use time formatting strings. Additionally the following transformations will happen: %s Other text will be kept as is. See the FAQ 6.27 for details.'|trans|format(filename_hint)) }}
</label>
<input type="text" name="filename_template" id="filename_template" value="{{ filename_template }}">
<input type="checkbox" name="remember_template" id="checkbox_remember_template"{{ is_checked_remember_file_template ? ' checked' }}>

View File

@ -1,4 +1,33 @@
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
{% extends 'export.twig' %}
{{ display|raw }}
{% block title %}{% trans 'Exporting databases from the current server' %}{% endblock %}
{% block selection_options %}
<div class="exportoptions" id="databases_and_tables">
<h3>{% trans 'Databases:' %}</h3>
<div>
<p>
<a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', true); return false;">
{% trans 'Select all' %}
</a>
/
<a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', false); return false;">
{% trans 'Unselect all' %}
</a>
</p>
<select name="db_select[]" id="db_select" size="10" multiple>
{% for database in databases %}
<option value="{{ database.name }}"{{ database.is_selected ? ' selected' }}>
{{ database.name }}
</option>
{% endfor %}
</select>
</div>
</div>
{% endblock %}
{% set filename_hint %}
{% trans '@SERVER@ will become the server name.' %}
{% endset %}

View File

@ -1,6 +1,9 @@
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
{% extends 'export.twig' %}
{{ message|raw }}
{% block message %}{{ message|raw }}{% endblock %}
{{ display|raw }}
{% block title %}{{ 'Exporting rows from "%s" table'|trans|format(table) }}{% endblock %}
{% set filename_hint %}
{% trans '@SERVER@ will become the server name, @DATABASE@ will become the database name and @TABLE@ will become the table name.' %}
{% endset %}

View File

@ -85,7 +85,7 @@ class ExportTemplateControllerTest extends AbstractTestCase
]),
];
$options = $this->template->render('display/export/template_options', [
$options = $this->template->render('export/template_options', [
'templates' => $templates,
'selected_template' => null,
]);

View File

@ -1,197 +0,0 @@
<?php
/**
* tests for PhpMyAdmin\Display\Export
*/
declare(strict_types=1);
namespace PhpMyAdmin\Tests\Display;
use PhpMyAdmin\Config;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Util;
use function htmlspecialchars;
/**
* this class is for testing PhpMyAdmin\Display\Export methods
*
* @group large
*/
class ExportTest extends AbstractTestCase
{
/** @var Export */
private $export;
/**
* Test for setUp
*/
protected function setUp(): void
{
parent::setUp();
parent::setLanguage();
parent::setGlobalConfig();
$GLOBALS['PMA_Config']->enableBc();
$GLOBALS['cfg']['Server']['host'] = 'localhost';
$GLOBALS['cfg']['Server']['user'] = 'pma_user';
$GLOBALS['server'] = 0;
$GLOBALS['table'] = 'table';
$GLOBALS['db'] = 'PMA';
//$_SESSION
$_SESSION['relation'][$GLOBALS['server']] = '';
$pmaconfig = $this->getMockBuilder(Config::class)
->disableOriginalConstructor()
->getMock();
$pmaconfig->expects($this->any())
->method('getUserValue')
->will($this->returnValue('user value for test'));
$GLOBALS['PMA_Config'] = $pmaconfig;
$this->export = new Export();
}
/**
* Test for Export::getHtmlForOptions
*/
public function testGetHtmlForOptions(): void
{
global $cfg;
$cfg['Export']['method'] = 'XML';
$cfg['SaveDir'] = '/tmp';
$export_type = 'server';
$db = 'PMA';
$table = 'PMA_test';
$multi_values_str = 'multi_values_str';
$num_tables_str = '10';
$unlim_num_rows_str = 'unlim_num_rows_str';
//$single_table = "single_table";
$GLOBALS['dbi']->getCache()->cacheTableContent([$db, $table, 'ENGINE'], 'MERGE');
$columns_info = [
'test_column1' => ['COLUMN_NAME' => 'test_column1'],
'test_column2' => ['COLUMN_NAME' => 'test_column2'],
];
$dbi = $this->getMockBuilder(DatabaseInterface::class)
->disableOriginalConstructor()
->getMock();
$dbi->expects($this->any())->method('getColumnsFull')
->will($this->returnValue($columns_info));
$dbi->expects($this->any())->method('getCompatibilities')
->will($this->returnValue([]));
$GLOBALS['dbi'] = $dbi;
//Call the test function
$html = $this->export->getDisplay(
$export_type,
$db,
$table,
'',
$num_tables_str,
$unlim_num_rows_str,
$multi_values_str
);
//validate 2: Export::getHtmlForOptionsMethod
$this->assertStringContainsString(
$cfg['Export']['method'],
$html
);
$this->assertStringContainsString(
'<div class="exportoptions" id="quick_or_custom">',
$html
);
$this->assertStringContainsString(
__('Export method:'),
$html
);
$this->assertStringContainsString(
__('Custom - display all possible options'),
$html
);
//validate 3: Export::getHtmlForOptionsSelection
$this->assertStringContainsString(
'<div class="exportoptions" id="databases_and_tables">',
$html
);
$this->assertStringContainsString(
'<h3>' . __('Databases:') . '</h3>',
$html
);
$this->assertStringContainsString(
$multi_values_str,
$html
);
//validate 4: Export::getHtmlForOptionsQuickExport
$this->assertStringContainsString(
'<input type="checkbox" name="onserver" value="saveit"',
$html
);
$dir = htmlspecialchars(Util::userDir($cfg['SaveDir']));
$this->assertStringContainsString(
'Save on server in the directory <strong>' . $dir . '</strong>',
$html
);
//validate 5: Export::getHtmlForAliasModalDialog
$this->assertStringContainsString(
'<div id="alias_modal" class="hide" title="'
. 'Rename exported databases/tables/columns">',
$html
);
$this->assertStringContainsString(
'Select database',
$html
);
$this->assertStringContainsString(
'Select table',
$html
);
$this->assertStringContainsString(
'New database name',
$html
);
$this->assertStringContainsString(
'New table name',
$html
);
$this->assertStringContainsString(
'<div id="alias_modal" class="hide" title="'
. 'Rename exported databases/tables/columns">',
$html
);
$this->assertStringContainsString('<button class="alias_remove', $html);
//validate 6: Export::getHtmlForOptionsOutput
$this->assertStringContainsString(
'<div class="exportoptions" id="output">',
$html
);
$this->assertStringContainsString(
'user value for test',
$html
);
//validate 7: Export::getHtmlForOptionsFormat
$this->assertStringContainsString(
'<div class="exportoptions" id="format">',
$html
);
$this->assertStringContainsString(
'<h3>' . __('Format:') . '</h3>',
$html
);
}
}

View File

@ -0,0 +1,150 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tests\Export;
use PhpMyAdmin\Config;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\Export\Options;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Util;
class OptionsTest extends AbstractTestCase
{
/** @var Options */
private $export;
protected function setUp(): void
{
parent::setUp();
parent::setLanguage();
parent::setGlobalConfig();
$GLOBALS['PMA_Config']->enableBc();
$GLOBALS['cfg']['Server']['host'] = 'localhost';
$GLOBALS['cfg']['Server']['user'] = 'pma_user';
$GLOBALS['server'] = 0;
$GLOBALS['table'] = 'table';
$GLOBALS['db'] = 'PMA';
//$_SESSION
$_SESSION['relation'][$GLOBALS['server']] = '';
$pmaconfig = $this->getMockBuilder(Config::class)
->disableOriginalConstructor()
->getMock();
$pmaconfig->expects($this->any())
->method('getUserValue')
->will($this->returnValue('user value for test'));
$GLOBALS['PMA_Config'] = $pmaconfig;
$this->export = new Options();
}
public function testGetOptions(): void
{
global $cfg;
$cfg['Export']['method'] = 'XML';
$cfg['SaveDir'] = '/tmp';
$cfg['ZipDump'] = false;
$cfg['GZipDump'] = false;
$export_type = 'server';
$db = 'PMA';
$table = 'PMA_test';
$num_tables_str = '10';
$unlim_num_rows_str = 'unlim_num_rows_str';
//$single_table = "single_table";
$GLOBALS['dbi']->getCache()->cacheTableContent([$db, $table, 'ENGINE'], 'MERGE');
$columns_info = [
'test_column1' => ['COLUMN_NAME' => 'test_column1'],
'test_column2' => ['COLUMN_NAME' => 'test_column2'],
];
$dbi = $this->getMockBuilder(DatabaseInterface::class)
->disableOriginalConstructor()
->getMock();
$dbi->expects($this->any())->method('getColumnsFull')
->will($this->returnValue($columns_info));
$dbi->expects($this->any())->method('getCompatibilities')
->will($this->returnValue([]));
$GLOBALS['dbi'] = $dbi;
/** @var ExportPlugin[] $exportList */
$exportList = Plugins::getPlugins('export', 'libraries/classes/Plugins/Export/', [
'export_type' => $export_type,
'single_table' => true,
]);
$dropdown = Plugins::getChoice('Export', 'what', $exportList, 'format');
//Call the test function
$actual = $this->export->getOptions(
$export_type,
$db,
$table,
'',
$num_tables_str,
$unlim_num_rows_str,
$exportList
);
$expected = [
'export_type' => $export_type,
'db' => $db,
'table' => $table,
'templates' => [
'is_enabled' => '',
'templates' => [],
'selected' => null,
],
'sql_query' => '',
'hidden_inputs' => [
'db' => $db,
'table' => $table,
'export_type' => $export_type,
'export_method' => $cfg['Export']['method'],
'template_id' => '',
],
'export_method' => $cfg['Export']['method'],
'dropdown' => $dropdown,
'options' => Plugins::getOptions('Export', $exportList),
'can_convert_kanji' => Encoding::canConvertKanji(),
'exec_time_limit' => $cfg['ExecTimeLimit'],
'rows' => [],
'has_save_dir' => true,
'save_dir' => Util::userDir($cfg['SaveDir']),
'export_is_checked' => $cfg['Export']['quick_export_onserver'],
'export_overwrite_is_checked' => $cfg['Export']['quick_export_onserver_overwrite'],
'has_aliases' => false,
'aliases' => [],
'is_checked_lock_tables' => $cfg['Export']['lock_tables'],
'is_checked_asfile' => $cfg['Export']['asfile'],
'is_checked_as_separate_files' => $cfg['Export']['as_separate_files'],
'is_checked_export' => $cfg['Export']['onserver'],
'is_checked_export_overwrite' => $cfg['Export']['onserver_overwrite'],
'is_checked_remember_file_template' => $cfg['Export']['remember_file_template'],
'repopulate' => '',
'lock_tables' => '',
'is_encoding_supported' => true,
'encodings' => Encoding::listEncodings(),
'export_charset' => $cfg['Export']['charset'],
'export_asfile' => $cfg['Export']['asfile'],
'has_zip' => $cfg['ZipDump'],
'has_gzip' => $cfg['GZipDump'],
'selected_compression' => 'none',
'filename_template' => 'user value for test',
];
$this->assertIsArray($actual);
$this->assertEquals($expected, $actual);
}
}