Update website

This commit is contained in:
Guilhem Lavaux 2024-11-23 20:45:29 +01:00
parent 41ce1aa076
commit ea0eb1c6e0
4222 changed files with 721797 additions and 14 deletions

View file

@ -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">
<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>

View file

@ -0,0 +1,22 @@
{% if submit_attribute is defined and submit_attribute != false %}
{% set attribute = submit_attribute %}
{# MariaDB has additional parentheses #}
{% elseif column_meta['Extra'] is defined
and ('on update current_timestamp' in column_meta['Extra'] or 'on update current_timestamp()' in column_meta['Extra']|lower) %}
{% 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>

View file

@ -0,0 +1,259 @@
{# 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="text-center">
{# column name #}
{% include 'columns_definitions/column_name.twig' with {
'column_number': column_number,
'ci': ci,
'ci_offset': ci_offset,
'column_meta': column_meta,
'has_central_columns_feature': relation_parameters.centralColumnsFeature is not null,
'max_rows': max_rows
} only %}
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<select class="column_type" name="field_type[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}"
{{- column_meta['column_status'] is defined and not column_meta['column_status']['isEditable'] ? ' disabled' }}>
{{ get_supported_datatypes(true, type_upper) }}
</select>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<input id="field_{{ column_number }}_{{ ci - ci_offset }}" type="text" name="field_length[{{ column_number }}]" size="
{{- length_values_input_size }}" value="{{ length }}" 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>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<select name="field_default_type[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}" class="default_type">
<option value="NONE"{{ column_meta['DefaultType'] is defined and column_meta['DefaultType'] == 'NONE' ? ' selected' }}>
{% trans %}None{% context %}for default{% endtrans %}
</option>
<option value="USER_DEFINED"{{ column_meta['DefaultType'] is defined and column_meta['DefaultType'] == 'USER_DEFINED' ? ' selected' }}>
{% trans 'As defined:' %}
</option>
<option value="NULL"{{ column_meta['DefaultType'] is defined and column_meta['DefaultType'] == 'NULL' ? ' selected' }}>
NULL
</option>
<option value="CURRENT_TIMESTAMP"{{ column_meta['DefaultType'] is defined and column_meta['DefaultType'] == 'CURRENT_TIMESTAMP' ? ' selected' }}>
CURRENT_TIMESTAMP
</option>
{% if is_uuid_supported() %}
<option value="UUID"{{ column_meta['DefaultType'] is defined and column_meta['DefaultType'] == 'UUID' ? ' selected' }}>
UUID
</option>
{% endif %}
</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 %}
{% set ci = ci + 1 %}
</td>
<td class="text-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="text-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="text-center">
<input name="field_null[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}" type="checkbox" value="YES" class="allow_null"
{{- column_meta['Null'] is not empty and column_meta['Null'] != 'NO' and column_meta['Null'] != 'NOT NULL' ? ' checked' }}>
{% 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="text-center">
<input name="field_adjust_privileges[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}" type="checkbox" value="NULL" class="allow_null"
{%- if privs_available %} checked>
{%- else %} title="{% trans "You don't have sufficient privileges to perform this operation; Please refer to the documentation for more details" %}" disabled>
{%- endif %}
{% set ci = ci + 1 %}
</td>
{% endif %}
{% if not is_backup %}
{# column indexes, See my other comment about this 'if'. #}
<td class="text-center">
<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' }}>
PRIMARY
</option>
<option value="unique_{{ column_number }}" title="{% trans "Unique" %}"
{{- column_meta['Key'] is defined and column_meta['Key'] == 'UNI' ? ' selected' }}>
UNIQUE
</option>
<option value="index_{{ column_number }}" title="{% trans "Index" %}"
{{- column_meta['Key'] is defined and column_meta['Key'] == 'MUL' ? ' selected' }}>
INDEX
</option>
<option value="fulltext_{{ column_number }}" title="{% trans "Fulltext" %}"
{{- column_meta['Key'] is defined and column_meta['Key'] == 'FULLTEXT' ? ' selected' }}>
FULLTEXT
</option>
<option value="spatial_{{ column_number }}" title="{% trans "Spatial" %}"
{{- column_meta['Key'] is defined and column_meta['Key'] == 'SPATIAL' ? ' selected' }}>
SPATIAL
</option>
</select>
{% set ci = ci + 1 %}
</td>
{% endif %}
<td class="text-center">
<input name="field_extra[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}" type="checkbox" value="AUTO_INCREMENT"
{{- column_meta['Extra'] is defined and column_meta['Extra']|lower == 'auto_increment' ? ' checked' }}>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<textarea id="field_{{ column_number }}_{{ ci - ci_offset }}" rows="1" name="field_comments[{{ column_number }}]" maxlength="{{ max_length }}">
{{- column_meta['Field'] is defined and comments_map is iterable and comments_map[column_meta['Field']] is defined ? comments_map[column_meta['Field']] -}}
</textarea>
{% set ci = ci + 1 %}
</td>
{# column virtuality #}
{% if is_virtual_columns_supported %}
<td class="text-center">
<select name="field_virtuality[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}" class="virtuality">
{% for key, value in options %}
{% set virtuality = column_meta['Extra'] is defined ? column_meta['Extra'] : null %}
{# Creating a new row on create table sends a Virtuality field #}
{% set virtuality = column_meta['Virtuality'] is defined ? column_meta['Virtuality'] : virtuality %}
<option value="{{ key }}"{{ virtuality is not null and key != '' and virtuality|slice(0, key|length) is same as (key) ? ' selected' }}>
{{ value }}
</option>
{% endfor %}
</select>
{% if char_editing == 'textarea' %}
<textarea name="field_expression[{{ column_number }}]" cols="15" class="textfield expression">{{ column_meta['Expression'] is defined ? column_meta['Expression'] }}</textarea>
{% else %}
<input type="text" name="field_expression[{{ column_number }}]" size="12" value="{{ column_meta['Expression'] is defined ? column_meta['Expression'] }}" placeholder="{% trans 'Expression' %}" class="textfield expression">
{% endif %}
{% 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="text-center">
<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' }}>
{{ 'after %s'|trans|format(backquote(move_columns[mi].name|e)) }}
</option>
{% endfor %}
</select>
{% set ci = ci + 1 %}
</td>
{% endif %}
{% if relation_parameters.browserTransformationFeature is not null and relation_parameters.columnCommentsFeature is not null and browse_mime %}
<td class="text-center">
<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 media_type in available_mime['mimetype'] %}
<option value="{{ media_type|replace({'/': '_'}) }}"
{{- column_meta['Field'] is defined and mime_map[column_meta['Field']]['mimetype'] is defined
and mime_map[column_meta['Field']]['mimetype'] == media_type|replace({'/': '_'}) ? ' selected' }}>
{{ media_type|lower }}
</option>
{% endfor %}
{% endif %}
</select>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<select id="field_{{ column_number }}_{{ ci - ci_offset }}" size="1" name="field_transformation[{{ column_number }}]">
<option value="" title="{% trans 'None' %}"></option>
{% if available_mime['transformation'] is defined and available_mime['transformation'] is iterable %}
{% for mimekey, transform in available_mime['transformation'] %}
{% set parts = transform|split(':') %}
<option value="{{ available_mime['transformation_file'][mimekey] }}" title="{{ get_description(available_mime['transformation_file'][mimekey]) }}"
{{- column_meta['Field'] is defined
and mime_map[column_meta['Field']]['transformation'] is defined
and mime_map[column_meta['Field']]['transformation'] is not null
and mime_map[column_meta['Field']]['transformation'] matches '@' ~ available_mime['transformation_file_quoted'][mimekey] ~ '3?@i' ? ' selected'}}>
{{ get_name(available_mime['transformation_file'][mimekey]) ~ ' (' ~ parts[0]|lower ~ ':' ~ parts[1] ~ ')' }}
</option>
{% endfor %}
{% endif %}
</select>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<input id="field_{{ column_number }}_{{ ci - ci_offset }}" type="text" name="field_transformation_options[{{ column_number }}]" size="16" class="textfield" value="
{{- column_meta['Field'] is defined and mime_map[column_meta['Field']]['transformation_options'] is defined ? mime_map[column_meta['Field']]['transformation_options'] }}">
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<select id="field_{{ column_number }}_{{ ci - ci_offset }}" size="1" name="field_input_transformation[{{ column_number }}]">
<option value="" title="{% trans 'None' %}"></option>
{% if available_mime['input_transformation'] is defined and available_mime['input_transformation'] is iterable %}
{% for mimekey, transform in available_mime['input_transformation'] %}
{% set parts = transform|split(':') %}
<option value="{{ available_mime['input_transformation_file'][mimekey] }}" title="{{ get_description(available_mime['input_transformation_file'][mimekey]) }}"
{{- column_meta['Field'] is defined and mime_map[column_meta['Field']]['input_transformation'] is defined
and mime_map[column_meta['Field']]['input_transformation'] matches '@' ~ available_mime['input_transformation_file_quoted'][mimekey] ~ '3?@i' ? ' selected' }}>
{{ get_name(available_mime['input_transformation_file'][mimekey]) ~ ' (' ~ parts[0]|lower ~ ':' ~ parts[1] ~ ')' }}
</option>
{% endfor %}
{% endif %}
</select>
{% set ci = ci + 1 %}
</td>
<td class="text-center">
<input id="field_{{ column_number }}_{{ ci - ci_offset }}" type="text" name="field_input_transformation_options[{{ column_number }}]" size="16" class="textfield" value="
{{- column_meta['Field'] is defined and mime_map[column_meta['Field']]['input_transformation_options'] is defined ? mime_map[column_meta['Field']]['input_transformation_options'] }}">
{% set ci = ci + 1 %}
</td>
{% endif %}

View file

@ -0,0 +1,188 @@
<form method="post" action="{{ action }}" class="
{{- action == url('/table/create') ? '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 == url('/table/create') %}
<div id="table_name_col_no_outer">
<table id="table_name_col_no" class="table table-borderless tdblock">
<tr class="align-middle float-start">
<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,
'relation_parameters': relation_parameters,
'content_cells': content_cells,
'change_column': change_column,
'is_virtual_columns_supported': is_virtual_columns_supported,
'server_version' : server_version,
'browse_mime': browse_mime,
'supports_stored_keyword': supports_stored_keyword,
'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 == url('/table/create') %}
<div class="responsivetable">
<table class="table table-borderless w-auto align-middle mb-0">
<tr class="align-top">
<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 id="storage-engine-connection">
{% 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>
<select class="form-select" name="tbl_storage_engine" aria-label="{% trans 'Storage engine' %}">
{% for engine in storage_engines %}
<option value="{{ engine.name }}"{% if engine.comment is not empty %} title="{{ engine.comment }}"{% endif %}
{{- engine.name|lower == tbl_storage_engine|lower or (tbl_storage_engine is empty and engine.is_default) ? ' selected' }}>
{{- engine.name -}}
</option>
{% endfor %}
</select>
</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="align-top">
<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,
'storage_engines': storage_engines
} only %}
</td>
</tr>
{% endif %}
</table>
</div>
{% endif %}
<fieldset class="pma-fieldset tblFooters">
{% if action == url('/table/add-field') or action == url('/table/structure/save') %}
<input type="checkbox" name="online_transaction" value="ONLINE_TRANSACTION_ENABLED" />{% trans %}Online transaction{% context %}Online transaction part of the SQL DDL for InnoDB{% endtrans %}{{ show_mysql_docu('innodb-online-ddl') }}
{% endif %}
<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>
{% if is_integers_length_restricted %}
<div class="alert alert-primary" id="length_not_allowed" role="alert">
{{ get_image('s_notice') }}
{% trans %}The column width of integer types is ignored in your MySQL version unless defining a TINYINT(1) column{% endtrans %}
{{ show_mysql_docu('', false, 'https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html') }}
</div>
{% endif %}
</form>
<div class="modal fade" id="previewSqlModal" tabindex="-1" aria-labelledby="previewSqlModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="previewSqlModalLabel">{% trans 'Loading' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="previewSQLCloseButton" data-bs-dismiss="modal">{% trans 'Close' %}</button>
</div>
</div>
</div>
</div>
{# Used by add new column of type ENUM/SET #}
{{ include('modals/enum_set_editor.twig') }}

View file

@ -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 has_central_columns_feature
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 %}

View file

@ -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 class="table table-borderless w-auto align-middle mb-0" id="partition_table">
<tr class="align-middle">
<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="align-middle">
<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="align-middle">
<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="align-middle">
<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 class="table align-middle" 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="align-middle">
<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>
<select name="{{ subpartition['prefix'] }}[engine]" aria-label="{% trans 'Storage engine' %}">
<option value=""></option>
{% for engine in storage_engines %}
<option value="{{ engine.name }}"{% if engine.comment is not empty %} title="{{ engine.comment }}"{% endif %}
{{- engine.name|lower == subpartition['engine']|lower ? ' selected' }}>
{{- engine.name -}}
</option>
{% endfor %}
</select>
</td>
<td>
<textarea name="{{ subpartition['prefix'] }}[comment]">
{{- subpartition['comment'] -}}
</textarea>
</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 %}

View file

@ -0,0 +1,121 @@
<div class="responsivetable">
<table id="table_columns" class="table table-striped caption-top align-middle mb-0 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 relation_parameters.browserTransformationFeature is not null and browse_mime %}
<th>
{% trans 'Media type' %}
</th>
<th>
<a href="{{ url('/transformation/overview') }}#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="{{ url('/transformation/overview') }}#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 supports_stored_keyword %}
{% set options = options|merge({'STORED': 'STORED'}) %}
{% else %}
{% set options = options|merge({'PERSISTENT': 'PERSISTENT'}) %}
{% 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,
'relation_parameters': relation_parameters
}) only %}
</tr>
{% endfor %}
</table>
</div>

View file

@ -0,0 +1,4 @@
<div class="alert alert-danger" role="alert">
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">
{{ msg }}
</div>

View file

@ -0,0 +1,78 @@
<form method="post" action="{{ action|e('html_attr') }}" class="config-form disableAjax">
<input type="hidden" name="tab_hash" value="">
{% if has_check_page_refresh %}
<input type="hidden" name="check_page_refresh" id="check_page_refresh" value="">
{% endif %}
{{ get_hidden_inputs('', '', 0, 'server') }}
{{ get_hidden_fields(hidden_fields, '', true) }}
<ul class="nav nav-tabs" id="configFormDisplayTab" role="tablist">
{% for id, name in tabs %}
<li class="nav-item" role="presentation">
<a class="nav-link{{ loop.first ? ' active' }}" id="{{ id }}-tab" href="#{{ id }}" data-bs-toggle="tab" role="tab" aria-controls="{{ id }}" aria-selected="{{ loop.first ? 'true' : 'false' }}">{{ name }}</a>
</li>
{% endfor %}
</ul>
<div class="tab-content">
{% for form in forms %}
<div class="tab-pane fade{{ loop.first ? ' show active' }}" id="{{ form.name }}" role="tabpanel" aria-labelledby="{{ form.name }}-tab">
<div class="card border-top-0">
<div class="card-body">
<h5 class="card-title visually-hidden">{{ form.descriptions.name }}</h5>
{% if form.descriptions.desc is not empty %}
<h6 class="card-subtitle mb-2 text-muted">{{ form.descriptions.desc|raw }}</h6>
{% endif %}
<fieldset class="optbox">
<legend>{{ form.descriptions.name }}</legend>
{# This must match with displayErrors() in scripts.js #}
{% if form.errors is iterable and form.errors|length > 0 %}
<dl class="errors">
{% for error in form.errors %}
<dd>{{ error }}</dd>
{% endfor %}
</dl>
{% endif %}
<table class="table table-borderless">
{{ form.fields_html|raw }}
</table>
</fieldset>
</div>
{% if show_buttons %}
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="submit_save" value="{% trans 'Apply' %}">
<input class="btn btn-secondary" type="button" name="submit_reset" value="{% trans 'Reset' %}">
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</form>
<script type="text/javascript">
if (typeof configInlineParams === 'undefined' || !Array.isArray(configInlineParams)) {
configInlineParams = [];
}
configInlineParams.push(function () {
{{ js_array|join(';\n')|raw }};
$.extend(Messages, {
'error_nan_p': '{{ 'Not a positive number!'|trans|e('js') }}',
'error_nan_nneg': '{{ 'Not a non-negative number!'|trans|e('js') }}',
'error_incorrect_port': '{{ 'Not a valid port number!'|trans|e('js') }}',
'error_invalid_value': '{{ 'Incorrect value!'|trans|e('js') }}',
'error_value_lte': '{{ 'Value must be less than or equal to %s!'|trans|e('js') }}',
});
$.extend(defaultValues, {
{{ js_default|join(",\n ")|raw }}
});
});
if (typeof configScriptLoaded !== 'undefined' && configInlineParams) {
loadInlineConfig();
}
</script>

View file

@ -0,0 +1,6 @@
<dl>
<dt>{{ name }}</dt>
{% for error in error_list %}
<dd>{{ error|raw }}</dd>
{% endfor %}
</dl>

View file

@ -0,0 +1,5 @@
<tr class="group-header group-header-{{ group }}">
<th colspan="{{ colspan }}">
{{ header_text }}
</th>
</tr>

View file

@ -0,0 +1,85 @@
{% if option_is_disabled %}
{% set tr_class = tr_class ~ ' disabled-field' %}
{% endif %}
<tr{% if tr_class %} class="{{ tr_class }}"{% endif %}>
<th>
<label for="{{ path }}">{{ name|raw }}</label>
{% if doc is not empty %}
<span class="doc">
<a href="{{ doc }}" target="documentation">{{- get_image('b_help', 'Documentation'|trans) -}}</a>
</span>
{% endif %}
{% if option_is_disabled %}
<span class="disabled-notice" title="{% trans 'This setting is disabled, it will not be applied to your configuration.' %}">
{% trans 'Disabled' %}
</span>
{% endif %}
{% if description is not empty %}
<small>{{ description|raw }}</small>
{% endif %}
</th>
<td>
{% if type == 'text' %}
<input type="text" name="{{ path }}" id="{{ path }}" value="{{ value }}" class="w-75{{ not value_is_default ? (has_errors ? ' custom field-error' : ' custom') }}">
{% elseif type == 'password' %}
<input type="password" name="{{ path }}" id="{{ path }}" value="{{ value }}" class="w-75{{ not value_is_default ? (has_errors ? ' custom field-error' : ' custom') }}" spellcheck="false">
{% elseif type == 'short_text' and value is not iterable %}
{# https://github.com/phpmyadmin/phpmyadmin/issues/11505 #}
<input type="text" size="25" name="{{ path }}" id="{{ path }}" value="{{ value }}" class="{{ not value_is_default ? (has_errors ? 'custom field-error' : 'custom') }}">
{% elseif type == 'number_text' %}
<input type="number" name="{{ path }}" id="{{ path }}" value="{{ value }}" class="{{ not value_is_default ? (has_errors ? 'custom field-error' : 'custom') }}">
{% elseif type == 'checkbox' %}
<span class="checkbox{{ not value_is_default ? (has_errors ? ' custom field-error' : ' custom') }}">
<input type="checkbox" name="{{ path }}" id="{{ path }}"{{ value ? ' checked' }}>
</span>
{% elseif type == 'select' %}
<select name="{{ path }}" id="{{ path }}" class="w-75{{ not value_is_default ? (has_errors ? ' custom field-error' : ' custom') }}">
{% for key, val in select_values %}
{% if val is same as(true) %}{% set val = 'Yes'|trans %}{% elseif val is same as(false) %}{% set val = 'No'|trans %}{% endif %}
<option value="{{ key }}"{{ key is same as(value) or (value is same as(true) and key is same as(1)) or (value is same as(false) and key is same as(0)) ? ' selected' }}{{ key in select_values_disabled ? ' disabled' }}>{{ val }}</option>
{% endfor %}
</select>
{% elseif type == 'list' %}
<textarea cols="35" rows="5" name="{{ path }}" id="{{ path }}" class="{{ not value_is_default ? (has_errors ? 'custom field-error' : 'custom') }}">
{%- for key, val in value %}{% if key != 'wrapper_params' %}{{ val }}{{ not loop.last ? "\n" }}{% endif %}{% endfor -%}
</textarea>
{% endif %}
{% if is_setup and comment %}
<a class="userprefs-comment" title="{{ comment }}">{{ get_image('b_tblops', 'Comment'|trans) }}</a>
{% endif %}
{% if set_value %}
<a class="set-value hide" href="#{{ path }}={{ set_value }}" title="{{ 'Set value: %s'|trans|format(set_value) }}">
{{- get_image('b_edit', 'Set value: %s'|trans|format(set_value)) -}}
</a>
{% endif %}
{% if show_restore_default %}
<a class="restore-default hide" href="#{{ path }}" title="{% trans 'Restore default value' %}">
{{- get_image('s_reload', 'Restore default value'|trans) -}}
</a>
{% endif %}
{# This must match with displayErrors() in scripts/config.js. #}
{% if has_errors %}
<dl class="inline_errors">
{% for error in errors %}
<dd>{{ error|raw }}</dd>
{% endfor %}
</dl>
{% endif %}
</td>
{% if is_setup and allows_customization is not null %}
<td class="userprefs-allow" title="{% trans 'Allow users to customize this value' %}">
<input type="checkbox" name="{{ path }}-userprefs-allow"{{ allows_customization ? ' checked' }} aria-label="{% trans 'Allow users to customize this value' %}">
</td>
{% elseif is_setup %}
<td>&nbsp;</td>
{% endif %}
</tr>

View file

@ -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 %}

View file

@ -0,0 +1,192 @@
<div id="pma_console_container" class="d-print-none">
<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],
has_bookmark_feature ? ['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],
has_bookmark_feature ? ['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],
{0: 'text count hide', 1: 'Count'|trans, 'extraSpan': ''},
{0: 'text time', 1: 'Time taken'|trans, 'extraSpan': ''},
]
} only %}
</div> <!-- Template -->
</div> <!-- Debug SQL card -->
{% if has_bookmark_feature %}
<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],
has_bookmark_feature ? ['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 -->

View file

@ -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>

View file

@ -0,0 +1,10 @@
<div class="toolbar {{ parent_div_classes }}">
{% for content in content_array %}
{% if content is defined and content is not null %}
<div class="{{ content[0] }}">
{{ content['image'] is defined ? content['image']|raw }}
<span>{{ content[1] }}</span>
</div>
{% endif %}
{% endfor %}
</div>

View file

@ -0,0 +1,80 @@
<div class="card mt-3">
<form method="post" action="{{ url(route, url_params) }}">
{{ get_hidden_inputs(db) }}
{% for selected_table in selected %}
<input type="hidden" name="selected[]" value="{{ selected_table }}">
{% endfor %}
<div class="card-header">
{% 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 %}
</div>
<div class="card-body">
<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>
</div>
<div class="card-footer">
<input type="hidden" name="submit_create_version" value="1">
<input class="btn btn-primary" type="submit" value="{% trans 'Create version' %}">
</div>
</form>
</div>

View file

@ -0,0 +1,25 @@
<form id="multi_edit_central_columns">
<div class="card">
<div class="card-header">{% trans 'Structure' %}</div>
<div class="card-body">
<table id="table_columns" class="table align-middle mb-0 noclick">
<thead>
<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Length/Values' %}</th>
<th>{% trans 'Default' %}</th>
<th>{% trans 'Collation' %}</th>
<th>{% trans 'Attributes' %}</th>
<th>{% trans 'Null' %}</th>
<th>{% trans %}A_I{% context %}Auto Increment{% endtrans %}</th>
</tr>
</thead>
{{ rows|raw }}
</table>
</div>
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="save_multi_central_column_edit" value="{% trans 'Save' %}">
</div>
</div>
</form>

View file

@ -0,0 +1,85 @@
<tr>
<input name="orig_col_name[{{ row_num }}]" type="hidden" value="{{ row['col_name'] }}">
<td name="col_name" class="text-nowrap">
{% include 'columns_definitions/column_name.twig' with {
'column_number': row_num,
'ci': 0,
'ci_offset': 0,
'column_meta': {'Field': row['col_name']},
'has_central_columns_feature': false,
'max_rows': max_rows
} only %}
</td>
<td name="col_type" class="text-nowrap">
<select class="column_type" name="field_type[{{ row_num }}]" id="field_{{ row_num }}_1">
{{ get_supported_datatypes(true, row['col_type']|upper) }}
</select>
</td>
<td class="text-nowrap" name="col_length">
<input id="field_{{ row_num }}_2" type="text" name="field_length[{{ row_num }}]" size="8" value="{{ row['col_length'] }}" class="textfield">
<p class="enum_notice" id="enum_notice_{{ row_num }}_2">
<a href="#" class="open_enum_editor">{% trans 'Edit ENUM/SET values' %}</a>
</p>
</td>
<td class="text-nowrap" name="col_default">
<select name="field_default_type[{{ row_num }}]" id="field_{{ row_num }}_3" class="default_type">
<option value="NONE"{{ meta['DefaultType'] is defined and meta['DefaultType'] == 'NONE' ? ' selected' }}>
{% trans %}None{% context %}for default{% endtrans %}
</option>
<option value="USER_DEFINED"{{ meta['DefaultType'] is defined and meta['DefaultType'] == 'USER_DEFINED' ? ' selected' }}>
{% trans 'As defined:' %}
</option>
<option value="NULL"{{ meta['DefaultType'] is defined and meta['DefaultType'] == 'NULL' ? ' selected' }}>
NULL
</option>
<option value="CURRENT_TIMESTAMP"{{ meta['DefaultType'] is defined and meta['DefaultType'] == 'CURRENT_TIMESTAMP' ? ' selected' }}>
CURRENT_TIMESTAMP
</option>
</select>
{% if char_editing == 'textarea' %}
<textarea name="field_default_value[{{ row_num }}]" cols="15" class="textfield default_value"></textarea>
{% else %}
<input type="text" name="field_default_value[{{ row_num }}]" size="12" value="" class="textfield default_value">
{% endif %}
</td>
<td name="collation" class="text-nowrap">
<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.getName() }}" title="{{ charset.getDescription() }}">
{% for collation in collations[charset.getName()] %}
<option value="{{ collation.getName() }}" title="{{ collation.getDescription() }}"{{ row['col_collation'] == collation.getName() ? ' selected' }}>
{{ collation.getName() }}
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
</td>
<td class="text-nowrap" name="col_attribute">
{% include 'columns_definitions/column_attribute.twig' with {
'column_number': row_num,
'ci': 5,
'ci_offset': 0,
'column_meta': [],
'extracted_columnspec': {'attribute': row['col_attribute']},
'submit_attribute': false,
'attribute_types': attribute_types
} only %}
</td>
<td class="text-nowrap" name="col_isNull">
<input name="field_null[{{ row_num }}]" id="field_{{ row_num }}_6" type="checkbox" value="YES" class="allow_null"
{{- row['col_isNull'] is not empty and row['col_isNull'] != 'NO' and row['col_isNull'] != 'NOT NULL' ? ' checked' }}>
</td>
<td class="text-nowrap" name="col_extra">
<input name="col_extra[{{ row_num }}]" id="field_{{ row_num }}_7" type="checkbox" value="auto_increment"
{{- row['col_extra'] is not empty and row['col_extra'] == 'auto_increment' }}>
</td>
</tr>

View file

@ -0,0 +1,385 @@
{# 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="{{ url('/database/central-columns') }}">
{{ get_hidden_inputs(db) }}
<input type="hidden" name="add_new_column" value="add_new_column">
<div class="table-responsive">
<table class="table w-auto">
<thead>
<tr>
<th></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>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td name="col_name" class="text-nowrap">
{% include 'columns_definitions/column_name.twig' with {
'column_number': 0,
'ci': 0,
'ci_offset': 0,
'column_meta': {},
'has_central_columns_feature': false,
'max_rows': max_rows,
} only %}
</td>
<td name="col_type" class="text-nowrap">
<select class="column_type" name="field_type[0]" id="field_0_1">
{{ get_supported_datatypes(true) }}
</select>
</td>
<td class="text-nowrap" name="col_length">
<input id="field_0_2" type="text" name="field_length[0]" size="8" value="" class="textfield">
<p class="enum_notice" id="enum_notice_0_2">
<a href="#" class="open_enum_editor">{% trans 'Edit ENUM/SET values' %}</a>
</p>
</td>
<td class="text-nowrap" name="col_default">
<select name="field_default_type[0]" id="field_0_3" class="default_type">
<option value="NONE">{% trans %}None{% context %}for default{% endtrans %}</option>
<option value="USER_DEFINED">{% trans 'As defined:' %}</option>
<option value="NULL">NULL</option>
<option value="CURRENT_TIMESTAMP">CURRENT_TIMESTAMP</option>
</select>
{% if char_editing == 'textarea' %}
<textarea name="field_default_value[0]" cols="15" class="textfield default_value"></textarea>
{% else %}
<input type="text" name="field_default_value[0]" size="12" value="" class="textfield default_value">
{% endif %}
</td>
<td name="collation" class="text-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="text-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="text-nowrap" name="col_isNull">
<input name="field_null[0]" id="field_0_6" type="checkbox" value="YES" class="allow_null">
</td>
<td class="text-nowrap" name="col_extra">
<input name="col_extra[0]" id="field_0_7" type="checkbox" value="auto_increment">
</td>
<td>
<input id="add_column_save" class="btn btn-primary" type="submit" value="{% trans 'Save' %}">
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
{% if total_rows <= 0 %}
<div class="alert alert-info" role="alert">
{% trans 'The central list of columns for the current database is empty' %}
</div>
{% else %}
<table class="table table-borderless table-sm w-auto d-inline-block navigation">
<tr>
<td class="navigation_separator"></td>
{% if pos - max_rows >= 0 %}
<td>
<form action="{{ url('/database/central-columns') }}" 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="{{ url('/database/central-columns') }}" 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="{{ url('/database/central-columns') }}" 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 %}
<table class="table table-borderless table-sm w-auto d-inline-block">
<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="{{ url('/database/central-columns') }}" 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="{{ url('/database/central-columns') }}">
{{ 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="table table-striped table-hover tablesorter w-auto">
{% 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="text-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 text-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'|trans }}">
</td>
<td id="{{ 'save_' ~ row_num }}" class="hide">
<input type="submit" data-rownum="{{ row_num }}" class="btn btn-primary edit_save_form" value="{{ 'Save'|trans }}">
</td>
<td name="col_name" class="text-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']
},
'has_central_columns_feature': false,
'max_rows': max_rows
} only %}
</td>
<td name="col_type" class="text-nowrap">
<span>{{ row['col_type'] }}</span>
<select class="column_type" name="field_type[{{ row_num }}]" id="field_{{ row_num }}_1">
{{ get_supported_datatypes(true, types_upper[row_num]) }}
</select>
</td>
<td class="text-nowrap" name="col_length">
<span>{{ (row['col_length']?(row['col_length']):'') }}</span>
<input id="field_{{ row_num }}_2" type="text" name="field_length[{{ row_num }}]" size="8" value="{{ row['col_length'] }}" class="textfield">
<p class="enum_notice" id="enum_notice_{{ row_num }}_2">
<a href="#" class="open_enum_editor">{% trans 'Edit ENUM/SET values' %}</a>
</p>
</td>
<td class="text-nowrap" name="col_default">
{% if row['col_default'] is defined %}
<span>{{ row['col_default'] }}</span>
{% else %}
<span>{% trans 'None' %}</span>
{% endif %}
<select name="field_default_type[{{ row_num }}]" id="field_{{ row_num }}_3" class="default_type">
<option value="NONE"{{ rows_meta[row_num]['DefaultType'] is defined and rows_meta[row_num]['DefaultType'] == 'NONE' ? ' selected' }}>
{% trans %}None{% context %}for default{% endtrans %}
</option>
<option value="USER_DEFINED"{{ rows_meta[row_num]['DefaultType'] is defined and rows_meta[row_num]['DefaultType'] == 'USER_DEFINED' ? ' selected' }}>
{% trans 'As defined:' %}
</option>
<option value="NULL"{{ rows_meta[row_num]['DefaultType'] is defined and rows_meta[row_num]['DefaultType'] == 'NULL' ? ' selected' }}>
NULL
</option>
<option value="CURRENT_TIMESTAMP"{{ rows_meta[row_num]['DefaultType'] is defined and rows_meta[row_num]['DefaultType'] == 'CURRENT_TIMESTAMP' ? ' selected' }}>
CURRENT_TIMESTAMP
</option>
</select>
{% if char_editing == 'textarea' %}
<textarea name="field_default_value[{{ row_num }}]" cols="15" class="textfield default_value">{{ default_values[row_num] }}</textarea>
{% else %}
<input type="text" name="field_default_value[{{ row_num }}]" size="12" value="{{ default_values[row_num] }}" class="textfield default_value">
{% endif %}
</td>
<td name="collation" class="text-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="text-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="text-nowrap" name="col_isNull">
<span>{{ row['col_isNull'] ? 'Yes' | trans : 'No' | trans }}</span>
<input name="field_null[{{ row_num }}]" id="field_{{ row_num }}_6" type="checkbox" value="YES" class="allow_null"
{{- row['col_isNull'] is not empty and row['col_isNull'] != 'NO' and row['col_isNull'] != 'NOT NULL' ? ' checked' }}>
</td>
<td class="text-nowrap" name="col_extra">
<span>{{ row['col_extra'] }}</span>
<input name="col_extra[{{ row_num }}]" id="field_{{ row_num }}_7" type="checkbox" value="auto_increment"
{{- row['col_extra'] is not empty and row['col_extra'] == 'auto_increment' ? ' checked' }}>
</td>
</tr>
{% set row_num = row_num + 1 %}
{% endfor %}
</tbody>
</table>
{% include 'select_all.twig' with {
'text_dir': text_dir,
'form_name': 'tableslistcontainer',
} only %}
<button class="btn btn-link mult_submit change_central_columns" type="submit" name="edit_central_columns"
value="edit central columns" title="{% trans 'Edit' %}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</button>
<button class="btn btn-link mult_submit" type="submit" name="delete_central_columns"
value="remove_from_central_columns" title="{% trans 'Delete' %}">
{{ get_icon('b_drop', 'Delete'|trans) }}
</button>
</form>
</div>
{% endif %}

View file

@ -0,0 +1,3 @@
{% for column in columns %}
<option value="{{ column }}">{{ column }}</option>
{% endfor %}

View file

@ -0,0 +1,17 @@
<form id="createTableMinimalForm" method="post" action="{{ url('/table/create') }}" class="card d-print-none lock-page">
{{ get_hidden_inputs(db) }}
<div class="card-header">{{ get_icon('b_table_add', 'Create new table'|trans, true) }}</div>
<div class="card-body row row-cols-lg-auto g-3">
<div class="col-12">
<label for="createTableNameInput" class="form-label">{% trans 'Table name' %}</label>
<input type="text" class="form-control" name="table" id="createTableNameInput" maxlength="64" required>
</div>
<div class="col-12">
<label for="createTableNumFieldsInput" class="form-label">{% trans 'Number of columns' %}</label>
<input type="number" class="form-control" name="num_fields" id="createTableNumFieldsInput" min="1" value="4" required>
</div>
<div class="col-12 align-self-lg-end">
<input class="btn btn-primary" type="submit" value="{% trans 'Create' %}">
</div>
</div>
</form>

View file

@ -0,0 +1,126 @@
<div class="container-fluid">
<h1>{{ database }}</h1>
{% if comment is not empty %}
<p>{% trans 'Database comment:' %} <em>{{ comment }}</em></p>
{% endif %}
<p class="d-print-none">
<button type="button" class="btn btn-secondary jsPrintButton">{{ get_icon('b_print', 'Print'|trans, true) }}</button>
</p>
<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="table table-striped align-middle">
<thead>
<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 type' %}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for column in table.columns %}
<tr>
<td class="text-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="text-nowrap"' }}>
{{ column.print_type }}
</td>
<td>{{ column.is_nullable ? 'Yes'|trans : 'No'|trans }}</td>
<td class="text-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 %}
</tbody>
</table>
{% if table.indexes is not empty %}
<h3>{% trans 'Indexes' %}</h3>
<table class="table table-striped align-middle">
<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 table.indexes %}
{% set columns_count = index.getColumnCount() %}
<tr>
<td rowspan="{{ columns_count }}">{{ index.getName() }}</td>
<td rowspan="{{ columns_count }}">{{ index.getType()|default(index.getChoice()) }}</td>
<td rowspan="{{ columns_count }}">{{ index.isUnique() ? 'Yes'|trans : 'No'|trans }}</td>
<td rowspan="{{ columns_count }}">{{ index.isPacked()|raw }}</td>
{% for column in index.getColumns() %}
{% if column.getSeqInIndex() > 1 %}
<tr>
{% endif %}
<td>
{{ column.getName() }}
{% if column.getSubPart() is not empty %}
({{ column.getSubPart() }})
{% endif %}
</td>
<td>{{ column.getCardinality() }}</td>
<td>{{ column.getCollation() }}</td>
<td>{{ column.getNull(true) }}</td>
{% if column.getSeqInIndex() == 1 %}
<td rowspan="{{ columns_count }}">{{ index.getComments() }}</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
{% else %}
<p>{% trans 'No index defined!' %}</p>
{% endif %}
</div>
{% endfor %}
</div>
<p class="d-print-none">
<button type="button" class="btn btn-secondary jsPrintButton">{{ get_icon('b_print', 'Print'|trans, true) }}</button>
</p>
</div>

View file

@ -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="table table-sm table-striped table-hover w-auto designer_tab"
style="position:absolute; {{ text_dir == 'rtl' ? 'right' : '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="{{ image('designer/exec_small.png') }}"
title="{% trans 'See table structure' %}">
</td>
<td id="id_zag_{{ t_n_url }}"
class="tab_zag text-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="text-nowrap">
{% set type = columns_type[t_n ~ '.' ~ tab_column[t_n]['COLUMN_NAME'][j]] %}
<img src="{{ image(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="{{ image('designer/exec_small.png') }}" title="{% trans 'Options' %}" />
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}

View file

@ -0,0 +1,13 @@
<form action="{{ url('/database/designer') }}" method="post" name="edit_delete_pages" id="edit_delete_pages" class="ajax">
{{ get_hidden_inputs(db) }}
<fieldset class="pma-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>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
<form action="{{ url('/database/designer') }}" method="post" name="save_as_pages" id="save_as_pages" class="ajax">
{{ get_hidden_inputs(db) }}
<fieldset class="pma-fieldset" id="page_save_as_options">
<table class="table table-borderless">
<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>
<div>
<input type="radio" name="save_page" id="savePageSameRadio" value="same" checked>
<label for="savePageSameRadio">{% trans 'Save to selected page' %}</label>
</div>
<div>
<input type="radio" name="save_page" id="savePageNewRadio" value="new">
<label for="savePageNewRadio">{% trans 'Create a page and save to it' %}</label>
</div>
</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>

View file

@ -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>

View file

@ -0,0 +1,18 @@
<form method="post" action="{{ url('/schema-export') }}" class="disableAjax" id="id_export_pages">
<fieldset class="pma-fieldset">
{{ get_hidden_inputs(db) }}
<label for="plugins">{% trans 'Select Export Relational Type' %}</label>
<select id="plugins" name="export_type">
{% for option in plugins_choice %}
<option value="{{ option.name }}"{{ option.is_selected ? ' selected' }}>{{ option.text }}</option>
{% endfor %}
</select>
{% for option in plugins_choice %}
<input type="hidden" id="force_file_{{ option.name }}" value="true">
{% endfor %}
<input type="hidden" name="page_number" value="{{ page }}">
{{ options|raw }}
</fieldset>
</form>

View file

@ -0,0 +1,119 @@
<form class="rte_form" action="{{ url('/database/events') }}" method="post">
{{ get_hidden_inputs(db) }}
<input name="{{ mode }}_item" type="hidden" value="1">
{% if mode == 'edit' %}
<input name="item_original_name" type="hidden" value="{{ event.item_original_name }}">
{% endif %}
<div class="card">
<div class="card-header">
{% trans 'Details' %}
{% if mode != 'edit' %}
{{ show_mysql_docu('CREATE_EVENT') }}
{% endif %}
</div>
<div class="card-body">
<table class="rte_table table table-borderless table-sm">
<tr>
<td>{% trans 'Event name' %}</td>
<td>
<input type="text" name="item_name" value="{{ event.item_name }}" maxlength="64">
</td>
</tr>
<tr>
<td>{% trans 'Status' %}</td>
<td>
<select name="item_status">
{% for status in status_display %}
<option value="{{ status }}"{{ status == event.item_status ? ' selected' }}>{{ status }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>{% trans 'Event type' %}</td>
<td>
{% if is_ajax %}
<select name="item_type">
{% for type in event_type %}
<option value="{{ type }}"{{ type == event.item_type ? ' selected' }}>{{ type }}</option>
{% endfor %}
</select>
{% else %}
<input name="item_type" type="hidden" value="{{ event.item_type }}">
<div class="fw-bold text-center w-50">
{{ event.item_type }}
</div>
<input type="submit" name="item_changetype" class="w-50" value="{{ 'Change to %s'|trans|format(event.item_type_toggle) }}">
{% endif %}
</td>
</tr>
<tr class="onetime_event_row{{ event.item_type != 'ONE TIME' ? ' hide' }}">
<td>{% trans 'Execute at' %}</td>
<td class="text-nowrap">
<input type="text" name="item_execute_at" value="{{ event.item_execute_at }}" class="datetimefield">
</td>
</tr>
<tr class="recurring_event_row{{ event.item_type != 'RECURRING' ? ' hide' }}">
<td>{% trans 'Execute every' %}</td>
<td>
<input class="w-50" type="text" name="item_interval_value" value="{{ event.item_interval_value }}">
<select class="w-50" name="item_interval_field">
{% for interval in event_interval %}
<option value="{{ interval }}"{{ interval == event.item_interval_field ? ' selected' }}>{{ interval }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="recurring_event_row{{ event.item_type != 'RECURRING' ? ' hide' }}">
<td>{% trans %}Start{% context %}Start of recurring event{% endtrans %}</td>
<td class="text-nowrap">
<input type="text" name="item_starts" value="{{ event.item_starts }}" class="datetimefield">
</td>
</tr>
<tr class="recurring_event_row{{ event.item_type != 'RECURRING' ? ' hide' }}">
<td>{% trans %}End{% context %}End of recurring event{% endtrans %}</td>
<td class="text-nowrap">
<input type="text" name="item_ends" value="{{ event.item_ends }}" class="datetimefield">
</td>
</tr>
<tr>
<td>{% trans 'Definition' %}</td>
<td>
<textarea name="item_definition" rows="15" cols="40">
{{- event.item_definition -}}
</textarea>
</td>
</tr>
<tr>
<td>{% trans 'On completion preserve' %}</td>
<td>
<input type="checkbox" name="item_preserve"{{ event.item_preserve|raw }}>
</td>
</tr>
<tr>
<td>{% trans 'Definer' %}</td>
<td>
<input type="text" name="item_definer" value="{{ event.item_definer }}">
</td>
</tr>
<tr>
<td>{% trans 'Comment' %}</td>
<td>
<input type="text" name="item_comment" value="{{ event.item_comment }}" maxlength="64">
</td>
</tr>
</table>
</div>
{% if is_ajax %}
<input type="hidden" name="editor_process_{{ mode }}" value="true">
<input type="hidden" name="ajax_request" value="true">
{% else %}
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="editor_process_{{ mode }}" value="{% trans 'Go' %}">
</div>
{% endif %}
</div>
</form>

View file

@ -0,0 +1,154 @@
<div class="container-fluid my-3">
<h2>
{{ get_icon('b_events', 'Events'|trans) }}
{{ show_mysql_docu('EVENTS') }}
</h2>
<div class="d-flex flex-wrap my-3">
<div>
<div class="input-group">
<div class="input-group-text">
<div class="form-check mb-0">
<input class="form-check-input checkall_box" type="checkbox" value="" id="checkAllCheckbox" form="rteListForm">
<label class="form-check-label" for="checkAllCheckbox">{% trans 'Check all' %}</label>
</div>
</div>
<button class="btn btn-outline-secondary" id="bulkActionExportButton" type="submit" name="submit_mult" value="export" form="rteListForm" title="{% trans 'Export' %}">
{{ get_icon('b_export', 'Export'|trans) }}
</button>
<button class="btn btn-outline-secondary" id="bulkActionDropButton" type="submit" name="submit_mult" value="drop" form="rteListForm" title="{% trans 'Drop' %}">
{{ get_icon('b_drop', 'Drop'|trans) }}
</button>
</div>
</div>
<div class="ms-auto">
<a class="ajax add_anchor btn btn-primary{{ not has_privilege ? ' disabled' }}" href="{{ url('/database/events', {'db': db, 'add_item': true}) }}" role="button"{{ not has_privilege ? ' tabindex="-1" aria-disabled="true"' }}>
{{ get_icon('b_event_add', 'Create new event'|trans) }}
</a>
</div>
</div>
<form id="rteListForm" class="ajax" action="{{ url('/database/events') }}">
{{ get_hidden_inputs(db) }}
<div id="nothing2display"{{ items is not empty ? ' class="hide"' }}>
{% trans 'There are no events to display.' %}
</div>
<table id="eventsTable" class="table table-striped table-hover{{ items is empty ? ' hide' }} w-auto data">
<thead>
<tr>
<th></th>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'Type' %}</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr class="hide">{% for i in 0..6 %}<td></td>{% endfor %}</tr>
{% for event in items %}
<tr{{ is_ajax ? ' class="ajaxInsert hide"' }}>
<td>
<input type="checkbox" class="checkall" name="item_name[]" value="{{ event.name }}">
</td>
<td>
<span class="drop_sql hide">{{ 'DROP EVENT IF EXISTS %s'|format(backquote(event.name)) }}</span>
<strong>{{ event.name }}</strong>
</td>
<td>
{{ event.status }}
</td>
<td>
{{ event.type }}
</td>
<td>
{% if has_privilege %}
<a class="ajax edit_anchor" href="{{ url('/database/events', {
'db': db,
'edit_item': true,
'item_name': event.name
}) }}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</a>
{% else %}
{{ get_icon('bd_edit', 'Edit'|trans) }}
{% endif %}
</td>
<td>
<a class="ajax export_anchor" href="{{ url('/database/events', {
'db': db,
'export_item': true,
'item_name': event.name
}) }}">
{{ get_icon('b_export', 'Export'|trans) }}
</a>
</td>
<td>
{% if has_privilege %}
{{ link_or_button(
url('/sql'),
{
'db': db,
'sql_query': 'DROP EVENT IF EXISTS %s'|format(backquote(event.name)),
'goto': url('/database/events', {'db': db})
},
get_icon('b_drop', 'Drop'|trans),
{'class': 'ajax drop_anchor'}
) }}
{% else %}
{{ get_icon('bd_drop', 'Drop'|trans) }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
<div class="card mt-3">
<div class="card-header">{% trans 'Event scheduler status' %}</div>
<div class="card-body">
<div class="wrap">
<div class="wrapper toggleAjax hide">
<div class="toggleButton">
<div title="{% trans 'Click to toggle' %}" class="toggle-container {{ scheduler_state ? 'on' : 'off' }}">
<img src="{{ image('toggle-' ~ text_dir ~ '.png') }}">
<table>
<tbody>
<tr>
<td class="toggleOn">
<span class="hide">
{{- url('/sql', {
'db': db,
'goto': url('/database/events', {'db': db}),
'sql_query': 'SET GLOBAL event_scheduler="ON"',
}) -}}
</span>
<div>{% trans 'ON' %}</div>
</td>
<td><div>&nbsp;</div></td>
<td class="toggleOff">
<span class="hide">
{{- url('/sql', {
'db': db,
'goto': url('/database/events', {'db': db}),
'sql_query': 'SET GLOBAL event_scheduler="OFF"',
}) -}}
</span>
<div>{% trans 'OFF' %}</div>
</td>
</tr>
</tbody>
</table>
<span class="hide callback">Functions.slidingMessage(data.sql_query);</span>
<span class="hide text_direction">{{ text_dir }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,56 @@
<tr{% if row_class is not empty %} class="{{ row_class }}"{% endif %}>
<td>
<input type="checkbox" class="checkall" name="item_name[]" value="{{ event.name }}">
</td>
<td>
<span class='drop_sql hide'>{{ sql_drop }}</span>
<strong>{{ event.name }}</strong>
</td>
<td>
{{ event.status }}
</td>
<td>
{{ event.type }}
</td>
<td>
{% if has_privilege %}
<a class="ajax edit_anchor" href="{{ url('/database/events', {
'db': db,
'table': table,
'edit_item': true,
'item_name': event.name
}) }}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</a>
{% else %}
{{ get_icon('bd_edit', 'Edit'|trans) }}
{% endif %}
</td>
<td>
<a class="ajax export_anchor" href="{{ url('/database/events', {
'db': db,
'table': table,
'export_item': true,
'item_name': event.name
}) }}">
{{ get_icon('b_export', 'Export'|trans) }}
</a>
</td>
<td>
{% if has_privilege %}
{{ link_or_button(
url('/sql'),
{
'db': db,
'table': table,
'sql_query': sql_drop,
'goto': url('/database/events', {'db': db})
},
get_icon('b_drop', 'Drop'|trans),
{'class': 'ajax drop_anchor'}
) }}
{% else %}
{{ get_icon('bd_drop', 'Drop'|trans) }}
{% endif %}
</td>
</tr>

View file

@ -0,0 +1,62 @@
{% extends 'export.twig' %}
{% block title %}
{% if export_type == 'raw' %}
{% trans %}Exporting a raw query{% notes %}A query that the user has written freely{% endtrans %}
{% else %}
{{ 'Exporting tables from "%s" database'|trans|format(db) }}
{% endif %}
{% endblock %}
{% block selection_options %}
{% if export_type != 'raw' %}
<div class="card mb-3" id="databases_and_tables">
<div class="card-header">{% trans 'Tables:' %}</div>
<div class="card-body" style="overflow-y: scroll; max-height: 20em;">
<input type="hidden" name="structure_or_data_forced" value="{{ structure_or_data_forced }}">
<table class="table table-sm table-striped table-hover export_table_select">
<thead>
<tr>
<th></th>
<th>{% trans 'Tables' %}</th>
<th class="export_structure text-center">{% trans 'Structure' %}</th>
<th class="export_data text-center">{% trans 'Data' %}</th>
</tr>
<tr>
<td></td>
<td class="align-middle">{% trans 'Select all' %}</td>
<td class="export_structure text-center">
<input type="checkbox" id="table_structure_all" aria-label="{% trans 'Export the structure of all tables.' %}">
</td>
<td class="export_data text-center">
<input type="checkbox" id="table_data_all" aria-label="{% trans 'Export the data of all tables.' %}">
</td>
</tr>
</thead>
<tbody>
{% for each_table in tables %}
<tr class="marked">
<td>
<input class="checkall" type="checkbox" name="table_select[]" value="{{ each_table.name }}"{{ each_table.is_checked_select ? ' checked' }}>
</td>
<td class="align-middle text-nowrap">{{ each_table.name }}</td>
<td class="export_structure text-center">
<input type="checkbox" name="table_structure[]" value="{{ each_table.name }}"{{ each_table.is_checked_structure ? ' checked' }}>
</td>
<td class="export_data text-center">
<input type="checkbox" name="table_data[]" value="{{ each_table.name }}"{{ each_table.is_checked_data ? ' checked' }}>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
{% endblock %}
{% set filename_hint %}
{% trans '@SERVER@ will become the server name and @DATABASE@ will become the database name.' %}
{% endset %}

View file

@ -0,0 +1,3 @@
{% extends 'import.twig' %}
{% block title %}{{ 'Importing into the database "%s"'|trans|format(db) }}{% endblock %}

View file

@ -0,0 +1,179 @@
<ul class="nav nav-pills m-2">
<li class="nav-item">
<a class="nav-link active" href="{{ url('/database/multi-table-query', {'db': db}) }}">
{% trans 'Multi-table query' %}
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('/database/qbe', {'db': db}) }}">
{% trans 'Query by example' %}
</a>
</li>
</ul>
<div class="mb-3">
<button class="btn btn-sm btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#queryWindow" aria-expanded="true" aria-controls="queryWindow">
{% trans 'Query window' %}
</button>
</div>
<div class="collapse show mb-3" id="queryWindow">
<form action="" id="multi_table_query_form" class="multi_table_query_form query_form">
<input type="hidden" id="db_name" value="{{ db }}">
<fieldset class="pma-fieldset">
{% for table in tables %}
<div class="d-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 class="d-none" id="new_column_layout">{% endif %}
<fieldset class="pma-fieldset column_details query-form__fieldset--inline position-relative">
<select class="tableNameSelect query-form__select--inline">
<option value="">{% trans 'select table' %}</option>
{% for keyTableName, table in tables %}
<option data-hash="{{ table.hash }}" value="{{ keyTableName }}">{{ keyTableName }}</option>
{% endfor %}
</select>
<span>.</span>
<select class="columnNameSelect query-form__select--inline">
<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">
<button class="btn btn-link p-0 jsCriteriaButton" type="button" data-bs-toggle="collapse" data-bs-target="#criteriaOptions{{ id }}" aria-expanded="false" aria-controls="criteriaOptions{{ id }}">
{% trans 'criteria' %}
</button>
<div class="collapse jsCriteriaOptions" id="criteriaOptions{{ id }}">
<div>
<table class="table table-sm table-borderless align-middle w-auto">
<tr class="sort_order query-form__tr--bg-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 query-form__tr--bg-none query-form__tr--hide">
<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 class="query-form__tr--bg-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="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 query-form__tr--hide query-form__tr--bg-none">
<td></td>
<td>
<select class="tableNameSelect">
<option value="">{% trans 'select table' %}</option>
{% for keyTableName, table in tables %}
<option data-hash="{{ table.hash }}" value="{{ keyTableName }}">{{ keyTableName }}</option>
{% endfor %}
</select><span>.</span>
</td>
<td>
<select class="columnNameSelect query-form__select--inline">
<option value="">{% trans 'select column' %}</option>
</select>
</td>
</tr>
<tr class="rhs_text query-form__tr--bg-none">
<td></td>
<td colspan="2">
<input type="text"
class="rhs_text_val query-form__input--wide"
placeholder="{% trans 'Enter criteria as free text' %}">
</td>
</tr>
</table>
</div>
</div>
<button type="button" class="btn-close position-absolute top-0 end-0 jsRemoveColumn" aria-label="{% trans 'Remove this column' %}"></button>
</fieldset>
{% if id == 0 %}</div>{% endif %}
{% endfor %}
<fieldset class="pma-fieldset query-form__fieldset--inline">
<input class="btn btn-secondary" type="button" value="{% trans '+ Add column' %}" id="add_column_button">
</fieldset>
<fieldset class="pma-fieldset">
{# Keep the block without a space between the open and close tag #}
<textarea id="MultiSqlquery"
class="query-form__multi-sql-query"
cols="80"
rows="4"
name="sql_query"
dir="ltr"></textarea>
</fieldset>
</fieldset>
<fieldset class="pma-fieldset 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>
<div id="sql_results"></div>

View file

@ -0,0 +1,230 @@
<div class="container-fluid">
{{ message|raw }}
{% if has_comment %}
<form method="post" action="{{ url('/database/operations') }}" id="formDatabaseComment">
{{ get_hidden_inputs(db) }}
<div class="card mb-2">
<div class="card-header">{{ get_icon('b_comment', 'Database comment'|trans, true) }}</div>
<div class="card-body">
<div class="row g-3">
<div class="col-auto">
<label class="visually-hidden" for="databaseCommentInput">{% trans 'Database comment' %}</label>
<input class="form-control textfield" id="databaseCommentInput" type="text" name="comment" value="{{ db_comment }}">
</div>
</div>
</div>
<div class="card-footer text-end">
<input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
</div>
</div>
</form>
{% endif %}
<form id="createTableMinimalForm" method="post" action="{{ url('/table/create') }}" class="card mb-2 lock-page">
{{ get_hidden_inputs(db) }}
<div class="card-header">{{ get_icon('b_table_add', 'Create new table'|trans, true) }}</div>
<div class="card-body row row-cols-lg-auto g-3">
<div class="col-md-6">
<label for="createTableNameInput" class="form-label">{% trans 'Table name' %}</label>
<input type="text" class="form-control" name="table" id="createTableNameInput" maxlength="64" required>
</div>
<div class="col-md-6">
<label for="createTableNumFieldsInput" class="form-label">{% trans 'Number of columns' %}</label>
<input type="number" class="form-control" name="num_fields" id="createTableNumFieldsInput" min="1" value="4" required>
</div>
</div>
<div class="card-footer text-end">
<input class="btn btn-primary" type="submit" value="{% trans 'Create' %}">
</div>
</form>
{% if db != 'mysql' %}
<form id="rename_db_form" class="ajax" method="post" action="{{ url('/database/operations') }}">
{{ get_hidden_inputs(db) }}
<input type="hidden" name="what" value="data">
<input type="hidden" name="db_rename" value="true">
{% if db_collation is not empty %}
<input type="hidden" name="db_collation" value="{{ db_collation }}">
{% endif %}
<div class="card mb-2">
<div class="card-header">{{ get_icon('b_edit', 'Rename database to'|trans, true) }}</div>
<div class="card-body">
<div class="mb-3 row g-3">
<div class="col-auto">
<label class="visually-hidden" for="new_db_name">{% trans 'New database name' %}</label>
<input class="form-control textfield" id="new_db_name" type="text" name="newname" maxlength="64" required>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="adjust_privileges" value="1" id="checkbox_adjust_privileges"
{%- if has_adjust_privileges %} checked{% else %} title="
{%- trans 'You don\'t have sufficient privileges to perform this operation; Please refer to the documentation for more details.' %}" disabled{% endif %}>
<label class="form-check-label" for="checkbox_adjust_privileges">
{% trans 'Adjust privileges' %}
{{ show_docu('faq', 'faq6-39') }}
</label>
</div>
</div>
<div class="card-footer text-end">
<input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
</div>
</div>
</form>
{% endif %}
{% if is_drop_database_allowed %}
<div class="card mb-2">
<div class="card-header">{{ get_icon('b_deltbl', 'Remove database'|trans, true) }}</div>
<div class="card-body">
<div class="card-text">
{{ link_or_button(
url('/sql'),
{
'sql_query': 'DROP DATABASE ' ~ backquote(db),
'back': url('/database/operations'),
'goto': url('/'),
'reload': true,
'purge': true,
'message_to_show': 'Database %s has been dropped.'|trans|format(backquote(db))|e,
'db': null
},
'Drop the database (DROP)'|trans,
{
'id': 'drop_db_anchor',
'class': 'ajax text-danger'
}
) }}
{{ show_mysql_docu('DROP_DATABASE') }}
</div>
</div>
</div>
{% endif %}
<form id="copy_db_form" class="ajax" method="post" action="{{ url('/database/operations') }}">
{{ get_hidden_inputs(db) }}
<input type="hidden" name="db_copy" value="true">
{% if db_collation is not empty %}
<input type="hidden" name="db_collation" value="{{ db_collation }}">
{% endif %}
<div class="card mb-2">
<div class="card-header">{{ get_icon('b_edit', 'Copy database to'|trans, true) }}</div>
<div class="card-body">
<div class="mb-3 row g-3">
<div class="col-auto">
<label class="visually-hidden" for="renameDbNameInput">{% trans 'Database name' %}</label>
<input class="form-control textfield" id="renameDbNameInput" type="text" maxlength="64" name="newname" required>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="what" id="whatRadio1" value="structure">
<label class="form-check-label" for="whatRadio1">
{% trans 'Structure only' %}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="what" id="whatRadio2" value="data" checked>
<label class="form-check-label" for="whatRadio2">
{% trans 'Structure and data' %}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="what" id="whatRadio3" value="dataonly">
<label class="form-check-label" for="whatRadio3">
{% trans 'Data only' %}
</label>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="create_database_before_copying" value="1" id="checkbox_create_database_before_copying" checked>
<label class="form-check-label" for="checkbox_create_database_before_copying">{% trans 'CREATE DATABASE before copying' %}</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="drop_if_exists" value="true" id="checkbox_drop">
<label class="form-check-label" for="checkbox_drop">{{ 'Add %s'|trans|format('DROP TABLE / DROP VIEW') }}</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="sql_auto_increment" value="1" id="checkbox_auto_increment" checked>
<label class="form-check-label" for="checkbox_auto_increment">{% trans 'Add AUTO_INCREMENT value' %}</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="add_constraints" value="1" id="checkbox_constraints" checked>
<label class="form-check-label" for="checkbox_constraints">{% trans 'Add constraints' %}</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="adjust_privileges" value="1" id="checkbox_privileges"
{%- if has_adjust_privileges %} checked{% else %} title="
{%- trans 'You don\'t have sufficient privileges to perform this operation; Please refer to the documentation for more details.' %}" disabled{% endif %}>
<label class="form-check-label" for="checkbox_privileges">
{% trans 'Adjust privileges' %}
{{ show_docu('faq', 'faq6-39') }}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="switch_to_new" value="true" id="checkbox_switch"{{ switch_to_new ? ' checked' }}>
<label class="form-check-label" for="checkbox_switch">{% trans 'Switch to copied database' %}</label>
</div>
</div>
<div class="card-footer text-end">
<input class="btn btn-primary" type="submit" name="submit_copy" value="{% trans 'Go' %}">
</div>
</div>
</form>
<form id="change_db_charset_form" class="ajax" method="post" action="{{ url('/database/operations/collation') }}">
{{ get_hidden_inputs(db) }}
<div class="card mb-2">
<div class="card-header">{{ get_icon('s_asci', 'Collation'|trans, true) }}</div>
<div class="card-body">
<div class="mb-3 row g-3">
<div class="col-auto">
<label class="visually-hidden" for="select_db_collation">{% trans 'Collation' %}</label>
<select class="form-select" lang="en" dir="ltr" name="db_collation" id="select_db_collation">
<option value=""></option>
{% for charset in charsets %}
<optgroup label="{{ charset.getName() }}" title="{{ charset.getDescription() }}">
{% for collation in collations[charset.getName()] %}
<option value="{{ collation.getName() }}" title="{{ collation.getDescription() }}"{{ db_collation == collation.getName() ? ' selected' }}>
{{ collation.getName() }}
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="change_all_tables_collations" id="checkbox_change_all_tables_collations">
<label class="form-check-label" for="checkbox_change_all_tables_collations">{% trans 'Change all tables collations' %}</label>
</div>
<div class="form-check" id="span_change_all_tables_columns_collations">
<input class="form-check-input" type="checkbox" name="change_all_tables_columns_collations" id="checkbox_change_all_tables_columns_collations">
<label class="form-check-label" for="checkbox_change_all_tables_columns_collations">{% trans 'Change all tables columns collations' %}</label>
</div>
</div>
<div class="card-footer text-end">
<input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
</div>
</div>
</form>
</div>

View file

@ -0,0 +1,141 @@
{% if is_superuser %}
<form id="usersForm" action="{{ url('/server/privileges') }}">
{{ get_hidden_inputs(db) }}
<div class="w-100">
<fieldset class="pma-fieldset">
<legend>
{{ get_icon('b_usrcheck') }}
{{ 'Users having access to "%s"'|trans|format('<a href="' ~ database_url ~ get_common({'db': db}, '&') ~ '">' ~ db|escape('html') ~ '</a>')|raw }}
</legend>
<div class="table-responsive jsresponsive">
<table class="table table-striped table-hover w-auto">
<thead>
<tr>
<th></th>
<th scope="col">{% trans 'User name' %}</th>
<th scope="col">{% trans 'Host name' %}</th>
<th scope="col">{% trans 'Type' %}</th>
<th scope="col">{% trans 'Privileges' %}</th>
<th scope="col">{% trans 'Grant' %}</th>
<th scope="col" colspan="2">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
{% for privilege in privileges %}
{% set privileges_amount = privilege.privileges|length %}
<tr>
<td{% if privileges_amount > 1 %} class="align-middle" rowspan="{{ privileges_amount }}"{% endif %}>
<input type="checkbox" class="checkall" name="selected_usr[]" id="checkbox_sel_users_{{ loop.index0 }}" value="
{{- privilege.user ~ '&amp;#27;' ~ privilege.host }}">
</td>
<td{% if privileges_amount > 1 %} class="align-middle" rowspan="{{ privileges_amount }}"{% endif %}>
{% if privilege.user is empty %}
<span class="text-danger">{% trans 'Any' %}</span>
{% else %}
{{ privilege.user }}
{% endif %}
</td>
<td{% if privileges_amount > 1 %} class="align-middle" rowspan="{{ privileges_amount }}"{% endif %}>
{{ privilege.host }}
</td>
{% for priv in privilege.privileges %}
<td>
{% if priv.type == 'g' %}
{% trans 'global' %}
{% elseif priv.type == 'd' %}
{% if priv.database == db|replace({'_': '\\_', '%': '\\%'}) %}
{% trans 'database-specific' %}
{% else %}
{% trans 'wildcard' %}: <code>{{ priv.database }}</code>
{% endif %}
{% elseif priv.type == 'r' %}
{% trans 'routine' %}
{% endif %}
</td>
<td>
<code>
{% if priv.type == 'r' %}
{{ priv.routine }}
({{ priv.privileges|join(', ')|upper }})
{% else %}
{{ priv.privileges|join(', ')|raw }}
{% endif %}
</code>
</td>
<td>
{{ priv.has_grant ? 'Yes'|trans : 'No'|trans }}
</td>
<td>
{% if is_grantuser %}
<a class="edit_user_anchor" href="{{ url('/server/privileges', {
'username': privilege.user,
'hostname': privilege.host,
'dbname': priv.database != '*' ? priv.database,
'tablename': '',
'routinename': priv.routine ?? ''
}) }}">
{{ get_icon('b_usredit', 'Edit privileges'|trans) }}
</a>
{% endif %}
</td>
<td class="text-center">
<a class="export_user_anchor ajax" href="{{ url('/server/privileges', {
'username': privilege.user,
'hostname': privilege.host,
'export': true,
'initial': ''
}) }}">
{{ get_icon('b_tblexport', 'Export'|trans) }}
</a>
</td>
</tr>
{% if privileges_amount > 1 %}
<tr class="noclick">
{% endif %}
{% endfor %}
{% else %}
<tr>
<td colspan="7">
{% trans 'No user found.' %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="float-start">
<img class="selectallarrow" src="{{ image('arrow_' ~ text_dir ~ '.png') }}" alt="
{%- trans 'With selected:' %}" width="38" height="22">
<input type="checkbox" id="usersForm_checkall" class="checkall_box" title="{% trans 'Check all' %}">
<label for="usersForm_checkall">{% trans 'Check all' %}</label>
<em class="with-selected">{% trans 'With selected:' %}</em>
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="export" title="{% trans 'Export' %}">
{{ get_icon('b_tblexport', 'Export'|trans) }}
</button>
</div>
</fieldset>
</div>
</form>
{% else %}
{{ 'Not enough privilege to view users.'|trans|error }}
{% endif %}
{% if is_createuser %}
<div class="row">
<div class="col-12">
<fieldset class="pma-fieldset" id="fieldset_add_user">
<legend>{% trans %}New{% context %}Create new user{% endtrans %}</legend>
<a id="add_user_anchor" href="{{ url('/server/privileges', {
'adduser': true,
'dbname': db
}) }}" rel="{{ get_common({'checkprivsdb': db}) }}">
{{ get_icon('b_usradd', 'Add user account'|trans) }}
</a>
</fieldset>
</div>
</div>
{% endif %}

View file

@ -0,0 +1,11 @@
<td class="text-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 -}}
</option>
{% endfor %}
</select>
</td>

View file

@ -0,0 +1,23 @@
<ul class="nav nav-pills m-2">
<li class="nav-item">
<a class="nav-link" href="{{ url('/database/multi-table-query', url_params) }}">
{% trans 'Multi-table query' %}
</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="{{ url('/database/qbe', url_params) }}">
{% trans 'Query by example' %}
</a>
</li>
</ul>
{% apply format('<a href="' ~ url('/database/designer', url_params|merge({query: true})) ~ '">', '</a>')|notice %}
{% trans 'Switch to %svisual builder%s' %}
{% endapply %}
{% if has_message_to_display %}
{{ 'You have to choose at least one column to display!'|trans|error }}
{% endif %}
{{ selection_form_html|raw }}

View file

@ -0,0 +1,28 @@
<td class="value text-nowrap">
<table class="table table-borderless table-sm">
<tr>
<td class="value text-nowrap p-0">
<small>{% trans 'Ins:' %}</small>
<input type="checkbox" name="criteriaRowInsert[{{ row_index }}]" aria-label="{% trans 'Insert' %}">
</td>
<td class="value p-0">
<strong>{% trans 'And:' %}</strong>
</td>
<td class="p-0">
<input type="radio" name="criteriaAndOrRow[{{ row_index }}]" value="and"{{ checked_options.and ? ' checked' }} aria-label="{% trans 'And' %}">
</td>
</tr>
<tr>
<td class="value text-nowrap p-0">
<small>{% trans 'Del:' %}</small>
<input type="checkbox" name="criteriaRowDelete[{{ row_index }}]" aria-label="{% trans 'Delete' %}">
</td>
<td class="value p-0">
<strong>{% trans 'Or:' %}</strong>
</td>
<td class="p-0">
<input type="radio" name="criteriaAndOrRow[{{ row_index }}]" value="or"{{ checked_options.or ? ' checked' }} aria-label="{% trans 'Or' %}">
</td>
</tr>
</table>
</td>

View file

@ -0,0 +1,118 @@
<form action="{{ url('/database/qbe') }}" method="post" id="formQBE" class="lock-page">
{{ get_hidden_inputs(url_params) }}
<div class="w-100">
<fieldset class="pma-fieldset">
{{ saved_searches_field|raw }}
<div class="table-responsive jsresponsive">
<table class="table table-borderless table-sm w-auto">
<tr class="noclick">
<th>{% trans 'Column:' %}</th>
{{ column_names_row|raw }}
</tr>
<tr class="noclick">
<th>{% trans 'Alias:' %}</th>
{{ column_alias_row|raw }}
</tr>
<tr class="noclick">
<th>{% trans 'Show:' %}</th>
{{ show_row|raw }}
</tr>
<tr class="noclick">
<th>{% trans 'Sort:' %}</th>
{{ sort_row|raw }}
</tr>
<tr class="noclick">
<th>{% trans 'Sort order:' %}</th>
{{ sort_order|raw }}
</tr>
<tr class="noclick">
<th>{% trans 'Criteria:' %}</th>
{{ criteria_input_box_row|raw }}
</tr>
{{ ins_del_and_or_criteria_rows|raw }}
<tr class="noclick">
<th>{% trans 'Modify:' %}</th>
{{ modify_columns_row|raw }}
</tr>
</table>
</div>
</fieldset>
</div>
<fieldset class="pma-fieldset tblFooters">
<div class="float-start">
<label for="criteriaRowAddSelect">{% trans 'Add/Delete criteria rows:' %}</label>
<select size="1" name="criteriaRowAdd" id="criteriaRowAddSelect">
<option value="-3">-3</option>
<option value="-2">-2</option>
<option value="-1">-1</option>
<option value="0" selected>0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div class="float-start">
<label for="criteriaColumnAddSelect">{% trans 'Add/Delete columns:' %}</label>
<select size="1" name="criteriaColumnAdd" id="criteriaColumnAddSelect">
<option value="-3">-3</option>
<option value="-2">-2</option>
<option value="-1">-1</option>
<option value="0" selected>0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div class="float-start">
<input class="btn btn-secondary" type="submit" name="modify" value="{% trans 'Update query' %}">
</div>
</fieldset>
<div class="float-start w-100">
<fieldset class="pma-fieldset">
<legend>{% trans 'Use tables' %}</legend>
<select class="resize-vertical" name="TableList[]" id="listTable" size="{{ criteria_tables|length > 30 ? '15' : '7' }}" aria-label="{% trans 'Use tables' %}" multiple>
{% for table, selected in criteria_tables %}
<option value="{{ table }}"{{ selected|raw }}>{{ table }}</option>
{% endfor %}
</select>
</fieldset>
<fieldset class="pma-fieldset tblFooters">
<input class="btn btn-secondary" type="submit" name="modify" value="{% trans 'Update query' %}">
</fieldset>
</div>
</form>
<form action="{{ url('/database/qbe') }}" method="post" class="lock-page">
{{ get_hidden_inputs(db) }}
<input type="hidden" name="submit_sql" value="1">
<div class="float-start w-50">
<fieldset class="pma-fieldset" id="tblQbe">
<legend>{{ 'SQL query on database <b>%s</b>:'|trans|format(db_link)|raw }}</legend>
<textarea cols="80" name="sql_query" id="textSqlquery" rows="{{ criteria_tables|length > 30 ? '15' : '7' }}" dir="ltr" aria-label="{% trans 'SQL query' %}">
{{- sql_query -}}
</textarea>
</fieldset>
<fieldset class="pma-fieldset tblFooters" id="tblQbeFooters">
<input class="btn btn-primary" type="submit" value="{% trans 'Submit query' %}">
</fieldset>
</div>
</form>

View file

@ -0,0 +1,10 @@
<td class="text-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>

View file

@ -0,0 +1,9 @@
<td class="text-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>

View file

@ -0,0 +1,184 @@
<form class="rte_form{{ not is_ajax ? ' disableAjax' }}" action="{{ url('/database/routines') }}" method="post">
<input name="{{ is_edit_mode ? 'edit_item' : 'add_item' }}" type="hidden" value="1">
{% if is_edit_mode %}
<input name="item_original_name" type="hidden" value="{{ routine.item_original_name }}">
<input name="item_original_type" type="hidden" value="{{ routine.item_original_type }}">
{% endif %}
{{ get_hidden_inputs(db) }}
<div class="card">
<div class="card-header">
{% trans 'Details' %}
{% if not is_edit_mode %}
{{ show_mysql_docu('CREATE_PROCEDURE') }}
{% endif %}
</div>
<div class="card-body">
<table class="rte_table table table-borderless table-sm">
<tr>
<td>{% trans 'Routine name' %}</td>
<td>
<input type="text" name="item_name" maxlength="64" value="{{ routine.item_name }}">
</td>
</tr>
<tr>
<td>{% trans 'Type' %}</td>
<td>
{% if is_ajax %}
<select name="item_type">
<option value="PROCEDURE"{{ routine.item_type == 'PROCEDURE' ? ' selected' }}>PROCEDURE</option>
<option value="FUNCTION"{{ routine.item_type == 'FUNCTION' ? ' selected' }}>FUNCTION</option>
</select>
{% else %}
<input name="item_type" type="hidden" value="{{ routine.item_type }}">
<div class="fw-bold text-center w-50">
{{ routine['item_type'] }}
</div>
<input type="submit" class="btn btn-secondary" name="routine_changetype" value="{{ 'Change to %s'|trans|format(routine.item_type_toggle) }}">
{% endif %}
</td>
</tr>
<tr>
<td>{% trans 'Parameters' %}</td>
<td>
<table class="routine_params_table table table-borderless table-sm">
<thead>
<tr>
<td></td>
<th class="routine_direction_cell{{ routine.item_type == 'FUNCTION' ? ' hide' }}">{% trans 'Direction' %}</th>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Length/Values' %}</th>
<th colspan="2">{% trans 'Options' %}</th>
<th class="routine_param_remove hide"></th>
</tr>
</thead>
<tbody>
{{ parameter_rows|raw }}
</tbody>
</table>
</td>
</tr>
<tr>
<td></td>
<td>
{% if is_ajax %}
<button type="button" class="btn btn-primary" id="addRoutineParameterButton">{% trans 'Add parameter' %}</button>
{% else %}
<input type="submit" class="btn btn-primary" name="routine_addparameter" value="{% trans 'Add parameter' %}">
<input type="submit" class="btn btn-secondary" name="routine_removeparameter" value="{% trans 'Remove last parameter' %}"{{ not routine.item_num_params ? ' disabled' }}>
{% endif %}
</td>
</tr>
<tr class="routine_return_row{{ routine.item_type == 'PROCEDURE' ? ' hide' }}">
<td>{% trans 'Return type' %}</td>
<td>
<select name="item_returntype">
{{ get_supported_datatypes(true, routine.item_returntype) }}
</select>
</td>
</tr>
<tr class="routine_return_row{{ routine.item_type == 'PROCEDURE' ? ' hide' }}">
<td>{% trans 'Return length/values' %}</td>
<td>
<input type="text" name="item_returnlength" value="{{ routine.item_returnlength }}">
</td>
<td class="hide no_len">---</td>
</tr>
<tr class="routine_return_row{{ routine.item_type == 'PROCEDURE' ? ' hide' }}">
<td>{% trans 'Return options' %}</td>
<td>
<div>
<select lang="en" dir="ltr" name="item_returnopts_text">
<option value="">{% trans 'Charset' %}</option>
<option value=""></option>
{% for charset in charsets %}
<option value="{{ charset.getName() }}" title="{{ charset.getDescription() }}"{{ routine.item_returnopts_text == charset.getName() ? ' selected' }}>{{ charset.getName() }}</option>
{% endfor %}
</select>
</div>
<div>
<select name="item_returnopts_num">
<option value=""></option>
{% for numeric_option in numeric_options %}
<option value="{{ numeric_option }}"{{ routine.item_returnopts_num == numeric_option ? ' selected' }}>{{ numeric_option }}</option>
{% endfor %}
</select>
</div>
<div class="hide no_opts">---</div>
</td>
</tr>
<tr>
<td>{% trans 'Definition' %}</td>
<td>
<textarea name="item_definition" rows="15" cols="40">{{ routine.item_definition }}</textarea>
</td>
</tr>
<tr>
<td>{% trans 'Is deterministic' %}</td>
<td>
<input type="checkbox" name="item_isdeterministic"{{ routine.item_isdeterministic|raw }}>
</td>
</tr>
{% if is_edit_mode %}
<tr>
<td>
{% trans 'Adjust privileges' %}
{{ show_docu('faq', 'faq6-39') }}
</td>
<td>
{% if has_privileges %}
<input type="checkbox" name="item_adjust_privileges" value="1" checked>
{% else %}
<input type="checkbox" name="item_adjust_privileges" value="1" title="{% trans 'You do not have sufficient privileges to perform this operation; Please refer to the documentation for more details.' %}" disabled>
{% endif %}
</td>
</tr>
{% endif %}
<tr>
<td>{% trans 'Definer' %}</td>
<td>
<input type="text" name="item_definer" value="{{ routine.item_definer }}">
</td>
</tr>
<tr>
<td>{% trans 'Security type' %}</td>
<td>
<select name="item_securitytype">
<option value="DEFINER"{{ routine.item_securitytype_definer|raw }}>DEFINER</option>
<option value="INVOKER"{{ routine.item_securitytype_invoker|raw }}>INVOKER</option>
</select>
</td>
</tr>
<tr>
<td>{% trans 'SQL data access' %}</td>
<td>
<select name="item_sqldataaccess">
{% for value in sql_data_access %}
<option value="{{ value }}"{{ routine.item_sqldataaccess == value ? ' selected' }}>{{ value }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>{% trans 'Comment' %}</td>
<td>
<input type="text" name="item_comment" maxlength="64" value="{{ routine.item_comment }}">
</td>
</tr>
</table>
</div>
{% if is_ajax %}
<input type="hidden" name="{{ is_edit_mode ? 'editor_process_edit' : 'editor_process_add' }}" value="true">
<input type="hidden" name="ajax_request" value="true">
{% else %}
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="{{ is_edit_mode ? 'editor_process_edit' : 'editor_process_add' }}" value="{% trans 'Go' %}">
</div>
{% endif %}
</div>
</form>

View file

@ -0,0 +1,62 @@
<form action="{{ url('/database/routines') }}" method="post" class="rte_form ajax" onsubmit="return false">
<input type="hidden" name="item_name" value="{{ routine['item_name'] }}">
<input type="hidden" name="item_type" value="{{ routine['item_type'] }}">
{{ get_hidden_inputs(db) }}
<div class="card">
<div class="card-header">{{ ajax ? 'Routine parameters'|trans : routine['item_name'] }}</div>
<div class="card-body">
<table class="table w-auto rte_table{{ not ajax ? ' caption-top' }}">
{% if not ajax %}
<caption class="tblHeaders">{% trans 'Routine parameters' %}</caption>
{% endif %}
<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th>
{% if show_function_fields %}
<th>{% trans 'Function' %}</th>
{% endif %}
<th>{% trans 'Value' %}</th>
</tr>
{% for i in 0..routine['item_num_params'] - 1 %}
<tr>
<td>{{ routine['item_param_name'][loop.index0] }}</td>
<td>{{ routine['item_param_type'][loop.index0] }}</td>
{% if show_function_fields %}
<td>
{% if params[loop.index0]['generator'] is not null %}
<select name="funcs[{{ routine['item_param_name'][loop.index0] }}]">
{{ params[loop.index0]['generator']|raw }}</select>
{% else %}
--
{% endif %}
</td>
{% endif %}
<td class="nowrap">
{% if routine['item_param_type'][loop.index0] in ['ENUM', 'SET'] %}
{% for value in routine['item_param_length_arr'][loop.index0] %}
<input name="params[{{ routine['item_param_name'][loop.parent.loop.index0] }}][]" value="{{ params[loop.parent.loop.index0]['htmlentities'][loop.index0] }}" type="{{ params[loop.parent.loop.index0]['input_type'] }}">
{{ params[loop.parent.loop.index0]['htmlentities'][loop.index0] }}
<br>
{% endfor %}
{% elseif routine['item_param_type'][loop.index0]|lower in params['no_support_types'] %}
{% else %}
<input class="{{ params[loop.index0]['class'] }}" type="text" name="params[{{ routine['item_param_name'][loop.index0] }}]">
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% if not ajax %}
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="execute_routine" value="{% trans 'Go' %}">
</div>
{% else %}
<input type="hidden" name="execute_routine" value="true">
<input type="hidden" name="ajax_request" value="true">
{% endif %}
</div>
</form>

View file

@ -0,0 +1,62 @@
<div class="container-fluid my-3">
<h2>
{{ get_icon('b_routines', 'Routines'|trans) }}
{{ show_mysql_docu('STORED_ROUTINES') }}
</h2>
<div class="d-flex flex-wrap my-3">
<div>
<div class="input-group">
<div class="input-group-text">
<div class="form-check mb-0">
<input class="form-check-input checkall_box" type="checkbox" value="" id="checkAllCheckbox" form="rteListForm">
<label class="form-check-label" for="checkAllCheckbox">{% trans 'Check all' %}</label>
</div>
</div>
<button class="btn btn-outline-secondary" id="bulkActionExportButton" type="submit" name="submit_mult" value="export" form="rteListForm" title="{% trans 'Export' %}">
{{ get_icon('b_export', 'Export'|trans) }}
</button>
<button class="btn btn-outline-secondary" id="bulkActionDropButton" type="submit" name="submit_mult" value="drop" form="rteListForm" title="{% trans 'Drop' %}">
{{ get_icon('b_drop', 'Drop'|trans) }}
</button>
</div>
</div>
<div class="ms-auto">
<div class="input-group">
<span class="input-group-text">{{ get_image('b_search', 'Search'|trans) }}</span>
<input class="form-control" name="filterText" type="text" id="filterText" value="" placeholder="{% trans 'Search' %}" aria-label="{% trans 'Search' %}">
</div>
</div>
<div class="ms-2">
<a class="ajax add_anchor btn btn-primary{{ not has_privilege ? ' disabled' }}" href="{{ url('/database/routines', {'db': db, 'table': table, 'add_item': true}) }}" role="button"{{ not has_privilege ? ' tabindex="-1" aria-disabled="true"' }}>
{{ get_icon('b_routine_add', 'Create new routine'|trans) }}
</a>
</div>
</div>
<form id="rteListForm" class="ajax" action="{{ url('/database/routines') }}">
{{ get_hidden_inputs(db, table) }}
<div id="nothing2display"{{ items is not empty ? ' class="hide"' }}>
{% trans 'There are no routines to display.' %}
</div>
<table id="routinesTable" class="table table-striped table-hover{{ items is empty ? ' hide' }} data w-auto">
<thead>
<tr>
<th></th>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Returns' %}</th>
<th colspan="4"></th>
</tr>
</thead>
<tbody>
<tr class="hide">{% for i in 0..7 %}<td></td>{% endfor %}</tr>
{{ rows|raw }}
</tbody>
</table>
</form>
</div>

View file

@ -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|raw }}">
</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|raw }}">
<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>

View file

@ -0,0 +1,83 @@
<tr{% if row_class is not empty %} class="{{ row_class }}"{% endif %} data-filter-row="{{ routine.name|upper }}">
<td>
<input type="checkbox" class="checkall" name="item_name[]" value="{{ routine.name }}">
</td>
<td>
<span class="drop_sql hide">{{ sql_drop }}</span>
<strong>{{ routine.name }}</strong>
</td>
<td>
{{ routine.type }}
</td>
<td dir="ltr">
{{ routine.returns }}
</td>
<td>
{% if has_edit_privilege %}
<a class="ajax edit_anchor" href="{{ url('/database/routines', {
'db': db,
'table': table,
'edit_item': true,
'item_name': routine.name,
'item_type': routine.type
}) }}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</a>
{% else %}
{{ get_icon('bd_edit', 'Edit'|trans) }}
{% endif %}
</td>
<td>
{% if has_execute_privilege and execute_action is not empty %}
{% if execute_action == 'execute_routine' %}
<a class="ajax exec_anchor" href="{{ url('/database/routines', {'db': db, 'table': table}) }}" data-post="{{ get_common({
'execute_routine': true,
'item_name': routine.name,
'item_type': routine.type
}, '') }}">
{{ get_icon('b_nextpage', 'Execute'|trans) }}
</a>
{% else %}
<a class="ajax exec_anchor" href="{{ url('/database/routines', {
'db': db,
'table': table,
'execute_dialog': true,
'item_name': routine.name,
'item_type': routine.type
}) }}">
{{ get_icon('b_nextpage', 'Execute'|trans) }}
</a>
{% endif %}
{% else %}
{{ get_icon('bd_nextpage', 'Execute'|trans) }}
{% endif %}
</td>
<td>
{% if has_export_privilege %}
<a class="ajax export_anchor" href="{{ url('/database/routines', {
'db': db,
'table': table,
'export_item': true,
'item_name': routine.name,
'item_type': routine.type
}) }}">
{{ get_icon('b_export', 'Export'|trans) }}
</a>
{% else %}
{{ get_icon('bd_export', 'Export'|trans) }}
{% endif %}
</td>
<td>
{{ link_or_button(
url('/sql'),
{
'db': db,
'table': table,
'sql_query': sql_drop,
'goto': url('/database/routines', {'db': db})
},
get_icon('b_drop', 'Drop'|trans),
{'class': 'ajax drop_anchor'}
) }}
</td>
</tr>

View file

@ -0,0 +1,95 @@
<a id="db_search"></a>
<form id="db_search_form" method="post" action="{{ url('/database/search') }}" name="db_search" class="ajax lock-page">
{{ get_hidden_inputs(db) }}
<fieldset class="pma-fieldset">
<legend>{% trans 'Search in database' %}</legend>
<p>
<label for="criteriaSearchString" class="d-block">
{% trans 'Words or values to search for (wildcard: "%"):' %}
</label>
<input id="criteriaSearchString" name="criteriaSearchString" class="w-75" type="text" value="
{{- criteria_search_string }}">
</p>
<fieldset class="pma-fieldset">
<legend>{% trans 'Find:' %}</legend>
<div>
<input type="radio" name="criteriaSearchType" id="criteriaSearchTypeRadio1" value="1"{{ criteria_search_type == '1' ? ' checked' }}>
<label for="criteriaSearchTypeRadio1">{% trans 'at least one of the words' %} {{ show_hint('Words are separated by a space character (" ").'|trans) }}</label>
</div>
<div>
<input type="radio" name="criteriaSearchType" id="criteriaSearchTypeRadio2" value="2"{{ criteria_search_type == '2' ? ' checked' }}>
<label for="criteriaSearchTypeRadio2">{% trans 'all of the words' %} {{ show_hint('Words are separated by a space character (" ").'|trans) }}</label>
</div>
<div>
<input type="radio" name="criteriaSearchType" id="criteriaSearchTypeRadio3" value="3"{{ criteria_search_type == '3' ? ' checked' }}>
<label for="criteriaSearchTypeRadio3">{% trans 'the exact phrase as substring' %}</label>
</div>
<div>
<input type="radio" name="criteriaSearchType" id="criteriaSearchTypeRadio4" value="4"{{ criteria_search_type == '4' ? ' checked' }}>
<label for="criteriaSearchTypeRadio4">{% trans 'the exact phrase as whole field' %}</label>
</div>
<div>
<input type="radio" name="criteriaSearchType" id="criteriaSearchTypeRadio5" value="5"{{ criteria_search_type == '5' ? ' checked' }}>
<label for="criteriaSearchTypeRadio5">{% trans 'as regular expression' %} {{ show_mysql_docu('Regexp') }}</label>
</div>
</fieldset>
<fieldset class="pma-fieldset">
<legend>{% trans 'Inside tables:' %}</legend>
<p>
<a href="#" id="select_all">
{% trans 'Select all' %}
</a> /
<a href="#" id="unselect_all">
{% trans 'Unselect all' %}
</a>
</p>
<select class="resize-vertical" id="criteriaTables" 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="d-block">
{% trans 'Inside column:' %}
</label>
<input id="criteriaColumnName" type="text" name="criteriaColumnName" class="w-75" value="
{{- criteria_column_name is not empty ? criteria_column_name }}">
</p>
</fieldset>
<fieldset class="pma-fieldset 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 #}
<button class="btn btn-secondary" id="togglequerybox"></button>

View file

@ -0,0 +1,62 @@
<table class="table table-striped caption-top w-auto">
<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': url('/database/sql'),
'pos': 0,
'is_js_confirmed': 0
} %}
<td>
<a name="browse_search"
class="ajax browse_results"
href="{{ url('/sql', 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="{{ url('/sql', 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 %}

View file

@ -0,0 +1,15 @@
<form id="ajax_form" action="{{ url('/database/structure/add-prefix-table') }}" method="post">
{{ get_hidden_inputs(url_params) }}
<fieldset class="pma-fieldset input">
<table>
<tr>
<td>{% trans 'Add prefix' %}</td>
<td>
<input type="text" name="add_prefix" id="txtPrefix" aria-label="{% trans 'Add prefix' %}">
</td>
</tr>
<tr>
</table>
</fieldset>
</form>

View file

@ -0,0 +1,93 @@
<tfoot id="tbl_summary_row">
<tr>
<th class="d-print-none"></th>
<th class="tbl_num text-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_replica_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="d-print-none">{% 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_all': 'true'
} %}
{% endif %}
{% if approx_rows %}
{% set cell_text -%}
<a href="{{ url('/database/structure/real-row-count', 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 font-monospace text-end">{{ 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="text-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 font-monospace text-end">{{ 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 font-monospace text-end">{{ 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 font-monospace text-end">
{{ create_time_all }}
</th>
{% endif %}
{% if show_last_update %}
<th class="value tbl_last_update font-monospace text-end">
{{ update_time_all }}
</th>
{% endif %}
{% if show_last_check %}
<th class="value tbl_last_check font-monospace text-end">
{{ check_time_all }}
</th>
{% endif %}
</tr>
</tfoot>

View file

@ -0,0 +1,16 @@
<div class="modal fade" id="bulkActionModal" data-bs-backdrop="static" data-bs-keyboard="false"
tabindex="-1" aria-labelledby="bulkActionLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="bulkActionLabel"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Cancel' %}"></button>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
<button type="button" class="btn btn-primary" id="bulkActionContinue">{% trans 'Continue' %}</button>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,20 @@
<form id="ajax_form" action="{{ url(route) }}" method="post">
{{ get_hidden_inputs(url_params) }}
<fieldset class="pma-fieldset input">
<table>
<tr>
<td>{% trans 'From' %}</td>
<td>
<input type="text" name="from_prefix" id="initialPrefix">
</td>
</tr>
<tr>
<td>{% trans 'To' %}</td>
<td>
<input type="text" name="to_prefix" id="newPrefix">
</td>
</tr>
</table>
</fieldset>
</form>

View file

@ -0,0 +1,61 @@
<div class="clearfloat d-print-none">
<img class="selectallarrow" src="{{ 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>
{% if central_columns_work is defined and central_columns_work %}
<div class="modal fade" id="makeConsistentWithCentralListModal" data-bs-backdrop="static" data-bs-keyboard="false"
tabindex="-1" aria-labelledby="makeConsistentWithCentralListModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="makeConsistentWithCentralListModalLabel">{% trans 'Are you sure?' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Cancel' %}"></button>
</div>
<div class="modal-body">
{{ 'This action may change some of the columns definition.[br]Are you sure you want to continue?'|trans|sanitize }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
<button type="button" class="btn btn-primary" id="makeConsistentWithCentralListContinue">{% trans 'Continue' %}</button>
</div>
</div>
</div>
</div>
{% endif %}

View file

@ -0,0 +1 @@
<dfn title="{{ valueTitle }}">{{ value }}</dfn>

View file

@ -0,0 +1,54 @@
<form id="ajax_form" action="{{ url('/database/structure/copy-table') }}" method="post">
{{ get_hidden_inputs(url_params) }}
<fieldset class="pma-fieldset">
<strong><label for="db_name_dropdown">{% trans 'Database:' %}</label></strong>
<select id="db_name_dropdown" name="target_db">
{% for each_db in options %}
<option value="{{ each_db.name }}"{{ each_db.is_selected ? ' selected' }}>{{ each_db.name }}</option>
{% endfor %}
</select>
<br><br>
<strong><label>{% trans 'Options:' %}</label></strong>
<br>
<input type="radio" id="what_structure" value="structure" name="what">
<label for="what_structure">{% trans 'Structure only' %}</label>
<br>
<input type="radio" id="what_data" value="data" name="what" checked>
<label for="what_data">{% trans 'Structure and data' %}</label>
<br>
<input type="radio" id="what_dataonly" value="dataonly" name="what">
<label for="what_dataonly">{% trans 'Data only' %}</label>
<br><br>
<input type="checkbox" id="checkbox_drop" value="true" name="drop_if_exists">
<label for="checkbox_drop">{% trans 'Add DROP TABLE' %}</label>
<br>
<input type="checkbox" id="checkbox_auto_increment_cp" value="1" name="sql_auto_increment">
<label for="checkbox_auto_increment_cp">{% trans 'Add AUTO INCREMENT value' %}</label>
<br>
<input type="checkbox" id="checkbox_constraints" value="1" name="sql_auto_increment" checked>
<label for="checkbox_constraints">{% trans 'Add constraints' %}</label>
<br><br>
<input type="checkbox" name="adjust_privileges" value="1" id="checkbox_adjust_privileges" checked>
<label for="checkbox_adjust_privileges">
{% trans 'Adjust privileges' %}
{{ show_docu('faq', 'faq6-39') }}
</label>
</fieldset>
</form>

View file

@ -0,0 +1,23 @@
<form action="{{ url('/database/structure/drop-table') }}" method="post">
{{ get_hidden_inputs(url_params) }}
<fieldset class="pma-fieldset confirmation">
<legend>
{% trans 'Do you really want to execute the following query?' %}
</legend>
<code>{{ full_query|raw }}</code>
</fieldset>
<fieldset class="pma-fieldset tblFooters">
<div id="foreignkeychk" class="float-start">
<input type="hidden" name="fk_checks" value="0">
<input type="checkbox" name="fk_checks" id="fk_checks" value="1"{{ is_foreign_key_check ? ' checked' }}>
<label for="fk_checks">{% trans 'Enable foreign key checks' %}</label>
</div>
<div class="float-end">
<input id="buttonYes" class="btn btn-secondary" type="submit" name="mult_btn" value="{% trans 'Yes' %}">
<input id="buttonNo" class="btn btn-secondary" type="submit" name="mult_btn" value="{% trans 'No' %}">
</div>
</fieldset>
</form>

View file

@ -0,0 +1,23 @@
<form action="{{ url('/database/structure/empty-table') }}" class="disableAjax" method="post">
{{ get_hidden_inputs(url_params) }}
<fieldset class="pma-fieldset confirmation">
<legend>
{% trans 'Do you really want to execute the following query?' %}
</legend>
<code>{{ full_query|raw }}</code>
</fieldset>
<fieldset class="pma-fieldset tblFooters">
<div id="foreignkeychk" class="float-start">
<input type="hidden" name="fk_checks" value="0">
<input type="checkbox" name="fk_checks" id="fk_checks" value="1"{{ is_foreign_key_check ? ' checked' }}>
<label for="fk_checks">{% trans 'Enable foreign key checks' %}</label>
</div>
<div class="float-end">
<input id="buttonYes" class="btn btn-secondary" type="submit" name="mult_btn" value="{% trans 'Yes' %}">
<input id="buttonNo" class="btn btn-secondary" type="submit" name="mult_btn" value="{% trans 'No' %}">
</div>
</fieldset>
</form>

View file

@ -0,0 +1,7 @@
<a id="{{ table_name_hash }}_favorite_anchor"
class="ajax favorite_table_anchor"
href="{{ url('/database/structure/favorite-table', fav_params) }}"
title="{{ already_favorite ? 'Remove from Favorites'|trans : 'Add to Favorites'|trans }}"
data-favtargets="{{ db_table_name_hash }}">
{{ already_favorite ? get_icon('b_favorite') : get_icon('b_no_favorite') }}
</a>

View file

@ -0,0 +1,30 @@
{% for flash_key, flash_messages in flash() %}
{% for flash_message in flash_messages %}
<div class="alert alert-{{ flash_key }}" role="alert">
{{ flash_message }}
</div>
{% endfor %}
{% endfor %}
{% if has_tables %}
<div id="tableslistcontainer">
{{ list_navigator_html|raw }}
{{ table_list_html|raw }}
{{ list_navigator_html|raw }}
</div>
<hr>
<p class="d-print-none">
<button type="button" class="btn btn-link p-0 jsPrintButton">{{ get_icon('b_print', 'Print'|trans, true) }}</button>
<a href="{{ url('/database/data-dictionary', {'db': database, 'goto': url('/database/structure')}) }}">
{{ 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 %}

View file

@ -0,0 +1,4 @@
<a href="{{ url('/table/structure', table_url_params) }}#showusage" id="overhead">
<span>{{ formatted_overhead }}</span>&nbsp;
<span class="unit">{{ overhead_unit }}</span>
</a>

View file

@ -0,0 +1,47 @@
<div class="show_create_results">
<h2>{% trans 'Showing create queries' %}</h2>
{% if tables.tables is not empty %}
<fieldset class="pma-fieldset">
<legend>{% trans 'Tables' %}</legend>
<table class="table table-striped show_create">
<thead>
<tr>
<th>{% trans 'Table' %}</th>
<th>{% trans 'Create table' %}</th>
</tr>
</thead>
<tbody>
{% for table in tables.tables %}
<tr>
<td><strong>{{ table.name|raw }}</strong></td>
<td>{{ table.show_create|raw }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
{% endif %}
{% if tables.views is not empty %}
<fieldset class="pma-fieldset">
<legend>{% trans 'Views' %}</legend>
<table class="table table-striped show_create">
<thead>
<tr>
<th>{% trans 'View' %}</th>
<th>{% trans 'Create view' %}</th>
</tr>
</thead>
<tbody>
{% for view in tables.views %}
<tr>
<td><strong>{{ view.name }}</strong></td>
<td>{{ view.show_create|raw }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
{% endif %}
</div>

View file

@ -0,0 +1,226 @@
<tr id="row_tbl_{{ curr }}"{{ table_is_view ? ' class="is_view"' }} data-filter-row="{{ current_table['TABLE_NAME']|upper }}">
<td class="text-center d-print-none">
<input type="checkbox"
name="selected_tbl[]"
class="{{ input_class }}"
value="{{ current_table['TABLE_NAME'] }}"
id="checkbox_tbl_{{ curr }}">
</td>
<th>
<a href="{{ url('/sql', table_url_params|merge({'pos': 0})) }}" title="{{ browse_table_label_title }}">
{{- browse_table_label_truename -}}
</a>
{{ tracking_icon|raw }}
</th>
{% if server_replica_status %}
<td class="text-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="text-center d-print-none">
{# 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,
} only %}
</td>
{% endif %}
<td class="text-center d-print-none">
<a href="{{ url('/sql', table_url_params|merge({'pos': 0})) }}">
{{ may_have_rows ? get_icon('b_browse', 'Browse'|trans) : get_icon('bd_browse', 'Browse'|trans) }}
</a>
</td>
<td class="text-center d-print-none">
<a href="{{ url('/table/structure', table_url_params) }}">
{{ get_icon('b_props', 'Structure'|trans) }}
</a>
</td>
<td class="text-center d-print-none">
<a href="{{ url('/table/search', table_url_params) }}">
{{ may_have_rows ? get_icon('b_select', 'Search'|trans) : get_icon('bd_select', 'Search'|trans) }}
</a>
</td>
{% if not db_is_system_schema %}
<td class="insert_table text-center d-print-none">
<a href="{{ url('/table/change', table_url_params) }}">{{ get_icon('b_insrow', 'Insert'|trans) }}</a>
</td>
{% if table_is_view %}
<td class="text-center d-print-none">
<a href="{{ url('/view/create', {
'db': db,
'table': current_table['TABLE_NAME']
}) }}">{{ get_icon('b_edit', 'Edit'|trans) }}</a>
</td>
{% else %}
<td class="text-center d-print-none">
<a class="truncate_table_anchor ajax" href="{{ url('/sql') }}" data-post="{{ get_common(table_url_params|merge({
'sql_query': empty_table_sql_query,
'message_to_show': empty_table_message_to_show
}), '') }}">
{{ may_have_rows ? get_icon('b_empty', 'Empty'|trans) : get_icon('bd_empty', 'Empty'|trans) }}
</a>
</td>
{% endif %}
<td class="text-center d-print-none">
<a class="ajax drop_table_anchor
{{- table_is_view or current_table['ENGINE'] == null ? ' view' }}" href="{{ url('/sql') }}" data-post="
{{- get_common(table_url_params|merge({
'reload': 1,
'purge': 1,
'sql_query': drop_query,
'message_to_show': drop_message
}), '') }}">
{{ get_icon('b_drop', 'Drop'|trans) }}
</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 font-monospace text-end"
data-table="{{ current_table['TABLE_NAME'] }}">
{% if approx_rows %}
<a href="{{ url('/database/structure/real-row-count', {
'ajax_request': true,
'db': db,
'table': current_table['TABLE_NAME']
}) }}" 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="text-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="text-nowrap">
{{ collation|raw }}
</td>
{% endif %}
{% endif %}
{% if is_show_stats %}
<td class="value tbl_size font-monospace text-end">
<a href="{{ url('/table/structure', table_url_params) }}#showusage">
<span>{{ formatted_size }}</span>&nbsp;<span class="unit">{{ unit }}</span>
</a>
</td>
<td class="value tbl_overhead font-monospace text-end">
{{ overhead|raw }}
</td>
{% endif %}
{% if not (show_charset > 1) %}
{% if charset|length > 0 %}
<td class="text-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 font-monospace text-end">
{{ create_time }}
</td>
{% endif %}
{% if show_last_update %}
<td class="value tbl_last_update font-monospace text-end">
{{ update_time }}
</td>
{% endif %}
{% if show_last_check %}
<td class="value tbl_last_check font-monospace text-end">
{{ check_time }}
</td>
{% endif %}
{% elseif table_is_view %}
<td class="value tbl_rows font-monospace text-end">-</td>
<td class="text-nowrap">
{% trans 'View' %}
</td>
<td class="text-nowrap">---</td>
{% if is_show_stats %}
<td class="value tbl_size font-monospace text-end">-</td>
<td class="value tbl_overhead font-monospace text-end">-</td>
{% endif %}
{% if show_charset %}
<td></td>
{% endif %}
{% if show_comment %}
<td></td>
{% endif %}
{% if show_creation %}
<td class="value tbl_creation font-monospace text-end">-</td>
{% endif %}
{% if show_last_update %}
<td class="value tbl_last_update font-monospace text-end">-</td>
{% endif %}
{% if show_last_check %}
<td class="value tbl_last_check font-monospace text-end">-</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="text-center">
{% trans 'in use' %}
</td>
{% endif %}
</tr>

View file

@ -0,0 +1,81 @@
<form method="post" action="{{ url('/database/structure') }}" name="tablesForm" id="tablesForm">
{{ get_hidden_inputs(db) }}
<div class="table-responsive">
<table class="table table-striped table-hover table-sm w-auto data">
<thead>
<tr>
<th class="d-print-none"></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="d-print-none">
{% 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>
{% if check_all_tables %}
{% include 'database/structure/bulk_action_modal.twig' with check_all_tables only %}
{% endif %}

View file

@ -0,0 +1,7 @@
<a href="{{ url('/table/tracking', {'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>

View file

@ -0,0 +1,192 @@
{# Tracked tables exists#}
{% if head_version_exists %}
<div id="tracked_tables">
<h3>{% trans 'Tracked tables' %}</h3>
<form method="post" action="{{ url('/database/tracking') }}" name="trackedForm"
id="trackedForm" class="ajax">
{{ get_hidden_inputs(db) }}
<table id="versions" class="table table-striped table-hover w-auto">
<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="text-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="text-end">
{{ version.version }}
</td>
<td>
{{ version.date_created }}
</td>
<td>
{{ version.date_updated }}
</td>
<td>
<div class="wrapper toggleAjax hide">
<div class="toggleButton">
<div title="{% trans 'Click to toggle' %}" class="toggle-container {{ version.tracking_active == 1 ? 'on' : 'off' }}">
<img src="{{ image('toggle-' ~ text_dir ~ '.png') }}">
<table>
<tbody>
<tr>
<td class="toggleOn">
<span class="hide">
{{- url('/table/tracking', {
'db': version.db_name,
'table': version.table_name,
'version': version.version,
'toggle_activation': 'activate_now',
}) -}}
</span>
<div>{% trans 'active' %}</div>
</td>
<td><div>&nbsp;</div></td>
<td class="toggleOff">
<span class="hide">
{{- url('/table/tracking', {
'db': version.db_name,
'table': version.table_name,
'version': version.version,
'toggle_activation': 'deactivate_now',
}) -}}
</span>
<div>{% trans 'not active' %}</div>
</td>
</tr>
</tbody>
</table>
<span class="hide callback"></span>
<span class="hide text_direction">{{ text_dir }}</span>
</div>
</div>
</div>
</td>
<td>
<a class="delete_tracking_anchor ajax" href="{{ url('/database/tracking') }}" data-post="
{{- get_common({
'db': db,
'goto': url('/table/tracking'),
'back': url('/database/tracking'),
'table': version.table_name,
'delete_tracking': true
}, '', false) }}">
{{ get_icon('b_drop', 'Delete tracking'|trans) }}
</a>
</td>
<td>
<a href="{{ url('/table/tracking') }}" data-post="
{{- get_common({
'db': db,
'goto': url('/table/tracking'),
'back': url('/database/tracking'),
'table': version.table_name
}, '', false) }}">
{{ get_icon('b_versions', 'Versions'|trans) }}
</a>
<a href="{{ url('/table/tracking') }}" data-post="
{{- get_common({
'db': db,
'goto': url('/table/tracking'),
'back': url('/database/tracking'),
'table': version.table_name,
'report': true,
'version': version.version
}, '', false) }}">
{{ get_icon('b_report', 'Tracking report'|trans) }}
</a>
<a href="{{ url('/table/tracking') }}" data-post="
{{- get_common({
'db': db,
'goto': url('/table/tracking'),
'back': url('/database/tracking'),
'table': version.table_name,
'snapshot': true,
'version': version.version
}, '', false) }}">
{{ get_icon('b_props', 'Structure snapshot'|trans) }}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include 'select_all.twig' with {
'text_dir': text_dir,
'form_name': 'trackedForm'
} only %}
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="delete_tracking"
title="{% trans 'Delete tracking' %}">
{{ get_icon('b_drop', 'Delete tracking'|trans) }}
</button>
</form>
</div>
{% endif %}
{% if untracked_tables_exists %}
<h3>{% trans 'Untracked tables' %}</h3>
<form method="post" action="{{ url('/database/tracking') }}" name="untrackedForm"
id="untrackedForm" class="ajax">
{{ get_hidden_inputs(db) }}
<table id="noversions" class="table table-striped table-hover w-auto">
<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="text-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="{{ url('/table/tracking', url_params|merge({
'db': db,
'table': table_name
})) }}">
{{ get_icon('eye', 'Track table'|trans) }}
</a>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% include 'select_all.twig' with {
'text_dir': text_dir,
'form_name': 'untrackedForm'
} only %}
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="track" title="{% trans 'Track table' %}">
{{ get_icon('eye', 'Track table'|trans) }}
</button>
</form>
{% endif %}

View file

@ -0,0 +1,73 @@
<form class="rte_form" action="{{ url('/database/triggers') }}" method="post">
{{ get_hidden_inputs(db, table) }}
<input name="{{ is_edit ? 'edit_item' : 'add_item' }}" type="hidden" value="1">
{% if is_edit %}
<input name="item_original_name" type="hidden" value="{{ item.item_original_name }}">
{% endif %}
{% if is_ajax %}
<input type="hidden" name="{{ is_edit ? 'editor_process_edit' : 'editor_process_add' }}" value="true">
<input type="hidden" name="ajax_request" value="true">
{% endif %}
<div class="card">
<div class="card-header">
{% trans 'Details' %}
{% if not is_edit %}
{{ show_mysql_docu('CREATE_TRIGGER') }}
{% endif %}
</div>
<div class="card-body">
<table class="rte_table table table-borderless table-sm">
<tr>
<td>{% trans 'Trigger name' %}</td>
<td><input type="text" name="item_name" maxlength="64" value="{{ item.item_name }}"></td>
</tr>
<tr>
<td>{% trans 'Table' %}</td>
<td>
<select name="item_table">
{% for item_table in tables %}
<option value="{{ item_table }}"{{ (is_edit and item_table == item.item_table) or (not is_edit and item_table == table) ? ' selected' }}>{{ item_table }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>{% trans %}Time{% context %}Trigger action time{% endtrans %}</td>
<td>
<select name="item_timing">
{% for item_time in time %}
<option value="{{ item_time }}"{{ item.item_action_timing == item_time ? ' selected' }}>{{ item_time }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>{% trans 'Event' %}</td>
<td>
<select name="item_event">
{% for event in events %}
<option value="{{ event }}"{{ item.item_event_manipulation == event ? ' selected' }}>{{ event }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td>{% trans 'Definition' %}</td>
<td><textarea name="item_definition" rows="15" cols="40">{{ item.item_definition }}</textarea></td>
</tr>
<tr>
<td>{% trans 'Definer' %}</td>
<td><input type="text" name="item_definer" value="{{ item.item_definer }}"></td>
</tr>
</table>
</div>
{% if not is_ajax %}
<div class="card-footer">
<input class="btn btn-primary" type="submit" name="{{ is_edit ? 'editor_process_edit' : 'editor_process_add' }}" value="{% trans 'Go' %}">
</div>
{% endif %}
</div>
</form>

View file

@ -0,0 +1,9 @@
<div class="container">
<h2>{{ 'Export of trigger %s'|trans|format(backquote(item_name)) }}</h2>
<div class="card">
<div class="card-body">
<textarea rows="15" class="form-control">{{ data|trim }}</textarea>
</div>
</div>
</div>

View file

@ -0,0 +1,59 @@
<div class="container-fluid my-3">
<h2>
{{ get_icon('b_triggers', 'Triggers'|trans) }}
{{ show_mysql_docu('TRIGGERS') }}
</h2>
<div class="d-flex flex-wrap my-3">
<div>
<div class="input-group">
<div class="input-group-text">
<div class="form-check mb-0">
<input class="form-check-input checkall_box" type="checkbox" value="" id="checkAllCheckbox" form="rteListForm">
<label class="form-check-label" for="checkAllCheckbox">{% trans 'Check all' %}</label>
</div>
</div>
<button class="btn btn-outline-secondary" id="bulkActionExportButton" type="submit" name="submit_mult" value="export" form="rteListForm" title="{% trans 'Export' %}">
{{ get_icon('b_export', 'Export'|trans) }}
</button>
<button class="btn btn-outline-secondary" id="bulkActionDropButton" type="submit" name="submit_mult" value="drop" form="rteListForm" title="{% trans 'Drop' %}">
{{ get_icon('b_drop', 'Drop'|trans) }}
</button>
</div>
</div>
<div class="ms-auto">
<a class="ajax add_anchor btn btn-primary{{ not has_privilege ? ' disabled' }}" href="{{ url('/database/triggers', {'db': db, 'table': table, 'add_item': true}) }}" role="button"{{ not has_privilege ? ' tabindex="-1" aria-disabled="true"' }}>
{{ get_icon('b_trigger_add', 'Create new trigger'|trans) }}
</a>
</div>
</div>
<form id="rteListForm" class="ajax" action="{{ url(table is not empty ? '/table/triggers' : '/database/triggers') }}">
{{ get_hidden_inputs(db, table) }}
<div id="nothing2display"{{ items is not empty ? ' class="hide"' }}>
{% trans 'There are no triggers to display.' %}
</div>
<table id="triggersTable" class="table table-striped table-hover{{ items is empty ? ' hide' }} w-auto data">
<thead>
<tr>
<th></th>
<th>{% trans 'Name' %}</th>
{% if table is empty %}
<th>{% trans 'Table' %}</th>
{% endif %}
<th>{% trans 'Time' %}</th>
<th>{% trans 'Event' %}</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr class="hide">{% for i in 0..(table is empty ? 7 : 6) %}<td></td>{% endfor %}</tr>
{{ rows|raw }}
</tbody>
</table>
</form>
</div>

View file

@ -0,0 +1,61 @@
<tr{% if row_class is not empty %} class="{{ row_class }}"{% endif %}>
<td>
<input type="checkbox" class="checkall" name="item_name[]" value="{{ trigger.name }}">
</td>
<td>
<span class='drop_sql hide'>{{ trigger.drop }}</span>
<strong>{{ trigger.name }}</strong>
</td>
{% if table is empty %}
<td>
<a href="{{ url('/table/triggers', {'db': db, 'table': trigger.table}) }}">{{ trigger.table }}</a>
</td>
{% endif %}
<td>
{{ trigger.action_timing }}
</td>
<td>
{{ trigger.event_manipulation }}
</td>
<td>
{% if has_edit_privilege %}
<a class="ajax edit_anchor" href="{{ url('/database/triggers', {
'db': db,
'table': table,
'edit_item': true,
'item_name': trigger.name
}) }}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</a>
{% else %}
{{ get_icon('bd_edit', 'Edit'|trans) }}
{% endif %}
</td>
<td>
<a class="ajax export_anchor" href="{{ url('/database/triggers', {
'db': db,
'table': table,
'export_item': true,
'item_name': trigger.name
}) }}">
{{ get_icon('b_export', 'Export'|trans) }}
</a>
</td>
<td>
{% if has_drop_privilege %}
{{ link_or_button(
url('/sql'),
{
'db': db,
'table': table,
'sql_query': trigger.drop,
'goto': url('/database/triggers', {'db': db})
},
get_icon('b_drop', 'Drop'|trans),
{'class': 'ajax drop_anchor'}
) }}
{% else %}
{{ get_icon('bd_drop', 'Drop'|trans) }}
{% endif %}
</td>
</tr>

View file

@ -0,0 +1,91 @@
{% if position == 'left' %}
{% if has_checkbox %}
<td class="text-center d-print-none">
<input type="checkbox" class="multi_checkbox checkall" id="id_rows_to_delete
{{- row_number }}_left" name="rows_to_delete[{{ row_number }}]" value="{{ where_clause }}">
<input type="hidden" class="condition_array" value="{{ condition }}">
</td>
{% endif %}
{% if edit.url is not empty %}
<td class="text-center d-print-none edit_row_anchor{{ not edit.clause_is_unique ? ' nonunique' }}">
<span class="text-nowrap">
{{ link_or_button(edit.url, edit.params, edit.string) }}
{% if where_clause is not empty %}
<input type="hidden" class="where_clause" value="{{ where_clause }}">
{% endif %}
</span>
</td>
{% endif %}
{% if copy.url is not empty %}
<td class="text-center d-print-none">
<span class="text-nowrap">
{{ link_or_button(copy.url, copy.params, copy.string) }}
{% if where_clause is not empty %}
<input type="hidden" class="where_clause" value="{{ where_clause }}">
{% endif %}
</span>
</td>
{% endif %}
{% if delete.url is not empty %}
<td class="text-center d-print-none{{ is_ajax ? ' ajax' }}">
<span class="text-nowrap">
{{ link_or_button(delete.url, delete.params, delete.string, {'class': 'delete_row requireConfirm' ~ (is_ajax ? ' ajax') }) }}
{% if js_conf is not empty %}
<div class="hide">{{ js_conf }}</div>
{% endif %}
</span>
</td>
{% endif %}
{% elseif position == 'right' %}
{% if delete.url is not empty %}
<td class="text-center d-print-none{{ is_ajax ? ' ajax' }}">
<span class="text-nowrap">
{{ link_or_button(delete.url, delete.params, delete.string, {'class': 'delete_row requireConfirm' ~ (is_ajax ? ' ajax') }) }}
{% if js_conf is not empty %}
<div class="hide">{{ js_conf }}</div>
{% endif %}
</span>
</td>
{% endif %}
{% if copy.url is not empty %}
<td class="text-center d-print-none">
<span class="text-nowrap">
{{ link_or_button(copy.url, copy.params, copy.string) }}
{% if where_clause is not empty %}
<input type="hidden" class="where_clause" value="{{ where_clause }}">
{% endif %}
</span>
</td>
{% endif %}
{% if edit.url is not empty %}
<td class="text-center d-print-none edit_row_anchor{{ not edit.clause_is_unique ? ' nonunique' }}">
<span class="text-nowrap">
{{ link_or_button(edit.url, edit.params, edit.string) }}
{% if where_clause is not empty %}
<input type="hidden" class="where_clause" value="{{ where_clause }}">
{% endif %}
</span>
</td>
{% endif %}
{% if has_checkbox %}
<td class="text-center d-print-none">
<input type="checkbox" class="multi_checkbox checkall" id="id_rows_to_delete
{{- row_number }}_right" name="rows_to_delete[{{ row_number }}]" value="{{ where_clause }}">
<input type="hidden" class="condition_array" value="{{ condition }}">
</td>
{% endif %}
{% else %}
{% if has_checkbox %}
<td class="text-center d-print-none">
<input type="checkbox" class="multi_checkbox checkall" id="id_rows_to_delete
{{- row_number }}_left" name="rows_to_delete[{{ row_number }}]" value="{{ where_clause }}">
<input type="hidden" class="condition_array" value="{{ condition }}">
</td>
{% endif %}
{% endif %}

View file

@ -0,0 +1,10 @@
{% if comments_map[table_name] is defined
and comments_map[table_name][column_name] is defined %}
<br><span class="tblcomment" title="{{ comments_map[table_name][column_name] }}">
{% if comments_map[table_name][column_name]|length > limit_chars %}
{{ comments_map[table_name][column_name]|slice(0, limit_chars) }}
{% else %}
{{ comments_map[table_name][column_name] }}
{% endif %}
</span>
{% endif %}

View file

@ -0,0 +1 @@
<td class="{{ classes }}"></td>

View file

@ -0,0 +1,6 @@
<td data-decimals="{{ data_decimals }}"
data-type="{{ data_type }}"
{# The null class is needed for grid editing #}
class="{{ classes }} null">
<em>NULL</em>
</td>

View file

@ -0,0 +1,6 @@
<td>
<form action="{{ url('/sql') }}" method="post">
{{ get_hidden_inputs(url_params) }}
{{ page_selector|raw }}
</form>
</td>

View file

@ -0,0 +1,3 @@
<td data-decimals="{{ decimals }}" data-type="{{ type }}"{% if original_length is not empty %} data-originallength="{{ original_length }}"{% endif %} class="{{ td_class }}">
{{- value|raw -}}
</td>

View file

@ -0,0 +1,307 @@
{% set navigation_html %}
{% if navigation is not empty %}
<table class="navigation d-print-none">
<tr>
<td class="navigation_separator"></td>
{{ navigation.move_backward_buttons|raw }}
{{ navigation.page_selector|raw }}
{{ navigation.move_forward_buttons|raw }}
{% if navigation.number_total_page != 1 %}
<td><div class="navigation_separator">|</div></td>
{% endif %}
{% if navigation.has_show_all %}
<td>
<form action="{{ url('/sql') }}" method="post">
{{ get_hidden_fields(navigation.hidden_fields|merge({
'session_max_rows': navigation.session_max_rows,
'pos': '0'
})) }}
<input type="checkbox" name="navig" id="showAll_{{ unique_id }}" class="showAllRows" value="all"
{{- navigation.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">
<form action="{{ url('/sql') }}" method="post" class="maxRowsForm">
{{ get_hidden_fields(navigation.hidden_fields|merge({
'pos': navigation.pos,
'unlim_num_rows': unlim_num_rows
})) }}
<label for="sessionMaxRowsSelect">{% trans 'Number of rows:' %}</label>
<select class="autosubmit" name="session_max_rows" id="sessionMaxRowsSelect">
{% if navigation.is_showing_all %}
<option value="" disabled selected>{% trans 'All' %}</option>
{% endif %}
{% for option in ['25', '50', '100', '250', '500'] %}
<option value="{{ option }}"{{ navigation.max_rows == option ? ' selected' }}>{{ option }}</option>
{% endfor %}
</select>
</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">
{% if navigation.sort_by_key is not empty %}
<form action="{{ url('/sql') }}" method="post" class="d-print-none">
{{ get_hidden_fields(navigation.sort_by_key.hidden_fields) }}
{% trans 'Sort by key:' %}
<select name="sql_query" class="autosubmit">
{% for option in navigation.sort_by_key.options %}
<option value="{{ option.value }}"{{ option.is_selected ? ' selected' }}>{{ option.content }}</option>
{% endfor %}
</select>
</form>
{% endif %}
</td>
<td class="navigation_separator"></td>
</tr>
</table>
{% endif %}
{% endset %}
{{ sql_query_message|raw }}
{{ navigation_html }}
<input class="save_cells_at_once" type="hidden" value="{{ save_cells_at_once }}">
<div class="common_hidden_inputs">
{{ get_hidden_inputs(db, table) }}
</div>
{% if headers.column_order is not empty %}
{% if headers.column_order.order %}
<input class="col_order" type="hidden" value="{{ headers.column_order.order|join(',') }}">
{% endif %}
{% if headers.column_order.visibility %}
<input class="col_visib" type="hidden" value="{{ headers.column_order.visibility|join(',') }}">
{% endif %}
{% if not headers.column_order.is_view %}
<input class="table_create_time" type="hidden" value="{{ headers.column_order.table_create_time }}">
{% endif %}
{% endif %}
{% if headers.options is not empty %}
<form method="post" action="{{ url('/sql') }}" name="displayOptionsForm" class="ajax d-print-none">
{{ get_hidden_inputs({
'db': db,
'table': table,
'sql_query': sql_query,
'goto': goto,
'display_options_form': 1
}) }}
{% if default_sliders_state != 'disabled' %}
<div class="mb-3">
<button class="btn btn-sm btn-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#extraOptions" aria-expanded="{{ default_sliders_state == 'open' ? 'true' : 'false' }}" aria-controls="extraOptions">
{% trans 'Extra options' %}
</button>
</div>
<div class="collapse mb-3{{ default_sliders_state == 'open' ? ' show' }}" id="extraOptions">
{% endif %}
<fieldset class="pma-fieldset">
<div class="formelement">
<div>
<input type="radio" name="pftext" id="partialFulltextRadioP{{ unique_id }}" value="P"{{ headers.options.pftext == 'P' ? ' checked' }}>
<label for="partialFulltextRadioP{{ unique_id }}">{% trans 'Partial texts' %}</label>
</div>
<div>
<input type="radio" name="pftext" id="partialFulltextRadioF{{ unique_id }}" value="F"{{ headers.options.pftext == 'F' ? ' checked' }}>
<label for="partialFulltextRadioF{{ unique_id }}">{% trans 'Full texts' %}</label>
</div>
</div>
{% if relwork and displaywork %}
<div class="formelement">
<div>
<input type="radio" name="relational_display" id="relationalDisplayRadioK{{ unique_id }}" value="K"{{ headers.options.relational_display == 'K' ? ' checked' }}>
<label for="relationalDisplayRadioK{{ unique_id }}">{% trans 'Relational key' %}</label>
</div>
<div>
<input type="radio" name="relational_display" id="relationalDisplayRadioD{{ unique_id }}" value="D"{{ headers.options.relational_display == 'D' ? ' checked' }}>
<label for="relationalDisplayRadioD{{ unique_id }}">{% trans 'Display column for relationships' %}</label>
</div>
</div>
{% endif %}
<div class="formelement">
<input type="checkbox" name="display_binary" id="display_binary_{{ unique_id }}"
{{- headers.options.display_binary is not empty ? ' checked' }}>
<label for="display_binary_{{ unique_id }}">{% trans 'Show binary contents' %}</label>
<input type="checkbox" name="display_blob" id="display_blob_{{ unique_id }}"
{{- headers.options.display_blob is not empty ? ' checked' }}>
<label for="display_blob_{{ unique_id }}">{% trans 'Show BLOB contents' %}</label>
</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">
<input type="checkbox" name="hide_transformation" id="hide_transformation_{{ unique_id }}"
{{- headers.options.hide_transformation is not empty ? ' checked' }}>
<label for="hide_transformation_{{ unique_id }}">{% trans 'Hide browser transformation' %}</label>
</div>
<div class="formelement">
{% if headers.options.possible_as_geometry %}
<div>
<input type="radio" name="geoOption" id="geoOptionRadioGeom{{ unique_id }}" value="GEOM"{{ headers.options.geo_option == 'GEOM' ? ' checked' }}>
<label for="geoOptionRadioGeom{{ unique_id }}">{% trans 'Geometry' %}</label>
</div>
{% endif %}
<div>
<input type="radio" name="geoOption" id="geoOptionRadioWkt{{ unique_id }}" value="WKT"{{ headers.options.geo_option == 'WKT' ? ' checked' }}>
<label for="geoOptionRadioWkt{{ unique_id }}">{% trans 'Well Known Text' %}</label>
</div>
<div>
<input type="radio" name="geoOption" id="geoOptionRadioWkb{{ unique_id }}" value="WKB"{{ headers.options.geo_option == 'WKB' ? ' checked' }}>
<label for="geoOptionRadioWkb{{ unique_id }}">{% trans 'Well Known Binary' %}</label>
</div>
</div>
<div class="clearfloat"></div>
</fieldset>
<fieldset class="pma-fieldset tblFooters">
<input class="btn btn-primary" type="submit" value="{% trans 'Go' %}">
</fieldset>
{% if default_sliders_state != 'disabled' %}
</div>
{% endif %}
</form>
{% endif %}
{% if headers.has_bulk_actions_form %}
<form method="post" name="resultsForm" id="resultsForm_{{ unique_id }}" class="ajax">
{{ get_hidden_inputs(db, table, 1) }}
<input type="hidden" name="goto" value="{{ url('/sql') }}">
{% endif %}
<div class="table-responsive-md">
<table class="table table-striped table-hover table-sm table_results data ajax w-auto" data-uniqueId="{{ unique_id }}">
{{ headers.button|raw }}
{{ headers.table_headers_for_columns|raw }}
{{ headers.column_at_right_side|raw }}
</tr>
</thead>
<tbody>
{{ body|raw }}
</tbody>
</table>
</div>
{% if bulk_links is not empty %}
<div class="d-print-none">
<img class="selectallarrow" src="{{ image('arrow_' ~ text_dir ~ '.png') }}" width="38" height="22" alt="{% trans 'With selected:' %}">
<input type="checkbox" id="resultsForm_{{ unique_id }}_checkall" class="checkall_box" title="{% trans 'Check all' %}">
<label for="resultsForm_{{ unique_id }}_checkall">{% trans 'Check all' %}</label>
<em class="with-selected">{% trans 'With selected:' %}</em>
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="edit" title="{% trans 'Edit' %}">
{{ get_icon('b_edit', 'Edit'|trans) }}
</button>
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="copy" title="{% trans 'Copy' %}">
{{ get_icon('b_insrow', 'Copy'|trans) }}
</button>
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="delete" title="{% trans 'Delete' %}">
{{ get_icon('b_drop', 'Delete'|trans) }}
</button>
{% if bulk_links.has_export_button %}
<button class="btn btn-link mult_submit" type="submit" name="submit_mult" value="export" title="{% trans 'Export' %}">
{{ get_icon('b_tblexport', 'Export'|trans) }}
</button>
{% endif %}
</div>
<input type="hidden" name="clause_is_unique" value="{{ bulk_links.clause_is_unique }}">
<input type="hidden" name="sql_query" value="{{ sql_query }}">
</form>
{% endif %}
{{ navigation_html }}
{% if operations is not empty %}
<fieldset class="pma-fieldset d-print-none">
<legend>{% trans 'Query results operations' %}</legend>
{% if operations.has_print_link %}
<button type="button" class="btn btn-link jsPrintButton">{{ get_icon('b_print', 'Print'|trans, true) }}</button>
{{ link_or_button(
'#',
null,
get_icon('b_insrow', 'Copy to clipboard'|trans, true),
{'id': 'copyToClipBoard', 'class': 'btn'}
) }}
{% endif %}
{% if not operations.has_procedure %}
{% if operations.has_export_link %}
{{ link_or_button(
url('/table/export'),
operations.url_params,
get_icon('b_tblexport', 'Export'|trans, true),
{'class': 'btn'}
) }}
{{ link_or_button(
url('/table/chart'),
operations.url_params,
get_icon('b_chart', 'Display chart'|trans, true),
{'class': 'btn'}
) }}
{% if operations.has_geometry %}
{{ link_or_button(
url('/table/gis-visualization'),
operations.url_params,
get_icon('b_globe', 'Visualize GIS data'|trans, true),
{'class': 'btn'}
) }}
{% endif %}
{% endif %}
<span>
{{ link_or_button(
url('/view/create'),
{'db': db, 'table': table, 'sql_query': sql_query, 'printview': true},
get_icon('b_view_add', 'Create view'|trans, true),
{'class': 'btn create_view ajax'}
) }}
</span>
{% endif %}
</fieldset>
{% endif %}
{% if operations is not empty and not operations.has_procedure %}
{{ include('modals/create_view.twig') }}
{% endif %}

View file

@ -0,0 +1,12 @@
{% for column in columns %}
<th class="draggable position-sticky{{ column.is_column_numeric ? ' text-end' }}{{ column.is_column_hidden ? ' hide' -}}
{{- is_sortable ? ' column_heading' }}{{ is_sortable and column.is_browse_marker_enabled ? ' marker' }}{{ is_sortable and column.is_browse_pointer_enabled ? ' pointer' -}}
{{- not is_sortable and column.has_condition ? ' condition' }}" data-column="{{ column.column_name }}">
{% if is_sortable %}
{{ column.order_link|raw }}
{% else %}
{{ column.column_name }}
{% endif %}
{{ column.comments|raw }}
</th>
{% endfor %}

View file

@ -0,0 +1,11 @@
<td>
<form action="{{ url('/sql') }}" 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 }}">
</form>
</td>

View file

@ -0,0 +1,3 @@
<td class="text-start {{ class }}{{ condition_field ? ' condition' }}">
{{- value|raw -}}
</td>

View file

@ -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>

View file

@ -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 - {% trans 'Error' %}</h1>
<p>{{ error_message|raw }}</p>
</body>
</html>

View file

@ -0,0 +1,36 @@
{% if allowed_to_send_error_reports %}
<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>
<form action="{{ url('/error-report') }}" method="post" id="errorReportForm" class="ajax">
<div class="mb-3">
<label for="errorReportDescription">
<strong>
{% trans "Can you tell us the steps leading to this error? It decisively helps in debugging:" %}
</strong>
</label>
<textarea class="form-control" name="description" id="errorReportDescription"></textarea>
</div>
<div class="mb-3">
{% trans "You may examine the data in the error report:" %}
<pre class="pre-scrollable">{{ report_data|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_SLASHES')) }}</pre>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="always_send" id="errorReportAlwaysSendCheckbox">
<label class="form-check-label" for="errorReportAlwaysSendCheckbox">
{% trans "Automatically send report next time" %}
</label>
</div>
{{ hidden_inputs|raw }}
{{ hidden_fields|raw }}
</form>
{% else %}
<div class="mb-3">
<pre class="pre-scrollable">{{ report_data|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_SLASHES')) }}</pre>
</div>
{% endif %}

View file

@ -0,0 +1,19 @@
<div class="modal fade" id="errorReportModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="errorReportModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="errorReportModalLabel">{% trans 'Submit error report' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Cancel' %}"></button>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
{% if allowed_to_send_error_reports %}
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
<button type="button" class="btn btn-primary" id="errorReportModalConfirm">{% trans 'Send error report' %}</button>
{% else %}
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">{% trans 'Close' %}</button>
{% endif %}
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,502 @@
<div class="container">
<h2 class="my-3">
{{ get_image('b_export', 'Export'|trans) }}
{% block title %}{% endblock %}
</h2>
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
{% block message %}{% endblock %}
{% if templates.is_enabled %}
<div class="card mb-3">
<div class="card-header">{% trans 'Export templates:' %}</div>
<div class="card-body row gy-3">
<form method="post" action="{{ url('/export/template/create') }}" class="col-12 col-md ajax">
<fieldset>
<legend>{% trans 'New template:' %}</legend>
<div class="row g-3 align-items-center">
<div class="col-auto">
<label for="templateName" class="col-form-label">{% trans 'Template name' %}</label>
</div>
<div class="col-auto">
<input class="form-control" type="text" name="templateName" id="templateName" maxlength="64" placeholder="{% trans 'Template name' %}" required>
</div>
<div class="col-auto">
<input class="btn btn-secondary" type="submit" name="createTemplate" id="createTemplate" value="{% trans 'Create' %}">
</div>
</div>
</fieldset>
</form>
<form method="post" id="existingTemplatesForm" class="col-12 col-md ajax">
<fieldset>
<legend>{% trans 'Existing templates:' %}</legend>
<div class="row g-3 align-items-center">
<div class="col-auto">
<label for="template" class="col-form-label">{% trans 'Template:' %}</label>
</div>
<div class="col-auto">
<select class="form-select" name="template" id="template" required>
<option value="">-- {% trans 'Select a template' %} --</option>
{% for template in templates.templates %}
<option value="{{ template.getId() }}"{{ template.getId() == templates.selected ? ' selected' }}>
{{ template.getName() }}
</option>
{% endfor %}
</select>
</div>
<div class="col-auto">
<input class="btn btn-secondary" type="submit" formaction="{{ url('/export/template/update') }}" name="updateTemplate" id="updateTemplate" value="{% trans 'Update' %}">
</div>
<div class="col-auto">
<input class="btn btn-secondary" type="submit" formaction="{{ url('/export/template/delete') }}" name="deleteTemplate" id="deleteTemplate" value="{% trans 'Delete' %}">
</div>
</div>
</fieldset>
</form>
</div>
</div>
{% endif %}
{% if sql_query is not empty %}
<div class="card mb-3">
<div class="card-header">
{# l10n: Title of the option on the Export page #}
{% trans 'SQL query:' %}
</div>
<div class="card-body">
<div id="sqlqueryform">
{# l10n: Button to show the SQL query on the export page #}
<input class="btn btn-secondary" type="submit" id="showsqlquery" value="{% trans 'Show SQL query' %}">
</div>
<div class="d-none"></div>
</div>
</div>
<div class="modal fade" id="showSqlQueryModal" tabindex="-1" aria-labelledby="showSqlQueryModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="showSqlQueryModalLabel">{% trans 'Loading' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body">
<div id="export_sql_modal_content">
<code class="sql">
<pre id="sql_preview_query">{{ sql_query }}</pre>
</code>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Close' %}</button>
</div>
</div>
</div>
</div>
{% endif %}
<form method="post" action="{{ url('/export') }}" name="dump" class="disableAjax">
{{ get_hidden_inputs(hidden_inputs) }}
{% if export_method != 'custom-no-form' %}
<div class="card mb-3" id="quick_or_custom">
<div class="card-header">{% trans 'Export method:' %}</div>
<div class="card-body">
<div class="form-check">
<input class="form-check-input" type="radio" name="quick_or_custom" value="quick" id="radio_quick_export"{{ export_method == 'quick' ? ' checked' }}>
<label class="form-check-label" for="radio_quick_export">{% trans 'Quick - display only the minimal options' %}</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="quick_or_custom" value="custom" id="radio_custom_export"{{ export_method == 'custom' ? ' checked' }}>
<label class="form-check-label" for="radio_custom_export">{% trans 'Custom - display all possible options' %}</label>
</div>
</div>
</div>
{% endif %}
<div class="card mb-3" id="format">
<div class="card-header">{% trans 'Format:' %}</div>
<div class="card-body">
<select class="form-select" id="plugins" name="what" aria-label="{% trans 'File format to export' %}">
{% for option in plugins_choice %}
<option value="{{ option.name }}"{{ option.is_selected ? ' selected' }}>{{ option.text }}</option>
{% endfor %}
</select>
{% for option in plugins_choice %}
<input type="hidden" id="force_file_{{ option.name }}" value="{{ option.force_file ? 'true' : 'false' }}">
{% endfor %}
</div>
</div>
{% block selection_options %}{% endblock %}
{% if rows is not empty %}
<div class="card mb-3" id="rows">
<div class="card-header">{% trans 'Rows:' %}</div>
<div class="card-body">
<div class="form-check">
<input class="form-check-input" type="radio" name="allrows" value="1" id="radio_allrows_1"{{ rows.allrows is null or rows.allrows == 1 ? ' checked' }}>
<label class="form-check-label" for="radio_allrows_1">{% trans 'Dump all rows' %}</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="allrows" value="0" id="radio_allrows_0"{{ rows.allrows is not null and rows.allrows == 0 ? ' checked' }}>
<label class="form-check-label" for="radio_allrows_0">{% trans 'Dump some row(s)' %}</label>
</div>
<ul class="list-group">
<li class="list-group-item">
<label class="form-label" for="limit_to">{% trans 'Number of rows:' %}</label>
<input class="form-control" type="text" id="limit_to" name="limit_to" size="5" value="
{%- if rows.limit_to is not null -%}
{{- rows.limit_to -}}
{%- elseif rows.unlim_num_rows is not empty and rows.unlim_num_rows != 0 -%}
{{- rows.unlim_num_rows -}}
{%- else %}
{{- rows.number_of_rows -}}
{%- endif -%}" onfocus="this.select()">
</li>
<li class="list-group-item">
<label class="form-label" for="limit_from">{% trans 'Row to begin at:' %}</label>
<input class="form-control" type="text" id="limit_from" name="limit_from" size="5" value="{{ rows.limit_from is not null ? rows.limit_from : 0 }}" onfocus="this.select()">
</li>
</ul>
</div>
</div>
{% endif %}
{% if has_save_dir %}
<div class="card mb-3 d-none" id="output_quick_export">
<div class="card-header">{% trans 'Output:' %}</div>
<div class="card-body">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="quick_export_onserver" value="saveit" id="checkbox_quick_dump_onserver"{{ export_is_checked ? ' checked' }}>
<label class="form-check-label" for="checkbox_quick_dump_onserver">
{{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }}
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="quick_export_onserver_overwrite" value="saveitover" id="checkbox_quick_dump_onserver_overwrite"
{{- export_overwrite_is_checked ? ' checked' }}>
<label class="form-check-label" for="checkbox_quick_dump_onserver_overwrite">
{% trans 'Overwrite existing file(s)' %}
</label>
</div>
</div>
</div>
{% endif %}
<div class="modal fade" id="renameExportModal" tabindex="-1" aria-labelledby="renameExportModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameExportModalLabel">{% trans 'Rename exported databases/tables/columns' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body overflow-auto">
<table class="table align-middle mb-3" id="alias_data">
<thead>
<tr>
<th colspan="4">
{% trans 'Defined aliases' %}
</th>
</tr>
</thead>
<tbody>
{% for db, db_data in aliases %}
{% if db_data.alias is defined and db_data.alias is not null %}
<tr>
<th>{% trans %}Database{% context %}Alias{% endtrans %}</th>
<td>{{ db }}</td>
<td>
<input name="aliases[{{ db }}][alias]" value="{{ db_data.alias }}" type="text">
</td>
<td>
<button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button>
</td>
</tr>
{% endif %}
{% for table, table_data in db_data.tables ?? [] %}
{% if table_data.alias is defined and table_data.alias is not null %}
<tr>
<th>{% trans %}Table{% context %}Alias{% endtrans %}</th>
<td>{{ db }}.{{ table }}</td>
<td>
<input name="aliases[{{ db }}][tables][{{ table }}][alias]" value="{{ table_data.alias }}" type="text">
</td>
<td>
<button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button>
</td>
</tr>
{% endif %}
{% for column, column_name in table_data.columns ?? [] %}
<tr>
<th>{% trans %}Column{% context %}Alias{% endtrans %}</th>
<td>{{ db }}.{{ table }}.{{ column }}</td>
<td>
<input name="aliases[{{ db }}][tables][{{ table }}][colums][{{ column }}]" value="{{ column_name }}" type="text">
</td>
<td>
<button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button>
</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
</tbody>
{# Empty row for javascript manipulations. #}
<tfoot class="hide">
<tr>
<th></th>
<td></td>
<td>
<input name="aliases_new" value="" type="text">
</td>
<td>
<button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button>
</td>
</tr>
</tfoot>
</table>
<table class="table align-middle">
<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>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="saveAndCloseBtn" data-bs-dismiss="modal">
{% trans 'Save & close' %}
</button>
</div>
</div>
</div>
</div>
<div class="card mb-3" id="output">
<div class="card-header">{% trans 'Output:' %}</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="btn_alias_config"{{ has_aliases ? ' checked' }}>
<label class="form-check-label" for="btn_alias_config">{% trans 'Rename exported databases/tables/columns' %}</label>
</div>
</li>
{% if export_type != 'server' %}
<li class="list-group-item">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="lock_tables" value="something" id="checkbox_lock_tables"
{{- (not repopulate and is_checked_lock_tables) or lock_tables ? ' checked' }}>
<label class="form-check-label" for="checkbox_lock_tables">
{{ 'Use %s statement'|trans|format('<code>LOCK TABLES</code>')|raw }}
</label>
</div>
</li>
{% endif %}
<li class="list-group-item">
<div class="form-check">
<input class="form-check-input" type="radio" id="radio_view_as_text" name="output_format" value="astext"{{ repopulate or export_asfile == false ? ' checked' }}>
<label class="form-check-label" for="radio_view_as_text">{% trans 'View output as text' %}</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="output_format" value="sendit" id="radio_dump_asfile"{{ not repopulate and is_checked_asfile ? ' checked' }}>
<label class="form-check-label" for="radio_dump_asfile">{% trans 'Save output to a file' %}</label>
</div>
<div class="hstack gap-3">
<div class="vr"></div>
<ul class="list-group" id="ul_save_asfile">
{% if has_save_dir %}
<li class="list-group-item">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="onserver" value="saveit" id="checkbox_dump_onserver"{{ is_checked_export ? ' checked' }}>
<label class="form-check-label" for="checkbox_dump_onserver">
{{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }}
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="onserver_overwrite" value="saveitover" id="checkbox_dump_onserver_overwrite"
{{- is_checked_export_overwrite ? ' checked' }}>
<label class="form-check-label" for="checkbox_dump_onserver_overwrite">
{% trans 'Overwrite existing file(s)' %}
</label>
</div>
</li>
{% endif %}
<li class="list-group-item">
<div class="row g-3 align-items-center">
<div class="col-auto">
<label for="filename_template" class="col-form-label">
{% trans 'File name template:' %}
{{ show_hint('This value is interpreted using the \'strftime\' function, so you can use time formatting strings. Additionally the following transformations will happen: %s Other text will be kept as is. See the FAQ 6.27 for details.'|trans|format(filename_hint)) }}
</label>
</div>
<div class="col-auto">
<input type="text" class="form-control" name="filename_template" id="filename_template" value="{{ filename_template }}">
</div>
<div class="col-auto">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="remember_template" id="checkbox_remember_template"{{ is_checked_remember_file_template ? ' checked' }}>
<label class="form-check-label" for="checkbox_remember_template">
{% trans 'Use this for future exports' %}
</label>
</div>
</div>
</div>
</li>
{% if is_encoding_supported %}
<li class="list-group-item">
<div class="row">
<div class="col-auto">
<label for="select_charset" class="col-form-label">{% trans 'Character set of the file:' %}</label>
</div>
<div class="col-auto">
<select class="form-select" id="select_charset" name="charset">
{% for charset in encodings %}
<option value="{{ charset }}"
{{- (export_charset is empty and charset == 'utf-8') or charset == export_charset ? ' selected' }}>
{{- charset -}}
</option>
{% endfor %}
</select>
</div>
</div>
</li>
{% endif %}
{% if has_zip or has_gzip %}
<li class="list-group-item">
<div class="row">
<div class="col-auto">
<label for="compression" class="col-form-label">{% trans 'Compression:' %}</label>
</div>
<div class="col-auto">
<select class="form-select" id="compression" name="compression">
<option value="none">{% trans 'None' %}</option>
{% if has_zip %}
<option value="zip"
{{- selected_compression == 'zip' ? ' selected' }}>
{% trans 'zipped' %}
</option>
{% endif %}
{% if has_gzip %}
<option value="gzip"
{{- selected_compression == 'gzip' ? ' selected' }}>
{% trans 'gzipped' %}
</option>
{% endif %}
</select>
</div>
</div>
</li>
{% else %}
<input type="hidden" name="compression" value="{{ selected_compression }}">
{% endif %}
{% if export_type == 'server' or export_type == 'database' %}
<li class="list-group-item">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="checkbox_as_separate_files" name="as_separate_files" value="{{ export_type }}"
{{- is_checked_as_separate_files ? ' checked' }}>
<label class="form-check-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>
</div>
</li>
{% endif %}
</ul>
</div>
</li>
<li class="list-group-item">
<label for="maxsize" class="form-label">{% trans 'Skip tables larger than:' %}</label>
<input class="form-control" type="number" id="maxsize" name="maxsize" aria-describedby="maxsizeHelp">
<div id="maxsizeHelp" class="form-text">{% trans 'The size is measured in MiB.' %}</div>
</li>
</ul>
</div>
<div class="card mb-3" id="format_specific_opts">
<div class="card-header">{% trans 'Format-specific options:' %}</div>
<div class="card-body">
{{ options|raw }}
</div>
</div>
{% if can_convert_kanji %}
{# Japanese encoding setting #}
<div class="card mb-3" id="kanji_encoding">
<div class="card-header">{% trans 'Encoding Conversion:' %}</div>
<div class="card-body">
{% include 'encoding/kanji_encoding_form.twig' %}
</div>
</div>
{% endif %}
<div id="submit">
<input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Export' %}" data-exec-time-limit="{{ exec_time_limit }}">
</div>
</form>
</div>

View file

@ -0,0 +1,7 @@
<option value="">-- {% trans 'Select a template' %} --</option>
{% for template in templates %}
<option value="{{ template.getId() }}"{{ template.getId() == selected_template ? ' selected' }}>
{{ template.getName() }}
</option>
{% endfor %}

View file

@ -0,0 +1,14 @@
<div class="modal fade" id="exportPrivilegesModal" tabindex="-1" aria-labelledby="exportPrivilegesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exportPrivilegesModalLabel">{% trans 'Loading' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Close' %}</button>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,5 @@
{% for file in filesList %}
<option value="{{ file }}"{% if file == active %} selected="selected"{% endif %}>
{{ file }}
</option>
{% endfor %}

View file

@ -0,0 +1,9 @@
<div class="card mb-3" id="tableFilter">
<div class="card-header">{% trans 'Filters' %}</div>
<div class="card-body row row-cols-lg-auto gy-1 gx-3 align-items-center">
<label class="col-12 col-form-label" for="filterText">{% trans 'Containing the word:' %}</label>
<div class="col-12">
<input class="form-control" name="filterText" type="text" id="filterText" value="{{ filter_value }}">
</div>
</div>
</div>

View file

@ -0,0 +1,47 @@
{% if not is_ajax %}
</div>
{% endif %}
{% if not is_ajax and not is_minimal %}
{% if self_url is not empty %}
<div id="selflink" class="d-print-none">
<a href="{{ self_url }}" title="{% trans 'Open new phpMyAdmin window' %}" target="_blank" rel="noopener noreferrer">
{% if show_icons('TabsMode') %}
{{ get_image('window-new', 'Open new phpMyAdmin window'|trans) }}
{% else %}
{% trans 'Open new phpMyAdmin window' %}
{% endif %}
</a>
</div>
{% endif %}
<div class="clearfloat d-print-none" id="pma_errors">
{{ error_messages|raw }}
</div>
{{ scripts|raw }}
{% if is_demo %}
<div id="pma_demo" class="d-print-none">
{% apply notice %}
<a href="{{ url('/') }}">{% trans 'phpMyAdmin Demo Server' %}:</a>
{% if git_revision_info is not empty %}
{% set revision_info -%}
<a target="_blank" rel="noopener noreferrer" href="{{ git_revision_info.revisionUrl|link }}">{{ git_revision_info.revision }}</a>
{%- endset %}
{% set branch_info -%}
<a target="_blank" rel="noopener noreferrer" href="{{ git_revision_info.branchUrl|link }}">{{ git_revision_info.branch }}</a>
{%- endset %}
{{ 'Currently running Git revision %1$s from the %2$s branch.'|trans|format(revision_info, branch_info)|raw }}
{% else %}
{% trans 'Git information missing!' %}
{% endif %}
{% endapply %}
</div>
{% endif %}
{{ footer|raw }}
{% endif %}
{% if not is_ajax %}
</body>
</html>
{% endif %}

View file

@ -0,0 +1,221 @@
<form id="gis_data_editor_form" action="{{ url('/gis-data-editor') }}" method="post">
<input type="hidden" id="themeImagePath" value="{{ 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 float-end">
<input type="checkbox" id="choice" value="useBaseLayer"{{ srid != 0 ? ' checked="checked"' }}>
<label for="choice">{% trans "Use OpenStreetMaps as Base Layer" %}</label>
</div>
<script 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>

View file

@ -0,0 +1,60 @@
<!doctype html>
<html lang="{{ lang }}" dir="{{ text_dir }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="referrer" content="no-referrer">
<meta name="robots" content="noindex,nofollow,notranslate">
<meta name="google" content="notranslate">
{% 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">
<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 }}">
<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" class="d-print-none">
<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 }}
{{ recent_table|raw }}
{%- if is_logged_in -%}
{{ include('modals/preview_sql_modal.twig') }}
{{ include('modals/enum_set_editor.twig') }}
{{ include('modals/create_view.twig') }}
{%- endif -%}

View file

@ -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>

View file

@ -0,0 +1,37 @@
<li id="li_pma_version_git" class="list-group-item">
{% trans 'Git revision:' %}
{% if is_remote_commit %}
<a href="{{ 'https://github.com/phpmyadmin/phpmyadmin/commit/%s'|format(hash|e)|link }}" rel="noopener noreferrer" target="_blank">
<strong title="{{ message }}">{{ hash|slice(0, 7) }}</strong>
</a>
{% else %}
<strong title="{{ message }}">{{ hash|slice(0, 7) }}</strong>
{% endif %}
{% if branch is same as(false) %}
({% trans 'no branch' %})
{% elseif is_remote_branch %}
{{ 'from %s branch'|trans|format(
'<a href="%s" rel="noopener noreferrer" target="_blank">%s</a>'|format(
'https://github.com/phpmyadmin/phpmyadmin/tree/%s'|format(branch|e)|link,
branch|e
)
)|raw }},<br>
{% else %}
{{ 'from %s branch'|trans|format(branch) }},<br>
{% endif %}
{{ 'committed on %s by %s'|trans|format(
committer.date,
'<a href="mailto:%s">%s</a>'|format(committer.email|e, committer.name|e)
)|raw }}
{%- if committer is not same as(author) -%}
,<br>
{{ 'authored on %s by %s'|trans|format(
author.date,
'<a href="mailto:%s">%s</a>'|format(author.email|e, author.name|e)
)|raw }}
{% endif %}
</li>

View file

@ -0,0 +1,314 @@
{% if is_git_revision %}
<div id="is_git_revision"></div>
{% endif %}
{{ message|raw }}
{{ partial_logout|raw }}
<div id="maincontainer">
{{ sync_favorite_tables|raw }}
<div class="container-fluid">
<div class="row mb-3">
<div class="col-lg-7 col-12">
{% if has_server %}
{% if is_demo %}
<div class="card mt-4">
<div class="card-header">
{% trans 'phpMyAdmin Demo Server' %}
</div>
<div class="card-body">
{% 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 %}
</div>
</div>
{% endif %}
<div class="card mt-4">
<div class="card-header">
{% trans 'General settings' %}
</div>
<ul class="list-group list-group-flush">
{% if has_server_selection %}
<li id="li_select_server" class="list-group-item">
{{ get_image('s_host') }}
{{ server_selection|raw }}
</li>
{% endif %}
{% if server > 0 %}
{% if has_change_password_link %}
<li id="li_change_password" class="list-group-item">
<a href="{{ url('/user-password') }}" id="change_password_anchor" class="ajax">
{{ get_icon('s_passwd', 'Change password'|trans, true) }}
</a>
</li>
{% endif %}
<li id="li_select_mysql_collation" class="list-group-item">
<form method="post" action="{{ url('/collation-connection') }}" class="row row-cols-lg-auto align-items-center disableAjax">
{{ get_hidden_inputs(null, null, 4, 'collation_connection') }}
<div class="col-12">
<label for="collationConnectionSelect" class="col-form-label">
{{ get_image('s_asci') }}
{% trans 'Server connection collation:' %}
{{ show_mysql_docu('charset-connection') }}
</label>
</div>
{% if charsets is not empty %}
<div class="col-12">
<select lang="en" dir="ltr" name="collation_connection" id="collationConnectionSelect" class="form-select 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>
</div>
{% endif %}
</form>
</li>
<li id="li_user_preferences" class="list-group-item">
<a href="{{ url('/preferences/manage') }}">
{{ get_icon('b_tblops', 'More settings'|trans, true) }}
</a>
</li>
{% endif %}
</ul>
</div>
{% endif %}
<div class="card mt-4">
<div class="card-header">
{% trans 'Appearance settings' %}
</div>
<ul class="list-group list-group-flush">
{% if available_languages is not empty %}
<li id="li_select_lang" class="list-group-item">
<form method="get" action="{{ url('/') }}" class="row row-cols-lg-auto align-items-center disableAjax">
{{ get_hidden_inputs({'db': db, 'table': table}) }}
<div class="col-12">
<label for="languageSelect" class="col-form-label text-nowrap">
{{ get_image('s_lang') }}
{% trans 'Language' %}
{% if 'Language'|trans != 'Language' %}
{# For non-English, display "Language" with emphasis because it's not a proper word
in the current language; we show it to help people recognize the dialog #}
<i lang="en" dir="ltr">(Language)</i>
{% endif %}
{{ show_docu('faq', 'faq7-2') }}
</label>
</div>
<div class="col-12">
<select name="lang" class="form-select autosubmit w-auto" lang="en" dir="ltr" id="languageSelect">
{% for language in available_languages %}
<option value="{{ language.getCode()|lower }}"{{ language.isActive() ? ' selected' }}>
{{- language.getName()|raw -}}
</option>
{% endfor %}
</select>
</div>
</form>
</li>
{% endif %}
{% if has_theme_manager %}
<li id="li_select_theme" class="list-group-item">
<form method="post" action="{{ url('/themes/set') }}" class="row row-cols-lg-auto align-items-center disableAjax">
{{ get_hidden_inputs() }}
<div class="col-12">
<label for="themeSelect" class="col-form-label">
{{ get_icon('s_theme', 'Theme'|trans) }}
</label>
</div>
<div class="col-12">
<div class="input-group">
<select name="set_theme" class="form-select autosubmit" lang="en" dir="ltr" id="themeSelect">
{% for theme in themes %}
<option value="{{ theme.id }}"{{ theme.is_active ? ' selected' }}>{{ theme.name }}</option>
{% endfor %}
</select>
<button type="button" class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#themesModal">
{% trans %}View all{% context %}View all themes{% endtrans %}
</button>
</div>
</div>
</form>
</li>
{% endif %}
</ul>
</div>
</div>
<div class="col-lg-5 col-12">
{% if database_server is not empty %}
<div class="card mt-4">
<div class="card-header">
{% trans 'Database server' %}
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
{% trans 'Server:' %}
{{ database_server.host }}
</li>
<li class="list-group-item">
{% trans 'Server type:' %}
{{ database_server.type }}
</li>
<li class="list-group-item">
{% trans 'Server connection:' %}
{{ database_server.connection|raw }}
</li>
<li class="list-group-item">
{% trans 'Server version:' %}
{{ database_server.version }}
</li>
<li class="list-group-item">
{% trans 'Protocol version:' %}
{{ database_server.protocol }}
</li>
<li class="list-group-item">
{% trans 'User:' %}
{{ database_server.user }}
</li>
<li class="list-group-item">
{% trans 'Server charset:' %}
<span lang="en" dir="ltr">
{{ database_server.charset }}
</span>
</li>
</ul>
</div>
{% endif %}
{% if web_server is not empty or show_php_info %}
<div class="card mt-4">
<div class="card-header">
{% trans 'Web server' %}
</div>
<ul class="list-group list-group-flush">
{% if web_server is not empty %}
{% if web_server.software is not null %}
<li class="list-group-item">
{{ web_server.software }}
</li>
{% endif %}
<li class="list-group-item" id="li_mysql_client_version">
{% trans 'Database client version:' %}
{{ web_server.database }}
</li>
<li class="list-group-item">
{% trans 'PHP extension:' %}
{% for extension in web_server.php_extensions %}
{{ extension }}
{{ show_php_docu('book.' ~ extension ~ '.php') }}
{% endfor %}
</li>
<li class="list-group-item">
{% trans 'PHP version:' %}
{{ web_server.php_version }}
</li>
{% endif %}
{% if show_php_info %}
<li class="list-group-item">
<a href="{{ url('/phpinfo') }}" target="_blank" rel="noopener noreferrer">
{% trans 'Show PHP information' %}
</a>
</li>
{% endif %}
</ul>
</div>
{% endif %}
<div class="card mt-4">
<div class="card-header">
phpMyAdmin
</div>
<ul class="list-group list-group-flush">
<li id="li_pma_version" class="list-group-item{{ is_version_checked ? ' jsversioncheck' }}">
{% trans 'Version information:' %}
<span class="version">{{ phpmyadmin_version }}</span>
</li>
<li class="list-group-item">
<a href="{{ get_docu_link('index') }}" target="_blank" rel="noopener noreferrer">
{% trans 'Documentation' %}
</a>
</li>
<li class="list-group-item">
<a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer">
{% trans 'Official Homepage' %}
</a>
</li>
<li class="list-group-item">
<a href="{{ 'https://www.phpmyadmin.net/contribute/'|link }}" target="_blank" rel="noopener noreferrer">
{% trans 'Contribute' %}
</a>
</li>
<li class="list-group-item">
<a href="{{ 'https://www.phpmyadmin.net/support/'|link }}" target="_blank" rel="noopener noreferrer">
{% trans 'Get support' %}
</a>
</li>
<li class="list-group-item">
<a href="{{ url('/changelog') }}" target="_blank">
{% trans 'List of changes' %}
</a>
</li>
<li class="list-group-item">
<a href="{{ url('/license') }}" target="_blank">
{% trans 'License' %}
</a>
</li>
</ul>
</div>
</div>
</div>
{% for error in errors %}
<div class="alert {{ error.severity == 'warning' ? 'alert-warning' : 'alert-info' }}" role="alert">
{% if error.severity == 'warning' %}
{{ get_image('s_attention', 'Warning'|trans) }}
{% else %}
{{ get_image('s_notice', 'Notice'|trans) }}
{% endif %}
{{ error.message|sanitize }}
</div>
{% endfor %}
</div>
</div>
{% if has_theme_manager %}
<div class="modal fade" id="themesModal" tabindex="-1" aria-labelledby="themesModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="themesModalLabel">{% trans 'phpMyAdmin Themes' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
</div>
<div class="modal-body">
<div class="spinner-border" role="status">
<span class="visually-hidden">{% trans 'Loading…' %}</span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Close' %}</button>
<a href="{{ 'https://www.phpmyadmin.net/themes/'|link }}#pma_{{ phpmyadmin_major_version|replace({'.': '_'}) }}" class="btn btn-primary" rel="noopener noreferrer" target="_blank">
{% trans 'Get more themes!' %}
</a>
</div>
</div>
</div>
</div>
{% endif %}
{{ config_storage_message|raw }}

View file

@ -0,0 +1,18 @@
<form method="post" action="{{ url('/themes/set') }}" class="disableAjax">
{{ get_hidden_inputs() }}
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-4">
{% for theme in themes %}
<div class="col">
<div class="card">
<img src="./themes/{{ theme.id }}/screen.png" class="card-img-top" alt="{{ 'Screenshot of the %s theme.'|trans|format(theme.name) }}">
<div class="card-body">
<h5 class="card-title">{{ theme.name }} <small>({{ theme.version }})</small></h5>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary" name="set_theme" value="{{ theme.id }}">{% trans %}Take it{% notes %}Choose the theme button in the themes list modal{% endtrans %}</button>
</div>
</div>
</div>
{% endfor %}
</div>
</form>

View file

@ -0,0 +1,203 @@
<div class="container">
<h2 class="my-3">
{{ get_image('b_import', 'Import'|trans) }}
{% block title %}{% endblock %}
</h2>
{{ page_settings_error_html|raw }}
{{ page_settings_html|raw }}
<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="{{ image('ajax_clock_small.gif') }}" width="16" height="16" alt="ajax clock" class="hide">
<script type="text/javascript">
//<![CDATA[
{% include 'import/javascript.twig' with {'upload_id': upload_id, 'handler': handler} only %}
//]]>
</script>
<form id="import_file_form" action="{{ url('/import') }}" method="post" enctype="multipart/form-data" name="import" class="ajax"
{%- if handler != 'PhpMyAdmin\\Plugins\\Import\\Upload\\UploadNoplugin' %} target="import_upload_iframe"{% endif %}>
{{ get_hidden_inputs(hidden_inputs) }}
<div class="card mb-3">
<div class="card-header">{% trans 'File to import:' %}</div>
<div class="card-body">
{# We don't have show anything about compression, when no supported #}
{% if compressions is not empty %}
<p class="card-text">
{{ '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>
{% endif %}
{% if is_upload and upload_dir is not empty %}
{% set use_local_file_import = timeout_passed_global is not empty and local_import_file is not empty %}
<ul class="nav nav-pills mb-3" id="importFileTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link{{ not use_local_file_import ? ' active' }}" id="uploadFileTab" data-bs-toggle="tab" data-bs-target="#uploadFile" type="button" role="tab" aria-controls="uploadFile" aria-selected="{{ not use_local_file_import ? 'true' : 'false' }}">{% trans 'Upload a file' %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link{{ use_local_file_import ? ' active' }}" id="localFileTab" data-bs-toggle="tab" data-bs-target="#localFile" type="button" role="tab" aria-controls="localFile" aria-selected="{{ use_local_file_import ? 'true' : 'false' }}">{% trans 'Select file to import' %}</button>
</li>
</ul>
<div class="tab-content mb-3" id="importFileTabContent">
<div class="tab-pane fade{{ not use_local_file_import ? ' show active' }}" id="uploadFile" role="tabpanel" aria-labelledby="uploadFileTab">
<input type="hidden" name="MAX_FILE_SIZE" value="{{ max_upload_size }}">
<div class="mb-3">
<label class="form-label" for="input_import_file">{% trans 'Browse your computer:' %} <small>{{ formatted_maximum_upload_size }}</small></label>
<input class="form-control" type="file" name="import_file" id="input_import_file">
</div>
<div id="upload_form_status" class="hide"></div>
<div id="upload_form_status_info" class="hide"></div>
<p class="card-text">{% trans 'You may also drag and drop a file on any page.' %}</p>
</div>
<div class="tab-pane fade{{ use_local_file_import ? ' show active' }}" id="localFile" role="tabpanel" aria-labelledby="localFileTab">
{% if local_files is same as(false) %}
{{ 'The directory you set for upload work cannot be reached.'|trans|error }}
{% elseif local_files is not empty %}
<label class="form-label" for="select_local_import_file">{{ 'Select from the web server upload directory [strong]%s[/strong]:'|trans|format(user_upload_dir)|sanitize }}</label>
<select class="form-select" size="1" name="local_import_file" id="select_local_import_file">
<option value=""></option>
{{ local_files|raw }}
</select>
{% else %}
<div class="alert alert-info" role="alert">
{% trans 'There are no files to import!' %}
</div>
{% endif %}
</div>
</div>
{% elseif is_upload %}
<input type="hidden" name="MAX_FILE_SIZE" value="{{ max_upload_size }}">
<div class="mb-3">
<label class="form-label" for="input_import_file">{% trans 'Browse your computer:' %} <small>{{ formatted_maximum_upload_size }}</small></label>
<input class="form-control" type="file" name="import_file" id="input_import_file">
</div>
<div id="upload_form_status" class="hide"></div>
<div id="upload_form_status_info" class="hide"></div>
<p class="card-text">{% trans 'You may also drag and drop a file on any page.' %}</p>
{% elseif upload_dir is not empty %}
{% if local_files is same as(false) %}
{{ 'The directory you set for upload work cannot be reached.'|trans|error }}
{% elseif local_files is not empty %}
<div class="mb-3">
<label class="form-label" for="select_local_import_file">{{ 'Select from the web server upload directory [strong]%s[/strong]:'|trans|format(user_upload_dir)|sanitize }}</label>
<select class="form-select" size="1" name="local_import_file" id="select_local_import_file">
<option value=""></option>
{{ local_files|raw }}
</select>
</div>
{% else %}
<div class="alert alert-info" role="alert">
{% trans 'There are no files to import!' %}
</div>
{% endif %}
{% else %}
{{ 'File uploads are not allowed on this server.'|trans|notice }}
{% endif %}
<label class="form-label" for="charset_of_file">{% trans 'Character set of the file:' %}</label>
{% if is_encoding_supported %}
<select class="form-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{% endif %}>
{{- charset -}}
</option>
{% endfor %}
</select>
{% else %}
<select class="form-select" lang="en" dir="ltr" name="charset_of_file" id="charset_of_file">
<option value=""></option>
{% for charset in charsets %}
<option value="{{ charset.getName() }}" title="{{ charset.getDescription() }}"{{ charset.getName() == 'utf8' ? ' selected' }}>
{{- charset.getName() -}}
</option>
{% endfor %}
</select>
{% endif %}
</div>
</div>
<div class="card mb-3">
<div class="card-header">{% trans 'Partial import:' %}</div>
<div class="card-body">
{% if timeout_passed is defined and timeout_passed %}
<input type="hidden" name="skip" value="{{ offset }}">
<div class="alert alert-info" role="alert">
{{ 'Previous import timed out, after resubmitting will continue from position %d.'|trans|format(offset) }}
</div>
{% endif %}
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" role="switch" name="allow_interrupt" value="yes" id="checkbox_allow_interrupt"{{ is_allow_interrupt_checked|raw }} aria-describedby="allowInterruptHelp">
<label class="form-check-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.' %}
</label>
<div id="allowInterruptHelp" class="form-text">{% trans 'This might be a good way to import large files, however it can break transactions.' %}</div>
</div>
{% if not (timeout_passed is defined and timeout_passed) %}
<label class="form-label" for="text_skip_queries">{% trans 'Skip this number of queries (for SQL) starting from the first one:' %}</label>
<input class="form-control" type="number" name="skip_queries" value="{{ skip_queries_default|raw }}" id="text_skip_queries" min="0">
{% 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="{{ skip_queries_default|raw }}" id="text_skip_queries">
{% endif %}
</div>
</div>
<div class="card mb-3">
<div class="card-header">{% trans 'Other options' %}</div>
<div class="card-body">
<input type="hidden" name="fk_checks" value="0">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="fk_checks" id="fk_checks" value="1"{{ is_foreign_key_check ? ' checked' }}>
<label class="form-check-label" for="fk_checks">{% trans 'Enable foreign key checks' %}</label>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header">{% trans 'Format' %}</div>
<div class="card-body">
<select class="form-select" id="plugins" name="format" aria-label="{% trans 'Format' %}">
{% for option in plugins_choice %}
<option value="{{ option.name }}"{{ option.is_selected ? ' selected' }}>{{ option.text }}</option>
{% endfor %}
</select>
{% for option in plugins_choice %}
<input type="hidden" id="force_file_{{ option.name }}" value="true">
{% endfor %}
<div id="import_notification"></div>
</div>
</div>
<div class="card mb-3" id="format_specific_opts">
<div class="card-header">{% trans 'Format-specific options:' %}</div>
<div class="card-body">
{{ options|raw }}
</div>
</div>
{# Japanese encoding setting #}
{% if can_convert_kanji %}
<div class="card mb-3" id="kanji_encoding">
<div class="card-header">{% trans 'Encoding Conversion:' %}</div>
<div class="card-body">
{% include 'encoding/kanji_encoding_form.twig' %}
</div>
</div>
{% endif %}
<div id="submit">
<input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Import' %}">
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,159 @@
$( 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 = 'index.php?route=/import-status&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 %}
<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="{{ 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>
{% 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="{{ 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|spaceless|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="{{ image('ajax_clock_small.gif') }}" width="16" height="16" alt="ajax clock"> {{ processed_str|raw }}')
.show();
$("#import_form_status").load("index.php?route=/import-status&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="{{ 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 %}
});
});

View file

@ -0,0 +1,3 @@
<fieldset class="pma-fieldset tblFooters">
[ <a href="{{ go_back_url }}">{% trans 'Back' %}</a> ]
</fieldset>

Some files were not shown because too many files have changed in this diff Show more