aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/templates
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-01-09 10:55:03 +0100
committerCharles <sircharlesaze@gmail.com>2020-01-09 13:09:38 +0100
commit04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch)
tree5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/templates
parent7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff)
downloadft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.gz
ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.bz2
ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.zip
phpmyadmin working
Diffstat (limited to 'srcs/phpmyadmin/templates')
-rw-r--r--srcs/phpmyadmin/templates/changelog.twig15
-rw-r--r--srcs/phpmyadmin/templates/checkbox.twig6
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig16
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig21
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig246
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig7
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_comment.twig6
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_default.twig35
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig155
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_extra.twig7
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig24
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_length.twig11
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_name.twig42
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_null.twig8
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_type.twig8
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig32
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/mime_type.twig17
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/move_column.twig15
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/partitions.twig180
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig122
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/transformation.twig26
-rw-r--r--srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig9
-rw-r--r--srcs/phpmyadmin/templates/components/error_message.twig4
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/errors.twig6
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig14
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig17
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/form_bottom.twig1
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/group_header.twig5
-rw-r--r--srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig1
-rw-r--r--srcs/phpmyadmin/templates/console/bookmark_content.twig25
-rw-r--r--srcs/phpmyadmin/templates/console/display.twig192
-rw-r--r--srcs/phpmyadmin/templates/console/query_action.twig12
-rw-r--r--srcs/phpmyadmin/templates/console/toolbar.twig10
-rw-r--r--srcs/phpmyadmin/templates/create_tracking_version.twig79
-rw-r--r--srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig9
-rw-r--r--srcs/phpmyadmin/templates/database/central_columns/main.twig418
-rw-r--r--srcs/phpmyadmin/templates/database/create_table.twig23
-rw-r--r--srcs/phpmyadmin/templates/database/data_dictionary/index.twig65
-rw-r--r--srcs/phpmyadmin/templates/database/designer/database_tables.twig121
-rw-r--r--srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig13
-rw-r--r--srcs/phpmyadmin/templates/database/designer/main.twig1105
-rw-r--r--srcs/phpmyadmin/templates/database/designer/page_save_as.twig37
-rw-r--r--srcs/phpmyadmin/templates/database/designer/page_selector.twig10
-rw-r--r--srcs/phpmyadmin/templates/database/designer/schema_export.twig9
-rw-r--r--srcs/phpmyadmin/templates/database/multi_table_query/form.twig184
-rw-r--r--srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig11
-rw-r--r--srcs/phpmyadmin/templates/database/qbe/footer_options.twig16
-rw-r--r--srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig10
-rw-r--r--srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig9
-rw-r--r--srcs/phpmyadmin/templates/database/search/main.twig84
-rw-r--r--srcs/phpmyadmin/templates/database/search/results.twig62
-rw-r--r--srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig95
-rw-r--r--srcs/phpmyadmin/templates/database/structure/check_all_tables.twig40
-rw-r--r--srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig7
-rw-r--r--srcs/phpmyadmin/templates/database/structure/index.twig24
-rw-r--r--srcs/phpmyadmin/templates/database/structure/show_create.twig31
-rw-r--r--srcs/phpmyadmin/templates/database/structure/show_create_row.twig19
-rw-r--r--srcs/phpmyadmin/templates/database/structure/structure_table_row.twig223
-rw-r--r--srcs/phpmyadmin/templates/database/structure/table_header.twig78
-rw-r--r--srcs/phpmyadmin/templates/database/structure/tracking_icon.twig7
-rw-r--r--srcs/phpmyadmin/templates/database/tracking/tables.twig161
-rw-r--r--srcs/phpmyadmin/templates/display/export/format_dropdown.twig4
-rw-r--r--srcs/phpmyadmin/templates/display/export/hidden_inputs.twig23
-rw-r--r--srcs/phpmyadmin/templates/display/export/method.twig22
-rw-r--r--srcs/phpmyadmin/templates/display/export/option_header.twig12
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_format.twig24
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output.twig54
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_charset.twig16
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_compression.twig24
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_format.twig13
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_radio.twig7
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig15
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig12
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_quick_export.twig20
-rw-r--r--srcs/phpmyadmin/templates/display/export/options_rows.twig35
-rw-r--r--srcs/phpmyadmin/templates/display/export/select_options.twig19
-rw-r--r--srcs/phpmyadmin/templates/display/export/selection.twig10
-rw-r--r--srcs/phpmyadmin/templates/display/export/template_loading.twig27
-rw-r--r--srcs/phpmyadmin/templates/display/export/template_options.twig7
-rw-r--r--srcs/phpmyadmin/templates/display/import/import.twig195
-rw-r--r--srcs/phpmyadmin/templates/display/import/javascript.twig162
-rw-r--r--srcs/phpmyadmin/templates/display/results/comment_for_row.twig10
-rw-r--r--srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig9
-rw-r--r--srcs/phpmyadmin/templates/display/results/empty_display.twig1
-rw-r--r--srcs/phpmyadmin/templates/display/results/null_display.twig7
-rw-r--r--srcs/phpmyadmin/templates/display/results/options_block.twig121
-rw-r--r--srcs/phpmyadmin/templates/display/results/page_selector.twig6
-rw-r--r--srcs/phpmyadmin/templates/display/results/sort_by_key.twig9
-rw-r--r--srcs/phpmyadmin/templates/display/results/table.twig11
-rw-r--r--srcs/phpmyadmin/templates/display/results/table_headers.twig23
-rw-r--r--srcs/phpmyadmin/templates/display/results/table_navigation.twig82
-rw-r--r--srcs/phpmyadmin/templates/display/results/table_navigation_button.twig12
-rw-r--r--srcs/phpmyadmin/templates/display/results/value_display.twig3
-rw-r--r--srcs/phpmyadmin/templates/div_for_slider_effect.twig16
-rw-r--r--srcs/phpmyadmin/templates/dropdown.twig11
-rw-r--r--srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig20
-rw-r--r--srcs/phpmyadmin/templates/error/generic.twig40
-rw-r--r--srcs/phpmyadmin/templates/error/report_form.twig32
-rw-r--r--srcs/phpmyadmin/templates/export/alias_add.twig49
-rw-r--r--srcs/phpmyadmin/templates/export/alias_item.twig10
-rw-r--r--srcs/phpmyadmin/templates/filter.twig8
-rw-r--r--srcs/phpmyadmin/templates/fk_checkbox.twig4
-rw-r--r--srcs/phpmyadmin/templates/footer.twig24
-rw-r--r--srcs/phpmyadmin/templates/gis_data_editor_form.twig221
-rw-r--r--srcs/phpmyadmin/templates/header.twig66
-rw-r--r--srcs/phpmyadmin/templates/header_location.twig22
-rw-r--r--srcs/phpmyadmin/templates/home/index.twig203
-rw-r--r--srcs/phpmyadmin/templates/javascript/display.twig7
-rw-r--r--srcs/phpmyadmin/templates/list/item.twig19
-rw-r--r--srcs/phpmyadmin/templates/list/unordered.twig14
-rw-r--r--srcs/phpmyadmin/templates/login/footer.twig4
-rw-r--r--srcs/phpmyadmin/templates/login/header.twig16
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor.twig7
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/application.twig4
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/application_configure.twig17
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/invalid.twig3
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig5
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/key.twig5
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/key_configure.twig5
-rw-r--r--srcs/phpmyadmin/templates/login/twofactor/simple.twig1
-rw-r--r--srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig29
-rw-r--r--srcs/phpmyadmin/templates/navigation/main.twig98
-rw-r--r--srcs/phpmyadmin/templates/navigation/tree/database_select.twig22
-rw-r--r--srcs/phpmyadmin/templates/navigation/tree/path.twig12
-rw-r--r--srcs/phpmyadmin/templates/navigation/tree/state.twig16
-rw-r--r--srcs/phpmyadmin/templates/preferences/autoload.twig15
-rw-r--r--srcs/phpmyadmin/templates/preferences/forms/main.twig8
-rw-r--r--srcs/phpmyadmin/templates/preferences/manage/error.twig20
-rw-r--r--srcs/phpmyadmin/templates/preferences/manage/main.twig112
-rw-r--r--srcs/phpmyadmin/templates/preferences/two_factor/configure.twig11
-rw-r--r--srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig12
-rw-r--r--srcs/phpmyadmin/templates/preferences/two_factor/main.twig60
-rw-r--r--srcs/phpmyadmin/templates/preview_sql.twig11
-rw-r--r--srcs/phpmyadmin/templates/radio_fields.twig11
-rw-r--r--srcs/phpmyadmin/templates/rte/routines/parameter_row.twig54
-rw-r--r--srcs/phpmyadmin/templates/scripts.twig24
-rw-r--r--srcs/phpmyadmin/templates/secondary_tabs.twig6
-rw-r--r--srcs/phpmyadmin/templates/select_all.twig6
-rw-r--r--srcs/phpmyadmin/templates/select_lang.twig32
-rw-r--r--srcs/phpmyadmin/templates/server/binlog/index.twig107
-rw-r--r--srcs/phpmyadmin/templates/server/collations/index.twig32
-rw-r--r--srcs/phpmyadmin/templates/server/databases/index.twig323
-rw-r--r--srcs/phpmyadmin/templates/server/engines/index.twig27
-rw-r--r--srcs/phpmyadmin/templates/server/engines/show.twig48
-rw-r--r--srcs/phpmyadmin/templates/server/plugins/index.twig58
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig8
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig9
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/column_privileges.twig24
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig17
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig26
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig22
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/initials_row.twig26
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig104
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/require_options.twig32
-rw-r--r--srcs/phpmyadmin/templates/server/privileges/resource_limits.twig21
-rw-r--r--srcs/phpmyadmin/templates/server/replication/change_master.twig35
-rw-r--r--srcs/phpmyadmin/templates/server/replication/database_multibox.twig9
-rw-r--r--srcs/phpmyadmin/templates/server/replication/index.twig36
-rw-r--r--srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig84
-rw-r--r--srcs/phpmyadmin/templates/server/replication/master_configuration.twig32
-rw-r--r--srcs/phpmyadmin/templates/server/replication/master_replication.twig52
-rw-r--r--srcs/phpmyadmin/templates/server/replication/slave_configuration.twig109
-rw-r--r--srcs/phpmyadmin/templates/server/replication/status_table.twig34
-rw-r--r--srcs/phpmyadmin/templates/server/status/advisor/index.twig39
-rw-r--r--srcs/phpmyadmin/templates/server/status/base.twig39
-rw-r--r--srcs/phpmyadmin/templates/server/status/monitor/index.twig268
-rw-r--r--srcs/phpmyadmin/templates/server/status/processes/index.twig53
-rw-r--r--srcs/phpmyadmin/templates/server/status/processes/list.twig65
-rw-r--r--srcs/phpmyadmin/templates/server/status/queries/index.twig56
-rw-r--r--srcs/phpmyadmin/templates/server/status/status/index.twig78
-rw-r--r--srcs/phpmyadmin/templates/server/status/variables/index.twig137
-rw-r--r--srcs/phpmyadmin/templates/server/sub_page_header.twig16
-rw-r--r--srcs/phpmyadmin/templates/server/variables/index.twig78
-rw-r--r--srcs/phpmyadmin/templates/setup/base.twig48
-rw-r--r--srcs/phpmyadmin/templates/setup/config/index.twig29
-rw-r--r--srcs/phpmyadmin/templates/setup/error.twig19
-rw-r--r--srcs/phpmyadmin/templates/setup/form/index.twig8
-rw-r--r--srcs/phpmyadmin/templates/setup/home/index.twig121
-rw-r--r--srcs/phpmyadmin/templates/setup/servers/index.twig16
-rw-r--r--srcs/phpmyadmin/templates/sql/bookmark.twig31
-rw-r--r--srcs/phpmyadmin/templates/sql/detailed_table.twig8
-rw-r--r--srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig6
-rw-r--r--srcs/phpmyadmin/templates/sql/profiling_chart.twig97
-rw-r--r--srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig4
-rw-r--r--srcs/phpmyadmin/templates/sql/set_column.twig5
-rw-r--r--srcs/phpmyadmin/templates/sql/sql_query_results.twig10
-rw-r--r--srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig20
-rw-r--r--srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig12
-rw-r--r--srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig5
-rw-r--r--srcs/phpmyadmin/templates/table/chart/tbl_chart.twig159
-rw-r--r--srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig80
-rw-r--r--srcs/phpmyadmin/templates/table/index_form.twig223
-rw-r--r--srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig19
-rw-r--r--srcs/phpmyadmin/templates/table/operations/view.twig31
-rw-r--r--srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig22
-rw-r--r--srcs/phpmyadmin/templates/table/relation/common_form.twig223
-rw-r--r--srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig9
-rw-r--r--srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig136
-rw-r--r--srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig18
-rw-r--r--srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig3
-rw-r--r--srcs/phpmyadmin/templates/table/search/fields_table.twig33
-rw-r--r--srcs/phpmyadmin/templates/table/search/form_tag.twig4
-rw-r--r--srcs/phpmyadmin/templates/table/search/geom_func.twig19
-rw-r--r--srcs/phpmyadmin/templates/table/search/input_box.twig97
-rw-r--r--srcs/phpmyadmin/templates/table/search/replace_preview.twig39
-rw-r--r--srcs/phpmyadmin/templates/table/search/rows_normal.twig39
-rw-r--r--srcs/phpmyadmin/templates/table/search/rows_zoom.twig74
-rw-r--r--srcs/phpmyadmin/templates/table/search/selection_form.twig226
-rw-r--r--srcs/phpmyadmin/templates/table/search/zoom_result_form.twig86
-rw-r--r--srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig31
-rw-r--r--srcs/phpmyadmin/templates/table/structure/display_partitions.twig145
-rw-r--r--srcs/phpmyadmin/templates/table/structure/display_structure.twig516
-rw-r--r--srcs/phpmyadmin/templates/table/structure/display_table_stats.twig169
-rw-r--r--srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig14
-rw-r--r--srcs/phpmyadmin/templates/table/tracking/main.twig132
-rw-r--r--srcs/phpmyadmin/templates/table/tracking/report_table.twig27
-rw-r--r--srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig56
-rw-r--r--srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig33
-rw-r--r--srcs/phpmyadmin/templates/test/add_data.twig2
-rw-r--r--srcs/phpmyadmin/templates/test/echo.twig1
-rw-r--r--srcs/phpmyadmin/templates/test/gettext/gettext.twig1
-rw-r--r--srcs/phpmyadmin/templates/test/gettext/notes.twig5
-rw-r--r--srcs/phpmyadmin/templates/test/gettext/pgettext.twig5
-rw-r--r--srcs/phpmyadmin/templates/test/gettext/plural.twig5
-rw-r--r--srcs/phpmyadmin/templates/test/gettext/plural_notes.twig7
-rw-r--r--srcs/phpmyadmin/templates/test/static.twig1
-rw-r--r--srcs/phpmyadmin/templates/theme_preview.twig16
-rw-r--r--srcs/phpmyadmin/templates/themes.twig7
-rw-r--r--srcs/phpmyadmin/templates/toggle_button.twig24
-rw-r--r--srcs/phpmyadmin/templates/transformation_overview.twig49
-rw-r--r--srcs/phpmyadmin/templates/view_create.twig120
231 files changed, 12081 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/templates/changelog.twig b/srcs/phpmyadmin/templates/changelog.twig
new file mode 100644
index 0000000..cdda84f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/changelog.twig
@@ -0,0 +1,15 @@
+<!doctype html>
+<html lang="en" dir="ltr">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="icon" href="favicon.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
+ <title>phpMyAdmin - ChangeLog</title>
+</head>
+<body>
+<h1>phpMyAdmin - ChangeLog</h1>
+<pre>{{ changelog|raw }}</pre>
+</body>
+</html>
diff --git a/srcs/phpmyadmin/templates/checkbox.twig b/srcs/phpmyadmin/templates/checkbox.twig
new file mode 100644
index 0000000..2b29f7e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/checkbox.twig
@@ -0,0 +1,6 @@
+<input type="checkbox" name="{{ html_field_name }}"
+{%- if html_field_id is defined %} id="{{ html_field_id }}"{% endif -%}
+{%- if checked is defined and checked %} checked="checked"{% endif -%}
+{%- if onclick is defined and onclick %} class="autosubmit"{% endif %}><label
+{%- if html_field_id is defined %} for="{{ html_field_id }}"
+{%- endif %}>{{ label }}</label>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig b/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig
new file mode 100644
index 0000000..d0d1e91
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig
@@ -0,0 +1,16 @@
+{% if privs_available %}
+ <input name="field_adjust_privileges[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ checked="checked"
+ type="checkbox"
+ value="NULL"
+ class="allow_null">
+{% else %}
+ <input name="field_adjust_privileges[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ disabled
+ type="checkbox"
+ value="NULL"
+ class="allow_null"
+ title="{% trans "You don't have sufficient privileges to perform this operation; Please refer to the documentation for more details" %}">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig b/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig
new file mode 100644
index 0000000..905d093
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig
@@ -0,0 +1,21 @@
+{% if submit_attribute is defined and submit_attribute != false %}
+ {% set attribute = submit_attribute %}
+{% elseif column_meta['Extra'] is defined
+ and column_meta['Extra'] == 'on update CURRENT_TIMESTAMP' %}
+ {% set attribute = 'on update CURRENT_TIMESTAMP' %}
+{% elseif extracted_columnspec['attribute'] is defined %}
+ {% set attribute = extracted_columnspec['attribute'] %}
+{% else %}
+ {% set attribute = '' %}
+{% endif %}
+{% set attribute = attribute|upper %}
+<select name="field_attribute[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}">
+ {% set cnt_attribute_types = attribute_types|length - 1 %}
+ {% for i in 0..cnt_attribute_types %}
+ <option value="{{ attribute_types[i] }}"
+ {{- attribute == attribute_types[i]|upper ? ' selected="selected"' }}>
+ {{ attribute_types[i] }}
+ </option>
+ {% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig b/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig
new file mode 100644
index 0000000..89eef86
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig
@@ -0,0 +1,246 @@
+{# Cell index: If certain fields get left out, the counter shouldn't change. #}
+{% set ci = 0 %}
+
+{# Every time a cell shall be left out the STRG-jumping feature, $ci_offset has
+ to be incremented ($ci_offset++) #}
+{% set ci_offset = -1 %}
+
+<td class="center">
+ {# column name #}
+ {% include 'columns_definitions/column_name.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'cfg_relation': cfg_relation,
+ 'max_rows': max_rows
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column type #}
+ {% include 'columns_definitions/column_type.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'type_upper': type_upper
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column length #}
+ {% include 'columns_definitions/column_length.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'length_values_input_size': length_values_input_size,
+ 'length_to_display': length
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column default #}
+ {% include 'columns_definitions/column_default.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'type_upper': type_upper,
+ 'default_value': default_value,
+ 'char_editing': char_editing
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column collation #}
+ <select lang="en" dir="ltr" name="field_collation[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}">
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}"
+ {{- collation.name == column_meta['Collation'] ? ' selected' }}>
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column attribute #}
+ {% include 'columns_definitions/column_attribute.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'extracted_columnspec': extracted_columnspec,
+ 'submit_attribute': submit_attribute,
+ 'attribute_types': attribute_types
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column NULL #}
+ {% include 'columns_definitions/column_null.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+{% if change_column is defined and change_column is not empty %}
+ {# column Adjust privileges, Only for 'Edit' Column(s) #}
+ <td class="center">
+ {% include 'columns_definitions/column_adjust_privileges.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'privs_available': privs_available
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+{% endif %}
+{% if not is_backup %}
+ {# column indexes, See my other comment about this 'if'. #}
+ <td class="center">
+ {% include 'columns_definitions/column_indexes.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+{% endif %}
+<td class="center">
+ {# column auto_increment #}
+ {% include 'columns_definitions/column_auto_increment.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+<td class="center">
+ {# column comments #}
+ {% include 'columns_definitions/column_comment.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'max_length': max_length,
+ 'value': column_meta['Field'] is defined
+ and comments_map is iterable
+ and comments_map[column_meta['Field']] is defined
+ ? comments_map[column_meta['Field']]|e
+ } only %}
+ {% set ci = ci + 1 %}
+</td>
+ {# column virtuality #}
+{% if is_virtual_columns_supported %}
+ <td class="center">
+ {% include 'columns_definitions/column_virtuality.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'char_editing': char_editing,
+ 'expression': column_meta['Expression'] is defined ? column_meta['Expression'],
+ 'options': options
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+{% endif %}
+{# move column #}
+{% if fields_meta is defined %}
+ {% set current_index = 0 %}
+ {% set cols = move_columns|length - 1 %}
+ {% set break = false %}
+ {% for mi in 0..cols %}
+ {% if move_columns[mi].name == column_meta['Field'] and not break %}
+ {% set current_index = mi %}
+ {% set break = true %}
+ {% endif %}
+ {% endfor %}
+
+ <td class="center">
+ {% include 'columns_definitions/move_column.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'move_columns': move_columns,
+ 'current_index': current_index
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+{% endif %}
+
+{% if cfg_relation['mimework'] and browse_mime and cfg_relation['commwork'] %}
+ <td class="center">
+ {# Column Mime-type #}
+ {% include 'columns_definitions/mime_type.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'available_mime': available_mime,
+ 'mime_map': mime_map
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+ <td class="center">
+ {# Column Browser transformation #}
+ {% include 'columns_definitions/transformation.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'available_mime': available_mime,
+ 'mime_map': mime_map,
+ 'type': 'transformation'
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+ <td class="center">
+ {# column Transformation options #}
+ {% include 'columns_definitions/transformation_option.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'mime_map': mime_map,
+ 'type_prefix': ''
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+ <td class="center">
+ {# Column Input transformation #}
+ {% include 'columns_definitions/transformation.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'available_mime': available_mime,
+ 'mime_map': mime_map,
+ 'type': 'input_transformation'
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+ <td class="center">
+ {# column Input transformation options #}
+ {% include 'columns_definitions/transformation_option.twig' with {
+ 'column_number': column_number,
+ 'ci': ci,
+ 'ci_offset': ci_offset,
+ 'column_meta': column_meta,
+ 'mime_map': mime_map,
+ 'type_prefix': 'input_'
+ } only %}
+ {% set ci = ci + 1 %}
+ </td>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig b/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig
new file mode 100644
index 0000000..46bfb42
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig
@@ -0,0 +1,7 @@
+<input name="field_extra[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ {% if column_meta['Extra'] is defined and column_meta['Extra']|lower == 'auto_increment' -%}
+ checked="checked"
+ {%- endif %}
+ type="checkbox"
+ value="AUTO_INCREMENT">
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig b/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig
new file mode 100644
index 0000000..653441b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig
@@ -0,0 +1,6 @@
+<textarea id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ rows="1"
+ name="field_comments[{{ column_number }}]"
+ maxlength="{{ max_length }}">
+ {{- value|raw -}}
+</textarea>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_default.twig b/srcs/phpmyadmin/templates/columns_definitions/column_default.twig
new file mode 100644
index 0000000..dcb6644
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_default.twig
@@ -0,0 +1,35 @@
+{# here we put 'NONE' as the default value of drop-down; otherwise users would
+have problems if they forget to enter the default value (example, for an INT) #}
+{% set translation %}{% trans %}None{% context %}for default{% endtrans %}{% endset %}
+{% set default_options = {
+ 'NONE': translation,
+ 'USER_DEFINED': 'As defined:'|trans,
+ 'NULL': 'NULL',
+ 'CURRENT_TIMESTAMP': 'CURRENT_TIMESTAMP'
+} %}
+
+<select name="field_default_type[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ class="default_type">
+ {% for key, value in default_options %}
+ <option value="{{ key }}"
+ {%- if column_meta['DefaultType'] is defined
+ and column_meta['DefaultType'] == key %}
+ selected="selected"
+ {%- endif %}>
+ {{ value }}
+ </option>
+ {% endfor %}
+</select>
+{% if char_editing == 'textarea' %}
+ <textarea name="field_default_value[{{ column_number }}]"
+ cols="15"
+ class="textfield
+ default_value">{{ default_value }}</textarea>
+{% else %}
+ <input type="text"
+ name="field_default_value[{{ column_number }}]"
+ size="12"
+ value="{{ default_value }}"
+ class="textfield default_value">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig b/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig
new file mode 100644
index 0000000..1fd4b64
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig
@@ -0,0 +1,155 @@
+<form method="post" action="{{ action }}" class="
+ {{- action == 'tbl_create.php' ? 'create_table' : 'append_fields' -}}
+ _form ajax lock-page">
+ {{ get_hidden_inputs(form_params) }}
+ {# happens when an index has been set on a column #}
+ {# and a column is added to the table creation dialog #}
+ {# This contains a JSON-encoded string #}
+ <input type="hidden" name="primary_indexes" value="
+ {{- primary_indexes is not empty ? primary_indexes : '[]' }}">
+ <input type="hidden" name="unique_indexes" value="
+ {{- unique_indexes is not empty ? unique_indexes : '[]' }}">
+ <input type="hidden" name="indexes" value="
+ {{- indexes is not empty ? indexes : '[]' }}">
+ <input type="hidden" name="fulltext_indexes" value="
+ {{- fulltext_indexes is not empty ? fulltext_indexes : '[]' }}">
+ <input type="hidden" name="spatial_indexes" value="
+ {{- spatial_indexes is not empty ? spatial_indexes : '[]' }}">
+
+ {% if action == 'tbl_create.php' %}
+ <div id="table_name_col_no_outer">
+ <table id="table_name_col_no" class="tdblock">
+ <tr class="vmiddle floatleft">
+ <td>{% trans 'Table name' %}:
+ <input type="text"
+ name="table"
+ size="40"
+ maxlength="64"
+ value="{{ table is defined ? table }}"
+ class="textfield" autofocus required>
+ </td>
+ <td>
+ {% trans 'Add' %}
+ <input type="number"
+ id="added_fields"
+ name="added_fields"
+ size="2"
+ value="1"
+ min="1"
+ onfocus="this.select()">
+ {% trans 'column(s)' %}
+ <input class="btn btn-secondary" type="button"
+ name="submit_num_fields"
+ value="{% trans 'Go' %}">
+ </td>
+ </tr>
+ </table>
+ </div>
+ {% endif %}
+ {% if content_cells is iterable %}
+ {% include 'columns_definitions/table_fields_definitions.twig' with {
+ 'is_backup': is_backup,
+ 'fields_meta': fields_meta,
+ 'mimework': mimework,
+ 'content_cells': content_cells,
+ 'change_column': change_column,
+ 'is_virtual_columns_supported': is_virtual_columns_supported,
+ 'browse_mime': browse_mime,
+ 'server_type': server_type,
+ 'max_rows': max_rows,
+ 'char_editing': char_editing,
+ 'attribute_types': attribute_types,
+ 'privs_available': privs_available,
+ 'max_length': max_length,
+ 'charsets': charsets
+ } only %}
+ {% endif %}
+ {% if action == 'tbl_create.php' %}
+ <div class="responsivetable">
+ <table>
+ <tr class="vtop">
+ <th>{% trans 'Table comments:' %}</th>
+ <td width="25">&nbsp;</td>
+ <th>{% trans 'Collation:' %}</th>
+ <td width="25">&nbsp;</td>
+ <th>
+ {% trans 'Storage Engine:' %}
+ {{ show_mysql_docu('Storage_engines') }}
+ </th>
+ <td width="25">&nbsp;</td>
+ <th>
+ {% trans 'Connection:' %}
+ {{ show_mysql_docu('federated-create-connection') }}
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <input type="text"
+ name="comment"
+ size="40"
+ maxlength="60"
+ value="{{ comment is defined ? comment }}"
+ class="textfield">
+ </td>
+ <td width="25">&nbsp;</td>
+ <td>
+ <select lang="en" dir="ltr" name="tbl_collation">
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}"
+ {{- collation.name == tbl_collation ? ' selected' }}>
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ </td>
+ <td width="25">&nbsp;</td>
+ <td>
+ {{ get_html_select(
+ 'tbl_storage_engine',
+ null,
+ tbl_storage_engine
+ ) }}
+ </td>
+ <td width="25">&nbsp;</td>
+ <td>
+ <input type="text"
+ name="connection"
+ size="40"
+ value="{{ connection is defined ? connection }}"
+ placeholder="scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name"
+ class="textfield"
+ required="required">
+ </td>
+ </tr>
+ {% if have_partitioning %}
+ <tr class="vtop">
+ <th colspan="5">
+ {% trans 'PARTITION definition:' %}
+ {{ show_mysql_docu('Partitioning') }}
+ </th>
+ </tr>
+ <tr>
+ <td colspan="5">
+ {% include 'columns_definitions/partitions.twig' with {
+ 'partition_details': partition_details
+ } only %}
+ </td>
+ </tr>
+ {% endif %}
+ </table>
+ </div>
+ {% endif %}
+ <fieldset class="tblFooters">
+ <input class="btn btn-secondary preview_sql" type="button"
+ value="{% trans 'Preview SQL' %}">
+ <input class="btn btn-primary" type="submit"
+ name="do_save_data"
+ value="{% trans 'Save' %}">
+ </fieldset>
+ <div id="properties_message"></div>
+</form>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig b/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig
new file mode 100644
index 0000000..7f61f5c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig
@@ -0,0 +1,7 @@
+<input name="col_extra[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ {% if column_meta['Extra'] is not empty and column_meta['Extra'] == 'auto_increment' -%}
+ checked="checked"
+ {%- endif %}
+ type="checkbox"
+ value="auto_increment">
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig b/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig
new file mode 100644
index 0000000..3980229
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig
@@ -0,0 +1,24 @@
+<select name="field_key[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}" data-index="">
+ <option value="none_{{ column_number }}">---</option>
+ <option value="primary_{{ column_number }}" title="{% trans "Primary" %}"
+ {{- column_meta['Key'] is defined and column_meta['Key'] == 'PRI' ? ' selected="selected"' }}>
+ PRIMARY
+ </option>
+ <option value="unique_{{ column_number }}" title="{% trans "Unique" %}"
+ {{- column_meta['Key'] is defined and column_meta['Key'] == 'UNI' ? ' selected="selected"' }}>
+ UNIQUE
+ </option>
+ <option value="index_{{ column_number }}" title="{% trans "Index" %}"
+ {{- column_meta['Key'] is defined and column_meta['Key'] == 'MUL' ? ' selected="selected"' }}>
+ INDEX
+ </option>
+ <option value="fulltext_{{ column_number }}" title="{% trans "Fulltext" %}"
+ {{- column_meta['Key'] is defined and column_meta['Key'] == 'FULLTEXT' ? ' selected="selected"' }}>
+ FULLTEXT
+ </option>
+ <option value="spatial_{{ column_number }}" title="{% trans "Spatial" %}"
+ {{- column_meta['Key'] is defined and column_meta['Key'] == 'SPATIAL' ? ' selected="selected"' }}>
+ SPATIAL
+ </option>
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_length.twig b/srcs/phpmyadmin/templates/columns_definitions/column_length.twig
new file mode 100644
index 0000000..ef7e5f0
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_length.twig
@@ -0,0 +1,11 @@
+<input id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ type="text"
+ name="field_length[{{ column_number }}]"
+ size="{{ length_values_input_size }}"
+ value="{{ length_to_display }}"
+ class="textfield">
+<p class="enum_notice" id="enum_notice_{{ column_number }}_{{ ci - ci_offset }}">
+ <a href="#" class="open_enum_editor">
+ {% trans 'Edit ENUM/SET values' %}
+ </a>
+</p>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_name.twig b/srcs/phpmyadmin/templates/columns_definitions/column_name.twig
new file mode 100644
index 0000000..a0a31ad
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_name.twig
@@ -0,0 +1,42 @@
+{% set title = '' %}
+{% if column_meta['column_status'] is defined %}
+ {% if column_meta['column_status']['isReferenced'] %}
+ {% set title = title ~ 'Referenced by %s.'|trans|format(
+ column_meta['column_status']['references']|join(',')
+ ) %}
+ {% endif %}
+ {% if column_meta['column_status']['isForeignKey'] %}
+ {% if title is not empty %}
+ {% set title = title ~ '\n'|raw %}
+ {% endif %}
+ {% set title = title ~ 'Is a foreign key.'|trans %}
+ {% endif %}
+{% endif %}
+{% if title is empty %}
+ {% set title = 'Column'|trans %}
+{% endif %}
+
+<input id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ {% if column_meta['column_status'] is defined
+ and not column_meta['column_status']['isEditable'] %}
+ disabled="disabled"
+ {% endif %}
+ type="text"
+ name="field_name[{{ column_number }}]"
+ maxlength="64"
+ class="textfield"
+ title="{{ title }}"
+ size="10"
+ value="{{ column_meta['Field'] is defined ? column_meta['Field'] }}">
+
+{% if cfg_relation['centralcolumnswork']
+ and not (column_meta['column_status'] is defined
+ and not column_meta['column_status']['isEditable']) %}
+ <p class="column_name" id="central_columns_{{ column_number }}_{{ ci - ci_offset }}">
+ <a data-maxrows="{{ max_rows }}"
+ href="#"
+ class="central_columns_dialog">
+ {% trans 'Pick from Central Columns' %}
+ </a>
+ </p>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_null.twig b/srcs/phpmyadmin/templates/columns_definitions/column_null.twig
new file mode 100644
index 0000000..5afd649
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_null.twig
@@ -0,0 +1,8 @@
+<input name="field_null[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ {% if column_meta['Null'] is not empty and column_meta['Null'] != 'NO' and column_meta['Null'] != 'NOT NULL' -%}
+ checked="checked"
+ {%- endif %}
+ type="checkbox"
+ value="YES"
+ class="allow_null">
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_type.twig b/srcs/phpmyadmin/templates/columns_definitions/column_type.twig
new file mode 100644
index 0000000..e74eb0e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_type.twig
@@ -0,0 +1,8 @@
+<select class="column_type"
+ name="field_type[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ {%- if column_meta['column_status'] is defined and not column_meta['column_status']['isEditable'] -%}
+ disabled="disabled"
+ {%- endif %}>
+ {{ get_supported_datatypes(true, type_upper) }}
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig b/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig
new file mode 100644
index 0000000..96f020e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig
@@ -0,0 +1,32 @@
+<select name="field_virtuality[{{ column_number }}]"
+ id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ class="virtuality">
+ {% for key, value in options %}
+ <option value="{{ key }}"
+ {% set key_length = key|length %}
+ {%- if column_meta['Extra'] is defined
+ and key != ''
+ and column_meta['Extra']|slice(0,key_length) is same as (key) %}
+ selected="selected"
+ {%- endif %}>
+ {{ value }}
+ </option>
+ {% endfor %}
+</select>
+
+{% if char_editing == 'textarea' %}
+ {% apply spaceless %}
+ <textarea name="field_expression[{{ column_number }}]"
+ cols="15"
+ class="textfield expression">
+ {{ expression }}
+ </textarea>
+ {% endapply %}
+{% else %}
+ <input type="text"
+ name="field_expression[{{ column_number }}]"
+ size="12"
+ value="{{ expression }}"
+ placeholder="{% trans 'Expression' %}"
+ class="textfield expression">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig b/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig
new file mode 100644
index 0000000..ef395b6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig
@@ -0,0 +1,17 @@
+<select id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ size="1"
+ name="field_mimetype[{{ column_number }}]">
+ <option value="">&nbsp;</option>
+ {% if available_mime['mimetype'] is defined
+ and available_mime['mimetype'] is iterable %}
+ {% for mimetype in available_mime['mimetype'] %}
+ {% set checked = column_meta['Field'] is defined
+ and mime_map[column_meta['Field']]['mimetype'] is defined
+ and mime_map[column_meta['Field']]['mimetype'] == mimetype|replace({'/': '_'})
+ ? ' selected' %}
+ <option value="{{ mimetype|replace({'/': '_'}) }}"{{ checked }}>
+ {{ mimetype|lower }}
+ </option>
+ {% endfor %}
+ {% endif %}
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/move_column.twig b/srcs/phpmyadmin/templates/columns_definitions/move_column.twig
new file mode 100644
index 0000000..7c0b3f4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/move_column.twig
@@ -0,0 +1,15 @@
+<select id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ name="field_move_to[{{ column_number }}]"
+ size="1"
+ width="5em">
+ <option value="" selected="selected">&nbsp;</option>
+ <option value="-first"{{ current_index == 0 ? ' disabled="disabled"' }}>
+ {% trans 'first' %}
+ </option>
+ {% for mi in 0..move_columns|length - 1 %}
+ <option value="{{ move_columns[mi].name }}"
+ {{- current_index == mi or current_index == mi + 1 ? ' disabled="disabled"' }}>
+ {{ 'after %s'|trans|format(backquote(move_columns[mi].name|e)) }}
+ </option>
+ {% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/partitions.twig b/srcs/phpmyadmin/templates/columns_definitions/partitions.twig
new file mode 100644
index 0000000..b8c88af
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/partitions.twig
@@ -0,0 +1,180 @@
+{% set partition_options = [
+ '',
+ 'HASH',
+ 'LINEAR HASH',
+ 'KEY',
+ 'LINEAR KEY',
+ 'RANGE',
+ 'RANGE COLUMNS',
+ 'LIST',
+ 'LIST COLUMNS'
+] %}
+{% set sub_partition_options = ['', 'HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY'] %}
+{% set value_type_options = ['', 'LESS THAN', 'LESS THAN MAXVALUE', 'IN'] %}
+
+<table id="partition_table">
+ <tr class="vmiddle">
+ <td><label for="partition_by">{% trans 'Partition by:' %}</label></td>
+ <td>
+ <select name="partition_by" id="partition_by">
+ {% for option in partition_options %}
+ <option value="{{ option }}"
+ {%- if partition_details['partition_by'] == option %}
+ selected="selected"
+ {%- endif %}>
+ {{ option }}
+ </option>
+ {% endfor %}
+ </select>
+ </td>
+ <td>
+ (<input name="partition_expr" type="text"
+ placeholder="{% trans 'Expression or column list' %}"
+ value="{{ partition_details['partition_expr'] }}">)
+ </td>
+ </tr>
+ <tr class="vmiddle">
+ <td><label for="partition_count">{% trans 'Partitions:' %}</label></td>
+ <td colspan="2">
+ <input name="partition_count" type="number" min="2"
+ value="{{ partition_details['partition_count'] }}">
+ </td>
+ </tr>
+ {% if partition_details['can_have_subpartitions'] %}
+ <tr class="vmiddle">
+ <td><label for="subpartition_by">{% trans 'Subpartition by:' %}</label></td>
+ <td>
+ <select name="subpartition_by" id="subpartition_by">
+ {% for option in sub_partition_options %}
+ <option value="{{ option }}"
+ {%- if partition_details['subpartition_by'] == option %}
+ selected="selected"
+ {%- endif %}>
+ {{ option }}
+ </option>
+ {% endfor %}
+ </select>
+ </td>
+ <td>
+ (<input name="subpartition_expr" type="text"
+ placeholder="{% trans 'Expression or column list' %}"
+ value="{{ partition_details['subpartition_expr'] }}">)
+ </td>
+ </tr>
+ <tr class="vmiddle">
+ <td><label for="subpartition_count">{% trans 'Subpartitions:' %}</label></td>
+ <td colspan="2">
+ <input name="subpartition_count" type="number" min="2"
+ value="{{ partition_details['subpartition_count'] }}">
+ </td>
+ </tr>
+ {% endif %}
+</table>
+{% if partition_details['partition_count'] > 1 %}
+ <table id="partition_definition_table">
+ <thead><tr>
+ <th>{% trans 'Partition' %}</th>
+ {% if partition_details['value_enabled'] %}
+ <th>{% trans 'Values' %}</th>
+ {% endif %}
+ {% if partition_details['can_have_subpartitions']
+ and partition_details['subpartition_count'] > 1 %}
+ <th>{% trans 'Subpartition' %}</th>
+ {% endif %}
+ <th>{% trans 'Engine' %}</th>
+ <th>{% trans 'Comment' %}</th>
+ <th>{% trans 'Data directory' %}</th>
+ <th>{% trans 'Index directory' %}</th>
+ <th>{% trans 'Max rows' %}</th>
+ <th>{% trans 'Min rows' %}</th>
+ <th>{% trans 'Table space' %}</th>
+ <th>{% trans 'Node group' %}</th>
+ </tr></thead>
+ {% for partition in partition_details['partitions'] %}
+ {% set rowspan = partition['subpartition_count'] is not empty
+ ? partition['subpartition_count'] + 1 : 2 %}
+ <tr>
+ <td rowspan="{{ rowspan }}">
+ <input type="text" name="{{ partition['prefix'] }}[name]"
+ value="{{ partition['name'] }}">
+ </td>
+ {% if partition_details['value_enabled'] %}
+ <td rowspan="{{ rowspan }}" class="vmiddle">
+ <select class="partition_value"
+ name="{{ partition['prefix'] }}[value_type]">
+ {% for option in value_type_options %}
+ <option value="{{ option }}"
+ {%- if partition['value_type'] == option %}
+ selected="selected"
+ {%- endif %}>
+ {{ option }}
+ </option>
+ {% endfor %}
+ </select>
+ <input type="text" class="partition_value"
+ name="{{ partition['prefix'] }}[value]"
+ value="{{ partition['value'] }}">
+ </td>
+ {% endif %}
+ </tr>
+
+ {% if partition['subpartitions'] is defined %}
+ {% set subpartitions = partition['subpartitions'] %}
+ {% else %}
+ {% set subpartitions = [partition] %}
+ {% endif %}
+
+ {% for subpartition in subpartitions %}
+ <tr>
+ {% if partition_details['can_have_subpartitions']
+ and partition_details['subpartition_count'] > 1 %}
+ <td>
+ <input type="text" name="{{ subpartition['prefix'] }}[name]"
+ value="{{ subpartition['name'] }}">
+ </td>
+ {% endif %}
+ <td>
+ {{ get_html_select(
+ subpartition['prefix'] ~ '[engine]',
+ null,
+ subpartition['engine'],
+ false,
+ true
+ ) }}
+ </td>
+ <td>
+ {% apply spaceless %}
+ <textarea name="{{ subpartition['prefix'] }}[comment]">
+ {{ subpartition['comment'] }}
+ </textarea>
+ {% endapply %}
+ </td>
+ <td>
+ <input type="text" name="{{ subpartition['prefix'] }}[data_directory]"
+ value="{{ subpartition['data_directory'] }}">
+ </td>
+ <td>
+ <input type="text" name="{{ subpartition['prefix'] }}[index_directory]"
+ value="{{ subpartition['index_directory'] }}">
+ </td>
+ <td>
+ <input type="number" name="{{ subpartition['prefix'] }}[max_rows]"
+ value="{{ subpartition['max_rows'] }}">
+ </td>
+ <td>
+ <input type="number" min="0" name="{{ subpartition['prefix'] }}[min_rows]"
+ value="{{ subpartition['min_rows'] }}">
+ </td>
+ <td>
+ <input type="text" min="0" name="{{ subpartition['prefix'] }}[tablespace]"
+ value="{{ subpartition['tablespace'] }}">
+ </td>
+ <td>
+ <input type="text" name="{{ subpartition['prefix'] }}[node_group]"
+ value="{{ subpartition['node_group'] }}">
+ </td>
+ </tr>
+ {% endfor %}
+ {% endfor %}
+ </table>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig b/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig
new file mode 100644
index 0000000..f23b2fe
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig
@@ -0,0 +1,122 @@
+<div class="responsivetable">
+<table id="table_columns" class="noclick">
+ <caption class="tblHeaders">
+ {% trans 'Structure' %}
+ {{ show_mysql_docu('CREATE_TABLE') }}
+ </caption>
+ <tr>
+ <th>
+ {% trans 'Name' %}
+ </th>
+ <th>
+ {% trans 'Type' %}
+ {{ show_mysql_docu('data-types') }}
+ </th>
+ <th>
+ {% trans 'Length/Values' %}
+ {{ show_hint('If column type is "enum" or "set", please enter the values using this format: \'a\',\'b\',\'c\'…<br>If you ever need to put a backslash ("\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }}
+ </th>
+ <th>
+ {% trans 'Default' %}
+ {{ show_hint('For default values, please enter just a single value, without backslash escaping or quotes, using this format: a'|trans) }}
+ </th>
+ <th>
+ {% trans 'Collation' %}
+ </th>
+ <th>
+ {% trans 'Attributes' %}
+ </th>
+ <th>
+ {% trans 'Null' %}
+ </th>
+
+ {# Only for 'Edit' Column(s) #}
+ {% if change_column is defined and change_column is not empty %}
+ <th>
+ {% trans 'Adjust privileges' %}
+ {{ show_docu('faq', 'faq6-39') }}
+ </th>
+ {% endif %}
+
+ {# We could remove this 'if' and let the key information be shown and
+ editable. However, for this to work, structure.lib.php must be
+ modified to use the key fields, as tbl_addfield does. #}
+ {% if not is_backup %}
+ <th>
+ {% trans 'Index' %}
+ </th>
+ {% endif %}
+
+ <th>
+ <abbr title="AUTO_INCREMENT">A_I</abbr>
+ </th>
+ <th>
+ {% trans 'Comments' %}
+ </th>
+
+ {% if is_virtual_columns_supported %}
+ <th>
+ {% trans 'Virtuality' %}
+ </th>
+ {% endif %}
+
+ {% if fields_meta is defined %}
+ <th>
+ {% trans 'Move column' %}
+ </th>
+ {% endif %}
+
+ {% if mimework and browse_mime %}
+ <th>
+ {% trans 'Media (MIME) type' %}
+ </th>
+ <th>
+ <a href="transformation_overview.php
+ {{- get_common() }}#transformation" title="
+ {%- trans 'List of available transformations and their options' -%}
+ " target="_blank">
+ {% trans 'Browser display transformation' %}
+ </a>
+ </th>
+ <th>
+ {% trans 'Browser display transformation options' %}
+ {{ show_hint('Please enter the values for transformation options using this format: \'a\', 100, b,\'c\'…<br>If you ever need to put a backslash ("\\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }}
+ </th>
+ <th>
+ <a href="transformation_overview.php{{ get_common() }}#input_transformation"
+ title="{% trans 'List of available transformations and their options' %}"
+ target="_blank">
+ {% trans 'Input transformation' %}
+ </a>
+ </th>
+ <th>
+ {% trans 'Input transformation options' %}
+ {{ show_hint('Please enter the values for transformation options using this format: \'a\', 100, b,\'c\'…<br>If you ever need to put a backslash ("\\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }}
+ </th>
+ {% endif %}
+ </tr>
+ {% set options = {'': '', 'VIRTUAL': 'VIRTUAL'} %}
+ {% if server_type == 'MariaDB' %}
+ {% set options = options|merge({'PERSISTENT': 'PERSISTENT'}) %}
+ {% set options = options|merge({'STORED': 'STORED'}) %}
+ {% else %}
+ {% set options = options|merge({'STORED': 'STORED'}) %}
+ {% endif %}
+ {% for content_row in content_cells %}
+ <tr>
+ {% include 'columns_definitions/column_attributes.twig' with content_row|merge({
+ 'options': options,
+ 'change_column': change_column,
+ 'is_virtual_columns_supported': is_virtual_columns_supported,
+ 'browse_mime': browse_mime,
+ 'max_rows': max_rows,
+ 'char_editing': char_editing,
+ 'attribute_types': attribute_types,
+ 'privs_available': privs_available,
+ 'max_length': max_length,
+ 'charsets': charsets
+ }) only %}
+ </tr>
+ {% endfor %}
+</table>
+</div>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/transformation.twig b/srcs/phpmyadmin/templates/columns_definitions/transformation.twig
new file mode 100644
index 0000000..9aec94a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/transformation.twig
@@ -0,0 +1,26 @@
+<select id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ size="1"
+ name="field_{{ type }}[{{ column_number }}]">
+ <option value="" title="{% trans 'None' %}"></option>
+ {% if available_mime[type] is defined and available_mime[type] is iterable %}
+ {% for mimekey, transform in available_mime[type] %}
+ {% set checked = column_meta['Field'] is defined
+ and mime_map[column_meta['Field']][type] is defined
+ and mime_map[column_meta['Field']][type] matches
+ '@' ~ available_mime[type ~ '_file_quoted'][mimekey] ~ '3?@i'
+ ? 'selected ' %}
+ {% set tooltip = get_description(
+ available_mime[type ~ '_file'][mimekey]
+ ) %}
+ {% set parts = transform|split(':') %}
+ {% set name = get_name(
+ available_mime[type ~ '_file'][mimekey]
+ ) ~ ' (' ~ parts[0]|lower ~ ':' ~ parts[1] ~ ')' %}
+ <option value="{{ available_mime[type ~ '_file'][mimekey] }}"
+ {{ checked }}
+ title="{{ tooltip }}">
+ {{ name }}
+ </option>
+ {% endfor %}
+ {% endif %}
+</select>
diff --git a/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig b/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig
new file mode 100644
index 0000000..f87ba7c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig
@@ -0,0 +1,9 @@
+{% set options_key = type_prefix ~ 'transformation_options' %}
+<input id="field_{{ column_number }}_{{ ci - ci_offset }}"
+ type="text"
+ name="field_{{ options_key }}[{{ column_number }}]"
+ size="16"
+ class="textfield"
+ value="{% if column_meta['Field'] is defined and mime_map[column_meta['Field']][options_key] is defined -%}
+ {{- mime_map[column_meta['Field']][options_key] -}}
+ {%- endif %}">
diff --git a/srcs/phpmyadmin/templates/components/error_message.twig b/srcs/phpmyadmin/templates/components/error_message.twig
new file mode 100644
index 0000000..5b964c3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/components/error_message.twig
@@ -0,0 +1,4 @@
+<div class="error">
+ <img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">
+ {{ msg }}
+</div>
diff --git a/srcs/phpmyadmin/templates/config/form_display/errors.twig b/srcs/phpmyadmin/templates/config/form_display/errors.twig
new file mode 100644
index 0000000..b243ce4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/errors.twig
@@ -0,0 +1,6 @@
+<dl>
+ <dt>{{ name }}</dt>
+ {% for error in error_list %}
+ <dd>{{ error|raw }}</dd>
+ {% endfor %}
+</dl>
diff --git a/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig
new file mode 100644
index 0000000..1c8d570
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig
@@ -0,0 +1,14 @@
+{% set colspan = 2 %}
+{% if is_setup %}
+ {% set colspan = colspan + 1 %}
+{% endif %}
+{% if show_buttons %}
+ <tr>
+ <td colspan="{{ colspan }}" class="lastrow">
+ <input class="btn btn-primary green" type="submit" name="submit_save" value="{% trans 'Apply' %}">
+ <input class="btn btn-secondary" type="button" name="submit_reset" value="{% trans 'Reset' %}">
+ </td>
+ </tr>
+{% endif %}
+</table>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig b/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig
new file mode 100644
index 0000000..e359e92
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig
@@ -0,0 +1,17 @@
+<fieldset
+ {%- for key, value in attributes -%}
+ {{- ' ' }}{{ key }}="{{ value }}"
+ {%- endfor %}>
+<legend>{{ title }}</legend>
+{% if description is not empty %}
+ <p>{{ description|raw }}</p>
+{% endif %}
+{# This must match with displayErrors() in scripts.js #}
+{% if errors is iterable and errors|length > 0 %}
+ <dl class="errors">
+ {% for error in errors %}
+ <dd>{{ error }}</dd>
+ {% endfor %}
+ </dl>
+{% endif %}
+<table width="100%" cellspacing="0">
diff --git a/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig
new file mode 100644
index 0000000..5582354
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig
@@ -0,0 +1 @@
+</form>
diff --git a/srcs/phpmyadmin/templates/config/form_display/group_header.twig b/srcs/phpmyadmin/templates/config/form_display/group_header.twig
new file mode 100644
index 0000000..47f1388
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/group_header.twig
@@ -0,0 +1,5 @@
+<tr class="group-header group-header-{{ group }}">
+ <th colspan="{{ colspan }}">
+ {{ header_text }}
+ </th>
+</tr>
diff --git a/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig
new file mode 100644
index 0000000..04f5b84
--- /dev/null
+++ b/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig
@@ -0,0 +1 @@
+</div>
diff --git a/srcs/phpmyadmin/templates/console/bookmark_content.twig b/srcs/phpmyadmin/templates/console/bookmark_content.twig
new file mode 100644
index 0000000..259edbf
--- /dev/null
+++ b/srcs/phpmyadmin/templates/console/bookmark_content.twig
@@ -0,0 +1,25 @@
+<div class="message welcome">
+ <span>{{ welcome_message }}</span>
+</div>
+{% for bookmark in bookmarks %}
+ <div class="message collapsed bookmark" bookmarkid="{{ bookmark.getId() }}"
+ targetdb="{{ bookmark.getDatabase() }}">
+ {% include 'console/query_action.twig' with {
+ 'parent_div_classes': 'action_content',
+ 'content_array': [
+ ['action collapse', 'Collapse'|trans],
+ ['action expand', 'Expand'|trans],
+ ['action requery', 'Requery'|trans],
+ ['action edit_bookmark', 'Edit'|trans],
+ ['action delete_bookmark', 'Delete'|trans],
+ {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': bookmark.getDatabase()}
+ ]
+ } only %}
+ <span class="bookmark_label{{ bookmark.getUser() is empty ? ' shared' }}">
+ {{ bookmark.getLabel() }}
+ </span>
+ <span class="query">
+ {{ bookmark.getQuery() }}
+ </span>
+ </div>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/console/display.twig b/srcs/phpmyadmin/templates/console/display.twig
new file mode 100644
index 0000000..3d54c9e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/console/display.twig
@@ -0,0 +1,192 @@
+<div id="pma_console_container">
+ <div id="pma_console">
+ {# Console toolbar #}
+ {% include 'console/toolbar.twig' with {
+ 'parent_div_classes': 'collapsed',
+ 'content_array': [
+ {0: 'switch_button console_switch', 1: 'Console'|trans, 'image': image},
+ ['button clear', 'Clear'|trans],
+ ['button history', 'History'|trans],
+ ['button options', 'Options'|trans],
+ cfg_bookmark is defined ? ['button bookmarks', 'Bookmarks'|trans] : null,
+ ['button debug hide', 'Debug SQL'|trans]
+ ]
+ } only %}
+ {# Console messages #}
+ <div class="content">
+ <div class="console_message_container">
+ <div class="message welcome">
+ <span id="instructions-0">
+ {% trans 'Press Ctrl+Enter to execute query' %}
+ </span>
+ <span class="hide" id="instructions-1">
+ {% trans 'Press Enter to execute query' %}
+ </span>
+ </div>
+ {% if sql_history is not empty %}
+ {% for record in sql_history|reverse %}
+ <div class="message history collapsed hide
+ {{- record['sqlquery'] matches '@^SELECT[[:space:]]+@i' ? ' select' }}"
+ targetdb="{{ record['db'] }}" targettable="{{ record['table'] }}">
+ {% include 'console/query_action.twig' with {
+ 'parent_div_classes': 'action_content',
+ 'content_array': [
+ ['action collapse', 'Collapse'|trans],
+ ['action expand', 'Expand'|trans],
+ ['action requery', 'Requery'|trans],
+ ['action edit', 'Edit'|trans],
+ ['action explain', 'Explain'|trans],
+ ['action profiling', 'Profiling'|trans],
+ cfg_bookmark is defined ? ['action bookmark', 'Bookmark'|trans] : null,
+ ['text failed', 'Query failed'|trans],
+ {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': record['db']},
+ {
+ 0: 'text query_time',
+ 1: 'Queried time'|trans,
+ 'extraSpan': record['timevalue'] is defined ?
+ record['timevalue'] : 'During current session'|trans
+ }
+ ]
+ } only %}
+ <span class="query">{{ record['sqlquery'] }}</span>
+ </div>
+ {% endfor %}
+ {% endif %}
+ </div><!-- console_message_container -->
+ <div class="query_input">
+ <span class="console_query_input"></span>
+ </div>
+ </div><!-- message end -->
+ {# Drak the console with other cards over it #}
+ <div class="mid_layer"></div>
+ {# Debug SQL card #}
+ <div class="card" id="debug_console">
+ {% include 'console/toolbar.twig' with {
+ 'parent_div_classes': '',
+ 'content_array': [
+ ['button order order_asc', 'ascending'|trans],
+ ['button order order_desc', 'descending'|trans],
+ ['text', 'Order:'|trans],
+ ['switch_button', 'Debug SQL'|trans],
+ ['button order_by sort_count', 'Count'|trans],
+ ['button order_by sort_exec', 'Execution order'|trans],
+ ['button order_by sort_time', 'Time taken'|trans],
+ ['text', 'Order by:'|trans],
+ ['button group_queries', 'Group queries'|trans],
+ ['button ungroup_queries', 'Ungroup queries'|trans]
+ ]
+ } only %}
+ <div class="content debug">
+ <div class="message welcome"></div>
+ <div class="debugLog"></div>
+ </div> <!-- Content -->
+ <div class="templates">
+ {% include 'console/query_action.twig' with {
+ 'parent_div_classes': 'debug_query action_content',
+ 'content_array': [
+ ['action collapse', 'Collapse'|trans],
+ ['action expand', 'Expand'|trans],
+ ['action dbg_show_trace', 'Show trace'|trans],
+ ['action dbg_hide_trace', 'Hide trace'|trans],
+ ['text count hide', 'Count'|trans],
+ ['text time', 'Time taken'|trans]
+ ]
+ } only %}
+ </div> <!-- Template -->
+ </div> <!-- Debug SQL card -->
+ {% if cfg_bookmark %}
+ <div class="card" id="pma_bookmarks">
+ {% include 'console/toolbar.twig' with {
+ 'parent_div_classes': '',
+ 'content_array': [
+ ['switch_button', 'Bookmarks'|trans],
+ ['button refresh', 'Refresh'|trans],
+ ['button add', 'Add'|trans]
+ ]
+ } only %}
+ <div class="content bookmark">
+ {{ bookmark_content|raw }}
+ </div>
+ <div class="mid_layer"></div>
+ <div class="card add">
+ {% include 'console/toolbar.twig' with {
+ 'parent_div_classes': '',
+ 'content_array': [
+ ['switch_button', 'Add bookmark'|trans]
+ ]
+ } only %}
+ <div class="content add_bookmark">
+ <div class="options">
+ <label>
+ {% trans 'Label' %}: <input type="text" name="label">
+ </label>
+ <label>
+ {% trans 'Target database' %}: <input type="text" name="targetdb">
+ </label>
+ <label>
+ <input type="checkbox" name="shared">{% trans 'Share this bookmark' %}
+ </label>
+ <button class="btn btn-primary" type="submit" name="submit">{% trans 'OK' %}</button>
+ </div> <!-- options -->
+ <div class="query_input">
+ <span class="bookmark_add_input"></span>
+ </div>
+ </div>
+ </div> <!-- Add bookmark card -->
+ </div> <!-- Bookmarks card -->
+ {% endif %}
+ {# Options card #}
+ <div class="card" id="pma_console_options">
+ {% include 'console/toolbar.twig' with {
+ 'parent_div_classes': '',
+ 'content_array': [
+ ['switch_button', 'Options'|trans],
+ ['button default', 'Set default'|trans]
+ ]
+ } only %}
+ <div class="content">
+ <label>
+ <input type="checkbox" name="always_expand">{% trans 'Always expand query messages' %}
+ </label>
+ <br>
+ <label>
+ <input type="checkbox" name="start_history">{% trans 'Show query history at start' %}
+ </label>
+ <br>
+ <label>
+ <input type="checkbox" name="current_query">{% trans 'Show current browsing query' %}
+ </label>
+ <br>
+ <label>
+ <input type="checkbox" name="enter_executes">
+ {% trans %}
+ Execute queries on Enter and insert new line with Shift + Enter. To make this permanent, view settings.
+ {% endtrans %}
+ </label>
+ <br>
+ <label>
+ <input type="checkbox" name="dark_theme">{% trans 'Switch to dark theme' %}
+ </label>
+ <br>
+ </div>
+ </div> <!-- Options card -->
+ <div class="templates">
+ {# Templates for console message actions #}
+ {% include 'console/query_action.twig' with {
+ 'parent_div_classes': 'query_actions',
+ 'content_array': [
+ ['action collapse', 'Collapse'|trans],
+ ['action expand', 'Expand'|trans],
+ ['action requery', 'Requery'|trans],
+ ['action edit', 'Edit'|trans],
+ ['action explain', 'Explain'|trans],
+ ['action profiling', 'Profiling'|trans],
+ cfg_bookmark is defined ? ['action bookmark', 'Bookmark'|trans] : null,
+ ['text failed', 'Query failed'|trans],
+ {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': ''},
+ {0: 'text query_time', 1: 'Queried time'|trans, 'extraSpan': ''}
+ ]
+ } only %}
+ </div>
+ </div> <!-- #console end -->
+</div> <!-- #console_container end -->
diff --git a/srcs/phpmyadmin/templates/console/query_action.twig b/srcs/phpmyadmin/templates/console/query_action.twig
new file mode 100644
index 0000000..62bc30a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/console/query_action.twig
@@ -0,0 +1,12 @@
+<div class="{{ parent_div_classes }}">
+ {% for content in content_array %}
+ {% if content is defined %}
+ <span class="{{ content[0] }}">
+ {{ content[1] }}
+ {% if content['extraSpan'] is defined %}
+ : <span>{{ content['extraSpan'] }}</span>
+ {% endif %}
+ </span>
+ {% endif %}
+ {% endfor %}
+</div>
diff --git a/srcs/phpmyadmin/templates/console/toolbar.twig b/srcs/phpmyadmin/templates/console/toolbar.twig
new file mode 100644
index 0000000..b16c290
--- /dev/null
+++ b/srcs/phpmyadmin/templates/console/toolbar.twig
@@ -0,0 +1,10 @@
+<div class="toolbar {{ parent_div_classes }}">
+ {% for content in content_array %}
+ {% if content is defined %}
+ <div class="{{ content[0] }}">
+ {{ content['image'] is defined ? content['image']|raw }}
+ <span>{{ content[1] }}</span>
+ </div>
+ {% endif %}
+ {% endfor %}
+</div>
diff --git a/srcs/phpmyadmin/templates/create_tracking_version.twig b/srcs/phpmyadmin/templates/create_tracking_version.twig
new file mode 100644
index 0000000..ba93434
--- /dev/null
+++ b/srcs/phpmyadmin/templates/create_tracking_version.twig
@@ -0,0 +1,79 @@
+<div id="div_create_version">
+ <form method="post" action="{{ url_query|raw }}">
+ {{ get_hidden_inputs(db) }}
+ {% for selected_table in selected %}
+ <input type="hidden" name="selected[]" value="{{ selected_table }}">
+ {% endfor %}
+
+ <fieldset>
+ <legend>
+ {% if selected|length == 1 %}
+ {{ 'Create version %1$s of %2$s'|trans|format(
+ last_version + 1,
+ db ~ '.' ~ selected[0]
+ ) }}
+ {% else %}
+ {{ 'Create version %1$s'|trans|format(last_version + 1) }}
+ {% endif %}
+ </legend>
+ <input type="hidden" name="version" value="{{ last_version + 1 }}">
+ <p>{% trans 'Track these data definition statements:' %}</p>
+
+ {% if type == 'both' or type == 'table' %}
+ <input type="checkbox" name="alter_table" value="true"
+ {{- 'ALTER TABLE' in default_statements ? ' checked="checked"' }}>
+ ALTER TABLE<br>
+ <input type="checkbox" name="rename_table" value="true"
+ {{- 'RENAME TABLE' in default_statements ? ' checked="checked"' }}>
+ RENAME TABLE<br>
+ <input type="checkbox" name="create_table" value="true"
+ {{- 'CREATE TABLE' in default_statements ? ' checked="checked"' }}>
+ CREATE TABLE<br>
+ <input type="checkbox" name="drop_table" value="true"
+ {{- 'DROP TABLE' in default_statements ? ' checked="checked"' }}>
+ DROP TABLE<br>
+ {% endif %}
+ {% if type == 'both' %}
+ <br>
+ {% endif %}
+ {% if type == 'both' or type == 'view' %}
+ <input type="checkbox" name="alter_view" value="true"
+ {{- 'ALTER VIEW' in default_statements ? ' checked="checked"' }}>
+ ALTER VIEW<br>
+ <input type="checkbox" name="create_view" value="true"
+ {{- 'CREATE VIEW' in default_statements ? ' checked="checked"' }}>
+ CREATE VIEW<br>
+ <input type="checkbox" name="drop_view" value="true"
+ {{- 'DROP VIEW' in default_statements ? ' checked="checked"' }}>
+ DROP VIEW<br>
+ {% endif %}
+ <br>
+
+ <input type="checkbox" name="create_index" value="true"
+ {{- 'CREATE INDEX' in default_statements ? ' checked="checked"' }}>
+ CREATE INDEX<br>
+ <input type="checkbox" name="drop_index" value="true"
+ {{- 'DROP INDEX' in default_statements ? ' checked="checked"' }}>
+ DROP INDEX<br>
+
+ <p>{% trans 'Track these data manipulation statements:' %}</p>
+ <input type="checkbox" name="insert" value="true"
+ {{- 'INSERT' in default_statements ? ' checked="checked"' }}>
+ INSERT<br>
+ <input type="checkbox" name="update" value="true"
+ {{- 'UPDATE' in default_statements ? ' checked="checked"' }}>
+ UPDATE<br>
+ <input type="checkbox" name="delete" value="true"
+ {{- 'DELETE' in default_statements ? ' checked="checked"' }}>
+ DELETE<br>
+ <input type="checkbox" name="truncate" value="true"
+ {{- 'TRUNCATE' in default_statements ? ' checked="checked"' }}>
+ TRUNCATE<br>
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input type="hidden" name="submit_create_version" value="1">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Create version' %}">
+ </fieldset>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig b/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig
new file mode 100644
index 0000000..947d841
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig
@@ -0,0 +1,9 @@
+<table id="table_columns" class="noclick">
+ <caption class="tblHeaders">{% trans 'Structure' %}</caption>
+ <thead>
+ <tr>
+ {% for header in headers %}
+ <th>{{ header }}</th>
+ {% endfor %}
+ </tr>
+ </thead>
diff --git a/srcs/phpmyadmin/templates/database/central_columns/main.twig b/srcs/phpmyadmin/templates/database/central_columns/main.twig
new file mode 100644
index 0000000..30b7276
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/central_columns/main.twig
@@ -0,0 +1,418 @@
+{# getHtmlForAddNewColumn #}
+<div id="add_col_div" class="topmargin">
+ <a href="#">
+ <span>{{ (total_rows > 0) ? '+' : '-' }}</span>{% trans 'Add new column' %}
+ </a>
+ <form id="add_new" class="new_central_col{{ (total_rows != 0) ? ' hide' : ''}}"
+ method="post" action="db_central_columns.php">
+ {{ get_hidden_inputs(db) }}
+ <input type="hidden" name="add_new_column" value="add_new_column">
+ <div class="responsivetable">
+ <table>
+ <thead>
+ <tr>
+ <th class=""></th>
+ <th class="hide"></th>
+ <th class="" title="" data-column="name">
+ {% trans 'Name' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="type">
+ {% trans 'Type' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="length">
+ {% trans 'Length/Value' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="default">
+ {% trans 'Default' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="collation">
+ {% trans 'Collation' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="attribute">
+ {% trans 'Attribute' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="isnull">
+ {% trans 'Null' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="" title="" data-column="extra">
+ {% trans 'A_I' %}
+ <div class="sorticon"></div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td></td>
+ <td name="col_name" class="nowrap">
+ {% include 'columns_definitions/column_name.twig' with {
+ 'column_number': 0,
+ 'ci': 0,
+ 'ci_offset': 0,
+ 'column_meta': {},
+ 'cfg_relation': {
+ 'centralcolumnswork': false
+ },
+ 'max_rows': max_rows,
+ } only %}
+ </td>
+ <td name="col_type" class="nowrap">
+ {% include 'columns_definitions/column_type.twig' with {
+ 'column_number': 0,
+ 'ci': 1,
+ 'ci_offset': 0,
+ 'type_upper': '',
+ 'column_meta': {}
+ } only %}
+ </td>
+ <td class="nowrap" name="col_length">
+ {% include 'columns_definitions/column_length.twig' with {
+ 'column_number': 0,
+ 'ci': 2,
+ 'ci_offset': 0,
+ 'length_values_input_size': 8,
+ 'length_to_display': ''
+ } only %}
+ </td>
+ <td class="nowrap" name="col_default">
+ {% include 'columns_definitions/column_default.twig' with {
+ 'column_number': 0,
+ 'ci': 3,
+ 'ci_offset': 0,
+ 'type_upper': '',
+ 'column_meta': {},
+ 'char_editing': char_editing,
+ } only %}
+ </td>
+ <td name="collation" class="nowrap">
+ <select lang="en" dir="ltr" name="field_collation[0]" id="field_0_4">
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}">
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ </td>
+ <td class="nowrap" name="col_attribute">
+ {% include 'columns_definitions/column_attribute.twig' with {
+ 'column_number': 0,
+ 'ci': 5,
+ 'ci_offset': 0,
+ 'extracted_columnspec': {},
+ 'column_meta': {},
+ 'submit_attribute': false,
+ 'attribute_types': attribute_types,
+ } only %}
+ </td>
+ <td class="nowrap" name="col_isNull">
+ {% include 'columns_definitions/column_null.twig' with {
+ 'column_number': 0,
+ 'ci': 6,
+ 'ci_offset': 0,
+ 'column_meta': {}
+ } only %}
+ </td>
+ <td class="nowrap" name="col_extra">
+ {% include 'columns_definitions/column_extra.twig' with {
+ 'column_number': 0,
+ 'ci': 7,
+ 'ci_offset': 0,
+ 'column_meta': {}
+ } only %}
+ </td>
+ <td>
+ <input id="add_column_save" class="btn btn-primary" type="submit" value="Save">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </form>
+</div>
+{% if total_rows <= 0 %}
+ <fieldset>
+ {% trans 'The central list of columns for the current database is empty' %}
+ </fieldset>
+{% else %}
+ <table style="display:inline-block;max-width:49%" class="navigation nospacing nopadding">
+ <tr>
+ <td class="navigation_separator"></td>
+ {% if pos - max_rows >= 0 %}
+ <td>
+ <form action="db_central_columns.php" method="post">
+ {{ get_hidden_inputs(db) }}
+ <input type="hidden" name="pos" value="{{ pos - max_rows }}">
+ <input type="hidden" name="total_rows" value="{{ total_rows }}">
+ <input class="btn btn-secondary ajax" type="submit" name="navig" value="&lt">
+ </form>
+ </td>
+ {% endif %}
+ {% if tn_nbTotalPage > 1 %}
+ <td>
+ <form action="db_central_columns.php" method="post">
+ {{ get_hidden_inputs(db) }}
+ <input type="hidden" name="total_rows" value="{{ total_rows }}">
+ {{ tn_page_selector | raw }}
+ </form>
+ </td>
+ {% endif %}
+ {% if pos + max_rows < total_rows %}
+ <td>
+ <form action="db_central_columns.php" method="post">
+ {{ get_hidden_inputs(db) }}
+ <input type="hidden" name="pos" value="{{ pos + max_rows }}">
+ <input type="hidden" name="total_rows" value="{{ total_rows }}">
+ <input class="btn btn-secondary ajax" type="submit" name="navig" value="&gt">
+ </form>
+ </td>
+ {% endif %}
+ <td class="navigation_separator"></td>
+ <td>
+ <span>{% trans 'Filter rows' %}:</span>
+ <input type="text" class="filter_rows" placeholder="{% trans 'Search this table' %}">
+ </td>
+ <td class="navigation_separator"></td>
+ </tr>
+ </table>
+{% endif %}
+{# getHtmlForAddColumn #}
+<table class="central_columns_add_column" class="navigation nospacing nopadding">
+ <tr>
+ <td class="navigation_separator largescreenonly"></td>
+ <td class="central_columns_navigation">
+ {{ get_icon('centralColumns_add', 'Add column' | trans)|raw }}
+ <form id="add_column" action="db_central_columns.php" method="post">
+ {{ get_hidden_inputs(db) | raw }}
+ <input type="hidden" name="add_column" value="add">
+ <input type="hidden" name="pos" value="{{ pos }}">
+ <input type="hidden" name="total_rows" value="{{ total_rows }}">
+ {# getHtmlForTableDropdown #}
+ <select name="table-select" id="table-select">
+ <option value="" disabled="disabled" selected="selected">
+ {% trans 'Select a table' %}
+ </option>
+ {% for table in tables %}
+ <option value="{{ table|e }}">{{ table|e }}</option>
+ {% endfor %}
+ </select>
+ <select name="column-select" id="column-select">
+ <option value="" selected="selected">{% trans 'Select a column.' %}</option>
+ </select>
+ <input class="btn btn-primary" type="submit" value="{% trans 'Add' %}">
+ </form>
+ </td>
+ <td class="navigation_separator largescreenonly"></td>
+ </tr>
+</table>
+{% if total_rows > 0 %}
+ <form method="post" id="del_form" action="db_central_columns.php">
+ {{ get_hidden_inputs(db) }}
+ <input id="del_col_name" type="hidden" name="col_name" value="">
+ <input type="hidden" name="pos" value="{{ pos }}">
+ <input type="hidden" name="delete_save" value="delete">
+ </form>
+ <div id="tableslistcontainer">
+ <form name="tableslistcontainer">
+ <table id="table_columns" class="tablesorter" class="data">
+ {% set class = 'column_heading' %}
+ {% set title = 'Click to sort.' | trans %}
+ <thead>
+ <tr>
+ <th class="{{ class }}"></th>
+ <th class="hide"></th>
+ <th class="column_action" colspan="2">{% trans 'Action' %}</th>
+ <th class="{{ class }}" title="{{ title }}" data-column="name">
+ {% trans 'Name' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="type">
+ {% trans 'Type' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="length">
+ {% trans 'Length/Value' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="default">
+ {% trans 'Default' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="collation">
+ {% trans 'Collation' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="attribute">
+ {% trans 'Attribute' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="isnull">
+ {% trans 'Null' %}
+ <div class="sorticon"></div>
+ </th>
+ <th class="{{ class }}" title="{{ title }}" data-column="extra">
+ {% trans 'A_I' %}
+ <div class="sorticon"></div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {% set row_num = 0 %}
+ {% for row in rows_list %}
+ {# getHtmlForTableRow #}
+ <tr data-rownum="{{ row_num }}" id="{{ 'f_' ~ row_num }}">
+ {{ get_hidden_inputs(db) }}
+ <input type="hidden" name="edit_save" value="save">
+ <td class="nowrap">
+ <input type="checkbox" class="checkall" name="selected_fld[]"
+ value="{{ row['col_name'] }}" id="{{ 'checkbox_row_' ~ row_num }}">
+ </td>
+ <td id="{{ 'edit_' ~ row_num }}" class="edit center">
+ <a href="#"> {{ get_icon('b_edit', 'Edit' | trans) | raw }}</a>
+ </td>
+ <td class="del_row" data-rownum = "{{ row_num }}">
+ <a hrf="#">{{ get_icon('b_drop', 'Delete' | trans) }}</a>
+ <input type="submit" data-rownum = "{{ row_num }}" class="btn btn-secondary edit_cancel_form" value="Cancel">
+ </td>
+ <td id="{{ 'save_' ~ row_num }}" class="hide">
+ <input type="submit" data-rownum="{{ row_num }}" class="btn btn-primary edit_save_form" value="Save">
+ </td>
+ <td name="col_name" class="nowrap">
+ <span>{{ row['col_name'] }}</span>
+ <input name="orig_col_name" type="hidden" value="{{ row['col_name'] }}">
+ {% include 'columns_definitions/column_name.twig' with {
+ 'column_number': row_num,
+ 'ci': 0,
+ 'ci_offset': 0,
+ 'column_meta': {
+ 'Field': row['col_name']
+ },
+ 'cfg_relation': {
+ 'centralcolumnswork': false
+ },
+ 'max_rows': max_rows
+ } only %}
+ </td>
+ <td name = "col_type" class="nowrap">
+ <span>{{ row['col_type'] }}</span>
+ {% include 'columns_definitions/column_type.twig' with {
+ 'column_number': row_num,
+ 'ci': 1,
+ 'ci_offset': 0,
+ 'type_upper': types_upper[row_num],
+ 'column_meta': {}
+ } only %}
+ </td>
+ <td class="nowrap" name="col_length">
+ <span>{{ (row['col_length']?(row['col_length']):'') }}</span>
+ {% include 'columns_definitions/column_length.twig' with {
+ 'column_number': row_num,
+ 'ci': 2,
+ 'ci_offset': 0,
+ 'length_values_input_size': 8,
+ 'length_to_display': row['col_length']
+ } only %}
+ </td>
+ <td class="nowrap" name="col_default">
+ {% if row['col_default'] is defined %}
+ <span>{{ row['col_default'] }}</span>
+ {% else %}
+ <span>None</span>
+ {% endif %}
+ {% include 'columns_definitions/column_default.twig' with {
+ 'column_number': row_num,
+ 'ci': 3,
+ 'ci_offset': 0,
+ 'type_upper': types_upper[row_num],
+ 'column_meta': rows_meta[row_num],
+ 'char_editing': char_editing,
+ } only %}
+ </td>
+ <td name="collation" class="nowrap">
+ <span>{{ row['col_collation'] }}</span>
+ <select lang="en" dir="ltr" name="field_collation[{{ row_num }}]" id="field_{{ row_num }}_4">
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}"
+ {{- collation.name == row['col_collation'] ? ' selected' }}>
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ </td>
+ <td class="nowrap" name="col_attribute">
+ <span>{{ row['col_attribute']?(row['col_attribute']):"" }}</span>
+ {% include 'columns_definitions/column_attribute.twig' with {
+ 'column_number': row_num,
+ 'ci': 5,
+ 'ci_offset': 0,
+ 'extracted_columnspec': {},
+ 'column_meta': row['col_attribute'],
+ 'submit_attribute': false,
+ 'attribute_types': attribute_types,
+ } only %}
+ </td>
+ <td class="nowrap" name="col_isNull">
+ <span>{{ row['col_isNull'] ? 'Yes' | trans : 'No' | trans }}</span>
+ {% include 'columns_definitions/column_null.twig' with {
+ 'column_number': row_num,
+ 'ci': 6,
+ 'ci_offset': 0,
+ 'column_meta': {
+ 'Null': row['col_isNull']
+ }
+ } only %}
+ </td>
+ <td class="nowrap" name="col_extra">
+ <span>{{ row['col_extra'] }}</span>
+ {% include 'columns_definitions/column_extra.twig' with {
+ 'column_number': row_num,
+ 'ci': 7,
+ 'ci_offset': 0,
+ 'column_meta': {
+ 'Extra': row['col_extra']
+ }
+ } only %}
+ </td>
+ </tr>
+ {% set row_num = row_num + 1 %}
+ {% endfor %}
+ </tbody>
+ </table>
+ {# getTableFooter #}
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pmaThemeImage,
+ 'text_dir' : text_dir,
+ 'form_name' : 'tableslistcontainer',
+ } only %}
+ {{ get_button_or_image(
+ 'edit_central_columns',
+ 'mult_submit change_central_columns',
+ 'Edit' | trans,
+ 'b_edit',
+ 'edit central columns'
+ ) | raw }}
+ {{ get_button_or_image(
+ 'delete_central_columns',
+ 'mult_submit',
+ 'Delete' | trans,
+ 'b_drop',
+ 'remove_from_central_columns'
+ ) | raw }}
+ </form>
+ </div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/database/create_table.twig b/srcs/phpmyadmin/templates/database/create_table.twig
new file mode 100644
index 0000000..e57d93a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/create_table.twig
@@ -0,0 +1,23 @@
+<form id="create_table_form_minimal" method="post" action="tbl_create.php" class="lock-page">
+ <fieldset>
+ <legend>
+ {% if show_icons('ActionLinksMode') -%}
+ {{ get_image('b_table_add') }}
+ {%- endif %}
+ {% trans "Create table" %}
+ </legend>
+ {{ get_hidden_inputs(db) }}
+ <div class="formelement">
+ {% trans "Name" %}:
+ <input type="text" name="table" maxlength="64" size="30" required="required">
+ </div>
+ <div class="formelement">
+ {% trans "Number of columns" %}:
+ <input type="number" min="1" name="num_fields" value="4" required="required">
+ </div>
+ <div class="clearfloat"></div>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit" value="{% trans "Go" %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/database/data_dictionary/index.twig b/srcs/phpmyadmin/templates/database/data_dictionary/index.twig
new file mode 100644
index 0000000..2f5dc5a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/data_dictionary/index.twig
@@ -0,0 +1,65 @@
+<h1>{{ database }}</h1>
+{% if comment is not empty %}
+ <p>{% trans 'Database comment:' %} <em>{{ comment }}</em></p>
+{% endif %}
+
+<div>
+ {% for table in tables %}
+ <div>
+ <h2>{{ table.name }}</h2>
+ {% if table.comment is not empty %}
+ <p>{% trans 'Table comments:' %} <em>{{ table.comment }}</em></p>
+ {% endif %}
+
+ <table class="print">
+ <tr>
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Type' %}</th>
+ <th>{% trans 'Null' %}</th>
+ <th>{% trans 'Default' %}</th>
+ {% if table.has_relation %}
+ <th>{% trans 'Links to' %}</th>
+ {% endif %}
+ <th>{% trans 'Comments' %}</th>
+ {% if table.has_mime %}
+ <th>{% trans 'Media (MIME) type' %}</th>
+ {% endif %}
+ </tr>
+ {% for column in table.columns %}
+ <tr>
+ <td class="nowrap">
+ {{ column.name }}
+ {% if column.has_primary_key %}
+ <em>({% trans 'Primary' %})</em>
+ {% endif %}
+ </td>
+ <td lang="en" dir="ltr"{{ 'set' != column.type and 'enum' != column.type ? ' class="nowrap"' }}>
+ {{ column.print_type }}
+ </td>
+ <td>{{ column.is_nullable ? 'Yes'|trans : 'No'|trans }}</td>
+ <td class="nowrap">
+ {% if column.default is null and column.is_nullable %}
+ <em>NULL</em>
+ {% else %}
+ {{ column.default }}
+ {% endif %}
+ </td>
+ {% if table.has_relation %}
+ <td>{{ column.relation }}</td>
+ {% endif %}
+ <td>{{ column.comment }}</td>
+ {% if table.has_mime %}
+ <td>{{ column.mime }}</td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </table>
+
+ {{ table.indexes_table|raw }}
+ </div>
+ {% endfor %}
+</div>
+
+<p class="print_ignore">
+ <input type="button" class="btn btn-secondary button" id="print" value="{% trans 'Print' %}">
+</p>
diff --git a/srcs/phpmyadmin/templates/database/designer/database_tables.twig b/srcs/phpmyadmin/templates/database/designer/database_tables.twig
new file mode 100644
index 0000000..5453bb5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/database_tables.twig
@@ -0,0 +1,121 @@
+{% for designerTable in tables %}
+ {% set i = loop.index0 %}
+ {% set t_n_url = designerTable.getDbTableString()|escape('url') %}
+ {% set db = designerTable.getDatabaseName() %}
+ {% set db_url = db|escape('url') %}
+ {% set t_n = designerTable.getDbTableString() %}
+ {% set table_name = designerTable.getTableName()|escape('html') %}
+ <input name="t_x[{{ t_n_url }}]" type="hidden" id="t_x_{{ t_n_url }}_" />
+ <input name="t_y[{{ t_n_url }}]" type="hidden" id="t_y_{{ t_n_url }}_" />
+ <input name="t_v[{{ t_n_url }}]" type="hidden" id="t_v_{{ t_n_url }}_" />
+ <input name="t_h[{{ t_n_url }}]" type="hidden" id="t_h_{{ t_n_url }}_" />
+ <table id="{{ t_n_url }}"
+ db_url="{{ designerTable.getDatabaseName()|escape('url') }}"
+ table_name_url="{{ designerTable.getTableName()|escape('url') }}"
+ cellpadding="0"
+ cellspacing="0"
+ class="designer_tab"
+ style="position:absolute; left:
+ {{- tab_pos[t_n] is defined ? tab_pos[t_n]['X'] : random(range(20, 700)) }}px; top:
+ {{- tab_pos[t_n] is defined ? tab_pos[t_n]['Y'] : random(range(20, 550)) }}px; display:
+ {{- tab_pos[t_n] is defined or display_page == -1 ? 'block' : 'none' }}; z-index: 1;"> <!--"-->
+ <thead>
+ <tr class="header">
+ {% if has_query %}
+ <td class="select_all">
+ <input class="select_all_1"
+ type="checkbox"
+ style="margin: 0;"
+ value="select_all_{{ t_n_url }}"
+ id="select_all_{{ i }}"
+ title="{% trans 'Select all' %}"
+ table_name="{{ table_name }}"
+ db_name="{{ db }}">
+ </td>
+ {% endif %}
+ <td class="small_tab"
+ title="{% trans 'Show/hide columns' %}"
+ id="id_hide_tbody_{{ t_n_url }}"
+ table_name="{{ t_n_url }}">{{ tab_pos[t_n] is not defined or tab_pos[t_n]['V'] is not empty ? 'v' : '&gt;' }}</td>
+ <td class="small_tab_pref small_tab_pref_1"
+ db="{{ designerTable.getDatabaseName() }}"
+ db_url="{{ designerTable.getDatabaseName()|escape('url') }}"
+ table_name="{{ designerTable.getTableName() }}"
+ table_name_url="{{ designerTable.getTableName()|escape('url') }}">
+ <img src="{{ theme.getImgPath('designer/exec_small.png') }}"
+ title="{% trans 'See table structure' %}">
+ </td>
+ <td id="id_zag_{{ t_n_url }}"
+ class="tab_zag nowrap tab_zag_noquery"
+ table_name="{{ t_n_url }}"
+ query_set="{{ has_query ? 1 : 0 }}">
+ <span class="owner">{{ designerTable.getDatabaseName() }}</span>
+ {{ designerTable.getTableName() }}
+ </td>
+ {% if has_query %}
+ <td class="tab_zag tab_zag_query"
+ id="id_zag_{{ t_n_url }}_2"
+ table_name="{{ t_n_url }}">
+ </td>
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody id="id_tbody_{{ t_n_url }}"
+ {{- tab_pos[t_n] is defined and tab_pos[t_n]['V'] is empty ? ' style="display: none"' }}>
+ {% set display_field = designerTable.getDisplayField() %}
+ {% for j in 0..tab_column[t_n]['COLUMN_ID']|length - 1 %}
+ {% set col_name = tab_column[t_n]['COLUMN_NAME'][j] %}
+ {% set tmp_column = t_n ~ '.' ~ tab_column[t_n]['COLUMN_NAME'][j] %}
+ {% set click_field_param = [
+ designerTable.getTableName()|escape('url'),
+ tab_column[t_n]['COLUMN_NAME'][j]|url_encode
+ ] %}
+ {% if not designerTable.supportsForeignkeys() %}
+ {% set click_field_param = click_field_param|merge([tables_pk_or_unique_keys[tmp_column] is defined ? 1 : 0]) %}
+ {% else %}
+ {# if foreign keys are supported, it's not necessary that the
+ index is a primary key #}
+ {% set click_field_param = click_field_param|merge([tables_all_keys[tmp_column] is defined ? 1 : 0]) %}
+ {% endif %}
+ {% set click_field_param = click_field_param|merge([db]) %}
+ <tr id="id_tr_{{ designerTable.getTableName()|escape('url') }}.{{ tab_column[t_n]['COLUMN_NAME'][j] }}" class="tab_field
+ {{- display_field == tab_column[t_n]['COLUMN_NAME'][j] ? '_3' }}" click_field_param="
+ {{- click_field_param|join(',') }}">
+ {% if has_query %}
+ <td class="select_all">
+ <input class="select_all_store_col"
+ value="{{ t_n_url }}{{ tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}"
+ type="checkbox"
+ id="select_{{ t_n_url }}._{{ tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}"
+ style="margin: 0;"
+ title="{{ 'Select "%s"'|trans|format(col_name) }}"
+ id_check_all="select_all_{{ i }}"
+ db_name="{{ db }}"
+ table_name="{{ table_name }}"
+ col_name="{{ col_name }}">
+ </td>
+ {% endif %}
+ <td width="10px" colspan="3" id="{{ t_n_url }}.
+ {{- tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}">
+ <div class="nowrap">
+ {% set type = columns_type[t_n ~ '.' ~ tab_column[t_n]['COLUMN_NAME'][j]] %}
+ <img src="{{ theme.getImgPath(type) }}.png" alt="*">
+ {{ tab_column[t_n]['COLUMN_NAME'][j] }} : {{ tab_column[t_n]['TYPE'][j] }}
+ </div>
+ </td>
+ {% if has_query %}
+ <td class="small_tab_pref small_tab_pref_click_opt"
+ {# Escaped 2 times to be able to use it in innerHtml #}
+ option_col_name_modal="<strong>{{ 'Add an option for column "%s".'|trans|format(col_name)|escape('html')|escape('html') }}</strong>"
+ db_name="{{ db }}"
+ table_name="{{ table_name }}"
+ col_name="{{ col_name }}"
+ db_table_name_url="{{ t_n_url }}">
+ <img src="{{ theme.getImgPath('designer/exec_small.png') }}" title="{% trans 'Options' %}" />
+ </td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig b/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig
new file mode 100644
index 0000000..75d1a1a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig
@@ -0,0 +1,13 @@
+<form action="db_designer.php" method="post" name="edit_delete_pages" id="edit_delete_pages" class="ajax">
+ {{ get_hidden_inputs(db) }}
+ <fieldset id="page_edit_delete_options">
+ <input type="hidden" name="operation" value="{{ operation }}">
+ <label for="selected_page">
+ {{ operation == 'editPage' ? 'Page to open'|trans : 'Page to delete'|trans }}:
+ </label>
+ {% include 'database/designer/page_selector.twig' with {
+ 'pdfwork': pdfwork,
+ 'pages': pages
+ } only %}
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/database/designer/main.twig b/srcs/phpmyadmin/templates/database/designer/main.twig
new file mode 100644
index 0000000..f971dc5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/main.twig
@@ -0,0 +1,1105 @@
+{# Invisible characters will make javascript crash #}
+{% apply spaceless %}
+<script type="text/javascript">
+var designerConfig = {{ designer_config|raw }};
+</script>
+{% endapply %}
+
+{# side menu #}
+{% if not has_query %}
+ <div id="name-panel">
+ <span id="page_name">
+ {{ selected_page == null ? 'Untitled'|trans : selected_page }}
+ </span>
+ <span id="saved_state">
+ {{ selected_page == null ? '*' : '' }}
+ </span>
+ </div>
+{% endif %}
+<div class="designer_header side-menu" id="side_menu">
+ <a class="M_butt" id="key_Show_left_menu" href="#">
+ <img title="{% trans 'Show/Hide tables list' %}"
+ alt="v"
+ src="{{ theme.getImgPath('designer/downarrow2_m.png') }}"
+ data-down="{{ theme.getImgPath('designer/downarrow2_m.png') }}"
+ data-up="{{ theme.getImgPath('designer/uparrow2_m.png') }}">
+ <span class="hide hidable">
+ {% trans 'Show/Hide tables list' %}
+ </span>
+ </a>
+ <a href="#" id="toggleFullscreen" class="M_butt">
+ <img title="{% trans 'View in fullscreen' %}"
+ src="{{ theme.getImgPath('designer/viewInFullscreen.png') }}"
+ data-enter="{{ theme.getImgPath('designer/viewInFullscreen.png') }}"
+ data-exit="{{ theme.getImgPath('designer/exitFullscreen.png') }}">
+ <span class="hide hidable"
+ data-exit="{% trans 'Exit fullscreen' %}"
+ data-enter="{% trans 'View in fullscreen' %}">
+ {% trans 'View in fullscreen' %}
+ </span>
+ </a>
+ <a href="#" id="addOtherDbTables" class="M_butt">
+ <img title="{% trans 'Add tables from other databases' %}"
+ src="{{ theme.getImgPath('designer/other_table.png') }}">
+ <span class="hide hidable">
+ {% trans 'Add tables from other databases' %}
+ </span>
+ </a>
+ {% if not has_query %}
+ <a id="newPage" href="#" class="M_butt">
+ <img title="{% trans 'New page' %}"
+ alt=""
+ src="{{ theme.getImgPath('designer/page_add.png') }}">
+ <span class="hide hidable">
+ {% trans 'New page' %}
+ </span>
+ </a>
+ <a href="#" id="editPage" class="M_butt ajax">
+ <img title="{% trans 'Open page' %}"
+ src="{{ theme.getImgPath('designer/page_edit.png') }}">
+ <span class="hide hidable">
+ {% trans 'Open page' %}
+ </span>
+ </a>
+ <a href="#" id="savePos" class="M_butt">
+ <img title="{% trans 'Save page' %}"
+ src="{{ theme.getImgPath('designer/save.png') }}">
+ <span class="hide hidable">
+ {% trans 'Save page' %}
+ </span>
+ </a>
+ <a href="#" id="SaveAs" class="M_butt ajax">
+ <img title="{% trans 'Save page as' %}"
+ src="{{ theme.getImgPath('designer/save_as.png') }}">
+ <span class="hide hidable">
+ {% trans 'Save page as' %}
+ </span>
+ </a>
+ <a href="#" id="delPages" class="M_butt ajax">
+ <img title="{% trans 'Delete pages' %}"
+ src="{{ theme.getImgPath('designer/page_delete.png') }}">
+ <span class="hide hidable">
+ {% trans 'Delete pages' %}
+ </span>
+ </a>
+ <a href="#" id="StartTableNew" class="M_butt">
+ <img title="{% trans 'Create table' %}"
+ src="{{ theme.getImgPath('designer/table.png') }}">
+ <span class="hide hidable">
+ {% trans 'Create table' %}
+ </span>
+ </a>
+ <a href="#" class="M_butt" id="rel_button">
+ <img title="{% trans 'Create relationship' %}"
+ src="{{ theme.getImgPath('designer/relation.png') }}">
+ <span class="hide hidable">
+ {% trans 'Create relationship' %}
+ </span>
+ </a>
+ <a href="#" class="M_butt" id="display_field_button">
+ <img title="{% trans 'Choose column to display' %}"
+ src="{{ theme.getImgPath('designer/display_field.png') }}">
+ <span class="hide hidable">
+ {% trans 'Choose column to display' %}
+ </span>
+ </a>
+ <a href="#" id="reloadPage" class="M_butt">
+ <img title="{% trans 'Reload' %}"
+ src="{{ theme.getImgPath('designer/reload.png') }}">
+ <span class="hide hidable">
+ {% trans 'Reload' %}
+ </span>
+ </a>
+ <a href="{{ get_docu_link('faq', 'faq6-31') }}"
+ target="documentation"
+ class="M_butt">
+ <img title="{% trans 'Help' %}"
+ src="{{ theme.getImgPath('designer/help.png') }}">
+ <span class="hide hidable">
+ {% trans 'Help' %}
+ </span>
+ </a>
+ {% endif %}
+ <a href="#" class="{{ params_array['angular_direct'] }}" id="angular_direct_button">
+ <img title="{% trans 'Angular links' %} / {% trans 'Direct links' %}"
+ src="{{ theme.getImgPath('designer/ang_direct.png') }}">
+ <span class="hide hidable">
+ {% trans 'Angular links' %} / {% trans 'Direct links' %}
+ </span>
+ </a>
+ <a href="#" class="{{ params_array['snap_to_grid'] }}" id="grid_button">
+ <img title="{% trans 'Snap to grid' %}" src="{{ theme.getImgPath('designer/grid.png') }}">
+ <span class="hide hidable">
+ {% trans 'Snap to grid' %}
+ </span>
+ </a>
+ <a href="#" class="{{ params_array['small_big_all'] }}" id="key_SB_all">
+ <img title="{% trans 'Small/Big All' %}"
+ alt="v"
+ src="{{ theme.getImgPath('designer/downarrow1.png') }}"
+ data-down="{{ theme.getImgPath('designer/downarrow1.png') }}"
+ data-right="{{ theme.getImgPath('designer/rightarrow1.png') }}">
+ <span class="hide hidable">
+ {% trans 'Small/Big All' %}
+ </span>
+ </a>
+ <a href="#" id="SmallTabInvert" class="M_butt">
+ <img title="{% trans 'Toggle small/big' %}"
+ src="{{ theme.getImgPath('designer/bottom.png') }}">
+ <span class="hide hidable">
+ {% trans 'Toggle small/big' %}
+ </span>
+ </a>
+ <a href="#" id="relLineInvert" class="{{ params_array['relation_lines'] }}" >
+ <img title="{% trans 'Toggle relationship lines' %}"
+ src="{{ theme.getImgPath('designer/toggle_lines.png') }}">
+ <span class="hide hidable">
+ {% trans 'Toggle relationship lines' %}
+ </span>
+ </a>
+ {% if not visual_builder %}
+ <a href="#" id="exportPages" class="M_butt" >
+ <img title="{% trans 'Export schema' %}"
+ src="{{ theme.getImgPath('designer/export.png') }}">
+ <span class="hide hidable">
+ {% trans 'Export schema' %}
+ </span>
+ </a>
+ {% else %}
+ <a id="build_query_button"
+ class="M_butt"
+ href="#"
+ class="M_butt">
+ <img title="{% trans 'Build Query' %}"
+ src="{{ theme.getImgPath('designer/query_builder.png') }}">
+ <span class="hide hidable">
+ {% trans 'Build Query' %}
+ </span>
+ </a>
+ {% endif %}
+ <a href="#" class="{{ params_array['side_menu'] }}" id="key_Left_Right">
+ <img title="{% trans 'Move Menu' %}" alt=">"
+ data-right="{{ theme.getImgPath('designer/2leftarrow_m.png') }}"
+ src="{{ theme.getImgPath('designer/2rightarrow_m.png') }}">
+ <span class="hide hidable">
+ {% trans 'Move Menu' %}
+ </span>
+ </a>
+ <a href="#" class="{{ params_array['pin_text'] }}" id="pin_Text">
+ <img title="{% trans 'Pin text' %}"
+ alt=">"
+ data-right="{{ theme.getImgPath('designer/anchor.png') }}"
+ src="{{ theme.getImgPath('designer/anchor.png') }}">
+ <span class="hide hidable">
+ {% trans 'Pin text' %}
+ </span>
+ </a>
+</div>
+<div id="canvas_outer">
+ <form action="" id="container-form" method="post" name="form1">
+ <div id="osn_tab">
+ <canvas class="designer" id="canvas" width="100" height="100"></canvas>
+ </div>
+ <div id="layer_menu" class="hide">
+ <div class="center">
+ <a href="#" class="M_butt" target="_self" >
+ <img title="{% trans 'Hide/Show all' %}"
+ alt="v"
+ id="key_HS_all"
+ src="{{ theme.getImgPath('designer/downarrow1.png') }}"
+ data-down="{{ theme.getImgPath('designer/downarrow1.png') }}"
+ data-right="{{ theme.getImgPath('designer/rightarrow1.png') }}">
+ </a>
+ <a href="#" class="M_butt" target="_self" >
+ <img alt="v"
+ id="key_HS"
+ title="{% trans 'Hide/Show tables with no relationship' %}"
+ src="{{ theme.getImgPath('designer/downarrow2.png') }}"
+ data-down="{{ theme.getImgPath('designer/downarrow2.png') }}"
+ data-right="{{ theme.getImgPath('designer/rightarrow2.png') }}">
+ </a>
+ </div>
+ <div id="id_scroll_tab" class="scroll_tab">
+ <table width="100%" style="padding-left: 3px;"></table>
+ </div>
+ {# end id_scroll_tab #}
+ <div class="center">
+ {% trans 'Number of tables:' %} <span id="tables_counter">0</span>
+ </div>
+ <div id="layer_menu_sizer">
+ <div class="floatleft">
+ <img class="icon"
+ data-right="{{ theme.getImgPath('designer/resizeright.png') }}"
+ src="{{ theme.getImgPath('designer/resize.png') }}">
+ </div>
+ </div>
+ </div>
+ {# end layer_menu #}
+ {% include 'database/designer/database_tables.twig' with {
+ 'db': db,
+ 'get_db': get_db,
+ 'has_query': has_query,
+ 'tab_pos': tab_pos,
+ 'display_page': display_page,
+ 'tab_column': tab_column,
+ 'tables_all_keys': tables_all_keys,
+ 'tables_pk_or_unique_keys': tables_pk_or_unique_keys,
+ 'columns_type': columns_type,
+ 'tables': designerTables,
+ 'theme': theme,
+ } only %}
+ </form>
+</div>
+<div id="designer_hint"></div>
+{# create relation pane #}
+<table id="layer_new_relation" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ {% trans 'Create relationship' %}
+ </strong>
+ </td>
+ </tr>
+ </thead>
+ <tbody id="foreign_relation">
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ FOREIGN KEY
+ </strong>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ on delete
+ </td>
+ <td width="102">
+ <select name="on_delete" id="on_delete">
+ <option value="nix" selected="selected">
+ --
+ </option>
+ <option value="CASCADE">
+ CASCADE
+ </option>
+ <option value="SET NULL">
+ SET NULL
+ </option>
+ <option value="NO ACTION">
+ NO ACTION
+ </option>
+ <option value="RESTRICT">
+ RESTRICT
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="nowrap">
+ on update
+ </td>
+ <td>
+ <select name="on_update" id="on_update">
+ <option value="nix" selected="selected">
+ --
+ </option>
+ <option value="CASCADE">
+ CASCADE
+ </option>
+ <option value="SET NULL">
+ SET NULL
+ </option>
+ <option value="NO ACTION">
+ NO ACTION
+ </option>
+ <option value="RESTRICT">
+ RESTRICT
+ </option>
+ </select>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="button" id="ok_new_rel_panel" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input type="button" id="cancel_new_rel_panel"
+ class="btn btn-secondary butt" name="Button" value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+</table>
+{# delete relation pane #}
+<table id="layer_upd_relation" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%">
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="100%" class="center" cellpadding="2" cellspacing="0">
+ <tr>
+ <td colspan="3" class="center nowrap">
+ <strong>
+ {% trans 'Delete relationship' %}
+ </strong>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3" class="center nowrap">
+ <input id="del_button" name="Button" type="button"
+ class="btn btn-secondary butt" value="{% trans 'Delete' %}">
+ <input id="cancel_button" type="button" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+</table>
+{% if has_query %}
+ {# options pane #}
+ <table id="designer_optionse" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" rowspan="2" id="option_col_name" class="center nowrap">
+ </td>
+ </tr>
+ </thead>
+ <tbody id="where">
+ <tr>
+ <td class="center nowrap">
+ <b>
+ WHERE
+ </b>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Relationship operator' %}
+ </td>
+ <td width="102">
+ <select name="rel_opt" id="rel_opt">
+ <option value="--" selected="selected">
+ --
+ </option>
+ <option value="=">
+ =
+ </option>
+ <option value="&gt;">
+ &gt;
+ </option>
+ <option value="&lt;">
+ &lt;
+ </option>
+ <option value="&gt;=">
+ &gt;=
+ </option>
+ <option value="&lt;=">
+ &lt;=
+ </option>
+ <option value="NOT">
+ NOT
+ </option>
+ <option value="IN">
+ IN
+ </option>
+ <option value="EXCEPT">
+ {% trans 'Except' %}
+ </option>
+ <option value="NOT IN">
+ NOT IN
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="nowrap">
+ {% trans 'Value' %}
+ <br>
+ {% trans 'subquery' %}
+ </td>
+ <td>
+ <textarea id="Query" cols="18"></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td class="center nowrap">
+ <b>
+ {% trans 'Rename to' %}
+ </b>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'New name' %}
+ </td>
+ <td width="102">
+ <input type="text" id="new_name">
+ </td>
+ </tr>
+ <tr>
+ <td class="center nowrap">
+ <b>
+ {% trans 'Aggregate' %}
+ </b>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="operator" id="operator">
+ <option value="---" selected="selected">
+ ---
+ </option>
+ <option value="sum" >
+ SUM
+ </option>
+ <option value="min">
+ MIN
+ </option>
+ <option value="max">
+ MAX
+ </option>
+ <option value="avg">
+ AVG
+ </option>
+ <option value="count">
+ COUNT
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="center nowrap">
+ <b>
+ GROUP BY
+ </b>
+ </td>
+ <td>
+ <input type="checkbox" value="groupby" id="groupby">
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="center nowrap">
+ <b>
+ ORDER BY
+ </b>
+ </td>
+ <td>
+ <select name="orderby" id="orderby">
+ <option value="---" selected="selected">
+ ---
+ </option>
+ <option value="ASC" >
+ ASC
+ </option>
+ <option value="DESC">
+ DESC
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="center nowrap">
+ <b>
+ HAVING
+ </b>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="h_operator" id="h_operator">
+ <option value="---" selected="selected">
+ ---
+ </option>
+ <option value="None" >
+ {% trans 'None' %}
+ </option>
+ <option value="sum" >
+ SUM
+ </option>
+ <option value="min">
+ MIN
+ </option>
+ <option value="max">
+ MAX
+ </option>
+ <option value="avg">
+ AVG
+ </option>
+ <option value="count">
+ COUNT
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Relationship operator' %}
+ </td>
+ <td width="102">
+ <select name="h_rel_opt" id="h_rel_opt">
+ <option value="--" selected="selected">
+ --
+ </option>
+ <option value="=">
+ =
+ </option>
+ <option value="&gt;">
+ &gt;
+ </option>
+ <option value="&lt;">
+ &lt;
+ </option>
+ <option value="&gt;=">
+ &gt;=
+ </option>
+ <option value="&lt;=">
+ &lt;=
+ </option>
+ <option value="NOT">
+ NOT
+ </option>
+ <option value="IN">
+ IN
+ </option>
+ <option value="EXCEPT">
+ {% trans 'Except' %}
+ </option>
+ <option value="NOT IN">
+ NOT IN
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Value' %}
+ <br>
+ {% trans 'subquery' %}
+ </td>
+ <td width="102">
+ <textarea id="having" cols="18"></textarea>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="hidden" id="ok_add_object_db_and_table_name_url" />
+ <input type="hidden" id="ok_add_object_db_name" />
+ <input type="hidden" id="ok_add_object_table_name" />
+ <input type="hidden" id="ok_add_object_col_name" />
+ <input type="button" id="ok_add_object" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input type="button" id="cancel_close_option" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ {# rename to pane #}
+ <table id="query_rename_to" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ {% trans 'Rename to' %}
+ </strong>
+ </td>
+ </tr>
+ </thead>
+ <tbody id="rename_to">
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'New name' %}
+ </td>
+ <td width="102">
+ <input type="text" id="e_rename">
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="button" id="ok_edit_rename" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input id="query_rename_to_button" type="button"
+ class="btn btn-secondary butt"
+ name="Button"
+ value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ {# having query panel #}
+ <table id="query_having" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ HAVING
+ </strong>
+ </td>
+ </tr>
+ </thead>
+ <tbody id="rename_to">
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="hoperator" id="hoperator">
+ <option value="---" selected="selected">
+ ---
+ </option>
+ <option value="None" >
+ None
+ </option>
+ <option value="sum" >
+ SUM
+ </option>
+ <option value="min">
+ MIN
+ </option>
+ <option value="max">
+ MAX
+ </option>
+ <option value="avg">
+ AVG
+ </option>
+ <option value="count">
+ COUNT
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="hrel_opt" id="hrel_opt">
+ <option value="--" selected="selected">
+ --
+ </option>
+ <option value="=">
+ =
+ </option>
+ <option value="&gt;">
+ &gt;
+ </option>
+ <option value="&lt;">
+ &lt;
+ </option>
+ <option value="&gt;=">
+ &gt;=
+ </option>
+ <option value="&lt;=">
+ &lt;=
+ </option>
+ <option value="NOT">
+ NOT
+ </option>
+ <option value="IN">
+ IN
+ </option>
+ <option value="EXCEPT">
+ {% trans 'Except' %}
+ </option>
+ <option value="NOT IN">
+ NOT IN
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="nowrap">
+ {% trans 'Value' %}
+ <br>
+ {% trans 'subquery' %}
+ </td>
+ <td>
+ <textarea id="hQuery" cols="18">
+ </textarea>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="button" id="ok_edit_having" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input id="query_having_button" type="button"
+ class="btn btn-secondary butt"
+ name="Button"
+ value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ {# aggregate query pane #}
+ <table id="query_Aggregate" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ {% trans 'Aggregate' %}
+ </strong>
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="operator" id="e_operator">
+ <option value="---" selected="selected">
+ ---
+ </option>
+ <option value="sum" >
+ SUM
+ </option>
+ <option value="min">
+ MIN
+ </option>
+ <option value="max">
+ MAX
+ </option>
+ <option value="avg">
+ AVG
+ </option>
+ <option value="count">
+ COUNT
+ </option>
+ </select>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="button" id="ok_edit_Aggr" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input id="query_Aggregate_Button" type="button"
+ class="btn btn-secondary butt"
+ name="Button"
+ value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ {# where query pane #}
+ <table id="query_where" class="hide" width="5%" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td class="frams1" width="10px">
+ </td>
+ <td class="frams5" width="99%" >
+ </td>
+ <td class="frams2" width="10px">
+ <div class="bor">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="frams8">
+ </td>
+ <td class="input_tab">
+ <table width="168" class="center" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <strong>
+ WHERE
+ </strong>
+ </td>
+ </tr>
+ </thead>
+ <tbody id="rename_to">
+ <tr>
+ <td width="58" class="nowrap">
+ {% trans 'Operator' %}
+ </td>
+ <td width="102">
+ <select name="erel_opt" id="erel_opt">
+ <option value="--" selected="selected">
+ --
+ </option>
+ <option value="=" >
+ =
+ </option>
+ <option value="&gt;">
+ &gt;
+ </option>
+ <option value="&lt;">
+ &lt;
+ </option>
+ <option value="&gt;=">
+ &gt;=
+ </option>
+ <option value="&lt;=">
+ &lt;=
+ </option>
+ <option value="NOT">
+ NOT
+ </option>
+ <option value="IN">
+ IN
+ </option>
+ <option value="EXCEPT">
+ {% trans 'Except' %}
+ </option>
+ <option value="NOT IN">
+ NOT IN
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="nowrap">
+ {% trans 'Value' %}
+ <br>
+ {% trans 'subquery' %}
+ </td>
+ <td>
+ <textarea id="eQuery" cols="18">
+ </textarea>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="center nowrap">
+ <input type="button" id="ok_edit_where" class="btn btn-secondary butt"
+ name="Button" value="{% trans 'OK' %}">
+ <input id="query_where_button" type="button" class="btn btn-secondary butt" name="Button"
+ value="{% trans 'Cancel' %}">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td class="frams6">
+ </td>
+ </tr>
+ <tr>
+ <td class="frams4">
+ <div class="bor">
+ </div>
+ </td>
+ <td class="frams7">
+ </td>
+ <td class="frams3">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ {# query details #}
+ <div class="panel">
+ <div class="clearfloat"></div>
+ <div id="ab"></div>
+ <div class="clearfloat"></div>
+ </div>
+ <a class="trigger" href="#">{% trans 'Active options' %}</a>
+ <div id="box">
+ <form method="post" action="db_qbe.php" id="vqb_form">
+ <textarea cols="80" name="sql_query" id="textSqlquery" rows="15"></textarea>
+ <input type="hidden" name="submit_sql" value="true">
+ {{ get_hidden_inputs(get_db) }}
+ </form>
+ </div>
+{% endif %}
+<div id="PMA_disable_floating_menubar"></div>
diff --git a/srcs/phpmyadmin/templates/database/designer/page_save_as.twig b/srcs/phpmyadmin/templates/database/designer/page_save_as.twig
new file mode 100644
index 0000000..bbcf34b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/page_save_as.twig
@@ -0,0 +1,37 @@
+<form action="db_designer.php" method="post" name="save_as_pages" id="save_as_pages" class="ajax">
+ {{ get_hidden_inputs(db) }}
+ <fieldset id="page_save_as_options">
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <input type="hidden" name="operation" value="savePage">
+ {% include 'database/designer/page_selector.twig' with {
+ 'pdfwork': pdfwork,
+ 'pages': pages
+ } only %}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {{ get_radio_fields(
+ 'save_page',
+ {
+ 'same': 'Save to selected page'|trans,
+ 'new': 'Create a page and save to it'|trans
+ },
+ 'same',
+ true
+ ) }}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <label for="selected_value">{% trans 'New page name' %}</label>
+ <input type="text" name="selected_value" id="selected_value">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/database/designer/page_selector.twig b/srcs/phpmyadmin/templates/database/designer/page_selector.twig
new file mode 100644
index 0000000..01c0650
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/page_selector.twig
@@ -0,0 +1,10 @@
+<select name="selected_page" id="selected_page">
+ <option value="0">-- {% trans 'Select page' %} --</option>
+ {% if pdfwork %}
+ {% for nr, desc in pages %}
+ <option value="{{ nr }}">
+ {{ desc }}
+ </option>
+ {% endfor %}
+ {% endif %}
+</select>
diff --git a/srcs/phpmyadmin/templates/database/designer/schema_export.twig b/srcs/phpmyadmin/templates/database/designer/schema_export.twig
new file mode 100644
index 0000000..71f15f2
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/designer/schema_export.twig
@@ -0,0 +1,9 @@
+<form method="post" action="schema_export.php" class="disableAjax" id="id_export_pages">
+ <fieldset>
+ {{ get_hidden_inputs(db) }}
+ <label>{% trans 'Select Export Relational Type' %}</label>
+ {{ get_choice('Schema', 'export_type', export_list, 'format') }}
+ <input type="hidden" name="page_number" value="{{ page }}">
+ {{ get_options('Schema', export_list) }}
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/database/multi_table_query/form.twig b/srcs/phpmyadmin/templates/database/multi_table_query/form.twig
new file mode 100644
index 0000000..068ceda
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/multi_table_query/form.twig
@@ -0,0 +1,184 @@
+{% include 'secondary_tabs.twig' with {
+ 'url_params': {
+ 'db': db
+ },
+ 'sub_tabs': [
+ {
+ 'link': 'db_multi_table_query.php',
+ 'text': 'Multi-table query'|trans
+ },
+ {
+ 'link': 'db_qbe.php',
+ 'text': 'Query by example'|trans
+ }
+ ]
+} only %}
+{% include 'div_for_slider_effect.twig' with {
+ 'id': 'query_div',
+ 'message': 'Query window'|trans,
+ 'initial_sliders_state': 'open',
+} only %}
+<form action="" id="query_form">
+ <input type="hidden" id="db_name" value="{{ db }}">
+ <fieldset>
+ {% for table in tables %}
+ <div style="display:none" id="{{ table.hash }}">
+ <option value="*">*</option>
+ {% for column in table.columns %}
+ <option value="{{ column }}">{{ column }}</option>
+ {% endfor %}
+ </div>
+ {% endfor %}
+
+ {% for id in 0..default_no_of_columns %}
+ {% if id == 0 %}<div style="display:none" id="new_column_layout">{% endif %}
+ <fieldset style="display:inline" class="column_details">
+ <select style="display:inline" class="tableNameSelect">
+ <option value="">{% trans 'select table' %}</option>
+ {% for table in tables|keys %}
+ <option value="{{ table }}">{{ table }}</option>
+ {% endfor %}
+ </select>
+ <span>.</span>
+ <select style="display:inline" class="columnNameSelect">
+ <option value="">{% trans 'select column' %}</option>
+ </select>
+ <br>
+ <input type="checkbox" checked="checked" class="show_col">
+ <span>{% trans 'Show' %}</span>
+ <br>
+ <input type="text" placeholder="{% trans 'Table alias' %}" class="table_alias">
+ <input type="text" placeholder="{% trans 'Column alias' %}" class="col_alias">
+ <br>
+ <input type="checkbox"
+ title="{% trans 'Use this column in criteria' %}"
+ class="criteria_col">
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': 'criteria_div' ~ id,
+ 'initial_sliders_state': 'closed',
+ 'message': 'criteria'|trans
+ } %}
+ <div>
+ <table>
+
+ <tr class="sort_order" style="background:none">
+ <td>{% trans 'Sort' %}</td>
+ <td><input type="radio" name="sort[{{ id }}]">{% trans 'Ascending' %}</td>
+ <td><input type="radio" name="sort[{{ id }}]">{% trans 'Descending' %}</td>
+ </tr>
+
+ <tr class="logical_operator" style="background:none;display:none">
+ <td>{% trans 'Add as' %}</td>
+ <td>
+ <input type="radio"
+ name="logical_op[{{ id }}]"
+ value="AND"
+ class="logical_op"
+ checked="checked">
+ AND
+ </td>
+ <td>
+ <input type="radio"
+ name="logical_op[{{ id }}]"
+ value="OR"
+ class="logical_op">
+ OR
+ </td>
+ </tr>
+
+ <tr style="background:none">
+ <td>Op </td>
+ <td>
+ <select class="criteria_op">
+ <option value="=">=</option>
+ <option value=">">&gt;</option>
+ <option value=">=">&gt;=</option>
+ <option value="<">&lt;</option>
+ <option value="<=">&lt;=</option>
+ <option value="!=">!=</option>
+ <option value="LIKE">LIKE</option>
+ <option value="LIKE %...%">LIKE %...%</option>
+ <option value="NOT LIKE">NOT LIKE</option>
+ <option value="IN (...)">IN (...)</option>
+ <option value="NOT IN (...)">NOT IN (...)</option>
+ <option value="BETWEEN">BETWEEN</option>
+ <option value="NOT BETWEEN">NOT BETWEEN</option>
+ <option value="IS NULL">IS NULL</option>
+ <option value="IS NOT NULL">IS NOT NULL</option>
+ <option value="REGEXP">REGEXP</option>
+ <option value="REGEXP ^...$">REGEXP ^...$</option>
+ <option value="NOT REGEXP">NOT REGEXP</option>
+ </select>
+ </td>
+ <td>
+ <select class="criteria_rhs">
+ <option value="text">{% trans 'Text' %}</option>
+ <option value="anotherColumn">{% trans 'Another column' %}</option>
+ </select>
+ </td>
+ </tr>
+
+ <tr class="rhs_table" style="display:none;background:none">
+ <td></td>
+ <td>
+ <select class="tableNameSelect">
+ <option value="">{% trans 'select table' %}</option>
+ {% for table in tables|keys %}
+ <option value="{{ table }}">{{ table }}</option>
+ {% endfor %}
+ </select><span>.</span>
+ </td>
+ <td>
+ <select style="display:inline" class="columnNameSelect">
+ <option value="">{% trans 'select column' %}</option>
+ </select>
+ </td>
+ </tr>
+
+ <tr style="background:none" class="rhs_text">
+ <td></td>
+ <td colspan="2">
+ <input type="text"
+ style="width:91%"
+ class="rhs_text_val"
+ placeholder="{% trans 'Enter criteria as free text' %}">
+ </td>
+ </tr>
+
+ </table>
+ </div>
+ </div>
+ <a href="#"
+ title="{% trans 'Remove this column' %}"
+ style="float:right;color:red"
+ class="removeColumn">
+ X
+ </a>
+ </fieldset>
+ {% if id == 0 %}</div>{% endif %}
+ {% endfor %}
+
+ <fieldset style="display:inline">
+ <input class="btn btn-secondary" type="button" value="{% trans '+ Add column' %}" id="add_column_button">
+ </fieldset>
+
+ <fieldset>
+ {% apply spaceless %}
+ <textarea id="MultiSqlquery"
+ cols="80"
+ rows="4"
+ style="float:left"
+ name="sql_query"
+ dir="ltr">
+ </textarea>
+ {% endapply %}
+ </fieldset>
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-secondary" type="button" id="update_query_button" value="{% trans 'Update query' %}">
+ <input class="btn btn-primary" type="button" id="submit_query" value="{% trans 'Submit query' %}">
+ </fieldset>
+</form>
+</div>{# Slider div #}
+<div id="sql_results"></div>
diff --git a/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig
new file mode 100644
index 0000000..071249f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig
@@ -0,0 +1,11 @@
+<td class="center">
+ <select name="criteriaColumn[{{ column_number }}]" size="1">
+ <option value="">&nbsp;</option>
+ {% for column in column_names %}
+ <option value="{{ column }}"
+ {%- if column is same as(selected) %} selected="selected"{% endif %}>
+ {{ column|e|replace({' ': '&nbsp;'}) }}
+ </option>
+ {% endfor %}
+ </select>
+</td>
diff --git a/srcs/phpmyadmin/templates/database/qbe/footer_options.twig b/srcs/phpmyadmin/templates/database/qbe/footer_options.twig
new file mode 100644
index 0000000..7f43f8d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/qbe/footer_options.twig
@@ -0,0 +1,16 @@
+<div class="floatleft">
+ {% if type == 'row' %}
+ {% trans 'Add/Delete criteria rows' %}:
+ {% else %}
+ {% trans 'Add/Delete columns' %}:
+ {% endif %}
+ <select size="1" name="{{ type == 'row' ? 'criteriaRowAdd' : 'criteriaColumnAdd' }}">
+ <option value="-3">-3</option>
+ <option value="-2">-2</option>
+ <option value="-1">-1</option>
+ <option value="0" selected="selected">0</option>
+ <option value="1">1</option>
+ <option value="2">2</option>
+ <option value="3">3</option>
+ </select>
+</div>
diff --git a/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig
new file mode 100644
index 0000000..7a63d77
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig
@@ -0,0 +1,10 @@
+<td class="center">
+ <select name="criteriaSortOrder[{{ column_number }}]">
+ <option value="1000">&nbsp;</option>
+ {% for i in 1..total_column_count %}
+ <option value="{{ i }}"{{ i == sort_order ? ' selected="selected"' }}>
+ {{ i }}
+ </option>
+ {% endfor %}
+ </select>
+</td>
diff --git a/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig
new file mode 100644
index 0000000..4f0989e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig
@@ -0,0 +1,9 @@
+<td class="center">
+ <select style="width:{{ real_width }}" name="criteriaSort[{{ column_number }}]" size="1">
+ <option value="">&nbsp;</option>
+ <option value="ASC"
+ {{- selected == 'ASC' ? ' selected="selected"' }}>{% trans 'Ascending' %}</option>
+ <option value="DESC"
+ {{- selected == 'DESC' ? ' selected="selected"' }}>{% trans 'Descending' %}</option>
+ </select>
+</td>
diff --git a/srcs/phpmyadmin/templates/database/search/main.twig b/srcs/phpmyadmin/templates/database/search/main.twig
new file mode 100644
index 0000000..45e5e71
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/search/main.twig
@@ -0,0 +1,84 @@
+<a id="db_search"></a>
+<form id="db_search_form" method="post" action="db_search.php" name="db_search" class="ajax lock-page">
+ {{ get_hidden_inputs(db) }}
+ <fieldset>
+ <legend>{% trans 'Search in database' %}</legend>
+ <p>
+ <label for="criteriaSearchString" class="displayblock">
+ {% trans 'Words or values to search for (wildcard: "%"):' %}
+ </label>
+ <input id="criteriaSearchString" name="criteriaSearchString" class="all85" type="text" value="
+ {{- criteria_search_string }}">
+ </p>
+
+ <fieldset>
+ <legend>{% trans 'Find:' %}</legend>
+ {# 4th parameter set to true to add line breaks #}
+ {# 5th parameter set to false to avoid htmlspecialchars() escaping
+ in the label since we have some HTML in some labels #}
+ {{ get_radio_fields(
+ 'criteriaSearchType',
+ choices,
+ criteria_search_type,
+ true,
+ false
+ ) }}
+ </fieldset>
+
+ <fieldset>
+ <legend>{% trans 'Inside tables:' %}</legend>
+ <p>
+ <a href="#" onclick="Functions.setSelectOptions('db_search', 'criteriaTables[]', true); return false;">
+ {% trans 'Select all' %}
+ </a> /
+ <a href="#" onclick="Functions.setSelectOptions('db_search', 'criteriaTables[]', false); return false;">
+ {% trans 'Unselect all' %}
+ </a>
+ </p>
+ <select name="criteriaTables[]" multiple>
+ {% for each_table in tables_names_only %}
+ <option value="{{ each_table }}"
+ {% if criteria_tables|length > 0 %}
+ {{- each_table in criteria_tables ? ' selected' }}
+ {% else %}
+ {{- ' selected' }}
+ {% endif %}
+ >
+ {{ each_table }}
+ </option>
+ {% endfor %}
+ </select>
+ </fieldset>
+
+ <p>
+ {# Inputbox for column name entry #}
+ <label for="criteriaColumnName" class="displayblock">
+ {% trans 'Inside column:' %}
+ </label>
+ <input id="criteriaColumnName" type="text" name="criteriaColumnName" class="all85" value="
+ {{- criteria_column_name is not empty ? criteria_column_name }}">
+ </p>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input id="buttonGo" class="btn btn-primary" type="submit" name="submit_search" value="{% trans 'Go' %}">
+ </fieldset>
+</form>
+<div id="togglesearchformdiv">
+ <a id="togglesearchformlink"></a>
+</div>
+<div id="searchresults"></div>
+<div id="togglesearchresultsdiv"><a id="togglesearchresultlink"></a></div>
+<br class="clearfloat">
+{# These two table-image and table-link elements display the table name in browse search results #}
+<div id="table-info">
+ <a id="table-link" class="item"></a>
+</div>
+{# Div for browsing results #}
+<div id="browse-results">
+ {# This browse-results div is used to load the browse and delete results in the db search #}
+</div>
+<div id="sqlqueryform" class="clearfloat">
+ {# This sqlqueryform div is used to load the delete form in the db search #}
+</div>
+{# Toggle query box link #}
+<a id="togglequerybox"></a>
diff --git a/srcs/phpmyadmin/templates/database/search/results.twig b/srcs/phpmyadmin/templates/database/search/results.twig
new file mode 100644
index 0000000..3d7a780
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/search/results.twig
@@ -0,0 +1,62 @@
+<table class="data">
+ <caption class="tblHeaders">
+ {{ 'Search results for "<em>%s</em>" %s:'|format(
+ criteria_search_string,
+ search_type_description
+ )|raw }}
+ </caption>
+ {% for row in rows %}
+ <tr class="noclick">
+ <td>
+ {% set result_message %}
+ {% trans %}
+ %1$s match in <strong>%2$s</strong>
+ {% plural row.result_count %}
+ %1$s matches in <strong>%2$s</strong>
+ {% endtrans %}
+ {% endset %}
+ {{ result_message|format(row.result_count, row.table)|raw }}
+ </td>
+ {% if row.result_count > 0 %}
+ {% set url_params = {
+ 'db': db,
+ 'table': row.table,
+ 'goto': 'db_sql.php',
+ 'pos': 0,
+ 'is_js_confirmed': 0
+ } %}
+ <td>
+ <a name="browse_search"
+ class="ajax browse_results"
+ href="sql.php{{ get_common(url_params) }}"
+ data-browse-sql="{{ row.new_search_sqls.select_columns }}"
+ data-table-name="{{ row.table }}">
+ {% trans 'Browse' %}
+ </a>
+ </td>
+ <td>
+ <a name="delete_search"
+ class="ajax delete_results"
+ href="sql.php{{ get_common(url_params) }}"
+ data-delete-sql="{{ row.new_search_sqls.delete }}"
+ data-table-name="{{ row.table }}">
+ {% trans 'Delete' %}
+ </a>
+ </td>
+ {% else %}
+ <td></td>
+ <td></td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+</table>
+
+{% if criteria_tables|length > 1 %}
+ <p>
+ {% trans %}
+ <strong>Total:</strong> <em>{{ count }}</em> match
+ {% plural result_total %}
+ <strong>Total:</strong> <em>{{ count }}</em> matches
+ {% endtrans %}
+ </p>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig b/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig
new file mode 100644
index 0000000..8dcebdf
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig
@@ -0,0 +1,95 @@
+<tbody id="tbl_summary_row">
+<tr>
+ <th class="print_ignore"></th>
+ <th class="tbl_num nowrap">
+ {% set num_tables_trans -%}
+ {% trans %}%s table{% plural num_tables %}%s tables{% endtrans %}
+ {%- endset %}
+ {{ num_tables_trans|format(format_number(num_tables, 0)) }}
+ </th>
+ {% if server_slave_status %}
+ <th>{% trans 'Replication' %}</th>
+ {% endif %}
+ {% set sum_colspan = db_is_system_schema ? 4 : 7 %}
+ {% if num_favorite_tables == 0 %}
+ {% set sum_colspan = sum_colspan - 1 %}
+ {% endif %}
+ <th colspan="{{ sum_colspan }}" class="print_ignore">{% trans 'Sum' %}</th>
+ {% set row_count_sum = format_number(sum_entries, 0) %}
+ {# If a table shows approximate rows count, display update-all-real-count anchor. #}
+ {% set row_sum_url = [] %}
+ {% if approx_rows is defined %}
+ {% set row_sum_url = {
+ 'ajax_request': true,
+ 'db': db,
+ 'real_row_count': 'true',
+ 'real_row_count_all': 'true'
+ } %}
+ {% endif %}
+ {% if approx_rows %}
+ {% set cell_text -%}
+ <a href="db_structure.php
+ {{- get_common(row_sum_url) }}" class="ajax row_count_sum">~
+ {{- row_count_sum -}}
+ </a>
+ {%- endset %}
+ {% else %}
+ {% set cell_text = row_count_sum %}
+ {% endif %}
+ <th class="value tbl_rows">{{ cell_text }}</th>
+ {% if not (properties_num_columns > 1) %}
+ {# MySQL <= 5.5.2 #}
+ {% set default_engine = dbi.fetchValue('SELECT @@storage_engine;') %}
+ {% if default_engine is empty %}
+ {# MySQL >= 5.5.3 #}
+ {% set default_engine = dbi.fetchValue('SELECT @@default_storage_engine;') %}
+ {% endif %}
+ <th class="center">
+ <dfn title="{{ '%s is the default storage engine on this MySQL server.'|trans|format(default_engine) }}">
+ {{ default_engine }}
+ </dfn>
+ </th>
+ <th>
+ {% if database_collation is not empty %}
+ <dfn title="{{ database_collation.description }} ({% trans 'Default' %})">
+ {{ database_collation.name }}
+ </dfn>
+ {% endif %}
+ </th>
+ {% endif %}
+
+ {% if is_show_stats %}
+ {% set sum = format_byte_down(sum_size, 3, 1) %}
+ {% set sum_formatted = sum[0] %}
+ {% set sum_unit = sum[1] %}
+ <th class="value tbl_size">{{ sum_formatted }} {{ sum_unit }}</th>
+
+ {% set overhead = format_byte_down(overhead_size, 3, 1) %}
+ {% set overhead_formatted = overhead[0] %}
+ {% set overhead_unit = overhead[1] %}
+ <th class="value tbl_overhead">{{ overhead_formatted }} {{ overhead_unit }}</th>
+ {% endif %}
+
+ {% if show_charset %}
+ <th>{{ database_charset }}</th>
+ {% endif %}
+ {% if show_comment %}
+ <th></th>
+ {% endif %}
+ {% if show_creation %}
+ <th class="value tbl_creation">
+ {{ create_time_all }}
+ </th>
+ {% endif %}
+ {% if show_last_update %}
+ <th class="value tbl_last_update">
+ {{ update_time_all }}
+ </th>
+ {% endif %}
+ {% if show_last_check %}
+ <th class="value tbl_last_check">
+ {{ check_time_all }}
+ </th>
+ {% endif %}
+</tr>
+</tbody>
diff --git a/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig b/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig
new file mode 100644
index 0000000..7a4e7e9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig
@@ -0,0 +1,40 @@
+<div class="clearfloat print_ignore">
+ <img class="selectallarrow" src="{{ pma_theme_image }}arrow_{{ text_dir }}.png" width="38" height="22" alt="{% trans 'With selected:' %}">
+ <input type="checkbox" id="tablesForm_checkall" class="checkall_box" title="{% trans 'Check all' %}">
+ <label for="tablesForm_checkall">{% trans 'Check all' %}</label>
+ {% if overhead_check != '' %}
+ / <a href="#" class="checkall-filter" data-checkall-selector=".tbl-overhead">{% trans 'Check tables having overhead' %}</a>
+ {% endif %}
+ <select name="submit_mult" style="margin: 0 3em 0 3em;">
+ <option value="{% trans 'With selected:' %}" selected="selected">{% trans 'With selected:' %}</option>
+ <option value="copy_tbl">{% trans 'Copy table' %}</option>
+ <option value="show_create">{% trans 'Show create' %}</option>
+ <option value="export">{% trans 'Export' %}</option>
+ {% if not db_is_system_schema and not disable_multi_table %}
+ <optgroup label="{% trans 'Delete data or table' %}">
+ <option value="empty_tbl">{% trans 'Empty' %}</option>
+ <option value="drop_tbl">{% trans 'Drop' %}</option>
+ </optgroup>
+ <optgroup label="{% trans 'Table maintenance' %}">
+ <option value="analyze_tbl">{% trans 'Analyze table' %}</option>
+ <option value="check_tbl">{% trans 'Check table' %}</option>
+ <option value="checksum_tbl">{% trans 'Checksum table' %}</option>
+ <option value="optimize_tbl">{% trans 'Optimize table' %}</option>
+ <option value="repair_tbl">{% trans 'Repair table' %}</option>
+ </optgroup>
+ <optgroup label="{% trans 'Prefix' %}">
+ <option value="add_prefix_tbl">{% trans 'Add prefix to table' %}</option>
+ <option value="replace_prefix_tbl">{% trans 'Replace table prefix' %}</option>
+ <option value="copy_tbl_change_prefix">{% trans 'Copy table with prefix' %}</option>
+ </optgroup>
+ {% endif %}
+ {% if central_columns_work is defined and central_columns_work %}
+ <optgroup label="{% trans 'Central columns' %}">
+ <option value="sync_unique_columns_central_list">{% trans 'Add columns to central list' %}</option>
+ <option value="delete_unique_columns_central_list">{% trans 'Remove columns from central list' %}</option>
+ <option value="make_consistent_with_central_list">{% trans 'Make consistent with central list' %}</option>
+ </optgroup>
+ {% endif %}
+ </select>
+ {{ hidden_fields|join('\n')|raw }}
+</div>
diff --git a/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig b/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig
new file mode 100644
index 0000000..91e002e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig
@@ -0,0 +1,7 @@
+<a id="{{ table_name_hash }}_favorite_anchor"
+ class="ajax favorite_table_anchor"
+ href="db_structure.php{{ get_common(fav_params) }}"
+ title="{{ already_favorite ? 'Remove from Favorites'|trans : 'Add to Favorites'|trans }}"
+ data-favtargets="{{ db_table_name_hash }}" >
+ {{ already_favorite ? titles['Favorite']|raw : titles['NoFavorite']|raw }}
+</a>
diff --git a/srcs/phpmyadmin/templates/database/structure/index.twig b/srcs/phpmyadmin/templates/database/structure/index.twig
new file mode 100644
index 0000000..1632839
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/index.twig
@@ -0,0 +1,24 @@
+{% if has_tables %}
+ <div id="tableslistcontainer">
+ {{ list_navigator_html|raw }}
+
+ {{ table_list_html|raw }}
+
+ {{ list_navigator_html|raw }}
+ </div>
+ <hr>
+ <p class="print_ignore">
+ <a href="#" id="printView">
+ {{ get_icon('b_print', 'Print'|trans, true) }}
+ </a>
+ <a href="db_datadict.php{{ get_common({'db': database, 'goto': 'db_structure.php'}) }}" target="print_view">
+ {{ get_icon('b_tblanalyse', 'Data dictionary'|trans, true) }}
+ </a>
+ </p>
+{% else %}
+ {{ 'No tables found in database.'|trans|notice }}
+{% endif %}
+
+{% if not is_system_schema %}
+ {{ create_table_html|raw }}
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/database/structure/show_create.twig b/srcs/phpmyadmin/templates/database/structure/show_create.twig
new file mode 100644
index 0000000..520e974
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/show_create.twig
@@ -0,0 +1,31 @@
+<div class="show_create_results">
+ <h2>{% trans 'Showing create queries' %}</h2>
+ {% set views = [] %}
+ {% set tables = [] %}
+ {% for object in db_objects %}
+ {% if dbi.getTable(db, object).isView() %}
+ {% set views = views|merge([object]) %}
+ {% else %}
+ {% set tables = tables|merge([object]) %}
+ {% endif %}
+ {% endfor %}
+ {% if tables is not empty %}
+ {% include 'database/structure/show_create_row.twig' with {
+ 'db': db,
+ 'title': 'Tables'|trans,
+ 'raw_title': 'Table',
+ 'db_objects': tables,
+ 'dbi': dbi
+ } only %}
+ {% endif %}
+
+ {% if views is not empty %}
+ {% include 'database/structure/show_create_row.twig' with {
+ 'db': db,
+ 'title': 'Views'|trans,
+ 'raw_title': 'View',
+ 'db_objects': views,
+ 'dbi': dbi
+ } only %}
+ {% endif %}
+</div>
diff --git a/srcs/phpmyadmin/templates/database/structure/show_create_row.twig b/srcs/phpmyadmin/templates/database/structure/show_create_row.twig
new file mode 100644
index 0000000..db18cdd
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/show_create_row.twig
@@ -0,0 +1,19 @@
+<fieldset>
+ <legend>{{ title }}</legend>
+ <table class="show_create">
+ <thead>
+ <tr>
+ <th>{{ raw_title }}</th>
+ <th>{{ 'Create %s'|trans|format(raw_title) }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for object in db_objects %}
+ <tr>
+ <td><strong>{{ object|mime_default_function }}</strong></td>
+ <td>{{ dbi.getTable(db, object).showCreate()|mime_default_function }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig b/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig
new file mode 100644
index 0000000..b87ea48
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig
@@ -0,0 +1,223 @@
+<tr id="row_tbl_{{ curr }}"{{ table_is_view ? ' class="is_view"' }} data-filter-row="{{ current_table['TABLE_NAME']|upper }}">
+ <td class="center print_ignore">
+ <input type="checkbox"
+ name="selected_tbl[]"
+ class="{{ input_class }}"
+ value="{{ current_table['TABLE_NAME'] }}"
+ id="checkbox_tbl_{{ curr }}">
+ </td>
+ <th>
+ <a href="sql.php{{ tbl_url_query|raw }}&amp;pos=0" title="{{ browse_table_label_title }}">
+ {{ browse_table_label_truename }}
+ </a>
+ {{ tracking_icon|raw }}
+ </th>
+ {% if server_slave_status %}
+ <td class="center">
+ {{ ignored ? get_image('s_cancel', 'Not replicated'|trans) }}
+ {{ do ? get_image('s_success', 'Replicated'|trans) }}
+ </td>
+ {% endif %}
+
+ {# Favorite table anchor #}
+ {% if num_favorite_tables > 0 %}
+ <td class="center print_ignore">
+ {# Check if current table is already in favorite list #}
+ {% set fav_params = {
+ 'db': db,
+ 'ajax_request': true,
+ 'favorite_table': current_table['TABLE_NAME'],
+ ((already_favorite ? 'remove' : 'add') ~ '_favorite'): true
+ } %}
+ {% include 'database/structure/favorite_anchor.twig' with {
+ 'table_name_hash': table_name_hash,
+ 'db_table_name_hash': db_table_name_hash,
+ 'fav_params': fav_params,
+ 'already_favorite': already_favorite,
+ 'titles': titles
+ } only %}
+ </td>
+ {% endif %}
+
+ <td class="center print_ignore">
+ <a href="sql.php{{ tbl_url_query|raw }}&amp;pos=0">
+ {{ browse_table_title|raw }}
+ </a>
+
+ </td>
+ <td class="center print_ignore">
+ <a href="tbl_structure.php{{ tbl_url_query|raw }}">
+ {{ titles['Structure']|raw }}
+ </a>
+ </td>
+ <td class="center print_ignore">
+ <a href="tbl_select.php{{ tbl_url_query|raw }}">
+ {{ search_table_title|raw }}
+ </a>
+ </td>
+
+ {% if not db_is_system_schema %}
+ <td class="insert_table center print_ignore">
+ <a href="tbl_change.php{{ tbl_url_query|raw }}">{{ titles['Insert']|raw }}</a>
+ </td>
+ {% if table_is_view %}
+ <td class="center print_ignore">
+ <a href="view_create.php{{- get_common({
+ 'db': db,
+ 'table': current_table['TABLE_NAME']
+ }) }}">{{ titles['Edit']|raw }}</a>
+ </td>
+ {% else %}
+ <td class="center print_ignore">
+ <a class="truncate_table_anchor ajax" href="sql.php" data-post="{{ tbl_url_query|raw }}&amp;sql_query=
+ {{- empty_table_sql_query }}&amp;message_to_show={{ empty_table_message_to_show }}">
+ {{ empty_table_title|raw }}
+ </a>
+ </td>
+ {% endif %}
+ <td class="center print_ignore">
+ <a class="ajax drop_table_anchor
+ {{- table_is_view or current_table['ENGINE'] == null ? ' view' }}"
+ href="sql.php" data-post="{{ tbl_url_query|raw }}&amp;reload=1&amp;purge=1&amp;sql_query=
+ {{- drop_query|url_encode }}&amp;message_to_show={{ drop_message|url_encode }}">
+ {{ titles['Drop']|raw }}
+ </a>
+ </td>
+ {% endif %}
+
+ {% if current_table['TABLE_ROWS'] is defined
+ and (current_table['ENGINE'] != null or table_is_view) %}
+ {# Get the row count #}
+ {% set row_count = format_number(current_table['TABLE_ROWS'], 0) %}
+
+ {# Content to be appended into 'tbl_rows' cell.
+ If row count is approximate, display it as an anchor to get real count. #}
+ <td class="value tbl_rows"
+ data-table="{{ current_table['TABLE_NAME'] }}">
+ {% if approx_rows %}
+ <a href="db_structure.php{{ get_common({
+ 'ajax_request': true,
+ 'db': db,
+ 'table': current_table['TABLE_NAME'],
+ 'real_row_count': 'true'
+ }) }}" class="ajax real_row_count">
+ <bdi>
+ ~{{ row_count }}
+ </bdi>
+ </a>
+ {% else %}
+ {{ row_count }}
+ {% endif %}
+ {{ show_superscript|raw }}
+ </td>
+
+ {% if not (properties_num_columns > 1) %}
+ <td class="nowrap">
+ {% if current_table['ENGINE'] is not empty %}
+ {{ current_table['ENGINE'] }}
+ {% elseif table_is_view %}
+ {% trans 'View' %}
+ {% endif %}
+ </td>
+ {% if collation|length > 0 %}
+ <td class="nowrap">
+ {{ collation|raw }}
+ </td>
+ {% endif %}
+ {% endif %}
+
+ {% if is_show_stats %}
+ <td class="value tbl_size">
+ <a href="tbl_structure.php{{ tbl_url_query|raw }}#showusage">
+ <span>{{ formatted_size }}</span>&nbsp;<span class="unit">{{ unit }}</span>
+ </a>
+ </td>
+ <td class="value tbl_overhead">
+ {{ overhead|raw }}
+ </td>
+ {% endif %}
+
+ {% if not (show_charset > 1) %}
+ {% if charset|length > 0 %}
+ <td class="nowrap">
+ {{ charset|raw }}
+ </td>
+ {% endif %}
+ {% endif %}
+
+ {% if show_comment %}
+ {% set comment = current_table['Comment'] %}
+ <td>
+ {% if comment|length > limit_chars %}
+ <abbr title="{{ comment }}">
+ {{ comment|slice(0, limit_chars) }}
+ ...
+ </abbr>
+ {% else %}
+ {{ comment }}
+ {% endif %}
+ </td>
+ {% endif %}
+
+ {% if show_creation %}
+ <td class="value tbl_creation">
+ {{ create_time }}
+ </td>
+ {% endif %}
+
+ {% if show_last_update %}
+ <td class="value tbl_last_update">
+ {{ update_time }}
+ </td>
+ {% endif %}
+
+ {% if show_last_check %}
+ <td class="value tbl_last_check">
+ {{ check_time }}
+ </td>
+ {% endif %}
+
+ {% elseif table_is_view %}
+ <td class="value tbl_rows">-</td>
+ <td class="nowrap">
+ {% trans 'View' %}
+ </td>
+ <td class="nowrap">---</td>
+ {% if is_show_stats %}
+ <td class="value tbl_size">-</td>
+ <td class="value tbl_overhead">-</td>
+ {% endif %}
+ {% if show_charset %}
+ <td></td>
+ {% endif %}
+ {% if show_comment %}
+ <td></td>
+ {% endif %}
+ {% if show_creation %}
+ <td class="value tbl_creation">-</td>
+ {% endif %}
+ {% if show_last_update %}
+ <td class="value tbl_last_update">-</td>
+ {% endif %}
+ {% if show_last_check %}
+ <td class="value tbl_last_check">-</td>
+ {% endif %}
+
+ {% else %}
+
+ {% if db_is_system_schema %}
+ {% set action_colspan = 3 %}
+ {% else %}
+ {% set action_colspan = 6 %}
+ {% endif %}
+ {% if num_favorite_tables > 0 %}
+ {% set action_colspan = action_colspan + 1 %}
+ {% endif %}
+
+ {% set colspan_for_structure = action_colspan + 3 %}
+ <td colspan="{{ colspan_for_structure - db_is_system_schema ? 6 : 9 }}"
+ class="center">
+ {% trans 'in use' %}
+ </td>
+ {% endif %}
+</tr>
diff --git a/srcs/phpmyadmin/templates/database/structure/table_header.twig b/srcs/phpmyadmin/templates/database/structure/table_header.twig
new file mode 100644
index 0000000..e479f5e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/table_header.twig
@@ -0,0 +1,78 @@
+<form method="post" action="db_structure.php" name="tablesForm" id="tablesForm">
+{{ get_hidden_inputs(db) }}
+<div class="responsivetable">
+<table id="structureTable" class="data">
+ <thead>
+ <tr>
+ <th class="print_ignore"></th>
+ <th>{{ sortable_table_header('Table'|trans, 'table') }}</th>
+ {% if replication %}
+ <th>{% trans 'Replication' %}</th>
+ {% endif %}
+
+ {% if db_is_system_schema %}
+ {% set action_colspan = 3 %}
+ {% else %}
+ {% set action_colspan = 6 %}
+ {% endif %}
+ {% if num_favorite_tables > 0 %}
+ {% set action_colspan = action_colspan + 1 %}
+ {% endif %}
+ <th colspan="{{ action_colspan }}" class="print_ignore">
+ {% trans 'Action' %}
+ </th>
+ {# larger values are more interesting so default sort order is DESC #}
+ <th>
+ {{ sortable_table_header('Rows'|trans, 'records', 'DESC') }}
+ {{ show_hint('May be approximate. Click on the number to get the exact count. See [doc@faq3-11]FAQ 3.11[/doc].'|trans|sanitize) }}
+ </th>
+ {% if not (properties_num_columns > 1) %}
+ <th>{{ sortable_table_header('Type'|trans, 'type') }}</th>
+ <th>{{ sortable_table_header('Collation'|trans, 'collation') }}</th>
+ {% endif %}
+
+ {% if is_show_stats %}
+ {# larger values are more interesting so default sort order is DESC #}
+ <th>{{ sortable_table_header('Size'|trans, 'size', 'DESC') }}</th>
+ {# larger values are more interesting so default sort order is DESC #}
+ <th>{{ sortable_table_header('Overhead'|trans, 'overhead', 'DESC') }}</th>
+ {% endif %}
+
+ {% if show_charset %}
+ <th>{{ sortable_table_header('Charset'|trans, 'charset') }}</th>
+ {% endif %}
+
+ {% if show_comment %}
+ <th>{{ sortable_table_header('Comment'|trans, 'comment') }}</th>
+ {% endif %}
+
+ {% if show_creation %}
+ {# newer values are more interesting so default sort order is DESC #}
+ <th>{{ sortable_table_header('Creation'|trans, 'creation', 'DESC') }}</th>
+ {% endif %}
+
+ {% if show_last_update %}
+ {# newer values are more interesting so default sort order is DESC #}
+ <th>{{ sortable_table_header('Last update'|trans, 'last_update', 'DESC') }}</th>
+ {% endif %}
+
+ {% if show_last_check %}
+ {# newer values are more interesting so default sort order is DESC #}
+ <th>{{ sortable_table_header('Last check'|trans, 'last_check', 'DESC') }}</th>
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for structure_table_row in structure_table_rows %}
+ {% include 'database/structure/structure_table_row.twig' with structure_table_row only %}
+ {% endfor %}
+ </tbody>
+ {% if body_for_table_summary %}
+ {% include 'database/structure/body_for_table_summary.twig' with body_for_table_summary only %}
+ {% endif %}
+</table>
+</div>
+{% if check_all_tables %}
+ {% include 'database/structure/check_all_tables.twig' with check_all_tables only %}
+{% endif %}
+</form>
diff --git a/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig b/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig
new file mode 100644
index 0000000..b09c9bb
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig
@@ -0,0 +1,7 @@
+<a href="tbl_tracking.php{{ get_common({'table': table, 'db': db}) }}">
+ {% if is_tracked -%}
+ {{ get_image('eye', 'Tracking is active.'|trans) }}
+ {%- else -%}
+ {{ get_image('eye_grey', 'Tracking is not active.'|trans) }}
+ {%- endif %}
+</a>
diff --git a/srcs/phpmyadmin/templates/database/tracking/tables.twig b/srcs/phpmyadmin/templates/database/tracking/tables.twig
new file mode 100644
index 0000000..7f95947
--- /dev/null
+++ b/srcs/phpmyadmin/templates/database/tracking/tables.twig
@@ -0,0 +1,161 @@
+{# Tracked tables exists#}
+{% if head_version_exists %}
+ <div id="tracked_tables">
+ <h3>{% trans 'Tracked tables' %}</h3>
+
+ <form method="post" action="db_tracking.php" name="trackedForm"
+ id="trackedForm" class="ajax">
+ {{ get_hidden_inputs(db) }}
+ <table id="versions" class="data">
+ <thead>
+ <tr>
+ <th></th>
+ <th>{% trans 'Table' %}</th>
+ <th>{% trans 'Last version' %}</th>
+ <th>{% trans 'Created' %}</th>
+ <th>{% trans 'Updated' %}</th>
+ <th>{% trans 'Status' %}</th>
+ <th>{% trans 'Action' %}</th>
+ <th>{% trans 'Show' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for version in versions %}
+ <tr>
+ <td class="center">
+ <input type="checkbox" name="selected_tbl[]"
+ class="checkall" id="selected_tbl_{{ version.table_name }}"
+ value="{{ version.table_name }}">
+ </td>
+ <th>
+ <label for="selected_tbl_{{ version.table_name }}">
+ {{ version.table_name }}
+ </label>
+ </th>
+ <td class="right">
+ {{ version.version }}
+ </td>
+ <td>
+ {{ version.date_created }}
+ </td>
+ <td>
+ {{ version.date_updated }}
+ </td>
+ <td>
+ {{ version.status_button|raw }}
+ </td>
+ <td>
+ <a class="delete_tracking_anchor ajax" href="db_tracking.php" data-post="
+ {{- get_common({
+ 'db': db,
+ 'goto': 'tbl_tracking.php',
+ 'back': 'db_tracking.php',
+ 'table': version.table_name,
+ 'delete_tracking': true
+ }, '') }}">
+ {{ get_icon('b_drop', 'Delete tracking'|trans) }}
+ </a>
+ </td>
+ <td>
+ <a href="tbl_tracking.php" data-post="
+ {{- get_common({
+ 'db': db,
+ 'goto': 'tbl_tracking.php',
+ 'back': 'db_tracking.php',
+ 'table': version.table_name
+ }, '') }}">
+ {{ get_icon('b_versions', 'Versions'|trans) }}
+ </a>
+ <a href="tbl_tracking.php" data-post="
+ {{- get_common({
+ 'db': db,
+ 'goto': 'tbl_tracking.php',
+ 'back': 'db_tracking.php',
+ 'table': version.table_name,
+ 'report': true,
+ 'version': version.version
+ }, '') }}">
+ {{ get_icon('b_report', 'Tracking report'|trans) }}
+ </a>
+ <a href="tbl_tracking.php" data-post="
+ {{- get_common({
+ 'db': db,
+ 'goto': 'tbl_tracking.php',
+ 'back': 'db_tracking.php',
+ 'table': version.table_name,
+ 'snapshot': true,
+ 'version': version.version
+ }, '') }}">
+ {{ get_icon('b_props', 'Structure snapshot'|trans) }}
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pma_theme_image,
+ 'text_dir': text_dir,
+ 'form_name': 'trackedForm'
+ } only %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Delete tracking'|trans,
+ 'b_drop',
+ 'delete_tracking'
+ ) }}
+ </form>
+ </div>
+{% endif %}
+{% if untracked_tables_exists %}
+ <h3>{% trans 'Untracked tables' %}</h3>
+ <form method="post" action="db_tracking.php" name="untrackedForm"
+ id="untrackedForm" class="ajax">
+ {{ get_hidden_inputs(db) }}
+ <table id="noversions" class="data">
+ <thead>
+ <tr>
+ <th></th>
+ <th>{% trans 'Table' %}</th>
+ <th>{% trans 'Action' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for table_name in untracked_tables %}
+ {% if get_tracker_version(db, table_name) == -1 %}
+ <tr>
+ <td class="center">
+ <input type="checkbox" name="selected_tbl[]"
+ class="checkall" id="selected_tbl_{{ table_name }}"
+ value="{{ table_name }}">
+ </td>
+ <th>
+ <label for="selected_tbl_{{ table_name }}">
+ {{ table_name }}
+ </label>
+ </th>
+ <td>
+ <a href="tbl_tracking.php{{ url_query|raw }}&amp;table={{ table_name }}">
+ {{ get_icon('eye', 'Track table'|trans) }}
+ </a>
+ </td>
+ </tr>
+ {% endif %}
+ {% endfor %}
+ </tbody>
+ </table>
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pma_theme_image,
+ 'text_dir': text_dir,
+ 'form_name': 'untrackedForm'
+ } only %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Track table'|trans,
+ 'eye',
+ 'track'
+ ) }}
+ </form>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/display/export/format_dropdown.twig b/srcs/phpmyadmin/templates/display/export/format_dropdown.twig
new file mode 100644
index 0000000..adda19b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/format_dropdown.twig
@@ -0,0 +1,4 @@
+<div class="exportoptions" id="format">
+ <h3>{% trans 'Format:' %}</h3>
+ {{ dropdown|raw }}
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig b/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig
new file mode 100644
index 0000000..fc7c04e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig
@@ -0,0 +1,23 @@
+{% if export_type == 'server' %}
+ {{ get_hidden_inputs('', '', 1) }}
+{% elseif export_type == 'database' %}
+ {{ get_hidden_inputs(db, '', 1) }}
+{% else %}
+ {{ get_hidden_inputs(db, table, 1) }}
+{% endif %}
+
+{# Just to keep this value for possible next display of this form after saving on server #}
+{% if single_table is not empty %}
+ <input type="hidden" name="single_table" value="TRUE">
+{% endif %}
+
+<input type="hidden" name="export_type" value="{{ export_type }}">
+
+{# The export method (quick, custom or custom-no-form) #}
+<input type="hidden" name="export_method" value="{{ export_method }}">
+
+{% if sql_query is not empty %}
+ <input type="hidden" name="sql_query" value="{{ sql_query }}">
+{% endif %}
+
+<input type="hidden" name="template_id" value="{{ template_id }}">
diff --git a/srcs/phpmyadmin/templates/display/export/method.twig b/srcs/phpmyadmin/templates/display/export/method.twig
new file mode 100644
index 0000000..5521f57
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/method.twig
@@ -0,0 +1,22 @@
+{% if export_method != 'custom-no-form' %}
+ <div class="exportoptions" id="quick_or_custom">
+ <h3>{% trans 'Export method:' %}</h3>
+ <ul>
+ <li>
+ <input type="radio" name="quick_or_custom" value="quick" id="radio_quick_export"
+ {{- export_method == 'quick' ? ' checked' }}>
+ <label for="radio_quick_export">
+ {% trans 'Quick - display only the minimal options' %}
+ </label>
+ </li>
+
+ <li>
+ <input type="radio" name="quick_or_custom" value="custom" id="radio_custom_export"
+ {{- export_method == 'custom' ? ' checked' }}>
+ <label for="radio_custom_export">
+ {% trans 'Custom - display all possible options' %}
+ </label>
+ </li>
+ </ul>
+ </div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/display/export/option_header.twig b/srcs/phpmyadmin/templates/display/export/option_header.twig
new file mode 100644
index 0000000..03e4f6b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/option_header.twig
@@ -0,0 +1,12 @@
+<div class="exportoptions" 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) }}
+ {% else %}
+ {{ 'Exporting rows from "%s" table'|trans|format(table) }}
+ {% endif %}
+ </h2>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/options_format.twig b/srcs/phpmyadmin/templates/display/export/options_format.twig
new file mode 100644
index 0000000..6b09814
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_format.twig
@@ -0,0 +1,24 @@
+<div class="exportoptions" id="format_specific_opts">
+ <h3>{% trans 'Format-specific options:' %}</h3>
+ <p class="no_js_msg" id="scroll_to_options_msg">
+ {% trans 'Scroll down to fill in the options for the selected format and ignore the options for other formats.' %}
+ </p>
+ {{ options|raw }}
+</div>
+
+{% if can_convert_kanji %}
+ {# Japanese encoding setting #}
+ <div class="exportoptions" id="kanji_encoding">
+ <h3>{% trans 'Encoding Conversion:' %}</h3>
+ {% include 'encoding/kanji_encoding_form.twig' %}
+ </div>
+{% endif %}
+
+<div class="exportoptions" id="submit">
+ <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Go' %}"
+ {#- If the time limit set is zero, then time out won't occur so no need
+ to check for time out. -#}
+ {%- if exec_time_limit > 0 %}
+ onclick="Export.checkTimeOut({{ exec_time_limit }})"
+ {%- endif %}>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output.twig b/srcs/phpmyadmin/templates/display/export/options_output.twig
new file mode 100644
index 0000000..60d721c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output.twig
@@ -0,0 +1,54 @@
+<div class="exportoptions" id="output">
+ <h3>{% trans 'Output:' %}</h3>
+ <ul id="ul_output">
+ <li>
+ <input type="checkbox" id="btn_alias_config"{{ has_aliases ? ' checked' }}>
+ <label for="btn_alias_config">
+ {% trans 'Rename exported databases/tables/columns' %}
+ </label>
+ </li>
+
+ {% if export_type != 'server' %}
+ <li>
+ <input type="checkbox" name="lock_tables"
+ value="something" id="checkbox_lock_tables"
+ {{- (not repopulate and is_checked_lock_tables) or lock_tables ? ' checked' }}>
+ <label for="checkbox_lock_tables">
+ {{ 'Use %s statement'|trans|format('<code>LOCK TABLES</code>')|raw }}
+ </label>
+ </li>
+ {% endif %}
+
+ <li>
+ <input type="radio" name="output_format" value="sendit" id="radio_dump_asfile"
+ {{- not repopulate and is_checked_asfile ? ' checked' }}>
+ <label for="radio_dump_asfile">
+ {% trans 'Save output to a file' %}
+ </label>
+ <ul id="ul_save_asfile">
+ {% if save_dir is not empty %}
+ {{ options_output_save_dir|raw }}
+ {% endif %}
+
+ {{ options_output_format|raw }}
+
+ {% if is_encoding_supported %}
+ {{ options_output_charset|raw }}
+ {% endif %}
+
+ {{ options_output_compression|raw }}
+
+ {% if export_type == 'server' or export_type == 'database' %}
+ {{ options_output_separate_files|raw }}
+ {% endif %}
+ </ul>
+ </li>
+
+ {{ options_output_radio|raw }}
+ </ul>
+
+ <label for="maxsize">
+ {{- 'Skip tables larger than %s MiB'|trans|format(
+ '</label><input type="text" id="maxsize" name="maxsize" size="4">'
+ )|raw }}
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_charset.twig b/srcs/phpmyadmin/templates/display/export/options_output_charset.twig
new file mode 100644
index 0000000..bd316bf
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_charset.twig
@@ -0,0 +1,16 @@
+<li>
+ <label for="select_charset" class="desc">
+ {% trans 'Character set of the file:' %}
+ </label>
+ <select id="select_charset" name="charset" size="1">
+ {% for charset in encodings %}
+ <option value="{{ charset }}"
+ {%- if (export_charset is empty and charset == 'utf-8')
+ or charset == export_charset %}
+ selected
+ {%- endif %}>
+ {{- charset -}}
+ </option>
+ {% endfor %}
+ </select>
+</li>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_compression.twig b/srcs/phpmyadmin/templates/display/export/options_output_compression.twig
new file mode 100644
index 0000000..1905981
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_compression.twig
@@ -0,0 +1,24 @@
+{% if is_zip or is_gzip %}
+ <li>
+ <label for="compression" class="desc">
+ {% trans 'Compression:' %}
+ </label>
+ <select id="compression" name="compression">
+ <option value="none">{% trans 'None' %}</option>
+ {% if is_zip %}
+ <option value="zip"
+ {{- selected_compression == 'zip' ? ' selected' }}>
+ {% trans 'zipped' %}
+ </option>
+ {% endif %}
+ {% if is_gzip %}
+ <option value="gzip"
+ {{- selected_compression == 'gzip' ? ' selected' }}>
+ {% trans 'gzipped' %}
+ </option>
+ {% endif %}
+ </select>
+ </li>
+{% else %}
+ <input type="hidden" name="compression" value="{{ selected_compression }}">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_format.twig b/srcs/phpmyadmin/templates/display/export/options_output_format.twig
new file mode 100644
index 0000000..d75d330
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_format.twig
@@ -0,0 +1,13 @@
+<li>
+ <label for="filename_template" class="desc">
+ {% trans 'File name template:' %}
+ {{ show_hint(message) }}
+ </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 ? ' checked' }}>
+ <label for="checkbox_remember_template">
+ {% trans 'use this for future exports' %}
+ </label>
+</li>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_radio.twig b/srcs/phpmyadmin/templates/display/export/options_output_radio.twig
new file mode 100644
index 0000000..7adf21e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_radio.twig
@@ -0,0 +1,7 @@
+<li>
+ <input type="radio" id="radio_view_as_text" name="output_format" value="astext"
+ {{- has_repopulate or export_asfile == false ? ' checked' }}>
+ <label for="radio_view_as_text">
+ {% trans 'View output as text' %}
+ </label>
+</li>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig b/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig
new file mode 100644
index 0000000..b4526aa
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig
@@ -0,0 +1,15 @@
+<li>
+ <input type="checkbox" name="onserver" value="saveit"
+ id="checkbox_dump_onserver"{{ export_is_checked ? ' checked' }}>
+ <label for="checkbox_dump_onserver">
+ {{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }}
+ </label>
+</li>
+<li>
+ <input type="checkbox" name="onserver_overwrite"
+ value="saveitover" id="checkbox_dump_onserver_overwrite"
+ {{- export_overwrite_is_checked ? ' checked' }}>
+ <label for="checkbox_dump_onserver_overwrite">
+ {% trans 'Overwrite existing file(s)' %}
+ </label>
+</li>
diff --git a/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig b/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig
new file mode 100644
index 0000000..fec85c4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig
@@ -0,0 +1,12 @@
+<li>
+ <input type="checkbox" id="checkbox_as_separate_files"
+ name="as_separate_files" value="{{ export_type }}"
+ {{- is_checked ? ' checked' }}>
+ <label for="checkbox_as_separate_files">
+ {% if export_type == 'server' %}
+ {% trans 'Export databases as separate files' %}
+ {% elseif export_type == 'database' %}
+ {% trans 'Export tables as separate files' %}
+ {% endif %}
+ </label>
+</li>
diff --git a/srcs/phpmyadmin/templates/display/export/options_quick_export.twig b/srcs/phpmyadmin/templates/display/export/options_quick_export.twig
new file mode 100644
index 0000000..b3bd159
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_quick_export.twig
@@ -0,0 +1,20 @@
+<div class="exportoptions" id="output_quick_export">
+ <h3>{% trans 'Output:' %}</h3>
+ <ul>
+ <li>
+ <input type="checkbox" name="quick_export_onserver" value="saveit"
+ id="checkbox_quick_dump_onserver"{{ export_is_checked ? ' checked' }}>
+ <label for="checkbox_quick_dump_onserver">
+ {{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }}
+ </label>
+ </li>
+ <li>
+ <input type="checkbox" name="quick_export_onserver_overwrite"
+ value="saveitover" id="checkbox_quick_dump_onserver_overwrite"
+ {{- export_overwrite_is_checked ? ' checked' }}>
+ <label for="checkbox_quick_dump_onserver_overwrite">
+ {% trans 'Overwrite existing file(s)' %}
+ </label>
+ </li>
+ </ul>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/options_rows.twig b/srcs/phpmyadmin/templates/display/export/options_rows.twig
new file mode 100644
index 0000000..1d4f866
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/options_rows.twig
@@ -0,0 +1,35 @@
+<div class="exportoptions" id="rows">
+ <h3>{% trans 'Rows:' %}</h3>
+ <ul>
+ <li>
+ <input type="radio" name="allrows" value="0" id="radio_allrows_0"
+ {{- allrows is not null and allrows == 0 ? ' checked' }}>
+ <label for="radio_allrows_0">{% trans 'Dump some row(s)' %}</label>
+ <ul>
+ <li>
+ <label for="limit_to">{% trans 'Number of rows:' %}</label>
+ <input type="text" id="limit_to" name="limit_to" size="5" value="
+ {%- apply spaceless %}
+ {% if limit_to is not null %}
+ {{ limit_to }}
+ {% elseif unlim_num_rows is not empty and unlim_num_rows != 0 %}
+ {{ unlim_num_rows }}
+ {% else %}
+ {{ number_of_rows }}
+ {% endif %}
+ {% endapply %}" onfocus="this.select()">
+ </li>
+ <li>
+ <label for="limit_from">{% trans 'Row to begin at:' %}</label>
+ <input type="text" id="limit_from" name="limit_from" size="5" value="
+ {{- limit_from is not null ? limit_from : 0 }}" onfocus="this.select()">
+ </li>
+ </ul>
+ </li>
+ <li>
+ <input type="radio" name="allrows" value="1" id="radio_allrows_1"
+ {{- allrows is null or allrows == 1 ? ' checked' }}>
+ <label for="radio_allrows_1">{% trans 'Dump all rows' %}</label>
+ </li>
+ </ul>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/select_options.twig b/srcs/phpmyadmin/templates/display/export/select_options.twig
new file mode 100644
index 0000000..4ca00ba
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/select_options.twig
@@ -0,0 +1,19 @@
+<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>
diff --git a/srcs/phpmyadmin/templates/display/export/selection.twig b/srcs/phpmyadmin/templates/display/export/selection.twig
new file mode 100644
index 0000000..6f691f5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/selection.twig
@@ -0,0 +1,10 @@
+<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>
diff --git a/srcs/phpmyadmin/templates/display/export/template_loading.twig b/srcs/phpmyadmin/templates/display/export/template_loading.twig
new file mode 100644
index 0000000..16eaa6d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/template_loading.twig
@@ -0,0 +1,27 @@
+<div class="exportoptions" id="export_templates">
+ <h3>{% trans 'Export templates:' %}</h3>
+
+ <div class="floatleft">
+ <form method="post" action="tbl_export.php" id="newTemplateForm" class="ajax">
+ <h4>{% trans 'New template:' %}</h4>
+ <input type="text" name="templateName" id="templateName"
+ maxlength="64" placeholder="{% trans 'Template name' %}" required>
+ <input class="btn btn-secondary" type="submit" name="createTemplate" id="createTemplate"
+ value="{% trans 'Create' %}">
+ </form>
+ </div>
+
+ <div class="floatleft" style="margin-left: 50px;">
+ <form method="post" action="tbl_export.php" id="existingTemplatesForm" class="ajax">
+ <h4>{% trans 'Existing templates:' %}</h4>
+ <label for="template">{% trans 'Template:' %}</label>
+ <select name="template" id="template" required>
+ {{ options|raw }}
+ </select>
+ <input class="btn btn-secondary" type="submit" name="updateTemplate" id="updateTemplate" value="{% trans 'Update' %}">
+ <input class="btn btn-secondary" type="submit" name="deleteTemplate" id="deleteTemplate" value="{% trans 'Delete' %}">
+ </form>
+ </div>
+
+ <div class="clearfloat"></div>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/export/template_options.twig b/srcs/phpmyadmin/templates/display/export/template_options.twig
new file mode 100644
index 0000000..ddcd4f5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/export/template_options.twig
@@ -0,0 +1,7 @@
+<option value="">-- {% trans 'Select a template' %} --</option>
+
+{% for template in templates %}
+ <option value="{{ template.id }}"{{ template.id == selected_template ? ' selected' }}>
+ {{ template.name }}
+ </option>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/display/import/import.twig b/srcs/phpmyadmin/templates/display/import/import.twig
new file mode 100644
index 0000000..dab14a3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/import/import.twig
@@ -0,0 +1,195 @@
+<iframe id="import_upload_iframe" name="import_upload_iframe" width="1" height="1" class="hide"></iframe>
+<div id="import_form_status" class="hide"></div>
+<div id="importmain">
+ <img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock" class="hide">
+
+ <script type="text/javascript">
+ //<![CDATA[
+ {% include 'display/import/javascript.twig' with {
+ 'upload_id': upload_id,
+ 'handler': handler,
+ 'pma_theme_image': pma_theme_image
+ } only %}
+ //]]>
+ </script>
+
+ <form id="import_file_form"
+ action="import.php"
+ method="post"
+ enctype="multipart/form-data"
+ name="import"
+ class="ajax"
+ {%- if handler != 'PhpMyAdmin\\Plugins\\Import\\Upload\\UploadNoplugin' %}
+ target="import_upload_iframe"
+ {%- endif %}>
+
+ <input type="hidden" name="{{ id_key }}" value="{{ upload_id }}">
+ {% if import_type == 'server' %}
+ {{ get_hidden_inputs('', '', 1) }}
+ {% elseif import_type == 'database' %}
+ {{ get_hidden_inputs(db, '', 1) }}
+ {% else %}
+ {{ get_hidden_inputs(db, table, 1) }}
+ {% endif %}
+ <input type="hidden" name="import_type" value="{{ import_type }}">
+
+ <div class="exportoptions" id="header">
+ <h2>
+ {{ get_image('b_import', 'Import'|trans) }}
+ {% if import_type == 'server' %}
+ {% trans 'Importing into the current server' %}
+ {% elseif import_type == 'database' %}
+ {{ 'Importing into the database "%s"'|trans|format(db) }}
+ {% else %}
+ {{ 'Importing into the table "%s"'|trans|format(table) }}
+ {% endif %}
+ </h2>
+ </div>
+
+ <div class="importoptions">
+ <h3>{% trans 'File to import:' %}</h3>
+
+ {# We don't have show anything about compression, when no supported #}
+ {% if compressions is not empty %}
+ <div class="formelementrow" id="compression_info">
+ <p>
+ {{ 'File may be compressed (%s) or uncompressed.'|trans|format(compressions|join(', ')) }}
+ <br>
+ {% trans 'A compressed file\'s name must end in <strong>.[format].[compression]</strong>. Example: <strong>.sql.zip</strong>' %}
+ </p>
+ </div>
+ {% endif %}
+
+ <div class="formelementrow" id="upload_form">
+ {% if is_upload and upload_dir is not empty %}
+ <ul>
+ <li>
+ <input type="radio" name="file_location" id="radio_import_file" required="required">
+ {{ get_browse_upload_file_block(max_upload_size) }}
+ {% trans 'You may also drag and drop a file on any page.' %}
+ </li>
+ <li>
+ <input type="radio" name="file_location" id="radio_local_import_file"
+ {%- if timeout_passed_global is not empty and local_import_file is not empty %}
+ checked="checked"
+ {%- endif %}>
+ {{ get_select_upload_file_block(
+ import_list,
+ upload_dir
+ ) }}
+ </li>
+ </ul>
+ {% elseif is_upload %}
+ {{ get_browse_upload_file_block(max_upload_size) }}
+ <p>{% trans 'You may also drag and drop a file on any page.' %}</p>
+ {% elseif not is_upload %}
+ {{ 'File uploads are not allowed on this server.'|trans|notice }}
+ {% elseif upload_dir is not empty %}
+ {{ get_select_upload_file_block(
+ import_list,
+ upload_dir
+ ) }}
+ {% endif %}
+ </div>
+
+ <div class="formelementrow" id="charaset_of_file">
+ {# Charset of file #}
+ <label for="charset_of_file">{% trans 'Character set of the file:' %}</label>
+ {% if is_encoding_supported %}
+ <select id="charset_of_file" name="charset_of_file" size="1">
+ {% for charset in encodings %}
+ <option value="{{ charset }}"
+ {% if (import_charset is empty and charset == 'utf-8')
+ or charset == import_charset %}
+ selected="selected"
+ {% endif %}>
+ {{ charset }}
+ </option>
+ {% endfor %}
+ </select>
+ {% else %}
+ <select lang="en" dir="ltr" name="charset_of_file" id="charset_of_file">
+ <option value=""></option>
+ {% for charset in charsets %}
+ <option value="{{ charset.name }}" title="{{ charset.description }}"
+ {{- charset.name == 'utf8' ? ' selected' }}>
+ {{- charset.name -}}
+ </option>
+ {% endfor %}
+ </select>
+ {% endif %}
+ </div>
+ </div>
+
+ <div class="importoptions">
+ <h3>{% trans 'Partial import:' %}</h3>
+
+ {% if timeout_passed is defined and timeout_passed %}
+ <div class="formelementrow">
+ <input type="hidden" name="skip" value="{{ offset }}">
+ {{ 'Previous import timed out, after resubmitting will continue from position %d.'|trans|format(offset) }}
+ </div>
+ {% endif %}
+
+ <div class="formelementrow">
+ <input type="checkbox" name="allow_interrupt" value="yes" id="checkbox_allow_interrupt"
+ {{ checkbox_check('Import', 'allow_interrupt') }}>
+ <label for="checkbox_allow_interrupt">
+ {% trans 'Allow the interruption of an import in case the script detects it is close to the PHP timeout limit. <em>(This might be a good way to import large files, however it can break transactions.)</em>' %}
+ </label>
+ </div>
+
+ {% if not (timeout_passed is defined and timeout_passed) %}
+ <div class="formelementrow">
+ <label for="text_skip_queries">
+ {% trans 'Skip this number of queries (for SQL) starting from the first one:' %}
+ </label>
+ <input type="number" name="skip_queries" value="
+ {{- get_default_plugin('Import', 'skip_queries') -}}
+ " id="text_skip_queries" min="0">
+ </div>
+ {% else %}
+ {# If timeout has passed,
+ do not show the Skip dialog to avoid the risk of someone
+ entering a value here that would interfere with "skip" #}
+ <input type="hidden" name="skip_queries" value="
+ {{- get_default_plugin('Import', 'skip_queries') -}}
+ " id="text_skip_queries">
+ {% endif %}
+ </div>
+
+ <div class="importoptions">
+ <h3>{% trans 'Other options:' %}</h3>
+ <div class="formelementrow">
+ {{ get_fk_checkbox() }}
+ </div>
+ </div>
+
+ <div class="importoptions">
+ <h3>{% trans 'Format:' %}</h3>
+ {{ get_choice('Import', 'format', import_list) }}
+ <div id="import_notification"></div>
+ </div>
+
+ <div class="importoptions" id="format_specific_opts">
+ <h3>{% trans 'Format-specific options:' %}</h3>
+ <p class="no_js_msg" id="scroll_to_options_msg">
+ {% trans 'Scroll down to fill in the options for the selected format and ignore the options for other formats.' %}
+ </p>
+ {{ get_options('Import', import_list) }}
+ </div>
+ <div class="clearfloat"></div>
+
+ {# Japanese encoding setting #}
+ {% if can_convert_kanji %}
+ <div class="importoptions" id="kanji_encoding">
+ <h3>{% trans 'Encoding Conversion:' %}</h3>
+ {% include 'encoding/kanji_encoding_form.twig' %}
+ </div>
+ {% endif %}
+
+ <div class="importoptions" id="submit">
+ <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </div>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/display/import/javascript.twig b/srcs/phpmyadmin/templates/display/import/javascript.twig
new file mode 100644
index 0000000..ec91e3c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/import/javascript.twig
@@ -0,0 +1,162 @@
+$( function() {
+ {# Add event when user click on "Go" button #}
+ $("#buttonGo").on("click", function() {
+ {# Hide form #}
+ $("#upload_form_form").css("display", "none");
+
+ {% if handler != 'PhpMyAdmin\\Plugins\\Import\\Upload\\UploadNoplugin' %}
+ {# Some variable for javascript #}
+ {% set ajax_url = 'import_status.php?id=' ~ upload_id ~ get_common_raw({
+ 'import_status': 1
+ }, '&') %}
+ {% set promot_str = 'The file being uploaded is probably larger than the maximum allowed size or this is a known bug in webkit based (Safari, Google Chrome, Arora etc.) browsers.'|trans|js_format(false) %}
+ {% set statustext_str = '%s of %s'|trans|escape_js_string %}
+ {% set second_str = '%s/sec.'|trans|js_format(false) %}
+ {% set remaining_min = 'About %MIN min. %SEC sec. remaining.'|trans|js_format(false) %}
+ {% set remaining_second = 'About %SEC sec. remaining.'|trans|js_format(false) %}
+ {% set processed_str = 'The file is being processed, please be patient.'|trans|js_format(false) %}
+ {% set import_url = get_common_raw({'import_status': 1}, '&') %}
+
+ {% set upload_html %}
+ {% apply spaceless %}
+ <div class="upload_progress">
+ <div class="upload_progress_bar_outer">
+ <div class="percentage"></div>
+ <div id="status" class="upload_progress_bar_inner">
+ <div class="percentage"></div>
+ </div>
+ </div>
+ <div>
+ <img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ 'Uploading your import file…'|trans|js_format(false) -}}
+ </div>
+ <div id="statustext"></div>
+ </div>
+ {% endapply %}
+ {% endset %}
+
+ {# Start output #}
+ var finished = false;
+ var percent = 0.0;
+ var total = 0;
+ var complete = 0;
+ var original_title = parent && parent.document ? parent.document.title : false;
+ var import_start;
+
+ var perform_upload = function () {
+ new $.getJSON(
+ "{{ ajax_url|raw }}",
+ {},
+ function(response) {
+ finished = response.finished;
+ percent = response.percent;
+ total = response.total;
+ complete = response.complete;
+
+ if (total==0 && complete==0 && percent==0) {
+ $("#upload_form_status_info").html('<img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ promot_str|raw }}');
+ $("#upload_form_status").css("display", "none");
+ } else {
+ var now = new Date();
+ now = Date.UTC(
+ now.getFullYear(),
+ now.getMonth(),
+ now.getDate(),
+ now.getHours(),
+ now.getMinutes(),
+ now.getSeconds())
+ + now.getMilliseconds() - 1000;
+ var statustext = Functions.sprintf(
+ "{{ statustext_str|raw }}",
+ Functions.formatBytes(
+ complete, 1, Messages.strDecimalSeparator
+ ),
+ Functions.formatBytes(
+ total, 1, Messages.strDecimalSeparator
+ )
+ );
+
+ if ($("#importmain").is(":visible")) {
+ {# Show progress UI #}
+ $("#importmain").hide();
+ $("#import_form_status")
+ .html('{{ upload_html|raw }}')
+ .show();
+ import_start = now;
+ }
+ else if (percent > 9 || complete > 2000000) {
+ {# Calculate estimated time #}
+ var used_time = now - import_start;
+ var seconds = parseInt(((total - complete) / complete) * used_time / 1000);
+ var speed = Functions.sprintf(
+ "{{ second_str|raw }}",
+ Functions.formatBytes(complete / used_time * 1000, 1, Messages.strDecimalSeparator)
+ );
+
+ var minutes = parseInt(seconds / 60);
+ seconds %= 60;
+ var estimated_time;
+ if (minutes > 0) {
+ estimated_time = "{{ remaining_min|raw }}"
+ .replace("%MIN", minutes)
+ .replace("%SEC", seconds);
+ }
+ else {
+ estimated_time = "{{ remaining_second|raw }}"
+ .replace("%SEC", seconds);
+ }
+
+ statustext += "<br>" + speed + "<br><br>" + estimated_time;
+ }
+
+ var percent_str = Math.round(percent) + "%";
+ $("#status").animate({width: percent_str}, 150);
+ $(".percentage").text(percent_str);
+
+ {# Show percent in window title #}
+ if (original_title !== false) {
+ parent.document.title
+ = percent_str + " - " + original_title;
+ }
+ else {
+ document.title
+ = percent_str + " - " + original_title;
+ }
+ $("#statustext").html(statustext);
+ }
+
+ if (finished == true) {
+ if (original_title !== false) {
+ parent.document.title = original_title;
+ }
+ else {
+ document.title = original_title;
+ }
+ $("#importmain").hide();
+ {# Loads the message, either success or mysql error #}
+ $("#import_form_status")
+ .html('<img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ processed_str|raw }}')
+ .show();
+ $("#import_form_status").load("import_status.php?message=true&{{ import_url|raw }}");
+ Navigation.reload();
+
+ {# If finished #}
+ }
+ else {
+ setTimeout(perform_upload, 1000);
+ }
+ });
+ };
+ setTimeout(perform_upload, 1000);
+ {% else %}
+ {# No plugin available #}
+ {% set image_tag -%}
+ <img src="{{ pma_theme_image -}}
+ ajax_clock_small.gif" width="16" height="16" alt="ajax clock">
+ {{- 'Please be patient, the file is being uploaded. Details about the upload are not available.'|trans|js_format(false) -}}
+ {{- show_docu('faq', 'faq2-9') -}}
+ {%- endset %}
+ $('#upload_form_status_info').html('{{ image_tag|raw }}');
+ $("#upload_form_status").css("display", "none");
+ {% endif %}
+ });
+});
diff --git a/srcs/phpmyadmin/templates/display/results/comment_for_row.twig b/srcs/phpmyadmin/templates/display/results/comment_for_row.twig
new file mode 100644
index 0000000..f232375
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/comment_for_row.twig
@@ -0,0 +1,10 @@
+{% if comments_map[fields_meta.table] is defined
+ and comments_map[fields_meta.table][fields_meta.name] is defined %}
+ <br><span class="tblcomment" title="{{ comments_map[fields_meta.table][fields_meta.name] }}">
+ {% if comments_map[fields_meta.table][fields_meta.name]|length > limit_chars %}
+ {{ comments_map[fields_meta.table][fields_meta.name]|slice(0, limit_chars) }}…
+ {% else %}
+ {{ comments_map[fields_meta.table][fields_meta.name] }}
+ {% endif %}
+ </span>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig b/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig
new file mode 100644
index 0000000..6a345e7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig
@@ -0,0 +1,9 @@
+{% if column_order %}
+ <input class="col_order" type="hidden" value="{{ column_order|join(',') }}">
+{% endif %}
+{% if column_visibility %}
+ <input class="col_visib" type="hidden" value="{{ column_visibility|join(',') }}">
+{% endif %}
+{% if not is_view %}
+ <input class="table_create_time" type="hidden" value="{{ table_create_time }}">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/display/results/empty_display.twig b/srcs/phpmyadmin/templates/display/results/empty_display.twig
new file mode 100644
index 0000000..cd43ebc
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/empty_display.twig
@@ -0,0 +1 @@
+<td {{ align }} class="{{ classes }}"></td>
diff --git a/srcs/phpmyadmin/templates/display/results/null_display.twig b/srcs/phpmyadmin/templates/display/results/null_display.twig
new file mode 100644
index 0000000..f2ea2e5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/null_display.twig
@@ -0,0 +1,7 @@
+<td {{ align }}
+ data-decimals="{{ meta.decimals is defined ? meta.decimals : '-1' }}"
+ data-type="{{ meta.type }}"
+ {# The null class is needed for grid editing #}
+ class="{{ classes }} null">
+ <em>NULL</em>
+</td>
diff --git a/srcs/phpmyadmin/templates/display/results/options_block.twig b/srcs/phpmyadmin/templates/display/results/options_block.twig
new file mode 100644
index 0000000..d185fec
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/options_block.twig
@@ -0,0 +1,121 @@
+<form method="post" action="sql.php" name="displayOptionsForm" class="ajax print_ignore">
+ {{ get_hidden_inputs({
+ 'db': db,
+ 'table': table,
+ 'sql_query': sql_query,
+ 'goto': goto,
+ 'display_options_form': 1
+ }) }}
+
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': '',
+ 'message': 'Options'|trans,
+ 'initial_sliders_state': default_sliders_state
+ } only %}
+ <fieldset>
+ <div class="formelement">
+ {# pftext means "partial or full texts" (done to reduce line lengths #}
+ {{ get_radio_fields(
+ 'pftext',
+ {
+ 'P': 'Partial texts'|trans,
+ 'F': 'Full texts'|trans
+ },
+ pftext,
+ true,
+ true,
+ '',
+ 'pftext_' ~ unique_id
+ ) }}
+ </div>
+
+ {% if relwork and displaywork %}
+ <div class="formelement">
+ {{ get_radio_fields(
+ 'relational_display',
+ {
+ 'K': 'Relational key'|trans,
+ 'D': 'Display column for relationships'|trans
+ },
+ relational_display,
+ true,
+ true,
+ '',
+ 'relational_display_' ~ unique_id
+ ) }}
+ </div>
+ {% endif %}
+
+ <div class="formelement">
+ {% include 'checkbox.twig' with {
+ 'html_field_name': 'display_binary',
+ 'label': 'Show binary contents'|trans,
+ 'checked': display_binary is not empty,
+ 'onclick': false,
+ 'html_field_id': 'display_binary_' ~ unique_id
+ } only %}
+ {% include 'checkbox.twig' with {
+ 'html_field_name': 'display_blob',
+ 'label': 'Show BLOB contents'|trans,
+ 'checked': display_blob is not empty,
+ 'onclick': false,
+ 'html_field_id': 'display_blob_' ~ unique_id
+ } only %}
+ </div>
+
+ {# I would have preferred to name this "display_transformation".
+ This is the only way I found to be able to keep this setting sticky
+ per SQL query, and at the same time have a default that displays
+ the transformations. #}
+ <div class="formelement">
+ {% include 'checkbox.twig' with {
+ 'html_field_name': 'hide_transformation',
+ 'label': 'Hide browser transformation'|trans,
+ 'checked': hide_transformation is not empty,
+ 'onclick': false,
+ 'html_field_id': 'hide_transformation_' ~ unique_id
+ } only %}
+ </div>
+
+
+ {% if possible_as_geometry %}
+ <div class="formelement">
+ {{ get_radio_fields(
+ 'geoOption',
+ {
+ 'GEOM': 'Geometry'|trans,
+ 'WKT': 'Well Known Text'|trans,
+ 'WKB': 'Well Known Binary'|trans
+ },
+ geo_option,
+ true,
+ true,
+ '',
+ 'geoOption_' ~ unique_id
+ ) }}
+ </div>
+ {% else %}
+ <div class="formelement">
+ {{ possible_as_geometry }}
+ {{ get_radio_fields(
+ 'geoOption',
+ {
+ 'WKT': 'Well Known Text'|trans,
+ 'WKB': 'Well Known Binary'|trans
+ },
+ geo_option,
+ true,
+ true,
+ '',
+ 'geoOption_' ~ unique_id
+ ) }}
+ </div>
+ {% endif %}
+ <div class="clearfloat"></div>
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </fieldset>
+ </div>{# slider effect div #}
+</form>
diff --git a/srcs/phpmyadmin/templates/display/results/page_selector.twig b/srcs/phpmyadmin/templates/display/results/page_selector.twig
new file mode 100644
index 0000000..1791270
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/page_selector.twig
@@ -0,0 +1,6 @@
+<td>
+ <form action="sql.php" method="post">
+ {{ get_hidden_inputs(url_params) }}
+ {{ page_selector|raw }}
+ </form>
+</td>
diff --git a/srcs/phpmyadmin/templates/display/results/sort_by_key.twig b/srcs/phpmyadmin/templates/display/results/sort_by_key.twig
new file mode 100644
index 0000000..fb26f10
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/sort_by_key.twig
@@ -0,0 +1,9 @@
+<form action="sql.php" method="post" class="print_ignore">
+ {{ get_hidden_fields(hidden_fields) }}
+ {% trans 'Sort by key:' %}
+ <select name="sql_query" class="autosubmit">
+ {% for option in options %}
+ <option value="{{ option.value }}"{{ option.is_selected ? ' selected' }}>{{ option.content }}</option>
+ {% endfor %}
+ </select>
+</form>
diff --git a/srcs/phpmyadmin/templates/display/results/table.twig b/srcs/phpmyadmin/templates/display/results/table.twig
new file mode 100644
index 0000000..760ca1c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/table.twig
@@ -0,0 +1,11 @@
+{{ sql_query_message|raw }}
+{{ navigation|raw }}
+{{ headers|raw }}
+<tbody>
+ {{ body|raw }}
+</tbody>
+</table>
+</div>
+{{ multi_row_operation_links|raw }}
+{{ navigation|raw }}
+{{ operations|raw }}
diff --git a/srcs/phpmyadmin/templates/display/results/table_headers.twig b/srcs/phpmyadmin/templates/display/results/table_headers.twig
new file mode 100644
index 0000000..506a6c0
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/table_headers.twig
@@ -0,0 +1,23 @@
+<input class="save_cells_at_once" type="hidden" value="{{ save_cells_at_once }}">
+<div class="common_hidden_inputs">
+ {{ get_hidden_inputs(db, table) }}
+</div>
+
+{{ data_for_resetting_column_order|raw }}
+{{ options_block|raw }}
+
+{% if delete_link == delete_row or delete_link == kill_process %}
+ <form method="post" action="tbl_row_action.php" name="resultsForm" id="resultsForm_{{ unique_id }}" class="ajax">
+ {{ get_hidden_inputs(db, table, 1) }}
+ <input type="hidden" name="goto" value="sql.php">
+{% endif %}
+
+<div class="responsivetable">
+ <table class="table_results data ajax" data-uniqueId="{{ unique_id }}">
+
+ {{ button|raw }}
+ {{ table_headers_for_columns|raw }}
+ {{ column_at_right_side|raw }}
+
+ </tr>
+ </thead>
diff --git a/srcs/phpmyadmin/templates/display/results/table_navigation.twig b/srcs/phpmyadmin/templates/display/results/table_navigation.twig
new file mode 100644
index 0000000..0746243
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/table_navigation.twig
@@ -0,0 +1,82 @@
+<table class="navigation nospacing nopadding print_ignore">
+ <tr>
+ <td class="navigation_separator"></td>
+ {{ move_backward_buttons|raw }}
+ {{ page_selector|raw }}
+ {{ move_forward_buttons|raw }}
+ {% if number_total_page > 1 %}
+ <td><div class="navigation_separator">|</div></td>
+ {% endif %}
+ {% if has_show_all %}
+ <td>
+ <form action="sql.php" method="post">
+ {{ get_hidden_fields(hidden_fields|merge({
+ 'session_max_rows': session_max_rows,
+ 'pos': '0'
+ })) }}
+ <input type="checkbox" name="navig" id="showAll_{{ unique_id }}" class="showAllRows" value="all"
+ {{- is_showing_all ? ' checked' }}>
+ <label for="showAll_{{ unique_id }}">{% trans 'Show all' %}</label>
+ </form>
+ </td>
+ <td><div class="navigation_separator">|</div></td>
+ {% endif %}
+ <td>
+ <div class="save_edited hide">
+ <input class="btn btn-link" type="submit" value="{% trans 'Save edited data' %}">
+ <div class="navigation_separator">|</div>
+ </div>
+ </td>
+ <td>
+ <div class="restore_column hide">
+ <input class="btn btn-link" type="submit" value="{% trans 'Restore column order' %}">
+ <div class="navigation_separator">|</div>
+ </div>
+ </td>
+ <td class="navigation_goto">
+ {# if displaying a VIEW, $unlim_num_rows could be zero because #}
+ {# of $cfg['MaxExactCountViews']; in this case, avoid passing #}
+ {# the 5th parameter to Functions.checkFormElementInRange() #}
+ {# (this means we can't validate the upper limit) #}
+ <form action="sql.php" method="post" onsubmit="return (Functions.checkFormElementInRange(this, 'session_max_rows', '
+ {{- '%d is not valid row number.'|trans|replace({'\'': '\\\''}) -}}
+ ', 1) && Functions.checkFormElementInRange(this, 'pos', '
+ {{- '%d is not valid row number.'|trans|replace({'\'': '\\\''}) -}}
+ ', 0
+ {{- unlim_num_rows > 0 ? ', ' ~ (unlim_num_rows - 1) -}}
+ ));">
+
+ {{ get_hidden_fields(hidden_fields|merge({
+ 'pos': pos
+ })) }}
+
+ {% trans 'Number of rows:' %}
+
+ {{ get_dropdown(
+ 'session_max_rows',
+ {
+ '25': 25,
+ '50': 50,
+ '100': 100,
+ '250': 250,
+ '500': 500,
+ },
+ max_rows,
+ '',
+ 'autosubmit',
+ is_showing_all ? 'All'|trans
+ ) }}
+ </form>
+ </td>
+ <td class="navigation_separator"></td>
+ <td class="largescreenonly">
+ <span>{% trans 'Filter rows' %}:</span>
+ <input type="text" class="filter_rows" placeholder="
+ {%- trans 'Search this table' %}" data-for="{{ unique_id }}">
+ </td>
+ <td class="largescreenonly">
+ {{ sort_by_key|raw }}
+ </td>
+ <td class="navigation_separator"></td>
+ </tr>
+</table>
diff --git a/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig b/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig
new file mode 100644
index 0000000..2573c0c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig
@@ -0,0 +1,12 @@
+<td>
+ <form action="sql.php" method="post"{{ onsubmit|raw }}>
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="sql_query" value="{{ sql_query|raw }}">
+ <input type="hidden" name="pos" value="{{ pos }}">
+ <input type="hidden" name="is_browse_distinct" value="{{ is_browse_distinct }}">
+ <input type="hidden" name="goto" value="{{ goto }}">
+ {{ input_for_real_end|raw }}
+ <input type="submit" name="navig" class="btn btn-secondary ajax" value="{{ caption_output|raw }}" title="{{ title }}"
+ {{- onclick|raw }}>
+ </form>
+</td>
diff --git a/srcs/phpmyadmin/templates/display/results/value_display.twig b/srcs/phpmyadmin/templates/display/results/value_display.twig
new file mode 100644
index 0000000..35640b9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/display/results/value_display.twig
@@ -0,0 +1,3 @@
+<td class="left {{ class }}{{ condition_field ? ' condition' }}">
+ {{ value|raw }}
+</td>
diff --git a/srcs/phpmyadmin/templates/div_for_slider_effect.twig b/srcs/phpmyadmin/templates/div_for_slider_effect.twig
new file mode 100644
index 0000000..6453999
--- /dev/null
+++ b/srcs/phpmyadmin/templates/div_for_slider_effect.twig
@@ -0,0 +1,16 @@
+{% if initial_sliders_state == 'disabled' %}
+ <div{% if id is defined %} id="{{ id }}"{% endif %}>
+{% else %}
+ {#
+ Bad hack on the next line. document.write() conflicts with jQuery,
+ hence, opening the <div> with PHP itself instead of JavaScript.
+
+ @todo find a better solution that uses $.append(), the recommended
+ method maybe by using an additional param, the id of the div to
+ append to
+ #}
+ <div{% if id is defined %} id="{{ id }}"
+ {%- endif %} {% if initial_sliders_state == 'closed' -%}
+ style="display: none; overflow:auto;"{% endif %} class="pma_auto_slider"
+ {%- if message is defined %} title="{{ message }}"{% endif %}>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/dropdown.twig b/srcs/phpmyadmin/templates/dropdown.twig
new file mode 100644
index 0000000..6258ca7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/dropdown.twig
@@ -0,0 +1,11 @@
+<select name="{{ select_name }}"{% if id is not empty %} id="{{ id }}"{% endif -%}
+ {%- if class is not empty %} class="{{ class }}"{% endif %}>
+{% if placeholder is not empty %}
+ <option value="" disabled="disabled"
+ {%- if not selected %} selected="selected"{% endif %}>{{ placeholder }}</option>
+{% endif %}
+{% for option in result_options %}
+<option value="{{ option['value'] }}"
+ {{- option['selected'] ? ' selected="selected"' }}>{{ option['label'] }}</option>
+{% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig b/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig
new file mode 100644
index 0000000..cbff62f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig
@@ -0,0 +1,20 @@
+<ul>
+ <li>
+ <input type="radio" name="knjenc" value="" checked="checked" id="kj-none">
+ <label for="kj-none">
+ {# l10n: This is currently used only in Japanese locales #}
+ {% trans %}None{% context %}None encoding conversion{% endtrans %}
+ </label>
+ <input type="radio" name="knjenc" value="EUC-JP" id="kj-euc">
+ <label for="kj-euc">EUC</label>
+ <input type="radio" name="knjenc" value="SJIS" id="kj-sjis">
+ <label for="kj-sjis">SJIS</label>
+ </li>
+ <li>
+ <input type="checkbox" name="xkana" value="kana" id="kj-kana">
+ <label for="kj-kana">
+ {# l10n: This is currently used only in Japanese locales #}
+ {% trans 'Convert to Kana' %}
+ </label>
+ </li>
+</ul>
diff --git a/srcs/phpmyadmin/templates/error/generic.twig b/srcs/phpmyadmin/templates/error/generic.twig
new file mode 100644
index 0000000..a47bce6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/error/generic.twig
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html lang="{{ lang }}" dir="{{ dir }}">
+<head>
+ <link rel="icon" href="favicon.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
+ <title>phpMyAdmin</title>
+ <meta charset="utf-8">
+ <style type="text/css">
+ html {
+ padding: 0;
+ margin: 0;
+ }
+ body {
+ font-family: sans-serif;
+ font-size: small;
+ color: #000000;
+ background-color: #F5F5F5;
+ margin: 1em;
+ }
+ h1 {
+ margin: 0;
+ padding: 0.3em;
+ font-size: 1.4em;
+ font-weight: bold;
+ color: #ffffff;
+ background-color: #ff0000;
+ }
+ p {
+ margin: 0;
+ padding: 0.5em;
+ border: 0.1em solid red;
+ background-color: #ffeeee;
+ }
+ </style>
+</head>
+<body>
+<h1>phpMyAdmin - {{ error_header }}</h1>
+<p>{{ error_message|raw }}</p>
+</body>
+</html>
diff --git a/srcs/phpmyadmin/templates/error/report_form.twig b/srcs/phpmyadmin/templates/error/report_form.twig
new file mode 100644
index 0000000..c45d740
--- /dev/null
+++ b/srcs/phpmyadmin/templates/error/report_form.twig
@@ -0,0 +1,32 @@
+<form action="error_report.php" method="post" name="report_frm" id="report_frm"
+ class="ajax">
+ <fieldset style="padding-top:0">
+
+ <p>
+ {% trans %}
+ This report automatically includes data about the error and information about relevant configuration settings. It will be sent to the phpMyAdmin team for debugging the error.
+ {% endtrans %}
+ </p>
+
+ <div class="label"><label><strong>
+ {% trans "Can you tell us the steps leading to this error? It decisively helps in debugging:" %}
+ </strong></label>
+ </div>
+ <textarea class="report-description" name="description"
+ id="report_description"></textarea>
+
+ <div class="label"><label><p>
+ {% trans "You may examine the data in the error report:" %}
+ </p></label></div>
+ <pre class="report-data">{{ report_data|raw }}</pre>
+
+ <input type="checkbox" name="always_send" id="always_send_checkbox">
+ <label for="always_send_checkbox">
+ {% trans "Automatically send report next time" %}
+ </label>
+
+ </fieldset>
+
+ {{ hidden_inputs|raw }}
+ {{ hidden_fields|raw }}
+</form>
diff --git a/srcs/phpmyadmin/templates/export/alias_add.twig b/srcs/phpmyadmin/templates/export/alias_add.twig
new file mode 100644
index 0000000..479e523
--- /dev/null
+++ b/srcs/phpmyadmin/templates/export/alias_add.twig
@@ -0,0 +1,49 @@
+<table>
+ <thead>
+ <tr>
+ <th colspan="4">{% trans 'Define new aliases' %}</th>
+ </tr>
+ </thead>
+ <tr>
+ <td>
+ <label>{% trans 'Select database:' %}</label>
+ </td>
+ <td>
+ <select id="db_alias_select"><option value=""></option></select>
+ </td>
+ <td>
+ <input id="db_alias_name" placeholder="{% trans 'New database name' %}" disabled="1">
+ </td>
+ <td>
+ <button id="db_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <label>{% trans 'Select table:' %}</label>
+ </td>
+ <td>
+ <select id="table_alias_select"><option value=""></option></select>
+ </td>
+ <td>
+ <input id="table_alias_name" placeholder="{% trans 'New table name' %}" disabled="1">
+ </td>
+ <td>
+ <button id="table_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <label>{% trans 'Select column:' %}</label>
+ </td>
+ <td>
+ <select id="column_alias_select"><option value=""></option></select>
+ </td>
+ <td>
+ <input id="column_alias_name" placeholder="{% trans 'New column name' %}" disabled="1">
+ </td>
+ <td>
+ <button id="column_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button>
+ </td>
+ </tr>
+</table>
diff --git a/srcs/phpmyadmin/templates/export/alias_item.twig b/srcs/phpmyadmin/templates/export/alias_item.twig
new file mode 100644
index 0000000..3b2ce85
--- /dev/null
+++ b/srcs/phpmyadmin/templates/export/alias_item.twig
@@ -0,0 +1,10 @@
+<tr>
+ <th>{{ type }}</th>
+ <td>{{ name }}</td>
+ <td>
+ <input name="{{ field }}" value="{{ value }}" type="text">
+ </td>
+ <td>
+ <button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button>
+ </td>
+</tr>
diff --git a/srcs/phpmyadmin/templates/filter.twig b/srcs/phpmyadmin/templates/filter.twig
new file mode 100644
index 0000000..eee8850
--- /dev/null
+++ b/srcs/phpmyadmin/templates/filter.twig
@@ -0,0 +1,8 @@
+<fieldset id="tableFilter">
+ <legend>{% trans "Filters" %}</legend>
+ <div class="formelement">
+ <label for="filterText">{% trans "Containing the word:" %}</label>
+ <input name="filterText" type="text" id="filterText"
+ value="{{ filter_value }}">
+ </div>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/fk_checkbox.twig b/srcs/phpmyadmin/templates/fk_checkbox.twig
new file mode 100644
index 0000000..afcc615
--- /dev/null
+++ b/srcs/phpmyadmin/templates/fk_checkbox.twig
@@ -0,0 +1,4 @@
+<input type="hidden" name="fk_checks" value="0">
+<input type="checkbox" name="fk_checks" id="fk_checks" value="1"
+ {{- checked ? ' checked' }}>
+<label for="fk_checks">{% trans 'Enable foreign key checks' %}</label>
diff --git a/srcs/phpmyadmin/templates/footer.twig b/srcs/phpmyadmin/templates/footer.twig
new file mode 100644
index 0000000..8939308
--- /dev/null
+++ b/srcs/phpmyadmin/templates/footer.twig
@@ -0,0 +1,24 @@
+{% if not is_ajax %}
+ </div>
+{% endif %}
+{% if not is_ajax and not is_minimal %}
+ {{ self_link|raw }}
+
+ <div class="clearfloat" id="pma_errors">
+ {{ error_messages|raw }}
+ </div>
+
+ {{ scripts|raw }}
+
+ {% if is_demo %}
+ <div id="pma_demo">
+ {{ demo_message|raw }}
+ </div>
+ {% endif %}
+
+ {{ footer|raw }}
+{% endif %}
+{% if not is_ajax %}
+ </body>
+</html>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/gis_data_editor_form.twig b/srcs/phpmyadmin/templates/gis_data_editor_form.twig
new file mode 100644
index 0000000..412561a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/gis_data_editor_form.twig
@@ -0,0 +1,221 @@
+<form id="gis_data_editor_form" action="gis_data_editor.php" method="post">
+ <input type="hidden" id="pmaThemeImage" value="{{ pma_theme_image }}">
+ <div id="gis_data_editor">
+ <h3>{{ 'Value for the column "%s"'|trans|format(field) }}</h3>
+
+ <input type="hidden" name="field" value="{{ field }}">
+ {# The input field to which the final result should be added and corresponding null checkbox #}
+ {% if input_name is not null %}
+ <input type="hidden" name="input_name" value="{{ input_name }}">
+ {% endif %}
+ {{ get_hidden_inputs() }}
+
+ {# Visualization section #}
+ <div id="placeholder"{{ srid != 0 ? ' class="hide"' }}>
+ {{ visualization|raw }}
+ </div>
+
+ <div id="openlayersmap" style="width: {{width}}px; height: {{height}}px;"{{ srid == 0 ? ' class="hide"' }}></div>
+
+ <div class="choice floatright">
+ <input type="checkbox" id="choice" value="useBaseLayer"{{ srid != 0 ? ' checked="checked"' }}>
+ <label for="choice">{% trans "Use OpenStreetMaps as Base Layer" %}</label>
+ </div>
+
+ <script language="javascript" type="text/javascript">{{ open_layers|raw }}</script>
+ {# End of visualization section #}
+
+ {# Header section - Inclueds GIS type selector and input field for SRID #}
+ <div id="gis_data_header">
+ <select name="gis_data[gis_type]" class="gis_type">
+ {% for gis_type in gis_types %}
+ <option value="{{ gis_type }}"{{ geom_type == gis_type ? ' selected="selected"' }}>
+ {{ gis_type }}
+ </option>
+ {% endfor %}
+ </select>
+
+ <label for="srid">{% trans %}SRID:{% context %}Spatial Reference System Identifier{% endtrans %}</label>
+ <input name="gis_data[srid]" type="text" value="{{ srid }}">
+ </div>
+ {# End of header section #}
+
+ {# Data section #}
+ <div id="gis_data">
+ {% if geom_type == 'GEOMETRYCOLLECTION' %}
+ <input type="hidden" name="gis_data[GEOMETRYCOLLECTION][geom_count]" value="{{ geom_count }}">
+ {% endif %}
+
+ {% for a in 0..geom_count - 1 %}
+ {% if gis_data[a] is not null %}
+ {% if geom_type == 'GEOMETRYCOLLECTION' %}
+ <br><br>
+ {{ 'Geometry %d:'|trans|format(a + 1) }}
+ <br>
+ {% if gis_data[a]['gis_type'] is not null %}
+ {% set type = gis_data[a]['gis_type'] %}
+ {% else %}
+ {% set type = gis_types[0] %}
+ {% endif %}
+ <select name="gis_data[{{ a }}][gis_type]" class="gis_type">
+ {% for gis_type in gis_types|slice(0, 6) %}
+ <option value="{{ gis_type }}"{{ type == gis_type ? ' selected="selected"' }}>
+ {{ gis_type }}
+ </option>
+ {% endfor %}
+ </select>
+ {% else %}
+ {% set type = geom_type %}
+ {% endif %}
+
+ {% if type == 'POINT' %}
+ <br>
+ {% trans 'Point:' %}
+ <label for="x">{% trans 'X' %}</label>
+ <input name="gis_data[{{ a }}][POINT][x]" type="text" value="{{ gis_data[a]['POINT']['x'] }}">
+ <label for="y">{% trans 'Y' %}</label>
+ <input name="gis_data[{{ a }}][POINT][y]" type="text" value="{{ gis_data[a]['POINT']['y'] }}">
+ {% elseif type == 'MULTIPOINT' or type == 'LINESTRING' %}
+ {% set no_of_points = gis_data[a][type]['no_of_points'] ?? 1 %}
+ {% if type == 'LINESTRING' and no_of_points < 2 %}
+ {% set no_of_points = 2 %}
+ {% endif %}
+ {% if type == 'MULTIPOINT' and no_of_points < 1 %}
+ {% set no_of_points = 1 %}
+ {% endif %}
+ {% if gis_data[a][type]['add_point'] is not null %}
+ {% set no_of_points = no_of_points + 1 %}
+ {% endif %}
+ <input type="hidden" value="{{ no_of_points }}" name="gis_data[{{ a }}][{{ type }}][no_of_points]">
+
+ {% for i in 0..no_of_points - 1 %}
+ <br>
+ {{ 'Point %d:'|trans|format(i + 1) }}
+ <label for="x">{% trans 'X' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][x]" value="{{ gis_data[a][type][i]['x'] }}">
+ <label for="y">{% trans 'Y' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][y]" value="{{ gis_data[a][type][i]['y'] }}">
+ {% endfor %}
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}">
+ {% elseif type == 'MULTILINESTRING' or type == 'POLYGON' %}
+ {% set no_of_lines = gis_data[a][type]['no_of_lines'] ?? 1 %}
+ {% if no_of_lines < 1 %}
+ {% set no_of_lines = 1 %}
+ {% endif %}
+ {% if gis_data[a][type]['add_line'] is not null %}
+ {% set no_of_lines = no_of_lines + 1 %}
+ {% endif %}
+ <input type="hidden" value="{{ no_of_lines }}" name="gis_data[{{ a }}][{{ type }}][no_of_lines]">
+
+ {% for i in 0..no_of_lines - 1 %}
+ <br>
+ {% if type == 'MULTILINESTRING' %}
+ {{ 'Linestring %d:'|trans|format(i + 1) }}
+ {% elseif i == 0 %}
+ {% trans 'Outer ring:' %}
+ {% else %}
+ {{ 'Inner ring %d:'|trans|format(i) }}
+ {% endif %}
+
+ {% set no_of_points = gis_data[a][type][i]['no_of_points'] ?? 2 %}
+ {% if type == 'MULTILINESTRING' and no_of_points < 2 %}
+ {% set no_of_points = 2 %}
+ {% endif %}
+ {% if type == 'POLYGON' and no_of_points < 4 %}
+ {% set no_of_points = 4 %}
+ {% endif %}
+ {% if gis_data[a][type][i]['add_point'] is not null %}
+ {% set no_of_points = no_of_points + 1 %}
+ {% endif %}
+ <input type="hidden" value="{{ no_of_points }}" name="gis_data[{{ a }}][{{ type }}][{{ i }}][no_of_points]">
+
+ {% for j in 0..no_of_points - 1 %}
+ <br>
+ {{ 'Point %d:'|trans|format(j + 1) }}
+ <label for="x">{% trans 'X' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][{{ j }}][x]" value="{{ gis_data[a][type][i][j]['x'] }}">
+ <label for="y">{% trans 'Y' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][{{ j }}][y]" value="{{ gis_data[a][type][i][j]['y'] }}">
+ {% endfor %}
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ i }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}">
+ {% endfor %}
+ <br>
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_line]" class="btn btn-secondary add addLine" value="
+ {{- type == 'MULTILINESTRING' ? 'Add a linestring'|trans : 'Add an inner ring'|trans }}">
+ {% elseif type == 'MULTIPOLYGON' %}
+ {% set no_of_polygons = gis_data[a][type]['no_of_polygons'] ?? 1 %}
+ {% if no_of_polygons < 1 %}
+ {% set no_of_polygons = 1 %}
+ {% endif %}
+ {% if gis_data[a][type]['add_polygon'] is not null %}
+ {% set no_of_polygons = no_of_polygons + 1 %}
+ {% endif %}
+ <input type="hidden" name="gis_data[{{ a }}][{{ type }}][no_of_polygons]" value="{{ no_of_polygons }}">
+
+ {% for k in 0..no_of_polygons - 1 %}
+ <br>
+ {{ 'Polygon %d:'|trans|format(k + 1) }}
+ {% set no_of_lines = gis_data[a][type][k]['no_of_lines'] ?? 1 %}
+ {% if no_of_lines < 1 %}
+ {% set no_of_lines = 1 %}
+ {% endif %}
+ {% if gis_data[a][type][k]['add_line'] is not null %}
+ {% set no_of_lines = no_of_lines + 1 %}
+ {% endif %}
+ <input type="hidden" name="gis_data[{{ a }}][{{ type }}][{{ k }}][no_of_lines]" value="{{ no_of_lines }}">
+
+ {% for i in 0..no_of_lines - 1 %}
+ <br><br>
+ {% if i == 0 %}
+ {% trans 'Outer ring:' %}
+ {% else %}
+ {{ 'Inner ring %d:'|trans|format(i) }}
+ {% endif %}
+
+ {% set no_of_points = gis_data[a][type][k][i]['no_of_points'] ?? 4 %}
+ {% if no_of_points < 4 %}
+ {% set no_of_points = 4 %}
+ {% endif %}
+ {% if gis_data[a][type][k][i]['add_point'] is not null %}
+ {% set no_of_points = no_of_points + 1 %}
+ {% endif %}
+ <input type="hidden" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][no_of_points]" value="{{ no_of_points }}">
+
+ {% for j in 0..no_of_points - 1 %}
+ <br>
+ {{ 'Point %d:'|trans|format(j + 1) }}
+ <label for="x">{% trans 'X' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][{{ j }}][x]" value="{{ gis_data[a][type][k][i][j]['x'] }}">
+ <label for="y">{% trans 'Y' %}</label>
+ <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][{{ j }}][y]" value="{{ gis_data[a][type][k][i][j]['y'] }}">
+ {% endfor %}
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}">
+ {% endfor %}
+ <br>
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ k }}][add_line]" class="btn btn-secondary add addLine" value="{% trans 'Add an inner ring' %}">
+ <br>
+ {% endfor %}
+ <br>
+ <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_polygon]" class="btn btn-secondary add addPolygon" value="{% trans 'Add a polygon' %}">
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% if geom_type == 'GEOMETRYCOLLECTION' %}
+ <br><br>
+ <input type="submit" name="gis_data[GEOMETRYCOLLECTION][add_geom]" class="btn btn-secondary add addGeom" value="{% trans 'Add geometry' %}">
+ {% endif %}
+ </div>
+ {# End of data section #}
+
+ <br>
+ <input class="btn btn-primary" type="submit" name="gis_data[save]" value="{% trans 'Go' %}">
+
+ <div id="gis_data_output">
+ <h3>{% trans 'Output' %}</h3>
+ <p>
+ {% trans 'Choose "GeomFromText" from the "Function" column and paste the string below into the "Value" field.' %}
+ </p>
+ <textarea id="gis_data_textarea" cols="95" rows="5">{{ result }}</textarea>
+ </div>
+ </div>
+</form>
diff --git a/srcs/phpmyadmin/templates/header.twig b/srcs/phpmyadmin/templates/header.twig
new file mode 100644
index 0000000..c931e8c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/header.twig
@@ -0,0 +1,66 @@
+{% if not is_ajax and is_enabled -%}
+
+<!doctype html>
+<html lang="{{ lang }}" dir="{{ text_dir }}">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <meta name="referrer" content="no-referrer">
+ <meta name="robots" content="noindex,nofollow">
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge">
+ {% if not allow_third_party_framing -%}
+ <style id="cfs-style">html{display: none;}</style>
+ {%- endif %}
+
+ <link rel="icon" href="favicon.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
+ {% if is_print_view %}
+ <link rel="stylesheet" type="text/css" href="{{ base_dir }}print.css?{{ version }}">
+ {% else %}
+ <link rel="stylesheet" type="text/css" href="{{ theme_path }}/jquery/jquery-ui.css">
+ <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/lib/codemirror.css?{{ version }}">
+ <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/addon/hint/show-hint.css?{{ version }}">
+ <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/addon/lint/lint.css?{{ version }}">
+ <link rel="stylesheet" type="text/css" href="{{ theme_path }}/css/theme{{ text_dir == 'rtl' ? '-rtl' }}.css?{{ version }}&nocache=
+ {{- unique_value }}{{ text_dir }}{% if server is not empty %}&server={{ server }}{% endif %}">
+ <link rel="stylesheet" type="text/css" href="{{ theme_path }}/css/printview.css?{{ version }}" media="print" id="printcss">
+ {% endif %}
+ <title>{{ title }}</title>
+ {{ scripts|raw }}
+ <noscript><style>html{display:block}</style></noscript>
+</head>
+<body{{ body_id is not empty ? ' id=' ~ body_id }}>
+ {{ navigation|raw }}
+ {{ custom_header|raw }}
+ {{ load_user_preferences|raw }}
+
+ {% if not show_hint %}
+ <span id="no_hint" class="hide"></span>
+ {% endif %}
+
+ {% if is_warnings_enabled %}
+ <noscript>
+ {{ 'Javascript must be enabled past this point!'|trans|error }}
+ </noscript>
+ {% endif %}
+
+ {% if is_menu_enabled and server > 0 %}
+ {{ menu|raw }}
+ <span id="page_nav_icons">
+ <span id="lock_page_icon"></span>
+ <span id="page_settings_icon">
+ {{ get_image('s_cog', 'Page-related settings'|trans) }}
+ </span>
+ <a id="goto_pagetop" href="#">{{ get_image('s_top', 'Click on the bar to scroll to top of page'|trans) }}</a>
+ </span>
+ {% endif %}
+
+ {{ console|raw }}
+
+ <div id="page_content">
+ {{ messages|raw }}
+{% endif %}
+
+{% if is_enabled and has_recent_table %}
+ {{ recent_table|raw }}
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/header_location.twig b/srcs/phpmyadmin/templates/header_location.twig
new file mode 100644
index 0000000..f6e97a6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/header_location.twig
@@ -0,0 +1,22 @@
+{# Manage HTML redirection #}
+<html>
+<head>
+ <title>- - -</title>
+ <meta http-equiv="expires" content="0">
+ <meta http-equiv="Pragma" content="no-cache">
+ <meta http-equiv="Cache-Control" content="no-cache">
+ <meta http-equiv="Refresh" content="0;url={{ uri }}">
+ <script type="text/javascript">
+ //<![CDATA[
+ setTimeout(function() { window.location = decodeURI('{{ uri|escape_js_string }}'); }, 2000);
+ //]]>
+ </script>
+</head>
+<body>
+<script type="text/javascript">
+ //<![CDATA[
+ document.write('<p><a href="{{ uri|e|escape_js_string }}">{% trans 'Go' %}</a></p>');
+ //]]>
+</script>
+</body>
+</html>
diff --git a/srcs/phpmyadmin/templates/home/index.twig b/srcs/phpmyadmin/templates/home/index.twig
new file mode 100644
index 0000000..e0fb63a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/home/index.twig
@@ -0,0 +1,203 @@
+{% if is_git_revision %}
+ <div id="is_git_revision"></div>
+{% endif %}
+
+{{ message|raw }}
+
+{{ partial_logout|raw }}
+
+<div id="maincontainer">
+ {{ sync_favorite_tables|raw }}
+
+ <div id="main_pane_left">
+ {% if has_server %}
+ {% if is_demo %}
+ <div class="group">
+ <h2>{% trans 'phpMyAdmin Demo Server' %}</h2>
+ <p class="cfg_dbg_demo">
+ {% apply format('<a href="url.php?url=https://demo.phpmyadmin.net/" target="_blank" rel="noopener noreferrer">demo.phpmyadmin.net</a>')|raw %}
+ {% trans %}
+ You are using the demo server. You can do anything here, but please do not change root, debian-sys-maint and pma users. More information is available at %s.
+ {% endtrans %}
+ {% endapply %}
+ </p>
+ </div>
+ {% endif %}
+
+ <div class="group">
+ <h2>{% trans 'General settings' %}</h2>
+ <ul>
+ {% if has_server_selection %}
+ <li id="li_select_server" class="no_bullets">
+ {{ get_image('s_host') }}
+ {{ server_selection|raw }}
+ </li>
+ {% endif %}
+
+ {% if server > 0 %}
+ {{ change_password is not empty ? change_password|raw }}
+
+ <li id="li_select_mysql_collation" class="no_bullets">
+ <form class="disableAjax" method="post" action="index.php">
+ {{ get_hidden_inputs(null, null, 4, 'collation_connection') }}
+ <label for="select_collation_connection">
+ {{ get_image('s_asci') }}
+ {% trans 'Server connection collation:' %}
+ {{ show_mysql_docu('charset-connection') }}
+ </label>
+ {% if charsets is not empty %}
+ <select lang="en" dir="ltr" name="collation_connection" id="select_collation_connection" class="autosubmit">
+ <option value="">{% trans 'Collation' %}</option>
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}"{{ collation.is_selected ? ' selected' }}>
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ {% endif %}
+ </form>
+ </li>
+ {% endif %}
+ {{ user_preferences is not empty ? user_preferences|raw }}
+ </ul>
+ </div>
+ {% endif %}
+
+ <div class="group">
+ <h2>{% trans 'Appearance settings' %}</h2>
+ <ul>
+ {% if language_selector is not empty %}
+ <li id="li_select_lang" class="no_bullets">
+ {{ get_image('s_lang') }}
+ {{ language_selector|raw }}
+ </li>
+ {% endif %}
+
+ {% if theme_selection is not empty %}
+ <li id="li_select_theme" class="no_bullets">
+ {{ get_image('s_theme') }}
+ {{ theme_selection|raw }}
+ </li>
+ {% endif %}
+ </ul>
+ </div>
+ </div>
+
+ <div id="main_pane_right">
+ {% if database_server is not empty %}
+ <div class="group">
+ <h2>{% trans 'Database server' %}</h2>
+ <ul>
+ <li id="li_server_info">
+ {% trans 'Server:' %}
+ {{ database_server.host }}
+ </li>
+ <li id="li_server_type">
+ {% trans 'Server type:' %}
+ {{ database_server.type }}
+ </li>
+ <li id="li_server_connection">
+ {% trans 'Server connection:' %}
+ {{ database_server.connection|raw }}
+ </li>
+ <li id="li_server_version">
+ {% trans 'Server version:' %}
+ {{ database_server.version }}
+ </li>
+ <li id="li_mysql_proto">
+ {% trans 'Protocol version:' %}
+ {{ database_server.protocol }}
+ </li>
+ <li id="li_user_info">
+ {% trans 'User:' %}
+ {{ database_server.user }}
+ </li>
+ <li id="li_mysql_charset">
+ {% trans 'Server charset:' %}
+ <span lang="en" dir="ltr">
+ {{ database_server.charset }}
+ </span>
+ </li>
+ </ul>
+ </div>
+ {% endif %}
+
+ {% if web_server is not empty or php_info is not empty %}
+ <div class="group">
+ <h2>{% trans 'Web server' %}</h2>
+ <ul>
+ {% if web_server is not empty %}
+ <li id="li_web_server_software">
+ {{ web_server.software }}
+ </li>
+ <li id="li_mysql_client_version">
+ {% trans 'Database client version:' %}
+ {{ web_server.database }}
+ </li>
+ <li id="li_used_php_extension">
+ {% trans 'PHP extension:' %}
+ {% for extension in web_server.php_extensions %}
+ {{ extension }}
+ {{ show_php_docu('book.' ~ extension ~ '.php') }}
+ {% endfor %}
+ </li>
+ <li id="li_used_php_version">
+ {% trans 'PHP version:' %}
+ {{ web_server.php_version }}
+ </li>
+ {% endif %}
+ {% if php_info is not empty %}
+ {{ php_info|raw }}
+ {% endif %}
+ </ul>
+ </div>
+ {% endif %}
+
+ <div class="group pmagroup">
+ <h2>phpMyAdmin</h2>
+ <ul>
+ <li id="li_pma_version"{{ is_version_checked ? ' class="jsversioncheck"' }}>
+ {% trans 'Version information:' %}
+ <span class="version">{{ phpmyadmin_version }}</span>
+ </li>
+ <li id="li_pma_docs">
+ <a href="{{ get_docu_link('index') }}" target="_blank" rel="noopener noreferrer">
+ {% trans 'Documentation' %}
+ </a>
+ </li>
+ <li id="li_pma_homepage">
+ <a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer">
+ {% trans 'Official Homepage' %}
+ </a>
+ </li>
+ <li id="li_pma_contribute">
+ <a href="{{ 'https://www.phpmyadmin.net/contribute/'|link }}" target="_blank" rel="noopener noreferrer">
+ {% trans 'Contribute' %}
+ </a>
+ </li>
+ <li id="li_pma_support">
+ <a href="{{ 'https://www.phpmyadmin.net/support/'|link }}" target="_blank" rel="noopener noreferrer">
+ {% trans 'Get support' %}
+ </a>
+ </li>
+ <li id="li_pma_changes">
+ <a href="changelog.php{{ get_common() }}" target="_blank">
+ {% trans 'List of changes' %}
+ </a>
+ </li>
+ <li id="li_pma_license">
+ <a href="license.php{{ get_common() }}" target="_blank">
+ {% trans 'License' %}
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+
+{{ config_storage_message|raw }}
diff --git a/srcs/phpmyadmin/templates/javascript/display.twig b/srcs/phpmyadmin/templates/javascript/display.twig
new file mode 100644
index 0000000..12027ef
--- /dev/null
+++ b/srcs/phpmyadmin/templates/javascript/display.twig
@@ -0,0 +1,7 @@
+<script type="text/javascript">
+if (typeof configInlineParams === "undefined" || !Array.isArray(configInlineParams)) configInlineParams = [];
+configInlineParams.push(function() {
+{{ js_array|join(';\n')|raw }};
+});
+if (typeof configScriptLoaded !== "undefined" && configInlineParams) loadInlineConfig();
+</script>
diff --git a/srcs/phpmyadmin/templates/list/item.twig b/srcs/phpmyadmin/templates/list/item.twig
new file mode 100644
index 0000000..78f5e38
--- /dev/null
+++ b/srcs/phpmyadmin/templates/list/item.twig
@@ -0,0 +1,19 @@
+<li{% if id is not empty %} id="{{ id }}"{% endif -%}
+ {%- if class is not empty %} class="{{ class }}"{% endif %}>
+
+ {% if url is defined and url is iterable and url['href'] is not empty %}
+ <a{% if url['href'] is not empty %} href="{{ url['href']|raw }}"{% endif -%}
+ {%- if url['target'] is not empty %} target="{{ url['target'] }}"{% endif -%}
+ {%- if url['target'] is not empty and url['target'] == '_blank' %} rel="noopener noreferrer"{% endif -%}
+ {%- if url['id'] is not empty %} id="{{ url['id'] }}"{% endif -%}
+ {%- if url['class'] is not empty %} class="{{ url['class'] }}"{% endif -%}
+ {%- if url['title'] is not empty %} title="{{ url['title'] }}"{% endif %}>
+ {% endif %}
+ {{ content|raw }}
+ {% if url is defined and url is iterable and url['href'] is not empty %}
+ </a>
+ {% endif %}
+ {% if mysql_help_page is not empty %}
+ {{ show_mysql_docu(mysql_help_page) }}
+ {% endif %}
+</li>
diff --git a/srcs/phpmyadmin/templates/list/unordered.twig b/srcs/phpmyadmin/templates/list/unordered.twig
new file mode 100644
index 0000000..11f114e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/list/unordered.twig
@@ -0,0 +1,14 @@
+<ul{% if id is not empty %} id="{{ id }}"{% endif -%}
+ {%- if class is not empty %} class="{{ class }}"{% endif %}>
+
+ {% if items is not empty %}
+ {% for item in items %}
+ {% if item is not iterable %}
+ {% set item = {'content': item} %}
+ {% endif %}
+ {% include 'list/item.twig' with item only %}
+ {% endfor %}
+ {% elseif content is not empty %}
+ {{ content|raw }}
+ {% endif %}
+</ul>
diff --git a/srcs/phpmyadmin/templates/login/footer.twig b/srcs/phpmyadmin/templates/login/footer.twig
new file mode 100644
index 0000000..d9e9659
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/footer.twig
@@ -0,0 +1,4 @@
+</div>
+{% if check_timeout == true %}
+ </div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/login/header.twig b/srcs/phpmyadmin/templates/login/header.twig
new file mode 100644
index 0000000..a21dee5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/header.twig
@@ -0,0 +1,16 @@
+{% if session_expired == true %}
+ <div id="modalOverlay">
+{% endif %}
+<div class="container{{ add_class }}">
+<a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer" class="logo">
+<img src="{{ theme.getImgPath('logo_right.png', 'pma_logo.png') }}" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0">
+</a>
+<h1>{{ 'Welcome to %s'|trans|format('<bdo dir="ltr" lang="en">phpMyAdmin</bdo>')|raw }}</h1>
+
+<noscript>
+{{ "Javascript must be enabled past this point!"|trans|error }}
+</noscript>
+
+<div class="hide" id="js-https-mismatch">
+{{ "There is a mismatch between HTTPS indicated on the server and client. This can lead to a non working phpMyAdmin or a security risk. Please fix your server configuration to indicate HTTPS properly."|trans|error }}
+</div>
diff --git a/srcs/phpmyadmin/templates/login/twofactor.twig b/srcs/phpmyadmin/templates/login/twofactor.twig
new file mode 100644
index 0000000..af2bae3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor.twig
@@ -0,0 +1,7 @@
+<form method="post" class="disableAjax">
+ {{ get_hidden_inputs() }}
+ {{ form|raw }}
+ {% if show_submit %}
+ <input class="btn btn-primary" type="submit" value="{% trans "Verify" %}">
+ {% endif %}
+</form>
diff --git a/srcs/phpmyadmin/templates/login/twofactor/application.twig b/srcs/phpmyadmin/templates/login/twofactor/application.twig
new file mode 100644
index 0000000..3077e03
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/application.twig
@@ -0,0 +1,4 @@
+<p>
+<label>{% trans "Authentication code:" %} <input type="text" name="2fa_code" autocomplete="off"></label>
+</p>
+<p>{% trans "Open the two-factor authentication app on your device to view your authentication code and verify your identity." %}</p>
diff --git a/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig b/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig
new file mode 100644
index 0000000..e823bb3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig
@@ -0,0 +1,17 @@
+{{ get_hidden_inputs() }}
+<p>
+ {% trans "Please scan following QR code into the two-factor authentication app on your device and enter authentication code it generates." %}
+</p>
+<p>
+ {% if has_imagick %}
+ <img src="{{ image }}">
+ {% else %}
+ {{ image|raw }}
+ {% endif %}
+</p>
+<p>
+ {% trans "Secret/key:" %} <strong>{{ secret }}</strong>
+</p>
+<p>
+ <label>{% trans "Authentication code:" %} <input type="text" name="2fa_code" autocomplete="off"></label>
+</p>
diff --git a/srcs/phpmyadmin/templates/login/twofactor/invalid.twig b/srcs/phpmyadmin/templates/login/twofactor/invalid.twig
new file mode 100644
index 0000000..568dd94
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/invalid.twig
@@ -0,0 +1,3 @@
+<div class="error">
+{% trans "The configured two factor authentication is not available, please install missing dependencies." %}
+</div>
diff --git a/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig b/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig
new file mode 100644
index 0000000..d3f9c04
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig
@@ -0,0 +1,5 @@
+{% if not is_https %}
+<div class="error">
+{% trans "You are not using https to access phpMyAdmin, therefore FIDO U2F device will most likely refuse to authenticate you." %}
+</div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/login/twofactor/key.twig b/srcs/phpmyadmin/templates/login/twofactor/key.twig
new file mode 100644
index 0000000..79ade47
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/key.twig
@@ -0,0 +1,5 @@
+{% include 'login/twofactor/key-https-warning.twig' %}
+<p>
+{% trans "Please connect your FIDO U2F device into your computer's USB port. Then confirm login on the device." %}
+</p>
+<input id="u2f_authentication_response" name="u2f_authentication_response" value="" type="hidden" data-request="{{ request }}">
diff --git a/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig b/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig
new file mode 100644
index 0000000..8b502dc
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig
@@ -0,0 +1,5 @@
+{% include 'login/twofactor/key-https-warning.twig' %}
+<p>
+{% trans "Please connect your FIDO U2F device into your computer's USB port. Then confirm registration on the device." %}
+</p>
+<input id="u2f_registration_response" name="u2f_registration_response" value="" type="hidden" data-request="{{ request }}" data-signatures="{{ signatures }}">
diff --git a/srcs/phpmyadmin/templates/login/twofactor/simple.twig b/srcs/phpmyadmin/templates/login/twofactor/simple.twig
new file mode 100644
index 0000000..eeae140
--- /dev/null
+++ b/srcs/phpmyadmin/templates/login/twofactor/simple.twig
@@ -0,0 +1 @@
+<input type="hidden" name="2fa_confirm" value="1">
diff --git a/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig b/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig
new file mode 100644
index 0000000..8303b59
--- /dev/null
+++ b/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig
@@ -0,0 +1,29 @@
+<form class="ajax" action="navigation.php" method="post">
+ <fieldset>
+ {{ get_hidden_inputs(database, table) }}
+
+ {% for type, label in types %}
+ {% if (item_type is empty or item_type == type) and hidden[type] is iterable %}
+ {{ not loop.first ? '<br>' }}
+ <strong>{{ label }}</strong>
+ <table class="all100">
+ <tbody>
+ {% for item in hidden[type] %}
+ <tr>
+ <td>{{ item }}</td>
+ <td class="right">
+ <a class="unhideNavItem ajax" href="navigation.php" data-post="{{ get_common({
+ 'unhideNavItem': true,
+ 'itemType': type,
+ 'itemName': item,
+ 'dbName': database
+ }, '') }}">{{ get_icon('show', 'Unhide'|trans) }}</a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ {% endfor %}
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/navigation/main.twig b/srcs/phpmyadmin/templates/navigation/main.twig
new file mode 100644
index 0000000..574e3f4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/navigation/main.twig
@@ -0,0 +1,98 @@
+{% if not is_ajax %}
+ <div id="pma_navigation">
+ <div id="pma_navigation_resizer"></div>
+ <div id="pma_navigation_collapser"></div>
+ <div id="pma_navigation_content">
+ <div id="pma_navigation_header">
+ <a class="hide navigation_url" href="navigation.php{{ get_common({'ajax_request': true}) }}"></a>
+
+ {% if logo.is_displayed %}
+ <div id="pmalogo">
+ {% if logo.has_link %}
+ <a href="{{ logo.link|default('#') }}"{{ logo.attributes }}>
+ {% endif %}
+ {% if logo.source is not empty %}
+ <img id="imgpmalogo" src="{{ logo.source }}" alt="phpMyAdmin">
+ {% else %}
+ <h1>phpMyAdmin</h1>
+ {% endif %}
+ {% if logo.has_link %}
+ </a>
+ {% endif %}
+ </div>
+ {% endif %}
+
+ <div id="navipanellinks">
+ <a href="index.php{{ get_common() }}" title="{% trans 'Home' %}">
+ {{- get_image('b_home', 'Home'|trans) -}}
+ </a>
+
+ {% if server != 0 %}
+ <a class="logout disableAjax" href="logout.php{{ get_common() }}" title="{{ auth_type == 'config' ? 'Empty session data'|trans : 'Log out'|trans }}">
+ {{- get_image('s_loggoff', auth_type == 'config' ? 'Empty session data'|trans : 'Log out'|trans) -}}
+ </a>
+ {% endif %}
+
+ <a href="{{ get_docu_link('index') }}" title="{% trans 'phpMyAdmin documentation' %}" target="_blank" rel="noopener">
+ {{- get_image('b_docs', 'phpMyAdmin documentation'|trans) -}}
+ </a>
+
+ <a href="{{ get_mysql_docu_url('') }}" title="{% trans 'Documentation' %}" target="_blank" rel="noopener noreferrer">
+ {{- get_image('b_sqlhelp', 'Documentation'|trans) -}}
+ </a>
+
+ <a id="pma_navigation_settings_icon"{{ not is_navigation_settings_enabled ? ' class="hide"' }} href="#" title="{% trans 'Navigation panel settings' %}">
+ {{- get_image('s_cog', 'Navigation panel settings'|trans) -}}
+ </a>
+
+ <a id="pma_navigation_reload" href="#" title="{% trans 'Reload navigation panel' %}">
+ {{- get_image('s_reload', 'Reload navigation panel'|trans) -}}
+ </a>
+ </div>
+
+ {% if is_servers_displayed and servers|length > 1 %}
+ <div id="serverChoice">
+ {{ server_select|raw }}
+ </div>
+ {% endif %}
+
+ {{ get_image('ajax_clock_small', 'Loading…'|trans, {
+ 'style': 'visibility: hidden; display:none',
+ 'class': 'throbber'
+ }) }}
+ </div>
+ <div id="pma_navigation_tree" class="list_container{{ is_synced ? ' synced' }}{{ is_highlighted ? ' highlight' }}{{ is_autoexpanded ? ' autoexpand' }}">
+{% endif %}
+
+{% if not navigation_tree %}
+ {{ 'An error has occurred while loading the navigation display'|trans|error }}
+{% else %}
+ {{ navigation_tree|raw }}
+{% endif %}
+
+{% if not is_ajax %}
+ </div>
+
+ <div id="pma_navi_settings_container">
+ {% if is_navigation_settings_enabled %}
+ {{ navigation_settings|raw }}
+ {% endif %}
+ </div>
+ </div>
+
+ {% if is_drag_drop_import_enabled %}
+ <div class="pma_drop_handler">
+ {% trans 'Drop files here' %}
+ </div>
+ <div class="pma_sql_import_status">
+ <h2>
+ {% trans 'SQL upload' %}
+ ( <span class="pma_import_count">0</span> )
+ <span class="close">x</span>
+ <span class="minimize">-</span>
+ </h2>
+ <div></div>
+ </div>
+ {% endif %}
+ </div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/navigation/tree/database_select.twig b/srcs/phpmyadmin/templates/navigation/tree/database_select.twig
new file mode 100644
index 0000000..9b8beda
--- /dev/null
+++ b/srcs/phpmyadmin/templates/navigation/tree/database_select.twig
@@ -0,0 +1,22 @@
+{{ quick_warp|raw }}
+
+<div id="pma_navigation_select_database">
+ {{ list_navigator|raw }}
+
+ <div id="pma_navigation_db_select">
+ <form action="index.php">
+ {{ get_hidden_fields({'server': server}) }}
+
+ <select name="db" class="hide" id="navi_db_select">
+ <option value="" dir="{{ text_dir }}">{% trans 'Databases' %}…</option>
+ {{ options|raw }}
+ </select>
+ </form>
+ </div>
+</div>
+
+<div id="pma_navigation_tree_content">
+ <ul>
+ {{ nodes|raw }}
+ </ul>
+</div>
diff --git a/srcs/phpmyadmin/templates/navigation/tree/path.twig b/srcs/phpmyadmin/templates/navigation/tree/path.twig
new file mode 100644
index 0000000..540a992
--- /dev/null
+++ b/srcs/phpmyadmin/templates/navigation/tree/path.twig
@@ -0,0 +1,12 @@
+<div class='list_container hide'>
+ <ul{{ has_search_results ? ' class="search_results"' }}>
+ {{ list_content|raw }}
+ </ul>
+
+ {% if not is_tree %}
+ <span class='hide loaded_db'>{{ parent_name|url_encode }}</span>
+ {% if list_content is empty %}
+ <div>{% trans 'No tables found in database.' %}</div>
+ {% endif %}
+ {% endif %}
+</div>
diff --git a/srcs/phpmyadmin/templates/navigation/tree/state.twig b/srcs/phpmyadmin/templates/navigation/tree/state.twig
new file mode 100644
index 0000000..c59573d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/navigation/tree/state.twig
@@ -0,0 +1,16 @@
+{{ quick_warp|raw }}
+
+<div class="clearfloat"></div>
+
+<ul>
+ {{ fast_filter|raw }}
+ {{ controls|raw }}
+</ul>
+
+{{ page_selector|raw }}
+
+<div id='pma_navigation_tree_content'>
+ <ul>
+ {{ nodes|raw }}
+ </ul>
+</div>
diff --git a/srcs/phpmyadmin/templates/preferences/autoload.twig b/srcs/phpmyadmin/templates/preferences/autoload.twig
new file mode 100644
index 0000000..4c61045
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/autoload.twig
@@ -0,0 +1,15 @@
+<div id="prefs_autoload" class="notice print_ignore hide">
+ <form action="prefs_manage.php" method="post" class="disableAjax">
+ {{ hidden_inputs|raw }}
+ <input type="hidden" name="json" value="">
+ <input type="hidden" name="submit_import" value="1">
+ <input type="hidden" name="return_url" value="{{ return_url }}">
+ {% trans %}
+ Your browser has phpMyAdmin configuration for this domain. Would you like to import it for current session?
+ {% endtrans %}
+ <br>
+ <a href="#yes">{% trans "Yes" %}</a>
+ / <a href="#no">{% trans "No" %}</a>
+ / <a href="#delete">{% trans "Delete settings" %}</a>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/preferences/forms/main.twig b/srcs/phpmyadmin/templates/preferences/forms/main.twig
new file mode 100644
index 0000000..563b385
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/forms/main.twig
@@ -0,0 +1,8 @@
+{{ error|raw }}
+{% if has_errors %}
+ <div class="error config-form">
+ <strong>{% trans 'Cannot save settings, submitted form contains errors!' %}</strong>
+ {{ errors|raw }}
+ </div>
+{% endif %}
+{{ form|raw }}
diff --git a/srcs/phpmyadmin/templates/preferences/manage/error.twig b/srcs/phpmyadmin/templates/preferences/manage/error.twig
new file mode 100644
index 0000000..d6b3522
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/manage/error.twig
@@ -0,0 +1,20 @@
+{{ 'Configuration contains incorrect data for some fields.'|trans|error }}
+<div class="config-form">
+ {{ form_errors|raw }}
+</div>
+<form action="prefs_manage.php" method="post" class="disableAjax">
+ {{ get_hidden_inputs() }}
+ <input type="hidden" name="json" value="{{ json }}">
+ <input type="hidden" name="fix_errors" value="1">
+ {% if import_merge is not empty %}
+ <input type="hidden" name="import_merge" value="1">
+ {% endif %}
+ {% if return_url %}
+ <input type="hidden" name="return_url" value="{{ return_url }}">
+ {% endif %}
+ <p>
+ {% trans 'Do you want to import remaining settings?' %}
+ </p>
+ <input class="btn btn-secondary" type="submit" name="submit_import" value="{{ 'Yes'|trans }}">
+ <input class="btn btn-secondary" type="submit" name="submit_ignore" value="{{ 'No'|trans }}">
+</form>
diff --git a/srcs/phpmyadmin/templates/preferences/manage/main.twig b/srcs/phpmyadmin/templates/preferences/manage/main.twig
new file mode 100644
index 0000000..0e51327
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/manage/main.twig
@@ -0,0 +1,112 @@
+{{ error|raw }}
+<script type="text/javascript">
+ {{ get_js_value("Messages.strSavedOn", 'Saved on: @DATE@'|trans) }}
+</script>
+<div id="maincontainer">
+ <div id="main_pane_left">
+ <div class="group">
+ <h2> {% trans 'Import' %} </h2>
+ <form class="group-cnt prefs-form disableAjax" name="prefs_import" action="prefs_manage.php" method="post"
+ enctype="multipart/form-data">
+ {{ generate_hidden_max_file_size(max_upload_size) }}
+ {{ get_hidden_inputs() }}
+ <input type="hidden" name="json" value="">
+ <input type="radio" id="import_text_file" name="import_type" value="text_file" checked="checked">
+ <label for="import_text_file"> {% trans 'Import from file' %} </label>
+ <div id="opts_import_text_file" class="prefsmanage_opts">
+ <label for="input_import_file"> {% trans 'Browse your computer:' %} </label>
+ <input type="file" name="import_file" id="input_import_file">
+ </div>
+ <input type="radio" id="import_local_storage" name="import_type" value="local_storage"
+ disabled="disabled">
+ <label for="import_local_storage"> {% trans 'Import from browser\'s storage' %} </label>
+ <div id="opts_import_local_storage" class="prefsmanage_opts disabled">
+ <div class="localStorage-supported">
+ {% trans 'Settings will be imported from your browser\'s local storage.' %}
+ <br>
+ <div class="localStorage-exists">
+ {% trans 'Saved on: @DATE@' %}
+ </div>
+ <div class="localStorage-empty">
+ {{ 'You have no saved settings!'|trans|notice }}
+ </div>
+ </div>
+ <div class="localStorage-unsupported">
+ {{ 'This feature is not supported by your web browser'|trans|notice }}
+ </div>
+ </div>
+ <input type="checkbox" id="import_merge" name="import_merge">
+ <label for="import_merge"> {% trans 'Merge with current configuration' %} </label>
+ <br><br>
+ <input class="btn btn-primary" type="submit" name="submit_import" value="{{ 'Go'|trans }}">
+ </form>
+ </div>
+ {% if exists_setup_and_not_exists_config %}
+ {# show only if setup script is available, allows to disable this message #}
+ {# by simply removing setup directory #}
+ {# Also do not show in config exists (and setup would refuse to work) #}
+ <div class="group">
+ <h2>{% trans 'More settings' %}</h2>
+ <div class="group-cnt">
+ {{ 'You can set more settings by modifying config.inc.php, eg. by using %sSetup script%s.'|trans|format('<a href="setup/index.php" target="_blank">','</a>')|raw }}
+ {{ show_docu('setup', 'setup-script') }}
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ <div id="main_pane_right">
+ <div class="group">
+ <h2>{% trans 'Export' %}</h2>
+ <div class="click-hide-message group-cnt hide">
+ {{ 'Configuration has been saved.'|trans|raw_success }}
+ </div>
+ <form class="group-cnt prefs-form disableAjax" name="prefs_export"
+ action="prefs_manage.php" method="post">
+ {{ get_hidden_inputs() }}
+ <div>
+ <input type="radio" id="export_text_file" name="export_type"
+ value="text_file" checked="checked">
+ <label for="export_text_file">
+ {% trans 'Save as JSON file' %}
+ </label><br>
+ <input type="radio" id="export_php_file" name="export_type" value="php_file">
+ <label for="export_php_file">
+ {% trans 'Save as PHP file' %}
+ </label><br>
+ <input type="radio" id="export_local_storage" name="export_type" value="local_storage"
+ disabled="disabled">
+ <label for="export_local_storage">
+ {% trans 'Save to browser\'s storage' %}
+ </label>
+ </div>
+ <div id="opts_export_local_storage"
+ class="prefsmanage_opts disabled">
+ <span class="localStorage-supported">
+ {% trans 'Settings will be saved in your browser\'s local storage.' %}
+ <div class="localStorage-exists">
+ <b>
+ {% trans 'Existing settings will be overwritten!' %}
+ </b>
+ </div>
+ </span>
+ <div class="localStorage-unsupported">
+ {{ 'This feature is not supported by your web browser'|trans|notice }}
+ </div>
+ </div>
+ <br>
+ <input class="btn btn-primary" type="submit" name="submit_export" value="{% trans 'Go' %}">
+ </form>
+ </div>
+ <div class="group">
+ <h2>{% trans 'Reset' %}</h2>
+ <form class="group-cnt prefs-form disableAjax" name="prefs_reset"
+ action="prefs_manage.php" method="post">
+ {{ get_hidden_inputs() }}
+ {% trans 'You can reset all your settings and restore them to default values.' %}
+ <br><br>
+ <input class="btn btn-secondary" type="submit" name="submit_clear" value="{% trans 'Reset' %}">
+ </form>
+ </div>
+ </div>
+ <br class="clearfloat">
+</div>
diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig b/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig
new file mode 100644
index 0000000..574f112
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig
@@ -0,0 +1,11 @@
+<div class="group">
+<h2>{% trans "Configure two-factor authentication" %}</h2>
+<div class="group-cnt">
+<form method="POST" action="prefs_twofactor.php">
+{{ get_hidden_inputs() }}
+<input type="hidden" name="2fa_configure" value="{{ configure }}">
+{{ form|raw }}
+<input class="btn btn-secondary" type="submit" value="{% trans "Enable two-factor authentication" %}">
+</form>
+</div>
+</div>
diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig b/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig
new file mode 100644
index 0000000..f1ef175
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig
@@ -0,0 +1,12 @@
+<div class="group">
+<h2>{% trans "Confirm disabling two-factor authentication" %}</h2>
+<div class="group-cnt">
+<form method="POST" action="prefs_twofactor.php">
+{{ "By disabling two factor authentication you will be again able to login using password only."|trans|notice }}
+{{ get_hidden_inputs() }}
+{{ form|raw }}
+<input type="hidden" name="2fa_remove" value="1">
+<input class="btn btn-secondary" type="submit" value="{% trans "Disable two-factor authentication" %}">
+</form>
+</div>
+</div>
diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/main.twig b/srcs/phpmyadmin/templates/preferences/two_factor/main.twig
new file mode 100644
index 0000000..f95c047
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preferences/two_factor/main.twig
@@ -0,0 +1,60 @@
+<div class="group">
+ <h2>
+ {% trans "Two-factor authentication status" %}
+ {{ show_docu('two_factor') }}
+ </h2>
+ <div class="group-cnt">
+ {% if enabled %}
+ {% if num_backends == 0 %}
+ <p>{% trans "Two-factor authentication is not available, please install optional dependencies to enable authentication backends." %}</p>
+ <p>{% trans "Following composer packages are missing:" %}</p>
+ <ul>
+ {% for item in missing %}
+ <li><code>{{ item.dep }}</code> ({{ item.class }})</li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ {% if backend_id %}
+ <p>{% trans "Two-factor authentication is available and configured for this account." %}</p>
+ {% else %}
+ <p>{% trans "Two-factor authentication is available, but not configured for this account." %}</p>
+ {% endif %}
+ {% endif %}
+ {% else %}
+ <p>{% trans "Two-factor authentication is not available, enable phpMyAdmin configuration storage to use it." %}</p>
+ {% endif %}
+ </div>
+</div>
+
+{% if backend_id %}
+ <div class="group">
+ <h2>{{ backend_name }}</h2>
+ <div class="group-cnt">
+ <p>{% trans "You have enabled two factor authentication." %}</p>
+ <p>{{ backend_description }}</p>
+ <form method="post" action="prefs_twofactor.php">
+ {{ get_hidden_inputs() }}
+ <input class="btn btn-secondary" type="submit" name="2fa_remove" value="
+ {%- trans "Disable two-factor authentication" %}">
+ </form>
+ </div>
+ </div>
+{% elseif num_backends > 0 %}
+ <div class="group">
+ <h2>{% trans "Configure two-factor authentication" %}</h2>
+ <div class="group-cnt">
+ <form method="post" action="prefs_twofactor.php">
+ {{ get_hidden_inputs() }}
+ {% for backend in backends %}
+ <label class="displayblock">
+ <input type="radio" name="2fa_configure" value="{{ backend["id"] }}"
+ {{- backend["id"] == "" ? ' checked' }}>
+ <strong>{{ backend["name"] }}</strong>
+ <p>{{ backend["description"] }}</p>
+ </label>
+ {% endfor %}
+ <input class="btn btn-secondary" type="submit" value="{% trans "Configure two-factor authentication" %}">
+ </form>
+ </div>
+ </div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/preview_sql.twig b/srcs/phpmyadmin/templates/preview_sql.twig
new file mode 100644
index 0000000..5102341
--- /dev/null
+++ b/srcs/phpmyadmin/templates/preview_sql.twig
@@ -0,0 +1,11 @@
+<div class="preview_sql">
+ {% if query_data is empty %}
+ {% trans 'No change' %}
+ {% elseif query_data is iterable %}
+ {% for query in query_data %}
+ {{ format_sql(query) }}
+ {% endfor %}
+ {% else %}
+ {{ format_sql(query_data) }}
+ {% endif %}
+</div>
diff --git a/srcs/phpmyadmin/templates/radio_fields.twig b/srcs/phpmyadmin/templates/radio_fields.twig
new file mode 100644
index 0000000..58730e3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/radio_fields.twig
@@ -0,0 +1,11 @@
+{% if class is not empty %}
+<div class="{{ class }}">
+{% endif %}
+<input type="radio" name="{{ html_field_name }}" id="{{ html_field_id|raw }}" value="{{ choice_value }}"{{ checked ? ' checked="checked"' }}>
+<label for="{{ html_field_id|raw }}">{{ (escape_label ? choice_label|e : choice_label)|raw }}</label>
+{% if is_line_break %}
+<br>
+{% endif %}
+{% if class is not empty %}
+</div>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig b/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig
new file mode 100644
index 0000000..e15ea13
--- /dev/null
+++ b/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig
@@ -0,0 +1,54 @@
+<tr>
+ <td class="dragHandle">
+ <span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
+ </td>
+ <td class="routine_direction_cell{{ class }}">
+ <select name="item_param_dir[{{ index }}]">
+ {% for value in param_directions %}
+ <option value="{{ value }}"{{ item_param_dir == value ? ' selected' }}>{{ value }}</option>
+ {% endfor %}
+ </select>
+ </td>
+ <td>
+ <input name="item_param_name[{{ index }}]" type="text" value="{{ item_param_name }}">
+ </td>
+ <td>
+ <select name="item_param_type[{{ index }}]">
+ {{ supported_datatypes|raw }}
+ </select>
+ </td>
+ <td>
+ <input id="item_param_length_{{ index }}" name="item_param_length[{{ index }}]" type="text" value="{{ item_param_length }}">
+ <div class="enum_hint">
+ <a href="#" class="open_enum_editor">
+ {{ get_image('b_edit', '', {'title': 'ENUM/SET editor'|trans}) }}
+ </a>
+ </div>
+ </td>
+ <td class="hide no_len">---</td>
+ <td class="routine_param_opts_text">
+ <select lang="en" dir="ltr" name="item_param_opts_text[{{ index }}]">
+ <option value="">{% trans 'Charset' %}</option>
+ <option value=""></option>
+ {% for charset in charsets %}
+ <option value="{{ charset.name }}" title="{{ charset.description }}"{{ charset.is_selected ? ' selected' }}>
+ {{- charset.name -}}
+ </option>
+ {% endfor %}
+ </select>
+ </td>
+ <td class="hide no_opts">---</td>
+ <td class="routine_param_opts_num">
+ <select name="item_param_opts_num[{{ index }}]">
+ <option value=""></option>
+ {% for value in param_opts_num %}
+ <option value="{{ value }}"{{ item_param_opts_num == value ? ' selected' }}>{{ value }}</option>
+ {% endfor %}
+ </select>
+ </td>
+ <td class="routine_param_remove{{ drop_class }}">
+ <a href="#" class="routine_param_remove_anchor">
+ {{ get_icon('b_drop', 'Drop'|trans) }}
+ </a>
+ </td>
+</tr>
diff --git a/srcs/phpmyadmin/templates/scripts.twig b/srcs/phpmyadmin/templates/scripts.twig
new file mode 100644
index 0000000..13a29a3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/scripts.twig
@@ -0,0 +1,24 @@
+{% for file in files %}
+ <script data-cfasync="false" type="text/javascript" src="js/{{ file.filename }}
+ {{- '.php' in file.filename ? get_common(file.params|merge({'v': version})) : '?v=' ~ version|url_encode }}"></script>
+{% endfor %}
+
+<script data-cfasync="false" type="text/javascript">
+// <![CDATA[
+{{ code|raw }}
+{% if files is not empty %}
+AJAX.scriptHandler
+{% for file in files %}
+ .add('{{ file.filename|escape_js_string }}', {{ file.has_onload ? 1 : 0 }})
+{% endfor %}
+;
+$(function() {
+{% for file in files %}
+ {% if file.has_onload %}
+ AJAX.fireOnload('{{ file.filename|escape_js_string }}');
+ {% endif %}
+{% endfor %}
+});
+{% endif %}
+// ]]>
+</script>
diff --git a/srcs/phpmyadmin/templates/secondary_tabs.twig b/srcs/phpmyadmin/templates/secondary_tabs.twig
new file mode 100644
index 0000000..76b5725
--- /dev/null
+++ b/srcs/phpmyadmin/templates/secondary_tabs.twig
@@ -0,0 +1,6 @@
+<ul id="topmenu2">
+ {% for tab in sub_tabs %}
+ {{ get_html_tab(tab, url_params) }}
+ {% endfor %}
+</ul>
+<div class="clearfloat"></div>
diff --git a/srcs/phpmyadmin/templates/select_all.twig b/srcs/phpmyadmin/templates/select_all.twig
new file mode 100644
index 0000000..a0eb1eb
--- /dev/null
+++ b/srcs/phpmyadmin/templates/select_all.twig
@@ -0,0 +1,6 @@
+<img class="selectallarrow" src="{{ pma_theme_image }}arrow_{{ text_dir }}.png"
+ width="38" height="22" alt="{% trans 'With selected:' %}">
+<input type="checkbox" id="{{ form_name }}_checkall" class="checkall_box"
+ title="{% trans 'Check all' %}">
+<label for="{{ form_name }}_checkall">{% trans 'Check all' %}</label>
+<em class="with-selected">{% trans 'With selected:' %}</em>
diff --git a/srcs/phpmyadmin/templates/select_lang.twig b/srcs/phpmyadmin/templates/select_lang.twig
new file mode 100644
index 0000000..a8bddc8
--- /dev/null
+++ b/srcs/phpmyadmin/templates/select_lang.twig
@@ -0,0 +1,32 @@
+ <form method="get" action="index.php" class="disableAjax">
+ {{ get_hidden_inputs(_form_params) }}
+
+ {% if use_fieldset %}
+ <fieldset>
+ <legend lang="en" dir="ltr">{{ language_title|raw }}</legend>
+ {% else %}
+ <bdo lang="en" dir="ltr">
+ <label for="sel-lang">{{ language_title|raw }}</label>
+ </bdo>
+ {% endif %}
+
+ <select name="lang" class="autosubmit" lang="en" dir="ltr" id="sel-lang">
+
+ {% for language in available_languages %}
+ {# Is current one active ? #}
+ <option value="{{ language.getCode()|lower }}"
+ {%- if language.isActive() %}
+ selected="selected"
+ {%- endif -%}
+ >
+ {{ language.getName()|raw }}
+ </option>
+ {% endfor %}
+
+ </select>
+
+ {% if use_fieldset %}
+ </fieldset>
+ {% endif %}
+
+ </form>
diff --git a/srcs/phpmyadmin/templates/server/binlog/index.twig b/srcs/phpmyadmin/templates/server/binlog/index.twig
new file mode 100644
index 0000000..cdc85dc
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/binlog/index.twig
@@ -0,0 +1,107 @@
+<h2>
+ {{ get_image('s_tbl') }}
+ {% trans 'Binary log' %}
+</h2>
+
+<form action="server_binlog.php" method="post">
+ {{ get_hidden_inputs(url_params) }}
+ <fieldset>
+ <legend>
+ {% trans 'Select binary log to view' %}
+ </legend>
+
+ {% set full_size = 0 %}
+ <select name="log">
+ {% for each_log in binary_logs %}
+ <option value="{{ each_log['Log_name'] }}"
+ {{- each_log['Log_name'] == log ? ' selected' }}>
+ {{ each_log['Log_name'] }}
+ {% if each_log['File_size'] is defined %}
+ ({{ format_byte_down(each_log['File_size'], 3, 2)|join(' ') }})
+ {% set full_size = full_size + each_log['File_size'] %}
+ {% endif %}
+ </option>
+ {% endfor %}
+ </select>
+ {{ binary_logs|length }}
+ {% trans 'Files' %},
+ {% if full_size > 0 %}
+ {{ format_byte_down(full_size)|join(' ') }}
+ {% endif %}
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </fieldset>
+</form>
+
+{{ sql_message|raw }}
+
+<table id="binlogTable">
+ <thead>
+ <tr>
+ <td colspan="6" class="center">
+ {% if has_previous %}
+ {% if has_icons %}
+ <a href="server_binlog.php" data-post="{{ get_common(previous_params, '') }}" title="
+ {%- trans %}Previous{% context %}Previous page{% endtrans %}">
+ &laquo;
+ </a>
+ {% else %}
+ <a href="server_binlog.php" data-post="{{ get_common(previous_params, '') }}">
+ {% trans %}Previous{% context %}Previous page{% endtrans %} &laquo;
+ </a>
+ {% endif %}
+ -
+ {% endif %}
+
+ {% if is_full_query %}
+ <a href="server_binlog.php" data-post="{{ get_common(full_queries_params, '') }}" title="{% trans 'Truncate shown queries' %}">
+ <img src="{{ image_path }}s_partialtext.png" alt="{% trans 'Truncate shown queries' %}">
+ </a>
+ {% else %}
+ <a href="server_binlog.php" data-post="{{ get_common(full_queries_params, '') }}" title="{% trans 'Show full queries' %}">
+ <img src="{{ image_path }}s_fulltext.png" alt="{% trans 'Show full queries' %}">
+ </a>
+ {% endif %}
+
+ {% if has_next %}
+ -
+ {% if has_icons %}
+ <a href="server_binlog.php" data-post="{{ get_common(next_params, '') }}" title="
+ {%- trans %}Next{% context %}Next page{% endtrans %}">
+ &raquo;
+ </a>
+ {% else %}
+ <a href="server_binlog.php" data-post="{{ get_common(next_params, '') }}">
+ {% trans %}Next{% context %}Next page{% endtrans %} &raquo;
+ </a>
+ {% endif %}
+ {% endif %}
+ </td>
+ </tr>
+ <tr>
+ <th>{% trans 'Log name' %}</th>
+ <th>{% trans 'Position' %}</th>
+ <th>{% trans 'Event type' %}</th>
+ <th>{% trans 'Server ID' %}</th>
+ <th>{% trans 'Original position' %}</th>
+ <th>{% trans 'Information' %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for value in values %}
+ <tr class="noclick">
+ <td>{{ value['Log_name'] }}</td>
+ <td class="right">{{ value['Pos'] }}</td>
+ <td>{{ value['Event_type'] }}</td>
+ <td class="right">{{ value['Server_id'] }}</td>
+ <td class="right">
+ {{- value['Orig_log_pos'] is defined ? value['Orig_log_pos'] : value['End_log_pos'] -}}
+ </td>
+ <td>{{ format_sql(value['Info'], not is_full_query) }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/server/collations/index.twig b/srcs/phpmyadmin/templates/server/collations/index.twig
new file mode 100644
index 0000000..bb9dfb3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/collations/index.twig
@@ -0,0 +1,32 @@
+<h2>
+ {{ get_image('s_asci') }}
+ {% trans 'Character sets and collations' %}
+</h2>
+
+<div id="div_mysql_charset_collations">
+ <table class="data noclick">
+ <thead>
+ <tr>
+ <th id="collationHeader">{% trans 'Collation' %}</th>
+ <th>{% trans 'Description' %}</th>
+ </tr>
+ </thead>
+
+ {% for charset in charsets %}
+ <tr>
+ <th colspan="2" class="right">
+ {{ charset.name }}
+ {% if charset.description is not empty %}
+ (<em>{{ charset.description }}</em>)
+ {% endif %}
+ </th>
+ </tr>
+ {% for collation in charset.collations %}
+ <tr{{ collation.is_default ? ' class="marked"' }}>
+ <td>{{ collation.name }}</td>
+ <td>{{ collation.description }}</td>
+ </tr>
+ {% endfor %}
+ {% endfor %}
+ </table>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/databases/index.twig b/srcs/phpmyadmin/templates/server/databases/index.twig
new file mode 100644
index 0000000..ebff55f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/databases/index.twig
@@ -0,0 +1,323 @@
+<h2>
+ {{ get_image('s_db') }}
+ {% if has_statistics %}
+ {% trans 'Databases statistics' %}
+ {% else %}
+ {% trans 'Databases' %}
+ {% endif %}
+</h2>
+
+{% if is_create_database_shown %}
+ <ul>
+ <li id="li_create_database" class="no_bullets">
+ {% if has_create_database_privileges %}
+ <form method="post" action="server_databases.php" id="create_database_form" class="ajax">
+ <p>
+ <strong>
+ <label for="text_create_db">
+ {{ get_image('b_newdb') }}
+ {% trans 'Create database' %}
+ </label>
+ {{ show_mysql_docu('CREATE_DATABASE') }}
+ </strong>
+ </p>
+
+ {{ get_hidden_inputs('', '', 5) }}
+ <input type="hidden" name="reload" value="1">
+ {% if has_statistics %}
+ <input type="hidden" name="statistics" value="1">
+ {% endif %}
+
+ <input type="text" name="new_db" maxlength="64" class="textfield" value="
+ {{- database_to_create }}" id="text_create_db" placeholder="
+ {%- trans 'Database name' %}" required>
+
+ {% if charsets is not empty %}
+ <select lang="en" dir="ltr" name="db_collation">
+ <option value="">{% trans 'Collation' %}</option>
+ <option value=""></option>
+ {% for charset in charsets %}
+ <optgroup label="{{ charset.name }}" title="{{ charset.description }}">
+ {% for collation in charset.collations %}
+ <option value="{{ collation.name }}" title="{{ collation.description }}"{{ collation.is_selected ? ' selected' }}>
+ {{- collation.name -}}
+ </option>
+ {% endfor %}
+ </optgroup>
+ {% endfor %}
+ </select>
+ {% endif %}
+
+ <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Create' %}">
+ </form>
+ {% else %}
+ <p>
+ <strong>
+ {{ get_image('b_newdb') }}
+ {% trans 'Create database' %}
+ {{ show_mysql_docu('CREATE_DATABASE') }}
+ </strong>
+ </p>
+
+ <span class="noPrivileges">
+ {{ get_image('s_error', '', {
+ 'hspace': 2,
+ 'border': 0,
+ 'align': 'middle'
+ }) }}
+ {% trans 'No privileges to create databases' %}
+ </span>
+ {% endif %}
+ </li>
+ </ul>
+{% endif %}
+
+{% if database_count > 0 %}
+ {% include 'filter.twig' with {'filter_value': ''} only %}
+
+ <div id="tableslistcontainer">
+ {{ get_list_navigator(
+ database_count,
+ pos,
+ url_params,
+ 'server_databases.php',
+ 'frame_content',
+ max_db_list
+ ) }}
+
+ <form class="ajax" action="server_databases.php" method="post" name="dbStatsForm" id="dbStatsForm">
+ {{ get_hidden_inputs(url_params) }}
+ <div class="responsivetable">
+ <table id="tabledatabases" class="data">
+ <thead>
+ <tr>
+ {% if is_drop_allowed %}
+ <th></th>
+ {% endif %}
+ <th>
+ <a href="server_databases.php{{ get_common(url_params|merge({
+ 'sort_by': 'SCHEMA_NAME',
+ 'sort_order': url_params.sort_by == 'SCHEMA_NAME'
+ and url_params.sort_order == 'asc' ? 'desc' : 'asc'
+ })) }}">
+ {% trans 'Database' %}
+ {% if url_params.sort_by == 'SCHEMA_NAME' %}
+ {% if url_params.sort_order == 'asc' %}
+ {{ get_image('s_asc', 'Ascending'|trans) }}
+ {% else %}
+ {{ get_image('s_desc', 'Descending'|trans) }}
+ {% endif %}
+ {% endif %}
+ </a>
+ </th>
+
+ <th>
+ <a href="server_databases.php{{ get_common(url_params|merge({
+ 'sort_by': 'DEFAULT_COLLATION_NAME',
+ 'sort_order': url_params.sort_by == 'DEFAULT_COLLATION_NAME'
+ and url_params.sort_order == 'asc' ? 'desc' : 'asc'
+ })) }}">
+ {% trans 'Collation' %}
+ {% if url_params.sort_by == 'DEFAULT_COLLATION_NAME' %}
+ {% if url_params.sort_order == 'asc' %}
+ {{ get_image('s_asc', 'Ascending'|trans) }}
+ {% else %}
+ {{ get_image('s_desc', 'Descending'|trans) }}
+ {% endif %}
+ {% endif %}
+ </a>
+ </th>
+
+ {% if has_statistics %}
+ {% for name, statistic in header_statistics %}
+ <th{{ statistic.format == 'byte' ? ' colspan="2"' }}>
+ <a href="server_databases.php{{ get_common(url_params|merge({
+ 'sort_by': name,
+ 'sort_order': url_params.sort_by == name
+ and url_params.sort_order == 'asc' ? 'desc' : 'asc'
+ })) }}">
+ {{ statistic.title }}
+ {% if url_params.sort_by == name %}
+ {% if url_params.sort_order == 'asc' %}
+ {{ get_image('s_asc', 'Ascending'|trans) }}
+ {% else %}
+ {{ get_image('s_desc', 'Descending'|trans) }}
+ {% endif %}
+ {% endif %}
+ </a>
+ </th>
+ {% endfor %}
+ {% endif %}
+
+ {% if has_master_replication %}
+ <th>{% trans 'Master replication' %}</th>
+ {% endif %}
+
+ {% if has_slave_replication %}
+ <th>{% trans 'Slave replication' %}</th>
+ {% endif %}
+
+ <th>{% trans 'Action' %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for database in databases %}
+ <tr class="db-row{{ database.is_system_schema ? ' noclick' }}" data-filter-row="{{ database.name|upper }}">
+ {% if is_drop_allowed %}
+ <td class="tool">
+ <input type="checkbox" name="selected_dbs[]" class="checkall" title="
+ {{- database.name }}" value="
+ {{- database.name }}"
+ {{- database.is_system_schema ? ' disabled' }}>
+ </td>
+ {% endif %}
+
+ <td class="name">
+ <a href="{{ get_script_name_for_option(default_tab_database, 'database') }}
+ {{- get_common({'db': database.name}) }}" title="
+ {{- "Jump to database '%s'"|trans|format(database.name) }}">
+ {{ database.name }}
+ </a>
+ </td>
+
+ <td class="value">
+ <dfn title="{{ database.collation.description }}">
+ {{ database.collation.name }}
+ </dfn>
+ </td>
+
+ {% if has_statistics %}
+ {% for statistic in database.statistics %}
+ {% if statistic.format is same as('byte') %}
+ {% set value = format_byte_down(statistic.raw, 3, 1) %}
+ <td class="value">
+ <data value="{{ statistic.raw }}" title="{{ statistic.raw }}">
+ {{ value[0] }}
+ </data>
+ </td>
+ <td class="unit">{{ value[1] }}</td>
+ {% else %}
+ <td class="value">
+ <data value="{{ statistic.raw }}" title="{{ statistic.raw }}">
+ {{ format_number(statistic.raw, 0) }}
+ </data>
+ </td>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+
+ {% if database.replication.master.status %}
+ {% if database.replication.master.is_replicated %}
+ <td class="tool center">
+ {{ get_icon('s_success', 'Replicated'|trans) }}
+ </td>
+ {% else %}
+ <td class="tool center">
+ {{ get_icon('s_cancel', 'Not replicated'|trans) }}
+ </td>
+ {% endif %}
+ {% endif %}
+
+ {% if database.replication.slave.status %}
+ {% if database.replication.slave.is_replicated %}
+ <td class="tool center">
+ {{ get_icon('s_success', 'Replicated'|trans) }}
+ </td>
+ {% else %}
+ <td class="tool center">
+ {{ get_icon('s_cancel', 'Not replicated'|trans) }}
+ </td>
+ {% endif %}
+ {% endif %}
+
+ <td class="tool">
+ <a class="server_databases" data="
+ {{- database.name|js_format }}" href="server_privileges.php
+ {{- get_common({
+ 'db': database.name,
+ 'checkprivsdb': database.name
+ }) }}" title="
+ {{- 'Check privileges for database "%s".'|trans|format(database.name) }}">
+ {{ get_icon('s_rights', 'Check privileges'|trans) }}
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+
+ <tfoot>
+ <tr>
+ <th colspan="{{ is_drop_allowed ? '3' : '2' }}">
+ {% trans 'Total:' %}
+ <span id="filter-rows-count">
+ {{- database_count -}}
+ </span>
+ </th>
+
+ {% if has_statistics %}
+ {% for statistic in total_statistics %}
+ {% if statistic.format is same as('byte') %}
+ {% set value = format_byte_down(statistic.raw, 3, 1) %}
+ <th class="value">
+ <data value="{{ statistic.raw }}" title="{{ statistic.raw }}">
+ {{ value[0] }}
+ </data>
+ </th>
+ <th class="unit">{{ value[1] }}</th>
+ {% else %}
+ <th class="value">
+ <data value="{{ statistic.raw }}" title="{{ statistic.raw }}">
+ {{ format_number(statistic.raw, 0) }}
+ </data>
+ </th>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+
+ {% if has_master_replication %}
+ <th></th>
+ {% endif %}
+
+ {% if has_slave_replication %}
+ <th></th>
+ {% endif %}
+
+ <th></th>
+ </tr>
+ </tfoot>
+ </table>
+ </div>
+
+ {# Footer buttons #}
+ {% if is_drop_allowed %}
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pma_theme_image,
+ 'text_dir': text_dir,
+ 'form_name': 'dbStatsForm'
+ } only %}
+
+ {{ get_button_or_image(
+ '',
+ 'mult_submit ajax',
+ 'Drop'|trans,
+ 'b_deltbl'
+ ) }}
+ {% endif %}
+
+ {# Enable statistics #}
+ {% if not has_statistics %}
+ {{ 'Note: Enabling the database statistics here might cause heavy traffic between the web server and the MySQL server.'|trans|notice }}
+ <ul>
+ <li class="li_switch_dbstats">
+ <a href="server_databases.php" data-post="{{ get_common({'statistics': '1'}, '') }}" title="{% trans 'Enable statistics' %}">
+ <strong>{% trans 'Enable statistics' %}</strong>
+ </a>
+ </li>
+ </ul>
+ {% endif %}
+ </form>
+ </div>
+{% else %}
+ <p>{{ 'No databases'|trans|notice }}</p>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/server/engines/index.twig b/srcs/phpmyadmin/templates/server/engines/index.twig
new file mode 100644
index 0000000..2b92dc1
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/engines/index.twig
@@ -0,0 +1,27 @@
+<h2>
+ {{ get_image('b_engine') }}
+ {% trans 'Storage engines' %}
+</h2>
+
+<table class="noclick">
+ <thead>
+ <tr>
+ <th>{% trans 'Storage Engine' %}</th>
+ <th>{% trans 'Description' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for engine, details in engines %}
+ <tr class="
+ {{- details['Support'] == 'NO' or details['Support'] == 'DISABLED' ? ' disabled' }}
+ {{ details['Support'] == 'DEFAULT' ? ' marked' }}">
+ <td>
+ <a rel="newpage" href="server_engines.php{{ get_common({'engine': engine}) }}">
+ {{ details['Engine'] }}
+ </a>
+ </td>
+ <td>{{ details['Comment'] }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/server/engines/show.twig b/srcs/phpmyadmin/templates/server/engines/show.twig
new file mode 100644
index 0000000..088e3a0
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/engines/show.twig
@@ -0,0 +1,48 @@
+<h2>
+ {{ get_image('b_engine') }}
+ {% trans 'Storage engines' %}
+</h2>
+
+{% if engine is not empty %}
+ <h2>
+ {{ get_image('b_engine') }}
+ {{ engine.title }}
+ {{ show_mysql_docu(engine.help_page) }}
+ </h2>
+ <p><em>{{ engine.comment }}</em></p>
+
+ {% if engine.info_pages is not empty and engine.info_pages is iterable %}
+ <p>
+ <strong>[</strong>
+ {% if page is empty %}
+ <strong>{% trans 'Variables' %}</strong>
+ {% else %}
+ <a href="server_engines.php
+ {{- get_common({'engine': engine.engine}) }}">
+ {% trans 'Variables' %}
+ </a>
+ {% endif %}
+ {% for current, label in engine.info_pages %}
+ <strong>|</strong>
+ {% if page is defined and page == current %}
+ <strong>{{ label }}</strong>
+ {% else %}
+ <a href="server_engines.php
+ {{- get_common({'engine': engine.engine, 'page': current}) }}">
+ {{ label }}
+ </a>
+ {% endif %}
+ {% endfor %}
+ <strong>]</strong>
+ </p>
+ {% endif %}
+
+ {% if engine.page is not empty %}
+ {{ engine.page|raw }}
+ {% else %}
+ <p>{{ engine.support }}</p>
+ {{ engine.variables|raw }}
+ {% endif %}
+{% else %}
+ <p>{{ 'Unknown storage engine.'|trans|error }}</p>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/server/plugins/index.twig b/srcs/phpmyadmin/templates/server/plugins/index.twig
new file mode 100644
index 0000000..ec8bbd4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/plugins/index.twig
@@ -0,0 +1,58 @@
+<h2>
+ {{ get_image('b_plugin') }}
+ {% trans 'Plugins' %}
+</h2>
+
+<div id="plugins_plugins">
+ <div id="sectionlinks">
+ {% for type in plugins|keys %}
+ <a class="btn btn-primary" href="#plugins-{{ clean_types[type] }}">
+ {{ type }}
+ </a>
+ {% endfor %}
+ </div>
+ {% for type, list in plugins %}
+ <div class="responsivetable">
+ <table class="data_full_width" id="plugins-{{ clean_types[type] }}">
+ <caption class="tblHeaders">
+ {{ type }}
+ </caption>
+ <thead>
+ <tr>
+ <th>{% trans 'Plugin' %}</th>
+ <th>{% trans 'Description' %}</th>
+ <th>{% trans 'Version' %}</th>
+ <th>{% trans 'Author' %}</th>
+ <th>{% trans 'License' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for plugin in list %}
+ <tr class="noclick">
+ <th>
+ {{ plugin.name }}
+ {% if plugin.status != 'ACTIVE' %}
+ <small class="attention">
+ {% if plugin.status == 'INACTIVE' %}
+ {% trans 'inactive' %}
+ {% elseif plugin.status == 'DISABLED' %}
+ {% trans 'disabled' %}
+ {% elseif plugin.status == 'DELETING' %}
+ {% trans 'deleting' %}
+ {% elseif plugin.status == 'DELETED' %}
+ {% trans 'deleted' %}
+ {% endif %}
+ </small>
+ {% endif %}
+ </th>
+ <td>{{ plugin.description }}</td>
+ <td>{{ plugin.version }}</td>
+ <td>{{ plugin.author }}</td>
+ <td>{{ plugin.license }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endfor %}
+</div>
diff --git a/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig b/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig
new file mode 100644
index 0000000..26f0419
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig
@@ -0,0 +1,8 @@
+<fieldset id="fieldset_add_user">
+ <legend>{% trans %}New{% context %}Create new user{% endtrans %}</legend>
+ <a id="add_user_anchor" href="server_privileges.php{{ get_common(url_params) }}"
+ {% if rel_params is not empty %}
+ rel="{{ get_common(rel_params) }}"
+ {% endif %}>
+ {{ get_icon('b_usradd') }}{% trans 'Add user account' %}</a>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig b/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig
new file mode 100644
index 0000000..a28f302
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig
@@ -0,0 +1,9 @@
+<form class="ajax" id="changeUserGroupForm" action="server_privileges.php" method="post">
+ {{ get_hidden_inputs(params) }}
+ <fieldset id="fieldset_user_group_selection">
+ <legend>{% trans 'User group' %}</legend>
+ {% trans 'User group' %}:
+ {{ get_dropdown('userGroup', all_user_groups, user_group, 'userGroup_select') }}
+ <input type="hidden" name="changeUserGroup" value="1">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig b/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig
new file mode 100644
index 0000000..b49efa5
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig
@@ -0,0 +1,24 @@
+<div class="item" id="div_item_{{ name }}">
+ <label for="select_{{ name }}_priv">
+ <code><dfn title="{{ name_for_dfn }}">{{ priv_for_header }}</dfn></code>
+ </label>
+
+ <select id="select_{{ name }}_priv" name="{{ name_for_select }}[]" multiple="multiple" size="8">
+ {% for curr_col, curr_col_privs in columns %}
+ <option value="{{ curr_col }}"
+ {% if row[name_for_select] == 'Y' or curr_col_privs[name_for_current] %}
+ selected="selected"
+ {% endif %}>
+ {{ curr_col }}
+ </option>
+ {% endfor %}
+ </select>
+
+ <em>{% trans 'Or' %}</em>
+ <label for="checkbox_{{ name_for_select }}_none">
+ <input type="checkbox" name="{{ name_for_select }}_none"
+ id="checkbox_{{ name_for_select }}_none"
+ title="{% trans %}None{% context %}None privileges{% endtrans %}">
+ {% trans %}None{% context %}None privileges{% endtrans %}
+ </label>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig b/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig
new file mode 100644
index 0000000..84d288f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig
@@ -0,0 +1,17 @@
+<fieldset id="fieldset_delete_user">
+ <legend>
+ {{ get_icon('b_usrdrop') }}{% trans 'Remove selected user accounts' %}
+ </legend>
+ <input type="hidden" name="mode" value="2">
+ <p>({% trans 'Revoke all active privileges from the users and delete them afterwards.' %})</p>
+ <input type="checkbox" title="{% trans 'Drop the databases that have the same names as the users.' %}"
+ name="drop_users_db" id="checkbox_drop_users_db">
+ <label for="checkbox_drop_users_db"
+ title="{% trans 'Drop the databases that have the same names as the users.' %}">
+ {% trans 'Drop the databases that have the same names as the users.' %}
+ </label>
+</fieldset>
+
+<fieldset id="fieldset_delete_user_footer" class="tblFooters">
+ <input id="buttonGo" class="btn btn-primary ajax" type="submit" name="delete" value="{% trans 'Go' %}">
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig b/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig
new file mode 100644
index 0000000..12f8433
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig
@@ -0,0 +1,26 @@
+<div id="edit_user_dialog">
+ {{ header|raw }}
+ <form class="submenu-item" name="usersForm" id="addUsersForm" action="server_privileges.php" method="post">
+ {{ get_hidden_inputs() }}
+ <input type="hidden" name="username" value="{{ username }}">
+ <input type="hidden" name="hostname" value="{{ hostname }}">
+ <input type="hidden" name="dbname" value="{{ database }}">
+ <input type="hidden" name="routinename" value="{{ routine }}">
+ <input type="hidden" name="grant_count" value="{{ grant_count }}">
+ <fieldset id="fieldset_user_global_rights">
+ <legend data-submenu-label="{% trans 'Routine' %}">
+ {% trans 'Routine-specific privileges' %}
+ </legend>
+ <p>
+ <small>
+ <em>{% trans 'Note: MySQL privilege names are expressed in English.' %}</em>
+ </small>
+ </p>
+ {{ priv_checkboxes|raw }}
+ </fieldset>
+ <fieldset id="fieldset_user_privtable_footer" class="tblFooters">
+ <input type="hidden" name="update_privs" value="1">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </fieldset>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig b/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig
new file mode 100644
index 0000000..54b1046
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig
@@ -0,0 +1,22 @@
+{% for key, table in priv_table %}
+ <fieldset>
+ <legend>
+ <input type="checkbox" class="sub_checkall_box" id="checkall_{{ priv_table_names[key] }}_priv"
+ title="{% trans 'Check all' %}">
+ <label for="checkall_{{ priv_table_names[key] }}_priv">{{ priv_table_names[key] }}</label>
+ </legend>
+ {% for priv in table %}
+ {% set checked = row[priv[0] ~ '_priv'] is defined and row[priv[0] ~ '_priv'] == 'Y' ? ' checked="checked"' %}
+ {% set formatted_priv = format_privilege(priv, true) %}
+ <div class="item">
+ <input type="checkbox" class="checkall" name="{{ priv[0] }}_priv" id="checkbox_{{ priv[0] }}_priv"
+ value="Y" title="{{ priv[2] }}" {{ checked }}>
+ <label for="checkbox_{{ priv[0] }}_priv">
+ <code>
+ {{ formatted_priv|raw }}
+ </code>
+ </label>
+ </div>
+ {% endfor %}
+ </fieldset>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/server/privileges/initials_row.twig b/srcs/phpmyadmin/templates/server/privileges/initials_row.twig
new file mode 100644
index 0000000..feadc46
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/initials_row.twig
@@ -0,0 +1,26 @@
+<table id="initials_table" cellspacing="5">
+ <tr>
+ {% for tmp_initial, initial_was_found in array_initials %}
+ {% if tmp_initial is not same as(null) %}
+ {% if initial_was_found %}
+ <td>
+ <a class="ajax
+ {{- initial is defined and initial is same as(tmp_initial) ? ' active' -}}
+ " href="server_privileges.php
+ {{- get_common({'initial': tmp_initial}) }}">
+ {{- tmp_initial|raw -}}
+ </a>
+ </td>
+ {% else %}
+ <td>{{ tmp_initial|raw }}</td>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ <td>
+ <a href="server_privileges.php
+ {{- get_common({'showall': 1}) }}" class="nowrap">
+ {% trans 'Show all' %}
+ </a>
+ </td>
+ </tr>
+</table>
diff --git a/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig b/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig
new file mode 100644
index 0000000..438ecb7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig
@@ -0,0 +1,104 @@
+<form class="submenu-item" action="server_privileges.php" id="{{ form_id }}" method="post">
+ {{ get_hidden_inputs() }}
+ <input type="hidden" name="username" value="{{ username }}">
+ <input type="hidden" name="hostname" value="{{ hostname }}">
+
+ <fieldset>
+ <legend data-submenu-label="{{ sub_menu_label }}">
+ {{ legend }}
+ </legend>
+
+ <table class="data">
+ <thead>
+ <tr>
+ <th>{{ type_label }}</th>
+ <th>{% trans 'Privileges' %}</th>
+ <th>{% trans 'Grant' %}</th>
+ {% if type == 'database' %}
+ <th>{% trans 'Table-specific privileges' %}</th>
+ {% elseif type == 'table' %}
+ <th>{% trans 'Column-specific privileges' %}</th>
+ {% endif %}
+ <th colspan="2">{% trans 'Action' %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% if privileges|length == 0 %}
+ {% set colspan = type == 'database' ? 7 : (type == 'table' ? 6 : 5) %}
+ <tr>
+ <td colspan="{{ colspan }}"><center><em>{% trans 'None' %}</em></center></td>
+ </tr>
+ {% else %}
+ {% for privilege in privileges %}
+ <tr>
+ <td>{{ privilege['name'] }}</td>
+ <td><code>{{ privilege['privileges']|raw }}</code></td>
+ <td>{{ privilege['grant'] ? 'Yes'|trans : 'No'|trans }}</td>
+
+ {% if type == 'database' %}
+ <td>{{ privilege['table_privs'] ? 'Yes'|trans : 'No'|trans }}</td>
+ {% elseif type == 'table' %}
+ <td>{{ privilege['column_privs'] ? 'Yes'|trans : 'No'|trans }}</td>
+ {% endif %}
+
+ <td>{{ privilege['edit_link']|raw }}</td>
+ <td>{{ privilege['revoke_link']|raw }}</td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
+
+ {% if type == 'database' %}
+ <label for="text_dbname">{% trans 'Add privileges on the following database(s):' %}</label>
+
+ {%- if databases is not empty %}
+ <select name="pred_dbname[]" multiple="multiple">
+ {% for database in databases %}
+ <option value="{{ database|escape_mysql_wildcards }}">
+ {{ database }}
+ </option>
+ {% endfor %}
+ </select>
+ {% endif -%}
+
+ <input type="text" id="text_dbname" name="dbname">
+ {{ show_hint("Wildcards % and _ should be escaped with a \\ to use them literally."|trans) }}
+ {% elseif type == 'table' %}
+ <input type="hidden" name="dbname" value="{{ database }}">
+
+ <label for="text_tablename">{% trans 'Add privileges on the following table:' %}</label>
+
+ {%- if tables is not empty %}
+ <select name="pred_tablename" class="autosubmit">
+ <option value="" selected="selected">{% trans 'Use text field' %}:</option>
+ {% for table in tables %}
+ <option value="{{ table }}">{{ table }}</option>
+ {% endfor %}
+ </select>
+ {% endif -%}
+
+ <input type="text" id="text_tablename" name="tablename">
+ {% else %}
+ <input type="hidden" name="dbname" value="{{ database }}">
+
+ <label for="text_routinename">{% trans 'Add privileges on the following routine:' %}</label>
+
+ {%- if routines is not empty %}
+ <select name="pred_routinename" class="autosubmit">
+ <option value="" selected="selected">{% trans 'Use text field' %}:</option>
+ {% for routine in routines %}
+ <option value="{{ routine }}">{{ routine }}</option>
+ {% endfor %}
+ </select>
+ {% endif -%}
+
+ <input type="text" id="text_routinename" name="routinename">
+ {% endif %}
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/server/privileges/require_options.twig b/srcs/phpmyadmin/templates/server/privileges/require_options.twig
new file mode 100644
index 0000000..03da691
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/require_options.twig
@@ -0,0 +1,32 @@
+<fieldset>
+ <legend>SSL</legend>
+ <div id="require_ssl_div">
+ {% for require_option in require_options %}
+ {% if require_option['name'] is same as('ssl_cipher') %}
+ <div id="specified_div" style="padding-left:20px;">
+ {% endif %}
+ <div class="item">
+ {% if require_option['radio'] %}
+ <input type="radio" name="ssl_type"
+ id="{{ require_option['name'] }}_{{ require_option['value'] }}"
+ title="{{ require_option['description'] }}"
+ value="{{ require_option['value'] }}" {{ require_option['checked']|raw }}>
+ <label for="{{ require_option['name'] }}_{{ require_option['value'] }}">
+ <code>{{ require_option['label'] }}</code>
+ </label>
+ {% else %}
+ <label for="text_{{ require_option['name'] }}">
+ <code>{{ require_option['label'] }}</code>
+ </label>
+ <input type="text" name="{{ require_option['name'] }}"
+ id="text_{{ require_option['name'] }}" value="{{ require_option['value'] }}"
+ size="80" title="{{ require_option['description'] }}"
+ {%- if require_option['disabled'] %}
+ disabled
+ {%- endif %}>
+ {% endif %}
+ </div>
+ {% endfor %}
+ </div>{# END specified_div #}
+ </div>{# END require_ssl_div #}
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig b/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig
new file mode 100644
index 0000000..2569bd7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig
@@ -0,0 +1,21 @@
+<fieldset>
+ <legend>{% trans 'Resource limits' %}</legend>
+ <p>
+ <small>
+ <em>{% trans 'Note: Setting these options to 0 (zero) removes the limit.' %}</em>
+ </small>
+ </p>
+ {% for limit in limits %}
+ <div class="item">
+ <label for="text_{{ limit['input_name'] }}">
+ <code>
+ <dfn title="{{ limit['description'] }}">
+ {{ limit['name_main'] }}
+ </dfn>
+ </code>
+ </label>
+ <input type="number" name="{{ limit['input_name'] }}" id="text_{{ limit['input_name'] }}"
+ value="{{ limit['value'] }}" title="{{ limit['description'] }}">
+ </div>
+ {% endfor %}
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/replication/change_master.twig b/srcs/phpmyadmin/templates/server/replication/change_master.twig
new file mode 100644
index 0000000..1ff75ba
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/change_master.twig
@@ -0,0 +1,35 @@
+<form method="post" action="server_replication.php">
+ {{ get_hidden_inputs('', '') }}
+ <fieldset id="fieldset_add_user_login">
+ <legend>
+ {% trans 'Slave configuration' %} -
+ {% trans 'Change or reconfigure master server' %}
+ </legend>
+ <p>
+ {% trans 'Make sure you have a unique server-id in your configuration file (my.cnf). If not, please add the following line into [mysqld] section:' %}
+ </p>
+ <pre>server-id={{ server_id }}</pre>
+
+ <div class="item">
+ <label for="text_username">{% trans 'User name:' %}</label>
+ <input id="text_username" name="username" type="text" maxlength="{{ username_length }}" title="{% trans 'User name' %}" required>
+ </div>
+ <div class="item">
+ <label for="text_pma_pw">{% trans 'Password:' %}</label>
+ <input id="text_pma_pw" name="pma_pw" type="password" title="{% trans 'Password' %}" required>
+ </div>
+ <div class="item">
+ <label for="text_hostname">{% trans 'Host:' %}</label>
+ <input id="text_hostname" name="hostname" type="text" maxlength="{{ hostname_length }}" value="" required>
+ </div>
+ <div class="item">
+ <label for="text_port">{% trans 'Port:' %}</label>
+ <input id="text_port" name="text_port" type="number" maxlength="6" value="3306" required>
+ </div>
+ </fieldset>
+ <fieldset id="fieldset_user_privtable_footer" class="tblFooters">
+ <input type="hidden" name="sr_take_action" value="true">
+ <input type="hidden" name="{{ submit_name }}" value="1">
+ <input class="btn btn-primary" type="submit" id="confslave_submit" value="{% trans 'Go' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/server/replication/database_multibox.twig b/srcs/phpmyadmin/templates/server/replication/database_multibox.twig
new file mode 100644
index 0000000..816db08
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/database_multibox.twig
@@ -0,0 +1,9 @@
+<select id="db_select" class="width96" name="db_select[]" size="6" multiple>
+ {% for database in databases %}
+ <option value="{{ database }}">{{ database }}</option>
+ {% endfor %}
+</select>
+<p>
+ <a href="#" id="db_select_href">{% trans 'Select all' %}</a> /
+ <a href="#" id="db_reset_href">{% trans 'Unselect all' %}</a>
+</p>
diff --git a/srcs/phpmyadmin/templates/server/replication/index.twig b/srcs/phpmyadmin/templates/server/replication/index.twig
new file mode 100644
index 0000000..c40df0d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/index.twig
@@ -0,0 +1,36 @@
+<h2>
+ {{ get_image('s_replication') }}
+ {% trans 'Replication' %}
+</h2>
+
+{% if is_super_user %}
+ <div id="replication">
+ {{ error_messages|raw }}
+
+ {% if is_master %}
+ {{ master_replication_html|raw }}
+ {% elseif master_configure is null and clear_screen is null %}
+ <fieldset>
+ <legend>{% trans 'Master replication' %}</legend>
+ {% apply format('<a href="server_replication.php" data-post="' ~ get_common(url_params|merge({'mr_configure': true}), '') ~ '">', '</a>')|raw %}
+ {% trans %}
+ This server is not configured as master in a replication process. Would you like to %sconfigure%s it?
+ {% endtrans %}
+ {% endapply %}
+ </fieldset>
+ {% endif %}
+
+ {% if master_configure is not null %}
+ {{ master_configuration_html|raw }}
+ {% else %}
+ {% if clear_screen is null %}
+ {{ slave_configuration_html|raw }}
+ {% endif %}
+ {% if slave_configure is not null %}
+ {{ change_master_html|raw }}
+ {% endif %}
+ {% endif %}
+ </div>
+{% else %}
+ {{ 'No privileges'|trans|error }}
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig b/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig
new file mode 100644
index 0000000..5c2eec3
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig
@@ -0,0 +1,84 @@
+<div id="master_addslaveuser_gui">
+ <form action="server_privileges.php" method="post" autocomplete="off" onsubmit="return checkAddUser(this);">
+ {{ get_hidden_inputs('', '') }}
+
+ <fieldset id="fieldset_add_user_login">
+ <legend>{% trans 'Add slave replication user' %}</legend>
+
+ <input type="hidden" name="grant_count" value="25">
+ <input type="hidden" name="createdb" id="createdb_0" value="0">
+ {# Needed for the replication slaves. #}
+ <input type="hidden" name="Repl_slave_priv" id="checkbox_Repl_slave_priv" value="Y">
+ <input type="hidden" name="sr_take_action" value="true">
+
+ <div class="item">
+ <label for="select_pred_username">
+ {% trans 'User name:' %}
+ </label>
+ <span class="options">
+ <select name="pred_username" id="select_pred_username" title="{% trans 'User name' %}">
+ <option value="any"{{ predefined_username == 'any' ? ' selected' }}>{% trans 'Any user' %}</option>
+ <option value="userdefined"{{ predefined_username == 'userdefined' ? ' selected' }}>{% trans 'Use text field:' %}</option>
+ </select>
+ </span>
+ <input type="text" name="username" id="pma_username" maxlength="{{ username_length }}" title="{% trans 'User name' %}" value="{{ username }}">
+ </div>
+
+ <div class="item">
+ <label for="select_pred_hostname">
+ {% trans 'Host:' %}
+ </label>
+ <span class="options">
+ <select name="pred_hostname" id="select_pred_hostname" title="{% trans 'Host' %}"
+ {%- if this_host is not null %} data-thishost="{{ this_host }}"{% endif %}>
+ <option value="any"{{ predefined_hostname == 'any' ? ' selected' }}>{% trans 'Any host' %}</option>
+ <option value="localhost"{{ predefined_hostname == 'localhost' ? ' selected' }}>{% trans 'Local' %}</option>
+ {% if this_host is not null %}
+ <option value="thishost"{{ predefined_hostname == 'thishost' ? ' selected' }}>{% trans 'This host' %}</option>
+ {% endif %}
+ <option value="hosttable"{{ predefined_hostname == 'hosttable' ? ' selected' }}>{% trans 'Use host table' %}</option>
+ <option value="userdefined"{{ predefined_hostname == 'userdefined' ? ' selected' }}>{% trans 'Use text field:' %}</option>
+ </select>
+ </span>
+ <input type="text" name="hostname" id="pma_hostname" maxlength="{{ hostname_length }}" title="{% trans 'Host' %}" value="{{ hostname }}">
+ {{ show_hint('When Host table is used, this field is ignored and values stored in Host table are used instead.'|trans) }}
+ </div>
+
+ <div class="item">
+ <label for="select_pred_password">
+ {% trans 'Password:' %}
+ </label>
+ <span class="options">
+ <select name="pred_password" id="select_pred_password" title="{% trans 'Password' %}">
+ <option value="none"{{ has_username ? ' selected' }}>{% trans 'No password' %}</option>
+ <option value="userdefined"{{ not has_username ? ' selected' }}>{% trans 'Use text field:' %}</option>
+ </select>
+ </span>
+ <input type="password" id="text_pma_pw" name="pma_pw" title="{% trans 'Password' %}">
+ </div>
+
+ <div class="item">
+ <label for="text_pma_pw2">
+ {% trans 'Re-type:' %}
+ </label>
+ <span class="options"></span>
+ <input type="password" id="text_pma_pw2" name="pma_pw2" title="{% trans 'Re-type' %}">
+ </div>
+
+ <div class="item">
+ <label for="button_generate_password">
+ {% trans 'Generate password:' %}
+ </label>
+ <span class="options">
+ <input type="button" class="btn btn-secondary button" id="button_generate_password" value="{% trans 'Generate' %}" onclick="Functions.suggestPassword(this.form)">
+ </span>
+ <input type="text" name="generated_pw" id="generated_pw">
+ </div>
+ </fieldset>
+
+ <fieldset id="fieldset_user_privtable_footer" class="tblFooters">
+ <input type="hidden" name="adduser_submit" value="1">
+ <input class="btn btn-primary" type="submit" id="adduser_submit" value="{% trans 'Go' %}">
+ </fieldset>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/replication/master_configuration.twig b/srcs/phpmyadmin/templates/server/replication/master_configuration.twig
new file mode 100644
index 0000000..5243bac
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/master_configuration.twig
@@ -0,0 +1,32 @@
+<fieldset>
+ <legend>{% trans 'Master configuration' %}</legend>
+ <p>
+ {% trans %}
+ This server is not configured as a master server in a replication process. You can choose from either replicating all databases and ignoring some of them (useful if you want to replicate a majority of the databases) or you can choose to ignore all databases by default and allow only certain databases to be replicated. Please select the mode:
+ {% endtrans %}
+ </p>
+ <select name="db_type" id="db_type">
+ <option value="all">{% trans 'Replicate all databases; Ignore:' %}</option>
+ <option value="ign">{% trans 'Ignore all databases; Replicate:' %}</option>
+ </select>
+ <p>{% trans 'Please select databases:' %}</p>
+ {{ database_multibox|raw }}
+ <p>
+ {% trans %}
+ Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards.
+ {% endtrans %}
+ </p>
+ <pre id="rep"></pre>
+ <p>
+ {% trans %}
+ Once you restarted MySQL server, please click on Go button. Afterwards, you should see a message informing you, that this server <strong>is</strong> configured as master.
+ {% endtrans %}
+ </p>
+</fieldset>
+
+<fieldset class="tblFooters">
+ <form method="post" action="server_replication.php">
+ {{ get_hidden_inputs('', '') }}
+ <input id="goButton" class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </form>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/replication/master_replication.twig b/srcs/phpmyadmin/templates/server/replication/master_replication.twig
new file mode 100644
index 0000000..8ba5d1b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/master_replication.twig
@@ -0,0 +1,52 @@
+{% if not clear_screen %}
+ <fieldset>
+ <legend>{% trans 'Master replication' %}</legend>
+ {% trans 'This server is configured as master in a replication process.' %}
+ <ul>
+ <li>
+ <a href="#master_status_href" id="master_status_href">
+ {% trans 'Show master status' %}
+ </a>
+ {{ master_status_table|raw }}
+ </li>
+ <li>
+ <p>
+ <a href="#master_slaves_href" id="master_slaves_href">
+ {% trans 'Show connected slaves' %}
+ </a>
+ </p>
+
+ <div id="replication_slaves_section" style="display: none;">
+ <table class="data">
+ <thead>
+ <tr>
+ <th>{% trans 'Server ID' %}</th>
+ <th>{% trans 'Host' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for slave in slaves %}
+ <tr>
+ <td class="value">{{ slave['Server_id'] }}</td>
+ <td class="value">{{ slave['Host'] }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ <br>
+ {{ 'Only slaves started with the --report-host=host_name option are visible in this list.'|trans|notice }}
+ <br>
+ </div>
+ </li>
+ <li>
+ <a href="server_replication.php" data-post="{{ get_common(url_params, '') }}" id="master_addslaveuser_href">
+ {% trans 'Add slave replication user' %}
+ </a>
+ </li>
+{% endif %}
+{% if master_add_user %}
+ {{ master_add_slave_user|raw }}
+{% elseif not clear_screen %}
+ </ul>
+ </fieldset>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig b/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig
new file mode 100644
index 0000000..5b12ea7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig
@@ -0,0 +1,109 @@
+<fieldset>
+ <legend>{% trans 'Slave replication' %}</legend>
+ {% if server_slave_multi_replication %}
+ {% trans 'Master connection:' %}
+ <form method="get" action="server_replication.php">
+ {{ get_hidden_inputs(url_params) }}
+ <select name="master_connection">
+ <option value="">{% trans 'Default' %}</option>
+ {% for server in server_slave_multi_replication %}
+ <option value="{{ server['Connection_name'] }}"{{ master_connection == server['Connection_name'] ? ' selected' }}>
+ {{ server['Connection_name'] }}
+ </option>
+ {% endfor %}
+ </select>
+ <input id="goButton" class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </form>
+ <br>
+ <br>
+ {% endif %}
+
+ {% if server_slave_status %}
+ <div id="slave_configuration_gui">
+ {% if not slave_sql_running %}
+ {{ 'Slave SQL Thread not running!'|trans|error }}
+ {% endif %}
+ {% if not slave_io_running %}
+ {{ 'Slave IO Thread not running!'|trans|error }}
+ {% endif %}
+
+ <p>{% trans 'Server is configured as slave in a replication process. Would you like to:' %}</p>
+ <ul>
+ <li>
+ <a href="#slave_status_href" id="slave_status_href">{% trans 'See slave status table' %}</a>
+ {{ slave_status_table|raw }}
+ </li>
+ <li>
+ <a href="#slave_control_href" id="slave_control_href">{% trans 'Control slave:' %}</a>
+ <div id="slave_control_gui" class="hide">
+ <ul>
+ <li>
+ <a href="server_replication.php" data-post="{{ slave_control_full_link }}">
+ {{ not slave_io_running or not slave_sql_running ? 'Full start' : 'Full stop' }}
+ </a>
+ </li>
+ <li>
+ <a class="ajax" id="reset_slave" href="server_replication.php" data-post="{{ slave_control_reset_link }}">
+ {% trans 'Reset slave' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_replication.php" data-post="{{ slave_control_sql_link }}">
+ {% if not slave_sql_running %}
+ {% trans 'Start SQL Thread only' %}
+ {% else %}
+ {% trans 'Stop SQL Thread only' %}
+ {% endif %}
+ </a>
+ </li>
+ <li>
+ <a href="server_replication.php" data-post="{{ slave_control_io_link }}">
+ {% if not slave_io_running %}
+ {% trans 'Start IO Thread only' %}
+ {% else %}
+ {% trans 'Stop IO Thread only' %}
+ {% endif %}
+ </a>
+ </li>
+ </ul>
+ </div>
+ </li>
+ <li>
+ <a href="#slave_errormanagement_href" id="slave_errormanagement_href">
+ {% trans 'Error management:' %}
+ </a>
+ <div id="slave_errormanagement_gui" class="hide">
+ {{ 'Skipping errors might lead into unsynchronized master and slave!'|trans|error }}
+ <ul>
+ <li>
+ <a href="server_replication.php" data-post="{{ slave_skip_error_link }}">
+ {% trans 'Skip current error' %}
+ </a>
+ </li>
+ <li>
+ <form method="post" action="server_replication.php">
+ {{ get_hidden_inputs('', '') }}
+ {{ 'Skip next %s errors.'|trans|format('<input type="text" name="sr_skip_errors_count" value="1" class="repl_gui_skip_err_cnt">')|raw }}
+ <input class="btn btn-primary" type="submit" name="sr_slave_skip_error" value="{% trans 'Go' %}">
+ <input type="hidden" name="sr_take_action" value="1">
+ </form>
+ </li>
+ </ul>
+ </div>
+ </li>
+ <li>
+ <a href="server_replication.php" data-post="{{ reconfigure_master_link }}">
+ {% trans 'Change or reconfigure master server' %}
+ </a>
+ </li>
+ </ul>
+ </div>
+ {% elseif not has_slave_configure %}
+ {% apply format('<a href="server_replication.php" data-post="' ~ get_common(url_params|merge({
+ 'sl_configure': true,
+ 'repl_clear_scr': true
+ })) ~ '">', '</a>')|raw %}
+ {% trans 'This server is not configured as slave in a replication process. Would you like to %sconfigure%s it?' %}
+ {% endapply %}
+ {% endif %}
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/server/replication/status_table.twig b/srcs/phpmyadmin/templates/server/replication/status_table.twig
new file mode 100644
index 0000000..79c45f6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/replication/status_table.twig
@@ -0,0 +1,34 @@
+<div id="replication_{{ type }}_section"{{ is_hidden ? ' style="display: none;"' }}>
+ {% if has_title %}
+ <h4>
+ <a id="replication_{{ type }}"></a>
+ {% if type == 'master' %}
+ {% trans 'Master status' %}
+ {% else %}
+ {% trans 'Slave status' %}
+ {% endif %}
+ </h4>
+ {% endif %}
+
+ <table id="server{{ type }}replicationsummary" class="data">
+ <thead>
+ <tr>
+ <th>{% trans 'Variable' %}</th>
+ <th>{% trans 'Value' %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for variable in variables %}
+ <tr>
+ <td class="name">{{ variable.name }}</td>
+ <td class="value">
+ <span{% if variable.status == 'attention' %} class="attention"{% elseif variable.status == 'allfine' %} class="allfine"{% endif %}>
+ {{ variable.value }}
+ </span>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/status/advisor/index.twig b/srcs/phpmyadmin/templates/server/status/advisor/index.twig
new file mode 100644
index 0000000..b1bc3a9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/advisor/index.twig
@@ -0,0 +1,39 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'advisor' %}
+
+{% block content %}
+
+ {% if data is not empty %}
+ <a href="#openAdvisorInstructions">{{ get_icon('b_help', 'Instructions'|trans) }}</a>
+
+ <div id="statustabs_advisor"></div>
+
+ <div id="advisorInstructionsDialog" class="hide">
+ <p>
+ {% trans %}
+ The Advisor system can provide recommendations on server variables by analyzing the server status variables.
+ {% endtrans %}
+ </p>
+ <p>
+ {% trans %}
+ Do note however that this system provides recommendations based on simple calculations and by rule of thumb which may not necessarily apply to your system.
+ {% endtrans %}
+ </p>
+ <p>
+ {% trans %}
+ Prior to changing any of the configuration, be sure to know what you are changing (by reading the documentation) and how to undo the change. Wrong tuning can have a very negative effect on performance.
+ {% endtrans %}
+ </p>
+ <p>
+ {% trans %}
+ The best way to tune your system would be to change only one setting at a time, observe or benchmark your database, and undo the change if there was no clearly measurable improvement.
+ {% endtrans %}
+ </p>
+ </div>
+
+ <div id="advisorData" class="hide">{{ data }}</div>
+ {% else %}
+ {{ 'Not enough privilege to view the advisor.'|trans|error }}
+ {% endif %}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/status/base.twig b/srcs/phpmyadmin/templates/server/status/base.twig
new file mode 100644
index 0000000..66547a8
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/base.twig
@@ -0,0 +1,39 @@
+<div>
+ <ul id="topmenu2">
+ <li>
+ <a href="server_status.php{{ get_common() }}"{{ active == 'status' ? ' class="tabactive"' }}>
+ {% trans 'Server' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_status_processes.php{{ get_common() }}"{{ active == 'processes' ? ' class="tabactive"' }}>
+ {% trans 'Processes' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_status_queries.php{{ get_common() }}"{{ active == 'queries' ? ' class="tabactive"' }}>
+ {% trans 'Query statistics' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_status_variables.php{{ get_common() }}"{{ active == 'variables' ? ' class="tabactive"' }}>
+ {% trans 'All status variables' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_status_monitor.php{{ get_common() }}"{{ active == 'monitor' ? ' class="tabactive"' }}>
+ {% trans 'Monitor' %}
+ </a>
+ </li>
+ <li>
+ <a href="server_status_advisor.php{{ get_common() }}"{{ active == 'advisor' ? ' class="tabactive"' }}>
+ {% trans 'Advisor' %}
+ </a>
+ </li>
+ </ul>
+ <div class="clearfloat"></div>
+
+ <div>
+ {% block content %}{% endblock %}
+ </div>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/status/monitor/index.twig b/srcs/phpmyadmin/templates/server/status/monitor/index.twig
new file mode 100644
index 0000000..c4c7277
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/monitor/index.twig
@@ -0,0 +1,268 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'monitor' %}
+{% block content %}
+
+<div class="tabLinks">
+ <a href="#pauseCharts">
+ {{ get_image('play') }}
+ {% trans 'Start Monitor' %}
+ </a>
+ <a href="#settingsPopup" class="popupLink">
+ {{ get_image('s_cog') }}
+ {% trans 'Settings' %}
+ </a>
+ <a href="#monitorInstructionsDialog">
+ {{ get_image('b_help') }}
+ {% trans 'Instructions/Setup' %}
+ </a>
+ <a href="#endChartEditMode" class="hide">
+ {{ get_image('s_okay') }}
+ {% trans 'Done dragging (rearranging) charts' %}
+ </a>
+</div>
+
+<div class="popupContent settingsPopup">
+ <a href="#addNewChart">
+ {{ get_image('b_chart') }}
+ {% trans 'Add chart' %}
+ </a>
+ <a href="#rearrangeCharts">
+ {{ get_image('b_tblops') }}
+ {% trans 'Enable charts dragging' %}
+ </a>
+ <div class="clearfloat paddingtop"></div>
+
+ <div class="floatleft">
+ {% trans 'Refresh rate' %}
+ <br>
+ <select id="id_gridChartRefresh" class="refreshRate" name="gridChartRefresh">
+ {% for rate in [2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200] %}
+ <option value="{{ rate }}"{{ rate == 5 ? ' selected' }}>
+ {% if rate < 60 %}
+ {% if rate == 1 %}
+ {{ '%d second'|trans|format(rate) }}
+ {% else %}
+ {{ '%d seconds'|trans|format(rate) }}
+ {% endif %}
+ {% else %}
+ {% if rate / 60 == 1 %}
+ {{ '%d minute'|trans|format(rate / 60) }}
+ {% else %}
+ {{ '%d minutes'|trans|format(rate / 60) }}
+ {% endif %}
+ {% endif %}
+ </option>
+ {% endfor %}
+ </select>
+ <br>
+ </div>
+
+ <div class="floatleft">
+ {% trans 'Chart columns' %}
+ <br>
+ <select name="chartColumns">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+ <option>6</option>
+ </select>
+ </div>
+
+ <div class="clearfloat paddingtop">
+ <strong>{% trans 'Chart arrangement' %}</strong>
+ {{ show_hint('The arrangement of the charts is stored to the browsers local storage. You may want to export it if you have a complicated set up.'|trans) }}
+ <br>
+ <a class="ajax" href="#importMonitorConfig">
+ {% trans 'Import' %}
+ </a> -
+ <a class="disableAjax" href="#exportMonitorConfig">
+ {% trans 'Export' %}
+ </a> -
+ <a href="#clearMonitorConfig">
+ {% trans 'Reset to default' %}
+ </a>
+ </div>
+</div>
+
+<div id="monitorInstructionsDialog" title="{% trans 'Monitor Instructions' %}" class="hide">
+ <p>
+ {% trans %}
+ The phpMyAdmin Monitor can assist you in optimizing the server configuration and track down time intensive queries. For the latter you will need to set log_output to 'TABLE' and have either the slow_query_log or general_log enabled. Note however, that the general_log produces a lot of data and increases server load by up to 15%.
+ {% endtrans %}
+ </p>
+ <img class="ajaxIcon" src="{{ image_path }}ajax_clock_small.gif" alt="{% trans 'Loading…' %}">
+
+ <div class="ajaxContent"></div>
+ <br>
+
+ <div class="monitorUse hide">
+ <p><strong>{% trans 'Using the monitor:' %}</strong></p>
+ <p>
+ {% trans %}
+ Your browser will refresh all displayed charts in a regular interval. You may add charts and change the refresh rate under 'Settings', or remove any chart using the cog icon on each respective chart.
+ {% endtrans %}
+ </p>
+ <p>
+ {% trans %}
+ To display queries from the logs, select the relevant time span on any chart by holding down the left mouse button and panning over the chart. Once confirmed, this will load a table of grouped queries, there you may click on any occurring SELECT statements to further analyze them.
+ {% endtrans %}
+ </p>
+ <p>
+ {{ get_image('s_attention') }}
+ <strong>{% trans 'Please note:' %}</strong>
+ </p>
+ <p>
+ {% trans %}
+ Enabling the general_log may increase the server load by 5-15%. Also be aware that generating statistics from the logs is a load intensive task, so it is advisable to select only a small time span and to disable the general_log and empty its table once monitoring is not required any more.
+ {% endtrans %}
+ </p>
+ </div>
+</div>
+
+<div id="addChartDialog" title="{% trans 'Add chart' %}" class="hide">
+ <div id="tabGridVariables">
+ <p>
+ <input type="text" name="chartTitle" value="{% trans 'Chart Title' %}">
+ </p>
+ <input type="radio" name="chartType" value="preset" id="chartPreset">
+
+ <label for="chartPreset">{% trans 'Preset chart' %}</label>
+ <select name="presetCharts"></select>
+ <br>
+
+ <input type="radio" name="chartType" value="variable" id="chartStatusVar" checked="checked">
+ <label for="chartStatusVar">
+ {% trans 'Status variable(s)' %}
+ </label>
+ <br>
+
+ <div id="chartVariableSettings">
+ <label for="chartSeries">{% trans 'Select series:' %}</label>
+ <br>
+ <select id="chartSeries" name="varChartList" size="1">
+ <option>{% trans 'Commonly monitored' %}</option>
+ <option>Processes</option>
+ <option>Questions</option>
+ <option>Connections</option>
+ <option>Bytes_sent</option>
+ <option>Bytes_received</option>
+ <option>Threads_connected</option>
+ <option>Created_tmp_disk_tables</option>
+ <option>Handler_read_first</option>
+ <option>Innodb_buffer_pool_wait_free</option>
+ <option>Key_reads</option>
+ <option>Open_tables</option>
+ <option>Select_full_join</option>
+ <option>Slow_queries</option>
+ </select>
+ <br>
+
+ <label for="variableInput">
+ {% trans 'or type variable name:' %}
+ </label>
+ <input type="text" name="variableInput" id="variableInput">
+ <br>
+
+ <input type="checkbox" name="differentialValue" id="differentialValue" value="differential" checked="checked">
+ <label for="differentialValue">
+ {% trans 'Display as differential value' %}
+ </label>
+ <br>
+
+ <input type="checkbox" id="useDivisor" name="useDivisor" value="1">
+ <label for="useDivisor">{% trans 'Apply a divisor' %}</label>
+
+ <span class="divisorInput hide">
+ <input type="text" name="valueDivisor" size="4" value="1">
+ (<a href="#kibDivisor">{% trans 'KiB' %}</a>,
+ <a href="#mibDivisor">{% trans 'MiB' %}</a>)
+ </span>
+ <br>
+
+ <input type="checkbox" id="useUnit" name="useUnit" value="1">
+ <label for="useUnit">
+ {% trans 'Append unit to data values' %}
+ </label>
+ <span class="unitInput hide">
+ <input type="text" name="valueUnit" size="4" value="">
+ </span>
+
+ <p>
+ <a href="#submitAddSeries">
+ <strong>{% trans 'Add this series' %}</strong>
+ </a>
+ <span id="clearSeriesLink" class="hide">
+ | <a href="#submitClearSeries">{% trans 'Clear series' %}</a>
+ </span>
+ </p>
+
+ {% trans 'Series in chart:' %}
+ <br>
+ <span id="seriesPreview">
+ <em>{% trans 'None' %}</em>
+ </span>
+ </div>
+ </div>
+</div>
+
+<div id="logAnalyseDialog" title="{% trans 'Log statistics' %}" class="hide">
+ <p>
+ {% trans 'Selected time range:' %}
+ <input type="text" name="dateStart" class="datetimefield" value="">
+ -
+ <input type="text" name="dateEnd" class="datetimefield" value="">
+ </p>
+
+ <input type="checkbox" id="limitTypes" value="1" checked="checked">
+ <label for="limitTypes">
+ {% trans 'Only retrieve SELECT,INSERT,UPDATE and DELETE Statements' %}
+ </label>
+ <br>
+
+ <input type="checkbox" id="removeVariables" value="1" checked="checked">
+ <label for="removeVariables">
+ {% trans 'Remove variable data in INSERT statements for better grouping' %}
+ </label>
+
+ <p>
+ {% trans 'Choose from which log you want the statistics to be generated from.' %}
+ </p>
+ <p>
+ {% trans 'Results are grouped by query text.' %}
+ </p>
+</div>
+
+<div id="queryAnalyzerDialog" title="{% trans 'Query analyzer' %}" class="hide">
+ <textarea id="sqlquery"></textarea>
+ <br>
+ <div class="placeHolder"></div>
+</div>
+
+<table class="clearfloat tdblock" id="chartGrid"></table>
+<div id="logTable"><br></div>
+
+<script type="text/javascript">
+ var variableNames = [
+ {% for variable_name in javascript_variable_names %}
+ "{{ variable_name|e('js') }}",
+ {% endfor %}
+ ];
+</script>
+
+<form id="js_data" class="hide">
+ {% for name, value in form %}
+ <input type="hidden" name="{{ name }}" value="{{ value }}">
+ {% endfor %}
+</form>
+
+<div id="profiling_docu" class="hide">
+ {{ show_mysql_docu('general-thread-states') }}
+</div>
+
+<div id="explain_docu" class="hide">
+ {{ show_mysql_docu('explain-output') }}
+</div>
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/status/processes/index.twig b/srcs/phpmyadmin/templates/server/status/processes/index.twig
new file mode 100644
index 0000000..bb73156
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/processes/index.twig
@@ -0,0 +1,53 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'processes' %}
+{% block content %}
+
+<fieldset id="tableFilter">
+ <legend>{% trans 'Filters' %}</legend>
+ <form action="server_status_processes.php" method="post">
+ {{ get_hidden_inputs(url_params) }}
+ <input class="btn btn-secondary" type="submit" value="{% trans 'Refresh' %}">
+ <div class="formelement">
+ <input type="checkbox" name="showExecuting" id="showExecuting" class="autosubmit"{{ is_checked ? ' checked' }}>
+ <label for="showExecuting">
+ {% trans 'Show only active' %}
+ </label>
+ </div>
+ </form>
+</fieldset>
+
+{{ server_process_list|raw }}
+
+{{ 'Note: Enabling the auto refresh here might cause heavy traffic between the web server and the MySQL server.'|trans|notice }}
+
+<div class="tabLinks">
+ <label>
+ {% trans 'Refresh rate' %}:
+
+ <select id="id_refreshRate" class="refreshRate" name="refreshRate">
+ {% for rate in [2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200] %}
+ <option value="{{ rate }}"{{ rate == 5 ? ' selected' }}>
+ {% if rate < 60 %}
+ {% if rate == 1 %}
+ {{ '%d second'|trans|format(rate) }}
+ {% else %}
+ {{ '%d seconds'|trans|format(rate) }}
+ {% endif %}
+ {% else %}
+ {% if rate / 60 == 1 %}
+ {{ '%d minute'|trans|format(rate / 60) }}
+ {% else %}
+ {{ '%d minutes'|trans|format(rate / 60) }}
+ {% endif %}
+ {% endif %}
+ </option>
+ {% endfor %}
+ </select>
+ </label>
+ <a id="toggleRefresh" href="#">
+ {{ get_image('play') }}
+ {% trans 'Start auto refresh' %}
+ </a>
+</div>
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/status/processes/list.twig b/srcs/phpmyadmin/templates/server/status/processes/list.twig
new file mode 100644
index 0000000..83561f9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/processes/list.twig
@@ -0,0 +1,65 @@
+<div class="responsivetable">
+ <table id="tableprocesslist" class="data clearfloat noclick sortable">
+ <thead>
+ <tr>
+ <th>{% trans 'Processes' %}</th>
+ {% for column in columns %}
+ <th>
+ <a href="server_status_processes.php" data-post="{{ get_common(column.params) }}" class="sortlink">
+ {{ column.name }}
+ {% if column.is_sorted %}
+ <img class="icon ic_s_desc soimg" alt="
+ {%- trans 'Descending' %}" src="themes/dot.gif" style="display: {{ column.sort_order == 'DESC' ? 'none' : 'inline' }}">
+ <img class="icon ic_s_asc soimg hide" alt="
+ {%- trans 'Ascending' %}" src="themes/dot.gif" style="display: {{ column.sort_order == 'DESC' ? 'inline' : 'none' }}">
+ {% endif %}
+ </a>
+ {% if column.has_full_query %}
+ <a href="server_status_processes.php" data-post="{{ get_common(refresh_params, '') }}">
+ {% if column.is_full %}
+ {{ get_image(
+ 's_partialtext',
+ 'Truncate shown queries'|trans,
+ {'class': 'icon_fulltext'}
+ ) }}
+ {% else %}
+ {{ get_image(
+ 's_fulltext',
+ 'Show full queries'|trans,
+ {'class': 'icon_fulltext'}
+ ) }}
+ {% endif %}
+ </a>
+ {% endif %}
+ </th>
+ {% endfor %}
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for row in rows %}
+ <tr>
+ <td>
+ <a class="ajax kill_process" href="server_status_processes.php" data-post="{{ get_common({'kill': row.id}, '') }}">
+ {% trans 'Kill' %}
+ </a>
+ </td>
+ <td class="value">{{ row.id }}</td>
+ <td>{{ row.user }}</td>
+ <td>{{ row.host }}</td>
+ <td>
+ {% if row.db != '' %}
+ {{ row.db }}
+ {% else %}
+ <em>{% trans 'None' %}</em>
+ {% endif %}
+ </td>
+ <td>{{ row.command }}</td>
+ <td class="value">{{ row.time }}</td>
+ <td>{{ row.state }}</td>
+ <td>{{ row.progress }}</td>
+ <td>{{ row.info|raw }}</td>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
diff --git a/srcs/phpmyadmin/templates/server/status/queries/index.twig b/srcs/phpmyadmin/templates/server/status/queries/index.twig
new file mode 100644
index 0000000..be743b9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/queries/index.twig
@@ -0,0 +1,56 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'queries' %}
+{% block content %}
+
+{% if is_data_loaded %}
+ <h3 id="serverstatusqueries">
+ {% trans %}
+ Questions since startup:
+ {% notes %}
+ Questions is the name of a MySQL Status variable
+ {% endtrans %}
+ {{ format_number(stats.total, 0) }}
+ {{ show_mysql_docu('server-status-variables', false, null, null, 'statvar_Questions') }}
+ </h3>
+
+ <ul>
+ <li>ø {% trans 'per hour:' %} {{ format_number(stats.per_hour, 0) }}</li>
+ <li>ø {% trans 'per minute:' %} {{ format_number(stats.per_minute, 0) }}</li>
+ {% if stats.per_second >= 1 %}
+ <li>ø {% trans 'per second:' %} {{ format_number(stats.per_second, 0) }}</li>
+ {% endif %}
+ </ul>
+
+ <table id="serverstatusqueriesdetails" class="width100 data sortable noclick">
+ <colgroup>
+ <col class="namecol">
+ <col class="valuecol" span="3">
+ </colgroup>
+
+ <thead>
+ <tr>
+ <th>{% trans 'Statements' %}</th>
+ <th>{% trans %}#{% notes %}# = Amount of queries{% endtrans %}</th>
+ <th>ø {% trans 'per hour' %}</th>
+ <th>%</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for query in queries %}
+ <tr>
+ <th class="name">{{ query.name }}</th>
+ <td class="value">{{ format_number(query.value, 5, 0, true) }}</td>
+ <td class="value">{{ format_number(query.per_hour, 4, 1, true) }}</td>
+ <td class="value">{{ format_number(query.percentage, 0, 2) }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ <div id="serverstatusquerieschart" class="width100" data-chart="{{ chart|json_encode }}"></div>
+{% else %}
+ {{ 'Not enough privilege to view query statistics.'|trans|error }}
+{% endif %}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/status/status/index.twig b/srcs/phpmyadmin/templates/server/status/status/index.twig
new file mode 100644
index 0000000..53fd63f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/status/index.twig
@@ -0,0 +1,78 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'status' %}
+{% block content %}
+
+{% if is_data_loaded %}
+ <h3>{{ 'Network traffic since startup: %s'|trans|format(network_traffic) }}</h3>
+ <p>{{ 'This MySQL server has been running for %1$s. It started up on %2$s.'|trans|format(uptime, start_time) }}</p>
+
+ <table id="serverstatustraffic" class="width100 data noclick">
+ <thead>
+ <tr>
+ <th>
+ {% trans 'Traffic' %}
+ {{ show_hint('On a busy server, the byte counters may overrun, so those statistics as reported by the MySQL server may be incorrect.'|trans) }}
+ </th>
+ <th>#</th>
+ <th>&oslash; {% trans 'per hour' %}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for each_traffic in traffic %}
+ <tr>
+ <th class="name">{{ each_traffic.name }}</th>
+ <td class="value">{{ each_traffic.number }}</td>
+ <td class="value">{{ each_traffic.per_hour }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ <table id="serverstatusconnections" class="width100 data noclick">
+ <thead>
+ <tr>
+ <th>{% trans 'Connections' %}</th>
+ <th>#</th>
+ <th>&oslash; {% trans 'per hour' %}</th>
+ <th>%</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for connection in connections %}
+ <tr>
+ <th class="name">{{ connection.name }}</th>
+ <td class="value">{{ connection.number }}</td>
+ <td class="value">{{ connection.per_hour }}</td>
+ <td class="value">{{ connection.percentage }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ {% if is_master or is_slave %}
+ <p class="notice clearfloat">
+ {% if is_master and is_slave %}
+ {% trans 'This MySQL server works as <b>master</b> and <b>slave</b> in <b>replication</b> process.' %}
+ {% elseif is_master %}
+ {% trans 'This MySQL server works as <b>master</b> in <b>replication</b> process.' %}
+ {% elseif is_slave %}
+ {% trans 'This MySQL server works as <b>slave</b> in <b>replication</b> process.' %}
+ {% endif %}
+ </p>
+
+ <hr class="clearfloat">
+
+ <h3>
+ <a name="replication">{% trans 'Replication status' %}</a>
+ </h3>
+
+ {{ replication|raw }}
+ {% endif %}
+
+{% else %}
+ {{ 'Not enough privilege to view server status.'|trans|error }}
+{% endif %}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/status/variables/index.twig b/srcs/phpmyadmin/templates/server/status/variables/index.twig
new file mode 100644
index 0000000..a5f8724
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/status/variables/index.twig
@@ -0,0 +1,137 @@
+{% extends 'server/status/base.twig' %}
+{% set active = 'variables' %}
+{% block content %}
+
+{% if is_data_loaded %}
+ <fieldset id="tableFilter">
+ <legend>{% trans 'Filters' %}</legend>
+ <form action="server_status_variables.php" method="post">
+ {{ get_hidden_inputs() }}
+
+ <input class="btn btn-secondary" type="submit" value="{% trans 'Refresh' %}">
+
+ <div class="formelement">
+ <label for="filterText">{% trans 'Containing the word:' %}</label>
+ <input name="filterText" type="text" id="filterText" value="{{ filter_text }}">
+ </div>
+
+ <div class="formelement">
+ <input type="checkbox" name="filterAlert" id="filterAlert"{{ is_only_alerts ? ' checked' }}>
+ <label for="filterAlert">
+ {% trans 'Show only alert values' %}
+ </label>
+ </div>
+
+ <div class="formelement">
+ <select id="filterCategory" name="filterCategory">
+ <option value="">{% trans 'Filter by category…' %}</option>
+ {% for category in categories %}
+ <option value="{{ category.id }}"{{ category.is_selected ? ' selected' }}>{{ category.name }}</option>
+ {% endfor %}
+ </select>
+ </div>
+
+ <div class="formelement">
+ <input type="checkbox" name="dontFormat" id="dontFormat"{{ is_not_formatted ? ' checked' }}>
+ <label for="dontFormat">
+ {% trans 'Show unformatted values' %}
+ </label>
+ </div>
+ </form>
+ </fieldset>
+
+ <div id="linkSuggestions" class="defaultLinks hide">
+ <p class="notice">
+ {% trans 'Related links:' %}
+ {% for link in links %}
+ <span class="{{ link.name }}">
+ {% for link_name, link_url in link.links %}
+ {% if link_name == 'doc' %}
+ {{ show_mysql_docu(link_url) }}
+ {% else %}
+ <a href="{{ link_url.url }}" data-post="{{ link_url.params }}">{{ link_name }}</a>
+ {% endif %}
+ |
+ {% endfor %}
+ </span>
+ {% endfor %}
+ </p>
+ </div>
+
+ <div class="responsivetable">
+ <table class="data noclick" id="serverstatusvariables">
+ <colgroup>
+ <col class="namecol">
+ <col class="valuecol">
+ <col class="descrcol">
+ </colgroup>
+ <thead>
+ <tr>
+ <th>{% trans 'Variable' %}</th>
+ <th>{% trans 'Value' %}</th>
+ <th>{% trans 'Description' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for variable in variables %}
+ <tr{% if variable.class is not empty %} class="s_{{ variable.class }}"{% endif %}>
+ <th class="name">
+ {{ variable.name|replace({'_': ' '}) }}
+ {{ variable.doc|raw }}
+ </th>
+
+ <td class="value">
+ <span class="formatted">
+ {% if variable.has_alert %}
+ <span class="{{ variable.is_alert ? 'attention' : 'allfine' }}">
+ {% endif %}
+
+ {% if variable.name ends with '%' %}
+ {{ format_number(variable.value, 0, 2) }} %
+ {% elseif 'Uptime' in variable.name %}
+ {{ timespan_format(variable.value) }}
+ {% elseif variable.is_numeric and variable.value >= 1000 %}
+ <abbr title="{{ format_number(variable.value, 0) }}">
+ {{ format_number(variable.value, 3, 1) }}
+ </abbr>
+ {% elseif variable.is_numeric %}
+ {{ format_number(variable.value, 3, 1) }}
+ {% else %}
+ {{ variable.value }}
+ {% endif %}
+
+ {% if variable.has_alert %}
+ </span>
+ {% endif %}
+ </span>
+ <span class="original hide">
+ {% if variable.has_alert %}
+ <span class="{{ variable.is_alert ? 'attention' : 'allfine' }}">
+ {% endif %}
+ {{ variable.value }}
+ {% if variable.has_alert %}
+ </span>
+ {% endif %}
+ </span>
+ </td>
+
+ <td class="descr">
+ {{ variable.description }}
+ {% for doc in variable.description_doc %}
+ {% if doc.name == 'doc' %}
+ {{ show_mysql_docu(doc.url) }}
+ {% else %}
+ <a href="{{ doc.url.url }}" data-post="{{ doc.url.params }}">{{ doc.name }}</a>
+ {% endif %}
+ {% endfor %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+{% else %}
+ {{ 'Not enough privilege to view status variables.'|trans|error }}
+{% endif %}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/server/sub_page_header.twig b/srcs/phpmyadmin/templates/server/sub_page_header.twig
new file mode 100644
index 0000000..d1c521c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/sub_page_header.twig
@@ -0,0 +1,16 @@
+{# array contains Sub page icon and text #}
+{% set header = {
+ 'privileges': {
+ 'image': 'b_usrlist',
+ 'text': 'Privileges'|trans
+ }
+} %}
+<h2>
+ {% if is_image|default(true) %}
+ {{ get_image(header[type]['image']) }}
+ {% else %}
+ {{ get_icon(header[type]['image']) }}
+ {% endif %}
+ {{ header[type]['text'] }}
+ {{ link is defined ? show_mysql_docu(link) }}
+</h2>
diff --git a/srcs/phpmyadmin/templates/server/variables/index.twig b/srcs/phpmyadmin/templates/server/variables/index.twig
new file mode 100644
index 0000000..75020cb
--- /dev/null
+++ b/srcs/phpmyadmin/templates/server/variables/index.twig
@@ -0,0 +1,78 @@
+<h2>
+ {{ get_image('s_vars') }}
+ {% trans 'Server variables and settings' %}
+ {{ show_mysql_docu('server_system_variables') }}
+</h2>
+
+{% if variables is not empty %}
+ <a href="server_variables.php{{ get_common() }}" class="ajax saveLink hide">
+ {{ get_icon('b_save', 'Save'|trans) }}
+ </a>
+ <a href="#" class="cancelLink hide">
+ {{ get_icon('b_close', 'Cancel'|trans) }}
+ </a>
+ {{ get_image('b_help', 'Documentation'|trans, {
+ 'class': 'hide',
+ 'id': 'docImage'
+ }) }}
+
+ {% include 'filter.twig' with {
+ 'filter_value': filter_value
+ } only %}
+
+ <div class="responsivetable">
+ <table id="serverVariables" class="width100 data filteredData noclick">
+ <thead>
+ <tr class="var-header var-row">
+ <td class="var-action">{% trans 'Action' %}</td>
+ <td class="var-name">{% trans 'Variable' %}</td>
+ <td class="var-value">{% trans 'Value' %}</td>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for variable in variables %}
+ <tr class="var-row{{ variable.has_session_value ? ' diffSession' }}" data-filter-row="{{ variable.name|upper }}">
+ <td class="var-action">
+ {% if variable.is_editable %}
+ <a href="#" data-variable="{{ variable.name }}" class="editLink">{{ get_icon('b_edit', 'Edit'|trans) }}</a>
+ {% else %}
+ <span title="{% trans 'This is a read-only variable and can not be edited' %}" class="read_only_var">
+ {{ get_icon('bd_edit', 'Edit'|trans) }}
+ </span>
+ {% endif %}
+ </td>
+ <td class="var-name">
+ {% if variable.doc_link != null %}
+ <span title="{{ variable.name|replace({'_': ' '}) }}">
+ {{ variable.doc_link|raw }}
+ </span>
+ {% else %}
+ {{ variable.name|replace({'_': ' '}) }}
+ {% endif %}
+ </td>
+ <td class="var-value value{{ is_superuser ? ' editable' }}">
+ {% if variable.is_escaped %}
+ {{ variable.value|raw }}
+ {% else %}
+ {{ variable.value|e|replace({',': ',&#8203;'})|raw }}
+ {% endif %}
+ </td>
+ </tr>
+
+ {% if variable.has_session_value %}
+ <tr class="var-row diffSession" data-filter-row="{{ variable.name|upper }}">
+ <td class="var-action"></td>
+ <td class="var-name session">({% trans 'Session value' %})</td>
+ <td class="var-value value">{{ variable.session_value }}</td>
+ </tr>
+ {% endif %}
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+{% else %}
+ {{ 'Not enough privilege to view server variables and settings. %s'|trans|format(
+ link_to_var_documentation('show_compatibility_56', is_mariadb)
+ )|error }}
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/setup/base.twig b/srcs/phpmyadmin/templates/setup/base.twig
new file mode 100644
index 0000000..7fe7fb6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/base.twig
@@ -0,0 +1,48 @@
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta charset="utf-8">
+ <title>phpMyAdmin setup</title>
+ <link href="../favicon.ico" rel="icon" type="image/x-icon">
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon">
+ <link href="styles.css" rel="stylesheet" type="text/css">
+ <script type="text/javascript" src="../js/vendor/jquery/jquery.min.js"></script>
+ <script type="text/javascript" src="../js/vendor/jquery/jquery-ui.min.js"></script>
+ <script type="text/javascript" src="../js/setup/ajax.js"></script>
+ <script type="text/javascript" src="../js/config.js"></script>
+ <script type="text/javascript" src="../js/setup/scripts.js"></script>
+ <script type="text/javascript" src="../js/messages.php"></script>
+</head>
+<body>
+
+<h1>
+ <span class="blue">php</span><span class="orange">MyAdmin</span>
+ setup
+</h1>
+
+<div id="menu">
+ <ul>
+ <li>
+ <a href="index.php{{ get_common() }}"{{ formset is empty ? ' class="active"' }}>
+ {% trans 'Overview' %}
+ </a>
+ </li>
+ {% for page in pages %}
+ <li>
+ <a href="index.php{{ get_common({
+ 'page': 'form',
+ 'formset': page.formset
+ }) }}"{{ formset == page.formset ? ' class="active"' }}>
+ {{ page.name }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+</div>
+
+<div id="page">
+ {% block content %}{% endblock %}
+</div>
+
+</body>
+</html>
diff --git a/srcs/phpmyadmin/templates/setup/config/index.twig b/srcs/phpmyadmin/templates/setup/config/index.twig
new file mode 100644
index 0000000..9f42695
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/config/index.twig
@@ -0,0 +1,29 @@
+{% extends 'setup/base.twig' %}
+{% block content %}
+
+<h2>{% trans 'Configuration file' %}</h2>
+
+{{ form_top_html|raw }}
+
+<input type="hidden" name="eol" value="{{ eol }}">
+
+{{ fieldset_top_html|raw }}
+
+<tr>
+ <td>
+ <textarea cols="50" rows="20" name="textconfig" id="textconfig" spellcheck="false">
+ {{- config -}}
+ </textarea>
+ </td>
+</tr>
+
+<tr>
+ <td class="lastrow left">
+ <input class="green" type="submit" name="submit_download" value="{% trans 'Download' %}">
+ </td>
+</tr>
+
+{{ form_bottom_html|raw }}
+{{ fieldset_bottom_html|raw }}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/setup/error.twig b/srcs/phpmyadmin/templates/setup/error.twig
new file mode 100644
index 0000000..17f042b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/error.twig
@@ -0,0 +1,19 @@
+<div class="error">
+ <h4>{% trans 'Warning' %}</h4>
+ <p>{% trans 'Submitted form contains errors' %}</p>
+ <p>
+ <a href="{{ get_common(url_params|merge({'mode': 'revert'})) }}">
+ {% trans 'Try to revert erroneous fields to their default values' %}
+ </a>
+ </p>
+</div>
+
+{{ errors|raw }}
+
+<a class="btn" href="index.php{{ get_common() }}">
+ {% trans 'Ignore errors' %}
+</a>
+
+<a class="btn" href="{{ get_common(url_params|merge({'mode': 'edit'})) }}">
+ {% trans 'Show form' %}
+</a>
diff --git a/srcs/phpmyadmin/templates/setup/form/index.twig b/srcs/phpmyadmin/templates/setup/form/index.twig
new file mode 100644
index 0000000..c7970eb
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/form/index.twig
@@ -0,0 +1,8 @@
+{% extends 'setup/base.twig' %}
+{% block content %}
+
+<h2>{{ name }}</h2>
+
+{{ page|raw }}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/setup/home/index.twig b/srcs/phpmyadmin/templates/setup/home/index.twig
new file mode 100644
index 0000000..a289af7
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/home/index.twig
@@ -0,0 +1,121 @@
+{% extends 'setup/base.twig' %}
+{% block content %}
+
+<form id="select_lang" method="post">
+ {{ get_hidden_inputs() }}
+ <bdo lang="en" dir="ltr">
+ <label for="lang">
+ {% trans 'Language' %}
+ {{ 'Language'|trans != 'Language' ? ' - Language' }}
+ </label>
+ </bdo>
+ <br>
+ <select id="lang" name="lang" class="autosubmit" lang="en" dir="ltr">
+ {% for language in languages %}
+ <option value="{{ language.code }}"{{ language.is_active ? ' selected' }}>{{ language.name|raw }}</option>
+ {% endfor %}
+ </select>
+</form>
+
+<h2>{% trans 'Overview' %}</h2>
+
+<a href="#" id="show_hidden_messages" class="hide">
+ {% trans 'Show hidden messages' %} (#MSG_COUNT)
+</a>
+
+{% for message in messages %}
+ <div class="{{ message.type }}{{ message.is_hidden ? ' hiddenmessage' }}" id="{{ message.id }}">
+ <h4>{{ message.title }}</h4>
+ {{ message.message|raw }}
+ </div>
+{% endfor %}
+
+<fieldset class="simple">
+ <legend>{% trans 'Servers' %}</legend>
+
+ {{ servers_form_top_html|raw }}
+
+ <div class="form">
+ {% if server_count > 0 %}
+ <table cellspacing="0" class="datatable">
+ <tr>
+ <th>#</th>
+ <th>{% trans 'Name' %}</th>
+ <th>{% trans 'Authentication type' %}</th>
+ <th colspan="2">DSN</th>
+ </tr>
+
+ {% for server in servers %}
+ <tr>
+ <td>{{ server.id }}</td>
+ <td>{{ server.name }}</td>
+ <td>{{ server.auth_type }}</td>
+ <td>{{ server.dsn }}</td>
+ <td class="nowrap">
+ <small>
+ <a href="{{ get_common(server.params.edit) }}">
+ {% trans 'Edit' %}
+ </a>
+ |
+ <a class="delete-server" href="{{ get_common(server.params.remove) }}" data-post="
+ {{- get_common({ token: server.params.token }, '') }}">
+ {% trans 'Delete' %}
+ </a>
+ </small>
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% else %}
+ <table width="100%">
+ <tr>
+ <td>
+ <em>{% trans 'There are no configured servers' %}</em>
+ </td>
+ </tr>
+ </table>
+ {% endif %}
+
+ <table width="100%">
+ <tr>
+ <td class="lastrow left">
+ <input type="submit" name="submit" value="{% trans 'New server' %}">
+ </td>
+ </tr>
+ </table>
+ </div>
+
+ {{ form_bottom_html|raw }}
+
+</fieldset>
+
+<fieldset class="simple">
+ <legend>{% trans 'Configuration file' %}</legend>
+
+ {{ config_form_top_html|raw }}
+
+ <table width="100%" cellspacing="0">
+ {{ default_language_input|raw }}
+ {{ server_default_input|raw }}
+ {{ eol_input|raw }}
+
+ <tr>
+ <td colspan="2" class="lastrow left">
+ <input type="submit" name="submit_display" value="{% trans 'Display' %}">
+ <input type="submit" name="submit_download" value="{% trans 'Download' %}">
+ <input class="red" type="submit" name="submit_clear" value="{% trans 'Clear' %}">
+ </td>
+ </tr>
+ </table>
+
+ {{ form_bottom_html|raw }}
+
+</fieldset>
+
+<div id="footer">
+ <a href="../url.php?url=https://www.phpmyadmin.net/">{% trans 'phpMyAdmin homepage' %}</a>
+ <a href="../url.php?url=https://www.phpmyadmin.net/donate/">{% trans 'Donate' %}</a>
+ <a href="{{ get_common({'version_check': '1'}) }}">{% trans 'Check for latest version' %}</a>
+</div>
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/setup/servers/index.twig b/srcs/phpmyadmin/templates/setup/servers/index.twig
new file mode 100644
index 0000000..42b0745
--- /dev/null
+++ b/srcs/phpmyadmin/templates/setup/servers/index.twig
@@ -0,0 +1,16 @@
+{% extends 'setup/base.twig' %}
+{% block content %}
+
+{% if mode == 'edit' and has_server %}
+ <h2>
+ {% trans 'Edit server' %}
+ {{ server_id }}
+ <small>({{ server_dsn }})</small>
+ </h2>
+{% elseif mode != 'revert' or not has_server %}
+ <h2>{% trans 'Add a new server' %}</h2>
+{% endif %}
+
+{{ page|raw }}
+
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/sql/bookmark.twig b/srcs/phpmyadmin/templates/sql/bookmark.twig
new file mode 100644
index 0000000..71abc3d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/bookmark.twig
@@ -0,0 +1,31 @@
+<form action="sql.php" method="post" class="bookmarkQueryForm print_ignore"
+ onsubmit="return ! Functions.emptyCheckTheField(this, 'bkm_fields[bkm_label]');">
+ {{ get_hidden_inputs() }}
+ <input type="hidden" name="db" value="{{ db }}">
+ <input type="hidden" name="goto" value="{{ goto }}">
+ <input type="hidden" name="bkm_fields[bkm_database]" value="{{ db }}">
+ <input type="hidden" name="bkm_fields[bkm_user]" value="{{ user }}">
+ <input type="hidden" name="bkm_fields[bkm_sql_query]" value="{{ sql_query }}">
+ <fieldset>
+ <legend>
+ {{ get_icon('b_bookmark', 'Bookmark this SQL query'|trans, true) }}
+ </legend>
+ <div class="formelement">
+ <label>
+ {% trans 'Label:' %}
+ <input type="text" name="bkm_fields[bkm_label]" value="">
+ </label>
+ </div>
+ <div class="formelement">
+ <label>
+ <input type="checkbox" name="bkm_all_users" value="true">
+ {% trans 'Let every user access this bookmark' %}
+ </label>
+ </div>
+ <div class="clearfloat"></div>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input type="hidden" name="store_bkm" value="1">
+ <input class="btn btn-secondary" type="submit" value="{% trans 'Bookmark this SQL query' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/sql/detailed_table.twig b/srcs/phpmyadmin/templates/sql/detailed_table.twig
new file mode 100644
index 0000000..4d8fe9c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/detailed_table.twig
@@ -0,0 +1,8 @@
+<tr>
+ <td>{{ index }}</td>
+ <td>{{ status|title }}</td>
+ <td class="right">
+ {{ format_number(duration, 3, 1) }}s
+ <span class="rawvalue hide">{{ duration }}</span>
+ </td>
+</tr>
diff --git a/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig b/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig
new file mode 100644
index 0000000..f8be9a8
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig
@@ -0,0 +1,6 @@
+<select>
+ <option value="">&nbsp;</option>
+ {% for value in values %}
+ <option value="{{ value }}"{{ value in selected_values ? " selected" }}>{{ value }}</option>
+ {% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/sql/profiling_chart.twig b/srcs/phpmyadmin/templates/sql/profiling_chart.twig
new file mode 100644
index 0000000..0f80954
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/profiling_chart.twig
@@ -0,0 +1,97 @@
+<fieldset>
+ <legend>{% trans 'Profiling' %}</legend>
+ <div class="floatleft">
+ <h3>{% trans 'Detailed profile' %}</h3>
+ <table id="profiletable">
+ <thead>
+ <tr>
+ <th>
+ {% trans 'Order' %}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans 'State' %}
+ {{ show_mysql_docu('general-thread-states') }}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans 'Time' %}
+ <div class="sorticon"></div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{ detailed_table|raw }}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="floatleft">
+ <h3>{% trans 'Summary by state' %}</h3>
+ <table id="profilesummarytable">
+ <thead>
+ <tr>
+ <th>
+ {% trans 'State' %}
+ {{ show_mysql_docu('general-thread-states') }}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans 'Total Time' %}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans '% Time' %}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans 'Calls' %}
+ <div class="sorticon"></div>
+ </th>
+ <th>
+ {% trans 'ø Time' %}
+ <div class="sorticon"></div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for name, stats in states %}
+ <tr>
+ <td>{{ name }}</td>
+ <td align="right">
+ {{ format_number(stats['total_time'], 3, 1) }}s
+ <span class="rawvalue hide">{{ stats['total_time'] }}</span>
+ </td>
+ <td align="right">
+ {{ format_number(100 * (stats['total_time'] / total_time), 0, 2) }}%
+ </td>
+ <td align="right">{{ stats['calls'] }}</td>
+ <td align="right">
+ {{ format_number(stats['total_time'] / stats['calls'], 3, 1) }}s
+ <span class="rawvalue hide">
+ {{ (stats['total_time'] / stats['calls'])|number_format(8, '.', '') }}
+ </span>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ <script type="text/javascript">
+ url_query = '{{ url_query }}';
+ </script>
+ </div>
+ <div class='clearfloat'></div>
+
+ <div id="profilingChartData" class="hide">
+ {{ chart_json|json_encode() }}
+ </div>
+ <div id="profilingchart" class="hide"></div>
+
+ <script type="text/javascript">
+ AJAX.registerOnload('sql.js', function () {
+ Sql.makeProfilingChart();
+ Sql.initProfilingTables();
+ });
+ </script>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig b/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig
new file mode 100644
index 0000000..6a2aaff
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig
@@ -0,0 +1,4 @@
+<span class="curr_value">{{ current_value }}</span>
+<a href="browse_foreigners.php" data-post="{{ get_common(params, '') }}">
+ {% trans 'Browse foreign values' %}
+</a>
diff --git a/srcs/phpmyadmin/templates/sql/set_column.twig b/srcs/phpmyadmin/templates/sql/set_column.twig
new file mode 100644
index 0000000..989812e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/set_column.twig
@@ -0,0 +1,5 @@
+<select size="{{ size }}" multiple>
+ {% for value in values %}
+ <option value="{{ value }}"{{ value in selected_values ? " selected" }}>{{ value }}</option>
+ {% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/sql/sql_query_results.twig b/srcs/phpmyadmin/templates/sql/sql_query_results.twig
new file mode 100644
index 0000000..d9f2c3b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/sql/sql_query_results.twig
@@ -0,0 +1,10 @@
+{{ table_maintenance|raw }}
+<div class="sqlqueryresults ajax">
+ {{ previous_update_query|raw }}
+ {{ profiling_chart|raw }}
+ {{ missing_unique_column_message|raw }}
+ {{ bookmark_created_message|raw }}
+ {{ table|raw }}
+ {{ indexes_problems|raw }}
+ {{ bookmark_support|raw }}
+</div>
diff --git a/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig b/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig
new file mode 100644
index 0000000..78d16f6
--- /dev/null
+++ b/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig
@@ -0,0 +1,20 @@
+<fieldset>
+ <div>
+ <label for="pos">{% trans "Start row:" %}</label>
+ <input type="number" name="pos" min="0" required="required"
+ {% if unlim_num_rows > 0 -%}
+ max="{{ unlim_num_rows - 1 }}"
+ {%- endif %}
+ value="{{ pos }}">
+
+ <label for="session_max_rows">{% trans "Number of rows:" %}</label>
+ <input type="number" name="session_max_rows" min="1"
+ value="{{ rows }}" required="required">
+ <input class="btn btn-primary" type="submit" name="submit" class="Go"
+ value="{% trans "Go" %}">
+ <input type="hidden" name="sql_query"
+ value="{{ sql_query }}">
+ <input type="hidden" name="unlim_num_rows"
+ value="{{ unlim_num_rows }}">
+ </div>
+</fieldset>
diff --git a/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig b/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig
new file mode 100644
index 0000000..f2ec2ba
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig
@@ -0,0 +1,12 @@
+<td{{ nowrap ? ' class="nowrap"' }}>
+ {{ is_selected ? '<strong>' }}
+ <a class="foreign_value" data-key="{{ keyname }}" href="#" title="
+ {%- trans 'Use this value' %}{{ title is not empty ? ': ' ~ title }}">
+ {% if nowrap %}
+ {{ keyname }}
+ {% else %}
+ {{ description }}
+ {% endif %}
+ </a>
+ {{ is_selected ? '</strong>' }}
+</td>
diff --git a/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig b/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig
new file mode 100644
index 0000000..4de9b81
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig
@@ -0,0 +1,5 @@
+{% if foreign_data.disp_row is iterable and
+ (show_all and foreign_data.the_total > max_rows) %}
+ <input class="btn btn-secondary" type="submit" id="foreign_showAll" name="foreign_showAll" value="
+ {%- trans 'Show all' %}">
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig b/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig
new file mode 100644
index 0000000..4201599
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig
@@ -0,0 +1,159 @@
+<script type="text/javascript">
+ url_query = '{{ url_query }}';
+</script>
+{# Display Chart options #}
+<div id="div_view_options">
+ <form method="post" id="tblchartform" action="tbl_chart.php" class="ajax">
+ {{ get_hidden_inputs(url_params) }}
+ <fieldset>
+ <legend>
+ {% trans 'Display chart' %}
+ </legend>
+ <div class="chartOption">
+ <div class="formelement">
+ <input type="radio" name="chartType" value="bar" id="radio_bar">
+ <label for ="radio_bar">{% trans %}Bar{% context %}Chart type{% endtrans %}</label>
+ </div>
+ <div class="formelement">
+ <input type="radio" name="chartType" value="column" id="radio_column">
+ <label for ="radio_column">{% trans %}Column{% context %}Chart type{% endtrans %}</label>
+ </div>
+ <div class="formelement">
+ <input type="radio" name="chartType" value="line" id="radio_line" checked="checked">
+ <label for ="radio_line">{% trans %}Line{% context %}Chart type{% endtrans %}</label>
+ </div>
+ <div class="formelement">
+ <input type="radio" name="chartType" value="spline" id="radio_spline">
+ <label for ="radio_spline">{% trans %}Spline{% context %}Chart type{% endtrans %}</label>
+ </div>
+ <div class="formelement">
+ <input type="radio" name="chartType" value="area" id="radio_area">
+ <label for ="radio_area">{% trans %}Area{% context %}Chart type{% endtrans %}</label>
+ </div>
+ <span class="span_pie hide">
+ <input type="radio" name="chartType" value="pie" id="radio_pie">
+ <label for ="radio_pie">{% trans %}Pie{% context %}Chart type{% endtrans %}</label>
+ </span>
+ <span class="span_timeline hide">
+ <input type="radio" name="chartType" value="timeline" id="radio_timeline">
+ <label for ="radio_timeline">{% trans %}Timeline{% context %}Chart type{% endtrans %}</label>
+ </span>
+ <span class="span_scatter hide">
+ <input type="radio" name="chartType" value="scatter" id="radio_scatter">
+ <label for ="radio_scatter">{% trans %}Scatter{% context %}Chart type{% endtrans %}</label>
+ </span>
+ <br><br>
+ <span class="barStacked hide">
+ <input type="checkbox" name="barStacked" value="1" id="checkbox_barStacked">
+ <label for ="checkbox_barStacked">{% trans 'Stacked' %}</label>
+ </span>
+ <br><br>
+ <label for ="chartTitle">{% trans 'Chart title:' %}</label>
+ <input type="text" name="chartTitle" id="chartTitle">
+ </div>
+ {% set xaxis = null %}
+ <div class="chartOption">
+ <label for="select_chartXAxis">{% trans 'X-Axis:' %}</label>
+ <select name="chartXAxis" id="select_chartXAxis">
+ {% for idx, key in keys %}
+ {% if xaxis is same as(null) %}
+ {% set xaxis = idx %}
+ {% endif %}
+ {% if xaxis is same as(idx) %}
+ <option value="{{ idx }}" selected="selected">{{ key }}</option>
+ {% else %}
+ <option value="{{ idx }}">{{ key }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ <br>
+ <label for="select_chartSeries">
+ {% trans 'Series:' %}
+ </label>
+ <select name="chartSeries" id="select_chartSeries" multiple="multiple">
+ {% for idx, key in keys %}
+ {% if fields_meta[idx].type in numeric_types %}
+ {% if idx == xaxis and numeric_column_count > 1 %}
+ <option value="{{ idx }}">{{ key }}</option>
+ {% else %}
+ <option value="{{ idx }}" selected="selected">{{ key }}</option>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ </select>
+ <input type="hidden" name="dateTimeCols" value="
+ {% set date_time_types = ['date', 'datetime', 'timestamp'] %}
+ {% for idx, key in keys %}
+ {% if fields_meta[idx].type in date_time_types %}
+ {{ idx ~ ' ' }}
+ {% endif %}
+ {% endfor %}">
+ <input type="hidden" name="numericCols" value="
+ {% for idx, key in keys %}
+ {% if fields_meta[idx].type in numeric_types %}
+ {{ idx ~ ' ' }}
+ {% endif %}
+ {% endfor %}">
+ </div>
+ <div class="chartOption">
+ <label for="xaxis_panel">
+ {% trans 'X-Axis label:' %}
+ </label>
+ <input style="margin-top:0;" type="text" name="xaxis_label" id="xaxis_label" value="{{ xaxis == -1 ? 'X Values'|trans : keys[xaxis] }}">
+ <br>
+ <label for="yaxis_label">
+ {% trans 'Y-Axis label:' %}
+ </label>
+ <input type="text" name="yaxis_label" id="yaxis_label" value="{% trans 'Y Values' %}">
+ <br>
+ </div>
+ <div class="clearfloat"></div>
+ <div>
+ <input type="checkbox" id="chkAlternative" name="chkAlternative" value="alternativeFormat">
+ <label for="chkAlternative">{% trans 'Series names are in a column' %}</label>
+ <br>
+ <label for="select_seriesColumn">
+ {% trans 'Series column:' %}
+ </label>
+ <select name="chartSeriesColumn" id="select_seriesColumn" disabled>
+ {% for idx, key in keys %}
+ <option value="{{ idx }}"
+ {% if idx == 1 %}
+ selected="selected"
+ {% endif %}>
+ {{ key }}
+ </option>
+ {% set series_column = idx %}
+ {% endfor %}
+ </select>
+ <label for="select_valueColumn">
+ {% trans 'Value Column:' %}
+ </label>
+ <select name="chartValueColumn" id="select_valueColumn" disabled>
+ {% set selected = false %}
+ {% for idx, key in keys %}
+ {% if fields_meta[idx].type in numeric_types %}
+ {% if not selected and idx != xaxis and idx != series_column %}
+ <option value="{{ idx }}" selected="selected">{{ key }}</option>
+ {% set selected = true %}
+ {% else %}
+ <option value="{{ idx }}">{{ key }}</option>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
+ {{ get_start_and_number_of_rows_panel(sql_query) }}
+ <div class="clearfloat"></div>
+ <div id="resizer" style="width:600px; height:400px;">
+ <div style="position: absolute; right: 10px; top: 10px; cursor: pointer; z-index: 1000;">
+ <a class="disableAjax" id="saveChart" href="#" download="chart.png">
+ {{ get_image('b_saveimage', 'Save chart as image'|trans) }}
+ </a>
+ </div>
+ <div id="querychart" dir="ltr">
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
diff --git a/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig b/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig
new file mode 100644
index 0000000..9e82e2e
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig
@@ -0,0 +1,80 @@
+<div id="div_view_options">
+ <fieldset>
+ <legend>{% trans 'Display GIS Visualization' %}</legend>
+ <div id="gis_div" style="position:relative;">
+ <form method="post" action="tbl_gis_visualization.php">
+ {{ get_hidden_inputs(url_params) }}
+ <label for="labelColumn">
+ {% trans "Label column" %}
+ </label>
+ <select name="visualizationSettings[labelColumn]" id="labelColumn" class="autosubmit">
+ <option value="">{% trans "-- None --" %}</option>
+ {% for value in label_candidates %}
+ <option value="{{ value }}"{{ value == visualization_settings['labelColumn'] ? ' selected="selected"' }}>
+ {{ value }}
+ </option>
+ {% endfor %}
+ </select>
+ <label for="spatialColumn">
+ {% trans "Spatial column" %}
+ </label>
+ <select name="visualizationSettings[spatialColumn]" id="spatialColumn" class="autosubmit">
+ {% for value in spatial_candidates %}
+ <option value="{{ value }}"{{ value == visualization_settings['spatialColumn'] ? ' selected="selected"' }}>
+ {{ value }}
+ </option>
+ {% endfor %}
+ </select>
+ <input type="hidden" name="displayVisualization" value="redraw">
+ <tr>
+ <td class="choice" colspan="2">
+ <input type="checkbox"
+ name="visualizationSettings[choice]"
+ id="choice" value="useBaseLayer"
+ {% if visualization_settings['choice'] is defined %}
+ checked="checked"
+ {% endif %}>
+ <label for="choice" id="labelChoice">
+ {% trans "Use OpenStreetMaps as Base Layer" %}
+ </label>
+ </td>
+ </tr>
+ {{ get_start_and_number_of_rows_panel(sql_query) }}
+ </form>
+
+ <div class="pma_quick_warp" style="width: 50px; position: absolute; right: 0; top: 0; cursor: pointer;">
+ <div class="drop_list">
+ <span class="drop_button" style="padding: 0; border: 0;">
+ {{ get_image('b_saveimage', 'Save'|trans) }}
+ </span>
+ <ul>
+ <li class="warp_link">
+ <a href="{{ download_url|raw }}&fileFormat=png" class="disableAjax">PNG</a>
+ </li>
+ <li class="warp_link">
+ <a href="{{ download_url|raw }}&fileFormat=pdf" class="disableAjax">PDF</a>
+ </li>
+ <li class="warp_link">
+ <a href="{{ download_url|raw }}&fileFormat=svg" class="disableAjax">SVG</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div class="clearfloat"></div>
+
+ <div id="placeholder"
+ style="width:{{ visualization_settings['width'] }}px;height:{{ visualization_settings['height'] }}px;">
+ {{ visualization|raw }}
+ </div>
+ <div id="openlayersmap"></div>
+ <input type="hidden" id="pmaThemeImage" value="{{ pma_theme_image }}">
+ <script language="javascript" type="text/javascript">
+ function drawOpenLayers()
+ {
+ {{ draw_ol|raw }}
+ }
+ </script>
+ </fieldset>
+</div>
diff --git a/srcs/phpmyadmin/templates/table/index_form.twig b/srcs/phpmyadmin/templates/table/index_form.twig
new file mode 100644
index 0000000..6364599
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/index_form.twig
@@ -0,0 +1,223 @@
+<form action="tbl_indexes.php"
+ method="post"
+ name="index_frm"
+ id="index_frm"
+ class="ajax">
+
+ {{ get_hidden_inputs(form_params) }}
+
+ <fieldset id="index_edit_fields">
+ <div class="index_info">
+ <div>
+ <div class="label">
+ <strong>
+ <label for="input_index_name">
+ {% trans 'Index name:' %}
+ {{ show_hint('"PRIMARY" <b>must</b> be the name of and <b>only of</b> a primary key!'|trans) }}
+ </label>
+ </strong>
+ </div>
+
+ <input type="text"
+ name="index[Key_name]"
+ id="input_index_name"
+ size="25"
+ maxlength="64"
+ value="{{ index.getName() }}"
+ onfocus="this.select()">
+ </div>
+
+ <div>
+ <div class="label">
+ <strong>
+ <label for="select_index_choice">
+ {% trans 'Index choice:' %}
+ {{ show_mysql_docu('ALTER_TABLE') }}
+ </label>
+ </strong>
+ </div>
+ {{ index.generateIndexChoiceSelector(create_edit_table)|raw }}
+ </div>
+
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': 'indexoptions',
+ 'message': 'Advanced Options'|trans,
+ 'initial_sliders_state': default_sliders_state
+ } only %}
+
+ <div>
+ <div class="label">
+ <strong>
+ <label for="input_key_block_size">
+ {% trans 'Key block size:' %}
+ </label>
+ </strong>
+ </div>
+
+ <input type="text"
+ name="index[Key_block_size]"
+ id="input_key_block_size"
+ size="30"
+ value="{{ index.getKeyBlockSize() }}">
+ </div>
+
+ <div>
+
+ <div class="label">
+ <strong>
+ <label for="select_index_type">
+ {% trans 'Index type:' %}
+ {{ show_mysql_docu('ALTER_TABLE') }}
+ </label>
+ </strong>
+ </div>
+ {{ index.generateIndexTypeSelector()|raw }}
+ </div>
+
+ <div>
+ <div class="label">
+ <strong>
+ <label for="input_parser">
+ {% trans 'Parser:' %}
+ </label>
+ </strong>
+ </div>
+
+ <input type="text"
+ name="index[Parser]"
+ id="input_parse"
+ size="30"
+ value="{{ index.getParser() }}">
+ </div>
+
+ <div>
+ <div class="label">
+ <strong>
+ <label for="input_index_comment">
+ {% trans 'Comment:' %}
+ </label>
+ </strong>
+ </div>
+
+ <input type="text"
+ name="index[Index_comment]"
+ id="input_index_comment"
+ size="30"
+ maxlength="1024"
+ value="{{ index.getComment() }}">
+ </div>
+ </div>
+ <!-- end of indexoptions div -->
+
+ <div class="clearfloat"></div>
+
+ <table id="index_columns">
+ <thead>
+ <tr>
+ <th></th>
+ <th>
+ {% trans 'Column' %}
+ </th>
+ <th>
+ {% trans 'Size' %}
+ </th>
+ </tr>
+ </thead>
+ {% set spatial_types = [
+ 'geometry',
+ 'point',
+ 'linestring',
+ 'polygon',
+ 'multipoint',
+ 'multilinestring',
+ 'multipolygon',
+ 'geomtrycollection'
+ ] %}
+ <tbody>
+ {% for column in index.getColumns() %}
+ <tr class="noclick">
+ <td>
+ <span class="drag_icon" title="{% trans 'Drag to reorder' %}"></span>
+ </td>
+ <td>
+ <select name="index[columns][names][]">
+ <option value="">
+ -- {% trans 'Ignore' %} --
+ </option>
+ {% for field_name, field_type in fields %}
+ {% if (index.getChoice() != 'FULLTEXT'
+ or field_type matches '/(char|text)/i')
+ and (index.getChoice() != 'SPATIAL'
+ or field_type in spatial_types) %}
+
+ <option value="{{ field_name }}"
+ {%- if field_name == column.getName() %}
+ selected="selected"
+ {%- endif %}>
+ {{ field_name }} [{{ field_type }}]
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </td>
+ <td>
+ <input type="text"
+ size="5"
+ onfocus="this.select()"
+ name="index[columns][sub_parts][]"
+ value="{{ index.getChoice() != 'SPATIAL' ?
+ column.getSubPart() }}">
+ </td>
+ </tr>
+ {% endfor %}
+ {% if add_fields > 0 %}
+ {% for i in range(1, add_fields) %}
+ <tr class="noclick">
+ <td>
+ <span class="drag_icon" title="{% trans 'Drag to reorder' %}"></span>
+ </td>
+ <td>
+ <select name="index[columns][names][]">
+ <option value="">-- {% trans 'Ignore' %} --</option>
+ {% set j = 0 %}
+ {% for field_name, field_type in fields %}
+ {% if create_edit_table %}
+ {% set col_index = field_type[1] %}
+ {% set field_type = field_type[0] %}
+ {% endif %}
+ {% set j = j + 1 %}
+ <option value="{{ col_index is defined ?
+ col_index : field_name }}"
+ {{- j == i ? ' selected="selected"' }}>
+ {{ field_name }} [{{ field_type }}]
+ </option>
+ {% endfor %}
+ </select>
+ </td>
+ <td>
+ <input type="text"
+ size="5"
+ onfocus="this.select()"
+ name="index[columns][sub_parts][]"
+ value="">
+ </td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
+ <div class="add_more">
+
+ <div class="slider"></div>
+ <div class="add_fields hide">
+ <input class="btn btn-secondary" type="submit"
+ id="add_fields"
+ value="{{ 'Add %s column(s) to index'|trans|format(1) }}">
+ </div>
+ </div>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <button class="btn btn-secondary" type="submit" id="preview_index_frm">{% trans 'Preview SQL' %}</button>
+ <input class="btn btn-primary" type="submit" id="save_index_frm" value="{% trans 'Go' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig b/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig
new file mode 100644
index 0000000..86a8215
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig
@@ -0,0 +1,19 @@
+<form id="continueForm" method="post" action="tbl_replace.php" name="continueForm">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="goto" value="{{ goto }}">
+ <input type="hidden" name="err_url" value="{{ err_url }}">
+ <input type="hidden" name="sql_query" value="{{ sql_query }}">
+
+ {% if has_where_clause %}
+ {% for key_id, where_clause in where_clause_array %}
+ <input type="hidden" name="where_clause[{{ key_id }}]" value="
+ {{- where_clause|trim }}">
+ {% endfor %}
+ {% endif %}
+
+ {% set insert_rows %}
+ <input type="number" name="insert_rows" id="insert_rows" value="
+ {{- insert_rows_default }}" min="1">
+ {% endset %}
+ {{ 'Continue insertion with %s rows'|trans|format(insert_rows)|raw }}
+</form>
diff --git a/srcs/phpmyadmin/templates/table/operations/view.twig b/srcs/phpmyadmin/templates/table/operations/view.twig
new file mode 100644
index 0000000..e590532
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/operations/view.twig
@@ -0,0 +1,31 @@
+<!-- VIEW operations -->
+<div>
+ <form method="post" action="view_operations.php">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="reload" value="1">
+ <fieldset>
+ <legend>{% trans 'Operations' %}</legend>
+ <table>
+ <!-- Change view name -->
+ <tr>
+ <td>{% trans 'Rename view to' %}</td>
+ <td><input type="text" name="new_name" onfocus="this.select()"
+ value="{{ table }}"
+ required>
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input type="hidden" name="submitoptions" value="1">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </fieldset>
+ </form>
+</div>
+
+<div>
+ <fieldset class="caution">
+ <legend>{% trans 'Delete data or table' %}</legend>
+ <ul>{{ delete_data_or_table_link | raw }}</ul>
+ </fieldset>
+</div>
diff --git a/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig b/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig
new file mode 100644
index 0000000..2aae85a
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig
@@ -0,0 +1,22 @@
+{% if cfg_relation['relwork'] or is_foreign_key_supported %}
+ <ul id="topmenu2">
+ {{ get_html_tab({
+ 'icon': 'b_props',
+ 'link': 'tbl_structure.php',
+ 'text': 'Table structure'|trans,
+ 'id': 'table_strucuture_id'
+ }, url_params) }}
+ {{ get_html_tab({
+ 'icon': 'b_relations',
+ 'link': 'tbl_relation.php',
+ 'text': 'Relation view'|trans,
+ 'id': 'table_relation_id'
+ }, url_params) }}
+ </ul>
+ <div class="clearfloat"></div>
+{% endif %}
+
+<div id="structure_content">
+ {% block content %}
+ {% endblock %}
+</div>
diff --git a/srcs/phpmyadmin/templates/table/relation/common_form.twig b/srcs/phpmyadmin/templates/table/relation/common_form.twig
new file mode 100644
index 0000000..e85c6ce
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/relation/common_form.twig
@@ -0,0 +1,223 @@
+{% extends 'table/page_with_secondary_tabs.twig' %}
+
+{% block content %}
+<form method="post" action="tbl_relation.php">
+ {{ get_hidden_inputs(db, table) }}
+ {# InnoDB #}
+ {% if is_foreign_key_supported(tbl_storage_engine) %}
+ <fieldset>
+ <legend>{% trans 'Foreign key constraints' %}</legend>
+ <div class="responsivetable jsresponsive">
+ <table id="foreign_keys" class="relationalTable">
+ <thead><tr>
+ <th>{% trans 'Actions' %}</th>
+ <th>{% trans 'Constraint properties' %}</th>
+ {% if tbl_storage_engine|upper == 'INNODB' %}
+ <th>
+ {% trans 'Column' %}
+ {{ show_hint('Creating a foreign key over a non-indexed column would automatically create an index on it. Alternatively, you can define an index below, before creating the foreign key.'|trans) }}
+ </th>
+ {% else %}
+ <th>
+ {% trans 'Column' %}
+ {{ show_hint('Only columns with index will be displayed. You can define an index below.'|trans) }}
+ </th>
+ {% endif %}
+ <th colspan="3">
+ {% trans 'Foreign key constraint' %}
+ ({{ tbl_storage_engine }})
+ </th>
+ </tr>
+ <tr>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th>{% trans 'Database' %}</th>
+ <th>{% trans 'Table' %}</th>
+ <th>{% trans 'Column' %}</th>
+ </tr></thead>
+ {% set i = 0 %}
+ {% if existrel_foreign is not empty %}
+ {% for key, one_key in existrel_foreign %}
+ {# Foreign database dropdown #}
+ {% set foreign_db = one_key['ref_db_name'] is defined
+ and one_key['ref_db_name'] is not null
+ ? one_key['ref_db_name'] : db %}
+ {% set foreign_table = false %}
+ {% if foreign_db %}
+ {% set foreign_table = one_key['ref_table_name'] is defined
+ and one_key['ref_table_name'] is not null
+ ? one_key['ref_table_name'] : false %}
+ {% endif %}
+ {% set unique_columns = [] %}
+ {% if foreign_db and foreign_table %}
+ {% set table_obj = table_get(foreign_table, foreign_db) %}
+ {% set unique_columns = table_obj.getUniqueColumns(false, false) %}
+ {% endif %}
+ {% include 'table/relation/foreign_key_row.twig' with {
+ 'i': i,
+ 'one_key': one_key,
+ 'column_array': column_array,
+ 'options_array': options_array,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'db': db,
+ 'table': table,
+ 'url_params': url_params,
+ 'databases': databases,
+ 'foreign_db': foreign_db,
+ 'foreign_table': foreign_table,
+ 'unique_columns': unique_columns
+ } only %}
+ {% set i = i + 1 %}
+ {% endfor %}
+ {% endif %}
+ {% include 'table/relation/foreign_key_row.twig' with {
+ 'i': i,
+ 'one_key': [],
+ 'column_array': column_array,
+ 'options_array': options_array,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'db': db,
+ 'table': table,
+ 'url_params': url_params,
+ 'databases': databases,
+ 'foreign_db': foreign_db,
+ 'foreign_table': foreign_table,
+ 'unique_columns': unique_columns
+ } only %}
+ {% set i = i + 1 %}
+ <tr>
+ <th colspan="6">
+ <a class="formelement clearfloat add_foreign_key" href="">
+ {% trans '+ Add constraint' %}
+ </a>
+ </th>
+ </tr>
+ </table>
+ </div>
+ </fieldset>
+ {% endif %}
+
+ {% if cfg_relation['relwork'] %}
+ {% if is_foreign_key_supported(tbl_storage_engine) %}
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': 'ir_div',
+ 'message': 'Internal relationships'|trans,
+ 'initial_sliders_state': default_sliders_state
+ } only %}
+ {% endif %}
+
+ <fieldset>
+ <legend>
+ {% trans 'Internal relationships' %}
+ {{ show_docu('config', 'cfg_Servers_relation') }}
+ </legend>
+ <table id="internal_relations" class="relationalTable">
+ <tr>
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Internal relation' %}
+ {% if is_foreign_key_supported(tbl_storage_engine) %}
+ {{ show_hint('An internal relation is not necessary when a corresponding FOREIGN KEY relation exists.'|trans) }}
+ {% endif %}
+ </th>
+ {% set saved_row_cnt = save_row|length - 1 %}
+ {% for i in 0..saved_row_cnt %}
+ {% set myfield = save_row[i]['Field'] %}
+ {# Use an md5 as array index to avoid having special characters
+ in the name attribute (see bug #1746964 ) #}
+ {% set myfield_md5 = column_hash_array[myfield] %}
+
+ {% set foreign_table = false %}
+ {% set foreign_column = false %}
+
+ {# Database dropdown #}
+ {% if existrel[myfield] is defined %}
+ {% set foreign_db = existrel[myfield]['foreign_db'] %}
+ {% else %}
+ {% set foreign_db = db %}
+ {% endif %}
+
+ {# Table dropdown #}
+ {% set tables = [] %}
+ {% if foreign_db %}
+ {% if existrel[myfield] is defined %}
+ {% set foreign_table = existrel[myfield]['foreign_table'] %}
+ {% endif %}
+ {% set tables = dbi.getTables(foreign_db) %}
+ {% endif %}
+
+ {# Column dropdown #}
+ {% set unique_columns = [] %}
+ {% if foreign_db and foreign_table %}
+ {% if existrel[myfield] is defined %}
+ {% set foreign_column = existrel[myfield]['foreign_field'] %}
+ {% endif %}
+ {% set table_obj = table_get(foreign_table, foreign_db) %}
+ {% set unique_columns = table_obj.getUniqueColumns(false, false) %}
+ {% endif %}
+
+ <tr>
+ <td class="vmiddle">
+ <strong>{{ myfield }}</strong>
+ <input type="hidden" name="fields_name[{{ myfield_md5 }}]"
+ value="{{ myfield }}">
+ </td>
+
+ <td>
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_db[' ~ myfield_md5 ~ ']',
+ 'title': 'Database'|trans,
+ 'values': databases,
+ 'foreign': foreign_db
+ } only %}
+
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_table[' ~ myfield_md5 ~ ']',
+ 'title': 'Table'|trans,
+ 'values': tables,
+ 'foreign': foreign_table
+ } only %}
+
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_column[' ~ myfield_md5 ~ ']',
+ 'title': 'Column'|trans,
+ 'values': unique_columns,
+ 'foreign': foreign_column
+ } only %}
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ </fieldset>
+ {% if is_foreign_key_supported(tbl_storage_engine) %}
+ </div>
+ {% endif %}
+ {% endif %}
+
+ {% if cfg_relation['displaywork'] %}
+ {% set disp = get_display_field(db, table) %}
+ <fieldset>
+ <label>{% trans 'Choose column to display:' %}</label>
+ <select name="display_field">
+ <option value="">---</option>
+ {% for row in save_row %}
+ <option value="{{ row['Field'] }}"
+ {%- if disp is defined and row['Field'] == disp %}
+ selected="selected"
+ {%- endif %}>
+ {{ row['Field'] }}
+ </option>
+ {% endfor %}
+ </select>
+ </fieldset>
+ {% endif %}
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-secondary preview_sql" type="button" value="{% trans 'Preview SQL' %}">
+ <input class="btn btn-primary" type="submit" value="{% trans 'Save' %}">
+ </fieldset>
+</form>
+{% if foreignKeySupported %}
+ {{ displayIndexesHtml|raw }}
+{% endif %}
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig b/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig
new file mode 100644
index 0000000..ff179bc
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig
@@ -0,0 +1,9 @@
+{{ dropdown_question is not empty ? dropdown_question -}}
+<select name="{{ select_name }}">
+{% for one_value, one_label in choices %}
+ <option value="{{ one_value }}"
+ {%- if selected_value == one_value %} selected="selected"{% endif %}>
+ {{ one_label }}
+ </option>
+{% endfor %}
+</select>
diff --git a/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig b/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig
new file mode 100644
index 0000000..3df6c34
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig
@@ -0,0 +1,136 @@
+<tr>
+ {# Drop key anchor #}
+ <td>
+ {% set js_msg = '' %}
+ {% set this_params = null %}
+ {% if one_key['constraint'] is defined %}
+ {% set drop_fk_query = 'ALTER TABLE ' ~ backquote(db) ~ '.' ~ backquote(table)
+ ~ ' DROP FOREIGN KEY '
+ ~ backquote(one_key['constraint']) ~ ';'
+ %}
+ {% set this_params = url_params %}
+ {% set this_params = {
+ 'goto': 'tbl_relation.php',
+ 'back': 'tbl_relation.php',
+ 'sql_query': drop_fk_query,
+ 'message_to_show': 'Foreign key constraint %s has been dropped'|trans|format(
+ one_key['constraint']
+ )
+ } %}
+ {% set js_msg = 'ALTER TABLE ' ~ db ~ '.' ~ table ~ ' DROP FOREIGN KEY ' ~ one_key['constraint'] ~ ';'|js_format %}
+ {% endif %}
+ {% if one_key['constraint'] is defined %}
+ <input type="hidden" class="drop_foreign_key_msg" value="
+ {{- js_msg }}">
+ {% set drop_url = 'sql.php' ~ get_common(this_params) %}
+ {% set drop_str = get_icon('b_drop', 'Drop'|trans) %}
+ {{ link_or_button(drop_url, drop_str, {'class': 'drop_foreign_key_anchor ajax'}) }}
+ {% endif %}
+ </td>
+ <td>
+ <span class="formelement clearfloat">
+ <input type="text" name="constraint_name[{{ i }}]" value="
+ {{- one_key['constraint'] is defined ? one_key['constraint'] -}}
+ " placeholder="{% trans 'Constraint name' %}" maxlength="64">
+ </span>
+ <div class="floatleft">
+ {# For ON DELETE and ON UPDATE, the default action
+ is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE
+ won't display the clause if it's set as RESTRICT. #}
+ {% set on_delete = one_key['on_delete'] is defined
+ ? one_key['on_delete'] : 'RESTRICT' %}
+ {% set on_update = one_key['on_update'] is defined
+ ? one_key['on_update'] : 'RESTRICT' %}
+ <span class="formelement">
+ {% include 'table/relation/dropdown_generate.twig' with {
+ 'dropdown_question': 'ON DELETE',
+ 'select_name': 'on_delete[' ~ i ~ ']',
+ 'choices': options_array,
+ 'selected_value': on_delete
+ } only %}
+ </span>
+ <span class="formelement">
+ {% include 'table/relation/dropdown_generate.twig' with {
+ 'dropdown_question': 'ON UPDATE',
+ 'select_name': 'on_update[' ~ i ~ ']',
+ 'choices': options_array,
+ 'selected_value': on_update
+ } only %}
+ </span>
+ </div>
+ </td>
+ <td>
+ {% if one_key['index_list'] is defined %}
+ {% for key, column in one_key['index_list'] %}
+ <span class="formelement clearfloat">
+ {% include 'table/relation/dropdown_generate.twig' with {
+ 'dropdown_question': '',
+ 'select_name': 'foreign_key_fields_name[' ~ i ~ '][]',
+ 'choices': column_array,
+ 'selected_value': column
+ } only %}
+ </span>
+ {% endfor %}
+ {% else %}
+ <span class="formelement clearfloat">
+ {% include 'table/relation/dropdown_generate.twig' with {
+ 'dropdown_question': '',
+ 'select_name': 'foreign_key_fields_name[' ~ i ~ '][]',
+ 'choices': column_array,
+ 'selected_value': ''
+ } only %}
+ </span>
+ {% endif %}
+ <a class="formelement clearfloat add_foreign_key_field" data-index="
+ {{- i }}" href="">
+ {% trans '+ Add column' %}
+ </a>
+ </td>
+ {% set tables = [] %}
+ {% if foreign_db %}
+ {% set tables = get_tables(foreign_db, tbl_storage_engine) %}
+ {% endif %}
+ <td>
+ <span class="formelement clearfloat">
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_foreign_db[' ~ i ~ ']',
+ 'title': 'Database'|trans,
+ 'values': databases,
+ 'foreign': foreign_db
+ } only %}
+ </span>
+ </td>
+ <td>
+ <span class="formelement clearfloat">
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_foreign_table[' ~ i ~ ']',
+ 'title': 'Table'|trans,
+ 'values': tables,
+ 'foreign': foreign_table
+ } only %}
+ </span>
+ </td>
+ <td>
+ {% if foreign_db and foreign_table %}
+ {% for foreign_column in one_key['ref_index_list'] %}
+ <span class="formelement clearfloat">
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_foreign_column[' ~ i ~ '][]',
+ 'title': 'Column'|trans,
+ 'values': unique_columns,
+ 'foreign': foreign_column
+ } only %}
+ </span>
+ {% endfor %}
+ {% else %}
+ <span class="formelement clearfloat">
+ {% include 'table/relation/relational_dropdown.twig' with {
+ 'name': 'destination_foreign_column[' ~ i ~ '][]',
+ 'title': 'Column'|trans,
+ 'values': [],
+ 'foreign': ''
+ } only %}
+ </span>
+ {% endif %}
+ </td>
+</tr>
diff --git a/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig b/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig
new file mode 100644
index 0000000..9d5f3c9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig
@@ -0,0 +1,18 @@
+<select name="{{ name }}" title="{{ title }}">
+ <option value=""></option>
+ {% set seen_key = false %}
+ {% for value in values %}
+ <option value="{{ value }}"
+ {%- if foreign is not same as(false) and value == foreign %}
+ selected="selected"
+ {%- set seen_key = true -%}
+ {%- endif %}>
+ {{ value }}
+ </option>
+ {% endfor %}
+ {% if foreign is not same as(false) and not seen_key %}
+ <option value="{{ foreign }}" selected="selected">
+ {{ foreign }}
+ </option>
+ {% endif %}
+</select>
diff --git a/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig b/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig
new file mode 100644
index 0000000..b72e530
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig
@@ -0,0 +1,3 @@
+<select id="ColumnOperator{{ search_index }}" name="criteriaColumnOperators[{{ search_index }}]">
+ {{ type_operators|raw }}
+</select>
diff --git a/srcs/phpmyadmin/templates/table/search/fields_table.twig b/srcs/phpmyadmin/templates/table/search/fields_table.twig
new file mode 100644
index 0000000..8b74939
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/fields_table.twig
@@ -0,0 +1,33 @@
+<table class="data"{{ search_type == 'zoom' ? ' id="tableFieldsId"' }}>
+ <thead>
+ <tr>
+ {% if geom_column_flag %}
+ <th>{% trans 'Function' %}</th>
+ {% endif %}
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Type' %}</th>
+ <th>{% trans 'Collation' %}</th>
+ <th>{% trans 'Operator' %}</th>
+ <th>{% trans 'Value' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if search_type == 'zoom' %}
+ {% include 'table/search/rows_zoom.twig' with {
+ 'self': self,
+ 'column_names': column_names,
+ 'keys': keys,
+ 'criteria_column_names': criteria_column_names,
+ 'criteria_column_types': criteria_column_types
+ } only %}
+ {% else %}
+ {% include 'table/search/rows_normal.twig' with {
+ 'self': self,
+ 'geom_column_flag': geom_column_flag,
+ 'column_names': column_names,
+ 'column_types': column_types,
+ 'column_collations': column_collations
+ } only %}
+ {% endif %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/table/search/form_tag.twig b/srcs/phpmyadmin/templates/table/search/form_tag.twig
new file mode 100644
index 0000000..1017abd
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/form_tag.twig
@@ -0,0 +1,4 @@
+<form method="post" action="{{ script_name }}" name="insertForm" id="{{ form_id }}" class="ajax lock-page">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="goto" value="{{ goto }}">
+ <input type="hidden" name="back" value="{{ script_name }}">
diff --git a/srcs/phpmyadmin/templates/table/search/geom_func.twig b/srcs/phpmyadmin/templates/table/search/geom_func.twig
new file mode 100644
index 0000000..f7a7415
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/geom_func.twig
@@ -0,0 +1,19 @@
+{# Displays 'Function' column if it is present #}
+<td>
+ {% set geom_types = get_gis_datatypes() %}
+ {% if column_types[column_index] in geom_types %}
+ <select class="geom_func" name="geom_func[{{ column_index }}]">
+ {# get the relevant list of GIS functions #}
+ {% set funcs = get_gis_functions(column_types[column_index], true, true) %}
+
+ {% for func_name, func in funcs %}
+ {% set name = func['display'] is defined ? func['display'] : func_name %}
+ <option value="{{ name }}">
+ {{ name }}
+ </option>
+ {% endfor %}
+ </select>
+ {% else %}
+ &nbsp;
+ {% endif %}
+</td>
diff --git a/srcs/phpmyadmin/templates/table/search/input_box.twig b/srcs/phpmyadmin/templates/table/search/input_box.twig
new file mode 100644
index 0000000..5c30535
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/input_box.twig
@@ -0,0 +1,97 @@
+{# Get inputbox based on different column types (Foreign key, geometrical, enum) #}
+{% if foreigners and search_column_in_foreigners(foreigners, column_name) %}
+ {% if foreign_data['disp_row'] is iterable %}
+ <select name="criteriaValues[{{ column_index }}]"
+ id="{{ column_id }}{{ column_index }}">
+ {{ foreign_dropdown(
+ foreign_data['disp_row'],
+ foreign_data['foreign_field'],
+ foreign_data['foreign_display'],
+ '',
+ foreign_max_limit
+ ) }}
+ </select>
+ {% elseif foreign_data['foreign_link'] == true %}
+ <input type="text"
+ id="{{ column_id }}{{ column_index }}"
+ name="criteriaValues[{{ column_index }}]"
+ id="field_{{ column_name_hash }}[{{ column_index }}]"
+ class="textfield"
+ {% if criteria_values[column_index] is defined %}
+ value="{{ criteria_values[column_index] }}"
+ {% endif %}>
+ <a class="ajax browse_foreign" href="browse_foreigners.php" data-post="
+ {{- get_common({'db': db, 'table': table}, '') -}}
+ &amp;field={{ column_name|url_encode }}&amp;fieldkey=
+ {{- column_index }}&amp;fromsearch=1">
+ {{ titles['Browse']|replace({"'": "\\'"})|raw }}
+ </a>
+ {% endif %}
+{% elseif column_type in get_gis_datatypes() %}
+ <input type="text"
+ name="criteriaValues[{{ column_index }}]"
+ size="40"
+ class="textfield"
+ id="field_{{ column_index }}">
+ {% if in_fbs %}
+ {% set edit_url = 'gis_data_editor.php' ~ get_common() %}
+ {% set edit_str = get_icon('b_edit', 'Edit/Insert'|trans) %}
+ <span class="open_search_gis_editor">
+ {{ link_or_button(edit_url, edit_str, [], '_blank') }}
+ </span>
+ {% endif %}
+{% elseif column_type starts with 'enum'
+ or (column_type starts with 'set' and in_zoom_search_edit) %}
+ {% set in_zoom_search_edit = false %}
+ {% set value = column_type|e|slice(5, -1)|replace({'&#039;': ''})|split(', ') %}
+ {% set cnt_value = value|length %}
+ {#
+ Enum in edit mode --> dropdown
+ Enum in search mode --> multiselect
+ Set in edit mode --> multiselect
+ Set in search mode --> input (skipped here, so the 'else' section would handle it)
+ #}
+ {% if (column_type starts with 'enum' and not in_zoom_search_edit)
+ or (column_type starts with 'set' and in_zoom_search_edit) %}
+ <select name="criteriaValues[{{ column_index }}]"
+ id="{{ column_id }}{{ column_index }}">
+ {% else %}
+ <select name="criteriaValues[{{ column_index }}]"
+ id="{{ column_id }}{{ column_index }}"
+ multiple="multiple"
+ size="{{ min(3, cnt_value) }}">
+ {% endif %}
+ {# Add select options #}
+ <option value=""></option>
+ {% for i in 0..cnt_value - 1 %}
+ {% if criteria_values[column_index] is defined
+ and criteria_values[column_index] is iterable
+ and value[i] in criteria_values[column_index] %}
+ <option value="{{ value[i]|raw }}" selected>
+ {{ value[i]|raw }}
+ </option>
+ {% else %}
+ <option value="{{ value[i]|raw }}">
+ {{ value[i]|raw }}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+{% else %}
+ {% set the_class = 'textfield' %}
+ {% if column_type == 'date' %}
+ {% set the_class = the_class ~ ' datefield' %}
+ {% elseif column_type == 'datetime' or column_type starts with 'timestamp' %}
+ {% set the_class = the_class ~ ' datetimefield' %}
+ {% elseif column_type starts with 'bit' %}
+ {% set the_class = the_class ~ ' bit' %}
+ {% endif %}
+ <input type="text"
+ name="criteriaValues[{{ column_index }}]"
+ size="40"
+ class="{{ the_class }}"
+ id="{{ column_id }}{{ column_index }}"
+ {% if criteria_values[column_index] is defined %}
+ value="{{ criteria_values[column_index] }}"
+ {%- endif %}>
+{% endif %}
diff --git a/srcs/phpmyadmin/templates/table/search/replace_preview.twig b/srcs/phpmyadmin/templates/table/search/replace_preview.twig
new file mode 100644
index 0000000..e7a2423
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/replace_preview.twig
@@ -0,0 +1,39 @@
+<form method="post"
+ action="tbl_find_replace.php"
+ name="previewForm"
+ id="previewForm">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="replace" value="true">
+ <input type="hidden" name="columnIndex" value="{{ column_index }}">
+ <input type="hidden" name="findString" value="{{ find }}">
+ <input type="hidden" name="replaceWith" value="{{ replace_with }}">
+ <input type="hidden" name="useRegex" value="{{ use_regex }}">
+
+ <fieldset id="fieldset_find_replace_preview">
+ <legend>{% trans 'Find and replace - preview' %}</legend>
+ <table id="previewTable">
+ <thead>
+ <tr>
+ <th>{% trans 'Count' %}</th>
+ <th>{% trans 'Original string' %}</th>
+ <th>{% trans 'Replaced string' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% if result is iterable %}
+ {% for row in result %}
+ <tr>
+ <td class="right">{{ row[2] }}</td>{# count #}
+ <td>{{ row[0] }}</td>{# original #}
+ <td>{{ row[1] }}</td>{# replaced #}
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tbody>
+ </table>
+ </fieldset>
+
+ <fieldset class="tblFooters">
+ <input class="btn btn-secondary" type="submit" name="replace" value="{% trans 'Replace' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/table/search/rows_normal.twig b/srcs/phpmyadmin/templates/table/search/rows_normal.twig
new file mode 100644
index 0000000..5e21efa
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/rows_normal.twig
@@ -0,0 +1,39 @@
+{% for column_index in 0..column_names|length - 1 %}
+ <tr class="noclick">
+ {# If 'Function' column is present trying to change comment #}
+ {% if geom_column_flag %}
+ {% include 'table/search/geom_func.twig' with {
+ 'column_index': column_index,
+ 'column_types': column_types
+ } only %}
+ {% endif %}
+ {# Displays column's name, type, collation and value #}
+ <th>
+ {{ column_names[column_index] }}
+ </th>
+ {% set properties = self.getColumnProperties(column_index, column_index) %}
+ <td dir="ltr">
+ {{ properties['type'] }}
+ </td>
+ <td>
+ {{ properties['collation'] }}
+ </td>
+ <td>
+ {{ properties['func']|raw }}
+ </td>
+ {# here, the data-type attribute is needed for a date/time picker #}
+ <td data-type="{{ properties['type'] }}">
+ {{ properties['value']|raw }}
+ {# Displays hidden fields #}
+ <input type="hidden"
+ name="criteriaColumnNames[{{ column_index }}]"
+ value="{{ column_names[column_index] }}">
+ <input type="hidden"
+ name="criteriaColumnTypes[{{ column_index }}]"
+ value="{{ column_types[column_index] }}">
+ <input type="hidden"
+ name="criteriaColumnCollations[{{ column_index }}]"
+ value="{{ column_collations[column_index] }}">
+ </td>
+ </tr>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/table/search/rows_zoom.twig b/srcs/phpmyadmin/templates/table/search/rows_zoom.twig
new file mode 100644
index 0000000..dc46f1d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/rows_zoom.twig
@@ -0,0 +1,74 @@
+{# Get already set search criteria (if any) #}
+{% set type = [] %}
+{% set collation = [] %}
+{% set func = [] %}
+{% set value = [] %}
+
+{% for i in 0..3 %}
+ {# After X-Axis and Y-Axis column rows, display additional criteria option #}
+ {% if i == 2 %}
+ <tr>
+ <td>
+ {% trans 'Additional search criteria' %}
+ </td>
+ </tr>
+ {% endif %}
+ <tr class="noclick">
+ <th>
+ <select name="criteriaColumnNames[]" id="tableid_{{ i }}" >
+ <option value="pma_null">
+ {% trans 'None' %}
+ </option>
+ {% for j in 0..column_names|length - 1 %}
+ {% if criteria_column_names[i] is defined
+ and criteria_column_names[i] == column_names[j] %}
+ <option value="{{ column_names[j] }}" selected="selected">
+ {{ column_names[j] }}
+ </option>
+ {% else %}
+ <option value="{{ column_names[j] }}">
+ {{ column_names[j] }}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </th>
+ {% if criteria_column_names[i] is defined
+ and criteria_column_names[i] != 'pma_null' %}
+ {% set key = keys[criteria_column_names[i]] %}
+ {% set properties = self.getColumnProperties(i, key) %}
+ {% set type = type|merge({i: properties['type']}) %}
+ {% set collation = collation|merge({i: properties['collation']}) %}
+ {% set func = func|merge({i: properties['func']}) %}
+ {% set value = value|merge({i: properties['value']}) %}
+ {% endif %}
+ {# Column type #}
+ <td dir="ltr">
+ {{ type[i] is defined ? type[i] }}
+ </td>
+ {# Column Collation #}
+ <td>
+ {{ collation[i] is defined ? collation[i] }}
+ </td>
+ {# Select options for column operators #}
+ <td>
+ {{ func[i] is defined ? func[i]|raw }}
+ </td>
+ {# Inputbox for search criteria value #}
+ <td>
+ </td>
+ <td>
+ {{ value[i] is defined ? value[i]|raw }}
+ {# Displays hidden fields #}
+ <input type="hidden"
+ name="criteriaColumnTypes[{{ i }}]"
+ id="types_{{ i }}"
+ {%- if criteria_column_types[i] is defined %}
+ value="{{ criteria_column_types[i] }}"
+ {%- endif %}>
+ <input type="hidden"
+ name="criteriaColumnCollations[{{ i }}]"
+ id="collations_{{ i }}">
+ </td>
+ </tr>
+{% endfor %}
diff --git a/srcs/phpmyadmin/templates/table/search/selection_form.twig b/srcs/phpmyadmin/templates/table/search/selection_form.twig
new file mode 100644
index 0000000..2ba4d60
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/selection_form.twig
@@ -0,0 +1,226 @@
+{% if search_type == 'zoom' %}
+ {% include 'table/search/form_tag.twig' with {
+ 'script_name': 'tbl_zoom_select.php',
+ 'form_id': 'zoom_search_form',
+ 'db': db,
+ 'table': table,
+ 'goto': goto
+ } only %}
+ <fieldset id="fieldset_zoom_search">
+ <fieldset id="inputSection">
+ <legend>
+ {% trans 'Do a "query by example" (wildcard: "%") for two different columns' %}
+ </legend>
+ {% include 'table/search/fields_table.twig' with {
+ 'self': self,
+ 'search_type': search_type,
+ 'geom_column_flag': geom_column_flag,
+ 'column_names': column_names,
+ 'column_types': column_types,
+ 'column_collations': column_collations,
+ 'keys' : keys,
+ 'criteria_column_names': criteria_column_names,
+ 'criteria_column_types': criteria_column_types
+ } only %}<table class="data">
+ {# Select options for data label #}
+ <tr>
+ <td>
+ <label for="dataLabel">
+ {% trans 'Use this column to label each point' %}
+ </label>
+ </td>
+ <td>
+ <select name="dataLabel" id="dataLabel" >
+ <option value = "">
+ {% trans 'None' %}
+ </option>
+ {% for i in 0..column_names|length - 1 %}
+ {% if data_label is defined and data_label == column_names[i]|e %}
+ <option value="{{ column_names[i] }}" selected="selected">
+ {{ column_names[i] }}
+ </option>
+ {% else %}
+ <option value="{{ column_names[i] }}" >
+ {{ column_names[i] }}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </td>
+ </tr>
+ {# Inputbox for changing default maximum rows to plot #}
+ <tr>
+ <td>
+ <label for="maxRowPlotLimit">
+ {% trans 'Maximum rows to plot' %}
+ </label>
+ </td>
+ <td>
+ <input type="number"
+ name="maxPlotLimit"
+ id="maxRowPlotLimit"
+ required="required"
+ value="{{ max_plot_limit }}">
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </fieldset>
+{% elseif search_type == 'normal' %}
+ {% include 'table/search/form_tag.twig' with {
+ 'script_name': 'tbl_select.php',
+ 'form_id': 'tbl_search_form',
+ 'db': db,
+ 'table': table,
+ 'goto': goto
+ } only %}
+ <fieldset id="fieldset_table_search">
+ <fieldset id="fieldset_table_qbe">
+ <legend>
+ {% trans 'Do a "query by example" (wildcard: "%")' %}
+ </legend>
+ <div class="responsivetable jsresponsive">
+ {% include 'table/search/fields_table.twig' with {
+ 'self': self,
+ 'search_type': search_type,
+ 'geom_column_flag': geom_column_flag,
+ 'column_names': column_names,
+ 'column_types': column_types,
+ 'column_collations': column_collations,
+ 'criteria_column_names': criteria_column_names,
+ 'criteria_column_types': criteria_column_types
+ } only %}
+ </div>
+ <div id="gis_editor"></div>
+ <div id="popup_background"></div>
+ </fieldset>
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': 'searchoptions',
+ 'message': 'Options'|trans,
+ 'initial_sliders_state': default_sliders_state
+ } only %}
+
+ {# Displays columns select list for selecting distinct columns in the search #}
+ <fieldset id="fieldset_select_fields">
+ <legend>
+ {% trans 'Select columns (at least one):' %}
+ </legend>
+ <select name="columnsToDisplay[]"
+ size="{{ min(column_names|length, 10) }}"
+ multiple="multiple">
+ {% for each_field in column_names %}
+ <option value="{{ each_field }}"
+ selected="selected">
+ {{ each_field }}
+ </option>
+ {% endfor %}
+ </select>
+ <input type="checkbox" name="distinct" value="DISTINCT" id="oDistinct">
+ <label for="oDistinct">DISTINCT</label>
+ </fieldset>
+
+ {# Displays input box for custom 'Where' clause to be used in the search #}
+ <fieldset id="fieldset_search_conditions">
+ <legend>
+ <em>{% trans 'Or' %}</em>
+ {% trans 'Add search conditions (body of the "where" clause):' %}
+ </legend>
+ {{ show_mysql_docu('Functions') }}
+ <input type="text" name="customWhereClause" class="textfield" size="64">
+ </fieldset>
+
+ {# Displays option of changing default number of rows displayed per page #}
+ <fieldset id="fieldset_limit_rows">
+ <legend>{% trans 'Number of rows per page' %}</legend>
+ <input type="number"
+ name="session_max_rows"
+ required="required"
+ min="1"
+ value="{{ max_rows }}"
+ class="textfield">
+ </fieldset>
+
+ {# Displays option for ordering search results by a column value (Asc or Desc) #}
+ <fieldset id="fieldset_display_order">
+ <legend>{% trans 'Display order:' %}</legend>
+ <select name="orderByColumn"><option value="--nil--"></option>
+ {% for each_field in column_names %}
+ <option value="{{ each_field }}">
+ {{ each_field }}
+ </option>
+ {% endfor %}
+ </select>
+
+ {{ get_radio_fields(
+ 'order',
+ {
+ 'ASC': 'Ascending'|trans,
+ 'DESC': 'Descending'|trans
+ },
+ 'ASC',
+ false,
+ true,
+ 'formelement'
+ ) }}
+
+ </fieldset>
+ <div class="clearfloat"></div>
+ </fieldset>
+{% elseif search_type == 'replace' %}
+ {% include 'table/search/form_tag.twig' with {
+ 'script_name': 'tbl_find_replace.php',
+ 'form_id': 'find_replace_form',
+ 'db': db,
+ 'table': table,
+ 'goto': goto
+ } only %}
+ <fieldset id="fieldset_find_replace">
+ <fieldset id="fieldset_find">
+ <legend>
+ {% trans 'Find and replace' %}
+ </legend>{% trans 'Find:' %}
+ <input type="text" value="" name="find" required>
+ {% trans 'Replace with:' %}
+ <input type="text" value="" name="replaceWith">
+
+ {% trans 'Column:' %}
+ <select name="columnIndex">
+ {% for i in 0..column_names|length - 1 %}
+ {% set type = types[column_names[i]] %}
+
+ {% if sql_types.getTypeClass(type) == 'CHAR' %}
+ <option value="{{ i }}">
+ {{- column_names[i] -}}
+ </option>
+ {% endif %}
+ {% endfor %}
+ </select>
+
+ {% include 'checkbox.twig' with {
+ 'html_field_id': 'useRegex',
+ 'html_field_name': 'useRegex',
+ 'label': 'Use regular expression'|trans,
+ 'checked': false,
+ 'onclick': false
+ } only %}
+ </fieldset>
+ </fieldset>
+{% else %}
+ {% include 'table/search/form_tag.twig' with {
+ 'script_name': '',
+ 'form_id': '',
+ 'db': db,
+ 'table': table,
+ 'goto': goto
+ } only %}
+{% endif %}
+
+{# Displays selection form's footer elements #}
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit"
+ name="{{ search_type == 'zoom' ? 'zoom_submit' : 'submit' }}"
+ {{ search_type == 'zoom' ? 'id="inputFormSubmitId"' }}
+ value="{% trans 'Go' %}">
+ </fieldset>
+</form>
+<div id="sqlqueryresultsouter"></div>
diff --git a/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig b/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig
new file mode 100644
index 0000000..7543f85
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig
@@ -0,0 +1,86 @@
+<form method="post" action="tbl_zoom_select.php" name="displayResultForm" id="zoom_display_form" class="ajax">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="goto" value="{{ goto }}">
+ <input type="hidden" name="back" value="tbl_zoom_select.php">
+
+ <fieldset id="displaySection">
+ <legend>{% trans 'Browse/Edit the points' %}</legend>
+
+ {# JSON encode the data(query result) #}
+ <center>
+ {% if zoom_submit and data is not empty %}
+ <div id="resizer">
+ <center>
+ <a id="help_dialog" href="#">
+ {% trans 'How to use' %}
+ </a>
+ </center>
+ <div id="querydata" class="hide">
+ {{ data_json }}
+ </div>
+ <div id="querychart"></div>
+ <button class="button-reset">
+ {% trans 'Reset zoom' %}
+ </button>
+ </div>
+ {% endif %}
+ </center>
+
+ {# Displays rows in point edit form #}
+ <div id="dataDisplay" class="hide">
+ <table>
+ <thead>
+ <tr>
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Null' %}</th>
+ <th>{% trans 'Value' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for column_index in 0..column_names|length - 1 %}
+ {% set field_popup = column_names[column_index] %}
+ {% set foreign_data = get_foreign_data(
+ foreigners,
+ field_popup,
+ false,
+ '',
+ ''
+ ) %}
+ <tr class="noclick">
+ <th>{{ column_names[column_index] }}</th>
+ {# Null checkbox if column can be null #}
+ <th>
+ {% if column_null_flags[column_index] == 'YES' %}
+ <input type="checkbox" class="checkbox_null"
+ name="criteriaColumnNullFlags[{{ column_index }}]"
+ id="edit_fields_null_id_{{ column_index }}">
+ {% endif %}
+ </th>
+ {# Column's Input box #}
+ <th>
+ {% include 'table/search/input_box.twig' with {
+ 'str': '',
+ 'column_type': column_types[column_index],
+ 'column_id': column_types[column_index] ? 'edit_fieldID_' : 'fieldID_',
+ 'in_zoom_search_edit': true,
+ 'foreigners': foreigners,
+ 'column_name': field_popup,
+ 'column_name_hash': column_name_hashes[field_popup],
+ 'foreign_data': foreign_data,
+ 'table': table,
+ 'column_index': column_index,
+ 'foreign_max_limit': foreign_max_limit,
+ 'criteria_values': '',
+ 'db': db,
+ 'titles': titles,
+ 'in_fbs': false
+ } only %}
+ </th>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ <input type="hidden" id="queryID" name="sql_query">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig b/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig
new file mode 100644
index 0000000..d9c629c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig
@@ -0,0 +1,31 @@
+<li class="{{ class }}">
+{% if type == 'text'
+ or type == 'blob'
+ or tbl_storage_engine == 'ARCHIVE'
+ or has_field %}
+ {{ titles['No' ~ action]|raw }}
+{% else %}
+ <a rel="samepage" class="ajax add_key print_ignore
+ {%- if has_link_class %}
+ add_primary_key_anchor
+ {%- elseif action == 'Index' %}
+ add_index_anchor
+ {%- elseif action == 'Unique' %}
+ add_unique_anchor
+ {%- elseif action == 'Spatial' %}
+ add_spatial_anchor
+ {%- endif %}" href="tbl_structure.php" data-post="{{ url_query|raw -}}
+ &amp;add_key=1&amp;sql_query=
+ {{- ('ALTER TABLE ' ~
+ backquote(table) ~
+ (is_primary ? (primary ? ' DROP PRIMARY KEY,')) ~
+ ' ' ~
+ syntax ~
+ '(' ~
+ backquote(row['Field']) ~
+ ');')|url_encode -}}
+ &amp;message_to_show={{ message|format(row['Field']|e)|url_encode }}">
+ {{ titles[action]|raw }}
+ </a>
+{% endif %}
+</li>
diff --git a/srcs/phpmyadmin/templates/table/structure/display_partitions.twig b/srcs/phpmyadmin/templates/table/structure/display_partitions.twig
new file mode 100644
index 0000000..b10a0bc
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/structure/display_partitions.twig
@@ -0,0 +1,145 @@
+<div id="partitions">
+ <fieldset>
+ <legend>
+ {% trans 'Partitions' %}
+ {{ show_mysql_docu('partitioning') }}
+ </legend>
+ {% if partitions is empty %}
+ {{ 'No partitioning defined!'|trans|notice }}
+ {% else %}
+ <p>
+ {% trans 'Partitioned by:' %}
+ <code>{{ partition_method }}({{ partition_expression }})</code>
+ </p>
+ {% if has_sub_partitions %}
+ <p>
+ {% trans 'Sub partitioned by:' %}
+ <code>{{ sub_partition_method }}({{ sub_partition_expression }})</code>
+ <p>
+ {% endif %}
+ <table>
+ <thead>
+ <tr>
+ <th colspan="2">#</th>
+ <th>{% trans 'Partition' %}</th>
+ {% if has_description %}
+ <th>{% trans 'Expression' %}</th>
+ {% endif %}
+ <th>{% trans 'Rows' %}</th>
+ <th>{% trans 'Data length' %}</th>
+ <th>{% trans 'Index length' %}</th>
+ <th>{% trans 'Comment' %}</th>
+ <th colspan="{{ range_or_list ? '7' : '6' }}">
+ {% trans 'Action' %}
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for partition in partitions %}
+ <tr class="noclick{{ has_sub_partitions ? ' marked' }}">
+ {% if has_sub_partitions %}
+ <td>{{ partition.getOrdinal() }}</td>
+ <td></td>
+ {% else %}
+ <td colspan="2">{{ partition.getOrdinal() }}</td>
+ {% endif %}
+ <th>{{ partition.getName() }}</th>
+ {% if has_description %}
+ <td>
+ <code>
+ {{- partition.getExpression() -}}
+ {{- partition.getMethod() == 'LIST' ? ' IN (' : ' < ' -}}
+ {{- partition.getDescription() -}}
+ {{- partition.getMethod() == 'LIST' ? ')' -}}
+ </code>
+ </td>
+ {% endif %}
+ <td class="value">{{ partition.getRows() }}</td>
+ <td class="value">
+ {% set data_length = format_byte_down(
+ partition.getDataLength(),
+ 3,
+ 1
+ ) %}
+ <span>{{ data_length[0] }}</span>
+ <span class="unit">{{ data_length[1] }}</span>
+ </td>
+ <td class="value">
+ {% set index_length = format_byte_down(
+ partition.getIndexLength(),
+ 3,
+ 1
+ ) %}
+ <span>{{ index_length[0] }}</span>
+ <span class="unit">{{ index_length[1] }}</span>
+ </td>
+ <td>{{ partition.getComment() }}</td>
+ {% for action, icon in action_icons %}
+ <td>
+ <a href="tbl_structure.php" data-post="{{ url_query -}}
+ &amp;partition_maintenance=1&amp;sql_query=
+ {{- ("ALTER TABLE " ~ backquote(table) ~ " " ~ action
+ ~ " PARTITION " ~ partition.getName())|url_encode }}"
+ id="partition_action_{{ action }}"
+ name="partition_action_{{ action }}"
+ class="ajax">
+ {{ icon|raw }}
+ </a>
+ </td>
+ {% endfor %}
+
+ {% if has_sub_partitions %}
+ {% for sub_partition in partition.getSubPartitions() %}
+ <tr class="noclick">
+ <td></td>
+ <td>{{ sub_partition.getOrdinal() }}</td>
+ <td>{{ sub_partition.getName() }}</td>
+ {% if has_description %}
+ <td></td>
+ {% endif %}
+ <td class="value">{{ sub_partition.getRows() }}</td>
+ <td class="value">
+ {% set data_length = format_byte_down(
+ sub_partition.getDataLength(),
+ 3,
+ 1
+ ) %}
+ <span>{{ data_length[0] }}</span>
+ <span class="unit">{{ data_length[1] }}</span>
+ </td>
+ <td class="value">
+ {% set index_length = format_byte_down(
+ sub_partition.getIndexLength(),
+ 3,
+ 1
+ ) %}
+ <span>{{ index_length[0] }}</span>
+ <span class="unit">{{ index_length[1] }}</span>
+ </td>
+ <td>{{ sub_partition.getComment() }}</td>
+ <td colspan="{{ range_or_list ? '7' : '6' }}"></td>
+ </tr>
+ {% endfor %}
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ </fieldset>
+ <fieldset class="tblFooters print_ignore">
+ <form action="tbl_structure.php" method="post">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="edit_partitioning" value="true">
+ {% if partitions is empty %}
+ <input class="btn btn-secondary" type="submit" name="edit_partitioning" value="{% trans 'Partition table' %}">
+ {% else %}
+ {{ link_or_button(remove_url, 'Remove partitioning'|trans, {
+ 'class': 'button ajax',
+ 'id': 'remove_partitioning'
+ }) }}
+ <input class="btn btn-secondary" type="submit" name="edit_partitioning" value="{% trans 'Edit partitioning' %}">
+ {% endif %}
+ </form>
+ </fieldset>
+</div>
diff --git a/srcs/phpmyadmin/templates/table/structure/display_structure.twig b/srcs/phpmyadmin/templates/table/structure/display_structure.twig
new file mode 100644
index 0000000..16e11db
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/structure/display_structure.twig
@@ -0,0 +1,516 @@
+{% extends 'table/page_with_secondary_tabs.twig' %}
+{% block content %}
+<form method="post" action="tbl_structure.php" name="fieldsForm" id="fieldsForm"
+ class="ajax{{ hide_structure_actions ? ' HideStructureActions' }}">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="table_type" value=
+ {%- if db_is_system_schema -%}
+ "information_schema"
+ {%- elseif tbl_is_view -%}
+ "view"
+ {%- else -%}
+ "table"
+ {%- endif %}>
+ <div class="responsivetable">
+ <table id="tablestructure" class="data topmargin">
+ {# Table header #}
+ <thead>
+ <tr>
+ <th class="print_ignore"></th>
+ <th>#</th>
+ <th>{% trans 'Name' %}</th>
+ <th>{% trans 'Type' %}</th>
+ <th>{% trans 'Collation' %}</th>
+ <th>{% trans 'Attributes' %}</th>
+ <th>{% trans 'Null' %}</th>
+ <th>{% trans 'Default' %}</th>
+ {% if show_column_comments -%}
+ <th>{% trans 'Comments' %}</th>
+ {%- endif %}
+ <th>{% trans 'Extra' %}</th>
+ {# @see table/structure.js, function moreOptsMenuResize() #}
+ {% if not db_is_system_schema and not tbl_is_view %}
+ <th colspan="{{ show_icons('ActionLinksMode') ? '8' : '9' -}}
+ " class="action print_ignore">{% trans 'Action' %}</th>
+ {% endif %}
+ </tr>
+ </thead>
+ <tbody>
+ {# Table body #}
+ {% set rownum = 0 %}
+ {% for row in fields %}
+ {% set rownum = rownum + 1 %}
+
+ {% set extracted_columnspec = extracted_columnspecs[rownum] %}
+ {% set field_name = row['Field']|e %}
+ {# For column comments #}
+ {% set comments = row_comments[rownum] %}
+ {# Underline commented fields and display a hover-title (CSS only) #}
+
+ <tr>
+ <td class="center print_ignore">
+ <input type="checkbox" class="checkall" name="selected_fld[]" value="{{ row['Field'] }}" id="checkbox_row_{{ rownum }}">
+ </td>
+ <td class="right">{{ rownum }}</td>
+ <th class="nowrap">
+ <label for="checkbox_row_{{ rownum }}">
+ {% if displayed_fields[rownum].comment is defined %}
+ <span class="commented_column" title="{{ displayed_fields[rownum].comment }}">{{ displayed_fields[rownum].text }}</span>
+ {% else %}
+ {{ displayed_fields[rownum].text }}
+ {% endif %}
+ {{ displayed_fields[rownum].icon|raw }}
+ </label>
+ </th>
+ <td{{ 'set' != extracted_columnspec['type'] and 'enum' != extracted_columnspec['type'] ? ' class="nowrap"' }}>
+ <bdo dir="ltr" lang="en">
+ {{ extracted_columnspec['displayed_type']|raw }}
+ {% if relation_commwork and relation_mimework and browse_mime
+ and mime_map[row['Field']]['mimetype'] is defined %}
+ <br>{% trans 'Media (MIME) type:' %} {{ mime_map[row['Field']]['mimetype']|replace({'_': '/'})|lower }}
+ {% endif %}
+ </bdo>
+ </td>
+ <td>
+ {% if row['Collation'] is not empty %}
+ <dfn title="{{ collations[row['Collation']].description }}">{{ collations[row['Collation']].name }}</dfn>
+ {% endif %}
+ </td>
+ <td class="column_attribute nowrap">{{ attributes[rownum] }}</td>
+ <td>{{ row['Null'] == 'YES' ? 'Yes'|trans : 'No'|trans }}</td>
+ <td class="nowrap">
+ {% if row['Default'] is not null %}
+ {% if extracted_columnspec['type'] == 'bit' %}
+ {{ row['Default']|convert_bit_default_value }}
+ {% else %}
+ {{ row['Default'] }}
+ {% endif %}
+ {% elseif row['Null'] == 'YES' %}
+ <em>NULL</em>
+ {% else %}
+ <em>{% trans %}None{% context %}None for default{% endtrans %}</em>
+ {% endif %}
+ </td>
+ {% if show_column_comments %}
+ <td>
+ {{ comments }}
+ </td>
+ {% endif %}
+ <td class="nowrap">{{ row['Extra']|upper }}</td>
+ {% if not tbl_is_view and not db_is_system_schema %}
+ <td class="edit center print_ignore">
+ <a class="change_column_anchor ajax" href="tbl_structure.php
+ {{- url_query }}&amp;field={{ row['Field']|url_encode }}&amp;change_column=1">
+ {{ titles['Change']|raw }}
+ </a>
+ </td>
+ <td class="drop center print_ignore">
+ <a class="drop_column_anchor ajax" href="sql.php" data-post="{{ url_query }}&amp;sql_query=
+ {{- ('ALTER TABLE ' ~ backquote(table)
+ ~ ' DROP ' ~ backquote(row['Field']) ~ ';')|url_encode -}}
+ &amp;dropped_column={{ row['Field']|url_encode }}&amp;purge=1&amp;message_to_show=
+ {{- ('Column %s has been dropped.'|trans|format(row['Field']|e))|url_encode }}">
+ {{ titles['Drop']|raw }}
+ </a>
+ </td>
+ {% endif %}
+
+ {% if not tbl_is_view and not db_is_system_schema %}
+ {% set type = extracted_columnspec['print_type'] is not empty ? extracted_columnspec['print_type'] %}
+ <td class="print_ignore">
+ <ul class="table-structure-actions resizable-menu">
+ {% if hide_structure_actions %}
+ <li class="submenu shown">
+ <a href="#" class="tab nowrap">{{ get_icon('b_more', 'More'|trans) }}</a>
+ <ul>
+ {% endif %}
+ {# Add primary #}
+ {% include 'table/structure/action_row_in_structure_table.twig' with {
+ 'type': type,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'class': 'primary nowrap',
+ 'has_field': primary and primary.hasColumn(field_name),
+ 'has_link_class': true,
+ 'url_query': url_query,
+ 'primary': primary,
+ 'syntax': 'ADD PRIMARY KEY',
+ 'message': 'A primary key has been added on %s.'|trans,
+ 'action': 'Primary',
+ 'titles': titles,
+ 'row': row,
+ 'is_primary': true,
+ 'table': table
+ } only %}
+
+ {# Add unique #}
+ {% include 'table/structure/action_row_in_structure_table.twig' with {
+ 'type': type,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'class': 'add_unique unique nowrap',
+ 'has_field': field_name in columns_with_unique_index,
+ 'has_link_class': false,
+ 'url_query': url_query,
+ 'primary': primary,
+ 'syntax': 'ADD UNIQUE',
+ 'message': 'An index has been added on %s.'|trans,
+ 'action': 'Unique',
+ 'titles': titles,
+ 'row': row,
+ 'is_primary': false,
+ 'table': table
+ } only %}
+
+ {# Add index #}
+ {% include 'table/structure/action_row_in_structure_table.twig' with {
+ 'type': type,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'class': 'add_index nowrap',
+ 'has_field': false,
+ 'has_link_class': false,
+ 'url_query': url_query,
+ 'primary': primary,
+ 'syntax': 'ADD INDEX',
+ 'message': 'An index has been added on %s.'|trans,
+ 'action': 'Index',
+ 'titles': titles,
+ 'row': row,
+ 'is_primary': false,
+ 'table': table
+ } only %}
+
+ {# Add spatial #}
+ {% set spatial_types = [
+ 'geometry',
+ 'point',
+ 'linestring',
+ 'polygon',
+ 'multipoint',
+ 'multilinestring',
+ 'multipolygon',
+ 'geomtrycollection'
+ ] %}
+ {% include 'table/structure/action_row_in_structure_table.twig' with {
+ 'type': type,
+ 'tbl_storage_engine': tbl_storage_engine,
+ 'class': 'spatial nowrap',
+ 'has_field': type not in spatial_types and
+ (tbl_storage_engine == 'MYISAM' or mysql_int_version >= 50705),
+ 'has_link_class': false,
+ 'url_query': url_query,
+ 'primary': primary,
+ 'syntax': 'ADD SPATIAL',
+ 'message': 'An index has been added on %s.'|trans,
+ 'action': 'Spatial',
+ 'titles': titles,
+ 'row': row,
+ 'is_primary': false,
+ 'table': table
+ } only %}
+
+ {# FULLTEXT is possible on TEXT, CHAR and VARCHAR #}
+ <li class="fulltext nowrap">
+ {% if tbl_storage_engine is not empty and (
+ tbl_storage_engine == 'MYISAM'
+ or tbl_storage_engine == 'ARIA'
+ or tbl_storage_engine == 'MARIA'
+ or (tbl_storage_engine == 'INNODB' and mysql_int_version >= 50604)
+ ) and ('text' in type or 'char' in type) %}
+ <a rel="samepage" class="ajax add_key add_fulltext_anchor" href="tbl_structure.php"
+ data-post="{{- url_query|raw }}&amp;add_key=1&amp;sql_query=
+ {{- ('ALTER TABLE ' ~ backquote(table)
+ ~ ' ADD FULLTEXT(' ~ backquote(row['Field'])
+ ~ ');')|url_encode }}&amp;message_to_show=
+ {{- ('An index has been added on %s.'|trans|format(row['Field']|e))|url_encode }}">
+ {{ titles['IdxFulltext']|raw }}
+ </a>
+ {% else %}
+ {{ titles['NoIdxFulltext']|raw }}
+ {% endif %}
+ </li>
+
+ {# Distinct value action #}
+ <li class="browse nowrap">
+ <a href="sql.php" data-post="{{ url_query|raw }}&amp;sql_query=
+ {{- ('SELECT COUNT(*) AS ' ~ backquote('Rows'|trans)
+ ~ ', ' ~ backquote(row['Field'])
+ ~ ' FROM ' ~ backquote(table)
+ ~ ' GROUP BY ' ~ backquote(row['Field'])
+ ~ ' ORDER BY ' ~ backquote(row['Field']))|url_encode -}}
+ &amp;is_browse_distinct=1">
+ {{ titles['DistinctValues']|raw }}
+ </a>
+ </li>
+ {% if central_columns_work %}
+ <li class="browse nowrap">
+ {% if row['Field'] in central_list %}
+ <a href="#" class="central_columns remove_button">
+ {{ get_icon('centralColumns_delete', 'Remove from central columns'|trans) }}
+ </a>
+ {% else %}
+ <a href="#" class="central_columns add_button">
+ {{ get_icon('centralColumns_add', 'Add to central columns'|trans) }}
+ </a>
+ {% endif %}
+ </li>
+ {% endif %}
+ {% if hide_structure_actions %}
+ </ul>
+ </li>
+ {% endif %}
+ </ul>
+ </td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ <div class="print_ignore">
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pma_theme_image,
+ 'text_dir': text_dir,
+ 'form_name': 'fieldsForm'
+ } only %}
+
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Browse'|trans,
+ 'b_browse',
+ 'browse'
+ ) }}
+
+ {% if not tbl_is_view and not db_is_system_schema %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit change_columns_anchor ajax',
+ 'Change'|trans,
+ 'b_edit',
+ 'change'
+ ) }}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Drop'|trans,
+ 'b_drop',
+ 'drop'
+ ) }}
+
+ {% if tbl_storage_engine != 'ARCHIVE' %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Primary'|trans,
+ 'b_primary',
+ 'primary'
+ ) }}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Unique'|trans,
+ 'b_unique',
+ 'unique'
+ ) }}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Index'|trans,
+ 'b_index',
+ 'index'
+ ) }}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Fulltext'|trans,
+ 'b_ftext',
+ 'ftext'
+ ) }}
+
+ {% if tbl_storage_engine is not empty and (
+ tbl_storage_engine == 'MYISAM'
+ or tbl_storage_engine == 'ARIA'
+ or tbl_storage_engine == 'MARIA') %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Fulltext'|trans,
+ 'b_ftext',
+ 'ftext'
+ ) }}
+ {% endif %}
+
+ {% if central_columns_work %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Add to central columns'|trans,
+ 'centralColumns_add',
+ 'add_to_central_columns'
+ ) }}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Remove from central columns'|trans,
+ 'centralColumns_delete',
+ 'remove_from_central_columns'
+ ) }}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ </div>
+</form>
+<hr class="print_ignore">
+<div id="move_columns_dialog" class="hide" title="{% trans 'Move columns' %}">
+ <p>{% trans 'Move the columns by dragging them up and down.' %}</p>
+ <form action="tbl_structure.php" name="move_column_form" id="move_column_form">
+ <div>
+ {{ get_hidden_inputs(db, table) }}
+ <ul></ul>
+ </div>
+ </form>
+</div>
+{# Work on the table #}
+<div id="structure-action-links">
+ {% if tbl_is_view and not db_is_system_schema %}
+ {% set edit_view_url = 'view_create.php' ~ edit_view_url %}
+ {{ link_or_button(
+ edit_view_url,
+ get_icon('b_edit', 'Edit view'|trans, true)
+ ) }}
+ {% endif %}
+ <a href="#" id="printView">{{ get_icon('b_print', 'Print'|trans, true) }}</a>
+ {% if not tbl_is_view and not db_is_system_schema %}
+ {# Only display propose table structure for MySQL < 8.0 #}
+ {% if mysql_int_version < 80000 or is_mariadb %}
+ <a href="sql.php" data-post="{{ url_query|raw }}&amp;session_max_rows=all&amp;sql_query=
+ {{- ('SELECT * FROM ' ~ backquote(table) ~ ' PROCEDURE ANALYSE()')|url_encode -}}
+ " style="margin-right: 0;">
+ {{ get_icon(
+ 'b_tblanalyse',
+ 'Propose table structure'|trans,
+ true
+ ) }}
+ </a>
+ {{ show_mysql_docu('procedure_analyse') }}
+ {% endif %}
+ {% if is_active %}
+ <a href="tbl_tracking.php{{ url_query|raw }}">
+ {{ get_icon('eye', 'Track table'|trans, true) }}
+ </a>
+ {% endif %}
+ <a href="#" id="move_columns_anchor">
+ {{ get_icon('b_move', 'Move columns'|trans, true) }}
+ </a>
+ <a href="normalization.php{{ url_query|raw }}">
+ {{ get_icon('normalize', 'Normalize'|trans, true) }}
+ </a>
+ {% endif %}
+ {% if tbl_is_view and not db_is_system_schema %}
+ {% if is_active %}
+ <a href="tbl_tracking.php{{ url_query|raw }}">
+ {{ get_icon('eye', 'Track view'|trans, true) }}
+ </a>
+ {% endif %}
+ {% endif %}
+</div>
+{% if not tbl_is_view and not db_is_system_schema %}
+ <form method="post" action="tbl_addfield.php" id="addColumns" name="addColumns">
+ {{ get_hidden_inputs(db, table) }}
+ {% if show_icons('ActionLinksMode') %}
+ {{ get_image('b_insrow', 'Add column'|trans) }}&nbsp;
+ {% endif %}
+ {% set num_fields -%}
+ <input type="number" name="num_fields" value="1" onfocus="this.select()" min="1" required>
+ {%- endset %}
+ {{ 'Add %s column(s)'|trans|format(num_fields)|raw }}
+ <input type="hidden" name="field_where" value="after">&nbsp;
+ {# I tried displaying the drop-down inside the label but with Firefox the drop-down was blinking #}
+ <select name="after_field">
+ <option value="first" data-pos="first">
+ {% trans 'at beginning of table' %}
+ </option>
+ {% for one_column_name in columns_list %}
+ <option value="{{ one_column_name }}"
+ {{- loop.revindex0 == 0 ? ' selected="selected"' }}>
+ {{ 'after %s'|trans|format(one_column_name) }}
+ </option>
+ {% endfor %}
+ </select>
+ <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
+ </form>
+{% endif %}
+
+{# Displays indexes #}
+{% if not tbl_is_view and not db_is_system_schema
+ and 'ARCHIVE' != tbl_storage_engine %}
+ {{ displayIndexesHtml|raw }}
+{% endif %}
+
+{# Display partition details #}
+{% if have_partitioning %}
+ {# Detect partitioning #}
+ {% if partition_names is not empty and partition_names[0] is not null %}
+ {% set first_partition = partitions[0] %}
+ {% set range_or_list = first_partition.getMethod() == 'RANGE'
+ or first_partition.getMethod() == 'RANGE COLUMNS'
+ or first_partition.getMethod() == 'LIST'
+ or first_partition.getMethod() == 'LIST COLUMNS' %}
+ {% set sub_partitions = first_partition.getSubPartitions() %}
+ {% set has_sub_partitions = first_partition.hasSubPartitions() %}
+ {% if has_sub_partitions %}
+ {% set first_sub_partition = sub_partitions[0] %}
+ {% endif %}
+
+ {% set action_icons = {
+ 'ANALYZE': get_icon('b_search', 'Analyze'|trans),
+ 'CHECK': get_icon('eye', 'Check'|trans),
+ 'OPTIMIZE': get_icon('normalize', 'Optimize'|trans),
+ 'REBUILD': get_icon('s_tbl', 'Rebuild'|trans),
+ 'REPAIR': get_icon('b_tblops', 'Repair'|trans),
+ 'TRUNCATE': get_icon('b_empty', 'Truncate'|trans),
+ } %}
+ {% if range_or_list %}
+ {% set action_icons = action_icons|merge({'DROP': get_icon('b_drop', 'Drop'|trans)}) %}
+ {% endif %}
+
+ {# open Slider Effect div #}
+ {% include 'div_for_slider_effect.twig' with {
+ 'id': 'partitions-2',
+ 'message': 'Partitions'|trans,
+ 'initial_sliders_state': default_sliders_state
+ } only %}
+
+ {% set remove_sql = 'ALTER TABLE ' ~ backquote(table) ~ ' REMOVE PARTITIONING' %}
+ {% set remove_url = 'sql.php' ~ url_query ~ '&sql_query=' ~ remove_sql|url_encode %}
+
+ {% include 'table/structure/display_partitions.twig' with {
+ 'db': db,
+ 'table': table,
+ 'url_query': url_query,
+ 'partitions': partitions,
+ 'partition_method': first_partition.getMethod(),
+ 'partition_expression': first_partition.getExpression(),
+ 'has_description': first_partition.getDescription() is not empty,
+ 'has_sub_partitions': has_sub_partitions,
+ 'sub_partition_method': has_sub_partitions ? first_sub_partition.getMethod(),
+ 'sub_partition_expression': has_sub_partitions ? first_sub_partition.getExpression(),
+ 'action_icons': action_icons,
+ 'range_or_list': range_or_list,
+ 'remove_url': remove_url
+ } only %}
+ {% else %}
+ {% include 'table/structure/display_partitions.twig' with {
+ 'db': db,
+ 'table': table
+ } only %}
+ {% endif %}
+ {# For closing Slider effect div #}
+ </div>
+{% endif %}
+
+{# Displays Space usage and row statistics #}
+{% if show_stats %}
+ {{ table_stats|raw }}
+{% endif %}
+<div class="clearfloat"></div>
+{% endblock %}
diff --git a/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig b/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig
new file mode 100644
index 0000000..01c74ae
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig
@@ -0,0 +1,169 @@
+<div id="tablestatistics">
+ <fieldset>
+ <legend>{% trans 'Information' %}</legend>
+ {% if showtable['TABLE_COMMENT'] %}
+ <p>
+ <strong>{% trans 'Table comments:' %}</strong>
+ {{ showtable['TABLE_COMMENT'] }}
+ </p>
+ {% endif %}
+ <a id="showusage"></a>
+
+ {% if not tbl_is_view and not db_is_system_schema %}
+ <table id="tablespaceusage" class="width100 data">
+ <caption class="tblHeaders">{% trans 'Space usage' %}</caption>
+ <tbody>
+ <tr>
+ <th class="name">{% trans 'Data' %}</th>
+ <td class="value">{{ data_size }}</td>
+ <td class="unit">{{ data_unit }}</td>
+ </tr>
+
+ {% if index_size is defined %}
+ <tr>
+ <th class="name">{% trans 'Index' %}</th>
+ <td class="value">{{ index_size }}</td>
+ <td class="unit">{{ index_unit }}</td>
+ </tr>
+ {% endif %}
+
+ {% if free_size is defined %}
+ <tr>
+ <th class="name">{% trans 'Overhead' %}</th>
+ <td class="value">{{ free_size }}</td>
+ <td class="unit">{{ free_unit }}</td>
+ </tr>
+ <tr>
+ <th class="name">{% trans 'Effective' %}</th>
+ <td class="value">{{ effect_size }}</td>
+ <td class="unit">{{ effect_unit }}</td>
+ </tr>
+ {% endif %}
+
+ {% if tot_size is defined and mergetable == false %}
+ <tr>
+ <th class="name">{% trans 'Total' %}</th>
+ <td class="value">{{ tot_size }}</td>
+ <td class="unit">{{ tot_unit }}</td>
+ </tr>
+ {% endif %}
+
+ {# Optimize link if overhead #}
+ {% if free_size is defined
+ and (tbl_storage_engine == 'MYISAM'
+ or tbl_storage_engine == 'ARIA'
+ or tbl_storage_engine == 'MARIA'
+ or tbl_storage_engine == 'BDB')
+ or (tbl_storage_engine == 'INNODB' and innodb_file_per_table == true) %}
+ <tr class="tblFooters print_ignore">
+ <td colspan="3" class="center">
+ <a href="sql.php" data-post="{{ url_query }}&amp;pos=0&amp;sql_query=
+ {{- ('OPTIMIZE TABLE ' ~ backquote(table))|url_encode }}">
+ {{ get_icon('b_tbloptimize', 'Optimize table'|trans) }}
+ </a>
+ </td>
+ </tr>
+ {% endif %}
+ </tbody>
+ </table>
+ {% endif %}
+
+ {% set avg_size = avg_size is defined ? avg_size : null %}
+ {% set avg_unit = avg_unit is defined ? avg_unit : null %}
+ <table id="tablerowstats" class="width100 data">
+ <caption class="tblHeaders">{% trans 'Row statistics' %}</caption>
+ <tbody>
+ {% if showtable['Row_format'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Format' %}</th>
+ {% if showtable['Row_format'] == 'Fixed' %}
+ <td class="value">{% trans 'static' %}</td>
+ {% elseif showtable['Row_format'] == 'Dynamic' %}
+ <td class="value">{% trans 'dynamic' %}</td>
+ {% else %}
+ <td class="value">{{ showtable['Row_format'] }}</td>
+ {% endif %}
+ </tr>
+ {% endif %}
+
+ {% if showtable['Create_options'] is not empty %}
+ <tr>
+ <th class="name">{% trans 'Options' %}</th>
+ {% if showtable['Create_options'] == 'partitioned' %}
+ <td class="value">{% trans 'partitioned' %}</td>
+ {% else %}
+ <td class="value">{{ showtable['Create_options'] }}</td>
+ {% endif %}
+ </tr>
+ {% endif %}
+
+ {% if table_collation is not empty %}
+ <tr>
+ <th class="name">{% trans 'Collation' %}</th>
+ <td class="value">
+ <dfn title="{{ table_collation.description }}">
+ {{ table_collation.name }}
+ </dfn>
+ </td>
+ </tr>
+ {% endif %}
+
+ {% if not is_innodb and showtable['Rows'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Rows' %}</th>
+ <td class="value">{{ format_number(showtable['Rows'], 0) }}</td>
+ </tr>
+ {% endif %}
+
+ {% if not is_innodb
+ and showtable['Avg_row_length'] is defined
+ and showtable['Avg_row_length'] > 0 %}
+ <tr>
+ <th class="name">{% trans 'Row length' %}</th>
+ {% set avg_row_length = format_byte_down(showtable['Avg_row_length'], 6, 1) %}
+ <td class="value">{{ avg_row_length[0] }} {{ avg_row_length[1] }}</td>
+ </tr>
+ {% endif %}
+
+ {% if not is_innodb
+ and showtable['Data_length'] is defined
+ and showtable['Rows'] is defined
+ and showtable['Rows'] > 0
+ and mergetable == false %}
+ <tr>
+ <th class="name">{% trans 'Row size' %}</th>
+ <td class="value">{{ avg_size }} {{ avg_unit }}</td>
+ </tr>
+ {% endif %}
+
+ {% if showtable['Auto_increment'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Next autoindex' %}</th>
+ <td class="value">{{ format_number(showtable['Auto_increment'], 0) }}</td>
+ </tr>
+ {% endif %}
+
+ {% if showtable['Create_time'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Creation' %}</th>
+ <td class="value">{{ localised_date(showtable['Create_time']|date('U')) }}</td>
+ </tr>
+ {% endif %}
+
+ {% if showtable['Update_time'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Last update' %}</th>
+ <td class="value">{{ localised_date(showtable['Update_time']|date('U')) }}</td>
+ </tr>
+ {% endif %}
+
+ {% if showtable['Check_time'] is defined %}
+ <tr>
+ <th class="name">{% trans 'Last check' %}</th>
+ <td class="value">{{ localised_date(showtable['Check_time']|date('U')) }}</td>
+ </tr>
+ {% endif %}
+ </tbody>
+ </table>
+ </fieldset>
+</div>
diff --git a/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig b/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig
new file mode 100644
index 0000000..7cf5e8d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig
@@ -0,0 +1,14 @@
+<form action="tbl_structure.php" method="post">
+ {{ get_hidden_inputs(db, table) }}
+ <input type="hidden" name="edit_partitioning" value="true">
+
+ <fieldset>
+ <legend>{% trans 'Edit partitioning' %}</legend>
+ {% include 'columns_definitions/partitions.twig' with {
+ 'partition_details': partition_details
+ } only %}
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input class="btn btn-primary" type="submit" name="save_partitioning" value="{% trans 'Save' %}">
+ </fieldset>
+</form>
diff --git a/srcs/phpmyadmin/templates/table/tracking/main.twig b/srcs/phpmyadmin/templates/table/tracking/main.twig
new file mode 100644
index 0000000..ff6c5c4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/tracking/main.twig
@@ -0,0 +1,132 @@
+{% if selectable_tables_num_rows > 0 %}
+ <form method="post" action="tbl_tracking.php{{ url_query|raw }}">
+ {{ get_hidden_inputs(db, table) }}
+ <select name="table" class="autosubmit">
+ {% for entry in selectable_tables_entries %}
+ <option value="{{ entry.table_name }}"
+ {{- entry.table_name == selected_table ? ' selected' }}>
+ {{ entry.db_name }}.{{ entry.table_name }}
+ {% if entry.is_tracked %}
+ ({% trans 'active' %})
+ {% else %}
+ ({% trans 'not active' %})
+ {% endif %}
+ </option>
+ {% endfor %}
+ </select>
+ <input type="hidden" name="show_versions_submit" value="1">
+ </form>
+{% endif %}
+<br>
+{% if last_version > 0 %}
+ <form method="post" action="tbl_tracking.php" name="versionsForm" id="versionsForm" class="ajax">
+ {{ get_hidden_inputs(db, table) }}
+ <table id="versions" class="data">
+ <thead>
+ <tr>
+ <th></th>
+ <th>{% trans 'Version' %}</th>
+ <th>{% trans 'Created' %}</th>
+ <th>{% trans 'Updated' %}</th>
+ <th>{% trans 'Status' %}</th>
+ <th>{% trans 'Action' %}</th>
+ <th>{% trans 'Show' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for version in versions %}
+ <tr>
+ <td class="center">
+ <input type="checkbox" name="selected_versions[]"
+ class="checkall" id="selected_versions_{{- version['version']|escape }}"
+ value="{{- version['version']|escape }}">
+ </td>
+ <td class="floatright">
+ <label for="selected_versions_{{- version['version']|escape }}">
+ <b>{{ version['version']|escape }}</b>
+ </label>
+ </td>
+ <td>{{ version['date_created']|escape }}</td>
+ <td>{{ version['date_updated']|escape }}</td>
+ {% if version['tracking_active'] == 1 %}
+ {% set last_version_status = 1 %}
+ <td>{% trans 'active' %}</td>
+ {% else %}
+ {% set last_version_status = 0 %}
+ <td>{% trans 'not active' %}</td>
+ {% endif %}
+ <td>
+ <a class="delete_version_anchor ajax" href="tbl_tracking.php" data-post="
+ {{- get_common(url_params|merge({
+ 'version': version['version'],
+ 'submit_delete_version': true
+ }), '') }}">
+ {{ get_icon('b_drop', 'Delete version'|trans) }}
+ </a>
+ </td>
+ <td>
+ <a href="tbl_tracking.php" data-post="
+ {{- get_common(url_params|merge({
+ 'version': version['version'],
+ 'report': 'true'
+ }), '') }}">
+ {{ get_icon('b_report', 'Tracking report'|trans) }}
+ </a>
+ <a href="tbl_tracking.php" data-post="
+ {{- get_common(url_params|merge({
+ 'version': version['version'],
+ 'snapshot': 'true'
+ }), '') }}">
+ {{ get_icon('b_props', 'Structure snapshot'|trans) }}
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% include 'select_all.twig' with {
+ 'pma_theme_image': pmaThemeImage,
+ 'text_dir': text_dir,
+ 'form_name': 'versionsForm',
+ } only %}
+ {{ get_button_or_image(
+ 'submit_mult',
+ 'mult_submit',
+ 'Delete version'|trans,
+ 'b_drop',
+ 'delete_version'
+ ) }}
+ </form>
+ {% set last_version_element = versions|first %}
+ <div>
+ <form method="post" action="tbl_tracking.php{{ url_query|raw }}">
+ {{ get_hidden_inputs(db, table) }}
+ <fieldset>
+ <legend>
+ {% if last_version_element['tracking_active'] == 0 %}
+ {% set legend = 'Activate tracking for %s'|trans %}
+ {% set value = 'activate_now' %}
+ {% set button = 'Activate now'|trans %}
+ {% else %}
+ {% set legend = 'Deactivate tracking for %s'|trans %}
+ {% set value = 'deactivate_now' %}
+ {% set button = 'Deactivate now'|trans %}
+ {% endif %}
+
+ {{ legend|format(db ~ '.' ~ table) }}
+ </legend>
+ <input type="hidden" name="version" value="{{ last_version }}">
+ <input type="hidden" name="toggle_activation" value="{{ value }}">
+ <input class="btn btn-secondary" type="submit" value="{{ button }}">
+ </fieldset>
+ </form>
+ </div>
+{% endif %}
+{% include 'create_tracking_version.twig' with {
+ 'url_query': url_query,
+ 'last_version': last_version,
+ 'db': db,
+ 'selected': [table],
+ 'type': type,
+ 'default_statements': default_statements,
+} only %}
diff --git a/srcs/phpmyadmin/templates/table/tracking/report_table.twig b/srcs/phpmyadmin/templates/table/tracking/report_table.twig
new file mode 100644
index 0000000..fe00526
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/tracking/report_table.twig
@@ -0,0 +1,27 @@
+<table id="{{ table_id }}" class="data">
+ <thead>
+ <tr>
+ <th>{% trans %}#{% context %}Number{% endtrans %}</th>
+ <th>{% trans 'Date' %}</th>
+ <th>{% trans 'Username' %}</th>
+ <th>{{ header_message }}</th>
+ <th>{% trans 'Action' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for entry in entries %}
+ <tr class="noclick">
+ <td class="right"><small>{{ entry.line_number }}</small></td>
+ <td><small>{{ entry.date }}</small></td>
+ <td><small>{{ entry.username }}</small></td>
+ <td>{{ entry.formated_statement|raw }}</td>
+ <td class="nowrap">
+ <a class="delete_entry_anchor ajax" href="tbl_tracking.php" data-post="
+ {{- entry.url_params|raw }}">
+ {{ drop_image_or_text|raw }}
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig
new file mode 100644
index 0000000..4ef8c21
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig
@@ -0,0 +1,56 @@
+<h3>{% trans 'Structure' %}</h3>
+<table id="tablestructure" class="data">
+ <thead>
+ <tr>
+ <th>{% trans %}#{% context %}Number{% endtrans %}</th>
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Type' %}</th>
+ <th>{% trans 'Collation' %}</th>
+ <th>{% trans 'Null' %}</th>
+ <th>{% trans 'Default' %}</th>
+ <th>{% trans 'Extra' %}</th>
+ <th>{% trans 'Comment' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% set index = 1 %}
+ {% for field in columns %}
+ <tr class="noclick">
+ <td>{{ index }}</td>
+ {% set index = index + 1 %}
+ <td>
+ <strong>
+ {{ field['Field'] }}
+ {% if field['Key'] == 'PRI' %}
+ {{ get_image('b_primary', 'Primary'|trans) }}
+ {% elseif field['Key'] is not empty %}
+ {{ get_image('bd_primary', 'Index'|trans) }}
+ {% endif %}
+ </strong>
+ </td>
+ <td>{{ field['Type'] }}</td>
+ <td>{{ field['Collation'] }}</td>
+ <td>{{ field['Null'] == 'YES' ? 'Yes'|trans : 'No'|trans }}</td>
+ <td>
+ {% if field['Default'] is defined %}
+ {% set extracted_columnspec = extract_column_spec(field['Type']) %}
+ {% if extracted_columnspec['type'] == 'bit' %}
+ {# here, $field['Default'] contains something like b'010' #}
+ {{ field['Default']|convert_bit_default_value }}
+ {% else %}
+ {{ field['Default'] }}
+ {% endif %}
+ {% else %}
+ {% if field['Null'] == 'YES' %}
+ <em>NULL</em>
+ {% else %}
+ <em>{% trans %}None{% context %}None for default{% endtrans %}</em>
+ {% endif %}
+ {% endif %}
+ </td>
+ <td>{{ field['Extra'] }}</td>
+ <td>{{ field['Comment'] }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig
new file mode 100644
index 0000000..a919252
--- /dev/null
+++ b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig
@@ -0,0 +1,33 @@
+<h3>{% trans 'Indexes' %}</h3>
+<table id="tablestructure_indexes" class="data">
+ <thead>
+ <tr>
+ <th>{% trans 'Keyname' %}</th>
+ <th>{% trans 'Type' %}</th>
+ <th>{% trans 'Unique' %}</th>
+ <th>{% trans 'Packed' %}</th>
+ <th>{% trans 'Column' %}</th>
+ <th>{% trans 'Cardinality' %}</th>
+ <th>{% trans 'Collation' %}</th>
+ <th>{% trans 'Null' %}</th>
+ <th>{% trans 'Comment' %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for index in indexes %}
+ <tr class="noclick">
+ <td>
+ <strong>{{ index['Key_name'] }}</strong>
+ </td>
+ <td>{{ index['Index_type'] }}</td>
+ <td>{{ index['Non_unique'] == 0 ? 'Yes'|trans : 'No'|trans }}</td>
+ <td>{{ index['Packed'] != '' ? 'Yes'|trans : 'No'|trans }}</td>
+ <td>{{ index['Column_name'] }}</td>
+ <td>{{ index['Cardinality'] }}</td>
+ <td>{{ index['Collation'] }}</td>
+ <td>{{ index['Null'] }}</td>
+ <td>{{ index['Comment'] }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/test/add_data.twig b/srcs/phpmyadmin/templates/test/add_data.twig
new file mode 100644
index 0000000..d562612
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/add_data.twig
@@ -0,0 +1,2 @@
+{{ variable1 }}
+{{ variable2 }}
diff --git a/srcs/phpmyadmin/templates/test/echo.twig b/srcs/phpmyadmin/templates/test/echo.twig
new file mode 100644
index 0000000..9c5fc60
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/echo.twig
@@ -0,0 +1 @@
+{{ variable -}}
diff --git a/srcs/phpmyadmin/templates/test/gettext/gettext.twig b/srcs/phpmyadmin/templates/test/gettext/gettext.twig
new file mode 100644
index 0000000..4fcf61b
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/gettext/gettext.twig
@@ -0,0 +1 @@
+{% trans "Text" %}
diff --git a/srcs/phpmyadmin/templates/test/gettext/notes.twig b/srcs/phpmyadmin/templates/test/gettext/notes.twig
new file mode 100644
index 0000000..e5a38e4
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/gettext/notes.twig
@@ -0,0 +1,5 @@
+{% trans %}
+Text
+{% notes %}
+Notes
+{% endtrans %}
diff --git a/srcs/phpmyadmin/templates/test/gettext/pgettext.twig b/srcs/phpmyadmin/templates/test/gettext/pgettext.twig
new file mode 100644
index 0000000..5365027
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/gettext/pgettext.twig
@@ -0,0 +1,5 @@
+{% trans %}
+Text
+{% context %}
+Text context
+{% endtrans %}
diff --git a/srcs/phpmyadmin/templates/test/gettext/plural.twig b/srcs/phpmyadmin/templates/test/gettext/plural.twig
new file mode 100644
index 0000000..5bc44e9
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/gettext/plural.twig
@@ -0,0 +1,5 @@
+{% trans %}
+One table
+{% plural table_count %}
+{{ count }} tables
+{% endtrans %}
diff --git a/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig b/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig
new file mode 100644
index 0000000..0c6da18
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig
@@ -0,0 +1,7 @@
+{% trans %}
+One table
+{% plural table_count %}
+{{ count }} tables
+{% notes %}
+Number of tables
+{% endtrans %}
diff --git a/srcs/phpmyadmin/templates/test/static.twig b/srcs/phpmyadmin/templates/test/static.twig
new file mode 100644
index 0000000..703390d
--- /dev/null
+++ b/srcs/phpmyadmin/templates/test/static.twig
@@ -0,0 +1 @@
+static content \ No newline at end of file
diff --git a/srcs/phpmyadmin/templates/theme_preview.twig b/srcs/phpmyadmin/templates/theme_preview.twig
new file mode 100644
index 0000000..f8308ff
--- /dev/null
+++ b/srcs/phpmyadmin/templates/theme_preview.twig
@@ -0,0 +1,16 @@
+<div class="theme_preview">
+ <h2>
+ {{ name }} ({{ version }})
+ </h2>
+ <p>
+ <a class="take_theme" name="{{ id }}" href="index.php{{ get_common(url_params) }}">
+ {% if screen is not empty %}
+ <img src="{{ screen }}" alt="{{ name }}" title="{{ name }}">
+ <br>
+ {% else %}
+ {% trans 'No preview available.' %}
+ {% endif %}
+ [ <strong>{% trans 'Take it' %}</strong> ]
+ </a>
+ </p>
+</div>
diff --git a/srcs/phpmyadmin/templates/themes.twig b/srcs/phpmyadmin/templates/themes.twig
new file mode 100644
index 0000000..c03089c
--- /dev/null
+++ b/srcs/phpmyadmin/templates/themes.twig
@@ -0,0 +1,7 @@
+<h1>phpMyAdmin - {% trans 'Theme' %}</h1>
+<p>
+ <a href="{{ 'https://www.phpmyadmin.net/themes/'|link }}#pma_{{ version }}" rel="noopener noreferrer" target="_blank">
+ {% trans 'Get more themes!' %}
+ </a>
+</p>
+{{ previews|raw }}
diff --git a/srcs/phpmyadmin/templates/toggle_button.twig b/srcs/phpmyadmin/templates/toggle_button.twig
new file mode 100644
index 0000000..85a8320
--- /dev/null
+++ b/srcs/phpmyadmin/templates/toggle_button.twig
@@ -0,0 +1,24 @@
+<div class='wrapper toggleAjax hide'>
+ <div class='toggleButton'>
+ <div title="{% trans 'Click to toggle' %}" class='container {{ state }}'>
+ <img src="{{ pma_theme_image }}toggle-{{ text_dir }}.png">
+ <table class='nospacing nopadding'>
+ <tbody>
+ <tr>
+ <td class='toggleOn'>
+ <span class='hide'>{{ link_on|raw }}</span>
+ <div>{{ toggle_on }}</div>
+ </td>
+ <td><div>&nbsp;</div></td>
+ <td class='toggleOff'>
+ <span class='hide'>{{ link_off|raw }}</span>
+ <div>{{ toggle_off }}</div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <span class='hide callback'>{{ callback }}</span>
+ <span class='hide text_direction'>{{ text_dir }}</span>
+ </div>
+ </div>
+</div>
diff --git a/srcs/phpmyadmin/templates/transformation_overview.twig b/srcs/phpmyadmin/templates/transformation_overview.twig
new file mode 100644
index 0000000..d6690fa
--- /dev/null
+++ b/srcs/phpmyadmin/templates/transformation_overview.twig
@@ -0,0 +1,49 @@
+<h2>{% trans 'Available media (MIME) types' %}</h2>
+
+<ul>
+ {% for mime_type in mime_types %}
+ <li>
+ {{ mime_type.is_empty ? '<em>' }}
+ {{ mime_type.name }}
+ {{ mime_type.is_empty ? '</em>' }}
+ </li>
+ {% endfor %}
+</ul>
+
+<h2 id="transformation">{% trans 'Available browser display transformations' %}</h2>
+
+<table>
+ <thead>
+ <tr>
+ <th>{% trans 'Browser display transformation' %}</th>
+ <th>{% trans %}Description{% context %}for media (MIME) type transformation{% endtrans %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for transformation in transformations.transformation %}
+ <tr>
+ <td>{{ transformation.name }}</td>
+ <td>{{ transformation.description }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+<h2 id="input_transformation">{% trans 'Available input transformations' %}</h2>
+
+<table>
+ <thead>
+ <tr>
+ <th>{% trans 'Input transformation' %}</th>
+ <th>{% trans %}Description{% context %}for media (MIME) type transformation{% endtrans %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for transformation in transformations.input_transformation %}
+ <tr>
+ <td>{{ transformation.name }}</td>
+ <td>{{ transformation.description }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
diff --git a/srcs/phpmyadmin/templates/view_create.twig b/srcs/phpmyadmin/templates/view_create.twig
new file mode 100644
index 0000000..857762f
--- /dev/null
+++ b/srcs/phpmyadmin/templates/view_create.twig
@@ -0,0 +1,120 @@
+<!-- CREATE VIEW options -->
+<div id="div_view_options">
+ <form method="post" action="view_create.php">
+ {{ get_hidden_inputs(url_params) }}
+ <fieldset>
+ <legend>
+ {% if ajax_dialog %}
+ {% trans 'Details' %}
+ {% else %}
+ {% if view['operation'] == 'create' %}
+ {% trans 'Create view' %}
+ {% else %}
+ {% trans 'Edit view' %}
+ {% endif %}
+ {% endif %}
+ </legend>
+ <table class="rte_table">
+ {% if view['operation'] == 'create' %}
+ <tr>
+ <td class="nowrap"><label for="or_replace">OR REPLACE</label></td>
+ <td>
+ <input type="checkbox" name="view[or_replace]" id="or_replace"
+ {% if (view['or_replace']) %} checked="checked" {% endif %}
+ value="1">
+ </td>
+ </tr>
+ {% endif %}
+
+ <tr>
+ <td class="nowrap"><label for="algorithm">ALGORITHM</label></td>
+ <td>
+ <select name="view[algorithm]" id="algorithm">
+ {% for option in view_algorithm_options %}
+ <option value="{{ option }}"
+ {% if view['algorithm'] == option %}
+ selected="selected"
+ {% endif %}
+ >{{ option }}</option>
+ {% endfor %}
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="nowrap">{% trans 'Definer' %}</td>
+ <td><input type="text" maxlength="100" size="50" name="view[definer]" value="{{ view['definer'] }}"></td>
+ </tr>
+
+ <tr>
+ <td class="nowrap">SQL SECURITY</td>
+ <td>
+ <select name="view[sql_security]">
+ <option value=""></option>
+ {% for option in view_security_options %}
+ <option value="{{ option }}"
+ {% if option == view['sql_security'] %} selected="selected" {% endif %}
+ >{{ option }}</option>
+ {% endfor %}
+ </select>
+ </td>
+ </tr>
+
+ {% if view['operation'] == 'create' %}
+ <tr>
+ <td class="nowrap">{% trans 'VIEW name' %}</td>
+ <td>
+ <input type="text" size="20" name="view[name]" onfocus="this.select()" maxlength="64" value="{{ view['name'] }}">
+ </td>
+ </tr>
+ {% else %}
+ <tr>
+ <td>
+ <input type="hidden" name="view[name]" value="{{ view['name'] }}">
+ </td>
+ </tr>
+ {% endif %}
+
+ <tr>
+ <td class="nowrap">{% trans 'Column names' %}</td>
+ <td>
+ <input type="text" maxlength="100" size="50" name="view[column_names]" onfocus="this.select()" value="{{ view['column_names'] }}">
+ </td>
+ </tr>
+
+ <tr>
+ <td class="nowrap">AS</td>
+ <td>
+ <textarea name="view[as]" rows="15" cols="40" dir="{{ text_dir }}" onclick="Functions.selectContent(this, sqlBoxLocked, true)">{{ view['as'] }}</textarea><br>
+ <input type="button" value="Format" id="format" class="btn btn-secondary button sqlbutton">
+ <span id="querymessage"></span>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="nowrap">WITH CHECK OPTION</td>
+ <td>
+ <select name="view[with]">
+ <option value=""></option>
+ {% for option in view_with_options %}
+ <option value="{{ option }}"
+ {% if option == view['with'] %} selected="selected" {% endif %}
+ >{{ option }}</option>
+ {% endfor %}
+ </select>
+ </td>
+ </tr>
+
+ </table>
+ </fieldset>
+
+ <input type="hidden" name="ajax_request" value="1" />
+ <input type="hidden" name="{{ (view['operation'] == 'create') ? 'createview' : 'alterview' }}" value="1" />
+
+ {% if ajax_dialog == false %}
+ <input type="hidden" name="ajax_dialog" value="1" />
+ <input type="submit" name="" value="{% trans 'Go' %}" />
+ {% endif %}
+
+ </form>
+</div>