diff options
Diffstat (limited to 'srcs/phpmyadmin/templates')
231 files changed, 12081 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/templates/changelog.twig b/srcs/phpmyadmin/templates/changelog.twig new file mode 100644 index 0000000..cdda84f --- /dev/null +++ b/srcs/phpmyadmin/templates/changelog.twig @@ -0,0 +1,15 @@ +<!doctype html> +<html lang="en" dir="ltr"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="robots" content="noindex,nofollow"> + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + <title>phpMyAdmin - ChangeLog</title> +</head> +<body> +<h1>phpMyAdmin - ChangeLog</h1> +<pre>{{ changelog|raw }}</pre> +</body> +</html> diff --git a/srcs/phpmyadmin/templates/checkbox.twig b/srcs/phpmyadmin/templates/checkbox.twig new file mode 100644 index 0000000..2b29f7e --- /dev/null +++ b/srcs/phpmyadmin/templates/checkbox.twig @@ -0,0 +1,6 @@ +<input type="checkbox" name="{{ html_field_name }}" +{%- if html_field_id is defined %} id="{{ html_field_id }}"{% endif -%} +{%- if checked is defined and checked %} checked="checked"{% endif -%} +{%- if onclick is defined and onclick %} class="autosubmit"{% endif %}><label +{%- if html_field_id is defined %} for="{{ html_field_id }}" +{%- endif %}>{{ label }}</label> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig b/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig new file mode 100644 index 0000000..d0d1e91 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_adjust_privileges.twig @@ -0,0 +1,16 @@ +{% if privs_available %} + <input name="field_adjust_privileges[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + checked="checked" + type="checkbox" + value="NULL" + class="allow_null"> +{% else %} + <input name="field_adjust_privileges[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + disabled + type="checkbox" + value="NULL" + class="allow_null" + title="{% trans "You don't have sufficient privileges to perform this operation; Please refer to the documentation for more details" %}"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig b/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig new file mode 100644 index 0000000..905d093 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_attribute.twig @@ -0,0 +1,21 @@ +{% if submit_attribute is defined and submit_attribute != false %} + {% set attribute = submit_attribute %} +{% elseif column_meta['Extra'] is defined + and column_meta['Extra'] == 'on update CURRENT_TIMESTAMP' %} + {% set attribute = 'on update CURRENT_TIMESTAMP' %} +{% elseif extracted_columnspec['attribute'] is defined %} + {% set attribute = extracted_columnspec['attribute'] %} +{% else %} + {% set attribute = '' %} +{% endif %} +{% set attribute = attribute|upper %} +<select name="field_attribute[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}"> + {% set cnt_attribute_types = attribute_types|length - 1 %} + {% for i in 0..cnt_attribute_types %} + <option value="{{ attribute_types[i] }}" + {{- attribute == attribute_types[i]|upper ? ' selected="selected"' }}> + {{ attribute_types[i] }} + </option> + {% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig b/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig new file mode 100644 index 0000000..89eef86 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_attributes.twig @@ -0,0 +1,246 @@ +{# Cell index: If certain fields get left out, the counter shouldn't change. #} +{% set ci = 0 %} + +{# Every time a cell shall be left out the STRG-jumping feature, $ci_offset has + to be incremented ($ci_offset++) #} +{% set ci_offset = -1 %} + +<td class="center"> + {# column name #} + {% include 'columns_definitions/column_name.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'cfg_relation': cfg_relation, + 'max_rows': max_rows + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column type #} + {% include 'columns_definitions/column_type.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'type_upper': type_upper + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column length #} + {% include 'columns_definitions/column_length.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'length_values_input_size': length_values_input_size, + 'length_to_display': length + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column default #} + {% include 'columns_definitions/column_default.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'type_upper': type_upper, + 'default_value': default_value, + 'char_editing': char_editing + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column collation #} + <select lang="en" dir="ltr" name="field_collation[{{ column_number }}]" id="field_{{ column_number }}_{{ ci - ci_offset }}"> + <option value=""></option> + {% for charset in charsets %} + <optgroup label="{{ charset.name }}" title="{{ charset.description }}"> + {% for collation in charset.collations %} + <option value="{{ collation.name }}" title="{{ collation.description }}" + {{- collation.name == column_meta['Collation'] ? ' selected' }}> + {{- collation.name -}} + </option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column attribute #} + {% include 'columns_definitions/column_attribute.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'extracted_columnspec': extracted_columnspec, + 'submit_attribute': submit_attribute, + 'attribute_types': attribute_types + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column NULL #} + {% include 'columns_definitions/column_null.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta + } only %} + {% set ci = ci + 1 %} +</td> +{% if change_column is defined and change_column is not empty %} + {# column Adjust privileges, Only for 'Edit' Column(s) #} + <td class="center"> + {% include 'columns_definitions/column_adjust_privileges.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'privs_available': privs_available + } only %} + {% set ci = ci + 1 %} + </td> +{% endif %} +{% if not is_backup %} + {# column indexes, See my other comment about this 'if'. #} + <td class="center"> + {% include 'columns_definitions/column_indexes.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta + } only %} + {% set ci = ci + 1 %} + </td> +{% endif %} +<td class="center"> + {# column auto_increment #} + {% include 'columns_definitions/column_auto_increment.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta + } only %} + {% set ci = ci + 1 %} +</td> +<td class="center"> + {# column comments #} + {% include 'columns_definitions/column_comment.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'max_length': max_length, + 'value': column_meta['Field'] is defined + and comments_map is iterable + and comments_map[column_meta['Field']] is defined + ? comments_map[column_meta['Field']]|e + } only %} + {% set ci = ci + 1 %} +</td> + {# column virtuality #} +{% if is_virtual_columns_supported %} + <td class="center"> + {% include 'columns_definitions/column_virtuality.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'char_editing': char_editing, + 'expression': column_meta['Expression'] is defined ? column_meta['Expression'], + 'options': options + } only %} + {% set ci = ci + 1 %} + </td> +{% endif %} +{# move column #} +{% if fields_meta is defined %} + {% set current_index = 0 %} + {% set cols = move_columns|length - 1 %} + {% set break = false %} + {% for mi in 0..cols %} + {% if move_columns[mi].name == column_meta['Field'] and not break %} + {% set current_index = mi %} + {% set break = true %} + {% endif %} + {% endfor %} + + <td class="center"> + {% include 'columns_definitions/move_column.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'move_columns': move_columns, + 'current_index': current_index + } only %} + {% set ci = ci + 1 %} + </td> +{% endif %} + +{% if cfg_relation['mimework'] and browse_mime and cfg_relation['commwork'] %} + <td class="center"> + {# Column Mime-type #} + {% include 'columns_definitions/mime_type.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'available_mime': available_mime, + 'mime_map': mime_map + } only %} + {% set ci = ci + 1 %} + </td> + <td class="center"> + {# Column Browser transformation #} + {% include 'columns_definitions/transformation.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'available_mime': available_mime, + 'mime_map': mime_map, + 'type': 'transformation' + } only %} + {% set ci = ci + 1 %} + </td> + <td class="center"> + {# column Transformation options #} + {% include 'columns_definitions/transformation_option.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'mime_map': mime_map, + 'type_prefix': '' + } only %} + {% set ci = ci + 1 %} + </td> + <td class="center"> + {# Column Input transformation #} + {% include 'columns_definitions/transformation.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'available_mime': available_mime, + 'mime_map': mime_map, + 'type': 'input_transformation' + } only %} + {% set ci = ci + 1 %} + </td> + <td class="center"> + {# column Input transformation options #} + {% include 'columns_definitions/transformation_option.twig' with { + 'column_number': column_number, + 'ci': ci, + 'ci_offset': ci_offset, + 'column_meta': column_meta, + 'mime_map': mime_map, + 'type_prefix': 'input_' + } only %} + {% set ci = ci + 1 %} + </td> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig b/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig new file mode 100644 index 0000000..46bfb42 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_auto_increment.twig @@ -0,0 +1,7 @@ +<input name="field_extra[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + {% if column_meta['Extra'] is defined and column_meta['Extra']|lower == 'auto_increment' -%} + checked="checked" + {%- endif %} + type="checkbox" + value="AUTO_INCREMENT"> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig b/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig new file mode 100644 index 0000000..653441b --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_comment.twig @@ -0,0 +1,6 @@ +<textarea id="field_{{ column_number }}_{{ ci - ci_offset }}" + rows="1" + name="field_comments[{{ column_number }}]" + maxlength="{{ max_length }}"> + {{- value|raw -}} +</textarea> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_default.twig b/srcs/phpmyadmin/templates/columns_definitions/column_default.twig new file mode 100644 index 0000000..dcb6644 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_default.twig @@ -0,0 +1,35 @@ +{# here we put 'NONE' as the default value of drop-down; otherwise users would +have problems if they forget to enter the default value (example, for an INT) #} +{% set translation %}{% trans %}None{% context %}for default{% endtrans %}{% endset %} +{% set default_options = { + 'NONE': translation, + 'USER_DEFINED': 'As defined:'|trans, + 'NULL': 'NULL', + 'CURRENT_TIMESTAMP': 'CURRENT_TIMESTAMP' +} %} + +<select name="field_default_type[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + class="default_type"> + {% for key, value in default_options %} + <option value="{{ key }}" + {%- if column_meta['DefaultType'] is defined + and column_meta['DefaultType'] == key %} + selected="selected" + {%- endif %}> + {{ value }} + </option> + {% endfor %} +</select> +{% if char_editing == 'textarea' %} + <textarea name="field_default_value[{{ column_number }}]" + cols="15" + class="textfield + default_value">{{ default_value }}</textarea> +{% else %} + <input type="text" + name="field_default_value[{{ column_number }}]" + size="12" + value="{{ default_value }}" + class="textfield default_value"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig b/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig new file mode 100644 index 0000000..1fd4b64 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_definitions_form.twig @@ -0,0 +1,155 @@ +<form method="post" action="{{ action }}" class=" + {{- action == 'tbl_create.php' ? 'create_table' : 'append_fields' -}} + _form ajax lock-page"> + {{ get_hidden_inputs(form_params) }} + {# happens when an index has been set on a column #} + {# and a column is added to the table creation dialog #} + {# This contains a JSON-encoded string #} + <input type="hidden" name="primary_indexes" value=" + {{- primary_indexes is not empty ? primary_indexes : '[]' }}"> + <input type="hidden" name="unique_indexes" value=" + {{- unique_indexes is not empty ? unique_indexes : '[]' }}"> + <input type="hidden" name="indexes" value=" + {{- indexes is not empty ? indexes : '[]' }}"> + <input type="hidden" name="fulltext_indexes" value=" + {{- fulltext_indexes is not empty ? fulltext_indexes : '[]' }}"> + <input type="hidden" name="spatial_indexes" value=" + {{- spatial_indexes is not empty ? spatial_indexes : '[]' }}"> + + {% if action == 'tbl_create.php' %} + <div id="table_name_col_no_outer"> + <table id="table_name_col_no" class="tdblock"> + <tr class="vmiddle floatleft"> + <td>{% trans 'Table name' %}: + <input type="text" + name="table" + size="40" + maxlength="64" + value="{{ table is defined ? table }}" + class="textfield" autofocus required> + </td> + <td> + {% trans 'Add' %} + <input type="number" + id="added_fields" + name="added_fields" + size="2" + value="1" + min="1" + onfocus="this.select()"> + {% trans 'column(s)' %} + <input class="btn btn-secondary" type="button" + name="submit_num_fields" + value="{% trans 'Go' %}"> + </td> + </tr> + </table> + </div> + {% endif %} + {% if content_cells is iterable %} + {% include 'columns_definitions/table_fields_definitions.twig' with { + 'is_backup': is_backup, + 'fields_meta': fields_meta, + 'mimework': mimework, + 'content_cells': content_cells, + 'change_column': change_column, + 'is_virtual_columns_supported': is_virtual_columns_supported, + 'browse_mime': browse_mime, + 'server_type': server_type, + 'max_rows': max_rows, + 'char_editing': char_editing, + 'attribute_types': attribute_types, + 'privs_available': privs_available, + 'max_length': max_length, + 'charsets': charsets + } only %} + {% endif %} + {% if action == 'tbl_create.php' %} + <div class="responsivetable"> + <table> + <tr class="vtop"> + <th>{% trans 'Table comments:' %}</th> + <td width="25"> </td> + <th>{% trans 'Collation:' %}</th> + <td width="25"> </td> + <th> + {% trans 'Storage Engine:' %} + {{ show_mysql_docu('Storage_engines') }} + </th> + <td width="25"> </td> + <th> + {% trans 'Connection:' %} + {{ show_mysql_docu('federated-create-connection') }} + </th> + </tr> + <tr> + <td> + <input type="text" + name="comment" + size="40" + maxlength="60" + value="{{ comment is defined ? comment }}" + class="textfield"> + </td> + <td width="25"> </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"> </td> + <td> + {{ get_html_select( + 'tbl_storage_engine', + null, + tbl_storage_engine + ) }} + </td> + <td width="25"> </td> + <td> + <input type="text" + name="connection" + size="40" + value="{{ connection is defined ? connection }}" + placeholder="scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name" + class="textfield" + required="required"> + </td> + </tr> + {% if have_partitioning %} + <tr class="vtop"> + <th colspan="5"> + {% trans 'PARTITION definition:' %} + {{ show_mysql_docu('Partitioning') }} + </th> + </tr> + <tr> + <td colspan="5"> + {% include 'columns_definitions/partitions.twig' with { + 'partition_details': partition_details + } only %} + </td> + </tr> + {% endif %} + </table> + </div> + {% endif %} + <fieldset class="tblFooters"> + <input class="btn btn-secondary preview_sql" type="button" + value="{% trans 'Preview SQL' %}"> + <input class="btn btn-primary" type="submit" + name="do_save_data" + value="{% trans 'Save' %}"> + </fieldset> + <div id="properties_message"></div> +</form> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig b/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig new file mode 100644 index 0000000..7f61f5c --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_extra.twig @@ -0,0 +1,7 @@ +<input name="col_extra[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + {% if column_meta['Extra'] is not empty and column_meta['Extra'] == 'auto_increment' -%} + checked="checked" + {%- endif %} + type="checkbox" + value="auto_increment"> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig b/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig new file mode 100644 index 0000000..3980229 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_indexes.twig @@ -0,0 +1,24 @@ +<select name="field_key[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" data-index=""> + <option value="none_{{ column_number }}">---</option> + <option value="primary_{{ column_number }}" title="{% trans "Primary" %}" + {{- column_meta['Key'] is defined and column_meta['Key'] == 'PRI' ? ' selected="selected"' }}> + PRIMARY + </option> + <option value="unique_{{ column_number }}" title="{% trans "Unique" %}" + {{- column_meta['Key'] is defined and column_meta['Key'] == 'UNI' ? ' selected="selected"' }}> + UNIQUE + </option> + <option value="index_{{ column_number }}" title="{% trans "Index" %}" + {{- column_meta['Key'] is defined and column_meta['Key'] == 'MUL' ? ' selected="selected"' }}> + INDEX + </option> + <option value="fulltext_{{ column_number }}" title="{% trans "Fulltext" %}" + {{- column_meta['Key'] is defined and column_meta['Key'] == 'FULLTEXT' ? ' selected="selected"' }}> + FULLTEXT + </option> + <option value="spatial_{{ column_number }}" title="{% trans "Spatial" %}" + {{- column_meta['Key'] is defined and column_meta['Key'] == 'SPATIAL' ? ' selected="selected"' }}> + SPATIAL + </option> +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_length.twig b/srcs/phpmyadmin/templates/columns_definitions/column_length.twig new file mode 100644 index 0000000..ef7e5f0 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_length.twig @@ -0,0 +1,11 @@ +<input id="field_{{ column_number }}_{{ ci - ci_offset }}" + type="text" + name="field_length[{{ column_number }}]" + size="{{ length_values_input_size }}" + value="{{ length_to_display }}" + class="textfield"> +<p class="enum_notice" id="enum_notice_{{ column_number }}_{{ ci - ci_offset }}"> + <a href="#" class="open_enum_editor"> + {% trans 'Edit ENUM/SET values' %} + </a> +</p> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_name.twig b/srcs/phpmyadmin/templates/columns_definitions/column_name.twig new file mode 100644 index 0000000..a0a31ad --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_name.twig @@ -0,0 +1,42 @@ +{% set title = '' %} +{% if column_meta['column_status'] is defined %} + {% if column_meta['column_status']['isReferenced'] %} + {% set title = title ~ 'Referenced by %s.'|trans|format( + column_meta['column_status']['references']|join(',') + ) %} + {% endif %} + {% if column_meta['column_status']['isForeignKey'] %} + {% if title is not empty %} + {% set title = title ~ '\n'|raw %} + {% endif %} + {% set title = title ~ 'Is a foreign key.'|trans %} + {% endif %} +{% endif %} +{% if title is empty %} + {% set title = 'Column'|trans %} +{% endif %} + +<input id="field_{{ column_number }}_{{ ci - ci_offset }}" + {% if column_meta['column_status'] is defined + and not column_meta['column_status']['isEditable'] %} + disabled="disabled" + {% endif %} + type="text" + name="field_name[{{ column_number }}]" + maxlength="64" + class="textfield" + title="{{ title }}" + size="10" + value="{{ column_meta['Field'] is defined ? column_meta['Field'] }}"> + +{% if cfg_relation['centralcolumnswork'] + and not (column_meta['column_status'] is defined + and not column_meta['column_status']['isEditable']) %} + <p class="column_name" id="central_columns_{{ column_number }}_{{ ci - ci_offset }}"> + <a data-maxrows="{{ max_rows }}" + href="#" + class="central_columns_dialog"> + {% trans 'Pick from Central Columns' %} + </a> + </p> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_null.twig b/srcs/phpmyadmin/templates/columns_definitions/column_null.twig new file mode 100644 index 0000000..5afd649 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_null.twig @@ -0,0 +1,8 @@ +<input name="field_null[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + {% if column_meta['Null'] is not empty and column_meta['Null'] != 'NO' and column_meta['Null'] != 'NOT NULL' -%} + checked="checked" + {%- endif %} + type="checkbox" + value="YES" + class="allow_null"> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_type.twig b/srcs/phpmyadmin/templates/columns_definitions/column_type.twig new file mode 100644 index 0000000..e74eb0e --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_type.twig @@ -0,0 +1,8 @@ +<select class="column_type" + name="field_type[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + {%- if column_meta['column_status'] is defined and not column_meta['column_status']['isEditable'] -%} + disabled="disabled" + {%- endif %}> + {{ get_supported_datatypes(true, type_upper) }} +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig b/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig new file mode 100644 index 0000000..96f020e --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/column_virtuality.twig @@ -0,0 +1,32 @@ +<select name="field_virtuality[{{ column_number }}]" + id="field_{{ column_number }}_{{ ci - ci_offset }}" + class="virtuality"> + {% for key, value in options %} + <option value="{{ key }}" + {% set key_length = key|length %} + {%- if column_meta['Extra'] is defined + and key != '' + and column_meta['Extra']|slice(0,key_length) is same as (key) %} + selected="selected" + {%- endif %}> + {{ value }} + </option> + {% endfor %} +</select> + +{% if char_editing == 'textarea' %} + {% apply spaceless %} + <textarea name="field_expression[{{ column_number }}]" + cols="15" + class="textfield expression"> + {{ expression }} + </textarea> + {% endapply %} +{% else %} + <input type="text" + name="field_expression[{{ column_number }}]" + size="12" + value="{{ expression }}" + placeholder="{% trans 'Expression' %}" + class="textfield expression"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig b/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig new file mode 100644 index 0000000..ef395b6 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/mime_type.twig @@ -0,0 +1,17 @@ +<select id="field_{{ column_number }}_{{ ci - ci_offset }}" + size="1" + name="field_mimetype[{{ column_number }}]"> + <option value=""> </option> + {% if available_mime['mimetype'] is defined + and available_mime['mimetype'] is iterable %} + {% for mimetype in available_mime['mimetype'] %} + {% set checked = column_meta['Field'] is defined + and mime_map[column_meta['Field']]['mimetype'] is defined + and mime_map[column_meta['Field']]['mimetype'] == mimetype|replace({'/': '_'}) + ? ' selected' %} + <option value="{{ mimetype|replace({'/': '_'}) }}"{{ checked }}> + {{ mimetype|lower }} + </option> + {% endfor %} + {% endif %} +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/move_column.twig b/srcs/phpmyadmin/templates/columns_definitions/move_column.twig new file mode 100644 index 0000000..7c0b3f4 --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/move_column.twig @@ -0,0 +1,15 @@ +<select id="field_{{ column_number }}_{{ ci - ci_offset }}" + name="field_move_to[{{ column_number }}]" + size="1" + width="5em"> + <option value="" selected="selected"> </option> + <option value="-first"{{ current_index == 0 ? ' disabled="disabled"' }}> + {% trans 'first' %} + </option> + {% for mi in 0..move_columns|length - 1 %} + <option value="{{ move_columns[mi].name }}" + {{- current_index == mi or current_index == mi + 1 ? ' disabled="disabled"' }}> + {{ 'after %s'|trans|format(backquote(move_columns[mi].name|e)) }} + </option> + {% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/partitions.twig b/srcs/phpmyadmin/templates/columns_definitions/partitions.twig new file mode 100644 index 0000000..b8c88af --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/partitions.twig @@ -0,0 +1,180 @@ +{% set partition_options = [ + '', + 'HASH', + 'LINEAR HASH', + 'KEY', + 'LINEAR KEY', + 'RANGE', + 'RANGE COLUMNS', + 'LIST', + 'LIST COLUMNS' +] %} +{% set sub_partition_options = ['', 'HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY'] %} +{% set value_type_options = ['', 'LESS THAN', 'LESS THAN MAXVALUE', 'IN'] %} + +<table id="partition_table"> + <tr class="vmiddle"> + <td><label for="partition_by">{% trans 'Partition by:' %}</label></td> + <td> + <select name="partition_by" id="partition_by"> + {% for option in partition_options %} + <option value="{{ option }}" + {%- if partition_details['partition_by'] == option %} + selected="selected" + {%- endif %}> + {{ option }} + </option> + {% endfor %} + </select> + </td> + <td> + (<input name="partition_expr" type="text" + placeholder="{% trans 'Expression or column list' %}" + value="{{ partition_details['partition_expr'] }}">) + </td> + </tr> + <tr class="vmiddle"> + <td><label for="partition_count">{% trans 'Partitions:' %}</label></td> + <td colspan="2"> + <input name="partition_count" type="number" min="2" + value="{{ partition_details['partition_count'] }}"> + </td> + </tr> + {% if partition_details['can_have_subpartitions'] %} + <tr class="vmiddle"> + <td><label for="subpartition_by">{% trans 'Subpartition by:' %}</label></td> + <td> + <select name="subpartition_by" id="subpartition_by"> + {% for option in sub_partition_options %} + <option value="{{ option }}" + {%- if partition_details['subpartition_by'] == option %} + selected="selected" + {%- endif %}> + {{ option }} + </option> + {% endfor %} + </select> + </td> + <td> + (<input name="subpartition_expr" type="text" + placeholder="{% trans 'Expression or column list' %}" + value="{{ partition_details['subpartition_expr'] }}">) + </td> + </tr> + <tr class="vmiddle"> + <td><label for="subpartition_count">{% trans 'Subpartitions:' %}</label></td> + <td colspan="2"> + <input name="subpartition_count" type="number" min="2" + value="{{ partition_details['subpartition_count'] }}"> + </td> + </tr> + {% endif %} +</table> +{% if partition_details['partition_count'] > 1 %} + <table id="partition_definition_table"> + <thead><tr> + <th>{% trans 'Partition' %}</th> + {% if partition_details['value_enabled'] %} + <th>{% trans 'Values' %}</th> + {% endif %} + {% if partition_details['can_have_subpartitions'] + and partition_details['subpartition_count'] > 1 %} + <th>{% trans 'Subpartition' %}</th> + {% endif %} + <th>{% trans 'Engine' %}</th> + <th>{% trans 'Comment' %}</th> + <th>{% trans 'Data directory' %}</th> + <th>{% trans 'Index directory' %}</th> + <th>{% trans 'Max rows' %}</th> + <th>{% trans 'Min rows' %}</th> + <th>{% trans 'Table space' %}</th> + <th>{% trans 'Node group' %}</th> + </tr></thead> + {% for partition in partition_details['partitions'] %} + {% set rowspan = partition['subpartition_count'] is not empty + ? partition['subpartition_count'] + 1 : 2 %} + <tr> + <td rowspan="{{ rowspan }}"> + <input type="text" name="{{ partition['prefix'] }}[name]" + value="{{ partition['name'] }}"> + </td> + {% if partition_details['value_enabled'] %} + <td rowspan="{{ rowspan }}" class="vmiddle"> + <select class="partition_value" + name="{{ partition['prefix'] }}[value_type]"> + {% for option in value_type_options %} + <option value="{{ option }}" + {%- if partition['value_type'] == option %} + selected="selected" + {%- endif %}> + {{ option }} + </option> + {% endfor %} + </select> + <input type="text" class="partition_value" + name="{{ partition['prefix'] }}[value]" + value="{{ partition['value'] }}"> + </td> + {% endif %} + </tr> + + {% if partition['subpartitions'] is defined %} + {% set subpartitions = partition['subpartitions'] %} + {% else %} + {% set subpartitions = [partition] %} + {% endif %} + + {% for subpartition in subpartitions %} + <tr> + {% if partition_details['can_have_subpartitions'] + and partition_details['subpartition_count'] > 1 %} + <td> + <input type="text" name="{{ subpartition['prefix'] }}[name]" + value="{{ subpartition['name'] }}"> + </td> + {% endif %} + <td> + {{ get_html_select( + subpartition['prefix'] ~ '[engine]', + null, + subpartition['engine'], + false, + true + ) }} + </td> + <td> + {% apply spaceless %} + <textarea name="{{ subpartition['prefix'] }}[comment]"> + {{ subpartition['comment'] }} + </textarea> + {% endapply %} + </td> + <td> + <input type="text" name="{{ subpartition['prefix'] }}[data_directory]" + value="{{ subpartition['data_directory'] }}"> + </td> + <td> + <input type="text" name="{{ subpartition['prefix'] }}[index_directory]" + value="{{ subpartition['index_directory'] }}"> + </td> + <td> + <input type="number" name="{{ subpartition['prefix'] }}[max_rows]" + value="{{ subpartition['max_rows'] }}"> + </td> + <td> + <input type="number" min="0" name="{{ subpartition['prefix'] }}[min_rows]" + value="{{ subpartition['min_rows'] }}"> + </td> + <td> + <input type="text" min="0" name="{{ subpartition['prefix'] }}[tablespace]" + value="{{ subpartition['tablespace'] }}"> + </td> + <td> + <input type="text" name="{{ subpartition['prefix'] }}[node_group]" + value="{{ subpartition['node_group'] }}"> + </td> + </tr> + {% endfor %} + {% endfor %} + </table> +{% endif %} diff --git a/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig b/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig new file mode 100644 index 0000000..f23b2fe --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/table_fields_definitions.twig @@ -0,0 +1,122 @@ +<div class="responsivetable"> +<table id="table_columns" class="noclick"> + <caption class="tblHeaders"> + {% trans 'Structure' %} + {{ show_mysql_docu('CREATE_TABLE') }} + </caption> + <tr> + <th> + {% trans 'Name' %} + </th> + <th> + {% trans 'Type' %} + {{ show_mysql_docu('data-types') }} + </th> + <th> + {% trans 'Length/Values' %} + {{ show_hint('If column type is "enum" or "set", please enter the values using this format: \'a\',\'b\',\'c\'…<br>If you ever need to put a backslash ("\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }} + </th> + <th> + {% trans 'Default' %} + {{ show_hint('For default values, please enter just a single value, without backslash escaping or quotes, using this format: a'|trans) }} + </th> + <th> + {% trans 'Collation' %} + </th> + <th> + {% trans 'Attributes' %} + </th> + <th> + {% trans 'Null' %} + </th> + + {# Only for 'Edit' Column(s) #} + {% if change_column is defined and change_column is not empty %} + <th> + {% trans 'Adjust privileges' %} + {{ show_docu('faq', 'faq6-39') }} + </th> + {% endif %} + + {# We could remove this 'if' and let the key information be shown and + editable. However, for this to work, structure.lib.php must be + modified to use the key fields, as tbl_addfield does. #} + {% if not is_backup %} + <th> + {% trans 'Index' %} + </th> + {% endif %} + + <th> + <abbr title="AUTO_INCREMENT">A_I</abbr> + </th> + <th> + {% trans 'Comments' %} + </th> + + {% if is_virtual_columns_supported %} + <th> + {% trans 'Virtuality' %} + </th> + {% endif %} + + {% if fields_meta is defined %} + <th> + {% trans 'Move column' %} + </th> + {% endif %} + + {% if mimework and browse_mime %} + <th> + {% trans 'Media (MIME) type' %} + </th> + <th> + <a href="transformation_overview.php + {{- get_common() }}#transformation" title=" + {%- trans 'List of available transformations and their options' -%} + " target="_blank"> + {% trans 'Browser display transformation' %} + </a> + </th> + <th> + {% trans 'Browser display transformation options' %} + {{ show_hint('Please enter the values for transformation options using this format: \'a\', 100, b,\'c\'…<br>If you ever need to put a backslash ("\\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }} + </th> + <th> + <a href="transformation_overview.php{{ get_common() }}#input_transformation" + title="{% trans 'List of available transformations and their options' %}" + target="_blank"> + {% trans 'Input transformation' %} + </a> + </th> + <th> + {% trans 'Input transformation options' %} + {{ show_hint('Please enter the values for transformation options using this format: \'a\', 100, b,\'c\'…<br>If you ever need to put a backslash ("\\") or a single quote ("\'") amongst those values, precede it with a backslash (for example \'\\\\xyz\' or \'a\\\'b\').'|trans) }} + </th> + {% endif %} + </tr> + {% set options = {'': '', 'VIRTUAL': 'VIRTUAL'} %} + {% if server_type == 'MariaDB' %} + {% set options = options|merge({'PERSISTENT': 'PERSISTENT'}) %} + {% set options = options|merge({'STORED': 'STORED'}) %} + {% else %} + {% set options = options|merge({'STORED': 'STORED'}) %} + {% endif %} + {% for content_row in content_cells %} + <tr> + {% include 'columns_definitions/column_attributes.twig' with content_row|merge({ + 'options': options, + 'change_column': change_column, + 'is_virtual_columns_supported': is_virtual_columns_supported, + 'browse_mime': browse_mime, + 'max_rows': max_rows, + 'char_editing': char_editing, + 'attribute_types': attribute_types, + 'privs_available': privs_available, + 'max_length': max_length, + 'charsets': charsets + }) only %} + </tr> + {% endfor %} +</table> +</div> diff --git a/srcs/phpmyadmin/templates/columns_definitions/transformation.twig b/srcs/phpmyadmin/templates/columns_definitions/transformation.twig new file mode 100644 index 0000000..9aec94a --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/transformation.twig @@ -0,0 +1,26 @@ +<select id="field_{{ column_number }}_{{ ci - ci_offset }}" + size="1" + name="field_{{ type }}[{{ column_number }}]"> + <option value="" title="{% trans 'None' %}"></option> + {% if available_mime[type] is defined and available_mime[type] is iterable %} + {% for mimekey, transform in available_mime[type] %} + {% set checked = column_meta['Field'] is defined + and mime_map[column_meta['Field']][type] is defined + and mime_map[column_meta['Field']][type] matches + '@' ~ available_mime[type ~ '_file_quoted'][mimekey] ~ '3?@i' + ? 'selected ' %} + {% set tooltip = get_description( + available_mime[type ~ '_file'][mimekey] + ) %} + {% set parts = transform|split(':') %} + {% set name = get_name( + available_mime[type ~ '_file'][mimekey] + ) ~ ' (' ~ parts[0]|lower ~ ':' ~ parts[1] ~ ')' %} + <option value="{{ available_mime[type ~ '_file'][mimekey] }}" + {{ checked }} + title="{{ tooltip }}"> + {{ name }} + </option> + {% endfor %} + {% endif %} +</select> diff --git a/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig b/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig new file mode 100644 index 0000000..f87ba7c --- /dev/null +++ b/srcs/phpmyadmin/templates/columns_definitions/transformation_option.twig @@ -0,0 +1,9 @@ +{% set options_key = type_prefix ~ 'transformation_options' %} +<input id="field_{{ column_number }}_{{ ci - ci_offset }}" + type="text" + name="field_{{ options_key }}[{{ column_number }}]" + size="16" + class="textfield" + value="{% if column_meta['Field'] is defined and mime_map[column_meta['Field']][options_key] is defined -%} + {{- mime_map[column_meta['Field']][options_key] -}} + {%- endif %}"> diff --git a/srcs/phpmyadmin/templates/components/error_message.twig b/srcs/phpmyadmin/templates/components/error_message.twig new file mode 100644 index 0000000..5b964c3 --- /dev/null +++ b/srcs/phpmyadmin/templates/components/error_message.twig @@ -0,0 +1,4 @@ +<div class="error"> + <img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> + {{ msg }} +</div> diff --git a/srcs/phpmyadmin/templates/config/form_display/errors.twig b/srcs/phpmyadmin/templates/config/form_display/errors.twig new file mode 100644 index 0000000..b243ce4 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/errors.twig @@ -0,0 +1,6 @@ +<dl> + <dt>{{ name }}</dt> + {% for error in error_list %} + <dd>{{ error|raw }}</dd> + {% endfor %} +</dl> diff --git a/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig new file mode 100644 index 0000000..1c8d570 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/fieldset_bottom.twig @@ -0,0 +1,14 @@ +{% set colspan = 2 %} +{% if is_setup %} + {% set colspan = colspan + 1 %} +{% endif %} +{% if show_buttons %} + <tr> + <td colspan="{{ colspan }}" class="lastrow"> + <input class="btn btn-primary green" type="submit" name="submit_save" value="{% trans 'Apply' %}"> + <input class="btn btn-secondary" type="button" name="submit_reset" value="{% trans 'Reset' %}"> + </td> + </tr> +{% endif %} +</table> +</fieldset> diff --git a/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig b/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig new file mode 100644 index 0000000..e359e92 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/fieldset_top.twig @@ -0,0 +1,17 @@ +<fieldset + {%- for key, value in attributes -%} + {{- ' ' }}{{ key }}="{{ value }}" + {%- endfor %}> +<legend>{{ title }}</legend> +{% if description is not empty %} + <p>{{ description|raw }}</p> +{% endif %} +{# This must match with displayErrors() in scripts.js #} +{% if errors is iterable and errors|length > 0 %} + <dl class="errors"> + {% for error in errors %} + <dd>{{ error }}</dd> + {% endfor %} + </dl> +{% endif %} +<table width="100%" cellspacing="0"> diff --git a/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig new file mode 100644 index 0000000..5582354 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/form_bottom.twig @@ -0,0 +1 @@ +</form> diff --git a/srcs/phpmyadmin/templates/config/form_display/group_header.twig b/srcs/phpmyadmin/templates/config/form_display/group_header.twig new file mode 100644 index 0000000..47f1388 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/group_header.twig @@ -0,0 +1,5 @@ +<tr class="group-header group-header-{{ group }}"> + <th colspan="{{ colspan }}"> + {{ header_text }} + </th> +</tr> diff --git a/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig b/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig new file mode 100644 index 0000000..04f5b84 --- /dev/null +++ b/srcs/phpmyadmin/templates/config/form_display/tabs_bottom.twig @@ -0,0 +1 @@ +</div> diff --git a/srcs/phpmyadmin/templates/console/bookmark_content.twig b/srcs/phpmyadmin/templates/console/bookmark_content.twig new file mode 100644 index 0000000..259edbf --- /dev/null +++ b/srcs/phpmyadmin/templates/console/bookmark_content.twig @@ -0,0 +1,25 @@ +<div class="message welcome"> + <span>{{ welcome_message }}</span> +</div> +{% for bookmark in bookmarks %} + <div class="message collapsed bookmark" bookmarkid="{{ bookmark.getId() }}" + targetdb="{{ bookmark.getDatabase() }}"> + {% include 'console/query_action.twig' with { + 'parent_div_classes': 'action_content', + 'content_array': [ + ['action collapse', 'Collapse'|trans], + ['action expand', 'Expand'|trans], + ['action requery', 'Requery'|trans], + ['action edit_bookmark', 'Edit'|trans], + ['action delete_bookmark', 'Delete'|trans], + {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': bookmark.getDatabase()} + ] + } only %} + <span class="bookmark_label{{ bookmark.getUser() is empty ? ' shared' }}"> + {{ bookmark.getLabel() }} + </span> + <span class="query"> + {{ bookmark.getQuery() }} + </span> + </div> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/console/display.twig b/srcs/phpmyadmin/templates/console/display.twig new file mode 100644 index 0000000..3d54c9e --- /dev/null +++ b/srcs/phpmyadmin/templates/console/display.twig @@ -0,0 +1,192 @@ +<div id="pma_console_container"> + <div id="pma_console"> + {# Console toolbar #} + {% include 'console/toolbar.twig' with { + 'parent_div_classes': 'collapsed', + 'content_array': [ + {0: 'switch_button console_switch', 1: 'Console'|trans, 'image': image}, + ['button clear', 'Clear'|trans], + ['button history', 'History'|trans], + ['button options', 'Options'|trans], + cfg_bookmark is defined ? ['button bookmarks', 'Bookmarks'|trans] : null, + ['button debug hide', 'Debug SQL'|trans] + ] + } only %} + {# Console messages #} + <div class="content"> + <div class="console_message_container"> + <div class="message welcome"> + <span id="instructions-0"> + {% trans 'Press Ctrl+Enter to execute query' %} + </span> + <span class="hide" id="instructions-1"> + {% trans 'Press Enter to execute query' %} + </span> + </div> + {% if sql_history is not empty %} + {% for record in sql_history|reverse %} + <div class="message history collapsed hide + {{- record['sqlquery'] matches '@^SELECT[[:space:]]+@i' ? ' select' }}" + targetdb="{{ record['db'] }}" targettable="{{ record['table'] }}"> + {% include 'console/query_action.twig' with { + 'parent_div_classes': 'action_content', + 'content_array': [ + ['action collapse', 'Collapse'|trans], + ['action expand', 'Expand'|trans], + ['action requery', 'Requery'|trans], + ['action edit', 'Edit'|trans], + ['action explain', 'Explain'|trans], + ['action profiling', 'Profiling'|trans], + cfg_bookmark is defined ? ['action bookmark', 'Bookmark'|trans] : null, + ['text failed', 'Query failed'|trans], + {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': record['db']}, + { + 0: 'text query_time', + 1: 'Queried time'|trans, + 'extraSpan': record['timevalue'] is defined ? + record['timevalue'] : 'During current session'|trans + } + ] + } only %} + <span class="query">{{ record['sqlquery'] }}</span> + </div> + {% endfor %} + {% endif %} + </div><!-- console_message_container --> + <div class="query_input"> + <span class="console_query_input"></span> + </div> + </div><!-- message end --> + {# Drak the console with other cards over it #} + <div class="mid_layer"></div> + {# Debug SQL card #} + <div class="card" id="debug_console"> + {% include 'console/toolbar.twig' with { + 'parent_div_classes': '', + 'content_array': [ + ['button order order_asc', 'ascending'|trans], + ['button order order_desc', 'descending'|trans], + ['text', 'Order:'|trans], + ['switch_button', 'Debug SQL'|trans], + ['button order_by sort_count', 'Count'|trans], + ['button order_by sort_exec', 'Execution order'|trans], + ['button order_by sort_time', 'Time taken'|trans], + ['text', 'Order by:'|trans], + ['button group_queries', 'Group queries'|trans], + ['button ungroup_queries', 'Ungroup queries'|trans] + ] + } only %} + <div class="content debug"> + <div class="message welcome"></div> + <div class="debugLog"></div> + </div> <!-- Content --> + <div class="templates"> + {% include 'console/query_action.twig' with { + 'parent_div_classes': 'debug_query action_content', + 'content_array': [ + ['action collapse', 'Collapse'|trans], + ['action expand', 'Expand'|trans], + ['action dbg_show_trace', 'Show trace'|trans], + ['action dbg_hide_trace', 'Hide trace'|trans], + ['text count hide', 'Count'|trans], + ['text time', 'Time taken'|trans] + ] + } only %} + </div> <!-- Template --> + </div> <!-- Debug SQL card --> + {% if cfg_bookmark %} + <div class="card" id="pma_bookmarks"> + {% include 'console/toolbar.twig' with { + 'parent_div_classes': '', + 'content_array': [ + ['switch_button', 'Bookmarks'|trans], + ['button refresh', 'Refresh'|trans], + ['button add', 'Add'|trans] + ] + } only %} + <div class="content bookmark"> + {{ bookmark_content|raw }} + </div> + <div class="mid_layer"></div> + <div class="card add"> + {% include 'console/toolbar.twig' with { + 'parent_div_classes': '', + 'content_array': [ + ['switch_button', 'Add bookmark'|trans] + ] + } only %} + <div class="content add_bookmark"> + <div class="options"> + <label> + {% trans 'Label' %}: <input type="text" name="label"> + </label> + <label> + {% trans 'Target database' %}: <input type="text" name="targetdb"> + </label> + <label> + <input type="checkbox" name="shared">{% trans 'Share this bookmark' %} + </label> + <button class="btn btn-primary" type="submit" name="submit">{% trans 'OK' %}</button> + </div> <!-- options --> + <div class="query_input"> + <span class="bookmark_add_input"></span> + </div> + </div> + </div> <!-- Add bookmark card --> + </div> <!-- Bookmarks card --> + {% endif %} + {# Options card #} + <div class="card" id="pma_console_options"> + {% include 'console/toolbar.twig' with { + 'parent_div_classes': '', + 'content_array': [ + ['switch_button', 'Options'|trans], + ['button default', 'Set default'|trans] + ] + } only %} + <div class="content"> + <label> + <input type="checkbox" name="always_expand">{% trans 'Always expand query messages' %} + </label> + <br> + <label> + <input type="checkbox" name="start_history">{% trans 'Show query history at start' %} + </label> + <br> + <label> + <input type="checkbox" name="current_query">{% trans 'Show current browsing query' %} + </label> + <br> + <label> + <input type="checkbox" name="enter_executes"> + {% trans %} + Execute queries on Enter and insert new line with Shift + Enter. To make this permanent, view settings. + {% endtrans %} + </label> + <br> + <label> + <input type="checkbox" name="dark_theme">{% trans 'Switch to dark theme' %} + </label> + <br> + </div> + </div> <!-- Options card --> + <div class="templates"> + {# Templates for console message actions #} + {% include 'console/query_action.twig' with { + 'parent_div_classes': 'query_actions', + 'content_array': [ + ['action collapse', 'Collapse'|trans], + ['action expand', 'Expand'|trans], + ['action requery', 'Requery'|trans], + ['action edit', 'Edit'|trans], + ['action explain', 'Explain'|trans], + ['action profiling', 'Profiling'|trans], + cfg_bookmark is defined ? ['action bookmark', 'Bookmark'|trans] : null, + ['text failed', 'Query failed'|trans], + {0: 'text targetdb', 1: 'Database'|trans, 'extraSpan': ''}, + {0: 'text query_time', 1: 'Queried time'|trans, 'extraSpan': ''} + ] + } only %} + </div> + </div> <!-- #console end --> +</div> <!-- #console_container end --> diff --git a/srcs/phpmyadmin/templates/console/query_action.twig b/srcs/phpmyadmin/templates/console/query_action.twig new file mode 100644 index 0000000..62bc30a --- /dev/null +++ b/srcs/phpmyadmin/templates/console/query_action.twig @@ -0,0 +1,12 @@ +<div class="{{ parent_div_classes }}"> + {% for content in content_array %} + {% if content is defined %} + <span class="{{ content[0] }}"> + {{ content[1] }} + {% if content['extraSpan'] is defined %} + : <span>{{ content['extraSpan'] }}</span> + {% endif %} + </span> + {% endif %} + {% endfor %} +</div> diff --git a/srcs/phpmyadmin/templates/console/toolbar.twig b/srcs/phpmyadmin/templates/console/toolbar.twig new file mode 100644 index 0000000..b16c290 --- /dev/null +++ b/srcs/phpmyadmin/templates/console/toolbar.twig @@ -0,0 +1,10 @@ +<div class="toolbar {{ parent_div_classes }}"> + {% for content in content_array %} + {% if content is defined %} + <div class="{{ content[0] }}"> + {{ content['image'] is defined ? content['image']|raw }} + <span>{{ content[1] }}</span> + </div> + {% endif %} + {% endfor %} +</div> diff --git a/srcs/phpmyadmin/templates/create_tracking_version.twig b/srcs/phpmyadmin/templates/create_tracking_version.twig new file mode 100644 index 0000000..ba93434 --- /dev/null +++ b/srcs/phpmyadmin/templates/create_tracking_version.twig @@ -0,0 +1,79 @@ +<div id="div_create_version"> + <form method="post" action="{{ url_query|raw }}"> + {{ get_hidden_inputs(db) }} + {% for selected_table in selected %} + <input type="hidden" name="selected[]" value="{{ selected_table }}"> + {% endfor %} + + <fieldset> + <legend> + {% if selected|length == 1 %} + {{ 'Create version %1$s of %2$s'|trans|format( + last_version + 1, + db ~ '.' ~ selected[0] + ) }} + {% else %} + {{ 'Create version %1$s'|trans|format(last_version + 1) }} + {% endif %} + </legend> + <input type="hidden" name="version" value="{{ last_version + 1 }}"> + <p>{% trans 'Track these data definition statements:' %}</p> + + {% if type == 'both' or type == 'table' %} + <input type="checkbox" name="alter_table" value="true" + {{- 'ALTER TABLE' in default_statements ? ' checked="checked"' }}> + ALTER TABLE<br> + <input type="checkbox" name="rename_table" value="true" + {{- 'RENAME TABLE' in default_statements ? ' checked="checked"' }}> + RENAME TABLE<br> + <input type="checkbox" name="create_table" value="true" + {{- 'CREATE TABLE' in default_statements ? ' checked="checked"' }}> + CREATE TABLE<br> + <input type="checkbox" name="drop_table" value="true" + {{- 'DROP TABLE' in default_statements ? ' checked="checked"' }}> + DROP TABLE<br> + {% endif %} + {% if type == 'both' %} + <br> + {% endif %} + {% if type == 'both' or type == 'view' %} + <input type="checkbox" name="alter_view" value="true" + {{- 'ALTER VIEW' in default_statements ? ' checked="checked"' }}> + ALTER VIEW<br> + <input type="checkbox" name="create_view" value="true" + {{- 'CREATE VIEW' in default_statements ? ' checked="checked"' }}> + CREATE VIEW<br> + <input type="checkbox" name="drop_view" value="true" + {{- 'DROP VIEW' in default_statements ? ' checked="checked"' }}> + DROP VIEW<br> + {% endif %} + <br> + + <input type="checkbox" name="create_index" value="true" + {{- 'CREATE INDEX' in default_statements ? ' checked="checked"' }}> + CREATE INDEX<br> + <input type="checkbox" name="drop_index" value="true" + {{- 'DROP INDEX' in default_statements ? ' checked="checked"' }}> + DROP INDEX<br> + + <p>{% trans 'Track these data manipulation statements:' %}</p> + <input type="checkbox" name="insert" value="true" + {{- 'INSERT' in default_statements ? ' checked="checked"' }}> + INSERT<br> + <input type="checkbox" name="update" value="true" + {{- 'UPDATE' in default_statements ? ' checked="checked"' }}> + UPDATE<br> + <input type="checkbox" name="delete" value="true" + {{- 'DELETE' in default_statements ? ' checked="checked"' }}> + DELETE<br> + <input type="checkbox" name="truncate" value="true" + {{- 'TRUNCATE' in default_statements ? ' checked="checked"' }}> + TRUNCATE<br> + </fieldset> + + <fieldset class="tblFooters"> + <input type="hidden" name="submit_create_version" value="1"> + <input class="btn btn-primary" type="submit" value="{% trans 'Create version' %}"> + </fieldset> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig b/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig new file mode 100644 index 0000000..947d841 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/central_columns/edit_table_header.twig @@ -0,0 +1,9 @@ +<table id="table_columns" class="noclick"> + <caption class="tblHeaders">{% trans 'Structure' %}</caption> + <thead> + <tr> + {% for header in headers %} + <th>{{ header }}</th> + {% endfor %} + </tr> + </thead> diff --git a/srcs/phpmyadmin/templates/database/central_columns/main.twig b/srcs/phpmyadmin/templates/database/central_columns/main.twig new file mode 100644 index 0000000..30b7276 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/central_columns/main.twig @@ -0,0 +1,418 @@ +{# getHtmlForAddNewColumn #} +<div id="add_col_div" class="topmargin"> + <a href="#"> + <span>{{ (total_rows > 0) ? '+' : '-' }}</span>{% trans 'Add new column' %} + </a> + <form id="add_new" class="new_central_col{{ (total_rows != 0) ? ' hide' : ''}}" + method="post" action="db_central_columns.php"> + {{ get_hidden_inputs(db) }} + <input type="hidden" name="add_new_column" value="add_new_column"> + <div class="responsivetable"> + <table> + <thead> + <tr> + <th class=""></th> + <th class="hide"></th> + <th class="" title="" data-column="name"> + {% trans 'Name' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="type"> + {% trans 'Type' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="length"> + {% trans 'Length/Value' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="default"> + {% trans 'Default' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="collation"> + {% trans 'Collation' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="attribute"> + {% trans 'Attribute' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="isnull"> + {% trans 'Null' %} + <div class="sorticon"></div> + </th> + <th class="" title="" data-column="extra"> + {% trans 'A_I' %} + <div class="sorticon"></div> + </th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + <td name="col_name" class="nowrap"> + {% include 'columns_definitions/column_name.twig' with { + 'column_number': 0, + 'ci': 0, + 'ci_offset': 0, + 'column_meta': {}, + 'cfg_relation': { + 'centralcolumnswork': false + }, + 'max_rows': max_rows, + } only %} + </td> + <td name="col_type" class="nowrap"> + {% include 'columns_definitions/column_type.twig' with { + 'column_number': 0, + 'ci': 1, + 'ci_offset': 0, + 'type_upper': '', + 'column_meta': {} + } only %} + </td> + <td class="nowrap" name="col_length"> + {% include 'columns_definitions/column_length.twig' with { + 'column_number': 0, + 'ci': 2, + 'ci_offset': 0, + 'length_values_input_size': 8, + 'length_to_display': '' + } only %} + </td> + <td class="nowrap" name="col_default"> + {% include 'columns_definitions/column_default.twig' with { + 'column_number': 0, + 'ci': 3, + 'ci_offset': 0, + 'type_upper': '', + 'column_meta': {}, + 'char_editing': char_editing, + } only %} + </td> + <td name="collation" class="nowrap"> + <select lang="en" dir="ltr" name="field_collation[0]" id="field_0_4"> + <option value=""></option> + {% for charset in charsets %} + <optgroup label="{{ charset.name }}" title="{{ charset.description }}"> + {% for collation in charset.collations %} + <option value="{{ collation.name }}" title="{{ collation.description }}"> + {{- collation.name -}} + </option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + </td> + <td class="nowrap" name="col_attribute"> + {% include 'columns_definitions/column_attribute.twig' with { + 'column_number': 0, + 'ci': 5, + 'ci_offset': 0, + 'extracted_columnspec': {}, + 'column_meta': {}, + 'submit_attribute': false, + 'attribute_types': attribute_types, + } only %} + </td> + <td class="nowrap" name="col_isNull"> + {% include 'columns_definitions/column_null.twig' with { + 'column_number': 0, + 'ci': 6, + 'ci_offset': 0, + 'column_meta': {} + } only %} + </td> + <td class="nowrap" name="col_extra"> + {% include 'columns_definitions/column_extra.twig' with { + 'column_number': 0, + 'ci': 7, + 'ci_offset': 0, + 'column_meta': {} + } only %} + </td> + <td> + <input id="add_column_save" class="btn btn-primary" type="submit" value="Save"> + </td> + </tr> + </tbody> + </table> + </div> + </form> +</div> +{% if total_rows <= 0 %} + <fieldset> + {% trans 'The central list of columns for the current database is empty' %} + </fieldset> +{% else %} + <table style="display:inline-block;max-width:49%" class="navigation nospacing nopadding"> + <tr> + <td class="navigation_separator"></td> + {% if pos - max_rows >= 0 %} + <td> + <form action="db_central_columns.php" method="post"> + {{ get_hidden_inputs(db) }} + <input type="hidden" name="pos" value="{{ pos - max_rows }}"> + <input type="hidden" name="total_rows" value="{{ total_rows }}"> + <input class="btn btn-secondary ajax" type="submit" name="navig" value="<"> + </form> + </td> + {% endif %} + {% if tn_nbTotalPage > 1 %} + <td> + <form action="db_central_columns.php" method="post"> + {{ get_hidden_inputs(db) }} + <input type="hidden" name="total_rows" value="{{ total_rows }}"> + {{ tn_page_selector | raw }} + </form> + </td> + {% endif %} + {% if pos + max_rows < total_rows %} + <td> + <form action="db_central_columns.php" method="post"> + {{ get_hidden_inputs(db) }} + <input type="hidden" name="pos" value="{{ pos + max_rows }}"> + <input type="hidden" name="total_rows" value="{{ total_rows }}"> + <input class="btn btn-secondary ajax" type="submit" name="navig" value=">"> + </form> + </td> + {% endif %} + <td class="navigation_separator"></td> + <td> + <span>{% trans 'Filter rows' %}:</span> + <input type="text" class="filter_rows" placeholder="{% trans 'Search this table' %}"> + </td> + <td class="navigation_separator"></td> + </tr> + </table> +{% endif %} +{# getHtmlForAddColumn #} +<table class="central_columns_add_column" class="navigation nospacing nopadding"> + <tr> + <td class="navigation_separator largescreenonly"></td> + <td class="central_columns_navigation"> + {{ get_icon('centralColumns_add', 'Add column' | trans)|raw }} + <form id="add_column" action="db_central_columns.php" method="post"> + {{ get_hidden_inputs(db) | raw }} + <input type="hidden" name="add_column" value="add"> + <input type="hidden" name="pos" value="{{ pos }}"> + <input type="hidden" name="total_rows" value="{{ total_rows }}"> + {# getHtmlForTableDropdown #} + <select name="table-select" id="table-select"> + <option value="" disabled="disabled" selected="selected"> + {% trans 'Select a table' %} + </option> + {% for table in tables %} + <option value="{{ table|e }}">{{ table|e }}</option> + {% endfor %} + </select> + <select name="column-select" id="column-select"> + <option value="" selected="selected">{% trans 'Select a column.' %}</option> + </select> + <input class="btn btn-primary" type="submit" value="{% trans 'Add' %}"> + </form> + </td> + <td class="navigation_separator largescreenonly"></td> + </tr> +</table> +{% if total_rows > 0 %} + <form method="post" id="del_form" action="db_central_columns.php"> + {{ get_hidden_inputs(db) }} + <input id="del_col_name" type="hidden" name="col_name" value=""> + <input type="hidden" name="pos" value="{{ pos }}"> + <input type="hidden" name="delete_save" value="delete"> + </form> + <div id="tableslistcontainer"> + <form name="tableslistcontainer"> + <table id="table_columns" class="tablesorter" class="data"> + {% set class = 'column_heading' %} + {% set title = 'Click to sort.' | trans %} + <thead> + <tr> + <th class="{{ class }}"></th> + <th class="hide"></th> + <th class="column_action" colspan="2">{% trans 'Action' %}</th> + <th class="{{ class }}" title="{{ title }}" data-column="name"> + {% trans 'Name' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="type"> + {% trans 'Type' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="length"> + {% trans 'Length/Value' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="default"> + {% trans 'Default' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="collation"> + {% trans 'Collation' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="attribute"> + {% trans 'Attribute' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="isnull"> + {% trans 'Null' %} + <div class="sorticon"></div> + </th> + <th class="{{ class }}" title="{{ title }}" data-column="extra"> + {% trans 'A_I' %} + <div class="sorticon"></div> + </th> + </tr> + </thead> + <tbody> + {% set row_num = 0 %} + {% for row in rows_list %} + {# getHtmlForTableRow #} + <tr data-rownum="{{ row_num }}" id="{{ 'f_' ~ row_num }}"> + {{ get_hidden_inputs(db) }} + <input type="hidden" name="edit_save" value="save"> + <td class="nowrap"> + <input type="checkbox" class="checkall" name="selected_fld[]" + value="{{ row['col_name'] }}" id="{{ 'checkbox_row_' ~ row_num }}"> + </td> + <td id="{{ 'edit_' ~ row_num }}" class="edit center"> + <a href="#"> {{ get_icon('b_edit', 'Edit' | trans) | raw }}</a> + </td> + <td class="del_row" data-rownum = "{{ row_num }}"> + <a hrf="#">{{ get_icon('b_drop', 'Delete' | trans) }}</a> + <input type="submit" data-rownum = "{{ row_num }}" class="btn btn-secondary edit_cancel_form" value="Cancel"> + </td> + <td id="{{ 'save_' ~ row_num }}" class="hide"> + <input type="submit" data-rownum="{{ row_num }}" class="btn btn-primary edit_save_form" value="Save"> + </td> + <td name="col_name" class="nowrap"> + <span>{{ row['col_name'] }}</span> + <input name="orig_col_name" type="hidden" value="{{ row['col_name'] }}"> + {% include 'columns_definitions/column_name.twig' with { + 'column_number': row_num, + 'ci': 0, + 'ci_offset': 0, + 'column_meta': { + 'Field': row['col_name'] + }, + 'cfg_relation': { + 'centralcolumnswork': false + }, + 'max_rows': max_rows + } only %} + </td> + <td name = "col_type" class="nowrap"> + <span>{{ row['col_type'] }}</span> + {% include 'columns_definitions/column_type.twig' with { + 'column_number': row_num, + 'ci': 1, + 'ci_offset': 0, + 'type_upper': types_upper[row_num], + 'column_meta': {} + } only %} + </td> + <td class="nowrap" name="col_length"> + <span>{{ (row['col_length']?(row['col_length']):'') }}</span> + {% include 'columns_definitions/column_length.twig' with { + 'column_number': row_num, + 'ci': 2, + 'ci_offset': 0, + 'length_values_input_size': 8, + 'length_to_display': row['col_length'] + } only %} + </td> + <td class="nowrap" name="col_default"> + {% if row['col_default'] is defined %} + <span>{{ row['col_default'] }}</span> + {% else %} + <span>None</span> + {% endif %} + {% include 'columns_definitions/column_default.twig' with { + 'column_number': row_num, + 'ci': 3, + 'ci_offset': 0, + 'type_upper': types_upper[row_num], + 'column_meta': rows_meta[row_num], + 'char_editing': char_editing, + } only %} + </td> + <td name="collation" class="nowrap"> + <span>{{ row['col_collation'] }}</span> + <select lang="en" dir="ltr" name="field_collation[{{ row_num }}]" id="field_{{ row_num }}_4"> + <option value=""></option> + {% for charset in charsets %} + <optgroup label="{{ charset.name }}" title="{{ charset.description }}"> + {% for collation in charset.collations %} + <option value="{{ collation.name }}" title="{{ collation.description }}" + {{- collation.name == row['col_collation'] ? ' selected' }}> + {{- collation.name -}} + </option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + </td> + <td class="nowrap" name="col_attribute"> + <span>{{ row['col_attribute']?(row['col_attribute']):"" }}</span> + {% include 'columns_definitions/column_attribute.twig' with { + 'column_number': row_num, + 'ci': 5, + 'ci_offset': 0, + 'extracted_columnspec': {}, + 'column_meta': row['col_attribute'], + 'submit_attribute': false, + 'attribute_types': attribute_types, + } only %} + </td> + <td class="nowrap" name="col_isNull"> + <span>{{ row['col_isNull'] ? 'Yes' | trans : 'No' | trans }}</span> + {% include 'columns_definitions/column_null.twig' with { + 'column_number': row_num, + 'ci': 6, + 'ci_offset': 0, + 'column_meta': { + 'Null': row['col_isNull'] + } + } only %} + </td> + <td class="nowrap" name="col_extra"> + <span>{{ row['col_extra'] }}</span> + {% include 'columns_definitions/column_extra.twig' with { + 'column_number': row_num, + 'ci': 7, + 'ci_offset': 0, + 'column_meta': { + 'Extra': row['col_extra'] + } + } only %} + </td> + </tr> + {% set row_num = row_num + 1 %} + {% endfor %} + </tbody> + </table> + {# getTableFooter #} + {% include 'select_all.twig' with { + 'pma_theme_image': pmaThemeImage, + 'text_dir' : text_dir, + 'form_name' : 'tableslistcontainer', + } only %} + {{ get_button_or_image( + 'edit_central_columns', + 'mult_submit change_central_columns', + 'Edit' | trans, + 'b_edit', + 'edit central columns' + ) | raw }} + {{ get_button_or_image( + 'delete_central_columns', + 'mult_submit', + 'Delete' | trans, + 'b_drop', + 'remove_from_central_columns' + ) | raw }} + </form> + </div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/database/create_table.twig b/srcs/phpmyadmin/templates/database/create_table.twig new file mode 100644 index 0000000..e57d93a --- /dev/null +++ b/srcs/phpmyadmin/templates/database/create_table.twig @@ -0,0 +1,23 @@ +<form id="create_table_form_minimal" method="post" action="tbl_create.php" class="lock-page"> + <fieldset> + <legend> + {% if show_icons('ActionLinksMode') -%} + {{ get_image('b_table_add') }} + {%- endif %} + {% trans "Create table" %} + </legend> + {{ get_hidden_inputs(db) }} + <div class="formelement"> + {% trans "Name" %}: + <input type="text" name="table" maxlength="64" size="30" required="required"> + </div> + <div class="formelement"> + {% trans "Number of columns" %}: + <input type="number" min="1" name="num_fields" value="4" required="required"> + </div> + <div class="clearfloat"></div> + </fieldset> + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" value="{% trans "Go" %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/database/data_dictionary/index.twig b/srcs/phpmyadmin/templates/database/data_dictionary/index.twig new file mode 100644 index 0000000..2f5dc5a --- /dev/null +++ b/srcs/phpmyadmin/templates/database/data_dictionary/index.twig @@ -0,0 +1,65 @@ +<h1>{{ database }}</h1> +{% if comment is not empty %} + <p>{% trans 'Database comment:' %} <em>{{ comment }}</em></p> +{% endif %} + +<div> + {% for table in tables %} + <div> + <h2>{{ table.name }}</h2> + {% if table.comment is not empty %} + <p>{% trans 'Table comments:' %} <em>{{ table.comment }}</em></p> + {% endif %} + + <table class="print"> + <tr> + <th>{% trans 'Column' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Null' %}</th> + <th>{% trans 'Default' %}</th> + {% if table.has_relation %} + <th>{% trans 'Links to' %}</th> + {% endif %} + <th>{% trans 'Comments' %}</th> + {% if table.has_mime %} + <th>{% trans 'Media (MIME) type' %}</th> + {% endif %} + </tr> + {% for column in table.columns %} + <tr> + <td class="nowrap"> + {{ column.name }} + {% if column.has_primary_key %} + <em>({% trans 'Primary' %})</em> + {% endif %} + </td> + <td lang="en" dir="ltr"{{ 'set' != column.type and 'enum' != column.type ? ' class="nowrap"' }}> + {{ column.print_type }} + </td> + <td>{{ column.is_nullable ? 'Yes'|trans : 'No'|trans }}</td> + <td class="nowrap"> + {% if column.default is null and column.is_nullable %} + <em>NULL</em> + {% else %} + {{ column.default }} + {% endif %} + </td> + {% if table.has_relation %} + <td>{{ column.relation }}</td> + {% endif %} + <td>{{ column.comment }}</td> + {% if table.has_mime %} + <td>{{ column.mime }}</td> + {% endif %} + </tr> + {% endfor %} + </table> + + {{ table.indexes_table|raw }} + </div> + {% endfor %} +</div> + +<p class="print_ignore"> + <input type="button" class="btn btn-secondary button" id="print" value="{% trans 'Print' %}"> +</p> diff --git a/srcs/phpmyadmin/templates/database/designer/database_tables.twig b/srcs/phpmyadmin/templates/database/designer/database_tables.twig new file mode 100644 index 0000000..5453bb5 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/database_tables.twig @@ -0,0 +1,121 @@ +{% for designerTable in tables %} + {% set i = loop.index0 %} + {% set t_n_url = designerTable.getDbTableString()|escape('url') %} + {% set db = designerTable.getDatabaseName() %} + {% set db_url = db|escape('url') %} + {% set t_n = designerTable.getDbTableString() %} + {% set table_name = designerTable.getTableName()|escape('html') %} + <input name="t_x[{{ t_n_url }}]" type="hidden" id="t_x_{{ t_n_url }}_" /> + <input name="t_y[{{ t_n_url }}]" type="hidden" id="t_y_{{ t_n_url }}_" /> + <input name="t_v[{{ t_n_url }}]" type="hidden" id="t_v_{{ t_n_url }}_" /> + <input name="t_h[{{ t_n_url }}]" type="hidden" id="t_h_{{ t_n_url }}_" /> + <table id="{{ t_n_url }}" + db_url="{{ designerTable.getDatabaseName()|escape('url') }}" + table_name_url="{{ designerTable.getTableName()|escape('url') }}" + cellpadding="0" + cellspacing="0" + class="designer_tab" + style="position:absolute; left: + {{- tab_pos[t_n] is defined ? tab_pos[t_n]['X'] : random(range(20, 700)) }}px; top: + {{- tab_pos[t_n] is defined ? tab_pos[t_n]['Y'] : random(range(20, 550)) }}px; display: + {{- tab_pos[t_n] is defined or display_page == -1 ? 'block' : 'none' }}; z-index: 1;"> <!--"--> + <thead> + <tr class="header"> + {% if has_query %} + <td class="select_all"> + <input class="select_all_1" + type="checkbox" + style="margin: 0;" + value="select_all_{{ t_n_url }}" + id="select_all_{{ i }}" + title="{% trans 'Select all' %}" + table_name="{{ table_name }}" + db_name="{{ db }}"> + </td> + {% endif %} + <td class="small_tab" + title="{% trans 'Show/hide columns' %}" + id="id_hide_tbody_{{ t_n_url }}" + table_name="{{ t_n_url }}">{{ tab_pos[t_n] is not defined or tab_pos[t_n]['V'] is not empty ? 'v' : '>' }}</td> + <td class="small_tab_pref small_tab_pref_1" + db="{{ designerTable.getDatabaseName() }}" + db_url="{{ designerTable.getDatabaseName()|escape('url') }}" + table_name="{{ designerTable.getTableName() }}" + table_name_url="{{ designerTable.getTableName()|escape('url') }}"> + <img src="{{ theme.getImgPath('designer/exec_small.png') }}" + title="{% trans 'See table structure' %}"> + </td> + <td id="id_zag_{{ t_n_url }}" + class="tab_zag nowrap tab_zag_noquery" + table_name="{{ t_n_url }}" + query_set="{{ has_query ? 1 : 0 }}"> + <span class="owner">{{ designerTable.getDatabaseName() }}</span> + {{ designerTable.getTableName() }} + </td> + {% if has_query %} + <td class="tab_zag tab_zag_query" + id="id_zag_{{ t_n_url }}_2" + table_name="{{ t_n_url }}"> + </td> + {% endif %} + </tr> + </thead> + <tbody id="id_tbody_{{ t_n_url }}" + {{- tab_pos[t_n] is defined and tab_pos[t_n]['V'] is empty ? ' style="display: none"' }}> + {% set display_field = designerTable.getDisplayField() %} + {% for j in 0..tab_column[t_n]['COLUMN_ID']|length - 1 %} + {% set col_name = tab_column[t_n]['COLUMN_NAME'][j] %} + {% set tmp_column = t_n ~ '.' ~ tab_column[t_n]['COLUMN_NAME'][j] %} + {% set click_field_param = [ + designerTable.getTableName()|escape('url'), + tab_column[t_n]['COLUMN_NAME'][j]|url_encode + ] %} + {% if not designerTable.supportsForeignkeys() %} + {% set click_field_param = click_field_param|merge([tables_pk_or_unique_keys[tmp_column] is defined ? 1 : 0]) %} + {% else %} + {# if foreign keys are supported, it's not necessary that the + index is a primary key #} + {% set click_field_param = click_field_param|merge([tables_all_keys[tmp_column] is defined ? 1 : 0]) %} + {% endif %} + {% set click_field_param = click_field_param|merge([db]) %} + <tr id="id_tr_{{ designerTable.getTableName()|escape('url') }}.{{ tab_column[t_n]['COLUMN_NAME'][j] }}" class="tab_field + {{- display_field == tab_column[t_n]['COLUMN_NAME'][j] ? '_3' }}" click_field_param=" + {{- click_field_param|join(',') }}"> + {% if has_query %} + <td class="select_all"> + <input class="select_all_store_col" + value="{{ t_n_url }}{{ tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}" + type="checkbox" + id="select_{{ t_n_url }}._{{ tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}" + style="margin: 0;" + title="{{ 'Select "%s"'|trans|format(col_name) }}" + id_check_all="select_all_{{ i }}" + db_name="{{ db }}" + table_name="{{ table_name }}" + col_name="{{ col_name }}"> + </td> + {% endif %} + <td width="10px" colspan="3" id="{{ t_n_url }}. + {{- tab_column[t_n]['COLUMN_NAME'][j]|url_encode }}"> + <div class="nowrap"> + {% set type = columns_type[t_n ~ '.' ~ tab_column[t_n]['COLUMN_NAME'][j]] %} + <img src="{{ theme.getImgPath(type) }}.png" alt="*"> + {{ tab_column[t_n]['COLUMN_NAME'][j] }} : {{ tab_column[t_n]['TYPE'][j] }} + </div> + </td> + {% if has_query %} + <td class="small_tab_pref small_tab_pref_click_opt" + {# Escaped 2 times to be able to use it in innerHtml #} + option_col_name_modal="<strong>{{ 'Add an option for column "%s".'|trans|format(col_name)|escape('html')|escape('html') }}</strong>" + db_name="{{ db }}" + table_name="{{ table_name }}" + col_name="{{ col_name }}" + db_table_name_url="{{ t_n_url }}"> + <img src="{{ theme.getImgPath('designer/exec_small.png') }}" title="{% trans 'Options' %}" /> + </td> + {% endif %} + </tr> + {% endfor %} + </tbody> + </table> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig b/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig new file mode 100644 index 0000000..75d1a1a --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/edit_delete_pages.twig @@ -0,0 +1,13 @@ +<form action="db_designer.php" method="post" name="edit_delete_pages" id="edit_delete_pages" class="ajax"> + {{ get_hidden_inputs(db) }} + <fieldset id="page_edit_delete_options"> + <input type="hidden" name="operation" value="{{ operation }}"> + <label for="selected_page"> + {{ operation == 'editPage' ? 'Page to open'|trans : 'Page to delete'|trans }}: + </label> + {% include 'database/designer/page_selector.twig' with { + 'pdfwork': pdfwork, + 'pages': pages + } only %} + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/database/designer/main.twig b/srcs/phpmyadmin/templates/database/designer/main.twig new file mode 100644 index 0000000..f971dc5 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/main.twig @@ -0,0 +1,1105 @@ +{# Invisible characters will make javascript crash #} +{% apply spaceless %} +<script type="text/javascript"> +var designerConfig = {{ designer_config|raw }}; +</script> +{% endapply %} + +{# side menu #} +{% if not has_query %} + <div id="name-panel"> + <span id="page_name"> + {{ selected_page == null ? 'Untitled'|trans : selected_page }} + </span> + <span id="saved_state"> + {{ selected_page == null ? '*' : '' }} + </span> + </div> +{% endif %} +<div class="designer_header side-menu" id="side_menu"> + <a class="M_butt" id="key_Show_left_menu" href="#"> + <img title="{% trans 'Show/Hide tables list' %}" + alt="v" + src="{{ theme.getImgPath('designer/downarrow2_m.png') }}" + data-down="{{ theme.getImgPath('designer/downarrow2_m.png') }}" + data-up="{{ theme.getImgPath('designer/uparrow2_m.png') }}"> + <span class="hide hidable"> + {% trans 'Show/Hide tables list' %} + </span> + </a> + <a href="#" id="toggleFullscreen" class="M_butt"> + <img title="{% trans 'View in fullscreen' %}" + src="{{ theme.getImgPath('designer/viewInFullscreen.png') }}" + data-enter="{{ theme.getImgPath('designer/viewInFullscreen.png') }}" + data-exit="{{ theme.getImgPath('designer/exitFullscreen.png') }}"> + <span class="hide hidable" + data-exit="{% trans 'Exit fullscreen' %}" + data-enter="{% trans 'View in fullscreen' %}"> + {% trans 'View in fullscreen' %} + </span> + </a> + <a href="#" id="addOtherDbTables" class="M_butt"> + <img title="{% trans 'Add tables from other databases' %}" + src="{{ theme.getImgPath('designer/other_table.png') }}"> + <span class="hide hidable"> + {% trans 'Add tables from other databases' %} + </span> + </a> + {% if not has_query %} + <a id="newPage" href="#" class="M_butt"> + <img title="{% trans 'New page' %}" + alt="" + src="{{ theme.getImgPath('designer/page_add.png') }}"> + <span class="hide hidable"> + {% trans 'New page' %} + </span> + </a> + <a href="#" id="editPage" class="M_butt ajax"> + <img title="{% trans 'Open page' %}" + src="{{ theme.getImgPath('designer/page_edit.png') }}"> + <span class="hide hidable"> + {% trans 'Open page' %} + </span> + </a> + <a href="#" id="savePos" class="M_butt"> + <img title="{% trans 'Save page' %}" + src="{{ theme.getImgPath('designer/save.png') }}"> + <span class="hide hidable"> + {% trans 'Save page' %} + </span> + </a> + <a href="#" id="SaveAs" class="M_butt ajax"> + <img title="{% trans 'Save page as' %}" + src="{{ theme.getImgPath('designer/save_as.png') }}"> + <span class="hide hidable"> + {% trans 'Save page as' %} + </span> + </a> + <a href="#" id="delPages" class="M_butt ajax"> + <img title="{% trans 'Delete pages' %}" + src="{{ theme.getImgPath('designer/page_delete.png') }}"> + <span class="hide hidable"> + {% trans 'Delete pages' %} + </span> + </a> + <a href="#" id="StartTableNew" class="M_butt"> + <img title="{% trans 'Create table' %}" + src="{{ theme.getImgPath('designer/table.png') }}"> + <span class="hide hidable"> + {% trans 'Create table' %} + </span> + </a> + <a href="#" class="M_butt" id="rel_button"> + <img title="{% trans 'Create relationship' %}" + src="{{ theme.getImgPath('designer/relation.png') }}"> + <span class="hide hidable"> + {% trans 'Create relationship' %} + </span> + </a> + <a href="#" class="M_butt" id="display_field_button"> + <img title="{% trans 'Choose column to display' %}" + src="{{ theme.getImgPath('designer/display_field.png') }}"> + <span class="hide hidable"> + {% trans 'Choose column to display' %} + </span> + </a> + <a href="#" id="reloadPage" class="M_butt"> + <img title="{% trans 'Reload' %}" + src="{{ theme.getImgPath('designer/reload.png') }}"> + <span class="hide hidable"> + {% trans 'Reload' %} + </span> + </a> + <a href="{{ get_docu_link('faq', 'faq6-31') }}" + target="documentation" + class="M_butt"> + <img title="{% trans 'Help' %}" + src="{{ theme.getImgPath('designer/help.png') }}"> + <span class="hide hidable"> + {% trans 'Help' %} + </span> + </a> + {% endif %} + <a href="#" class="{{ params_array['angular_direct'] }}" id="angular_direct_button"> + <img title="{% trans 'Angular links' %} / {% trans 'Direct links' %}" + src="{{ theme.getImgPath('designer/ang_direct.png') }}"> + <span class="hide hidable"> + {% trans 'Angular links' %} / {% trans 'Direct links' %} + </span> + </a> + <a href="#" class="{{ params_array['snap_to_grid'] }}" id="grid_button"> + <img title="{% trans 'Snap to grid' %}" src="{{ theme.getImgPath('designer/grid.png') }}"> + <span class="hide hidable"> + {% trans 'Snap to grid' %} + </span> + </a> + <a href="#" class="{{ params_array['small_big_all'] }}" id="key_SB_all"> + <img title="{% trans 'Small/Big All' %}" + alt="v" + src="{{ theme.getImgPath('designer/downarrow1.png') }}" + data-down="{{ theme.getImgPath('designer/downarrow1.png') }}" + data-right="{{ theme.getImgPath('designer/rightarrow1.png') }}"> + <span class="hide hidable"> + {% trans 'Small/Big All' %} + </span> + </a> + <a href="#" id="SmallTabInvert" class="M_butt"> + <img title="{% trans 'Toggle small/big' %}" + src="{{ theme.getImgPath('designer/bottom.png') }}"> + <span class="hide hidable"> + {% trans 'Toggle small/big' %} + </span> + </a> + <a href="#" id="relLineInvert" class="{{ params_array['relation_lines'] }}" > + <img title="{% trans 'Toggle relationship lines' %}" + src="{{ theme.getImgPath('designer/toggle_lines.png') }}"> + <span class="hide hidable"> + {% trans 'Toggle relationship lines' %} + </span> + </a> + {% if not visual_builder %} + <a href="#" id="exportPages" class="M_butt" > + <img title="{% trans 'Export schema' %}" + src="{{ theme.getImgPath('designer/export.png') }}"> + <span class="hide hidable"> + {% trans 'Export schema' %} + </span> + </a> + {% else %} + <a id="build_query_button" + class="M_butt" + href="#" + class="M_butt"> + <img title="{% trans 'Build Query' %}" + src="{{ theme.getImgPath('designer/query_builder.png') }}"> + <span class="hide hidable"> + {% trans 'Build Query' %} + </span> + </a> + {% endif %} + <a href="#" class="{{ params_array['side_menu'] }}" id="key_Left_Right"> + <img title="{% trans 'Move Menu' %}" alt=">" + data-right="{{ theme.getImgPath('designer/2leftarrow_m.png') }}" + src="{{ theme.getImgPath('designer/2rightarrow_m.png') }}"> + <span class="hide hidable"> + {% trans 'Move Menu' %} + </span> + </a> + <a href="#" class="{{ params_array['pin_text'] }}" id="pin_Text"> + <img title="{% trans 'Pin text' %}" + alt=">" + data-right="{{ theme.getImgPath('designer/anchor.png') }}" + src="{{ theme.getImgPath('designer/anchor.png') }}"> + <span class="hide hidable"> + {% trans 'Pin text' %} + </span> + </a> +</div> +<div id="canvas_outer"> + <form action="" id="container-form" method="post" name="form1"> + <div id="osn_tab"> + <canvas class="designer" id="canvas" width="100" height="100"></canvas> + </div> + <div id="layer_menu" class="hide"> + <div class="center"> + <a href="#" class="M_butt" target="_self" > + <img title="{% trans 'Hide/Show all' %}" + alt="v" + id="key_HS_all" + src="{{ theme.getImgPath('designer/downarrow1.png') }}" + data-down="{{ theme.getImgPath('designer/downarrow1.png') }}" + data-right="{{ theme.getImgPath('designer/rightarrow1.png') }}"> + </a> + <a href="#" class="M_butt" target="_self" > + <img alt="v" + id="key_HS" + title="{% trans 'Hide/Show tables with no relationship' %}" + src="{{ theme.getImgPath('designer/downarrow2.png') }}" + data-down="{{ theme.getImgPath('designer/downarrow2.png') }}" + data-right="{{ theme.getImgPath('designer/rightarrow2.png') }}"> + </a> + </div> + <div id="id_scroll_tab" class="scroll_tab"> + <table width="100%" style="padding-left: 3px;"></table> + </div> + {# end id_scroll_tab #} + <div class="center"> + {% trans 'Number of tables:' %} <span id="tables_counter">0</span> + </div> + <div id="layer_menu_sizer"> + <div class="floatleft"> + <img class="icon" + data-right="{{ theme.getImgPath('designer/resizeright.png') }}" + src="{{ theme.getImgPath('designer/resize.png') }}"> + </div> + </div> + </div> + {# end layer_menu #} + {% include 'database/designer/database_tables.twig' with { + 'db': db, + 'get_db': get_db, + 'has_query': has_query, + 'tab_pos': tab_pos, + 'display_page': display_page, + 'tab_column': tab_column, + 'tables_all_keys': tables_all_keys, + 'tables_pk_or_unique_keys': tables_pk_or_unique_keys, + 'columns_type': columns_type, + 'tables': designerTables, + 'theme': theme, + } only %} + </form> +</div> +<div id="designer_hint"></div> +{# create relation pane #} +<table id="layer_new_relation" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + {% trans 'Create relationship' %} + </strong> + </td> + </tr> + </thead> + <tbody id="foreign_relation"> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + FOREIGN KEY + </strong> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + on delete + </td> + <td width="102"> + <select name="on_delete" id="on_delete"> + <option value="nix" selected="selected"> + -- + </option> + <option value="CASCADE"> + CASCADE + </option> + <option value="SET NULL"> + SET NULL + </option> + <option value="NO ACTION"> + NO ACTION + </option> + <option value="RESTRICT"> + RESTRICT + </option> + </select> + </td> + </tr> + <tr> + <td class="nowrap"> + on update + </td> + <td> + <select name="on_update" id="on_update"> + <option value="nix" selected="selected"> + -- + </option> + <option value="CASCADE"> + CASCADE + </option> + <option value="SET NULL"> + SET NULL + </option> + <option value="NO ACTION"> + NO ACTION + </option> + <option value="RESTRICT"> + RESTRICT + </option> + </select> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="button" id="ok_new_rel_panel" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input type="button" id="cancel_new_rel_panel" + class="btn btn-secondary butt" name="Button" value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> +</table> +{# delete relation pane #} +<table id="layer_upd_relation" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%"> + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="100%" class="center" cellpadding="2" cellspacing="0"> + <tr> + <td colspan="3" class="center nowrap"> + <strong> + {% trans 'Delete relationship' %} + </strong> + </td> + </tr> + <tr> + <td colspan="3" class="center nowrap"> + <input id="del_button" name="Button" type="button" + class="btn btn-secondary butt" value="{% trans 'Delete' %}"> + <input id="cancel_button" type="button" class="btn btn-secondary butt" + name="Button" value="{% trans 'Cancel' %}"> + </td> + </tr> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> +</table> +{% if has_query %} + {# options pane #} + <table id="designer_optionse" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" rowspan="2" id="option_col_name" class="center nowrap"> + </td> + </tr> + </thead> + <tbody id="where"> + <tr> + <td class="center nowrap"> + <b> + WHERE + </b> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Relationship operator' %} + </td> + <td width="102"> + <select name="rel_opt" id="rel_opt"> + <option value="--" selected="selected"> + -- + </option> + <option value="="> + = + </option> + <option value=">"> + > + </option> + <option value="<"> + < + </option> + <option value=">="> + >= + </option> + <option value="<="> + <= + </option> + <option value="NOT"> + NOT + </option> + <option value="IN"> + IN + </option> + <option value="EXCEPT"> + {% trans 'Except' %} + </option> + <option value="NOT IN"> + NOT IN + </option> + </select> + </td> + </tr> + <tr> + <td class="nowrap"> + {% trans 'Value' %} + <br> + {% trans 'subquery' %} + </td> + <td> + <textarea id="Query" cols="18"></textarea> + </td> + </tr> + <tr> + <td class="center nowrap"> + <b> + {% trans 'Rename to' %} + </b> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'New name' %} + </td> + <td width="102"> + <input type="text" id="new_name"> + </td> + </tr> + <tr> + <td class="center nowrap"> + <b> + {% trans 'Aggregate' %} + </b> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="operator" id="operator"> + <option value="---" selected="selected"> + --- + </option> + <option value="sum" > + SUM + </option> + <option value="min"> + MIN + </option> + <option value="max"> + MAX + </option> + <option value="avg"> + AVG + </option> + <option value="count"> + COUNT + </option> + </select> + </td> + </tr> + <tr> + <td width="58" class="center nowrap"> + <b> + GROUP BY + </b> + </td> + <td> + <input type="checkbox" value="groupby" id="groupby"> + </td> + </tr> + <tr> + <td width="58" class="center nowrap"> + <b> + ORDER BY + </b> + </td> + <td> + <select name="orderby" id="orderby"> + <option value="---" selected="selected"> + --- + </option> + <option value="ASC" > + ASC + </option> + <option value="DESC"> + DESC + </option> + </select> + </td> + </tr> + <tr> + <td class="center nowrap"> + <b> + HAVING + </b> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="h_operator" id="h_operator"> + <option value="---" selected="selected"> + --- + </option> + <option value="None" > + {% trans 'None' %} + </option> + <option value="sum" > + SUM + </option> + <option value="min"> + MIN + </option> + <option value="max"> + MAX + </option> + <option value="avg"> + AVG + </option> + <option value="count"> + COUNT + </option> + </select> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Relationship operator' %} + </td> + <td width="102"> + <select name="h_rel_opt" id="h_rel_opt"> + <option value="--" selected="selected"> + -- + </option> + <option value="="> + = + </option> + <option value=">"> + > + </option> + <option value="<"> + < + </option> + <option value=">="> + >= + </option> + <option value="<="> + <= + </option> + <option value="NOT"> + NOT + </option> + <option value="IN"> + IN + </option> + <option value="EXCEPT"> + {% trans 'Except' %} + </option> + <option value="NOT IN"> + NOT IN + </option> + </select> + </td> + </tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Value' %} + <br> + {% trans 'subquery' %} + </td> + <td width="102"> + <textarea id="having" cols="18"></textarea> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="hidden" id="ok_add_object_db_and_table_name_url" /> + <input type="hidden" id="ok_add_object_db_name" /> + <input type="hidden" id="ok_add_object_table_name" /> + <input type="hidden" id="ok_add_object_col_name" /> + <input type="button" id="ok_add_object" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input type="button" id="cancel_close_option" class="btn btn-secondary butt" + name="Button" value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> + </table> + {# rename to pane #} + <table id="query_rename_to" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + {% trans 'Rename to' %} + </strong> + </td> + </tr> + </thead> + <tbody id="rename_to"> + <tr> + <td width="58" class="nowrap"> + {% trans 'New name' %} + </td> + <td width="102"> + <input type="text" id="e_rename"> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="button" id="ok_edit_rename" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input id="query_rename_to_button" type="button" + class="btn btn-secondary butt" + name="Button" + value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> + </table> + {# having query panel #} + <table id="query_having" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + HAVING + </strong> + </td> + </tr> + </thead> + <tbody id="rename_to"> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="hoperator" id="hoperator"> + <option value="---" selected="selected"> + --- + </option> + <option value="None" > + None + </option> + <option value="sum" > + SUM + </option> + <option value="min"> + MIN + </option> + <option value="max"> + MAX + </option> + <option value="avg"> + AVG + </option> + <option value="count"> + COUNT + </option> + </select> + </td> + </tr> + <tr> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="hrel_opt" id="hrel_opt"> + <option value="--" selected="selected"> + -- + </option> + <option value="="> + = + </option> + <option value=">"> + > + </option> + <option value="<"> + < + </option> + <option value=">="> + >= + </option> + <option value="<="> + <= + </option> + <option value="NOT"> + NOT + </option> + <option value="IN"> + IN + </option> + <option value="EXCEPT"> + {% trans 'Except' %} + </option> + <option value="NOT IN"> + NOT IN + </option> + </select> + </td> + </tr> + <tr> + <td class="nowrap"> + {% trans 'Value' %} + <br> + {% trans 'subquery' %} + </td> + <td> + <textarea id="hQuery" cols="18"> + </textarea> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="button" id="ok_edit_having" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input id="query_having_button" type="button" + class="btn btn-secondary butt" + name="Button" + value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> + </table> + {# aggregate query pane #} + <table id="query_Aggregate" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + {% trans 'Aggregate' %} + </strong> + </td> + </tr> + </thead> + <tbody> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="operator" id="e_operator"> + <option value="---" selected="selected"> + --- + </option> + <option value="sum" > + SUM + </option> + <option value="min"> + MIN + </option> + <option value="max"> + MAX + </option> + <option value="avg"> + AVG + </option> + <option value="count"> + COUNT + </option> + </select> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="button" id="ok_edit_Aggr" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input id="query_Aggregate_Button" type="button" + class="btn btn-secondary butt" + name="Button" + value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> + </table> + {# where query pane #} + <table id="query_where" class="hide" width="5%" cellpadding="0" cellspacing="0"> + <tbody> + <tr> + <td class="frams1" width="10px"> + </td> + <td class="frams5" width="99%" > + </td> + <td class="frams2" width="10px"> + <div class="bor"> + </div> + </td> + </tr> + <tr> + <td class="frams8"> + </td> + <td class="input_tab"> + <table width="168" class="center" cellpadding="2" cellspacing="0"> + <thead> + <tr> + <td colspan="2" class="center nowrap"> + <strong> + WHERE + </strong> + </td> + </tr> + </thead> + <tbody id="rename_to"> + <tr> + <td width="58" class="nowrap"> + {% trans 'Operator' %} + </td> + <td width="102"> + <select name="erel_opt" id="erel_opt"> + <option value="--" selected="selected"> + -- + </option> + <option value="=" > + = + </option> + <option value=">"> + > + </option> + <option value="<"> + < + </option> + <option value=">="> + >= + </option> + <option value="<="> + <= + </option> + <option value="NOT"> + NOT + </option> + <option value="IN"> + IN + </option> + <option value="EXCEPT"> + {% trans 'Except' %} + </option> + <option value="NOT IN"> + NOT IN + </option> + </select> + </td> + </tr> + <tr> + <td class="nowrap"> + {% trans 'Value' %} + <br> + {% trans 'subquery' %} + </td> + <td> + <textarea id="eQuery" cols="18"> + </textarea> + </td> + </tr> + </tbody> + <tbody> + <tr> + <td colspan="2" class="center nowrap"> + <input type="button" id="ok_edit_where" class="btn btn-secondary butt" + name="Button" value="{% trans 'OK' %}"> + <input id="query_where_button" type="button" class="btn btn-secondary butt" name="Button" + value="{% trans 'Cancel' %}"> + </td> + </tr> + </tbody> + </table> + </td> + <td class="frams6"> + </td> + </tr> + <tr> + <td class="frams4"> + <div class="bor"> + </div> + </td> + <td class="frams7"> + </td> + <td class="frams3"> + </td> + </tr> + </tbody> + </table> + {# query details #} + <div class="panel"> + <div class="clearfloat"></div> + <div id="ab"></div> + <div class="clearfloat"></div> + </div> + <a class="trigger" href="#">{% trans 'Active options' %}</a> + <div id="box"> + <form method="post" action="db_qbe.php" id="vqb_form"> + <textarea cols="80" name="sql_query" id="textSqlquery" rows="15"></textarea> + <input type="hidden" name="submit_sql" value="true"> + {{ get_hidden_inputs(get_db) }} + </form> + </div> +{% endif %} +<div id="PMA_disable_floating_menubar"></div> diff --git a/srcs/phpmyadmin/templates/database/designer/page_save_as.twig b/srcs/phpmyadmin/templates/database/designer/page_save_as.twig new file mode 100644 index 0000000..bbcf34b --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/page_save_as.twig @@ -0,0 +1,37 @@ +<form action="db_designer.php" method="post" name="save_as_pages" id="save_as_pages" class="ajax"> + {{ get_hidden_inputs(db) }} + <fieldset id="page_save_as_options"> + <table> + <tbody> + <tr> + <td> + <input type="hidden" name="operation" value="savePage"> + {% include 'database/designer/page_selector.twig' with { + 'pdfwork': pdfwork, + 'pages': pages + } only %} + </td> + </tr> + <tr> + <td> + {{ get_radio_fields( + 'save_page', + { + 'same': 'Save to selected page'|trans, + 'new': 'Create a page and save to it'|trans + }, + 'same', + true + ) }} + </td> + </tr> + <tr> + <td> + <label for="selected_value">{% trans 'New page name' %}</label> + <input type="text" name="selected_value" id="selected_value"> + </td> + </tr> + </tbody> + </table> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/database/designer/page_selector.twig b/srcs/phpmyadmin/templates/database/designer/page_selector.twig new file mode 100644 index 0000000..01c0650 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/page_selector.twig @@ -0,0 +1,10 @@ +<select name="selected_page" id="selected_page"> + <option value="0">-- {% trans 'Select page' %} --</option> + {% if pdfwork %} + {% for nr, desc in pages %} + <option value="{{ nr }}"> + {{ desc }} + </option> + {% endfor %} + {% endif %} +</select> diff --git a/srcs/phpmyadmin/templates/database/designer/schema_export.twig b/srcs/phpmyadmin/templates/database/designer/schema_export.twig new file mode 100644 index 0000000..71f15f2 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/designer/schema_export.twig @@ -0,0 +1,9 @@ +<form method="post" action="schema_export.php" class="disableAjax" id="id_export_pages"> + <fieldset> + {{ get_hidden_inputs(db) }} + <label>{% trans 'Select Export Relational Type' %}</label> + {{ get_choice('Schema', 'export_type', export_list, 'format') }} + <input type="hidden" name="page_number" value="{{ page }}"> + {{ get_options('Schema', export_list) }} + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/database/multi_table_query/form.twig b/srcs/phpmyadmin/templates/database/multi_table_query/form.twig new file mode 100644 index 0000000..068ceda --- /dev/null +++ b/srcs/phpmyadmin/templates/database/multi_table_query/form.twig @@ -0,0 +1,184 @@ +{% include 'secondary_tabs.twig' with { + 'url_params': { + 'db': db + }, + 'sub_tabs': [ + { + 'link': 'db_multi_table_query.php', + 'text': 'Multi-table query'|trans + }, + { + 'link': 'db_qbe.php', + 'text': 'Query by example'|trans + } + ] +} only %} +{% include 'div_for_slider_effect.twig' with { + 'id': 'query_div', + 'message': 'Query window'|trans, + 'initial_sliders_state': 'open', +} only %} +<form action="" id="query_form"> + <input type="hidden" id="db_name" value="{{ db }}"> + <fieldset> + {% for table in tables %} + <div style="display:none" id="{{ table.hash }}"> + <option value="*">*</option> + {% for column in table.columns %} + <option value="{{ column }}">{{ column }}</option> + {% endfor %} + </div> + {% endfor %} + + {% for id in 0..default_no_of_columns %} + {% if id == 0 %}<div style="display:none" id="new_column_layout">{% endif %} + <fieldset style="display:inline" class="column_details"> + <select style="display:inline" class="tableNameSelect"> + <option value="">{% trans 'select table' %}</option> + {% for table in tables|keys %} + <option value="{{ table }}">{{ table }}</option> + {% endfor %} + </select> + <span>.</span> + <select style="display:inline" class="columnNameSelect"> + <option value="">{% trans 'select column' %}</option> + </select> + <br> + <input type="checkbox" checked="checked" class="show_col"> + <span>{% trans 'Show' %}</span> + <br> + <input type="text" placeholder="{% trans 'Table alias' %}" class="table_alias"> + <input type="text" placeholder="{% trans 'Column alias' %}" class="col_alias"> + <br> + <input type="checkbox" + title="{% trans 'Use this column in criteria' %}" + class="criteria_col"> + {% include 'div_for_slider_effect.twig' with { + 'id': 'criteria_div' ~ id, + 'initial_sliders_state': 'closed', + 'message': 'criteria'|trans + } %} + <div> + <table> + + <tr class="sort_order" style="background:none"> + <td>{% trans 'Sort' %}</td> + <td><input type="radio" name="sort[{{ id }}]">{% trans 'Ascending' %}</td> + <td><input type="radio" name="sort[{{ id }}]">{% trans 'Descending' %}</td> + </tr> + + <tr class="logical_operator" style="background:none;display:none"> + <td>{% trans 'Add as' %}</td> + <td> + <input type="radio" + name="logical_op[{{ id }}]" + value="AND" + class="logical_op" + checked="checked"> + AND + </td> + <td> + <input type="radio" + name="logical_op[{{ id }}]" + value="OR" + class="logical_op"> + OR + </td> + </tr> + + <tr style="background:none"> + <td>Op </td> + <td> + <select class="criteria_op"> + <option value="=">=</option> + <option value=">">></option> + <option value=">=">>=</option> + <option value="<"><</option> + <option value="<="><=</option> + <option value="!=">!=</option> + <option value="LIKE">LIKE</option> + <option value="LIKE %...%">LIKE %...%</option> + <option value="NOT LIKE">NOT LIKE</option> + <option value="IN (...)">IN (...)</option> + <option value="NOT IN (...)">NOT IN (...)</option> + <option value="BETWEEN">BETWEEN</option> + <option value="NOT BETWEEN">NOT BETWEEN</option> + <option value="IS NULL">IS NULL</option> + <option value="IS NOT NULL">IS NOT NULL</option> + <option value="REGEXP">REGEXP</option> + <option value="REGEXP ^...$">REGEXP ^...$</option> + <option value="NOT REGEXP">NOT REGEXP</option> + </select> + </td> + <td> + <select class="criteria_rhs"> + <option value="text">{% trans 'Text' %}</option> + <option value="anotherColumn">{% trans 'Another column' %}</option> + </select> + </td> + </tr> + + <tr class="rhs_table" style="display:none;background:none"> + <td></td> + <td> + <select class="tableNameSelect"> + <option value="">{% trans 'select table' %}</option> + {% for table in tables|keys %} + <option value="{{ table }}">{{ table }}</option> + {% endfor %} + </select><span>.</span> + </td> + <td> + <select style="display:inline" class="columnNameSelect"> + <option value="">{% trans 'select column' %}</option> + </select> + </td> + </tr> + + <tr style="background:none" class="rhs_text"> + <td></td> + <td colspan="2"> + <input type="text" + style="width:91%" + class="rhs_text_val" + placeholder="{% trans 'Enter criteria as free text' %}"> + </td> + </tr> + + </table> + </div> + </div> + <a href="#" + title="{% trans 'Remove this column' %}" + style="float:right;color:red" + class="removeColumn"> + X + </a> + </fieldset> + {% if id == 0 %}</div>{% endif %} + {% endfor %} + + <fieldset style="display:inline"> + <input class="btn btn-secondary" type="button" value="{% trans '+ Add column' %}" id="add_column_button"> + </fieldset> + + <fieldset> + {% apply spaceless %} + <textarea id="MultiSqlquery" + cols="80" + rows="4" + style="float:left" + name="sql_query" + dir="ltr"> + </textarea> + {% endapply %} + </fieldset> + </fieldset> + + <fieldset class="tblFooters"> + <input class="btn btn-secondary" type="button" id="update_query_button" value="{% trans 'Update query' %}"> + <input class="btn btn-primary" type="button" id="submit_query" value="{% trans 'Submit query' %}"> + </fieldset> +</form> +</div>{# Slider div #} +<div id="sql_results"></div> diff --git a/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig new file mode 100644 index 0000000..071249f --- /dev/null +++ b/srcs/phpmyadmin/templates/database/qbe/column_select_cell.twig @@ -0,0 +1,11 @@ +<td class="center"> + <select name="criteriaColumn[{{ column_number }}]" size="1"> + <option value=""> </option> + {% for column in column_names %} + <option value="{{ column }}" + {%- if column is same as(selected) %} selected="selected"{% endif %}> + {{ column|e|replace({' ': ' '}) }} + </option> + {% endfor %} + </select> +</td> diff --git a/srcs/phpmyadmin/templates/database/qbe/footer_options.twig b/srcs/phpmyadmin/templates/database/qbe/footer_options.twig new file mode 100644 index 0000000..7f43f8d --- /dev/null +++ b/srcs/phpmyadmin/templates/database/qbe/footer_options.twig @@ -0,0 +1,16 @@ +<div class="floatleft"> + {% if type == 'row' %} + {% trans 'Add/Delete criteria rows' %}: + {% else %} + {% trans 'Add/Delete columns' %}: + {% endif %} + <select size="1" name="{{ type == 'row' ? 'criteriaRowAdd' : 'criteriaColumnAdd' }}"> + <option value="-3">-3</option> + <option value="-2">-2</option> + <option value="-1">-1</option> + <option value="0" selected="selected">0</option> + <option value="1">1</option> + <option value="2">2</option> + <option value="3">3</option> + </select> +</div> diff --git a/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig new file mode 100644 index 0000000..7a63d77 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/qbe/sort_order_select_cell.twig @@ -0,0 +1,10 @@ +<td class="center"> + <select name="criteriaSortOrder[{{ column_number }}]"> + <option value="1000"> </option> + {% for i in 1..total_column_count %} + <option value="{{ i }}"{{ i == sort_order ? ' selected="selected"' }}> + {{ i }} + </option> + {% endfor %} + </select> +</td> diff --git a/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig b/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig new file mode 100644 index 0000000..4f0989e --- /dev/null +++ b/srcs/phpmyadmin/templates/database/qbe/sort_select_cell.twig @@ -0,0 +1,9 @@ +<td class="center"> + <select style="width:{{ real_width }}" name="criteriaSort[{{ column_number }}]" size="1"> + <option value=""> </option> + <option value="ASC" + {{- selected == 'ASC' ? ' selected="selected"' }}>{% trans 'Ascending' %}</option> + <option value="DESC" + {{- selected == 'DESC' ? ' selected="selected"' }}>{% trans 'Descending' %}</option> + </select> +</td> diff --git a/srcs/phpmyadmin/templates/database/search/main.twig b/srcs/phpmyadmin/templates/database/search/main.twig new file mode 100644 index 0000000..45e5e71 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/search/main.twig @@ -0,0 +1,84 @@ +<a id="db_search"></a> +<form id="db_search_form" method="post" action="db_search.php" name="db_search" class="ajax lock-page"> + {{ get_hidden_inputs(db) }} + <fieldset> + <legend>{% trans 'Search in database' %}</legend> + <p> + <label for="criteriaSearchString" class="displayblock"> + {% trans 'Words or values to search for (wildcard: "%"):' %} + </label> + <input id="criteriaSearchString" name="criteriaSearchString" class="all85" type="text" value=" + {{- criteria_search_string }}"> + </p> + + <fieldset> + <legend>{% trans 'Find:' %}</legend> + {# 4th parameter set to true to add line breaks #} + {# 5th parameter set to false to avoid htmlspecialchars() escaping + in the label since we have some HTML in some labels #} + {{ get_radio_fields( + 'criteriaSearchType', + choices, + criteria_search_type, + true, + false + ) }} + </fieldset> + + <fieldset> + <legend>{% trans 'Inside tables:' %}</legend> + <p> + <a href="#" onclick="Functions.setSelectOptions('db_search', 'criteriaTables[]', true); return false;"> + {% trans 'Select all' %} + </a> / + <a href="#" onclick="Functions.setSelectOptions('db_search', 'criteriaTables[]', false); return false;"> + {% trans 'Unselect all' %} + </a> + </p> + <select name="criteriaTables[]" multiple> + {% for each_table in tables_names_only %} + <option value="{{ each_table }}" + {% if criteria_tables|length > 0 %} + {{- each_table in criteria_tables ? ' selected' }} + {% else %} + {{- ' selected' }} + {% endif %} + > + {{ each_table }} + </option> + {% endfor %} + </select> + </fieldset> + + <p> + {# Inputbox for column name entry #} + <label for="criteriaColumnName" class="displayblock"> + {% trans 'Inside column:' %} + </label> + <input id="criteriaColumnName" type="text" name="criteriaColumnName" class="all85" value=" + {{- criteria_column_name is not empty ? criteria_column_name }}"> + </p> + </fieldset> + <fieldset class="tblFooters"> + <input id="buttonGo" class="btn btn-primary" type="submit" name="submit_search" value="{% trans 'Go' %}"> + </fieldset> +</form> +<div id="togglesearchformdiv"> + <a id="togglesearchformlink"></a> +</div> +<div id="searchresults"></div> +<div id="togglesearchresultsdiv"><a id="togglesearchresultlink"></a></div> +<br class="clearfloat"> +{# These two table-image and table-link elements display the table name in browse search results #} +<div id="table-info"> + <a id="table-link" class="item"></a> +</div> +{# Div for browsing results #} +<div id="browse-results"> + {# This browse-results div is used to load the browse and delete results in the db search #} +</div> +<div id="sqlqueryform" class="clearfloat"> + {# This sqlqueryform div is used to load the delete form in the db search #} +</div> +{# Toggle query box link #} +<a id="togglequerybox"></a> diff --git a/srcs/phpmyadmin/templates/database/search/results.twig b/srcs/phpmyadmin/templates/database/search/results.twig new file mode 100644 index 0000000..3d7a780 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/search/results.twig @@ -0,0 +1,62 @@ +<table class="data"> + <caption class="tblHeaders"> + {{ 'Search results for "<em>%s</em>" %s:'|format( + criteria_search_string, + search_type_description + )|raw }} + </caption> + {% for row in rows %} + <tr class="noclick"> + <td> + {% set result_message %} + {% trans %} + %1$s match in <strong>%2$s</strong> + {% plural row.result_count %} + %1$s matches in <strong>%2$s</strong> + {% endtrans %} + {% endset %} + {{ result_message|format(row.result_count, row.table)|raw }} + </td> + {% if row.result_count > 0 %} + {% set url_params = { + 'db': db, + 'table': row.table, + 'goto': 'db_sql.php', + 'pos': 0, + 'is_js_confirmed': 0 + } %} + <td> + <a name="browse_search" + class="ajax browse_results" + href="sql.php{{ get_common(url_params) }}" + data-browse-sql="{{ row.new_search_sqls.select_columns }}" + data-table-name="{{ row.table }}"> + {% trans 'Browse' %} + </a> + </td> + <td> + <a name="delete_search" + class="ajax delete_results" + href="sql.php{{ get_common(url_params) }}" + data-delete-sql="{{ row.new_search_sqls.delete }}" + data-table-name="{{ row.table }}"> + {% trans 'Delete' %} + </a> + </td> + {% else %} + <td></td> + <td></td> + {% endif %} + </tr> + {% endfor %} +</table> + +{% if criteria_tables|length > 1 %} + <p> + {% trans %} + <strong>Total:</strong> <em>{{ count }}</em> match + {% plural result_total %} + <strong>Total:</strong> <em>{{ count }}</em> matches + {% endtrans %} + </p> +{% endif %} diff --git a/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig b/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig new file mode 100644 index 0000000..8dcebdf --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/body_for_table_summary.twig @@ -0,0 +1,95 @@ +<tbody id="tbl_summary_row"> +<tr> + <th class="print_ignore"></th> + <th class="tbl_num nowrap"> + {% set num_tables_trans -%} + {% trans %}%s table{% plural num_tables %}%s tables{% endtrans %} + {%- endset %} + {{ num_tables_trans|format(format_number(num_tables, 0)) }} + </th> + {% if server_slave_status %} + <th>{% trans 'Replication' %}</th> + {% endif %} + {% set sum_colspan = db_is_system_schema ? 4 : 7 %} + {% if num_favorite_tables == 0 %} + {% set sum_colspan = sum_colspan - 1 %} + {% endif %} + <th colspan="{{ sum_colspan }}" class="print_ignore">{% trans 'Sum' %}</th> + {% set row_count_sum = format_number(sum_entries, 0) %} + {# If a table shows approximate rows count, display update-all-real-count anchor. #} + {% set row_sum_url = [] %} + {% if approx_rows is defined %} + {% set row_sum_url = { + 'ajax_request': true, + 'db': db, + 'real_row_count': 'true', + 'real_row_count_all': 'true' + } %} + {% endif %} + {% if approx_rows %} + {% set cell_text -%} + <a href="db_structure.php + {{- get_common(row_sum_url) }}" class="ajax row_count_sum">~ + {{- row_count_sum -}} + </a> + {%- endset %} + {% else %} + {% set cell_text = row_count_sum %} + {% endif %} + <th class="value tbl_rows">{{ cell_text }}</th> + {% if not (properties_num_columns > 1) %} + {# MySQL <= 5.5.2 #} + {% set default_engine = dbi.fetchValue('SELECT @@storage_engine;') %} + {% if default_engine is empty %} + {# MySQL >= 5.5.3 #} + {% set default_engine = dbi.fetchValue('SELECT @@default_storage_engine;') %} + {% endif %} + <th class="center"> + <dfn title="{{ '%s is the default storage engine on this MySQL server.'|trans|format(default_engine) }}"> + {{ default_engine }} + </dfn> + </th> + <th> + {% if database_collation is not empty %} + <dfn title="{{ database_collation.description }} ({% trans 'Default' %})"> + {{ database_collation.name }} + </dfn> + {% endif %} + </th> + {% endif %} + + {% if is_show_stats %} + {% set sum = format_byte_down(sum_size, 3, 1) %} + {% set sum_formatted = sum[0] %} + {% set sum_unit = sum[1] %} + <th class="value tbl_size">{{ sum_formatted }} {{ sum_unit }}</th> + + {% set overhead = format_byte_down(overhead_size, 3, 1) %} + {% set overhead_formatted = overhead[0] %} + {% set overhead_unit = overhead[1] %} + <th class="value tbl_overhead">{{ overhead_formatted }} {{ overhead_unit }}</th> + {% endif %} + + {% if show_charset %} + <th>{{ database_charset }}</th> + {% endif %} + {% if show_comment %} + <th></th> + {% endif %} + {% if show_creation %} + <th class="value tbl_creation"> + {{ create_time_all }} + </th> + {% endif %} + {% if show_last_update %} + <th class="value tbl_last_update"> + {{ update_time_all }} + </th> + {% endif %} + {% if show_last_check %} + <th class="value tbl_last_check"> + {{ check_time_all }} + </th> + {% endif %} +</tr> +</tbody> diff --git a/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig b/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig new file mode 100644 index 0000000..7a4e7e9 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/check_all_tables.twig @@ -0,0 +1,40 @@ +<div class="clearfloat print_ignore"> + <img class="selectallarrow" src="{{ pma_theme_image }}arrow_{{ text_dir }}.png" width="38" height="22" alt="{% trans 'With selected:' %}"> + <input type="checkbox" id="tablesForm_checkall" class="checkall_box" title="{% trans 'Check all' %}"> + <label for="tablesForm_checkall">{% trans 'Check all' %}</label> + {% if overhead_check != '' %} + / <a href="#" class="checkall-filter" data-checkall-selector=".tbl-overhead">{% trans 'Check tables having overhead' %}</a> + {% endif %} + <select name="submit_mult" style="margin: 0 3em 0 3em;"> + <option value="{% trans 'With selected:' %}" selected="selected">{% trans 'With selected:' %}</option> + <option value="copy_tbl">{% trans 'Copy table' %}</option> + <option value="show_create">{% trans 'Show create' %}</option> + <option value="export">{% trans 'Export' %}</option> + {% if not db_is_system_schema and not disable_multi_table %} + <optgroup label="{% trans 'Delete data or table' %}"> + <option value="empty_tbl">{% trans 'Empty' %}</option> + <option value="drop_tbl">{% trans 'Drop' %}</option> + </optgroup> + <optgroup label="{% trans 'Table maintenance' %}"> + <option value="analyze_tbl">{% trans 'Analyze table' %}</option> + <option value="check_tbl">{% trans 'Check table' %}</option> + <option value="checksum_tbl">{% trans 'Checksum table' %}</option> + <option value="optimize_tbl">{% trans 'Optimize table' %}</option> + <option value="repair_tbl">{% trans 'Repair table' %}</option> + </optgroup> + <optgroup label="{% trans 'Prefix' %}"> + <option value="add_prefix_tbl">{% trans 'Add prefix to table' %}</option> + <option value="replace_prefix_tbl">{% trans 'Replace table prefix' %}</option> + <option value="copy_tbl_change_prefix">{% trans 'Copy table with prefix' %}</option> + </optgroup> + {% endif %} + {% if central_columns_work is defined and central_columns_work %} + <optgroup label="{% trans 'Central columns' %}"> + <option value="sync_unique_columns_central_list">{% trans 'Add columns to central list' %}</option> + <option value="delete_unique_columns_central_list">{% trans 'Remove columns from central list' %}</option> + <option value="make_consistent_with_central_list">{% trans 'Make consistent with central list' %}</option> + </optgroup> + {% endif %} + </select> + {{ hidden_fields|join('\n')|raw }} +</div> diff --git a/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig b/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig new file mode 100644 index 0000000..91e002e --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/favorite_anchor.twig @@ -0,0 +1,7 @@ +<a id="{{ table_name_hash }}_favorite_anchor" + class="ajax favorite_table_anchor" + href="db_structure.php{{ get_common(fav_params) }}" + title="{{ already_favorite ? 'Remove from Favorites'|trans : 'Add to Favorites'|trans }}" + data-favtargets="{{ db_table_name_hash }}" > + {{ already_favorite ? titles['Favorite']|raw : titles['NoFavorite']|raw }} +</a> diff --git a/srcs/phpmyadmin/templates/database/structure/index.twig b/srcs/phpmyadmin/templates/database/structure/index.twig new file mode 100644 index 0000000..1632839 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/index.twig @@ -0,0 +1,24 @@ +{% if has_tables %} + <div id="tableslistcontainer"> + {{ list_navigator_html|raw }} + + {{ table_list_html|raw }} + + {{ list_navigator_html|raw }} + </div> + <hr> + <p class="print_ignore"> + <a href="#" id="printView"> + {{ get_icon('b_print', 'Print'|trans, true) }} + </a> + <a href="db_datadict.php{{ get_common({'db': database, 'goto': 'db_structure.php'}) }}" target="print_view"> + {{ get_icon('b_tblanalyse', 'Data dictionary'|trans, true) }} + </a> + </p> +{% else %} + {{ 'No tables found in database.'|trans|notice }} +{% endif %} + +{% if not is_system_schema %} + {{ create_table_html|raw }} +{% endif %} diff --git a/srcs/phpmyadmin/templates/database/structure/show_create.twig b/srcs/phpmyadmin/templates/database/structure/show_create.twig new file mode 100644 index 0000000..520e974 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/show_create.twig @@ -0,0 +1,31 @@ +<div class="show_create_results"> + <h2>{% trans 'Showing create queries' %}</h2> + {% set views = [] %} + {% set tables = [] %} + {% for object in db_objects %} + {% if dbi.getTable(db, object).isView() %} + {% set views = views|merge([object]) %} + {% else %} + {% set tables = tables|merge([object]) %} + {% endif %} + {% endfor %} + {% if tables is not empty %} + {% include 'database/structure/show_create_row.twig' with { + 'db': db, + 'title': 'Tables'|trans, + 'raw_title': 'Table', + 'db_objects': tables, + 'dbi': dbi + } only %} + {% endif %} + + {% if views is not empty %} + {% include 'database/structure/show_create_row.twig' with { + 'db': db, + 'title': 'Views'|trans, + 'raw_title': 'View', + 'db_objects': views, + 'dbi': dbi + } only %} + {% endif %} +</div> diff --git a/srcs/phpmyadmin/templates/database/structure/show_create_row.twig b/srcs/phpmyadmin/templates/database/structure/show_create_row.twig new file mode 100644 index 0000000..db18cdd --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/show_create_row.twig @@ -0,0 +1,19 @@ +<fieldset> + <legend>{{ title }}</legend> + <table class="show_create"> + <thead> + <tr> + <th>{{ raw_title }}</th> + <th>{{ 'Create %s'|trans|format(raw_title) }}</th> + </tr> + </thead> + <tbody> + {% for object in db_objects %} + <tr> + <td><strong>{{ object|mime_default_function }}</strong></td> + <td>{{ dbi.getTable(db, object).showCreate()|mime_default_function }}</td> + </tr> + {% endfor %} + </tbody> + </table> +</fieldset> diff --git a/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig b/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig new file mode 100644 index 0000000..b87ea48 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/structure_table_row.twig @@ -0,0 +1,223 @@ +<tr id="row_tbl_{{ curr }}"{{ table_is_view ? ' class="is_view"' }} data-filter-row="{{ current_table['TABLE_NAME']|upper }}"> + <td class="center print_ignore"> + <input type="checkbox" + name="selected_tbl[]" + class="{{ input_class }}" + value="{{ current_table['TABLE_NAME'] }}" + id="checkbox_tbl_{{ curr }}"> + </td> + <th> + <a href="sql.php{{ tbl_url_query|raw }}&pos=0" title="{{ browse_table_label_title }}"> + {{ browse_table_label_truename }} + </a> + {{ tracking_icon|raw }} + </th> + {% if server_slave_status %} + <td class="center"> + {{ ignored ? get_image('s_cancel', 'Not replicated'|trans) }} + {{ do ? get_image('s_success', 'Replicated'|trans) }} + </td> + {% endif %} + + {# Favorite table anchor #} + {% if num_favorite_tables > 0 %} + <td class="center print_ignore"> + {# Check if current table is already in favorite list #} + {% set fav_params = { + 'db': db, + 'ajax_request': true, + 'favorite_table': current_table['TABLE_NAME'], + ((already_favorite ? 'remove' : 'add') ~ '_favorite'): true + } %} + {% include 'database/structure/favorite_anchor.twig' with { + 'table_name_hash': table_name_hash, + 'db_table_name_hash': db_table_name_hash, + 'fav_params': fav_params, + 'already_favorite': already_favorite, + 'titles': titles + } only %} + </td> + {% endif %} + + <td class="center print_ignore"> + <a href="sql.php{{ tbl_url_query|raw }}&pos=0"> + {{ browse_table_title|raw }} + </a> + + </td> + <td class="center print_ignore"> + <a href="tbl_structure.php{{ tbl_url_query|raw }}"> + {{ titles['Structure']|raw }} + </a> + </td> + <td class="center print_ignore"> + <a href="tbl_select.php{{ tbl_url_query|raw }}"> + {{ search_table_title|raw }} + </a> + </td> + + {% if not db_is_system_schema %} + <td class="insert_table center print_ignore"> + <a href="tbl_change.php{{ tbl_url_query|raw }}">{{ titles['Insert']|raw }}</a> + </td> + {% if table_is_view %} + <td class="center print_ignore"> + <a href="view_create.php{{- get_common({ + 'db': db, + 'table': current_table['TABLE_NAME'] + }) }}">{{ titles['Edit']|raw }}</a> + </td> + {% else %} + <td class="center print_ignore"> + <a class="truncate_table_anchor ajax" href="sql.php" data-post="{{ tbl_url_query|raw }}&sql_query= + {{- empty_table_sql_query }}&message_to_show={{ empty_table_message_to_show }}"> + {{ empty_table_title|raw }} + </a> + </td> + {% endif %} + <td class="center print_ignore"> + <a class="ajax drop_table_anchor + {{- table_is_view or current_table['ENGINE'] == null ? ' view' }}" + href="sql.php" data-post="{{ tbl_url_query|raw }}&reload=1&purge=1&sql_query= + {{- drop_query|url_encode }}&message_to_show={{ drop_message|url_encode }}"> + {{ titles['Drop']|raw }} + </a> + </td> + {% endif %} + + {% if current_table['TABLE_ROWS'] is defined + and (current_table['ENGINE'] != null or table_is_view) %} + {# Get the row count #} + {% set row_count = format_number(current_table['TABLE_ROWS'], 0) %} + + {# Content to be appended into 'tbl_rows' cell. + If row count is approximate, display it as an anchor to get real count. #} + <td class="value tbl_rows" + data-table="{{ current_table['TABLE_NAME'] }}"> + {% if approx_rows %} + <a href="db_structure.php{{ get_common({ + 'ajax_request': true, + 'db': db, + 'table': current_table['TABLE_NAME'], + 'real_row_count': 'true' + }) }}" class="ajax real_row_count"> + <bdi> + ~{{ row_count }} + </bdi> + </a> + {% else %} + {{ row_count }} + {% endif %} + {{ show_superscript|raw }} + </td> + + {% if not (properties_num_columns > 1) %} + <td class="nowrap"> + {% if current_table['ENGINE'] is not empty %} + {{ current_table['ENGINE'] }} + {% elseif table_is_view %} + {% trans 'View' %} + {% endif %} + </td> + {% if collation|length > 0 %} + <td class="nowrap"> + {{ collation|raw }} + </td> + {% endif %} + {% endif %} + + {% if is_show_stats %} + <td class="value tbl_size"> + <a href="tbl_structure.php{{ tbl_url_query|raw }}#showusage"> + <span>{{ formatted_size }}</span> <span class="unit">{{ unit }}</span> + </a> + </td> + <td class="value tbl_overhead"> + {{ overhead|raw }} + </td> + {% endif %} + + {% if not (show_charset > 1) %} + {% if charset|length > 0 %} + <td class="nowrap"> + {{ charset|raw }} + </td> + {% endif %} + {% endif %} + + {% if show_comment %} + {% set comment = current_table['Comment'] %} + <td> + {% if comment|length > limit_chars %} + <abbr title="{{ comment }}"> + {{ comment|slice(0, limit_chars) }} + ... + </abbr> + {% else %} + {{ comment }} + {% endif %} + </td> + {% endif %} + + {% if show_creation %} + <td class="value tbl_creation"> + {{ create_time }} + </td> + {% endif %} + + {% if show_last_update %} + <td class="value tbl_last_update"> + {{ update_time }} + </td> + {% endif %} + + {% if show_last_check %} + <td class="value tbl_last_check"> + {{ check_time }} + </td> + {% endif %} + + {% elseif table_is_view %} + <td class="value tbl_rows">-</td> + <td class="nowrap"> + {% trans 'View' %} + </td> + <td class="nowrap">---</td> + {% if is_show_stats %} + <td class="value tbl_size">-</td> + <td class="value tbl_overhead">-</td> + {% endif %} + {% if show_charset %} + <td></td> + {% endif %} + {% if show_comment %} + <td></td> + {% endif %} + {% if show_creation %} + <td class="value tbl_creation">-</td> + {% endif %} + {% if show_last_update %} + <td class="value tbl_last_update">-</td> + {% endif %} + {% if show_last_check %} + <td class="value tbl_last_check">-</td> + {% endif %} + + {% else %} + + {% if db_is_system_schema %} + {% set action_colspan = 3 %} + {% else %} + {% set action_colspan = 6 %} + {% endif %} + {% if num_favorite_tables > 0 %} + {% set action_colspan = action_colspan + 1 %} + {% endif %} + + {% set colspan_for_structure = action_colspan + 3 %} + <td colspan="{{ colspan_for_structure - db_is_system_schema ? 6 : 9 }}" + class="center"> + {% trans 'in use' %} + </td> + {% endif %} +</tr> diff --git a/srcs/phpmyadmin/templates/database/structure/table_header.twig b/srcs/phpmyadmin/templates/database/structure/table_header.twig new file mode 100644 index 0000000..e479f5e --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/table_header.twig @@ -0,0 +1,78 @@ +<form method="post" action="db_structure.php" name="tablesForm" id="tablesForm"> +{{ get_hidden_inputs(db) }} +<div class="responsivetable"> +<table id="structureTable" class="data"> + <thead> + <tr> + <th class="print_ignore"></th> + <th>{{ sortable_table_header('Table'|trans, 'table') }}</th> + {% if replication %} + <th>{% trans 'Replication' %}</th> + {% endif %} + + {% if db_is_system_schema %} + {% set action_colspan = 3 %} + {% else %} + {% set action_colspan = 6 %} + {% endif %} + {% if num_favorite_tables > 0 %} + {% set action_colspan = action_colspan + 1 %} + {% endif %} + <th colspan="{{ action_colspan }}" class="print_ignore"> + {% trans 'Action' %} + </th> + {# larger values are more interesting so default sort order is DESC #} + <th> + {{ sortable_table_header('Rows'|trans, 'records', 'DESC') }} + {{ show_hint('May be approximate. Click on the number to get the exact count. See [doc@faq3-11]FAQ 3.11[/doc].'|trans|sanitize) }} + </th> + {% if not (properties_num_columns > 1) %} + <th>{{ sortable_table_header('Type'|trans, 'type') }}</th> + <th>{{ sortable_table_header('Collation'|trans, 'collation') }}</th> + {% endif %} + + {% if is_show_stats %} + {# larger values are more interesting so default sort order is DESC #} + <th>{{ sortable_table_header('Size'|trans, 'size', 'DESC') }}</th> + {# larger values are more interesting so default sort order is DESC #} + <th>{{ sortable_table_header('Overhead'|trans, 'overhead', 'DESC') }}</th> + {% endif %} + + {% if show_charset %} + <th>{{ sortable_table_header('Charset'|trans, 'charset') }}</th> + {% endif %} + + {% if show_comment %} + <th>{{ sortable_table_header('Comment'|trans, 'comment') }}</th> + {% endif %} + + {% if show_creation %} + {# newer values are more interesting so default sort order is DESC #} + <th>{{ sortable_table_header('Creation'|trans, 'creation', 'DESC') }}</th> + {% endif %} + + {% if show_last_update %} + {# newer values are more interesting so default sort order is DESC #} + <th>{{ sortable_table_header('Last update'|trans, 'last_update', 'DESC') }}</th> + {% endif %} + + {% if show_last_check %} + {# newer values are more interesting so default sort order is DESC #} + <th>{{ sortable_table_header('Last check'|trans, 'last_check', 'DESC') }}</th> + {% endif %} + </tr> + </thead> + <tbody> + {% for structure_table_row in structure_table_rows %} + {% include 'database/structure/structure_table_row.twig' with structure_table_row only %} + {% endfor %} + </tbody> + {% if body_for_table_summary %} + {% include 'database/structure/body_for_table_summary.twig' with body_for_table_summary only %} + {% endif %} +</table> +</div> +{% if check_all_tables %} + {% include 'database/structure/check_all_tables.twig' with check_all_tables only %} +{% endif %} +</form> diff --git a/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig b/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig new file mode 100644 index 0000000..b09c9bb --- /dev/null +++ b/srcs/phpmyadmin/templates/database/structure/tracking_icon.twig @@ -0,0 +1,7 @@ +<a href="tbl_tracking.php{{ get_common({'table': table, 'db': db}) }}"> + {% if is_tracked -%} + {{ get_image('eye', 'Tracking is active.'|trans) }} + {%- else -%} + {{ get_image('eye_grey', 'Tracking is not active.'|trans) }} + {%- endif %} +</a> diff --git a/srcs/phpmyadmin/templates/database/tracking/tables.twig b/srcs/phpmyadmin/templates/database/tracking/tables.twig new file mode 100644 index 0000000..7f95947 --- /dev/null +++ b/srcs/phpmyadmin/templates/database/tracking/tables.twig @@ -0,0 +1,161 @@ +{# Tracked tables exists#} +{% if head_version_exists %} + <div id="tracked_tables"> + <h3>{% trans 'Tracked tables' %}</h3> + + <form method="post" action="db_tracking.php" name="trackedForm" + id="trackedForm" class="ajax"> + {{ get_hidden_inputs(db) }} + <table id="versions" class="data"> + <thead> + <tr> + <th></th> + <th>{% trans 'Table' %}</th> + <th>{% trans 'Last version' %}</th> + <th>{% trans 'Created' %}</th> + <th>{% trans 'Updated' %}</th> + <th>{% trans 'Status' %}</th> + <th>{% trans 'Action' %}</th> + <th>{% trans 'Show' %}</th> + </tr> + </thead> + <tbody> + {% for version in versions %} + <tr> + <td class="center"> + <input type="checkbox" name="selected_tbl[]" + class="checkall" id="selected_tbl_{{ version.table_name }}" + value="{{ version.table_name }}"> + </td> + <th> + <label for="selected_tbl_{{ version.table_name }}"> + {{ version.table_name }} + </label> + </th> + <td class="right"> + {{ version.version }} + </td> + <td> + {{ version.date_created }} + </td> + <td> + {{ version.date_updated }} + </td> + <td> + {{ version.status_button|raw }} + </td> + <td> + <a class="delete_tracking_anchor ajax" href="db_tracking.php" data-post=" + {{- get_common({ + 'db': db, + 'goto': 'tbl_tracking.php', + 'back': 'db_tracking.php', + 'table': version.table_name, + 'delete_tracking': true + }, '') }}"> + {{ get_icon('b_drop', 'Delete tracking'|trans) }} + </a> + </td> + <td> + <a href="tbl_tracking.php" data-post=" + {{- get_common({ + 'db': db, + 'goto': 'tbl_tracking.php', + 'back': 'db_tracking.php', + 'table': version.table_name + }, '') }}"> + {{ get_icon('b_versions', 'Versions'|trans) }} + </a> + <a href="tbl_tracking.php" data-post=" + {{- get_common({ + 'db': db, + 'goto': 'tbl_tracking.php', + 'back': 'db_tracking.php', + 'table': version.table_name, + 'report': true, + 'version': version.version + }, '') }}"> + {{ get_icon('b_report', 'Tracking report'|trans) }} + </a> + <a href="tbl_tracking.php" data-post=" + {{- get_common({ + 'db': db, + 'goto': 'tbl_tracking.php', + 'back': 'db_tracking.php', + 'table': version.table_name, + 'snapshot': true, + 'version': version.version + }, '') }}"> + {{ get_icon('b_props', 'Structure snapshot'|trans) }} + </a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% include 'select_all.twig' with { + 'pma_theme_image': pma_theme_image, + 'text_dir': text_dir, + 'form_name': 'trackedForm' + } only %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Delete tracking'|trans, + 'b_drop', + 'delete_tracking' + ) }} + </form> + </div> +{% endif %} +{% if untracked_tables_exists %} + <h3>{% trans 'Untracked tables' %}</h3> + <form method="post" action="db_tracking.php" name="untrackedForm" + id="untrackedForm" class="ajax"> + {{ get_hidden_inputs(db) }} + <table id="noversions" class="data"> + <thead> + <tr> + <th></th> + <th>{% trans 'Table' %}</th> + <th>{% trans 'Action' %}</th> + </tr> + </thead> + <tbody> + {% for table_name in untracked_tables %} + {% if get_tracker_version(db, table_name) == -1 %} + <tr> + <td class="center"> + <input type="checkbox" name="selected_tbl[]" + class="checkall" id="selected_tbl_{{ table_name }}" + value="{{ table_name }}"> + </td> + <th> + <label for="selected_tbl_{{ table_name }}"> + {{ table_name }} + </label> + </th> + <td> + <a href="tbl_tracking.php{{ url_query|raw }}&table={{ table_name }}"> + {{ get_icon('eye', 'Track table'|trans) }} + </a> + </td> + </tr> + {% endif %} + {% endfor %} + </tbody> + </table> + {% include 'select_all.twig' with { + 'pma_theme_image': pma_theme_image, + 'text_dir': text_dir, + 'form_name': 'untrackedForm' + } only %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Track table'|trans, + 'eye', + 'track' + ) }} + </form> +{% endif %} diff --git a/srcs/phpmyadmin/templates/display/export/format_dropdown.twig b/srcs/phpmyadmin/templates/display/export/format_dropdown.twig new file mode 100644 index 0000000..adda19b --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/format_dropdown.twig @@ -0,0 +1,4 @@ +<div class="exportoptions" id="format"> + <h3>{% trans 'Format:' %}</h3> + {{ dropdown|raw }} +</div> diff --git a/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig b/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig new file mode 100644 index 0000000..fc7c04e --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/hidden_inputs.twig @@ -0,0 +1,23 @@ +{% if export_type == 'server' %} + {{ get_hidden_inputs('', '', 1) }} +{% elseif export_type == 'database' %} + {{ get_hidden_inputs(db, '', 1) }} +{% else %} + {{ get_hidden_inputs(db, table, 1) }} +{% endif %} + +{# Just to keep this value for possible next display of this form after saving on server #} +{% if single_table is not empty %} + <input type="hidden" name="single_table" value="TRUE"> +{% endif %} + +<input type="hidden" name="export_type" value="{{ export_type }}"> + +{# The export method (quick, custom or custom-no-form) #} +<input type="hidden" name="export_method" value="{{ export_method }}"> + +{% if sql_query is not empty %} + <input type="hidden" name="sql_query" value="{{ sql_query }}"> +{% endif %} + +<input type="hidden" name="template_id" value="{{ template_id }}"> diff --git a/srcs/phpmyadmin/templates/display/export/method.twig b/srcs/phpmyadmin/templates/display/export/method.twig new file mode 100644 index 0000000..5521f57 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/method.twig @@ -0,0 +1,22 @@ +{% if export_method != 'custom-no-form' %} + <div class="exportoptions" id="quick_or_custom"> + <h3>{% trans 'Export method:' %}</h3> + <ul> + <li> + <input type="radio" name="quick_or_custom" value="quick" id="radio_quick_export" + {{- export_method == 'quick' ? ' checked' }}> + <label for="radio_quick_export"> + {% trans 'Quick - display only the minimal options' %} + </label> + </li> + + <li> + <input type="radio" name="quick_or_custom" value="custom" id="radio_custom_export" + {{- export_method == 'custom' ? ' checked' }}> + <label for="radio_custom_export"> + {% trans 'Custom - display all possible options' %} + </label> + </li> + </ul> + </div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/display/export/option_header.twig b/srcs/phpmyadmin/templates/display/export/option_header.twig new file mode 100644 index 0000000..03e4f6b --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/option_header.twig @@ -0,0 +1,12 @@ +<div class="exportoptions" id="header"> + <h2> + {{ get_image('b_export', 'Export'|trans) }} + {% if export_type == 'server' %} + {% trans 'Exporting databases from the current server' %} + {% elseif export_type == 'database' %} + {{ 'Exporting tables from "%s" database'|trans|format(db) }} + {% else %} + {{ 'Exporting rows from "%s" table'|trans|format(table) }} + {% endif %} + </h2> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/options_format.twig b/srcs/phpmyadmin/templates/display/export/options_format.twig new file mode 100644 index 0000000..6b09814 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_format.twig @@ -0,0 +1,24 @@ +<div class="exportoptions" id="format_specific_opts"> + <h3>{% trans 'Format-specific options:' %}</h3> + <p class="no_js_msg" id="scroll_to_options_msg"> + {% trans 'Scroll down to fill in the options for the selected format and ignore the options for other formats.' %} + </p> + {{ options|raw }} +</div> + +{% if can_convert_kanji %} + {# Japanese encoding setting #} + <div class="exportoptions" id="kanji_encoding"> + <h3>{% trans 'Encoding Conversion:' %}</h3> + {% include 'encoding/kanji_encoding_form.twig' %} + </div> +{% endif %} + +<div class="exportoptions" id="submit"> + <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Go' %}" + {#- If the time limit set is zero, then time out won't occur so no need + to check for time out. -#} + {%- if exec_time_limit > 0 %} + onclick="Export.checkTimeOut({{ exec_time_limit }})" + {%- endif %}> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/options_output.twig b/srcs/phpmyadmin/templates/display/export/options_output.twig new file mode 100644 index 0000000..60d721c --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output.twig @@ -0,0 +1,54 @@ +<div class="exportoptions" id="output"> + <h3>{% trans 'Output:' %}</h3> + <ul id="ul_output"> + <li> + <input type="checkbox" id="btn_alias_config"{{ has_aliases ? ' checked' }}> + <label for="btn_alias_config"> + {% trans 'Rename exported databases/tables/columns' %} + </label> + </li> + + {% if export_type != 'server' %} + <li> + <input type="checkbox" name="lock_tables" + value="something" id="checkbox_lock_tables" + {{- (not repopulate and is_checked_lock_tables) or lock_tables ? ' checked' }}> + <label for="checkbox_lock_tables"> + {{ 'Use %s statement'|trans|format('<code>LOCK TABLES</code>')|raw }} + </label> + </li> + {% endif %} + + <li> + <input type="radio" name="output_format" value="sendit" id="radio_dump_asfile" + {{- not repopulate and is_checked_asfile ? ' checked' }}> + <label for="radio_dump_asfile"> + {% trans 'Save output to a file' %} + </label> + <ul id="ul_save_asfile"> + {% if save_dir is not empty %} + {{ options_output_save_dir|raw }} + {% endif %} + + {{ options_output_format|raw }} + + {% if is_encoding_supported %} + {{ options_output_charset|raw }} + {% endif %} + + {{ options_output_compression|raw }} + + {% if export_type == 'server' or export_type == 'database' %} + {{ options_output_separate_files|raw }} + {% endif %} + </ul> + </li> + + {{ options_output_radio|raw }} + </ul> + + <label for="maxsize"> + {{- 'Skip tables larger than %s MiB'|trans|format( + '</label><input type="text" id="maxsize" name="maxsize" size="4">' + )|raw }} +</div> diff --git a/srcs/phpmyadmin/templates/display/export/options_output_charset.twig b/srcs/phpmyadmin/templates/display/export/options_output_charset.twig new file mode 100644 index 0000000..bd316bf --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_charset.twig @@ -0,0 +1,16 @@ +<li> + <label for="select_charset" class="desc"> + {% trans 'Character set of the file:' %} + </label> + <select id="select_charset" name="charset" size="1"> + {% for charset in encodings %} + <option value="{{ charset }}" + {%- if (export_charset is empty and charset == 'utf-8') + or charset == export_charset %} + selected + {%- endif %}> + {{- charset -}} + </option> + {% endfor %} + </select> +</li> diff --git a/srcs/phpmyadmin/templates/display/export/options_output_compression.twig b/srcs/phpmyadmin/templates/display/export/options_output_compression.twig new file mode 100644 index 0000000..1905981 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_compression.twig @@ -0,0 +1,24 @@ +{% if is_zip or is_gzip %} + <li> + <label for="compression" class="desc"> + {% trans 'Compression:' %} + </label> + <select id="compression" name="compression"> + <option value="none">{% trans 'None' %}</option> + {% if is_zip %} + <option value="zip" + {{- selected_compression == 'zip' ? ' selected' }}> + {% trans 'zipped' %} + </option> + {% endif %} + {% if is_gzip %} + <option value="gzip" + {{- selected_compression == 'gzip' ? ' selected' }}> + {% trans 'gzipped' %} + </option> + {% endif %} + </select> + </li> +{% else %} + <input type="hidden" name="compression" value="{{ selected_compression }}"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/display/export/options_output_format.twig b/srcs/phpmyadmin/templates/display/export/options_output_format.twig new file mode 100644 index 0000000..d75d330 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_format.twig @@ -0,0 +1,13 @@ +<li> + <label for="filename_template" class="desc"> + {% trans 'File name template:' %} + {{ show_hint(message) }} + </label> + <input type="text" name="filename_template" id="filename_template" value=" + {{- filename_template }}"> + <input type="checkbox" name="remember_template" id="checkbox_remember_template" + {{- is_checked ? ' checked' }}> + <label for="checkbox_remember_template"> + {% trans 'use this for future exports' %} + </label> +</li> diff --git a/srcs/phpmyadmin/templates/display/export/options_output_radio.twig b/srcs/phpmyadmin/templates/display/export/options_output_radio.twig new file mode 100644 index 0000000..7adf21e --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_radio.twig @@ -0,0 +1,7 @@ +<li> + <input type="radio" id="radio_view_as_text" name="output_format" value="astext" + {{- has_repopulate or export_asfile == false ? ' checked' }}> + <label for="radio_view_as_text"> + {% trans 'View output as text' %} + </label> +</li> diff --git a/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig b/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig new file mode 100644 index 0000000..b4526aa --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_save_dir.twig @@ -0,0 +1,15 @@ +<li> + <input type="checkbox" name="onserver" value="saveit" + id="checkbox_dump_onserver"{{ export_is_checked ? ' checked' }}> + <label for="checkbox_dump_onserver"> + {{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }} + </label> +</li> +<li> + <input type="checkbox" name="onserver_overwrite" + value="saveitover" id="checkbox_dump_onserver_overwrite" + {{- export_overwrite_is_checked ? ' checked' }}> + <label for="checkbox_dump_onserver_overwrite"> + {% trans 'Overwrite existing file(s)' %} + </label> +</li> diff --git a/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig b/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig new file mode 100644 index 0000000..fec85c4 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_output_separate_files.twig @@ -0,0 +1,12 @@ +<li> + <input type="checkbox" id="checkbox_as_separate_files" + name="as_separate_files" value="{{ export_type }}" + {{- is_checked ? ' checked' }}> + <label for="checkbox_as_separate_files"> + {% if export_type == 'server' %} + {% trans 'Export databases as separate files' %} + {% elseif export_type == 'database' %} + {% trans 'Export tables as separate files' %} + {% endif %} + </label> +</li> diff --git a/srcs/phpmyadmin/templates/display/export/options_quick_export.twig b/srcs/phpmyadmin/templates/display/export/options_quick_export.twig new file mode 100644 index 0000000..b3bd159 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_quick_export.twig @@ -0,0 +1,20 @@ +<div class="exportoptions" id="output_quick_export"> + <h3>{% trans 'Output:' %}</h3> + <ul> + <li> + <input type="checkbox" name="quick_export_onserver" value="saveit" + id="checkbox_quick_dump_onserver"{{ export_is_checked ? ' checked' }}> + <label for="checkbox_quick_dump_onserver"> + {{ 'Save on server in the directory <strong>%s</strong>'|trans|format(save_dir|e)|raw }} + </label> + </li> + <li> + <input type="checkbox" name="quick_export_onserver_overwrite" + value="saveitover" id="checkbox_quick_dump_onserver_overwrite" + {{- export_overwrite_is_checked ? ' checked' }}> + <label for="checkbox_quick_dump_onserver_overwrite"> + {% trans 'Overwrite existing file(s)' %} + </label> + </li> + </ul> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/options_rows.twig b/srcs/phpmyadmin/templates/display/export/options_rows.twig new file mode 100644 index 0000000..1d4f866 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/options_rows.twig @@ -0,0 +1,35 @@ +<div class="exportoptions" id="rows"> + <h3>{% trans 'Rows:' %}</h3> + <ul> + <li> + <input type="radio" name="allrows" value="0" id="radio_allrows_0" + {{- allrows is not null and allrows == 0 ? ' checked' }}> + <label for="radio_allrows_0">{% trans 'Dump some row(s)' %}</label> + <ul> + <li> + <label for="limit_to">{% trans 'Number of rows:' %}</label> + <input type="text" id="limit_to" name="limit_to" size="5" value=" + {%- apply spaceless %} + {% if limit_to is not null %} + {{ limit_to }} + {% elseif unlim_num_rows is not empty and unlim_num_rows != 0 %} + {{ unlim_num_rows }} + {% else %} + {{ number_of_rows }} + {% endif %} + {% endapply %}" onfocus="this.select()"> + </li> + <li> + <label for="limit_from">{% trans 'Row to begin at:' %}</label> + <input type="text" id="limit_from" name="limit_from" size="5" value=" + {{- limit_from is not null ? limit_from : 0 }}" onfocus="this.select()"> + </li> + </ul> + </li> + <li> + <input type="radio" name="allrows" value="1" id="radio_allrows_1" + {{- allrows is null or allrows == 1 ? ' checked' }}> + <label for="radio_allrows_1">{% trans 'Dump all rows' %}</label> + </li> + </ul> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/select_options.twig b/srcs/phpmyadmin/templates/display/export/select_options.twig new file mode 100644 index 0000000..4ca00ba --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/select_options.twig @@ -0,0 +1,19 @@ +<div> + <p> + <a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', true); return false;"> + {% trans 'Select all' %} + </a> + / + <a href="#" onclick="Functions.setSelectOptions('dump', 'db_select[]', false); return false;"> + {% trans 'Unselect all' %} + </a> + </p> + + <select name="db_select[]" id="db_select" size="10" multiple> + {% for database in databases %} + <option value="{{ database.name }}"{{ database.is_selected ? ' selected' }}> + {{ database.name }} + </option> + {% endfor %} + </select> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/selection.twig b/srcs/phpmyadmin/templates/display/export/selection.twig new file mode 100644 index 0000000..6f691f5 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/selection.twig @@ -0,0 +1,10 @@ +<div class="exportoptions" id="databases_and_tables"> + {% if export_type == 'server' %} + <h3>{% trans 'Databases:' %}</h3> + {% elseif export_type == 'database' %} + <h3>{% trans 'Tables:' %}</h3> + {% endif %} + {% if multi_values is not empty %} + {{ multi_values|raw }} + {% endif %} +</div> diff --git a/srcs/phpmyadmin/templates/display/export/template_loading.twig b/srcs/phpmyadmin/templates/display/export/template_loading.twig new file mode 100644 index 0000000..16eaa6d --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/template_loading.twig @@ -0,0 +1,27 @@ +<div class="exportoptions" id="export_templates"> + <h3>{% trans 'Export templates:' %}</h3> + + <div class="floatleft"> + <form method="post" action="tbl_export.php" id="newTemplateForm" class="ajax"> + <h4>{% trans 'New template:' %}</h4> + <input type="text" name="templateName" id="templateName" + maxlength="64" placeholder="{% trans 'Template name' %}" required> + <input class="btn btn-secondary" type="submit" name="createTemplate" id="createTemplate" + value="{% trans 'Create' %}"> + </form> + </div> + + <div class="floatleft" style="margin-left: 50px;"> + <form method="post" action="tbl_export.php" id="existingTemplatesForm" class="ajax"> + <h4>{% trans 'Existing templates:' %}</h4> + <label for="template">{% trans 'Template:' %}</label> + <select name="template" id="template" required> + {{ options|raw }} + </select> + <input class="btn btn-secondary" type="submit" name="updateTemplate" id="updateTemplate" value="{% trans 'Update' %}"> + <input class="btn btn-secondary" type="submit" name="deleteTemplate" id="deleteTemplate" value="{% trans 'Delete' %}"> + </form> + </div> + + <div class="clearfloat"></div> +</div> diff --git a/srcs/phpmyadmin/templates/display/export/template_options.twig b/srcs/phpmyadmin/templates/display/export/template_options.twig new file mode 100644 index 0000000..ddcd4f5 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/export/template_options.twig @@ -0,0 +1,7 @@ +<option value="">-- {% trans 'Select a template' %} --</option> + +{% for template in templates %} + <option value="{{ template.id }}"{{ template.id == selected_template ? ' selected' }}> + {{ template.name }} + </option> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/display/import/import.twig b/srcs/phpmyadmin/templates/display/import/import.twig new file mode 100644 index 0000000..dab14a3 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/import/import.twig @@ -0,0 +1,195 @@ +<iframe id="import_upload_iframe" name="import_upload_iframe" width="1" height="1" class="hide"></iframe> +<div id="import_form_status" class="hide"></div> +<div id="importmain"> + <img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock" class="hide"> + + <script type="text/javascript"> + //<![CDATA[ + {% include 'display/import/javascript.twig' with { + 'upload_id': upload_id, + 'handler': handler, + 'pma_theme_image': pma_theme_image + } only %} + //]]> + </script> + + <form id="import_file_form" + action="import.php" + method="post" + enctype="multipart/form-data" + name="import" + class="ajax" + {%- if handler != 'PhpMyAdmin\\Plugins\\Import\\Upload\\UploadNoplugin' %} + target="import_upload_iframe" + {%- endif %}> + + <input type="hidden" name="{{ id_key }}" value="{{ upload_id }}"> + {% if import_type == 'server' %} + {{ get_hidden_inputs('', '', 1) }} + {% elseif import_type == 'database' %} + {{ get_hidden_inputs(db, '', 1) }} + {% else %} + {{ get_hidden_inputs(db, table, 1) }} + {% endif %} + <input type="hidden" name="import_type" value="{{ import_type }}"> + + <div class="exportoptions" id="header"> + <h2> + {{ get_image('b_import', 'Import'|trans) }} + {% if import_type == 'server' %} + {% trans 'Importing into the current server' %} + {% elseif import_type == 'database' %} + {{ 'Importing into the database "%s"'|trans|format(db) }} + {% else %} + {{ 'Importing into the table "%s"'|trans|format(table) }} + {% endif %} + </h2> + </div> + + <div class="importoptions"> + <h3>{% trans 'File to import:' %}</h3> + + {# We don't have show anything about compression, when no supported #} + {% if compressions is not empty %} + <div class="formelementrow" id="compression_info"> + <p> + {{ 'File may be compressed (%s) or uncompressed.'|trans|format(compressions|join(', ')) }} + <br> + {% trans 'A compressed file\'s name must end in <strong>.[format].[compression]</strong>. Example: <strong>.sql.zip</strong>' %} + </p> + </div> + {% endif %} + + <div class="formelementrow" id="upload_form"> + {% if is_upload and upload_dir is not empty %} + <ul> + <li> + <input type="radio" name="file_location" id="radio_import_file" required="required"> + {{ get_browse_upload_file_block(max_upload_size) }} + {% trans 'You may also drag and drop a file on any page.' %} + </li> + <li> + <input type="radio" name="file_location" id="radio_local_import_file" + {%- if timeout_passed_global is not empty and local_import_file is not empty %} + checked="checked" + {%- endif %}> + {{ get_select_upload_file_block( + import_list, + upload_dir + ) }} + </li> + </ul> + {% elseif is_upload %} + {{ get_browse_upload_file_block(max_upload_size) }} + <p>{% trans 'You may also drag and drop a file on any page.' %}</p> + {% elseif not is_upload %} + {{ 'File uploads are not allowed on this server.'|trans|notice }} + {% elseif upload_dir is not empty %} + {{ get_select_upload_file_block( + import_list, + upload_dir + ) }} + {% endif %} + </div> + + <div class="formelementrow" id="charaset_of_file"> + {# Charset of file #} + <label for="charset_of_file">{% trans 'Character set of the file:' %}</label> + {% if is_encoding_supported %} + <select id="charset_of_file" name="charset_of_file" size="1"> + {% for charset in encodings %} + <option value="{{ charset }}" + {% if (import_charset is empty and charset == 'utf-8') + or charset == import_charset %} + selected="selected" + {% endif %}> + {{ charset }} + </option> + {% endfor %} + </select> + {% else %} + <select lang="en" dir="ltr" name="charset_of_file" id="charset_of_file"> + <option value=""></option> + {% for charset in charsets %} + <option value="{{ charset.name }}" title="{{ charset.description }}" + {{- charset.name == 'utf8' ? ' selected' }}> + {{- charset.name -}} + </option> + {% endfor %} + </select> + {% endif %} + </div> + </div> + + <div class="importoptions"> + <h3>{% trans 'Partial import:' %}</h3> + + {% if timeout_passed is defined and timeout_passed %} + <div class="formelementrow"> + <input type="hidden" name="skip" value="{{ offset }}"> + {{ 'Previous import timed out, after resubmitting will continue from position %d.'|trans|format(offset) }} + </div> + {% endif %} + + <div class="formelementrow"> + <input type="checkbox" name="allow_interrupt" value="yes" id="checkbox_allow_interrupt" + {{ checkbox_check('Import', 'allow_interrupt') }}> + <label for="checkbox_allow_interrupt"> + {% trans 'Allow the interruption of an import in case the script detects it is close to the PHP timeout limit. <em>(This might be a good way to import large files, however it can break transactions.)</em>' %} + </label> + </div> + + {% if not (timeout_passed is defined and timeout_passed) %} + <div class="formelementrow"> + <label for="text_skip_queries"> + {% trans 'Skip this number of queries (for SQL) starting from the first one:' %} + </label> + <input type="number" name="skip_queries" value=" + {{- get_default_plugin('Import', 'skip_queries') -}} + " id="text_skip_queries" min="0"> + </div> + {% else %} + {# If timeout has passed, + do not show the Skip dialog to avoid the risk of someone + entering a value here that would interfere with "skip" #} + <input type="hidden" name="skip_queries" value=" + {{- get_default_plugin('Import', 'skip_queries') -}} + " id="text_skip_queries"> + {% endif %} + </div> + + <div class="importoptions"> + <h3>{% trans 'Other options:' %}</h3> + <div class="formelementrow"> + {{ get_fk_checkbox() }} + </div> + </div> + + <div class="importoptions"> + <h3>{% trans 'Format:' %}</h3> + {{ get_choice('Import', 'format', import_list) }} + <div id="import_notification"></div> + </div> + + <div class="importoptions" id="format_specific_opts"> + <h3>{% trans 'Format-specific options:' %}</h3> + <p class="no_js_msg" id="scroll_to_options_msg"> + {% trans 'Scroll down to fill in the options for the selected format and ignore the options for other formats.' %} + </p> + {{ get_options('Import', import_list) }} + </div> + <div class="clearfloat"></div> + + {# Japanese encoding setting #} + {% if can_convert_kanji %} + <div class="importoptions" id="kanji_encoding"> + <h3>{% trans 'Encoding Conversion:' %}</h3> + {% include 'encoding/kanji_encoding_form.twig' %} + </div> + {% endif %} + + <div class="importoptions" id="submit"> + <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </div> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/display/import/javascript.twig b/srcs/phpmyadmin/templates/display/import/javascript.twig new file mode 100644 index 0000000..ec91e3c --- /dev/null +++ b/srcs/phpmyadmin/templates/display/import/javascript.twig @@ -0,0 +1,162 @@ +$( function() { + {# Add event when user click on "Go" button #} + $("#buttonGo").on("click", function() { + {# Hide form #} + $("#upload_form_form").css("display", "none"); + + {% if handler != 'PhpMyAdmin\\Plugins\\Import\\Upload\\UploadNoplugin' %} + {# Some variable for javascript #} + {% set ajax_url = 'import_status.php?id=' ~ upload_id ~ get_common_raw({ + 'import_status': 1 + }, '&') %} + {% set promot_str = 'The file being uploaded is probably larger than the maximum allowed size or this is a known bug in webkit based (Safari, Google Chrome, Arora etc.) browsers.'|trans|js_format(false) %} + {% set statustext_str = '%s of %s'|trans|escape_js_string %} + {% set second_str = '%s/sec.'|trans|js_format(false) %} + {% set remaining_min = 'About %MIN min. %SEC sec. remaining.'|trans|js_format(false) %} + {% set remaining_second = 'About %SEC sec. remaining.'|trans|js_format(false) %} + {% set processed_str = 'The file is being processed, please be patient.'|trans|js_format(false) %} + {% set import_url = get_common_raw({'import_status': 1}, '&') %} + + {% set upload_html %} + {% apply spaceless %} + <div class="upload_progress"> + <div class="upload_progress_bar_outer"> + <div class="percentage"></div> + <div id="status" class="upload_progress_bar_inner"> + <div class="percentage"></div> + </div> + </div> + <div> + <img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ 'Uploading your import file…'|trans|js_format(false) -}} + </div> + <div id="statustext"></div> + </div> + {% endapply %} + {% endset %} + + {# Start output #} + var finished = false; + var percent = 0.0; + var total = 0; + var complete = 0; + var original_title = parent && parent.document ? parent.document.title : false; + var import_start; + + var perform_upload = function () { + new $.getJSON( + "{{ ajax_url|raw }}", + {}, + function(response) { + finished = response.finished; + percent = response.percent; + total = response.total; + complete = response.complete; + + if (total==0 && complete==0 && percent==0) { + $("#upload_form_status_info").html('<img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ promot_str|raw }}'); + $("#upload_form_status").css("display", "none"); + } else { + var now = new Date(); + now = Date.UTC( + now.getFullYear(), + now.getMonth(), + now.getDate(), + now.getHours(), + now.getMinutes(), + now.getSeconds()) + + now.getMilliseconds() - 1000; + var statustext = Functions.sprintf( + "{{ statustext_str|raw }}", + Functions.formatBytes( + complete, 1, Messages.strDecimalSeparator + ), + Functions.formatBytes( + total, 1, Messages.strDecimalSeparator + ) + ); + + if ($("#importmain").is(":visible")) { + {# Show progress UI #} + $("#importmain").hide(); + $("#import_form_status") + .html('{{ upload_html|raw }}') + .show(); + import_start = now; + } + else if (percent > 9 || complete > 2000000) { + {# Calculate estimated time #} + var used_time = now - import_start; + var seconds = parseInt(((total - complete) / complete) * used_time / 1000); + var speed = Functions.sprintf( + "{{ second_str|raw }}", + Functions.formatBytes(complete / used_time * 1000, 1, Messages.strDecimalSeparator) + ); + + var minutes = parseInt(seconds / 60); + seconds %= 60; + var estimated_time; + if (minutes > 0) { + estimated_time = "{{ remaining_min|raw }}" + .replace("%MIN", minutes) + .replace("%SEC", seconds); + } + else { + estimated_time = "{{ remaining_second|raw }}" + .replace("%SEC", seconds); + } + + statustext += "<br>" + speed + "<br><br>" + estimated_time; + } + + var percent_str = Math.round(percent) + "%"; + $("#status").animate({width: percent_str}, 150); + $(".percentage").text(percent_str); + + {# Show percent in window title #} + if (original_title !== false) { + parent.document.title + = percent_str + " - " + original_title; + } + else { + document.title + = percent_str + " - " + original_title; + } + $("#statustext").html(statustext); + } + + if (finished == true) { + if (original_title !== false) { + parent.document.title = original_title; + } + else { + document.title = original_title; + } + $("#importmain").hide(); + {# Loads the message, either success or mysql error #} + $("#import_form_status") + .html('<img src="{{ pma_theme_image }}ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> {{ processed_str|raw }}') + .show(); + $("#import_form_status").load("import_status.php?message=true&{{ import_url|raw }}"); + Navigation.reload(); + + {# If finished #} + } + else { + setTimeout(perform_upload, 1000); + } + }); + }; + setTimeout(perform_upload, 1000); + {% else %} + {# No plugin available #} + {% set image_tag -%} + <img src="{{ pma_theme_image -}} + ajax_clock_small.gif" width="16" height="16" alt="ajax clock"> + {{- 'Please be patient, the file is being uploaded. Details about the upload are not available.'|trans|js_format(false) -}} + {{- show_docu('faq', 'faq2-9') -}} + {%- endset %} + $('#upload_form_status_info').html('{{ image_tag|raw }}'); + $("#upload_form_status").css("display", "none"); + {% endif %} + }); +}); diff --git a/srcs/phpmyadmin/templates/display/results/comment_for_row.twig b/srcs/phpmyadmin/templates/display/results/comment_for_row.twig new file mode 100644 index 0000000..f232375 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/comment_for_row.twig @@ -0,0 +1,10 @@ +{% if comments_map[fields_meta.table] is defined + and comments_map[fields_meta.table][fields_meta.name] is defined %} + <br><span class="tblcomment" title="{{ comments_map[fields_meta.table][fields_meta.name] }}"> + {% if comments_map[fields_meta.table][fields_meta.name]|length > limit_chars %} + {{ comments_map[fields_meta.table][fields_meta.name]|slice(0, limit_chars) }}… + {% else %} + {{ comments_map[fields_meta.table][fields_meta.name] }} + {% endif %} + </span> +{% endif %} diff --git a/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig b/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig new file mode 100644 index 0000000..6a345e7 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/data_for_resetting_column_order.twig @@ -0,0 +1,9 @@ +{% if column_order %} + <input class="col_order" type="hidden" value="{{ column_order|join(',') }}"> +{% endif %} +{% if column_visibility %} + <input class="col_visib" type="hidden" value="{{ column_visibility|join(',') }}"> +{% endif %} +{% if not is_view %} + <input class="table_create_time" type="hidden" value="{{ table_create_time }}"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/display/results/empty_display.twig b/srcs/phpmyadmin/templates/display/results/empty_display.twig new file mode 100644 index 0000000..cd43ebc --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/empty_display.twig @@ -0,0 +1 @@ +<td {{ align }} class="{{ classes }}"></td> diff --git a/srcs/phpmyadmin/templates/display/results/null_display.twig b/srcs/phpmyadmin/templates/display/results/null_display.twig new file mode 100644 index 0000000..f2ea2e5 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/null_display.twig @@ -0,0 +1,7 @@ +<td {{ align }} + data-decimals="{{ meta.decimals is defined ? meta.decimals : '-1' }}" + data-type="{{ meta.type }}" + {# The null class is needed for grid editing #} + class="{{ classes }} null"> + <em>NULL</em> +</td> diff --git a/srcs/phpmyadmin/templates/display/results/options_block.twig b/srcs/phpmyadmin/templates/display/results/options_block.twig new file mode 100644 index 0000000..d185fec --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/options_block.twig @@ -0,0 +1,121 @@ +<form method="post" action="sql.php" name="displayOptionsForm" class="ajax print_ignore"> + {{ get_hidden_inputs({ + 'db': db, + 'table': table, + 'sql_query': sql_query, + 'goto': goto, + 'display_options_form': 1 + }) }} + + {% include 'div_for_slider_effect.twig' with { + 'id': '', + 'message': 'Options'|trans, + 'initial_sliders_state': default_sliders_state + } only %} + <fieldset> + <div class="formelement"> + {# pftext means "partial or full texts" (done to reduce line lengths #} + {{ get_radio_fields( + 'pftext', + { + 'P': 'Partial texts'|trans, + 'F': 'Full texts'|trans + }, + pftext, + true, + true, + '', + 'pftext_' ~ unique_id + ) }} + </div> + + {% if relwork and displaywork %} + <div class="formelement"> + {{ get_radio_fields( + 'relational_display', + { + 'K': 'Relational key'|trans, + 'D': 'Display column for relationships'|trans + }, + relational_display, + true, + true, + '', + 'relational_display_' ~ unique_id + ) }} + </div> + {% endif %} + + <div class="formelement"> + {% include 'checkbox.twig' with { + 'html_field_name': 'display_binary', + 'label': 'Show binary contents'|trans, + 'checked': display_binary is not empty, + 'onclick': false, + 'html_field_id': 'display_binary_' ~ unique_id + } only %} + {% include 'checkbox.twig' with { + 'html_field_name': 'display_blob', + 'label': 'Show BLOB contents'|trans, + 'checked': display_blob is not empty, + 'onclick': false, + 'html_field_id': 'display_blob_' ~ unique_id + } only %} + </div> + + {# I would have preferred to name this "display_transformation". + This is the only way I found to be able to keep this setting sticky + per SQL query, and at the same time have a default that displays + the transformations. #} + <div class="formelement"> + {% include 'checkbox.twig' with { + 'html_field_name': 'hide_transformation', + 'label': 'Hide browser transformation'|trans, + 'checked': hide_transformation is not empty, + 'onclick': false, + 'html_field_id': 'hide_transformation_' ~ unique_id + } only %} + </div> + + + {% if possible_as_geometry %} + <div class="formelement"> + {{ get_radio_fields( + 'geoOption', + { + 'GEOM': 'Geometry'|trans, + 'WKT': 'Well Known Text'|trans, + 'WKB': 'Well Known Binary'|trans + }, + geo_option, + true, + true, + '', + 'geoOption_' ~ unique_id + ) }} + </div> + {% else %} + <div class="formelement"> + {{ possible_as_geometry }} + {{ get_radio_fields( + 'geoOption', + { + 'WKT': 'Well Known Text'|trans, + 'WKB': 'Well Known Binary'|trans + }, + geo_option, + true, + true, + '', + 'geoOption_' ~ unique_id + ) }} + </div> + {% endif %} + <div class="clearfloat"></div> + </fieldset> + + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </fieldset> + </div>{# slider effect div #} +</form> diff --git a/srcs/phpmyadmin/templates/display/results/page_selector.twig b/srcs/phpmyadmin/templates/display/results/page_selector.twig new file mode 100644 index 0000000..1791270 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/page_selector.twig @@ -0,0 +1,6 @@ +<td> + <form action="sql.php" method="post"> + {{ get_hidden_inputs(url_params) }} + {{ page_selector|raw }} + </form> +</td> diff --git a/srcs/phpmyadmin/templates/display/results/sort_by_key.twig b/srcs/phpmyadmin/templates/display/results/sort_by_key.twig new file mode 100644 index 0000000..fb26f10 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/sort_by_key.twig @@ -0,0 +1,9 @@ +<form action="sql.php" method="post" class="print_ignore"> + {{ get_hidden_fields(hidden_fields) }} + {% trans 'Sort by key:' %} + <select name="sql_query" class="autosubmit"> + {% for option in options %} + <option value="{{ option.value }}"{{ option.is_selected ? ' selected' }}>{{ option.content }}</option> + {% endfor %} + </select> +</form> diff --git a/srcs/phpmyadmin/templates/display/results/table.twig b/srcs/phpmyadmin/templates/display/results/table.twig new file mode 100644 index 0000000..760ca1c --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/table.twig @@ -0,0 +1,11 @@ +{{ sql_query_message|raw }} +{{ navigation|raw }} +{{ headers|raw }} +<tbody> + {{ body|raw }} +</tbody> +</table> +</div> +{{ multi_row_operation_links|raw }} +{{ navigation|raw }} +{{ operations|raw }} diff --git a/srcs/phpmyadmin/templates/display/results/table_headers.twig b/srcs/phpmyadmin/templates/display/results/table_headers.twig new file mode 100644 index 0000000..506a6c0 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/table_headers.twig @@ -0,0 +1,23 @@ +<input class="save_cells_at_once" type="hidden" value="{{ save_cells_at_once }}"> +<div class="common_hidden_inputs"> + {{ get_hidden_inputs(db, table) }} +</div> + +{{ data_for_resetting_column_order|raw }} +{{ options_block|raw }} + +{% if delete_link == delete_row or delete_link == kill_process %} + <form method="post" action="tbl_row_action.php" name="resultsForm" id="resultsForm_{{ unique_id }}" class="ajax"> + {{ get_hidden_inputs(db, table, 1) }} + <input type="hidden" name="goto" value="sql.php"> +{% endif %} + +<div class="responsivetable"> + <table class="table_results data ajax" data-uniqueId="{{ unique_id }}"> + + {{ button|raw }} + {{ table_headers_for_columns|raw }} + {{ column_at_right_side|raw }} + + </tr> + </thead> diff --git a/srcs/phpmyadmin/templates/display/results/table_navigation.twig b/srcs/phpmyadmin/templates/display/results/table_navigation.twig new file mode 100644 index 0000000..0746243 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/table_navigation.twig @@ -0,0 +1,82 @@ +<table class="navigation nospacing nopadding print_ignore"> + <tr> + <td class="navigation_separator"></td> + {{ move_backward_buttons|raw }} + {{ page_selector|raw }} + {{ move_forward_buttons|raw }} + {% if number_total_page > 1 %} + <td><div class="navigation_separator">|</div></td> + {% endif %} + {% if has_show_all %} + <td> + <form action="sql.php" method="post"> + {{ get_hidden_fields(hidden_fields|merge({ + 'session_max_rows': session_max_rows, + 'pos': '0' + })) }} + <input type="checkbox" name="navig" id="showAll_{{ unique_id }}" class="showAllRows" value="all" + {{- is_showing_all ? ' checked' }}> + <label for="showAll_{{ unique_id }}">{% trans 'Show all' %}</label> + </form> + </td> + <td><div class="navigation_separator">|</div></td> + {% endif %} + <td> + <div class="save_edited hide"> + <input class="btn btn-link" type="submit" value="{% trans 'Save edited data' %}"> + <div class="navigation_separator">|</div> + </div> + </td> + <td> + <div class="restore_column hide"> + <input class="btn btn-link" type="submit" value="{% trans 'Restore column order' %}"> + <div class="navigation_separator">|</div> + </div> + </td> + <td class="navigation_goto"> + {# if displaying a VIEW, $unlim_num_rows could be zero because #} + {# of $cfg['MaxExactCountViews']; in this case, avoid passing #} + {# the 5th parameter to Functions.checkFormElementInRange() #} + {# (this means we can't validate the upper limit) #} + <form action="sql.php" method="post" onsubmit="return (Functions.checkFormElementInRange(this, 'session_max_rows', ' + {{- '%d is not valid row number.'|trans|replace({'\'': '\\\''}) -}} + ', 1) && Functions.checkFormElementInRange(this, 'pos', ' + {{- '%d is not valid row number.'|trans|replace({'\'': '\\\''}) -}} + ', 0 + {{- unlim_num_rows > 0 ? ', ' ~ (unlim_num_rows - 1) -}} + ));"> + + {{ get_hidden_fields(hidden_fields|merge({ + 'pos': pos + })) }} + + {% trans 'Number of rows:' %} + + {{ get_dropdown( + 'session_max_rows', + { + '25': 25, + '50': 50, + '100': 100, + '250': 250, + '500': 500, + }, + max_rows, + '', + 'autosubmit', + is_showing_all ? 'All'|trans + ) }} + </form> + </td> + <td class="navigation_separator"></td> + <td class="largescreenonly"> + <span>{% trans 'Filter rows' %}:</span> + <input type="text" class="filter_rows" placeholder=" + {%- trans 'Search this table' %}" data-for="{{ unique_id }}"> + </td> + <td class="largescreenonly"> + {{ sort_by_key|raw }} + </td> + <td class="navigation_separator"></td> + </tr> +</table> diff --git a/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig b/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig new file mode 100644 index 0000000..2573c0c --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/table_navigation_button.twig @@ -0,0 +1,12 @@ +<td> + <form action="sql.php" method="post"{{ onsubmit|raw }}> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="sql_query" value="{{ sql_query|raw }}"> + <input type="hidden" name="pos" value="{{ pos }}"> + <input type="hidden" name="is_browse_distinct" value="{{ is_browse_distinct }}"> + <input type="hidden" name="goto" value="{{ goto }}"> + {{ input_for_real_end|raw }} + <input type="submit" name="navig" class="btn btn-secondary ajax" value="{{ caption_output|raw }}" title="{{ title }}" + {{- onclick|raw }}> + </form> +</td> diff --git a/srcs/phpmyadmin/templates/display/results/value_display.twig b/srcs/phpmyadmin/templates/display/results/value_display.twig new file mode 100644 index 0000000..35640b9 --- /dev/null +++ b/srcs/phpmyadmin/templates/display/results/value_display.twig @@ -0,0 +1,3 @@ +<td class="left {{ class }}{{ condition_field ? ' condition' }}"> + {{ value|raw }} +</td> diff --git a/srcs/phpmyadmin/templates/div_for_slider_effect.twig b/srcs/phpmyadmin/templates/div_for_slider_effect.twig new file mode 100644 index 0000000..6453999 --- /dev/null +++ b/srcs/phpmyadmin/templates/div_for_slider_effect.twig @@ -0,0 +1,16 @@ +{% if initial_sliders_state == 'disabled' %} + <div{% if id is defined %} id="{{ id }}"{% endif %}> +{% else %} + {# + Bad hack on the next line. document.write() conflicts with jQuery, + hence, opening the <div> with PHP itself instead of JavaScript. + + @todo find a better solution that uses $.append(), the recommended + method maybe by using an additional param, the id of the div to + append to + #} + <div{% if id is defined %} id="{{ id }}" + {%- endif %} {% if initial_sliders_state == 'closed' -%} + style="display: none; overflow:auto;"{% endif %} class="pma_auto_slider" + {%- if message is defined %} title="{{ message }}"{% endif %}> +{% endif %} diff --git a/srcs/phpmyadmin/templates/dropdown.twig b/srcs/phpmyadmin/templates/dropdown.twig new file mode 100644 index 0000000..6258ca7 --- /dev/null +++ b/srcs/phpmyadmin/templates/dropdown.twig @@ -0,0 +1,11 @@ +<select name="{{ select_name }}"{% if id is not empty %} id="{{ id }}"{% endif -%} + {%- if class is not empty %} class="{{ class }}"{% endif %}> +{% if placeholder is not empty %} + <option value="" disabled="disabled" + {%- if not selected %} selected="selected"{% endif %}>{{ placeholder }}</option> +{% endif %} +{% for option in result_options %} +<option value="{{ option['value'] }}" + {{- option['selected'] ? ' selected="selected"' }}>{{ option['label'] }}</option> +{% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig b/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig new file mode 100644 index 0000000..cbff62f --- /dev/null +++ b/srcs/phpmyadmin/templates/encoding/kanji_encoding_form.twig @@ -0,0 +1,20 @@ +<ul> + <li> + <input type="radio" name="knjenc" value="" checked="checked" id="kj-none"> + <label for="kj-none"> + {# l10n: This is currently used only in Japanese locales #} + {% trans %}None{% context %}None encoding conversion{% endtrans %} + </label> + <input type="radio" name="knjenc" value="EUC-JP" id="kj-euc"> + <label for="kj-euc">EUC</label> + <input type="radio" name="knjenc" value="SJIS" id="kj-sjis"> + <label for="kj-sjis">SJIS</label> + </li> + <li> + <input type="checkbox" name="xkana" value="kana" id="kj-kana"> + <label for="kj-kana"> + {# l10n: This is currently used only in Japanese locales #} + {% trans 'Convert to Kana' %} + </label> + </li> +</ul> diff --git a/srcs/phpmyadmin/templates/error/generic.twig b/srcs/phpmyadmin/templates/error/generic.twig new file mode 100644 index 0000000..a47bce6 --- /dev/null +++ b/srcs/phpmyadmin/templates/error/generic.twig @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html lang="{{ lang }}" dir="{{ dir }}"> +<head> + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + <title>phpMyAdmin</title> + <meta charset="utf-8"> + <style type="text/css"> + html { + padding: 0; + margin: 0; + } + body { + font-family: sans-serif; + font-size: small; + color: #000000; + background-color: #F5F5F5; + margin: 1em; + } + h1 { + margin: 0; + padding: 0.3em; + font-size: 1.4em; + font-weight: bold; + color: #ffffff; + background-color: #ff0000; + } + p { + margin: 0; + padding: 0.5em; + border: 0.1em solid red; + background-color: #ffeeee; + } + </style> +</head> +<body> +<h1>phpMyAdmin - {{ error_header }}</h1> +<p>{{ error_message|raw }}</p> +</body> +</html> diff --git a/srcs/phpmyadmin/templates/error/report_form.twig b/srcs/phpmyadmin/templates/error/report_form.twig new file mode 100644 index 0000000..c45d740 --- /dev/null +++ b/srcs/phpmyadmin/templates/error/report_form.twig @@ -0,0 +1,32 @@ +<form action="error_report.php" method="post" name="report_frm" id="report_frm" + class="ajax"> + <fieldset style="padding-top:0"> + + <p> + {% trans %} + This report automatically includes data about the error and information about relevant configuration settings. It will be sent to the phpMyAdmin team for debugging the error. + {% endtrans %} + </p> + + <div class="label"><label><strong> + {% trans "Can you tell us the steps leading to this error? It decisively helps in debugging:" %} + </strong></label> + </div> + <textarea class="report-description" name="description" + id="report_description"></textarea> + + <div class="label"><label><p> + {% trans "You may examine the data in the error report:" %} + </p></label></div> + <pre class="report-data">{{ report_data|raw }}</pre> + + <input type="checkbox" name="always_send" id="always_send_checkbox"> + <label for="always_send_checkbox"> + {% trans "Automatically send report next time" %} + </label> + + </fieldset> + + {{ hidden_inputs|raw }} + {{ hidden_fields|raw }} +</form> diff --git a/srcs/phpmyadmin/templates/export/alias_add.twig b/srcs/phpmyadmin/templates/export/alias_add.twig new file mode 100644 index 0000000..479e523 --- /dev/null +++ b/srcs/phpmyadmin/templates/export/alias_add.twig @@ -0,0 +1,49 @@ +<table> + <thead> + <tr> + <th colspan="4">{% trans 'Define new aliases' %}</th> + </tr> + </thead> + <tr> + <td> + <label>{% trans 'Select database:' %}</label> + </td> + <td> + <select id="db_alias_select"><option value=""></option></select> + </td> + <td> + <input id="db_alias_name" placeholder="{% trans 'New database name' %}" disabled="1"> + </td> + <td> + <button id="db_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button> + </td> + </tr> + <tr> + <td> + <label>{% trans 'Select table:' %}</label> + </td> + <td> + <select id="table_alias_select"><option value=""></option></select> + </td> + <td> + <input id="table_alias_name" placeholder="{% trans 'New table name' %}" disabled="1"> + </td> + <td> + <button id="table_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button> + </td> + </tr> + <tr> + <td> + <label>{% trans 'Select column:' %}</label> + </td> + <td> + <select id="column_alias_select"><option value=""></option></select> + </td> + <td> + <input id="column_alias_name" placeholder="{% trans 'New column name' %}" disabled="1"> + </td> + <td> + <button id="column_alias_button" class="btn btn-secondary" disabled="1">{% trans 'Add' %}</button> + </td> + </tr> +</table> diff --git a/srcs/phpmyadmin/templates/export/alias_item.twig b/srcs/phpmyadmin/templates/export/alias_item.twig new file mode 100644 index 0000000..3b2ce85 --- /dev/null +++ b/srcs/phpmyadmin/templates/export/alias_item.twig @@ -0,0 +1,10 @@ +<tr> + <th>{{ type }}</th> + <td>{{ name }}</td> + <td> + <input name="{{ field }}" value="{{ value }}" type="text"> + </td> + <td> + <button class="alias_remove btn btn-secondary">{% trans 'Remove' %}</button> + </td> +</tr> diff --git a/srcs/phpmyadmin/templates/filter.twig b/srcs/phpmyadmin/templates/filter.twig new file mode 100644 index 0000000..eee8850 --- /dev/null +++ b/srcs/phpmyadmin/templates/filter.twig @@ -0,0 +1,8 @@ +<fieldset id="tableFilter"> + <legend>{% trans "Filters" %}</legend> + <div class="formelement"> + <label for="filterText">{% trans "Containing the word:" %}</label> + <input name="filterText" type="text" id="filterText" + value="{{ filter_value }}"> + </div> +</fieldset> diff --git a/srcs/phpmyadmin/templates/fk_checkbox.twig b/srcs/phpmyadmin/templates/fk_checkbox.twig new file mode 100644 index 0000000..afcc615 --- /dev/null +++ b/srcs/phpmyadmin/templates/fk_checkbox.twig @@ -0,0 +1,4 @@ +<input type="hidden" name="fk_checks" value="0"> +<input type="checkbox" name="fk_checks" id="fk_checks" value="1" + {{- checked ? ' checked' }}> +<label for="fk_checks">{% trans 'Enable foreign key checks' %}</label> diff --git a/srcs/phpmyadmin/templates/footer.twig b/srcs/phpmyadmin/templates/footer.twig new file mode 100644 index 0000000..8939308 --- /dev/null +++ b/srcs/phpmyadmin/templates/footer.twig @@ -0,0 +1,24 @@ +{% if not is_ajax %} + </div> +{% endif %} +{% if not is_ajax and not is_minimal %} + {{ self_link|raw }} + + <div class="clearfloat" id="pma_errors"> + {{ error_messages|raw }} + </div> + + {{ scripts|raw }} + + {% if is_demo %} + <div id="pma_demo"> + {{ demo_message|raw }} + </div> + {% endif %} + + {{ footer|raw }} +{% endif %} +{% if not is_ajax %} + </body> +</html> +{% endif %} diff --git a/srcs/phpmyadmin/templates/gis_data_editor_form.twig b/srcs/phpmyadmin/templates/gis_data_editor_form.twig new file mode 100644 index 0000000..412561a --- /dev/null +++ b/srcs/phpmyadmin/templates/gis_data_editor_form.twig @@ -0,0 +1,221 @@ +<form id="gis_data_editor_form" action="gis_data_editor.php" method="post"> + <input type="hidden" id="pmaThemeImage" value="{{ pma_theme_image }}"> + <div id="gis_data_editor"> + <h3>{{ 'Value for the column "%s"'|trans|format(field) }}</h3> + + <input type="hidden" name="field" value="{{ field }}"> + {# The input field to which the final result should be added and corresponding null checkbox #} + {% if input_name is not null %} + <input type="hidden" name="input_name" value="{{ input_name }}"> + {% endif %} + {{ get_hidden_inputs() }} + + {# Visualization section #} + <div id="placeholder"{{ srid != 0 ? ' class="hide"' }}> + {{ visualization|raw }} + </div> + + <div id="openlayersmap" style="width: {{width}}px; height: {{height}}px;"{{ srid == 0 ? ' class="hide"' }}></div> + + <div class="choice floatright"> + <input type="checkbox" id="choice" value="useBaseLayer"{{ srid != 0 ? ' checked="checked"' }}> + <label for="choice">{% trans "Use OpenStreetMaps as Base Layer" %}</label> + </div> + + <script language="javascript" type="text/javascript">{{ open_layers|raw }}</script> + {# End of visualization section #} + + {# Header section - Inclueds GIS type selector and input field for SRID #} + <div id="gis_data_header"> + <select name="gis_data[gis_type]" class="gis_type"> + {% for gis_type in gis_types %} + <option value="{{ gis_type }}"{{ geom_type == gis_type ? ' selected="selected"' }}> + {{ gis_type }} + </option> + {% endfor %} + </select> + + <label for="srid">{% trans %}SRID:{% context %}Spatial Reference System Identifier{% endtrans %}</label> + <input name="gis_data[srid]" type="text" value="{{ srid }}"> + </div> + {# End of header section #} + + {# Data section #} + <div id="gis_data"> + {% if geom_type == 'GEOMETRYCOLLECTION' %} + <input type="hidden" name="gis_data[GEOMETRYCOLLECTION][geom_count]" value="{{ geom_count }}"> + {% endif %} + + {% for a in 0..geom_count - 1 %} + {% if gis_data[a] is not null %} + {% if geom_type == 'GEOMETRYCOLLECTION' %} + <br><br> + {{ 'Geometry %d:'|trans|format(a + 1) }} + <br> + {% if gis_data[a]['gis_type'] is not null %} + {% set type = gis_data[a]['gis_type'] %} + {% else %} + {% set type = gis_types[0] %} + {% endif %} + <select name="gis_data[{{ a }}][gis_type]" class="gis_type"> + {% for gis_type in gis_types|slice(0, 6) %} + <option value="{{ gis_type }}"{{ type == gis_type ? ' selected="selected"' }}> + {{ gis_type }} + </option> + {% endfor %} + </select> + {% else %} + {% set type = geom_type %} + {% endif %} + + {% if type == 'POINT' %} + <br> + {% trans 'Point:' %} + <label for="x">{% trans 'X' %}</label> + <input name="gis_data[{{ a }}][POINT][x]" type="text" value="{{ gis_data[a]['POINT']['x'] }}"> + <label for="y">{% trans 'Y' %}</label> + <input name="gis_data[{{ a }}][POINT][y]" type="text" value="{{ gis_data[a]['POINT']['y'] }}"> + {% elseif type == 'MULTIPOINT' or type == 'LINESTRING' %} + {% set no_of_points = gis_data[a][type]['no_of_points'] ?? 1 %} + {% if type == 'LINESTRING' and no_of_points < 2 %} + {% set no_of_points = 2 %} + {% endif %} + {% if type == 'MULTIPOINT' and no_of_points < 1 %} + {% set no_of_points = 1 %} + {% endif %} + {% if gis_data[a][type]['add_point'] is not null %} + {% set no_of_points = no_of_points + 1 %} + {% endif %} + <input type="hidden" value="{{ no_of_points }}" name="gis_data[{{ a }}][{{ type }}][no_of_points]"> + + {% for i in 0..no_of_points - 1 %} + <br> + {{ 'Point %d:'|trans|format(i + 1) }} + <label for="x">{% trans 'X' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][x]" value="{{ gis_data[a][type][i]['x'] }}"> + <label for="y">{% trans 'Y' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][y]" value="{{ gis_data[a][type][i]['y'] }}"> + {% endfor %} + <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}"> + {% elseif type == 'MULTILINESTRING' or type == 'POLYGON' %} + {% set no_of_lines = gis_data[a][type]['no_of_lines'] ?? 1 %} + {% if no_of_lines < 1 %} + {% set no_of_lines = 1 %} + {% endif %} + {% if gis_data[a][type]['add_line'] is not null %} + {% set no_of_lines = no_of_lines + 1 %} + {% endif %} + <input type="hidden" value="{{ no_of_lines }}" name="gis_data[{{ a }}][{{ type }}][no_of_lines]"> + + {% for i in 0..no_of_lines - 1 %} + <br> + {% if type == 'MULTILINESTRING' %} + {{ 'Linestring %d:'|trans|format(i + 1) }} + {% elseif i == 0 %} + {% trans 'Outer ring:' %} + {% else %} + {{ 'Inner ring %d:'|trans|format(i) }} + {% endif %} + + {% set no_of_points = gis_data[a][type][i]['no_of_points'] ?? 2 %} + {% if type == 'MULTILINESTRING' and no_of_points < 2 %} + {% set no_of_points = 2 %} + {% endif %} + {% if type == 'POLYGON' and no_of_points < 4 %} + {% set no_of_points = 4 %} + {% endif %} + {% if gis_data[a][type][i]['add_point'] is not null %} + {% set no_of_points = no_of_points + 1 %} + {% endif %} + <input type="hidden" value="{{ no_of_points }}" name="gis_data[{{ a }}][{{ type }}][{{ i }}][no_of_points]"> + + {% for j in 0..no_of_points - 1 %} + <br> + {{ 'Point %d:'|trans|format(j + 1) }} + <label for="x">{% trans 'X' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][{{ j }}][x]" value="{{ gis_data[a][type][i][j]['x'] }}"> + <label for="y">{% trans 'Y' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ i }}][{{ j }}][y]" value="{{ gis_data[a][type][i][j]['y'] }}"> + {% endfor %} + <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ i }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}"> + {% endfor %} + <br> + <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_line]" class="btn btn-secondary add addLine" value=" + {{- type == 'MULTILINESTRING' ? 'Add a linestring'|trans : 'Add an inner ring'|trans }}"> + {% elseif type == 'MULTIPOLYGON' %} + {% set no_of_polygons = gis_data[a][type]['no_of_polygons'] ?? 1 %} + {% if no_of_polygons < 1 %} + {% set no_of_polygons = 1 %} + {% endif %} + {% if gis_data[a][type]['add_polygon'] is not null %} + {% set no_of_polygons = no_of_polygons + 1 %} + {% endif %} + <input type="hidden" name="gis_data[{{ a }}][{{ type }}][no_of_polygons]" value="{{ no_of_polygons }}"> + + {% for k in 0..no_of_polygons - 1 %} + <br> + {{ 'Polygon %d:'|trans|format(k + 1) }} + {% set no_of_lines = gis_data[a][type][k]['no_of_lines'] ?? 1 %} + {% if no_of_lines < 1 %} + {% set no_of_lines = 1 %} + {% endif %} + {% if gis_data[a][type][k]['add_line'] is not null %} + {% set no_of_lines = no_of_lines + 1 %} + {% endif %} + <input type="hidden" name="gis_data[{{ a }}][{{ type }}][{{ k }}][no_of_lines]" value="{{ no_of_lines }}"> + + {% for i in 0..no_of_lines - 1 %} + <br><br> + {% if i == 0 %} + {% trans 'Outer ring:' %} + {% else %} + {{ 'Inner ring %d:'|trans|format(i) }} + {% endif %} + + {% set no_of_points = gis_data[a][type][k][i]['no_of_points'] ?? 4 %} + {% if no_of_points < 4 %} + {% set no_of_points = 4 %} + {% endif %} + {% if gis_data[a][type][k][i]['add_point'] is not null %} + {% set no_of_points = no_of_points + 1 %} + {% endif %} + <input type="hidden" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][no_of_points]" value="{{ no_of_points }}"> + + {% for j in 0..no_of_points - 1 %} + <br> + {{ 'Point %d:'|trans|format(j + 1) }} + <label for="x">{% trans 'X' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][{{ j }}][x]" value="{{ gis_data[a][type][k][i][j]['x'] }}"> + <label for="y">{% trans 'Y' %}</label> + <input type="text" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][{{ j }}][y]" value="{{ gis_data[a][type][k][i][j]['y'] }}"> + {% endfor %} + <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ k }}][{{ i }}][add_point]" class="btn btn-secondary add addPoint" value="{% trans 'Add a point' %}"> + {% endfor %} + <br> + <input type="submit" name="gis_data[{{ a }}][{{ type }}][{{ k }}][add_line]" class="btn btn-secondary add addLine" value="{% trans 'Add an inner ring' %}"> + <br> + {% endfor %} + <br> + <input type="submit" name="gis_data[{{ a }}][{{ type }}][add_polygon]" class="btn btn-secondary add addPolygon" value="{% trans 'Add a polygon' %}"> + {% endif %} + {% endif %} + {% endfor %} + {% if geom_type == 'GEOMETRYCOLLECTION' %} + <br><br> + <input type="submit" name="gis_data[GEOMETRYCOLLECTION][add_geom]" class="btn btn-secondary add addGeom" value="{% trans 'Add geometry' %}"> + {% endif %} + </div> + {# End of data section #} + + <br> + <input class="btn btn-primary" type="submit" name="gis_data[save]" value="{% trans 'Go' %}"> + + <div id="gis_data_output"> + <h3>{% trans 'Output' %}</h3> + <p> + {% trans 'Choose "GeomFromText" from the "Function" column and paste the string below into the "Value" field.' %} + </p> + <textarea id="gis_data_textarea" cols="95" rows="5">{{ result }}</textarea> + </div> + </div> +</form> diff --git a/srcs/phpmyadmin/templates/header.twig b/srcs/phpmyadmin/templates/header.twig new file mode 100644 index 0000000..c931e8c --- /dev/null +++ b/srcs/phpmyadmin/templates/header.twig @@ -0,0 +1,66 @@ +{% if not is_ajax and is_enabled -%} + +<!doctype html> +<html lang="{{ lang }}" dir="{{ text_dir }}"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="referrer" content="no-referrer"> + <meta name="robots" content="noindex,nofollow"> + <meta http-equiv="X-UA-Compatible" content="IE=Edge"> + {% if not allow_third_party_framing -%} + <style id="cfs-style">html{display: none;}</style> + {%- endif %} + + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + {% if is_print_view %} + <link rel="stylesheet" type="text/css" href="{{ base_dir }}print.css?{{ version }}"> + {% else %} + <link rel="stylesheet" type="text/css" href="{{ theme_path }}/jquery/jquery-ui.css"> + <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/lib/codemirror.css?{{ version }}"> + <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/addon/hint/show-hint.css?{{ version }}"> + <link rel="stylesheet" type="text/css" href="{{ base_dir }}js/vendor/codemirror/addon/lint/lint.css?{{ version }}"> + <link rel="stylesheet" type="text/css" href="{{ theme_path }}/css/theme{{ text_dir == 'rtl' ? '-rtl' }}.css?{{ version }}&nocache= + {{- unique_value }}{{ text_dir }}{% if server is not empty %}&server={{ server }}{% endif %}"> + <link rel="stylesheet" type="text/css" href="{{ theme_path }}/css/printview.css?{{ version }}" media="print" id="printcss"> + {% endif %} + <title>{{ title }}</title> + {{ scripts|raw }} + <noscript><style>html{display:block}</style></noscript> +</head> +<body{{ body_id is not empty ? ' id=' ~ body_id }}> + {{ navigation|raw }} + {{ custom_header|raw }} + {{ load_user_preferences|raw }} + + {% if not show_hint %} + <span id="no_hint" class="hide"></span> + {% endif %} + + {% if is_warnings_enabled %} + <noscript> + {{ 'Javascript must be enabled past this point!'|trans|error }} + </noscript> + {% endif %} + + {% if is_menu_enabled and server > 0 %} + {{ menu|raw }} + <span id="page_nav_icons"> + <span id="lock_page_icon"></span> + <span id="page_settings_icon"> + {{ get_image('s_cog', 'Page-related settings'|trans) }} + </span> + <a id="goto_pagetop" href="#">{{ get_image('s_top', 'Click on the bar to scroll to top of page'|trans) }}</a> + </span> + {% endif %} + + {{ console|raw }} + + <div id="page_content"> + {{ messages|raw }} +{% endif %} + +{% if is_enabled and has_recent_table %} + {{ recent_table|raw }} +{% endif %} diff --git a/srcs/phpmyadmin/templates/header_location.twig b/srcs/phpmyadmin/templates/header_location.twig new file mode 100644 index 0000000..f6e97a6 --- /dev/null +++ b/srcs/phpmyadmin/templates/header_location.twig @@ -0,0 +1,22 @@ +{# Manage HTML redirection #} +<html> +<head> + <title>- - -</title> + <meta http-equiv="expires" content="0"> + <meta http-equiv="Pragma" content="no-cache"> + <meta http-equiv="Cache-Control" content="no-cache"> + <meta http-equiv="Refresh" content="0;url={{ uri }}"> + <script type="text/javascript"> + //<![CDATA[ + setTimeout(function() { window.location = decodeURI('{{ uri|escape_js_string }}'); }, 2000); + //]]> + </script> +</head> +<body> +<script type="text/javascript"> + //<![CDATA[ + document.write('<p><a href="{{ uri|e|escape_js_string }}">{% trans 'Go' %}</a></p>'); + //]]> +</script> +</body> +</html> diff --git a/srcs/phpmyadmin/templates/home/index.twig b/srcs/phpmyadmin/templates/home/index.twig new file mode 100644 index 0000000..e0fb63a --- /dev/null +++ b/srcs/phpmyadmin/templates/home/index.twig @@ -0,0 +1,203 @@ +{% if is_git_revision %} + <div id="is_git_revision"></div> +{% endif %} + +{{ message|raw }} + +{{ partial_logout|raw }} + +<div id="maincontainer"> + {{ sync_favorite_tables|raw }} + + <div id="main_pane_left"> + {% if has_server %} + {% if is_demo %} + <div class="group"> + <h2>{% trans 'phpMyAdmin Demo Server' %}</h2> + <p class="cfg_dbg_demo"> + {% apply format('<a href="url.php?url=https://demo.phpmyadmin.net/" target="_blank" rel="noopener noreferrer">demo.phpmyadmin.net</a>')|raw %} + {% trans %} + You are using the demo server. You can do anything here, but please do not change root, debian-sys-maint and pma users. More information is available at %s. + {% endtrans %} + {% endapply %} + </p> + </div> + {% endif %} + + <div class="group"> + <h2>{% trans 'General settings' %}</h2> + <ul> + {% if has_server_selection %} + <li id="li_select_server" class="no_bullets"> + {{ get_image('s_host') }} + {{ server_selection|raw }} + </li> + {% endif %} + + {% if server > 0 %} + {{ change_password is not empty ? change_password|raw }} + + <li id="li_select_mysql_collation" class="no_bullets"> + <form class="disableAjax" method="post" action="index.php"> + {{ get_hidden_inputs(null, null, 4, 'collation_connection') }} + <label for="select_collation_connection"> + {{ get_image('s_asci') }} + {% trans 'Server connection collation:' %} + {{ show_mysql_docu('charset-connection') }} + </label> + {% if charsets is not empty %} + <select lang="en" dir="ltr" name="collation_connection" id="select_collation_connection" class="autosubmit"> + <option value="">{% trans 'Collation' %}</option> + <option value=""></option> + {% for charset in charsets %} + <optgroup label="{{ charset.name }}" title="{{ charset.description }}"> + {% for collation in charset.collations %} + <option value="{{ collation.name }}" title="{{ collation.description }}"{{ collation.is_selected ? ' selected' }}> + {{- collation.name -}} + </option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + {% endif %} + </form> + </li> + {% endif %} + {{ user_preferences is not empty ? user_preferences|raw }} + </ul> + </div> + {% endif %} + + <div class="group"> + <h2>{% trans 'Appearance settings' %}</h2> + <ul> + {% if language_selector is not empty %} + <li id="li_select_lang" class="no_bullets"> + {{ get_image('s_lang') }} + {{ language_selector|raw }} + </li> + {% endif %} + + {% if theme_selection is not empty %} + <li id="li_select_theme" class="no_bullets"> + {{ get_image('s_theme') }} + {{ theme_selection|raw }} + </li> + {% endif %} + </ul> + </div> + </div> + + <div id="main_pane_right"> + {% if database_server is not empty %} + <div class="group"> + <h2>{% trans 'Database server' %}</h2> + <ul> + <li id="li_server_info"> + {% trans 'Server:' %} + {{ database_server.host }} + </li> + <li id="li_server_type"> + {% trans 'Server type:' %} + {{ database_server.type }} + </li> + <li id="li_server_connection"> + {% trans 'Server connection:' %} + {{ database_server.connection|raw }} + </li> + <li id="li_server_version"> + {% trans 'Server version:' %} + {{ database_server.version }} + </li> + <li id="li_mysql_proto"> + {% trans 'Protocol version:' %} + {{ database_server.protocol }} + </li> + <li id="li_user_info"> + {% trans 'User:' %} + {{ database_server.user }} + </li> + <li id="li_mysql_charset"> + {% trans 'Server charset:' %} + <span lang="en" dir="ltr"> + {{ database_server.charset }} + </span> + </li> + </ul> + </div> + {% endif %} + + {% if web_server is not empty or php_info is not empty %} + <div class="group"> + <h2>{% trans 'Web server' %}</h2> + <ul> + {% if web_server is not empty %} + <li id="li_web_server_software"> + {{ web_server.software }} + </li> + <li id="li_mysql_client_version"> + {% trans 'Database client version:' %} + {{ web_server.database }} + </li> + <li id="li_used_php_extension"> + {% trans 'PHP extension:' %} + {% for extension in web_server.php_extensions %} + {{ extension }} + {{ show_php_docu('book.' ~ extension ~ '.php') }} + {% endfor %} + </li> + <li id="li_used_php_version"> + {% trans 'PHP version:' %} + {{ web_server.php_version }} + </li> + {% endif %} + {% if php_info is not empty %} + {{ php_info|raw }} + {% endif %} + </ul> + </div> + {% endif %} + + <div class="group pmagroup"> + <h2>phpMyAdmin</h2> + <ul> + <li id="li_pma_version"{{ is_version_checked ? ' class="jsversioncheck"' }}> + {% trans 'Version information:' %} + <span class="version">{{ phpmyadmin_version }}</span> + </li> + <li id="li_pma_docs"> + <a href="{{ get_docu_link('index') }}" target="_blank" rel="noopener noreferrer"> + {% trans 'Documentation' %} + </a> + </li> + <li id="li_pma_homepage"> + <a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer"> + {% trans 'Official Homepage' %} + </a> + </li> + <li id="li_pma_contribute"> + <a href="{{ 'https://www.phpmyadmin.net/contribute/'|link }}" target="_blank" rel="noopener noreferrer"> + {% trans 'Contribute' %} + </a> + </li> + <li id="li_pma_support"> + <a href="{{ 'https://www.phpmyadmin.net/support/'|link }}" target="_blank" rel="noopener noreferrer"> + {% trans 'Get support' %} + </a> + </li> + <li id="li_pma_changes"> + <a href="changelog.php{{ get_common() }}" target="_blank"> + {% trans 'List of changes' %} + </a> + </li> + <li id="li_pma_license"> + <a href="license.php{{ get_common() }}" target="_blank"> + {% trans 'License' %} + </a> + </li> + </ul> + </div> + </div> +</div> + +{{ config_storage_message|raw }} diff --git a/srcs/phpmyadmin/templates/javascript/display.twig b/srcs/phpmyadmin/templates/javascript/display.twig new file mode 100644 index 0000000..12027ef --- /dev/null +++ b/srcs/phpmyadmin/templates/javascript/display.twig @@ -0,0 +1,7 @@ +<script type="text/javascript"> +if (typeof configInlineParams === "undefined" || !Array.isArray(configInlineParams)) configInlineParams = []; +configInlineParams.push(function() { +{{ js_array|join(';\n')|raw }}; +}); +if (typeof configScriptLoaded !== "undefined" && configInlineParams) loadInlineConfig(); +</script> diff --git a/srcs/phpmyadmin/templates/list/item.twig b/srcs/phpmyadmin/templates/list/item.twig new file mode 100644 index 0000000..78f5e38 --- /dev/null +++ b/srcs/phpmyadmin/templates/list/item.twig @@ -0,0 +1,19 @@ +<li{% if id is not empty %} id="{{ id }}"{% endif -%} + {%- if class is not empty %} class="{{ class }}"{% endif %}> + + {% if url is defined and url is iterable and url['href'] is not empty %} + <a{% if url['href'] is not empty %} href="{{ url['href']|raw }}"{% endif -%} + {%- if url['target'] is not empty %} target="{{ url['target'] }}"{% endif -%} + {%- if url['target'] is not empty and url['target'] == '_blank' %} rel="noopener noreferrer"{% endif -%} + {%- if url['id'] is not empty %} id="{{ url['id'] }}"{% endif -%} + {%- if url['class'] is not empty %} class="{{ url['class'] }}"{% endif -%} + {%- if url['title'] is not empty %} title="{{ url['title'] }}"{% endif %}> + {% endif %} + {{ content|raw }} + {% if url is defined and url is iterable and url['href'] is not empty %} + </a> + {% endif %} + {% if mysql_help_page is not empty %} + {{ show_mysql_docu(mysql_help_page) }} + {% endif %} +</li> diff --git a/srcs/phpmyadmin/templates/list/unordered.twig b/srcs/phpmyadmin/templates/list/unordered.twig new file mode 100644 index 0000000..11f114e --- /dev/null +++ b/srcs/phpmyadmin/templates/list/unordered.twig @@ -0,0 +1,14 @@ +<ul{% if id is not empty %} id="{{ id }}"{% endif -%} + {%- if class is not empty %} class="{{ class }}"{% endif %}> + + {% if items is not empty %} + {% for item in items %} + {% if item is not iterable %} + {% set item = {'content': item} %} + {% endif %} + {% include 'list/item.twig' with item only %} + {% endfor %} + {% elseif content is not empty %} + {{ content|raw }} + {% endif %} +</ul> diff --git a/srcs/phpmyadmin/templates/login/footer.twig b/srcs/phpmyadmin/templates/login/footer.twig new file mode 100644 index 0000000..d9e9659 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/footer.twig @@ -0,0 +1,4 @@ +</div> +{% if check_timeout == true %} + </div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/login/header.twig b/srcs/phpmyadmin/templates/login/header.twig new file mode 100644 index 0000000..a21dee5 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/header.twig @@ -0,0 +1,16 @@ +{% if session_expired == true %} + <div id="modalOverlay"> +{% endif %} +<div class="container{{ add_class }}"> +<a href="{{ 'https://www.phpmyadmin.net/'|link }}" target="_blank" rel="noopener noreferrer" class="logo"> +<img src="{{ theme.getImgPath('logo_right.png', 'pma_logo.png') }}" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0"> +</a> +<h1>{{ 'Welcome to %s'|trans|format('<bdo dir="ltr" lang="en">phpMyAdmin</bdo>')|raw }}</h1> + +<noscript> +{{ "Javascript must be enabled past this point!"|trans|error }} +</noscript> + +<div class="hide" id="js-https-mismatch"> +{{ "There is a mismatch between HTTPS indicated on the server and client. This can lead to a non working phpMyAdmin or a security risk. Please fix your server configuration to indicate HTTPS properly."|trans|error }} +</div> diff --git a/srcs/phpmyadmin/templates/login/twofactor.twig b/srcs/phpmyadmin/templates/login/twofactor.twig new file mode 100644 index 0000000..af2bae3 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor.twig @@ -0,0 +1,7 @@ +<form method="post" class="disableAjax"> + {{ get_hidden_inputs() }} + {{ form|raw }} + {% if show_submit %} + <input class="btn btn-primary" type="submit" value="{% trans "Verify" %}"> + {% endif %} +</form> diff --git a/srcs/phpmyadmin/templates/login/twofactor/application.twig b/srcs/phpmyadmin/templates/login/twofactor/application.twig new file mode 100644 index 0000000..3077e03 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/application.twig @@ -0,0 +1,4 @@ +<p> +<label>{% trans "Authentication code:" %} <input type="text" name="2fa_code" autocomplete="off"></label> +</p> +<p>{% trans "Open the two-factor authentication app on your device to view your authentication code and verify your identity." %}</p> diff --git a/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig b/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig new file mode 100644 index 0000000..e823bb3 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/application_configure.twig @@ -0,0 +1,17 @@ +{{ get_hidden_inputs() }} +<p> + {% trans "Please scan following QR code into the two-factor authentication app on your device and enter authentication code it generates." %} +</p> +<p> + {% if has_imagick %} + <img src="{{ image }}"> + {% else %} + {{ image|raw }} + {% endif %} +</p> +<p> + {% trans "Secret/key:" %} <strong>{{ secret }}</strong> +</p> +<p> + <label>{% trans "Authentication code:" %} <input type="text" name="2fa_code" autocomplete="off"></label> +</p> diff --git a/srcs/phpmyadmin/templates/login/twofactor/invalid.twig b/srcs/phpmyadmin/templates/login/twofactor/invalid.twig new file mode 100644 index 0000000..568dd94 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/invalid.twig @@ -0,0 +1,3 @@ +<div class="error"> +{% trans "The configured two factor authentication is not available, please install missing dependencies." %} +</div> diff --git a/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig b/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig new file mode 100644 index 0000000..d3f9c04 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/key-https-warning.twig @@ -0,0 +1,5 @@ +{% if not is_https %} +<div class="error"> +{% trans "You are not using https to access phpMyAdmin, therefore FIDO U2F device will most likely refuse to authenticate you." %} +</div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/login/twofactor/key.twig b/srcs/phpmyadmin/templates/login/twofactor/key.twig new file mode 100644 index 0000000..79ade47 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/key.twig @@ -0,0 +1,5 @@ +{% include 'login/twofactor/key-https-warning.twig' %} +<p> +{% trans "Please connect your FIDO U2F device into your computer's USB port. Then confirm login on the device." %} +</p> +<input id="u2f_authentication_response" name="u2f_authentication_response" value="" type="hidden" data-request="{{ request }}"> diff --git a/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig b/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig new file mode 100644 index 0000000..8b502dc --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/key_configure.twig @@ -0,0 +1,5 @@ +{% include 'login/twofactor/key-https-warning.twig' %} +<p> +{% trans "Please connect your FIDO U2F device into your computer's USB port. Then confirm registration on the device." %} +</p> +<input id="u2f_registration_response" name="u2f_registration_response" value="" type="hidden" data-request="{{ request }}" data-signatures="{{ signatures }}"> diff --git a/srcs/phpmyadmin/templates/login/twofactor/simple.twig b/srcs/phpmyadmin/templates/login/twofactor/simple.twig new file mode 100644 index 0000000..eeae140 --- /dev/null +++ b/srcs/phpmyadmin/templates/login/twofactor/simple.twig @@ -0,0 +1 @@ +<input type="hidden" name="2fa_confirm" value="1"> diff --git a/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig b/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig new file mode 100644 index 0000000..8303b59 --- /dev/null +++ b/srcs/phpmyadmin/templates/navigation/item_unhide_dialog.twig @@ -0,0 +1,29 @@ +<form class="ajax" action="navigation.php" method="post"> + <fieldset> + {{ get_hidden_inputs(database, table) }} + + {% for type, label in types %} + {% if (item_type is empty or item_type == type) and hidden[type] is iterable %} + {{ not loop.first ? '<br>' }} + <strong>{{ label }}</strong> + <table class="all100"> + <tbody> + {% for item in hidden[type] %} + <tr> + <td>{{ item }}</td> + <td class="right"> + <a class="unhideNavItem ajax" href="navigation.php" data-post="{{ get_common({ + 'unhideNavItem': true, + 'itemType': type, + 'itemName': item, + 'dbName': database + }, '') }}">{{ get_icon('show', 'Unhide'|trans) }}</a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% endif %} + {% endfor %} + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/navigation/main.twig b/srcs/phpmyadmin/templates/navigation/main.twig new file mode 100644 index 0000000..574e3f4 --- /dev/null +++ b/srcs/phpmyadmin/templates/navigation/main.twig @@ -0,0 +1,98 @@ +{% if not is_ajax %} + <div id="pma_navigation"> + <div id="pma_navigation_resizer"></div> + <div id="pma_navigation_collapser"></div> + <div id="pma_navigation_content"> + <div id="pma_navigation_header"> + <a class="hide navigation_url" href="navigation.php{{ get_common({'ajax_request': true}) }}"></a> + + {% if logo.is_displayed %} + <div id="pmalogo"> + {% if logo.has_link %} + <a href="{{ logo.link|default('#') }}"{{ logo.attributes }}> + {% endif %} + {% if logo.source is not empty %} + <img id="imgpmalogo" src="{{ logo.source }}" alt="phpMyAdmin"> + {% else %} + <h1>phpMyAdmin</h1> + {% endif %} + {% if logo.has_link %} + </a> + {% endif %} + </div> + {% endif %} + + <div id="navipanellinks"> + <a href="index.php{{ get_common() }}" title="{% trans 'Home' %}"> + {{- get_image('b_home', 'Home'|trans) -}} + </a> + + {% if server != 0 %} + <a class="logout disableAjax" href="logout.php{{ get_common() }}" title="{{ auth_type == 'config' ? 'Empty session data'|trans : 'Log out'|trans }}"> + {{- get_image('s_loggoff', auth_type == 'config' ? 'Empty session data'|trans : 'Log out'|trans) -}} + </a> + {% endif %} + + <a href="{{ get_docu_link('index') }}" title="{% trans 'phpMyAdmin documentation' %}" target="_blank" rel="noopener"> + {{- get_image('b_docs', 'phpMyAdmin documentation'|trans) -}} + </a> + + <a href="{{ get_mysql_docu_url('') }}" title="{% trans 'Documentation' %}" target="_blank" rel="noopener noreferrer"> + {{- get_image('b_sqlhelp', 'Documentation'|trans) -}} + </a> + + <a id="pma_navigation_settings_icon"{{ not is_navigation_settings_enabled ? ' class="hide"' }} href="#" title="{% trans 'Navigation panel settings' %}"> + {{- get_image('s_cog', 'Navigation panel settings'|trans) -}} + </a> + + <a id="pma_navigation_reload" href="#" title="{% trans 'Reload navigation panel' %}"> + {{- get_image('s_reload', 'Reload navigation panel'|trans) -}} + </a> + </div> + + {% if is_servers_displayed and servers|length > 1 %} + <div id="serverChoice"> + {{ server_select|raw }} + </div> + {% endif %} + + {{ get_image('ajax_clock_small', 'Loading…'|trans, { + 'style': 'visibility: hidden; display:none', + 'class': 'throbber' + }) }} + </div> + <div id="pma_navigation_tree" class="list_container{{ is_synced ? ' synced' }}{{ is_highlighted ? ' highlight' }}{{ is_autoexpanded ? ' autoexpand' }}"> +{% endif %} + +{% if not navigation_tree %} + {{ 'An error has occurred while loading the navigation display'|trans|error }} +{% else %} + {{ navigation_tree|raw }} +{% endif %} + +{% if not is_ajax %} + </div> + + <div id="pma_navi_settings_container"> + {% if is_navigation_settings_enabled %} + {{ navigation_settings|raw }} + {% endif %} + </div> + </div> + + {% if is_drag_drop_import_enabled %} + <div class="pma_drop_handler"> + {% trans 'Drop files here' %} + </div> + <div class="pma_sql_import_status"> + <h2> + {% trans 'SQL upload' %} + ( <span class="pma_import_count">0</span> ) + <span class="close">x</span> + <span class="minimize">-</span> + </h2> + <div></div> + </div> + {% endif %} + </div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/navigation/tree/database_select.twig b/srcs/phpmyadmin/templates/navigation/tree/database_select.twig new file mode 100644 index 0000000..9b8beda --- /dev/null +++ b/srcs/phpmyadmin/templates/navigation/tree/database_select.twig @@ -0,0 +1,22 @@ +{{ quick_warp|raw }} + +<div id="pma_navigation_select_database"> + {{ list_navigator|raw }} + + <div id="pma_navigation_db_select"> + <form action="index.php"> + {{ get_hidden_fields({'server': server}) }} + + <select name="db" class="hide" id="navi_db_select"> + <option value="" dir="{{ text_dir }}">{% trans 'Databases' %}…</option> + {{ options|raw }} + </select> + </form> + </div> +</div> + +<div id="pma_navigation_tree_content"> + <ul> + {{ nodes|raw }} + </ul> +</div> diff --git a/srcs/phpmyadmin/templates/navigation/tree/path.twig b/srcs/phpmyadmin/templates/navigation/tree/path.twig new file mode 100644 index 0000000..540a992 --- /dev/null +++ b/srcs/phpmyadmin/templates/navigation/tree/path.twig @@ -0,0 +1,12 @@ +<div class='list_container hide'> + <ul{{ has_search_results ? ' class="search_results"' }}> + {{ list_content|raw }} + </ul> + + {% if not is_tree %} + <span class='hide loaded_db'>{{ parent_name|url_encode }}</span> + {% if list_content is empty %} + <div>{% trans 'No tables found in database.' %}</div> + {% endif %} + {% endif %} +</div> diff --git a/srcs/phpmyadmin/templates/navigation/tree/state.twig b/srcs/phpmyadmin/templates/navigation/tree/state.twig new file mode 100644 index 0000000..c59573d --- /dev/null +++ b/srcs/phpmyadmin/templates/navigation/tree/state.twig @@ -0,0 +1,16 @@ +{{ quick_warp|raw }} + +<div class="clearfloat"></div> + +<ul> + {{ fast_filter|raw }} + {{ controls|raw }} +</ul> + +{{ page_selector|raw }} + +<div id='pma_navigation_tree_content'> + <ul> + {{ nodes|raw }} + </ul> +</div> diff --git a/srcs/phpmyadmin/templates/preferences/autoload.twig b/srcs/phpmyadmin/templates/preferences/autoload.twig new file mode 100644 index 0000000..4c61045 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/autoload.twig @@ -0,0 +1,15 @@ +<div id="prefs_autoload" class="notice print_ignore hide"> + <form action="prefs_manage.php" method="post" class="disableAjax"> + {{ hidden_inputs|raw }} + <input type="hidden" name="json" value=""> + <input type="hidden" name="submit_import" value="1"> + <input type="hidden" name="return_url" value="{{ return_url }}"> + {% trans %} + Your browser has phpMyAdmin configuration for this domain. Would you like to import it for current session? + {% endtrans %} + <br> + <a href="#yes">{% trans "Yes" %}</a> + / <a href="#no">{% trans "No" %}</a> + / <a href="#delete">{% trans "Delete settings" %}</a> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/preferences/forms/main.twig b/srcs/phpmyadmin/templates/preferences/forms/main.twig new file mode 100644 index 0000000..563b385 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/forms/main.twig @@ -0,0 +1,8 @@ +{{ error|raw }} +{% if has_errors %} + <div class="error config-form"> + <strong>{% trans 'Cannot save settings, submitted form contains errors!' %}</strong> + {{ errors|raw }} + </div> +{% endif %} +{{ form|raw }} diff --git a/srcs/phpmyadmin/templates/preferences/manage/error.twig b/srcs/phpmyadmin/templates/preferences/manage/error.twig new file mode 100644 index 0000000..d6b3522 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/manage/error.twig @@ -0,0 +1,20 @@ +{{ 'Configuration contains incorrect data for some fields.'|trans|error }} +<div class="config-form"> + {{ form_errors|raw }} +</div> +<form action="prefs_manage.php" method="post" class="disableAjax"> + {{ get_hidden_inputs() }} + <input type="hidden" name="json" value="{{ json }}"> + <input type="hidden" name="fix_errors" value="1"> + {% if import_merge is not empty %} + <input type="hidden" name="import_merge" value="1"> + {% endif %} + {% if return_url %} + <input type="hidden" name="return_url" value="{{ return_url }}"> + {% endif %} + <p> + {% trans 'Do you want to import remaining settings?' %} + </p> + <input class="btn btn-secondary" type="submit" name="submit_import" value="{{ 'Yes'|trans }}"> + <input class="btn btn-secondary" type="submit" name="submit_ignore" value="{{ 'No'|trans }}"> +</form> diff --git a/srcs/phpmyadmin/templates/preferences/manage/main.twig b/srcs/phpmyadmin/templates/preferences/manage/main.twig new file mode 100644 index 0000000..0e51327 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/manage/main.twig @@ -0,0 +1,112 @@ +{{ error|raw }} +<script type="text/javascript"> + {{ get_js_value("Messages.strSavedOn", 'Saved on: @DATE@'|trans) }} +</script> +<div id="maincontainer"> + <div id="main_pane_left"> + <div class="group"> + <h2> {% trans 'Import' %} </h2> + <form class="group-cnt prefs-form disableAjax" name="prefs_import" action="prefs_manage.php" method="post" + enctype="multipart/form-data"> + {{ generate_hidden_max_file_size(max_upload_size) }} + {{ get_hidden_inputs() }} + <input type="hidden" name="json" value=""> + <input type="radio" id="import_text_file" name="import_type" value="text_file" checked="checked"> + <label for="import_text_file"> {% trans 'Import from file' %} </label> + <div id="opts_import_text_file" class="prefsmanage_opts"> + <label for="input_import_file"> {% trans 'Browse your computer:' %} </label> + <input type="file" name="import_file" id="input_import_file"> + </div> + <input type="radio" id="import_local_storage" name="import_type" value="local_storage" + disabled="disabled"> + <label for="import_local_storage"> {% trans 'Import from browser\'s storage' %} </label> + <div id="opts_import_local_storage" class="prefsmanage_opts disabled"> + <div class="localStorage-supported"> + {% trans 'Settings will be imported from your browser\'s local storage.' %} + <br> + <div class="localStorage-exists"> + {% trans 'Saved on: @DATE@' %} + </div> + <div class="localStorage-empty"> + {{ 'You have no saved settings!'|trans|notice }} + </div> + </div> + <div class="localStorage-unsupported"> + {{ 'This feature is not supported by your web browser'|trans|notice }} + </div> + </div> + <input type="checkbox" id="import_merge" name="import_merge"> + <label for="import_merge"> {% trans 'Merge with current configuration' %} </label> + <br><br> + <input class="btn btn-primary" type="submit" name="submit_import" value="{{ 'Go'|trans }}"> + </form> + </div> + {% if exists_setup_and_not_exists_config %} + {# show only if setup script is available, allows to disable this message #} + {# by simply removing setup directory #} + {# Also do not show in config exists (and setup would refuse to work) #} + <div class="group"> + <h2>{% trans 'More settings' %}</h2> + <div class="group-cnt"> + {{ 'You can set more settings by modifying config.inc.php, eg. by using %sSetup script%s.'|trans|format('<a href="setup/index.php" target="_blank">','</a>')|raw }} + {{ show_docu('setup', 'setup-script') }} + </div> + </div> + {% endif %} + </div> + <div id="main_pane_right"> + <div class="group"> + <h2>{% trans 'Export' %}</h2> + <div class="click-hide-message group-cnt hide"> + {{ 'Configuration has been saved.'|trans|raw_success }} + </div> + <form class="group-cnt prefs-form disableAjax" name="prefs_export" + action="prefs_manage.php" method="post"> + {{ get_hidden_inputs() }} + <div> + <input type="radio" id="export_text_file" name="export_type" + value="text_file" checked="checked"> + <label for="export_text_file"> + {% trans 'Save as JSON file' %} + </label><br> + <input type="radio" id="export_php_file" name="export_type" value="php_file"> + <label for="export_php_file"> + {% trans 'Save as PHP file' %} + </label><br> + <input type="radio" id="export_local_storage" name="export_type" value="local_storage" + disabled="disabled"> + <label for="export_local_storage"> + {% trans 'Save to browser\'s storage' %} + </label> + </div> + <div id="opts_export_local_storage" + class="prefsmanage_opts disabled"> + <span class="localStorage-supported"> + {% trans 'Settings will be saved in your browser\'s local storage.' %} + <div class="localStorage-exists"> + <b> + {% trans 'Existing settings will be overwritten!' %} + </b> + </div> + </span> + <div class="localStorage-unsupported"> + {{ 'This feature is not supported by your web browser'|trans|notice }} + </div> + </div> + <br> + <input class="btn btn-primary" type="submit" name="submit_export" value="{% trans 'Go' %}"> + </form> + </div> + <div class="group"> + <h2>{% trans 'Reset' %}</h2> + <form class="group-cnt prefs-form disableAjax" name="prefs_reset" + action="prefs_manage.php" method="post"> + {{ get_hidden_inputs() }} + {% trans 'You can reset all your settings and restore them to default values.' %} + <br><br> + <input class="btn btn-secondary" type="submit" name="submit_clear" value="{% trans 'Reset' %}"> + </form> + </div> + </div> + <br class="clearfloat"> +</div> diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig b/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig new file mode 100644 index 0000000..574f112 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/two_factor/configure.twig @@ -0,0 +1,11 @@ +<div class="group"> +<h2>{% trans "Configure two-factor authentication" %}</h2> +<div class="group-cnt"> +<form method="POST" action="prefs_twofactor.php"> +{{ get_hidden_inputs() }} +<input type="hidden" name="2fa_configure" value="{{ configure }}"> +{{ form|raw }} +<input class="btn btn-secondary" type="submit" value="{% trans "Enable two-factor authentication" %}"> +</form> +</div> +</div> diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig b/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig new file mode 100644 index 0000000..f1ef175 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/two_factor/confirm.twig @@ -0,0 +1,12 @@ +<div class="group"> +<h2>{% trans "Confirm disabling two-factor authentication" %}</h2> +<div class="group-cnt"> +<form method="POST" action="prefs_twofactor.php"> +{{ "By disabling two factor authentication you will be again able to login using password only."|trans|notice }} +{{ get_hidden_inputs() }} +{{ form|raw }} +<input type="hidden" name="2fa_remove" value="1"> +<input class="btn btn-secondary" type="submit" value="{% trans "Disable two-factor authentication" %}"> +</form> +</div> +</div> diff --git a/srcs/phpmyadmin/templates/preferences/two_factor/main.twig b/srcs/phpmyadmin/templates/preferences/two_factor/main.twig new file mode 100644 index 0000000..f95c047 --- /dev/null +++ b/srcs/phpmyadmin/templates/preferences/two_factor/main.twig @@ -0,0 +1,60 @@ +<div class="group"> + <h2> + {% trans "Two-factor authentication status" %} + {{ show_docu('two_factor') }} + </h2> + <div class="group-cnt"> + {% if enabled %} + {% if num_backends == 0 %} + <p>{% trans "Two-factor authentication is not available, please install optional dependencies to enable authentication backends." %}</p> + <p>{% trans "Following composer packages are missing:" %}</p> + <ul> + {% for item in missing %} + <li><code>{{ item.dep }}</code> ({{ item.class }})</li> + {% endfor %} + </ul> + {% else %} + {% if backend_id %} + <p>{% trans "Two-factor authentication is available and configured for this account." %}</p> + {% else %} + <p>{% trans "Two-factor authentication is available, but not configured for this account." %}</p> + {% endif %} + {% endif %} + {% else %} + <p>{% trans "Two-factor authentication is not available, enable phpMyAdmin configuration storage to use it." %}</p> + {% endif %} + </div> +</div> + +{% if backend_id %} + <div class="group"> + <h2>{{ backend_name }}</h2> + <div class="group-cnt"> + <p>{% trans "You have enabled two factor authentication." %}</p> + <p>{{ backend_description }}</p> + <form method="post" action="prefs_twofactor.php"> + {{ get_hidden_inputs() }} + <input class="btn btn-secondary" type="submit" name="2fa_remove" value=" + {%- trans "Disable two-factor authentication" %}"> + </form> + </div> + </div> +{% elseif num_backends > 0 %} + <div class="group"> + <h2>{% trans "Configure two-factor authentication" %}</h2> + <div class="group-cnt"> + <form method="post" action="prefs_twofactor.php"> + {{ get_hidden_inputs() }} + {% for backend in backends %} + <label class="displayblock"> + <input type="radio" name="2fa_configure" value="{{ backend["id"] }}" + {{- backend["id"] == "" ? ' checked' }}> + <strong>{{ backend["name"] }}</strong> + <p>{{ backend["description"] }}</p> + </label> + {% endfor %} + <input class="btn btn-secondary" type="submit" value="{% trans "Configure two-factor authentication" %}"> + </form> + </div> + </div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/preview_sql.twig b/srcs/phpmyadmin/templates/preview_sql.twig new file mode 100644 index 0000000..5102341 --- /dev/null +++ b/srcs/phpmyadmin/templates/preview_sql.twig @@ -0,0 +1,11 @@ +<div class="preview_sql"> + {% if query_data is empty %} + {% trans 'No change' %} + {% elseif query_data is iterable %} + {% for query in query_data %} + {{ format_sql(query) }} + {% endfor %} + {% else %} + {{ format_sql(query_data) }} + {% endif %} +</div> diff --git a/srcs/phpmyadmin/templates/radio_fields.twig b/srcs/phpmyadmin/templates/radio_fields.twig new file mode 100644 index 0000000..58730e3 --- /dev/null +++ b/srcs/phpmyadmin/templates/radio_fields.twig @@ -0,0 +1,11 @@ +{% if class is not empty %} +<div class="{{ class }}"> +{% endif %} +<input type="radio" name="{{ html_field_name }}" id="{{ html_field_id|raw }}" value="{{ choice_value }}"{{ checked ? ' checked="checked"' }}> +<label for="{{ html_field_id|raw }}">{{ (escape_label ? choice_label|e : choice_label)|raw }}</label> +{% if is_line_break %} +<br> +{% endif %} +{% if class is not empty %} +</div> +{% endif %} diff --git a/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig b/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig new file mode 100644 index 0000000..e15ea13 --- /dev/null +++ b/srcs/phpmyadmin/templates/rte/routines/parameter_row.twig @@ -0,0 +1,54 @@ +<tr> + <td class="dragHandle"> + <span class="ui-icon ui-icon-arrowthick-2-n-s"></span> + </td> + <td class="routine_direction_cell{{ class }}"> + <select name="item_param_dir[{{ index }}]"> + {% for value in param_directions %} + <option value="{{ value }}"{{ item_param_dir == value ? ' selected' }}>{{ value }}</option> + {% endfor %} + </select> + </td> + <td> + <input name="item_param_name[{{ index }}]" type="text" value="{{ item_param_name }}"> + </td> + <td> + <select name="item_param_type[{{ index }}]"> + {{ supported_datatypes|raw }} + </select> + </td> + <td> + <input id="item_param_length_{{ index }}" name="item_param_length[{{ index }}]" type="text" value="{{ item_param_length }}"> + <div class="enum_hint"> + <a href="#" class="open_enum_editor"> + {{ get_image('b_edit', '', {'title': 'ENUM/SET editor'|trans}) }} + </a> + </div> + </td> + <td class="hide no_len">---</td> + <td class="routine_param_opts_text"> + <select lang="en" dir="ltr" name="item_param_opts_text[{{ index }}]"> + <option value="">{% trans 'Charset' %}</option> + <option value=""></option> + {% for charset in charsets %} + <option value="{{ charset.name }}" title="{{ charset.description }}"{{ charset.is_selected ? ' selected' }}> + {{- charset.name -}} + </option> + {% endfor %} + </select> + </td> + <td class="hide no_opts">---</td> + <td class="routine_param_opts_num"> + <select name="item_param_opts_num[{{ index }}]"> + <option value=""></option> + {% for value in param_opts_num %} + <option value="{{ value }}"{{ item_param_opts_num == value ? ' selected' }}>{{ value }}</option> + {% endfor %} + </select> + </td> + <td class="routine_param_remove{{ drop_class }}"> + <a href="#" class="routine_param_remove_anchor"> + {{ get_icon('b_drop', 'Drop'|trans) }} + </a> + </td> +</tr> diff --git a/srcs/phpmyadmin/templates/scripts.twig b/srcs/phpmyadmin/templates/scripts.twig new file mode 100644 index 0000000..13a29a3 --- /dev/null +++ b/srcs/phpmyadmin/templates/scripts.twig @@ -0,0 +1,24 @@ +{% for file in files %} + <script data-cfasync="false" type="text/javascript" src="js/{{ file.filename }} + {{- '.php' in file.filename ? get_common(file.params|merge({'v': version})) : '?v=' ~ version|url_encode }}"></script> +{% endfor %} + +<script data-cfasync="false" type="text/javascript"> +// <![CDATA[ +{{ code|raw }} +{% if files is not empty %} +AJAX.scriptHandler +{% for file in files %} + .add('{{ file.filename|escape_js_string }}', {{ file.has_onload ? 1 : 0 }}) +{% endfor %} +; +$(function() { +{% for file in files %} + {% if file.has_onload %} + AJAX.fireOnload('{{ file.filename|escape_js_string }}'); + {% endif %} +{% endfor %} +}); +{% endif %} +// ]]> +</script> diff --git a/srcs/phpmyadmin/templates/secondary_tabs.twig b/srcs/phpmyadmin/templates/secondary_tabs.twig new file mode 100644 index 0000000..76b5725 --- /dev/null +++ b/srcs/phpmyadmin/templates/secondary_tabs.twig @@ -0,0 +1,6 @@ +<ul id="topmenu2"> + {% for tab in sub_tabs %} + {{ get_html_tab(tab, url_params) }} + {% endfor %} +</ul> +<div class="clearfloat"></div> diff --git a/srcs/phpmyadmin/templates/select_all.twig b/srcs/phpmyadmin/templates/select_all.twig new file mode 100644 index 0000000..a0eb1eb --- /dev/null +++ b/srcs/phpmyadmin/templates/select_all.twig @@ -0,0 +1,6 @@ +<img class="selectallarrow" src="{{ pma_theme_image }}arrow_{{ text_dir }}.png" + width="38" height="22" alt="{% trans 'With selected:' %}"> +<input type="checkbox" id="{{ form_name }}_checkall" class="checkall_box" + title="{% trans 'Check all' %}"> +<label for="{{ form_name }}_checkall">{% trans 'Check all' %}</label> +<em class="with-selected">{% trans 'With selected:' %}</em> diff --git a/srcs/phpmyadmin/templates/select_lang.twig b/srcs/phpmyadmin/templates/select_lang.twig new file mode 100644 index 0000000..a8bddc8 --- /dev/null +++ b/srcs/phpmyadmin/templates/select_lang.twig @@ -0,0 +1,32 @@ + <form method="get" action="index.php" class="disableAjax"> + {{ get_hidden_inputs(_form_params) }} + + {% if use_fieldset %} + <fieldset> + <legend lang="en" dir="ltr">{{ language_title|raw }}</legend> + {% else %} + <bdo lang="en" dir="ltr"> + <label for="sel-lang">{{ language_title|raw }}</label> + </bdo> + {% endif %} + + <select name="lang" class="autosubmit" lang="en" dir="ltr" id="sel-lang"> + + {% for language in available_languages %} + {# Is current one active ? #} + <option value="{{ language.getCode()|lower }}" + {%- if language.isActive() %} + selected="selected" + {%- endif -%} + > + {{ language.getName()|raw }} + </option> + {% endfor %} + + </select> + + {% if use_fieldset %} + </fieldset> + {% endif %} + + </form> diff --git a/srcs/phpmyadmin/templates/server/binlog/index.twig b/srcs/phpmyadmin/templates/server/binlog/index.twig new file mode 100644 index 0000000..cdc85dc --- /dev/null +++ b/srcs/phpmyadmin/templates/server/binlog/index.twig @@ -0,0 +1,107 @@ +<h2> + {{ get_image('s_tbl') }} + {% trans 'Binary log' %} +</h2> + +<form action="server_binlog.php" method="post"> + {{ get_hidden_inputs(url_params) }} + <fieldset> + <legend> + {% trans 'Select binary log to view' %} + </legend> + + {% set full_size = 0 %} + <select name="log"> + {% for each_log in binary_logs %} + <option value="{{ each_log['Log_name'] }}" + {{- each_log['Log_name'] == log ? ' selected' }}> + {{ each_log['Log_name'] }} + {% if each_log['File_size'] is defined %} + ({{ format_byte_down(each_log['File_size'], 3, 2)|join(' ') }}) + {% set full_size = full_size + each_log['File_size'] %} + {% endif %} + </option> + {% endfor %} + </select> + {{ binary_logs|length }} + {% trans 'Files' %}, + {% if full_size > 0 %} + {{ format_byte_down(full_size)|join(' ') }} + {% endif %} + </fieldset> + + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </fieldset> +</form> + +{{ sql_message|raw }} + +<table id="binlogTable"> + <thead> + <tr> + <td colspan="6" class="center"> + {% if has_previous %} + {% if has_icons %} + <a href="server_binlog.php" data-post="{{ get_common(previous_params, '') }}" title=" + {%- trans %}Previous{% context %}Previous page{% endtrans %}"> + « + </a> + {% else %} + <a href="server_binlog.php" data-post="{{ get_common(previous_params, '') }}"> + {% trans %}Previous{% context %}Previous page{% endtrans %} « + </a> + {% endif %} + - + {% endif %} + + {% if is_full_query %} + <a href="server_binlog.php" data-post="{{ get_common(full_queries_params, '') }}" title="{% trans 'Truncate shown queries' %}"> + <img src="{{ image_path }}s_partialtext.png" alt="{% trans 'Truncate shown queries' %}"> + </a> + {% else %} + <a href="server_binlog.php" data-post="{{ get_common(full_queries_params, '') }}" title="{% trans 'Show full queries' %}"> + <img src="{{ image_path }}s_fulltext.png" alt="{% trans 'Show full queries' %}"> + </a> + {% endif %} + + {% if has_next %} + - + {% if has_icons %} + <a href="server_binlog.php" data-post="{{ get_common(next_params, '') }}" title=" + {%- trans %}Next{% context %}Next page{% endtrans %}"> + » + </a> + {% else %} + <a href="server_binlog.php" data-post="{{ get_common(next_params, '') }}"> + {% trans %}Next{% context %}Next page{% endtrans %} » + </a> + {% endif %} + {% endif %} + </td> + </tr> + <tr> + <th>{% trans 'Log name' %}</th> + <th>{% trans 'Position' %}</th> + <th>{% trans 'Event type' %}</th> + <th>{% trans 'Server ID' %}</th> + <th>{% trans 'Original position' %}</th> + <th>{% trans 'Information' %}</th> + </tr> + </thead> + + <tbody> + {% for value in values %} + <tr class="noclick"> + <td>{{ value['Log_name'] }}</td> + <td class="right">{{ value['Pos'] }}</td> + <td>{{ value['Event_type'] }}</td> + <td class="right">{{ value['Server_id'] }}</td> + <td class="right"> + {{- value['Orig_log_pos'] is defined ? value['Orig_log_pos'] : value['End_log_pos'] -}} + </td> + <td>{{ format_sql(value['Info'], not is_full_query) }}</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/server/collations/index.twig b/srcs/phpmyadmin/templates/server/collations/index.twig new file mode 100644 index 0000000..bb9dfb3 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/collations/index.twig @@ -0,0 +1,32 @@ +<h2> + {{ get_image('s_asci') }} + {% trans 'Character sets and collations' %} +</h2> + +<div id="div_mysql_charset_collations"> + <table class="data noclick"> + <thead> + <tr> + <th id="collationHeader">{% trans 'Collation' %}</th> + <th>{% trans 'Description' %}</th> + </tr> + </thead> + + {% for charset in charsets %} + <tr> + <th colspan="2" class="right"> + {{ charset.name }} + {% if charset.description is not empty %} + (<em>{{ charset.description }}</em>) + {% endif %} + </th> + </tr> + {% for collation in charset.collations %} + <tr{{ collation.is_default ? ' class="marked"' }}> + <td>{{ collation.name }}</td> + <td>{{ collation.description }}</td> + </tr> + {% endfor %} + {% endfor %} + </table> +</div> diff --git a/srcs/phpmyadmin/templates/server/databases/index.twig b/srcs/phpmyadmin/templates/server/databases/index.twig new file mode 100644 index 0000000..ebff55f --- /dev/null +++ b/srcs/phpmyadmin/templates/server/databases/index.twig @@ -0,0 +1,323 @@ +<h2> + {{ get_image('s_db') }} + {% if has_statistics %} + {% trans 'Databases statistics' %} + {% else %} + {% trans 'Databases' %} + {% endif %} +</h2> + +{% if is_create_database_shown %} + <ul> + <li id="li_create_database" class="no_bullets"> + {% if has_create_database_privileges %} + <form method="post" action="server_databases.php" id="create_database_form" class="ajax"> + <p> + <strong> + <label for="text_create_db"> + {{ get_image('b_newdb') }} + {% trans 'Create database' %} + </label> + {{ show_mysql_docu('CREATE_DATABASE') }} + </strong> + </p> + + {{ get_hidden_inputs('', '', 5) }} + <input type="hidden" name="reload" value="1"> + {% if has_statistics %} + <input type="hidden" name="statistics" value="1"> + {% endif %} + + <input type="text" name="new_db" maxlength="64" class="textfield" value=" + {{- database_to_create }}" id="text_create_db" placeholder=" + {%- trans 'Database name' %}" required> + + {% if charsets is not empty %} + <select lang="en" dir="ltr" name="db_collation"> + <option value="">{% trans 'Collation' %}</option> + <option value=""></option> + {% for charset in charsets %} + <optgroup label="{{ charset.name }}" title="{{ charset.description }}"> + {% for collation in charset.collations %} + <option value="{{ collation.name }}" title="{{ collation.description }}"{{ collation.is_selected ? ' selected' }}> + {{- collation.name -}} + </option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + {% endif %} + + <input id="buttonGo" class="btn btn-primary" type="submit" value="{% trans 'Create' %}"> + </form> + {% else %} + <p> + <strong> + {{ get_image('b_newdb') }} + {% trans 'Create database' %} + {{ show_mysql_docu('CREATE_DATABASE') }} + </strong> + </p> + + <span class="noPrivileges"> + {{ get_image('s_error', '', { + 'hspace': 2, + 'border': 0, + 'align': 'middle' + }) }} + {% trans 'No privileges to create databases' %} + </span> + {% endif %} + </li> + </ul> +{% endif %} + +{% if database_count > 0 %} + {% include 'filter.twig' with {'filter_value': ''} only %} + + <div id="tableslistcontainer"> + {{ get_list_navigator( + database_count, + pos, + url_params, + 'server_databases.php', + 'frame_content', + max_db_list + ) }} + + <form class="ajax" action="server_databases.php" method="post" name="dbStatsForm" id="dbStatsForm"> + {{ get_hidden_inputs(url_params) }} + <div class="responsivetable"> + <table id="tabledatabases" class="data"> + <thead> + <tr> + {% if is_drop_allowed %} + <th></th> + {% endif %} + <th> + <a href="server_databases.php{{ get_common(url_params|merge({ + 'sort_by': 'SCHEMA_NAME', + 'sort_order': url_params.sort_by == 'SCHEMA_NAME' + and url_params.sort_order == 'asc' ? 'desc' : 'asc' + })) }}"> + {% trans 'Database' %} + {% if url_params.sort_by == 'SCHEMA_NAME' %} + {% if url_params.sort_order == 'asc' %} + {{ get_image('s_asc', 'Ascending'|trans) }} + {% else %} + {{ get_image('s_desc', 'Descending'|trans) }} + {% endif %} + {% endif %} + </a> + </th> + + <th> + <a href="server_databases.php{{ get_common(url_params|merge({ + 'sort_by': 'DEFAULT_COLLATION_NAME', + 'sort_order': url_params.sort_by == 'DEFAULT_COLLATION_NAME' + and url_params.sort_order == 'asc' ? 'desc' : 'asc' + })) }}"> + {% trans 'Collation' %} + {% if url_params.sort_by == 'DEFAULT_COLLATION_NAME' %} + {% if url_params.sort_order == 'asc' %} + {{ get_image('s_asc', 'Ascending'|trans) }} + {% else %} + {{ get_image('s_desc', 'Descending'|trans) }} + {% endif %} + {% endif %} + </a> + </th> + + {% if has_statistics %} + {% for name, statistic in header_statistics %} + <th{{ statistic.format == 'byte' ? ' colspan="2"' }}> + <a href="server_databases.php{{ get_common(url_params|merge({ + 'sort_by': name, + 'sort_order': url_params.sort_by == name + and url_params.sort_order == 'asc' ? 'desc' : 'asc' + })) }}"> + {{ statistic.title }} + {% if url_params.sort_by == name %} + {% if url_params.sort_order == 'asc' %} + {{ get_image('s_asc', 'Ascending'|trans) }} + {% else %} + {{ get_image('s_desc', 'Descending'|trans) }} + {% endif %} + {% endif %} + </a> + </th> + {% endfor %} + {% endif %} + + {% if has_master_replication %} + <th>{% trans 'Master replication' %}</th> + {% endif %} + + {% if has_slave_replication %} + <th>{% trans 'Slave replication' %}</th> + {% endif %} + + <th>{% trans 'Action' %}</th> + </tr> + </thead> + + <tbody> + {% for database in databases %} + <tr class="db-row{{ database.is_system_schema ? ' noclick' }}" data-filter-row="{{ database.name|upper }}"> + {% if is_drop_allowed %} + <td class="tool"> + <input type="checkbox" name="selected_dbs[]" class="checkall" title=" + {{- database.name }}" value=" + {{- database.name }}" + {{- database.is_system_schema ? ' disabled' }}> + </td> + {% endif %} + + <td class="name"> + <a href="{{ get_script_name_for_option(default_tab_database, 'database') }} + {{- get_common({'db': database.name}) }}" title=" + {{- "Jump to database '%s'"|trans|format(database.name) }}"> + {{ database.name }} + </a> + </td> + + <td class="value"> + <dfn title="{{ database.collation.description }}"> + {{ database.collation.name }} + </dfn> + </td> + + {% if has_statistics %} + {% for statistic in database.statistics %} + {% if statistic.format is same as('byte') %} + {% set value = format_byte_down(statistic.raw, 3, 1) %} + <td class="value"> + <data value="{{ statistic.raw }}" title="{{ statistic.raw }}"> + {{ value[0] }} + </data> + </td> + <td class="unit">{{ value[1] }}</td> + {% else %} + <td class="value"> + <data value="{{ statistic.raw }}" title="{{ statistic.raw }}"> + {{ format_number(statistic.raw, 0) }} + </data> + </td> + {% endif %} + {% endfor %} + {% endif %} + + {% if database.replication.master.status %} + {% if database.replication.master.is_replicated %} + <td class="tool center"> + {{ get_icon('s_success', 'Replicated'|trans) }} + </td> + {% else %} + <td class="tool center"> + {{ get_icon('s_cancel', 'Not replicated'|trans) }} + </td> + {% endif %} + {% endif %} + + {% if database.replication.slave.status %} + {% if database.replication.slave.is_replicated %} + <td class="tool center"> + {{ get_icon('s_success', 'Replicated'|trans) }} + </td> + {% else %} + <td class="tool center"> + {{ get_icon('s_cancel', 'Not replicated'|trans) }} + </td> + {% endif %} + {% endif %} + + <td class="tool"> + <a class="server_databases" data=" + {{- database.name|js_format }}" href="server_privileges.php + {{- get_common({ + 'db': database.name, + 'checkprivsdb': database.name + }) }}" title=" + {{- 'Check privileges for database "%s".'|trans|format(database.name) }}"> + {{ get_icon('s_rights', 'Check privileges'|trans) }} + </a> + </td> + </tr> + {% endfor %} + </tbody> + + <tfoot> + <tr> + <th colspan="{{ is_drop_allowed ? '3' : '2' }}"> + {% trans 'Total:' %} + <span id="filter-rows-count"> + {{- database_count -}} + </span> + </th> + + {% if has_statistics %} + {% for statistic in total_statistics %} + {% if statistic.format is same as('byte') %} + {% set value = format_byte_down(statistic.raw, 3, 1) %} + <th class="value"> + <data value="{{ statistic.raw }}" title="{{ statistic.raw }}"> + {{ value[0] }} + </data> + </th> + <th class="unit">{{ value[1] }}</th> + {% else %} + <th class="value"> + <data value="{{ statistic.raw }}" title="{{ statistic.raw }}"> + {{ format_number(statistic.raw, 0) }} + </data> + </th> + {% endif %} + {% endfor %} + {% endif %} + + {% if has_master_replication %} + <th></th> + {% endif %} + + {% if has_slave_replication %} + <th></th> + {% endif %} + + <th></th> + </tr> + </tfoot> + </table> + </div> + + {# Footer buttons #} + {% if is_drop_allowed %} + {% include 'select_all.twig' with { + 'pma_theme_image': pma_theme_image, + 'text_dir': text_dir, + 'form_name': 'dbStatsForm' + } only %} + + {{ get_button_or_image( + '', + 'mult_submit ajax', + 'Drop'|trans, + 'b_deltbl' + ) }} + {% endif %} + + {# Enable statistics #} + {% if not has_statistics %} + {{ 'Note: Enabling the database statistics here might cause heavy traffic between the web server and the MySQL server.'|trans|notice }} + <ul> + <li class="li_switch_dbstats"> + <a href="server_databases.php" data-post="{{ get_common({'statistics': '1'}, '') }}" title="{% trans 'Enable statistics' %}"> + <strong>{% trans 'Enable statistics' %}</strong> + </a> + </li> + </ul> + {% endif %} + </form> + </div> +{% else %} + <p>{{ 'No databases'|trans|notice }}</p> +{% endif %} diff --git a/srcs/phpmyadmin/templates/server/engines/index.twig b/srcs/phpmyadmin/templates/server/engines/index.twig new file mode 100644 index 0000000..2b92dc1 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/engines/index.twig @@ -0,0 +1,27 @@ +<h2> + {{ get_image('b_engine') }} + {% trans 'Storage engines' %} +</h2> + +<table class="noclick"> + <thead> + <tr> + <th>{% trans 'Storage Engine' %}</th> + <th>{% trans 'Description' %}</th> + </tr> + </thead> + <tbody> + {% for engine, details in engines %} + <tr class=" + {{- details['Support'] == 'NO' or details['Support'] == 'DISABLED' ? ' disabled' }} + {{ details['Support'] == 'DEFAULT' ? ' marked' }}"> + <td> + <a rel="newpage" href="server_engines.php{{ get_common({'engine': engine}) }}"> + {{ details['Engine'] }} + </a> + </td> + <td>{{ details['Comment'] }}</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/server/engines/show.twig b/srcs/phpmyadmin/templates/server/engines/show.twig new file mode 100644 index 0000000..088e3a0 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/engines/show.twig @@ -0,0 +1,48 @@ +<h2> + {{ get_image('b_engine') }} + {% trans 'Storage engines' %} +</h2> + +{% if engine is not empty %} + <h2> + {{ get_image('b_engine') }} + {{ engine.title }} + {{ show_mysql_docu(engine.help_page) }} + </h2> + <p><em>{{ engine.comment }}</em></p> + + {% if engine.info_pages is not empty and engine.info_pages is iterable %} + <p> + <strong>[</strong> + {% if page is empty %} + <strong>{% trans 'Variables' %}</strong> + {% else %} + <a href="server_engines.php + {{- get_common({'engine': engine.engine}) }}"> + {% trans 'Variables' %} + </a> + {% endif %} + {% for current, label in engine.info_pages %} + <strong>|</strong> + {% if page is defined and page == current %} + <strong>{{ label }}</strong> + {% else %} + <a href="server_engines.php + {{- get_common({'engine': engine.engine, 'page': current}) }}"> + {{ label }} + </a> + {% endif %} + {% endfor %} + <strong>]</strong> + </p> + {% endif %} + + {% if engine.page is not empty %} + {{ engine.page|raw }} + {% else %} + <p>{{ engine.support }}</p> + {{ engine.variables|raw }} + {% endif %} +{% else %} + <p>{{ 'Unknown storage engine.'|trans|error }}</p> +{% endif %} diff --git a/srcs/phpmyadmin/templates/server/plugins/index.twig b/srcs/phpmyadmin/templates/server/plugins/index.twig new file mode 100644 index 0000000..ec8bbd4 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/plugins/index.twig @@ -0,0 +1,58 @@ +<h2> + {{ get_image('b_plugin') }} + {% trans 'Plugins' %} +</h2> + +<div id="plugins_plugins"> + <div id="sectionlinks"> + {% for type in plugins|keys %} + <a class="btn btn-primary" href="#plugins-{{ clean_types[type] }}"> + {{ type }} + </a> + {% endfor %} + </div> + {% for type, list in plugins %} + <div class="responsivetable"> + <table class="data_full_width" id="plugins-{{ clean_types[type] }}"> + <caption class="tblHeaders"> + {{ type }} + </caption> + <thead> + <tr> + <th>{% trans 'Plugin' %}</th> + <th>{% trans 'Description' %}</th> + <th>{% trans 'Version' %}</th> + <th>{% trans 'Author' %}</th> + <th>{% trans 'License' %}</th> + </tr> + </thead> + <tbody> + {% for plugin in list %} + <tr class="noclick"> + <th> + {{ plugin.name }} + {% if plugin.status != 'ACTIVE' %} + <small class="attention"> + {% if plugin.status == 'INACTIVE' %} + {% trans 'inactive' %} + {% elseif plugin.status == 'DISABLED' %} + {% trans 'disabled' %} + {% elseif plugin.status == 'DELETING' %} + {% trans 'deleting' %} + {% elseif plugin.status == 'DELETED' %} + {% trans 'deleted' %} + {% endif %} + </small> + {% endif %} + </th> + <td>{{ plugin.description }}</td> + <td>{{ plugin.version }}</td> + <td>{{ plugin.author }}</td> + <td>{{ plugin.license }}</td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + {% endfor %} +</div> diff --git a/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig b/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig new file mode 100644 index 0000000..26f0419 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/add_user_fieldset.twig @@ -0,0 +1,8 @@ +<fieldset id="fieldset_add_user"> + <legend>{% trans %}New{% context %}Create new user{% endtrans %}</legend> + <a id="add_user_anchor" href="server_privileges.php{{ get_common(url_params) }}" + {% if rel_params is not empty %} + rel="{{ get_common(rel_params) }}" + {% endif %}> + {{ get_icon('b_usradd') }}{% trans 'Add user account' %}</a> +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig b/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig new file mode 100644 index 0000000..a28f302 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/choose_user_group.twig @@ -0,0 +1,9 @@ +<form class="ajax" id="changeUserGroupForm" action="server_privileges.php" method="post"> + {{ get_hidden_inputs(params) }} + <fieldset id="fieldset_user_group_selection"> + <legend>{% trans 'User group' %}</legend> + {% trans 'User group' %}: + {{ get_dropdown('userGroup', all_user_groups, user_group, 'userGroup_select') }} + <input type="hidden" name="changeUserGroup" value="1"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig b/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig new file mode 100644 index 0000000..b49efa5 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/column_privileges.twig @@ -0,0 +1,24 @@ +<div class="item" id="div_item_{{ name }}"> + <label for="select_{{ name }}_priv"> + <code><dfn title="{{ name_for_dfn }}">{{ priv_for_header }}</dfn></code> + </label> + + <select id="select_{{ name }}_priv" name="{{ name_for_select }}[]" multiple="multiple" size="8"> + {% for curr_col, curr_col_privs in columns %} + <option value="{{ curr_col }}" + {% if row[name_for_select] == 'Y' or curr_col_privs[name_for_current] %} + selected="selected" + {% endif %}> + {{ curr_col }} + </option> + {% endfor %} + </select> + + <em>{% trans 'Or' %}</em> + <label for="checkbox_{{ name_for_select }}_none"> + <input type="checkbox" name="{{ name_for_select }}_none" + id="checkbox_{{ name_for_select }}_none" + title="{% trans %}None{% context %}None privileges{% endtrans %}"> + {% trans %}None{% context %}None privileges{% endtrans %} + </label> +</div> diff --git a/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig b/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig new file mode 100644 index 0000000..84d288f --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/delete_user_fieldset.twig @@ -0,0 +1,17 @@ +<fieldset id="fieldset_delete_user"> + <legend> + {{ get_icon('b_usrdrop') }}{% trans 'Remove selected user accounts' %} + </legend> + <input type="hidden" name="mode" value="2"> + <p>({% trans 'Revoke all active privileges from the users and delete them afterwards.' %})</p> + <input type="checkbox" title="{% trans 'Drop the databases that have the same names as the users.' %}" + name="drop_users_db" id="checkbox_drop_users_db"> + <label for="checkbox_drop_users_db" + title="{% trans 'Drop the databases that have the same names as the users.' %}"> + {% trans 'Drop the databases that have the same names as the users.' %} + </label> +</fieldset> + +<fieldset id="fieldset_delete_user_footer" class="tblFooters"> + <input id="buttonGo" class="btn btn-primary ajax" type="submit" name="delete" value="{% trans 'Go' %}"> +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig b/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig new file mode 100644 index 0000000..12f8433 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/edit_routine_privileges.twig @@ -0,0 +1,26 @@ +<div id="edit_user_dialog"> + {{ header|raw }} + <form class="submenu-item" name="usersForm" id="addUsersForm" action="server_privileges.php" method="post"> + {{ get_hidden_inputs() }} + <input type="hidden" name="username" value="{{ username }}"> + <input type="hidden" name="hostname" value="{{ hostname }}"> + <input type="hidden" name="dbname" value="{{ database }}"> + <input type="hidden" name="routinename" value="{{ routine }}"> + <input type="hidden" name="grant_count" value="{{ grant_count }}"> + <fieldset id="fieldset_user_global_rights"> + <legend data-submenu-label="{% trans 'Routine' %}"> + {% trans 'Routine-specific privileges' %} + </legend> + <p> + <small> + <em>{% trans 'Note: MySQL privilege names are expressed in English.' %}</em> + </small> + </p> + {{ priv_checkboxes|raw }} + </fieldset> + <fieldset id="fieldset_user_privtable_footer" class="tblFooters"> + <input type="hidden" name="update_privs" value="1"> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </fieldset> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig b/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig new file mode 100644 index 0000000..54b1046 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/global_priv_table.twig @@ -0,0 +1,22 @@ +{% for key, table in priv_table %} + <fieldset> + <legend> + <input type="checkbox" class="sub_checkall_box" id="checkall_{{ priv_table_names[key] }}_priv" + title="{% trans 'Check all' %}"> + <label for="checkall_{{ priv_table_names[key] }}_priv">{{ priv_table_names[key] }}</label> + </legend> + {% for priv in table %} + {% set checked = row[priv[0] ~ '_priv'] is defined and row[priv[0] ~ '_priv'] == 'Y' ? ' checked="checked"' %} + {% set formatted_priv = format_privilege(priv, true) %} + <div class="item"> + <input type="checkbox" class="checkall" name="{{ priv[0] }}_priv" id="checkbox_{{ priv[0] }}_priv" + value="Y" title="{{ priv[2] }}" {{ checked }}> + <label for="checkbox_{{ priv[0] }}_priv"> + <code> + {{ formatted_priv|raw }} + </code> + </label> + </div> + {% endfor %} + </fieldset> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/server/privileges/initials_row.twig b/srcs/phpmyadmin/templates/server/privileges/initials_row.twig new file mode 100644 index 0000000..feadc46 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/initials_row.twig @@ -0,0 +1,26 @@ +<table id="initials_table" cellspacing="5"> + <tr> + {% for tmp_initial, initial_was_found in array_initials %} + {% if tmp_initial is not same as(null) %} + {% if initial_was_found %} + <td> + <a class="ajax + {{- initial is defined and initial is same as(tmp_initial) ? ' active' -}} + " href="server_privileges.php + {{- get_common({'initial': tmp_initial}) }}"> + {{- tmp_initial|raw -}} + </a> + </td> + {% else %} + <td>{{ tmp_initial|raw }}</td> + {% endif %} + {% endif %} + {% endfor %} + <td> + <a href="server_privileges.php + {{- get_common({'showall': 1}) }}" class="nowrap"> + {% trans 'Show all' %} + </a> + </td> + </tr> +</table> diff --git a/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig b/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig new file mode 100644 index 0000000..438ecb7 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/privileges_summary.twig @@ -0,0 +1,104 @@ +<form class="submenu-item" action="server_privileges.php" id="{{ form_id }}" method="post"> + {{ get_hidden_inputs() }} + <input type="hidden" name="username" value="{{ username }}"> + <input type="hidden" name="hostname" value="{{ hostname }}"> + + <fieldset> + <legend data-submenu-label="{{ sub_menu_label }}"> + {{ legend }} + </legend> + + <table class="data"> + <thead> + <tr> + <th>{{ type_label }}</th> + <th>{% trans 'Privileges' %}</th> + <th>{% trans 'Grant' %}</th> + {% if type == 'database' %} + <th>{% trans 'Table-specific privileges' %}</th> + {% elseif type == 'table' %} + <th>{% trans 'Column-specific privileges' %}</th> + {% endif %} + <th colspan="2">{% trans 'Action' %}</th> + </tr> + </thead> + + <tbody> + {% if privileges|length == 0 %} + {% set colspan = type == 'database' ? 7 : (type == 'table' ? 6 : 5) %} + <tr> + <td colspan="{{ colspan }}"><center><em>{% trans 'None' %}</em></center></td> + </tr> + {% else %} + {% for privilege in privileges %} + <tr> + <td>{{ privilege['name'] }}</td> + <td><code>{{ privilege['privileges']|raw }}</code></td> + <td>{{ privilege['grant'] ? 'Yes'|trans : 'No'|trans }}</td> + + {% if type == 'database' %} + <td>{{ privilege['table_privs'] ? 'Yes'|trans : 'No'|trans }}</td> + {% elseif type == 'table' %} + <td>{{ privilege['column_privs'] ? 'Yes'|trans : 'No'|trans }}</td> + {% endif %} + + <td>{{ privilege['edit_link']|raw }}</td> + <td>{{ privilege['revoke_link']|raw }}</td> + </tr> + {% endfor %} + {% endif %} + </tbody> + </table> + + {% if type == 'database' %} + <label for="text_dbname">{% trans 'Add privileges on the following database(s):' %}</label> + + {%- if databases is not empty %} + <select name="pred_dbname[]" multiple="multiple"> + {% for database in databases %} + <option value="{{ database|escape_mysql_wildcards }}"> + {{ database }} + </option> + {% endfor %} + </select> + {% endif -%} + + <input type="text" id="text_dbname" name="dbname"> + {{ show_hint("Wildcards % and _ should be escaped with a \\ to use them literally."|trans) }} + {% elseif type == 'table' %} + <input type="hidden" name="dbname" value="{{ database }}"> + + <label for="text_tablename">{% trans 'Add privileges on the following table:' %}</label> + + {%- if tables is not empty %} + <select name="pred_tablename" class="autosubmit"> + <option value="" selected="selected">{% trans 'Use text field' %}:</option> + {% for table in tables %} + <option value="{{ table }}">{{ table }}</option> + {% endfor %} + </select> + {% endif -%} + + <input type="text" id="text_tablename" name="tablename"> + {% else %} + <input type="hidden" name="dbname" value="{{ database }}"> + + <label for="text_routinename">{% trans 'Add privileges on the following routine:' %}</label> + + {%- if routines is not empty %} + <select name="pred_routinename" class="autosubmit"> + <option value="" selected="selected">{% trans 'Use text field' %}:</option> + {% for routine in routines %} + <option value="{{ routine }}">{{ routine }}</option> + {% endfor %} + </select> + {% endif -%} + + <input type="text" id="text_routinename" name="routinename"> + {% endif %} + </fieldset> + + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/server/privileges/require_options.twig b/srcs/phpmyadmin/templates/server/privileges/require_options.twig new file mode 100644 index 0000000..03da691 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/require_options.twig @@ -0,0 +1,32 @@ +<fieldset> + <legend>SSL</legend> + <div id="require_ssl_div"> + {% for require_option in require_options %} + {% if require_option['name'] is same as('ssl_cipher') %} + <div id="specified_div" style="padding-left:20px;"> + {% endif %} + <div class="item"> + {% if require_option['radio'] %} + <input type="radio" name="ssl_type" + id="{{ require_option['name'] }}_{{ require_option['value'] }}" + title="{{ require_option['description'] }}" + value="{{ require_option['value'] }}" {{ require_option['checked']|raw }}> + <label for="{{ require_option['name'] }}_{{ require_option['value'] }}"> + <code>{{ require_option['label'] }}</code> + </label> + {% else %} + <label for="text_{{ require_option['name'] }}"> + <code>{{ require_option['label'] }}</code> + </label> + <input type="text" name="{{ require_option['name'] }}" + id="text_{{ require_option['name'] }}" value="{{ require_option['value'] }}" + size="80" title="{{ require_option['description'] }}" + {%- if require_option['disabled'] %} + disabled + {%- endif %}> + {% endif %} + </div> + {% endfor %} + </div>{# END specified_div #} + </div>{# END require_ssl_div #} +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig b/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig new file mode 100644 index 0000000..2569bd7 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/privileges/resource_limits.twig @@ -0,0 +1,21 @@ +<fieldset> + <legend>{% trans 'Resource limits' %}</legend> + <p> + <small> + <em>{% trans 'Note: Setting these options to 0 (zero) removes the limit.' %}</em> + </small> + </p> + {% for limit in limits %} + <div class="item"> + <label for="text_{{ limit['input_name'] }}"> + <code> + <dfn title="{{ limit['description'] }}"> + {{ limit['name_main'] }} + </dfn> + </code> + </label> + <input type="number" name="{{ limit['input_name'] }}" id="text_{{ limit['input_name'] }}" + value="{{ limit['value'] }}" title="{{ limit['description'] }}"> + </div> + {% endfor %} +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/replication/change_master.twig b/srcs/phpmyadmin/templates/server/replication/change_master.twig new file mode 100644 index 0000000..1ff75ba --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/change_master.twig @@ -0,0 +1,35 @@ +<form method="post" action="server_replication.php"> + {{ get_hidden_inputs('', '') }} + <fieldset id="fieldset_add_user_login"> + <legend> + {% trans 'Slave configuration' %} - + {% trans 'Change or reconfigure master server' %} + </legend> + <p> + {% trans 'Make sure you have a unique server-id in your configuration file (my.cnf). If not, please add the following line into [mysqld] section:' %} + </p> + <pre>server-id={{ server_id }}</pre> + + <div class="item"> + <label for="text_username">{% trans 'User name:' %}</label> + <input id="text_username" name="username" type="text" maxlength="{{ username_length }}" title="{% trans 'User name' %}" required> + </div> + <div class="item"> + <label for="text_pma_pw">{% trans 'Password:' %}</label> + <input id="text_pma_pw" name="pma_pw" type="password" title="{% trans 'Password' %}" required> + </div> + <div class="item"> + <label for="text_hostname">{% trans 'Host:' %}</label> + <input id="text_hostname" name="hostname" type="text" maxlength="{{ hostname_length }}" value="" required> + </div> + <div class="item"> + <label for="text_port">{% trans 'Port:' %}</label> + <input id="text_port" name="text_port" type="number" maxlength="6" value="3306" required> + </div> + </fieldset> + <fieldset id="fieldset_user_privtable_footer" class="tblFooters"> + <input type="hidden" name="sr_take_action" value="true"> + <input type="hidden" name="{{ submit_name }}" value="1"> + <input class="btn btn-primary" type="submit" id="confslave_submit" value="{% trans 'Go' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/server/replication/database_multibox.twig b/srcs/phpmyadmin/templates/server/replication/database_multibox.twig new file mode 100644 index 0000000..816db08 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/database_multibox.twig @@ -0,0 +1,9 @@ +<select id="db_select" class="width96" name="db_select[]" size="6" multiple> + {% for database in databases %} + <option value="{{ database }}">{{ database }}</option> + {% endfor %} +</select> +<p> + <a href="#" id="db_select_href">{% trans 'Select all' %}</a> / + <a href="#" id="db_reset_href">{% trans 'Unselect all' %}</a> +</p> diff --git a/srcs/phpmyadmin/templates/server/replication/index.twig b/srcs/phpmyadmin/templates/server/replication/index.twig new file mode 100644 index 0000000..c40df0d --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/index.twig @@ -0,0 +1,36 @@ +<h2> + {{ get_image('s_replication') }} + {% trans 'Replication' %} +</h2> + +{% if is_super_user %} + <div id="replication"> + {{ error_messages|raw }} + + {% if is_master %} + {{ master_replication_html|raw }} + {% elseif master_configure is null and clear_screen is null %} + <fieldset> + <legend>{% trans 'Master replication' %}</legend> + {% apply format('<a href="server_replication.php" data-post="' ~ get_common(url_params|merge({'mr_configure': true}), '') ~ '">', '</a>')|raw %} + {% trans %} + This server is not configured as master in a replication process. Would you like to %sconfigure%s it? + {% endtrans %} + {% endapply %} + </fieldset> + {% endif %} + + {% if master_configure is not null %} + {{ master_configuration_html|raw }} + {% else %} + {% if clear_screen is null %} + {{ slave_configuration_html|raw }} + {% endif %} + {% if slave_configure is not null %} + {{ change_master_html|raw }} + {% endif %} + {% endif %} + </div> +{% else %} + {{ 'No privileges'|trans|error }} +{% endif %} diff --git a/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig b/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig new file mode 100644 index 0000000..5c2eec3 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/master_add_slave_user.twig @@ -0,0 +1,84 @@ +<div id="master_addslaveuser_gui"> + <form action="server_privileges.php" method="post" autocomplete="off" onsubmit="return checkAddUser(this);"> + {{ get_hidden_inputs('', '') }} + + <fieldset id="fieldset_add_user_login"> + <legend>{% trans 'Add slave replication user' %}</legend> + + <input type="hidden" name="grant_count" value="25"> + <input type="hidden" name="createdb" id="createdb_0" value="0"> + {# Needed for the replication slaves. #} + <input type="hidden" name="Repl_slave_priv" id="checkbox_Repl_slave_priv" value="Y"> + <input type="hidden" name="sr_take_action" value="true"> + + <div class="item"> + <label for="select_pred_username"> + {% trans 'User name:' %} + </label> + <span class="options"> + <select name="pred_username" id="select_pred_username" title="{% trans 'User name' %}"> + <option value="any"{{ predefined_username == 'any' ? ' selected' }}>{% trans 'Any user' %}</option> + <option value="userdefined"{{ predefined_username == 'userdefined' ? ' selected' }}>{% trans 'Use text field:' %}</option> + </select> + </span> + <input type="text" name="username" id="pma_username" maxlength="{{ username_length }}" title="{% trans 'User name' %}" value="{{ username }}"> + </div> + + <div class="item"> + <label for="select_pred_hostname"> + {% trans 'Host:' %} + </label> + <span class="options"> + <select name="pred_hostname" id="select_pred_hostname" title="{% trans 'Host' %}" + {%- if this_host is not null %} data-thishost="{{ this_host }}"{% endif %}> + <option value="any"{{ predefined_hostname == 'any' ? ' selected' }}>{% trans 'Any host' %}</option> + <option value="localhost"{{ predefined_hostname == 'localhost' ? ' selected' }}>{% trans 'Local' %}</option> + {% if this_host is not null %} + <option value="thishost"{{ predefined_hostname == 'thishost' ? ' selected' }}>{% trans 'This host' %}</option> + {% endif %} + <option value="hosttable"{{ predefined_hostname == 'hosttable' ? ' selected' }}>{% trans 'Use host table' %}</option> + <option value="userdefined"{{ predefined_hostname == 'userdefined' ? ' selected' }}>{% trans 'Use text field:' %}</option> + </select> + </span> + <input type="text" name="hostname" id="pma_hostname" maxlength="{{ hostname_length }}" title="{% trans 'Host' %}" value="{{ hostname }}"> + {{ show_hint('When Host table is used, this field is ignored and values stored in Host table are used instead.'|trans) }} + </div> + + <div class="item"> + <label for="select_pred_password"> + {% trans 'Password:' %} + </label> + <span class="options"> + <select name="pred_password" id="select_pred_password" title="{% trans 'Password' %}"> + <option value="none"{{ has_username ? ' selected' }}>{% trans 'No password' %}</option> + <option value="userdefined"{{ not has_username ? ' selected' }}>{% trans 'Use text field:' %}</option> + </select> + </span> + <input type="password" id="text_pma_pw" name="pma_pw" title="{% trans 'Password' %}"> + </div> + + <div class="item"> + <label for="text_pma_pw2"> + {% trans 'Re-type:' %} + </label> + <span class="options"></span> + <input type="password" id="text_pma_pw2" name="pma_pw2" title="{% trans 'Re-type' %}"> + </div> + + <div class="item"> + <label for="button_generate_password"> + {% trans 'Generate password:' %} + </label> + <span class="options"> + <input type="button" class="btn btn-secondary button" id="button_generate_password" value="{% trans 'Generate' %}" onclick="Functions.suggestPassword(this.form)"> + </span> + <input type="text" name="generated_pw" id="generated_pw"> + </div> + </fieldset> + + <fieldset id="fieldset_user_privtable_footer" class="tblFooters"> + <input type="hidden" name="adduser_submit" value="1"> + <input class="btn btn-primary" type="submit" id="adduser_submit" value="{% trans 'Go' %}"> + </fieldset> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/server/replication/master_configuration.twig b/srcs/phpmyadmin/templates/server/replication/master_configuration.twig new file mode 100644 index 0000000..5243bac --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/master_configuration.twig @@ -0,0 +1,32 @@ +<fieldset> + <legend>{% trans 'Master configuration' %}</legend> + <p> + {% trans %} + This server is not configured as a master server in a replication process. You can choose from either replicating all databases and ignoring some of them (useful if you want to replicate a majority of the databases) or you can choose to ignore all databases by default and allow only certain databases to be replicated. Please select the mode: + {% endtrans %} + </p> + <select name="db_type" id="db_type"> + <option value="all">{% trans 'Replicate all databases; Ignore:' %}</option> + <option value="ign">{% trans 'Ignore all databases; Replicate:' %}</option> + </select> + <p>{% trans 'Please select databases:' %}</p> + {{ database_multibox|raw }} + <p> + {% trans %} + Now, add the following lines at the end of [mysqld] section in your my.cnf and please restart the MySQL server afterwards. + {% endtrans %} + </p> + <pre id="rep"></pre> + <p> + {% trans %} + Once you restarted MySQL server, please click on Go button. Afterwards, you should see a message informing you, that this server <strong>is</strong> configured as master. + {% endtrans %} + </p> +</fieldset> + +<fieldset class="tblFooters"> + <form method="post" action="server_replication.php"> + {{ get_hidden_inputs('', '') }} + <input id="goButton" class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </form> +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/replication/master_replication.twig b/srcs/phpmyadmin/templates/server/replication/master_replication.twig new file mode 100644 index 0000000..8ba5d1b --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/master_replication.twig @@ -0,0 +1,52 @@ +{% if not clear_screen %} + <fieldset> + <legend>{% trans 'Master replication' %}</legend> + {% trans 'This server is configured as master in a replication process.' %} + <ul> + <li> + <a href="#master_status_href" id="master_status_href"> + {% trans 'Show master status' %} + </a> + {{ master_status_table|raw }} + </li> + <li> + <p> + <a href="#master_slaves_href" id="master_slaves_href"> + {% trans 'Show connected slaves' %} + </a> + </p> + + <div id="replication_slaves_section" style="display: none;"> + <table class="data"> + <thead> + <tr> + <th>{% trans 'Server ID' %}</th> + <th>{% trans 'Host' %}</th> + </tr> + </thead> + <tbody> + {% for slave in slaves %} + <tr> + <td class="value">{{ slave['Server_id'] }}</td> + <td class="value">{{ slave['Host'] }}</td> + </tr> + {% endfor %} + </tbody> + </table> + <br> + {{ 'Only slaves started with the --report-host=host_name option are visible in this list.'|trans|notice }} + <br> + </div> + </li> + <li> + <a href="server_replication.php" data-post="{{ get_common(url_params, '') }}" id="master_addslaveuser_href"> + {% trans 'Add slave replication user' %} + </a> + </li> +{% endif %} +{% if master_add_user %} + {{ master_add_slave_user|raw }} +{% elseif not clear_screen %} + </ul> + </fieldset> +{% endif %} diff --git a/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig b/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig new file mode 100644 index 0000000..5b12ea7 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/slave_configuration.twig @@ -0,0 +1,109 @@ +<fieldset> + <legend>{% trans 'Slave replication' %}</legend> + {% if server_slave_multi_replication %} + {% trans 'Master connection:' %} + <form method="get" action="server_replication.php"> + {{ get_hidden_inputs(url_params) }} + <select name="master_connection"> + <option value="">{% trans 'Default' %}</option> + {% for server in server_slave_multi_replication %} + <option value="{{ server['Connection_name'] }}"{{ master_connection == server['Connection_name'] ? ' selected' }}> + {{ server['Connection_name'] }} + </option> + {% endfor %} + </select> + <input id="goButton" class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </form> + <br> + <br> + {% endif %} + + {% if server_slave_status %} + <div id="slave_configuration_gui"> + {% if not slave_sql_running %} + {{ 'Slave SQL Thread not running!'|trans|error }} + {% endif %} + {% if not slave_io_running %} + {{ 'Slave IO Thread not running!'|trans|error }} + {% endif %} + + <p>{% trans 'Server is configured as slave in a replication process. Would you like to:' %}</p> + <ul> + <li> + <a href="#slave_status_href" id="slave_status_href">{% trans 'See slave status table' %}</a> + {{ slave_status_table|raw }} + </li> + <li> + <a href="#slave_control_href" id="slave_control_href">{% trans 'Control slave:' %}</a> + <div id="slave_control_gui" class="hide"> + <ul> + <li> + <a href="server_replication.php" data-post="{{ slave_control_full_link }}"> + {{ not slave_io_running or not slave_sql_running ? 'Full start' : 'Full stop' }} + </a> + </li> + <li> + <a class="ajax" id="reset_slave" href="server_replication.php" data-post="{{ slave_control_reset_link }}"> + {% trans 'Reset slave' %} + </a> + </li> + <li> + <a href="server_replication.php" data-post="{{ slave_control_sql_link }}"> + {% if not slave_sql_running %} + {% trans 'Start SQL Thread only' %} + {% else %} + {% trans 'Stop SQL Thread only' %} + {% endif %} + </a> + </li> + <li> + <a href="server_replication.php" data-post="{{ slave_control_io_link }}"> + {% if not slave_io_running %} + {% trans 'Start IO Thread only' %} + {% else %} + {% trans 'Stop IO Thread only' %} + {% endif %} + </a> + </li> + </ul> + </div> + </li> + <li> + <a href="#slave_errormanagement_href" id="slave_errormanagement_href"> + {% trans 'Error management:' %} + </a> + <div id="slave_errormanagement_gui" class="hide"> + {{ 'Skipping errors might lead into unsynchronized master and slave!'|trans|error }} + <ul> + <li> + <a href="server_replication.php" data-post="{{ slave_skip_error_link }}"> + {% trans 'Skip current error' %} + </a> + </li> + <li> + <form method="post" action="server_replication.php"> + {{ get_hidden_inputs('', '') }} + {{ 'Skip next %s errors.'|trans|format('<input type="text" name="sr_skip_errors_count" value="1" class="repl_gui_skip_err_cnt">')|raw }} + <input class="btn btn-primary" type="submit" name="sr_slave_skip_error" value="{% trans 'Go' %}"> + <input type="hidden" name="sr_take_action" value="1"> + </form> + </li> + </ul> + </div> + </li> + <li> + <a href="server_replication.php" data-post="{{ reconfigure_master_link }}"> + {% trans 'Change or reconfigure master server' %} + </a> + </li> + </ul> + </div> + {% elseif not has_slave_configure %} + {% apply format('<a href="server_replication.php" data-post="' ~ get_common(url_params|merge({ + 'sl_configure': true, + 'repl_clear_scr': true + })) ~ '">', '</a>')|raw %} + {% trans 'This server is not configured as slave in a replication process. Would you like to %sconfigure%s it?' %} + {% endapply %} + {% endif %} +</fieldset> diff --git a/srcs/phpmyadmin/templates/server/replication/status_table.twig b/srcs/phpmyadmin/templates/server/replication/status_table.twig new file mode 100644 index 0000000..79c45f6 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/replication/status_table.twig @@ -0,0 +1,34 @@ +<div id="replication_{{ type }}_section"{{ is_hidden ? ' style="display: none;"' }}> + {% if has_title %} + <h4> + <a id="replication_{{ type }}"></a> + {% if type == 'master' %} + {% trans 'Master status' %} + {% else %} + {% trans 'Slave status' %} + {% endif %} + </h4> + {% endif %} + + <table id="server{{ type }}replicationsummary" class="data"> + <thead> + <tr> + <th>{% trans 'Variable' %}</th> + <th>{% trans 'Value' %}</th> + </tr> + </thead> + + <tbody> + {% for variable in variables %} + <tr> + <td class="name">{{ variable.name }}</td> + <td class="value"> + <span{% if variable.status == 'attention' %} class="attention"{% elseif variable.status == 'allfine' %} class="allfine"{% endif %}> + {{ variable.value }} + </span> + </td> + </tr> + {% endfor %} + </tbody> + </table> +</div> diff --git a/srcs/phpmyadmin/templates/server/status/advisor/index.twig b/srcs/phpmyadmin/templates/server/status/advisor/index.twig new file mode 100644 index 0000000..b1bc3a9 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/advisor/index.twig @@ -0,0 +1,39 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'advisor' %} + +{% block content %} + + {% if data is not empty %} + <a href="#openAdvisorInstructions">{{ get_icon('b_help', 'Instructions'|trans) }}</a> + + <div id="statustabs_advisor"></div> + + <div id="advisorInstructionsDialog" class="hide"> + <p> + {% trans %} + The Advisor system can provide recommendations on server variables by analyzing the server status variables. + {% endtrans %} + </p> + <p> + {% trans %} + Do note however that this system provides recommendations based on simple calculations and by rule of thumb which may not necessarily apply to your system. + {% endtrans %} + </p> + <p> + {% trans %} + Prior to changing any of the configuration, be sure to know what you are changing (by reading the documentation) and how to undo the change. Wrong tuning can have a very negative effect on performance. + {% endtrans %} + </p> + <p> + {% trans %} + The best way to tune your system would be to change only one setting at a time, observe or benchmark your database, and undo the change if there was no clearly measurable improvement. + {% endtrans %} + </p> + </div> + + <div id="advisorData" class="hide">{{ data }}</div> + {% else %} + {{ 'Not enough privilege to view the advisor.'|trans|error }} + {% endif %} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/status/base.twig b/srcs/phpmyadmin/templates/server/status/base.twig new file mode 100644 index 0000000..66547a8 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/base.twig @@ -0,0 +1,39 @@ +<div> + <ul id="topmenu2"> + <li> + <a href="server_status.php{{ get_common() }}"{{ active == 'status' ? ' class="tabactive"' }}> + {% trans 'Server' %} + </a> + </li> + <li> + <a href="server_status_processes.php{{ get_common() }}"{{ active == 'processes' ? ' class="tabactive"' }}> + {% trans 'Processes' %} + </a> + </li> + <li> + <a href="server_status_queries.php{{ get_common() }}"{{ active == 'queries' ? ' class="tabactive"' }}> + {% trans 'Query statistics' %} + </a> + </li> + <li> + <a href="server_status_variables.php{{ get_common() }}"{{ active == 'variables' ? ' class="tabactive"' }}> + {% trans 'All status variables' %} + </a> + </li> + <li> + <a href="server_status_monitor.php{{ get_common() }}"{{ active == 'monitor' ? ' class="tabactive"' }}> + {% trans 'Monitor' %} + </a> + </li> + <li> + <a href="server_status_advisor.php{{ get_common() }}"{{ active == 'advisor' ? ' class="tabactive"' }}> + {% trans 'Advisor' %} + </a> + </li> + </ul> + <div class="clearfloat"></div> + + <div> + {% block content %}{% endblock %} + </div> +</div> diff --git a/srcs/phpmyadmin/templates/server/status/monitor/index.twig b/srcs/phpmyadmin/templates/server/status/monitor/index.twig new file mode 100644 index 0000000..c4c7277 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/monitor/index.twig @@ -0,0 +1,268 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'monitor' %} +{% block content %} + +<div class="tabLinks"> + <a href="#pauseCharts"> + {{ get_image('play') }} + {% trans 'Start Monitor' %} + </a> + <a href="#settingsPopup" class="popupLink"> + {{ get_image('s_cog') }} + {% trans 'Settings' %} + </a> + <a href="#monitorInstructionsDialog"> + {{ get_image('b_help') }} + {% trans 'Instructions/Setup' %} + </a> + <a href="#endChartEditMode" class="hide"> + {{ get_image('s_okay') }} + {% trans 'Done dragging (rearranging) charts' %} + </a> +</div> + +<div class="popupContent settingsPopup"> + <a href="#addNewChart"> + {{ get_image('b_chart') }} + {% trans 'Add chart' %} + </a> + <a href="#rearrangeCharts"> + {{ get_image('b_tblops') }} + {% trans 'Enable charts dragging' %} + </a> + <div class="clearfloat paddingtop"></div> + + <div class="floatleft"> + {% trans 'Refresh rate' %} + <br> + <select id="id_gridChartRefresh" class="refreshRate" name="gridChartRefresh"> + {% for rate in [2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200] %} + <option value="{{ rate }}"{{ rate == 5 ? ' selected' }}> + {% if rate < 60 %} + {% if rate == 1 %} + {{ '%d second'|trans|format(rate) }} + {% else %} + {{ '%d seconds'|trans|format(rate) }} + {% endif %} + {% else %} + {% if rate / 60 == 1 %} + {{ '%d minute'|trans|format(rate / 60) }} + {% else %} + {{ '%d minutes'|trans|format(rate / 60) }} + {% endif %} + {% endif %} + </option> + {% endfor %} + </select> + <br> + </div> + + <div class="floatleft"> + {% trans 'Chart columns' %} + <br> + <select name="chartColumns"> + <option>1</option> + <option>2</option> + <option>3</option> + <option>4</option> + <option>5</option> + <option>6</option> + </select> + </div> + + <div class="clearfloat paddingtop"> + <strong>{% trans 'Chart arrangement' %}</strong> + {{ show_hint('The arrangement of the charts is stored to the browsers local storage. You may want to export it if you have a complicated set up.'|trans) }} + <br> + <a class="ajax" href="#importMonitorConfig"> + {% trans 'Import' %} + </a> - + <a class="disableAjax" href="#exportMonitorConfig"> + {% trans 'Export' %} + </a> - + <a href="#clearMonitorConfig"> + {% trans 'Reset to default' %} + </a> + </div> +</div> + +<div id="monitorInstructionsDialog" title="{% trans 'Monitor Instructions' %}" class="hide"> + <p> + {% trans %} + The phpMyAdmin Monitor can assist you in optimizing the server configuration and track down time intensive queries. For the latter you will need to set log_output to 'TABLE' and have either the slow_query_log or general_log enabled. Note however, that the general_log produces a lot of data and increases server load by up to 15%. + {% endtrans %} + </p> + <img class="ajaxIcon" src="{{ image_path }}ajax_clock_small.gif" alt="{% trans 'Loading…' %}"> + + <div class="ajaxContent"></div> + <br> + + <div class="monitorUse hide"> + <p><strong>{% trans 'Using the monitor:' %}</strong></p> + <p> + {% trans %} + Your browser will refresh all displayed charts in a regular interval. You may add charts and change the refresh rate under 'Settings', or remove any chart using the cog icon on each respective chart. + {% endtrans %} + </p> + <p> + {% trans %} + To display queries from the logs, select the relevant time span on any chart by holding down the left mouse button and panning over the chart. Once confirmed, this will load a table of grouped queries, there you may click on any occurring SELECT statements to further analyze them. + {% endtrans %} + </p> + <p> + {{ get_image('s_attention') }} + <strong>{% trans 'Please note:' %}</strong> + </p> + <p> + {% trans %} + Enabling the general_log may increase the server load by 5-15%. Also be aware that generating statistics from the logs is a load intensive task, so it is advisable to select only a small time span and to disable the general_log and empty its table once monitoring is not required any more. + {% endtrans %} + </p> + </div> +</div> + +<div id="addChartDialog" title="{% trans 'Add chart' %}" class="hide"> + <div id="tabGridVariables"> + <p> + <input type="text" name="chartTitle" value="{% trans 'Chart Title' %}"> + </p> + <input type="radio" name="chartType" value="preset" id="chartPreset"> + + <label for="chartPreset">{% trans 'Preset chart' %}</label> + <select name="presetCharts"></select> + <br> + + <input type="radio" name="chartType" value="variable" id="chartStatusVar" checked="checked"> + <label for="chartStatusVar"> + {% trans 'Status variable(s)' %} + </label> + <br> + + <div id="chartVariableSettings"> + <label for="chartSeries">{% trans 'Select series:' %}</label> + <br> + <select id="chartSeries" name="varChartList" size="1"> + <option>{% trans 'Commonly monitored' %}</option> + <option>Processes</option> + <option>Questions</option> + <option>Connections</option> + <option>Bytes_sent</option> + <option>Bytes_received</option> + <option>Threads_connected</option> + <option>Created_tmp_disk_tables</option> + <option>Handler_read_first</option> + <option>Innodb_buffer_pool_wait_free</option> + <option>Key_reads</option> + <option>Open_tables</option> + <option>Select_full_join</option> + <option>Slow_queries</option> + </select> + <br> + + <label for="variableInput"> + {% trans 'or type variable name:' %} + </label> + <input type="text" name="variableInput" id="variableInput"> + <br> + + <input type="checkbox" name="differentialValue" id="differentialValue" value="differential" checked="checked"> + <label for="differentialValue"> + {% trans 'Display as differential value' %} + </label> + <br> + + <input type="checkbox" id="useDivisor" name="useDivisor" value="1"> + <label for="useDivisor">{% trans 'Apply a divisor' %}</label> + + <span class="divisorInput hide"> + <input type="text" name="valueDivisor" size="4" value="1"> + (<a href="#kibDivisor">{% trans 'KiB' %}</a>, + <a href="#mibDivisor">{% trans 'MiB' %}</a>) + </span> + <br> + + <input type="checkbox" id="useUnit" name="useUnit" value="1"> + <label for="useUnit"> + {% trans 'Append unit to data values' %} + </label> + <span class="unitInput hide"> + <input type="text" name="valueUnit" size="4" value=""> + </span> + + <p> + <a href="#submitAddSeries"> + <strong>{% trans 'Add this series' %}</strong> + </a> + <span id="clearSeriesLink" class="hide"> + | <a href="#submitClearSeries">{% trans 'Clear series' %}</a> + </span> + </p> + + {% trans 'Series in chart:' %} + <br> + <span id="seriesPreview"> + <em>{% trans 'None' %}</em> + </span> + </div> + </div> +</div> + +<div id="logAnalyseDialog" title="{% trans 'Log statistics' %}" class="hide"> + <p> + {% trans 'Selected time range:' %} + <input type="text" name="dateStart" class="datetimefield" value=""> + - + <input type="text" name="dateEnd" class="datetimefield" value=""> + </p> + + <input type="checkbox" id="limitTypes" value="1" checked="checked"> + <label for="limitTypes"> + {% trans 'Only retrieve SELECT,INSERT,UPDATE and DELETE Statements' %} + </label> + <br> + + <input type="checkbox" id="removeVariables" value="1" checked="checked"> + <label for="removeVariables"> + {% trans 'Remove variable data in INSERT statements for better grouping' %} + </label> + + <p> + {% trans 'Choose from which log you want the statistics to be generated from.' %} + </p> + <p> + {% trans 'Results are grouped by query text.' %} + </p> +</div> + +<div id="queryAnalyzerDialog" title="{% trans 'Query analyzer' %}" class="hide"> + <textarea id="sqlquery"></textarea> + <br> + <div class="placeHolder"></div> +</div> + +<table class="clearfloat tdblock" id="chartGrid"></table> +<div id="logTable"><br></div> + +<script type="text/javascript"> + var variableNames = [ + {% for variable_name in javascript_variable_names %} + "{{ variable_name|e('js') }}", + {% endfor %} + ]; +</script> + +<form id="js_data" class="hide"> + {% for name, value in form %} + <input type="hidden" name="{{ name }}" value="{{ value }}"> + {% endfor %} +</form> + +<div id="profiling_docu" class="hide"> + {{ show_mysql_docu('general-thread-states') }} +</div> + +<div id="explain_docu" class="hide"> + {{ show_mysql_docu('explain-output') }} +</div> + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/status/processes/index.twig b/srcs/phpmyadmin/templates/server/status/processes/index.twig new file mode 100644 index 0000000..bb73156 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/processes/index.twig @@ -0,0 +1,53 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'processes' %} +{% block content %} + +<fieldset id="tableFilter"> + <legend>{% trans 'Filters' %}</legend> + <form action="server_status_processes.php" method="post"> + {{ get_hidden_inputs(url_params) }} + <input class="btn btn-secondary" type="submit" value="{% trans 'Refresh' %}"> + <div class="formelement"> + <input type="checkbox" name="showExecuting" id="showExecuting" class="autosubmit"{{ is_checked ? ' checked' }}> + <label for="showExecuting"> + {% trans 'Show only active' %} + </label> + </div> + </form> +</fieldset> + +{{ server_process_list|raw }} + +{{ 'Note: Enabling the auto refresh here might cause heavy traffic between the web server and the MySQL server.'|trans|notice }} + +<div class="tabLinks"> + <label> + {% trans 'Refresh rate' %}: + + <select id="id_refreshRate" class="refreshRate" name="refreshRate"> + {% for rate in [2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200] %} + <option value="{{ rate }}"{{ rate == 5 ? ' selected' }}> + {% if rate < 60 %} + {% if rate == 1 %} + {{ '%d second'|trans|format(rate) }} + {% else %} + {{ '%d seconds'|trans|format(rate) }} + {% endif %} + {% else %} + {% if rate / 60 == 1 %} + {{ '%d minute'|trans|format(rate / 60) }} + {% else %} + {{ '%d minutes'|trans|format(rate / 60) }} + {% endif %} + {% endif %} + </option> + {% endfor %} + </select> + </label> + <a id="toggleRefresh" href="#"> + {{ get_image('play') }} + {% trans 'Start auto refresh' %} + </a> +</div> + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/status/processes/list.twig b/srcs/phpmyadmin/templates/server/status/processes/list.twig new file mode 100644 index 0000000..83561f9 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/processes/list.twig @@ -0,0 +1,65 @@ +<div class="responsivetable"> + <table id="tableprocesslist" class="data clearfloat noclick sortable"> + <thead> + <tr> + <th>{% trans 'Processes' %}</th> + {% for column in columns %} + <th> + <a href="server_status_processes.php" data-post="{{ get_common(column.params) }}" class="sortlink"> + {{ column.name }} + {% if column.is_sorted %} + <img class="icon ic_s_desc soimg" alt=" + {%- trans 'Descending' %}" src="themes/dot.gif" style="display: {{ column.sort_order == 'DESC' ? 'none' : 'inline' }}"> + <img class="icon ic_s_asc soimg hide" alt=" + {%- trans 'Ascending' %}" src="themes/dot.gif" style="display: {{ column.sort_order == 'DESC' ? 'inline' : 'none' }}"> + {% endif %} + </a> + {% if column.has_full_query %} + <a href="server_status_processes.php" data-post="{{ get_common(refresh_params, '') }}"> + {% if column.is_full %} + {{ get_image( + 's_partialtext', + 'Truncate shown queries'|trans, + {'class': 'icon_fulltext'} + ) }} + {% else %} + {{ get_image( + 's_fulltext', + 'Show full queries'|trans, + {'class': 'icon_fulltext'} + ) }} + {% endif %} + </a> + {% endif %} + </th> + {% endfor %} + </tr> + </thead> + + <tbody> + {% for row in rows %} + <tr> + <td> + <a class="ajax kill_process" href="server_status_processes.php" data-post="{{ get_common({'kill': row.id}, '') }}"> + {% trans 'Kill' %} + </a> + </td> + <td class="value">{{ row.id }}</td> + <td>{{ row.user }}</td> + <td>{{ row.host }}</td> + <td> + {% if row.db != '' %} + {{ row.db }} + {% else %} + <em>{% trans 'None' %}</em> + {% endif %} + </td> + <td>{{ row.command }}</td> + <td class="value">{{ row.time }}</td> + <td>{{ row.state }}</td> + <td>{{ row.progress }}</td> + <td>{{ row.info|raw }}</td> + {% endfor %} + </tbody> + </table> +</div> diff --git a/srcs/phpmyadmin/templates/server/status/queries/index.twig b/srcs/phpmyadmin/templates/server/status/queries/index.twig new file mode 100644 index 0000000..be743b9 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/queries/index.twig @@ -0,0 +1,56 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'queries' %} +{% block content %} + +{% if is_data_loaded %} + <h3 id="serverstatusqueries"> + {% trans %} + Questions since startup: + {% notes %} + Questions is the name of a MySQL Status variable + {% endtrans %} + {{ format_number(stats.total, 0) }} + {{ show_mysql_docu('server-status-variables', false, null, null, 'statvar_Questions') }} + </h3> + + <ul> + <li>ø {% trans 'per hour:' %} {{ format_number(stats.per_hour, 0) }}</li> + <li>ø {% trans 'per minute:' %} {{ format_number(stats.per_minute, 0) }}</li> + {% if stats.per_second >= 1 %} + <li>ø {% trans 'per second:' %} {{ format_number(stats.per_second, 0) }}</li> + {% endif %} + </ul> + + <table id="serverstatusqueriesdetails" class="width100 data sortable noclick"> + <colgroup> + <col class="namecol"> + <col class="valuecol" span="3"> + </colgroup> + + <thead> + <tr> + <th>{% trans 'Statements' %}</th> + <th>{% trans %}#{% notes %}# = Amount of queries{% endtrans %}</th> + <th>ø {% trans 'per hour' %}</th> + <th>%</th> + </tr> + </thead> + + <tbody> + {% for query in queries %} + <tr> + <th class="name">{{ query.name }}</th> + <td class="value">{{ format_number(query.value, 5, 0, true) }}</td> + <td class="value">{{ format_number(query.per_hour, 4, 1, true) }}</td> + <td class="value">{{ format_number(query.percentage, 0, 2) }}</td> + </tr> + {% endfor %} + </tbody> + </table> + + <div id="serverstatusquerieschart" class="width100" data-chart="{{ chart|json_encode }}"></div> +{% else %} + {{ 'Not enough privilege to view query statistics.'|trans|error }} +{% endif %} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/status/status/index.twig b/srcs/phpmyadmin/templates/server/status/status/index.twig new file mode 100644 index 0000000..53fd63f --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/status/index.twig @@ -0,0 +1,78 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'status' %} +{% block content %} + +{% if is_data_loaded %} + <h3>{{ 'Network traffic since startup: %s'|trans|format(network_traffic) }}</h3> + <p>{{ 'This MySQL server has been running for %1$s. It started up on %2$s.'|trans|format(uptime, start_time) }}</p> + + <table id="serverstatustraffic" class="width100 data noclick"> + <thead> + <tr> + <th> + {% trans 'Traffic' %} + {{ show_hint('On a busy server, the byte counters may overrun, so those statistics as reported by the MySQL server may be incorrect.'|trans) }} + </th> + <th>#</th> + <th>ø {% trans 'per hour' %}</th> + </tr> + </thead> + + <tbody> + {% for each_traffic in traffic %} + <tr> + <th class="name">{{ each_traffic.name }}</th> + <td class="value">{{ each_traffic.number }}</td> + <td class="value">{{ each_traffic.per_hour }}</td> + </tr> + {% endfor %} + </tbody> + </table> + + <table id="serverstatusconnections" class="width100 data noclick"> + <thead> + <tr> + <th>{% trans 'Connections' %}</th> + <th>#</th> + <th>ø {% trans 'per hour' %}</th> + <th>%</th> + </tr> + </thead> + + <tbody> + {% for connection in connections %} + <tr> + <th class="name">{{ connection.name }}</th> + <td class="value">{{ connection.number }}</td> + <td class="value">{{ connection.per_hour }}</td> + <td class="value">{{ connection.percentage }}</td> + </tr> + {% endfor %} + </tbody> + </table> + + {% if is_master or is_slave %} + <p class="notice clearfloat"> + {% if is_master and is_slave %} + {% trans 'This MySQL server works as <b>master</b> and <b>slave</b> in <b>replication</b> process.' %} + {% elseif is_master %} + {% trans 'This MySQL server works as <b>master</b> in <b>replication</b> process.' %} + {% elseif is_slave %} + {% trans 'This MySQL server works as <b>slave</b> in <b>replication</b> process.' %} + {% endif %} + </p> + + <hr class="clearfloat"> + + <h3> + <a name="replication">{% trans 'Replication status' %}</a> + </h3> + + {{ replication|raw }} + {% endif %} + +{% else %} + {{ 'Not enough privilege to view server status.'|trans|error }} +{% endif %} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/status/variables/index.twig b/srcs/phpmyadmin/templates/server/status/variables/index.twig new file mode 100644 index 0000000..a5f8724 --- /dev/null +++ b/srcs/phpmyadmin/templates/server/status/variables/index.twig @@ -0,0 +1,137 @@ +{% extends 'server/status/base.twig' %} +{% set active = 'variables' %} +{% block content %} + +{% if is_data_loaded %} + <fieldset id="tableFilter"> + <legend>{% trans 'Filters' %}</legend> + <form action="server_status_variables.php" method="post"> + {{ get_hidden_inputs() }} + + <input class="btn btn-secondary" type="submit" value="{% trans 'Refresh' %}"> + + <div class="formelement"> + <label for="filterText">{% trans 'Containing the word:' %}</label> + <input name="filterText" type="text" id="filterText" value="{{ filter_text }}"> + </div> + + <div class="formelement"> + <input type="checkbox" name="filterAlert" id="filterAlert"{{ is_only_alerts ? ' checked' }}> + <label for="filterAlert"> + {% trans 'Show only alert values' %} + </label> + </div> + + <div class="formelement"> + <select id="filterCategory" name="filterCategory"> + <option value="">{% trans 'Filter by category…' %}</option> + {% for category in categories %} + <option value="{{ category.id }}"{{ category.is_selected ? ' selected' }}>{{ category.name }}</option> + {% endfor %} + </select> + </div> + + <div class="formelement"> + <input type="checkbox" name="dontFormat" id="dontFormat"{{ is_not_formatted ? ' checked' }}> + <label for="dontFormat"> + {% trans 'Show unformatted values' %} + </label> + </div> + </form> + </fieldset> + + <div id="linkSuggestions" class="defaultLinks hide"> + <p class="notice"> + {% trans 'Related links:' %} + {% for link in links %} + <span class="{{ link.name }}"> + {% for link_name, link_url in link.links %} + {% if link_name == 'doc' %} + {{ show_mysql_docu(link_url) }} + {% else %} + <a href="{{ link_url.url }}" data-post="{{ link_url.params }}">{{ link_name }}</a> + {% endif %} + | + {% endfor %} + </span> + {% endfor %} + </p> + </div> + + <div class="responsivetable"> + <table class="data noclick" id="serverstatusvariables"> + <colgroup> + <col class="namecol"> + <col class="valuecol"> + <col class="descrcol"> + </colgroup> + <thead> + <tr> + <th>{% trans 'Variable' %}</th> + <th>{% trans 'Value' %}</th> + <th>{% trans 'Description' %}</th> + </tr> + </thead> + <tbody> + {% for variable in variables %} + <tr{% if variable.class is not empty %} class="s_{{ variable.class }}"{% endif %}> + <th class="name"> + {{ variable.name|replace({'_': ' '}) }} + {{ variable.doc|raw }} + </th> + + <td class="value"> + <span class="formatted"> + {% if variable.has_alert %} + <span class="{{ variable.is_alert ? 'attention' : 'allfine' }}"> + {% endif %} + + {% if variable.name ends with '%' %} + {{ format_number(variable.value, 0, 2) }} % + {% elseif 'Uptime' in variable.name %} + {{ timespan_format(variable.value) }} + {% elseif variable.is_numeric and variable.value >= 1000 %} + <abbr title="{{ format_number(variable.value, 0) }}"> + {{ format_number(variable.value, 3, 1) }} + </abbr> + {% elseif variable.is_numeric %} + {{ format_number(variable.value, 3, 1) }} + {% else %} + {{ variable.value }} + {% endif %} + + {% if variable.has_alert %} + </span> + {% endif %} + </span> + <span class="original hide"> + {% if variable.has_alert %} + <span class="{{ variable.is_alert ? 'attention' : 'allfine' }}"> + {% endif %} + {{ variable.value }} + {% if variable.has_alert %} + </span> + {% endif %} + </span> + </td> + + <td class="descr"> + {{ variable.description }} + {% for doc in variable.description_doc %} + {% if doc.name == 'doc' %} + {{ show_mysql_docu(doc.url) }} + {% else %} + <a href="{{ doc.url.url }}" data-post="{{ doc.url.params }}">{{ doc.name }}</a> + {% endif %} + {% endfor %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> +{% else %} + {{ 'Not enough privilege to view status variables.'|trans|error }} +{% endif %} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/server/sub_page_header.twig b/srcs/phpmyadmin/templates/server/sub_page_header.twig new file mode 100644 index 0000000..d1c521c --- /dev/null +++ b/srcs/phpmyadmin/templates/server/sub_page_header.twig @@ -0,0 +1,16 @@ +{# array contains Sub page icon and text #} +{% set header = { + 'privileges': { + 'image': 'b_usrlist', + 'text': 'Privileges'|trans + } +} %} +<h2> + {% if is_image|default(true) %} + {{ get_image(header[type]['image']) }} + {% else %} + {{ get_icon(header[type]['image']) }} + {% endif %} + {{ header[type]['text'] }} + {{ link is defined ? show_mysql_docu(link) }} +</h2> diff --git a/srcs/phpmyadmin/templates/server/variables/index.twig b/srcs/phpmyadmin/templates/server/variables/index.twig new file mode 100644 index 0000000..75020cb --- /dev/null +++ b/srcs/phpmyadmin/templates/server/variables/index.twig @@ -0,0 +1,78 @@ +<h2> + {{ get_image('s_vars') }} + {% trans 'Server variables and settings' %} + {{ show_mysql_docu('server_system_variables') }} +</h2> + +{% if variables is not empty %} + <a href="server_variables.php{{ get_common() }}" class="ajax saveLink hide"> + {{ get_icon('b_save', 'Save'|trans) }} + </a> + <a href="#" class="cancelLink hide"> + {{ get_icon('b_close', 'Cancel'|trans) }} + </a> + {{ get_image('b_help', 'Documentation'|trans, { + 'class': 'hide', + 'id': 'docImage' + }) }} + + {% include 'filter.twig' with { + 'filter_value': filter_value + } only %} + + <div class="responsivetable"> + <table id="serverVariables" class="width100 data filteredData noclick"> + <thead> + <tr class="var-header var-row"> + <td class="var-action">{% trans 'Action' %}</td> + <td class="var-name">{% trans 'Variable' %}</td> + <td class="var-value">{% trans 'Value' %}</td> + </tr> + </thead> + + <tbody> + {% for variable in variables %} + <tr class="var-row{{ variable.has_session_value ? ' diffSession' }}" data-filter-row="{{ variable.name|upper }}"> + <td class="var-action"> + {% if variable.is_editable %} + <a href="#" data-variable="{{ variable.name }}" class="editLink">{{ get_icon('b_edit', 'Edit'|trans) }}</a> + {% else %} + <span title="{% trans 'This is a read-only variable and can not be edited' %}" class="read_only_var"> + {{ get_icon('bd_edit', 'Edit'|trans) }} + </span> + {% endif %} + </td> + <td class="var-name"> + {% if variable.doc_link != null %} + <span title="{{ variable.name|replace({'_': ' '}) }}"> + {{ variable.doc_link|raw }} + </span> + {% else %} + {{ variable.name|replace({'_': ' '}) }} + {% endif %} + </td> + <td class="var-value value{{ is_superuser ? ' editable' }}"> + {% if variable.is_escaped %} + {{ variable.value|raw }} + {% else %} + {{ variable.value|e|replace({',': ',​'})|raw }} + {% endif %} + </td> + </tr> + + {% if variable.has_session_value %} + <tr class="var-row diffSession" data-filter-row="{{ variable.name|upper }}"> + <td class="var-action"></td> + <td class="var-name session">({% trans 'Session value' %})</td> + <td class="var-value value">{{ variable.session_value }}</td> + </tr> + {% endif %} + {% endfor %} + </tbody> + </table> + </div> +{% else %} + {{ 'Not enough privilege to view server variables and settings. %s'|trans|format( + link_to_var_documentation('show_compatibility_56', is_mariadb) + )|error }} +{% endif %} diff --git a/srcs/phpmyadmin/templates/setup/base.twig b/srcs/phpmyadmin/templates/setup/base.twig new file mode 100644 index 0000000..7fe7fb6 --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/base.twig @@ -0,0 +1,48 @@ +<!doctype html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta charset="utf-8"> + <title>phpMyAdmin setup</title> + <link href="../favicon.ico" rel="icon" type="image/x-icon"> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"> + <link href="styles.css" rel="stylesheet" type="text/css"> + <script type="text/javascript" src="../js/vendor/jquery/jquery.min.js"></script> + <script type="text/javascript" src="../js/vendor/jquery/jquery-ui.min.js"></script> + <script type="text/javascript" src="../js/setup/ajax.js"></script> + <script type="text/javascript" src="../js/config.js"></script> + <script type="text/javascript" src="../js/setup/scripts.js"></script> + <script type="text/javascript" src="../js/messages.php"></script> +</head> +<body> + +<h1> + <span class="blue">php</span><span class="orange">MyAdmin</span> + setup +</h1> + +<div id="menu"> + <ul> + <li> + <a href="index.php{{ get_common() }}"{{ formset is empty ? ' class="active"' }}> + {% trans 'Overview' %} + </a> + </li> + {% for page in pages %} + <li> + <a href="index.php{{ get_common({ + 'page': 'form', + 'formset': page.formset + }) }}"{{ formset == page.formset ? ' class="active"' }}> + {{ page.name }} + </a> + </li> + {% endfor %} + </ul> +</div> + +<div id="page"> + {% block content %}{% endblock %} +</div> + +</body> +</html> diff --git a/srcs/phpmyadmin/templates/setup/config/index.twig b/srcs/phpmyadmin/templates/setup/config/index.twig new file mode 100644 index 0000000..9f42695 --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/config/index.twig @@ -0,0 +1,29 @@ +{% extends 'setup/base.twig' %} +{% block content %} + +<h2>{% trans 'Configuration file' %}</h2> + +{{ form_top_html|raw }} + +<input type="hidden" name="eol" value="{{ eol }}"> + +{{ fieldset_top_html|raw }} + +<tr> + <td> + <textarea cols="50" rows="20" name="textconfig" id="textconfig" spellcheck="false"> + {{- config -}} + </textarea> + </td> +</tr> + +<tr> + <td class="lastrow left"> + <input class="green" type="submit" name="submit_download" value="{% trans 'Download' %}"> + </td> +</tr> + +{{ form_bottom_html|raw }} +{{ fieldset_bottom_html|raw }} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/setup/error.twig b/srcs/phpmyadmin/templates/setup/error.twig new file mode 100644 index 0000000..17f042b --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/error.twig @@ -0,0 +1,19 @@ +<div class="error"> + <h4>{% trans 'Warning' %}</h4> + <p>{% trans 'Submitted form contains errors' %}</p> + <p> + <a href="{{ get_common(url_params|merge({'mode': 'revert'})) }}"> + {% trans 'Try to revert erroneous fields to their default values' %} + </a> + </p> +</div> + +{{ errors|raw }} + +<a class="btn" href="index.php{{ get_common() }}"> + {% trans 'Ignore errors' %} +</a> + +<a class="btn" href="{{ get_common(url_params|merge({'mode': 'edit'})) }}"> + {% trans 'Show form' %} +</a> diff --git a/srcs/phpmyadmin/templates/setup/form/index.twig b/srcs/phpmyadmin/templates/setup/form/index.twig new file mode 100644 index 0000000..c7970eb --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/form/index.twig @@ -0,0 +1,8 @@ +{% extends 'setup/base.twig' %} +{% block content %} + +<h2>{{ name }}</h2> + +{{ page|raw }} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/setup/home/index.twig b/srcs/phpmyadmin/templates/setup/home/index.twig new file mode 100644 index 0000000..a289af7 --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/home/index.twig @@ -0,0 +1,121 @@ +{% extends 'setup/base.twig' %} +{% block content %} + +<form id="select_lang" method="post"> + {{ get_hidden_inputs() }} + <bdo lang="en" dir="ltr"> + <label for="lang"> + {% trans 'Language' %} + {{ 'Language'|trans != 'Language' ? ' - Language' }} + </label> + </bdo> + <br> + <select id="lang" name="lang" class="autosubmit" lang="en" dir="ltr"> + {% for language in languages %} + <option value="{{ language.code }}"{{ language.is_active ? ' selected' }}>{{ language.name|raw }}</option> + {% endfor %} + </select> +</form> + +<h2>{% trans 'Overview' %}</h2> + +<a href="#" id="show_hidden_messages" class="hide"> + {% trans 'Show hidden messages' %} (#MSG_COUNT) +</a> + +{% for message in messages %} + <div class="{{ message.type }}{{ message.is_hidden ? ' hiddenmessage' }}" id="{{ message.id }}"> + <h4>{{ message.title }}</h4> + {{ message.message|raw }} + </div> +{% endfor %} + +<fieldset class="simple"> + <legend>{% trans 'Servers' %}</legend> + + {{ servers_form_top_html|raw }} + + <div class="form"> + {% if server_count > 0 %} + <table cellspacing="0" class="datatable"> + <tr> + <th>#</th> + <th>{% trans 'Name' %}</th> + <th>{% trans 'Authentication type' %}</th> + <th colspan="2">DSN</th> + </tr> + + {% for server in servers %} + <tr> + <td>{{ server.id }}</td> + <td>{{ server.name }}</td> + <td>{{ server.auth_type }}</td> + <td>{{ server.dsn }}</td> + <td class="nowrap"> + <small> + <a href="{{ get_common(server.params.edit) }}"> + {% trans 'Edit' %} + </a> + | + <a class="delete-server" href="{{ get_common(server.params.remove) }}" data-post=" + {{- get_common({ token: server.params.token }, '') }}"> + {% trans 'Delete' %} + </a> + </small> + </td> + </tr> + {% endfor %} + </table> + {% else %} + <table width="100%"> + <tr> + <td> + <em>{% trans 'There are no configured servers' %}</em> + </td> + </tr> + </table> + {% endif %} + + <table width="100%"> + <tr> + <td class="lastrow left"> + <input type="submit" name="submit" value="{% trans 'New server' %}"> + </td> + </tr> + </table> + </div> + + {{ form_bottom_html|raw }} + +</fieldset> + +<fieldset class="simple"> + <legend>{% trans 'Configuration file' %}</legend> + + {{ config_form_top_html|raw }} + + <table width="100%" cellspacing="0"> + {{ default_language_input|raw }} + {{ server_default_input|raw }} + {{ eol_input|raw }} + + <tr> + <td colspan="2" class="lastrow left"> + <input type="submit" name="submit_display" value="{% trans 'Display' %}"> + <input type="submit" name="submit_download" value="{% trans 'Download' %}"> + <input class="red" type="submit" name="submit_clear" value="{% trans 'Clear' %}"> + </td> + </tr> + </table> + + {{ form_bottom_html|raw }} + +</fieldset> + +<div id="footer"> + <a href="../url.php?url=https://www.phpmyadmin.net/">{% trans 'phpMyAdmin homepage' %}</a> + <a href="../url.php?url=https://www.phpmyadmin.net/donate/">{% trans 'Donate' %}</a> + <a href="{{ get_common({'version_check': '1'}) }}">{% trans 'Check for latest version' %}</a> +</div> + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/setup/servers/index.twig b/srcs/phpmyadmin/templates/setup/servers/index.twig new file mode 100644 index 0000000..42b0745 --- /dev/null +++ b/srcs/phpmyadmin/templates/setup/servers/index.twig @@ -0,0 +1,16 @@ +{% extends 'setup/base.twig' %} +{% block content %} + +{% if mode == 'edit' and has_server %} + <h2> + {% trans 'Edit server' %} + {{ server_id }} + <small>({{ server_dsn }})</small> + </h2> +{% elseif mode != 'revert' or not has_server %} + <h2>{% trans 'Add a new server' %}</h2> +{% endif %} + +{{ page|raw }} + +{% endblock %} diff --git a/srcs/phpmyadmin/templates/sql/bookmark.twig b/srcs/phpmyadmin/templates/sql/bookmark.twig new file mode 100644 index 0000000..71abc3d --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/bookmark.twig @@ -0,0 +1,31 @@ +<form action="sql.php" method="post" class="bookmarkQueryForm print_ignore" + onsubmit="return ! Functions.emptyCheckTheField(this, 'bkm_fields[bkm_label]');"> + {{ get_hidden_inputs() }} + <input type="hidden" name="db" value="{{ db }}"> + <input type="hidden" name="goto" value="{{ goto }}"> + <input type="hidden" name="bkm_fields[bkm_database]" value="{{ db }}"> + <input type="hidden" name="bkm_fields[bkm_user]" value="{{ user }}"> + <input type="hidden" name="bkm_fields[bkm_sql_query]" value="{{ sql_query }}"> + <fieldset> + <legend> + {{ get_icon('b_bookmark', 'Bookmark this SQL query'|trans, true) }} + </legend> + <div class="formelement"> + <label> + {% trans 'Label:' %} + <input type="text" name="bkm_fields[bkm_label]" value=""> + </label> + </div> + <div class="formelement"> + <label> + <input type="checkbox" name="bkm_all_users" value="true"> + {% trans 'Let every user access this bookmark' %} + </label> + </div> + <div class="clearfloat"></div> + </fieldset> + <fieldset class="tblFooters"> + <input type="hidden" name="store_bkm" value="1"> + <input class="btn btn-secondary" type="submit" value="{% trans 'Bookmark this SQL query' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/sql/detailed_table.twig b/srcs/phpmyadmin/templates/sql/detailed_table.twig new file mode 100644 index 0000000..4d8fe9c --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/detailed_table.twig @@ -0,0 +1,8 @@ +<tr> + <td>{{ index }}</td> + <td>{{ status|title }}</td> + <td class="right"> + {{ format_number(duration, 3, 1) }}s + <span class="rawvalue hide">{{ duration }}</span> + </td> +</tr> diff --git a/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig b/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig new file mode 100644 index 0000000..f8be9a8 --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/enum_column_dropdown.twig @@ -0,0 +1,6 @@ +<select> + <option value=""> </option> + {% for value in values %} + <option value="{{ value }}"{{ value in selected_values ? " selected" }}>{{ value }}</option> + {% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/sql/profiling_chart.twig b/srcs/phpmyadmin/templates/sql/profiling_chart.twig new file mode 100644 index 0000000..0f80954 --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/profiling_chart.twig @@ -0,0 +1,97 @@ +<fieldset> + <legend>{% trans 'Profiling' %}</legend> + <div class="floatleft"> + <h3>{% trans 'Detailed profile' %}</h3> + <table id="profiletable"> + <thead> + <tr> + <th> + {% trans 'Order' %} + <div class="sorticon"></div> + </th> + <th> + {% trans 'State' %} + {{ show_mysql_docu('general-thread-states') }} + <div class="sorticon"></div> + </th> + <th> + {% trans 'Time' %} + <div class="sorticon"></div> + </th> + </tr> + </thead> + <tbody> + {{ detailed_table|raw }} + </tbody> + </table> + </div> + + <div class="floatleft"> + <h3>{% trans 'Summary by state' %}</h3> + <table id="profilesummarytable"> + <thead> + <tr> + <th> + {% trans 'State' %} + {{ show_mysql_docu('general-thread-states') }} + <div class="sorticon"></div> + </th> + <th> + {% trans 'Total Time' %} + <div class="sorticon"></div> + </th> + <th> + {% trans '% Time' %} + <div class="sorticon"></div> + </th> + <th> + {% trans 'Calls' %} + <div class="sorticon"></div> + </th> + <th> + {% trans 'ø Time' %} + <div class="sorticon"></div> + </th> + </tr> + </thead> + <tbody> + {% for name, stats in states %} + <tr> + <td>{{ name }}</td> + <td align="right"> + {{ format_number(stats['total_time'], 3, 1) }}s + <span class="rawvalue hide">{{ stats['total_time'] }}</span> + </td> + <td align="right"> + {{ format_number(100 * (stats['total_time'] / total_time), 0, 2) }}% + </td> + <td align="right">{{ stats['calls'] }}</td> + <td align="right"> + {{ format_number(stats['total_time'] / stats['calls'], 3, 1) }}s + <span class="rawvalue hide"> + {{ (stats['total_time'] / stats['calls'])|number_format(8, '.', '') }} + </span> + </td> + </tr> + {% endfor %} + </tbody> + </table> + + <script type="text/javascript"> + url_query = '{{ url_query }}'; + </script> + </div> + <div class='clearfloat'></div> + + <div id="profilingChartData" class="hide"> + {{ chart_json|json_encode() }} + </div> + <div id="profilingchart" class="hide"></div> + + <script type="text/javascript"> + AJAX.registerOnload('sql.js', function () { + Sql.makeProfilingChart(); + Sql.initProfilingTables(); + }); + </script> +</fieldset> diff --git a/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig b/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig new file mode 100644 index 0000000..6a2aaff --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/relational_column_dropdown.twig @@ -0,0 +1,4 @@ +<span class="curr_value">{{ current_value }}</span> +<a href="browse_foreigners.php" data-post="{{ get_common(params, '') }}"> + {% trans 'Browse foreign values' %} +</a> diff --git a/srcs/phpmyadmin/templates/sql/set_column.twig b/srcs/phpmyadmin/templates/sql/set_column.twig new file mode 100644 index 0000000..989812e --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/set_column.twig @@ -0,0 +1,5 @@ +<select size="{{ size }}" multiple> + {% for value in values %} + <option value="{{ value }}"{{ value in selected_values ? " selected" }}>{{ value }}</option> + {% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/sql/sql_query_results.twig b/srcs/phpmyadmin/templates/sql/sql_query_results.twig new file mode 100644 index 0000000..d9f2c3b --- /dev/null +++ b/srcs/phpmyadmin/templates/sql/sql_query_results.twig @@ -0,0 +1,10 @@ +{{ table_maintenance|raw }} +<div class="sqlqueryresults ajax"> + {{ previous_update_query|raw }} + {{ profiling_chart|raw }} + {{ missing_unique_column_message|raw }} + {{ bookmark_created_message|raw }} + {{ table|raw }} + {{ indexes_problems|raw }} + {{ bookmark_support|raw }} +</div> diff --git a/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig b/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig new file mode 100644 index 0000000..78d16f6 --- /dev/null +++ b/srcs/phpmyadmin/templates/start_and_number_of_rows_panel.twig @@ -0,0 +1,20 @@ +<fieldset> + <div> + <label for="pos">{% trans "Start row:" %}</label> + <input type="number" name="pos" min="0" required="required" + {% if unlim_num_rows > 0 -%} + max="{{ unlim_num_rows - 1 }}" + {%- endif %} + value="{{ pos }}"> + + <label for="session_max_rows">{% trans "Number of rows:" %}</label> + <input type="number" name="session_max_rows" min="1" + value="{{ rows }}" required="required"> + <input class="btn btn-primary" type="submit" name="submit" class="Go" + value="{% trans "Go" %}"> + <input type="hidden" name="sql_query" + value="{{ sql_query }}"> + <input type="hidden" name="unlim_num_rows" + value="{{ unlim_num_rows }}"> + </div> +</fieldset> diff --git a/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig b/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig new file mode 100644 index 0000000..f2ec2ba --- /dev/null +++ b/srcs/phpmyadmin/templates/table/browse_foreigners/column_element.twig @@ -0,0 +1,12 @@ +<td{{ nowrap ? ' class="nowrap"' }}> + {{ is_selected ? '<strong>' }} + <a class="foreign_value" data-key="{{ keyname }}" href="#" title=" + {%- trans 'Use this value' %}{{ title is not empty ? ': ' ~ title }}"> + {% if nowrap %} + {{ keyname }} + {% else %} + {{ description }} + {% endif %} + </a> + {{ is_selected ? '</strong>' }} +</td> diff --git a/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig b/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig new file mode 100644 index 0000000..4de9b81 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/browse_foreigners/show_all.twig @@ -0,0 +1,5 @@ +{% if foreign_data.disp_row is iterable and + (show_all and foreign_data.the_total > max_rows) %} + <input class="btn btn-secondary" type="submit" id="foreign_showAll" name="foreign_showAll" value=" + {%- trans 'Show all' %}"> +{% endif %} diff --git a/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig b/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig new file mode 100644 index 0000000..4201599 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/chart/tbl_chart.twig @@ -0,0 +1,159 @@ +<script type="text/javascript"> + url_query = '{{ url_query }}'; +</script> +{# Display Chart options #} +<div id="div_view_options"> + <form method="post" id="tblchartform" action="tbl_chart.php" class="ajax"> + {{ get_hidden_inputs(url_params) }} + <fieldset> + <legend> + {% trans 'Display chart' %} + </legend> + <div class="chartOption"> + <div class="formelement"> + <input type="radio" name="chartType" value="bar" id="radio_bar"> + <label for ="radio_bar">{% trans %}Bar{% context %}Chart type{% endtrans %}</label> + </div> + <div class="formelement"> + <input type="radio" name="chartType" value="column" id="radio_column"> + <label for ="radio_column">{% trans %}Column{% context %}Chart type{% endtrans %}</label> + </div> + <div class="formelement"> + <input type="radio" name="chartType" value="line" id="radio_line" checked="checked"> + <label for ="radio_line">{% trans %}Line{% context %}Chart type{% endtrans %}</label> + </div> + <div class="formelement"> + <input type="radio" name="chartType" value="spline" id="radio_spline"> + <label for ="radio_spline">{% trans %}Spline{% context %}Chart type{% endtrans %}</label> + </div> + <div class="formelement"> + <input type="radio" name="chartType" value="area" id="radio_area"> + <label for ="radio_area">{% trans %}Area{% context %}Chart type{% endtrans %}</label> + </div> + <span class="span_pie hide"> + <input type="radio" name="chartType" value="pie" id="radio_pie"> + <label for ="radio_pie">{% trans %}Pie{% context %}Chart type{% endtrans %}</label> + </span> + <span class="span_timeline hide"> + <input type="radio" name="chartType" value="timeline" id="radio_timeline"> + <label for ="radio_timeline">{% trans %}Timeline{% context %}Chart type{% endtrans %}</label> + </span> + <span class="span_scatter hide"> + <input type="radio" name="chartType" value="scatter" id="radio_scatter"> + <label for ="radio_scatter">{% trans %}Scatter{% context %}Chart type{% endtrans %}</label> + </span> + <br><br> + <span class="barStacked hide"> + <input type="checkbox" name="barStacked" value="1" id="checkbox_barStacked"> + <label for ="checkbox_barStacked">{% trans 'Stacked' %}</label> + </span> + <br><br> + <label for ="chartTitle">{% trans 'Chart title:' %}</label> + <input type="text" name="chartTitle" id="chartTitle"> + </div> + {% set xaxis = null %} + <div class="chartOption"> + <label for="select_chartXAxis">{% trans 'X-Axis:' %}</label> + <select name="chartXAxis" id="select_chartXAxis"> + {% for idx, key in keys %} + {% if xaxis is same as(null) %} + {% set xaxis = idx %} + {% endif %} + {% if xaxis is same as(idx) %} + <option value="{{ idx }}" selected="selected">{{ key }}</option> + {% else %} + <option value="{{ idx }}">{{ key }}</option> + {% endif %} + {% endfor %} + </select> + <br> + <label for="select_chartSeries"> + {% trans 'Series:' %} + </label> + <select name="chartSeries" id="select_chartSeries" multiple="multiple"> + {% for idx, key in keys %} + {% if fields_meta[idx].type in numeric_types %} + {% if idx == xaxis and numeric_column_count > 1 %} + <option value="{{ idx }}">{{ key }}</option> + {% else %} + <option value="{{ idx }}" selected="selected">{{ key }}</option> + {% endif %} + {% endif %} + {% endfor %} + </select> + <input type="hidden" name="dateTimeCols" value=" + {% set date_time_types = ['date', 'datetime', 'timestamp'] %} + {% for idx, key in keys %} + {% if fields_meta[idx].type in date_time_types %} + {{ idx ~ ' ' }} + {% endif %} + {% endfor %}"> + <input type="hidden" name="numericCols" value=" + {% for idx, key in keys %} + {% if fields_meta[idx].type in numeric_types %} + {{ idx ~ ' ' }} + {% endif %} + {% endfor %}"> + </div> + <div class="chartOption"> + <label for="xaxis_panel"> + {% trans 'X-Axis label:' %} + </label> + <input style="margin-top:0;" type="text" name="xaxis_label" id="xaxis_label" value="{{ xaxis == -1 ? 'X Values'|trans : keys[xaxis] }}"> + <br> + <label for="yaxis_label"> + {% trans 'Y-Axis label:' %} + </label> + <input type="text" name="yaxis_label" id="yaxis_label" value="{% trans 'Y Values' %}"> + <br> + </div> + <div class="clearfloat"></div> + <div> + <input type="checkbox" id="chkAlternative" name="chkAlternative" value="alternativeFormat"> + <label for="chkAlternative">{% trans 'Series names are in a column' %}</label> + <br> + <label for="select_seriesColumn"> + {% trans 'Series column:' %} + </label> + <select name="chartSeriesColumn" id="select_seriesColumn" disabled> + {% for idx, key in keys %} + <option value="{{ idx }}" + {% if idx == 1 %} + selected="selected" + {% endif %}> + {{ key }} + </option> + {% set series_column = idx %} + {% endfor %} + </select> + <label for="select_valueColumn"> + {% trans 'Value Column:' %} + </label> + <select name="chartValueColumn" id="select_valueColumn" disabled> + {% set selected = false %} + {% for idx, key in keys %} + {% if fields_meta[idx].type in numeric_types %} + {% if not selected and idx != xaxis and idx != series_column %} + <option value="{{ idx }}" selected="selected">{{ key }}</option> + {% set selected = true %} + {% else %} + <option value="{{ idx }}">{{ key }}</option> + {% endif %} + {% endif %} + {% endfor %} + </select> + </div> + {{ get_start_and_number_of_rows_panel(sql_query) }} + <div class="clearfloat"></div> + <div id="resizer" style="width:600px; height:400px;"> + <div style="position: absolute; right: 10px; top: 10px; cursor: pointer; z-index: 1000;"> + <a class="disableAjax" id="saveChart" href="#" download="chart.png"> + {{ get_image('b_saveimage', 'Save chart as image'|trans) }} + </a> + </div> + <div id="querychart" dir="ltr"> + </div> + </div> + </fieldset> + </form> +</div> diff --git a/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig b/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig new file mode 100644 index 0000000..9e82e2e --- /dev/null +++ b/srcs/phpmyadmin/templates/table/gis_visualization/gis_visualization.twig @@ -0,0 +1,80 @@ +<div id="div_view_options"> + <fieldset> + <legend>{% trans 'Display GIS Visualization' %}</legend> + <div id="gis_div" style="position:relative;"> + <form method="post" action="tbl_gis_visualization.php"> + {{ get_hidden_inputs(url_params) }} + <label for="labelColumn"> + {% trans "Label column" %} + </label> + <select name="visualizationSettings[labelColumn]" id="labelColumn" class="autosubmit"> + <option value="">{% trans "-- None --" %}</option> + {% for value in label_candidates %} + <option value="{{ value }}"{{ value == visualization_settings['labelColumn'] ? ' selected="selected"' }}> + {{ value }} + </option> + {% endfor %} + </select> + <label for="spatialColumn"> + {% trans "Spatial column" %} + </label> + <select name="visualizationSettings[spatialColumn]" id="spatialColumn" class="autosubmit"> + {% for value in spatial_candidates %} + <option value="{{ value }}"{{ value == visualization_settings['spatialColumn'] ? ' selected="selected"' }}> + {{ value }} + </option> + {% endfor %} + </select> + <input type="hidden" name="displayVisualization" value="redraw"> + <tr> + <td class="choice" colspan="2"> + <input type="checkbox" + name="visualizationSettings[choice]" + id="choice" value="useBaseLayer" + {% if visualization_settings['choice'] is defined %} + checked="checked" + {% endif %}> + <label for="choice" id="labelChoice"> + {% trans "Use OpenStreetMaps as Base Layer" %} + </label> + </td> + </tr> + {{ get_start_and_number_of_rows_panel(sql_query) }} + </form> + + <div class="pma_quick_warp" style="width: 50px; position: absolute; right: 0; top: 0; cursor: pointer;"> + <div class="drop_list"> + <span class="drop_button" style="padding: 0; border: 0;"> + {{ get_image('b_saveimage', 'Save'|trans) }} + </span> + <ul> + <li class="warp_link"> + <a href="{{ download_url|raw }}&fileFormat=png" class="disableAjax">PNG</a> + </li> + <li class="warp_link"> + <a href="{{ download_url|raw }}&fileFormat=pdf" class="disableAjax">PDF</a> + </li> + <li class="warp_link"> + <a href="{{ download_url|raw }}&fileFormat=svg" class="disableAjax">SVG</a> + </li> + </ul> + </div> + </div> + </div> + + <div class="clearfloat"></div> + + <div id="placeholder" + style="width:{{ visualization_settings['width'] }}px;height:{{ visualization_settings['height'] }}px;"> + {{ visualization|raw }} + </div> + <div id="openlayersmap"></div> + <input type="hidden" id="pmaThemeImage" value="{{ pma_theme_image }}"> + <script language="javascript" type="text/javascript"> + function drawOpenLayers() + { + {{ draw_ol|raw }} + } + </script> + </fieldset> +</div> diff --git a/srcs/phpmyadmin/templates/table/index_form.twig b/srcs/phpmyadmin/templates/table/index_form.twig new file mode 100644 index 0000000..6364599 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/index_form.twig @@ -0,0 +1,223 @@ +<form action="tbl_indexes.php" + method="post" + name="index_frm" + id="index_frm" + class="ajax"> + + {{ get_hidden_inputs(form_params) }} + + <fieldset id="index_edit_fields"> + <div class="index_info"> + <div> + <div class="label"> + <strong> + <label for="input_index_name"> + {% trans 'Index name:' %} + {{ show_hint('"PRIMARY" <b>must</b> be the name of and <b>only of</b> a primary key!'|trans) }} + </label> + </strong> + </div> + + <input type="text" + name="index[Key_name]" + id="input_index_name" + size="25" + maxlength="64" + value="{{ index.getName() }}" + onfocus="this.select()"> + </div> + + <div> + <div class="label"> + <strong> + <label for="select_index_choice"> + {% trans 'Index choice:' %} + {{ show_mysql_docu('ALTER_TABLE') }} + </label> + </strong> + </div> + {{ index.generateIndexChoiceSelector(create_edit_table)|raw }} + </div> + + {% include 'div_for_slider_effect.twig' with { + 'id': 'indexoptions', + 'message': 'Advanced Options'|trans, + 'initial_sliders_state': default_sliders_state + } only %} + + <div> + <div class="label"> + <strong> + <label for="input_key_block_size"> + {% trans 'Key block size:' %} + </label> + </strong> + </div> + + <input type="text" + name="index[Key_block_size]" + id="input_key_block_size" + size="30" + value="{{ index.getKeyBlockSize() }}"> + </div> + + <div> + + <div class="label"> + <strong> + <label for="select_index_type"> + {% trans 'Index type:' %} + {{ show_mysql_docu('ALTER_TABLE') }} + </label> + </strong> + </div> + {{ index.generateIndexTypeSelector()|raw }} + </div> + + <div> + <div class="label"> + <strong> + <label for="input_parser"> + {% trans 'Parser:' %} + </label> + </strong> + </div> + + <input type="text" + name="index[Parser]" + id="input_parse" + size="30" + value="{{ index.getParser() }}"> + </div> + + <div> + <div class="label"> + <strong> + <label for="input_index_comment"> + {% trans 'Comment:' %} + </label> + </strong> + </div> + + <input type="text" + name="index[Index_comment]" + id="input_index_comment" + size="30" + maxlength="1024" + value="{{ index.getComment() }}"> + </div> + </div> + <!-- end of indexoptions div --> + + <div class="clearfloat"></div> + + <table id="index_columns"> + <thead> + <tr> + <th></th> + <th> + {% trans 'Column' %} + </th> + <th> + {% trans 'Size' %} + </th> + </tr> + </thead> + {% set spatial_types = [ + 'geometry', + 'point', + 'linestring', + 'polygon', + 'multipoint', + 'multilinestring', + 'multipolygon', + 'geomtrycollection' + ] %} + <tbody> + {% for column in index.getColumns() %} + <tr class="noclick"> + <td> + <span class="drag_icon" title="{% trans 'Drag to reorder' %}"></span> + </td> + <td> + <select name="index[columns][names][]"> + <option value=""> + -- {% trans 'Ignore' %} -- + </option> + {% for field_name, field_type in fields %} + {% if (index.getChoice() != 'FULLTEXT' + or field_type matches '/(char|text)/i') + and (index.getChoice() != 'SPATIAL' + or field_type in spatial_types) %} + + <option value="{{ field_name }}" + {%- if field_name == column.getName() %} + selected="selected" + {%- endif %}> + {{ field_name }} [{{ field_type }}] + </option> + {% endif %} + {% endfor %} + </select> + </td> + <td> + <input type="text" + size="5" + onfocus="this.select()" + name="index[columns][sub_parts][]" + value="{{ index.getChoice() != 'SPATIAL' ? + column.getSubPart() }}"> + </td> + </tr> + {% endfor %} + {% if add_fields > 0 %} + {% for i in range(1, add_fields) %} + <tr class="noclick"> + <td> + <span class="drag_icon" title="{% trans 'Drag to reorder' %}"></span> + </td> + <td> + <select name="index[columns][names][]"> + <option value="">-- {% trans 'Ignore' %} --</option> + {% set j = 0 %} + {% for field_name, field_type in fields %} + {% if create_edit_table %} + {% set col_index = field_type[1] %} + {% set field_type = field_type[0] %} + {% endif %} + {% set j = j + 1 %} + <option value="{{ col_index is defined ? + col_index : field_name }}" + {{- j == i ? ' selected="selected"' }}> + {{ field_name }} [{{ field_type }}] + </option> + {% endfor %} + </select> + </td> + <td> + <input type="text" + size="5" + onfocus="this.select()" + name="index[columns][sub_parts][]" + value=""> + </td> + </tr> + {% endfor %} + {% endif %} + </tbody> + </table> + <div class="add_more"> + + <div class="slider"></div> + <div class="add_fields hide"> + <input class="btn btn-secondary" type="submit" + id="add_fields" + value="{{ 'Add %s column(s) to index'|trans|format(1) }}"> + </div> + </div> + </fieldset> + <fieldset class="tblFooters"> + <button class="btn btn-secondary" type="submit" id="preview_index_frm">{% trans 'Preview SQL' %}</button> + <input class="btn btn-primary" type="submit" id="save_index_frm" value="{% trans 'Go' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig b/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig new file mode 100644 index 0000000..86a8215 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/insert/continue_insertion_form.twig @@ -0,0 +1,19 @@ +<form id="continueForm" method="post" action="tbl_replace.php" name="continueForm"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="goto" value="{{ goto }}"> + <input type="hidden" name="err_url" value="{{ err_url }}"> + <input type="hidden" name="sql_query" value="{{ sql_query }}"> + + {% if has_where_clause %} + {% for key_id, where_clause in where_clause_array %} + <input type="hidden" name="where_clause[{{ key_id }}]" value=" + {{- where_clause|trim }}"> + {% endfor %} + {% endif %} + + {% set insert_rows %} + <input type="number" name="insert_rows" id="insert_rows" value=" + {{- insert_rows_default }}" min="1"> + {% endset %} + {{ 'Continue insertion with %s rows'|trans|format(insert_rows)|raw }} +</form> diff --git a/srcs/phpmyadmin/templates/table/operations/view.twig b/srcs/phpmyadmin/templates/table/operations/view.twig new file mode 100644 index 0000000..e590532 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/operations/view.twig @@ -0,0 +1,31 @@ +<!-- VIEW operations --> +<div> + <form method="post" action="view_operations.php"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="reload" value="1"> + <fieldset> + <legend>{% trans 'Operations' %}</legend> + <table> + <!-- Change view name --> + <tr> + <td>{% trans 'Rename view to' %}</td> + <td><input type="text" name="new_name" onfocus="this.select()" + value="{{ table }}" + required> + </td> + </tr> + </table> + </fieldset> + <fieldset class="tblFooters"> + <input type="hidden" name="submitoptions" value="1"> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </fieldset> + </form> +</div> + +<div> + <fieldset class="caution"> + <legend>{% trans 'Delete data or table' %}</legend> + <ul>{{ delete_data_or_table_link | raw }}</ul> + </fieldset> +</div> diff --git a/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig b/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig new file mode 100644 index 0000000..2aae85a --- /dev/null +++ b/srcs/phpmyadmin/templates/table/page_with_secondary_tabs.twig @@ -0,0 +1,22 @@ +{% if cfg_relation['relwork'] or is_foreign_key_supported %} + <ul id="topmenu2"> + {{ get_html_tab({ + 'icon': 'b_props', + 'link': 'tbl_structure.php', + 'text': 'Table structure'|trans, + 'id': 'table_strucuture_id' + }, url_params) }} + {{ get_html_tab({ + 'icon': 'b_relations', + 'link': 'tbl_relation.php', + 'text': 'Relation view'|trans, + 'id': 'table_relation_id' + }, url_params) }} + </ul> + <div class="clearfloat"></div> +{% endif %} + +<div id="structure_content"> + {% block content %} + {% endblock %} +</div> diff --git a/srcs/phpmyadmin/templates/table/relation/common_form.twig b/srcs/phpmyadmin/templates/table/relation/common_form.twig new file mode 100644 index 0000000..e85c6ce --- /dev/null +++ b/srcs/phpmyadmin/templates/table/relation/common_form.twig @@ -0,0 +1,223 @@ +{% extends 'table/page_with_secondary_tabs.twig' %} + +{% block content %} +<form method="post" action="tbl_relation.php"> + {{ get_hidden_inputs(db, table) }} + {# InnoDB #} + {% if is_foreign_key_supported(tbl_storage_engine) %} + <fieldset> + <legend>{% trans 'Foreign key constraints' %}</legend> + <div class="responsivetable jsresponsive"> + <table id="foreign_keys" class="relationalTable"> + <thead><tr> + <th>{% trans 'Actions' %}</th> + <th>{% trans 'Constraint properties' %}</th> + {% if tbl_storage_engine|upper == 'INNODB' %} + <th> + {% trans 'Column' %} + {{ show_hint('Creating a foreign key over a non-indexed column would automatically create an index on it. Alternatively, you can define an index below, before creating the foreign key.'|trans) }} + </th> + {% else %} + <th> + {% trans 'Column' %} + {{ show_hint('Only columns with index will be displayed. You can define an index below.'|trans) }} + </th> + {% endif %} + <th colspan="3"> + {% trans 'Foreign key constraint' %} + ({{ tbl_storage_engine }}) + </th> + </tr> + <tr> + <th></th> + <th></th> + <th></th> + <th>{% trans 'Database' %}</th> + <th>{% trans 'Table' %}</th> + <th>{% trans 'Column' %}</th> + </tr></thead> + {% set i = 0 %} + {% if existrel_foreign is not empty %} + {% for key, one_key in existrel_foreign %} + {# Foreign database dropdown #} + {% set foreign_db = one_key['ref_db_name'] is defined + and one_key['ref_db_name'] is not null + ? one_key['ref_db_name'] : db %} + {% set foreign_table = false %} + {% if foreign_db %} + {% set foreign_table = one_key['ref_table_name'] is defined + and one_key['ref_table_name'] is not null + ? one_key['ref_table_name'] : false %} + {% endif %} + {% set unique_columns = [] %} + {% if foreign_db and foreign_table %} + {% set table_obj = table_get(foreign_table, foreign_db) %} + {% set unique_columns = table_obj.getUniqueColumns(false, false) %} + {% endif %} + {% include 'table/relation/foreign_key_row.twig' with { + 'i': i, + 'one_key': one_key, + 'column_array': column_array, + 'options_array': options_array, + 'tbl_storage_engine': tbl_storage_engine, + 'db': db, + 'table': table, + 'url_params': url_params, + 'databases': databases, + 'foreign_db': foreign_db, + 'foreign_table': foreign_table, + 'unique_columns': unique_columns + } only %} + {% set i = i + 1 %} + {% endfor %} + {% endif %} + {% include 'table/relation/foreign_key_row.twig' with { + 'i': i, + 'one_key': [], + 'column_array': column_array, + 'options_array': options_array, + 'tbl_storage_engine': tbl_storage_engine, + 'db': db, + 'table': table, + 'url_params': url_params, + 'databases': databases, + 'foreign_db': foreign_db, + 'foreign_table': foreign_table, + 'unique_columns': unique_columns + } only %} + {% set i = i + 1 %} + <tr> + <th colspan="6"> + <a class="formelement clearfloat add_foreign_key" href=""> + {% trans '+ Add constraint' %} + </a> + </th> + </tr> + </table> + </div> + </fieldset> + {% endif %} + + {% if cfg_relation['relwork'] %} + {% if is_foreign_key_supported(tbl_storage_engine) %} + {% include 'div_for_slider_effect.twig' with { + 'id': 'ir_div', + 'message': 'Internal relationships'|trans, + 'initial_sliders_state': default_sliders_state + } only %} + {% endif %} + + <fieldset> + <legend> + {% trans 'Internal relationships' %} + {{ show_docu('config', 'cfg_Servers_relation') }} + </legend> + <table id="internal_relations" class="relationalTable"> + <tr> + <th>{% trans 'Column' %}</th> + <th>{% trans 'Internal relation' %} + {% if is_foreign_key_supported(tbl_storage_engine) %} + {{ show_hint('An internal relation is not necessary when a corresponding FOREIGN KEY relation exists.'|trans) }} + {% endif %} + </th> + {% set saved_row_cnt = save_row|length - 1 %} + {% for i in 0..saved_row_cnt %} + {% set myfield = save_row[i]['Field'] %} + {# Use an md5 as array index to avoid having special characters + in the name attribute (see bug #1746964 ) #} + {% set myfield_md5 = column_hash_array[myfield] %} + + {% set foreign_table = false %} + {% set foreign_column = false %} + + {# Database dropdown #} + {% if existrel[myfield] is defined %} + {% set foreign_db = existrel[myfield]['foreign_db'] %} + {% else %} + {% set foreign_db = db %} + {% endif %} + + {# Table dropdown #} + {% set tables = [] %} + {% if foreign_db %} + {% if existrel[myfield] is defined %} + {% set foreign_table = existrel[myfield]['foreign_table'] %} + {% endif %} + {% set tables = dbi.getTables(foreign_db) %} + {% endif %} + + {# Column dropdown #} + {% set unique_columns = [] %} + {% if foreign_db and foreign_table %} + {% if existrel[myfield] is defined %} + {% set foreign_column = existrel[myfield]['foreign_field'] %} + {% endif %} + {% set table_obj = table_get(foreign_table, foreign_db) %} + {% set unique_columns = table_obj.getUniqueColumns(false, false) %} + {% endif %} + + <tr> + <td class="vmiddle"> + <strong>{{ myfield }}</strong> + <input type="hidden" name="fields_name[{{ myfield_md5 }}]" + value="{{ myfield }}"> + </td> + + <td> + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_db[' ~ myfield_md5 ~ ']', + 'title': 'Database'|trans, + 'values': databases, + 'foreign': foreign_db + } only %} + + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_table[' ~ myfield_md5 ~ ']', + 'title': 'Table'|trans, + 'values': tables, + 'foreign': foreign_table + } only %} + + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_column[' ~ myfield_md5 ~ ']', + 'title': 'Column'|trans, + 'values': unique_columns, + 'foreign': foreign_column + } only %} + </td> + </tr> + {% endfor %} + </table> + </fieldset> + {% if is_foreign_key_supported(tbl_storage_engine) %} + </div> + {% endif %} + {% endif %} + + {% if cfg_relation['displaywork'] %} + {% set disp = get_display_field(db, table) %} + <fieldset> + <label>{% trans 'Choose column to display:' %}</label> + <select name="display_field"> + <option value="">---</option> + {% for row in save_row %} + <option value="{{ row['Field'] }}" + {%- if disp is defined and row['Field'] == disp %} + selected="selected" + {%- endif %}> + {{ row['Field'] }} + </option> + {% endfor %} + </select> + </fieldset> + {% endif %} + + <fieldset class="tblFooters"> + <input class="btn btn-secondary preview_sql" type="button" value="{% trans 'Preview SQL' %}"> + <input class="btn btn-primary" type="submit" value="{% trans 'Save' %}"> + </fieldset> +</form> +{% if foreignKeySupported %} + {{ displayIndexesHtml|raw }} +{% endif %} +{% endblock %} diff --git a/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig b/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig new file mode 100644 index 0000000..ff179bc --- /dev/null +++ b/srcs/phpmyadmin/templates/table/relation/dropdown_generate.twig @@ -0,0 +1,9 @@ +{{ dropdown_question is not empty ? dropdown_question -}} +<select name="{{ select_name }}"> +{% for one_value, one_label in choices %} + <option value="{{ one_value }}" + {%- if selected_value == one_value %} selected="selected"{% endif %}> + {{ one_label }} + </option> +{% endfor %} +</select> diff --git a/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig b/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig new file mode 100644 index 0000000..3df6c34 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/relation/foreign_key_row.twig @@ -0,0 +1,136 @@ +<tr> + {# Drop key anchor #} + <td> + {% set js_msg = '' %} + {% set this_params = null %} + {% if one_key['constraint'] is defined %} + {% set drop_fk_query = 'ALTER TABLE ' ~ backquote(db) ~ '.' ~ backquote(table) + ~ ' DROP FOREIGN KEY ' + ~ backquote(one_key['constraint']) ~ ';' + %} + {% set this_params = url_params %} + {% set this_params = { + 'goto': 'tbl_relation.php', + 'back': 'tbl_relation.php', + 'sql_query': drop_fk_query, + 'message_to_show': 'Foreign key constraint %s has been dropped'|trans|format( + one_key['constraint'] + ) + } %} + {% set js_msg = 'ALTER TABLE ' ~ db ~ '.' ~ table ~ ' DROP FOREIGN KEY ' ~ one_key['constraint'] ~ ';'|js_format %} + {% endif %} + {% if one_key['constraint'] is defined %} + <input type="hidden" class="drop_foreign_key_msg" value=" + {{- js_msg }}"> + {% set drop_url = 'sql.php' ~ get_common(this_params) %} + {% set drop_str = get_icon('b_drop', 'Drop'|trans) %} + {{ link_or_button(drop_url, drop_str, {'class': 'drop_foreign_key_anchor ajax'}) }} + {% endif %} + </td> + <td> + <span class="formelement clearfloat"> + <input type="text" name="constraint_name[{{ i }}]" value=" + {{- one_key['constraint'] is defined ? one_key['constraint'] -}} + " placeholder="{% trans 'Constraint name' %}" maxlength="64"> + </span> + <div class="floatleft"> + {# For ON DELETE and ON UPDATE, the default action + is RESTRICT as per MySQL doc; however, a SHOW CREATE TABLE + won't display the clause if it's set as RESTRICT. #} + {% set on_delete = one_key['on_delete'] is defined + ? one_key['on_delete'] : 'RESTRICT' %} + {% set on_update = one_key['on_update'] is defined + ? one_key['on_update'] : 'RESTRICT' %} + <span class="formelement"> + {% include 'table/relation/dropdown_generate.twig' with { + 'dropdown_question': 'ON DELETE', + 'select_name': 'on_delete[' ~ i ~ ']', + 'choices': options_array, + 'selected_value': on_delete + } only %} + </span> + <span class="formelement"> + {% include 'table/relation/dropdown_generate.twig' with { + 'dropdown_question': 'ON UPDATE', + 'select_name': 'on_update[' ~ i ~ ']', + 'choices': options_array, + 'selected_value': on_update + } only %} + </span> + </div> + </td> + <td> + {% if one_key['index_list'] is defined %} + {% for key, column in one_key['index_list'] %} + <span class="formelement clearfloat"> + {% include 'table/relation/dropdown_generate.twig' with { + 'dropdown_question': '', + 'select_name': 'foreign_key_fields_name[' ~ i ~ '][]', + 'choices': column_array, + 'selected_value': column + } only %} + </span> + {% endfor %} + {% else %} + <span class="formelement clearfloat"> + {% include 'table/relation/dropdown_generate.twig' with { + 'dropdown_question': '', + 'select_name': 'foreign_key_fields_name[' ~ i ~ '][]', + 'choices': column_array, + 'selected_value': '' + } only %} + </span> + {% endif %} + <a class="formelement clearfloat add_foreign_key_field" data-index=" + {{- i }}" href=""> + {% trans '+ Add column' %} + </a> + </td> + {% set tables = [] %} + {% if foreign_db %} + {% set tables = get_tables(foreign_db, tbl_storage_engine) %} + {% endif %} + <td> + <span class="formelement clearfloat"> + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_foreign_db[' ~ i ~ ']', + 'title': 'Database'|trans, + 'values': databases, + 'foreign': foreign_db + } only %} + </span> + </td> + <td> + <span class="formelement clearfloat"> + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_foreign_table[' ~ i ~ ']', + 'title': 'Table'|trans, + 'values': tables, + 'foreign': foreign_table + } only %} + </span> + </td> + <td> + {% if foreign_db and foreign_table %} + {% for foreign_column in one_key['ref_index_list'] %} + <span class="formelement clearfloat"> + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_foreign_column[' ~ i ~ '][]', + 'title': 'Column'|trans, + 'values': unique_columns, + 'foreign': foreign_column + } only %} + </span> + {% endfor %} + {% else %} + <span class="formelement clearfloat"> + {% include 'table/relation/relational_dropdown.twig' with { + 'name': 'destination_foreign_column[' ~ i ~ '][]', + 'title': 'Column'|trans, + 'values': [], + 'foreign': '' + } only %} + </span> + {% endif %} + </td> +</tr> diff --git a/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig b/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig new file mode 100644 index 0000000..9d5f3c9 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/relation/relational_dropdown.twig @@ -0,0 +1,18 @@ +<select name="{{ name }}" title="{{ title }}"> + <option value=""></option> + {% set seen_key = false %} + {% for value in values %} + <option value="{{ value }}" + {%- if foreign is not same as(false) and value == foreign %} + selected="selected" + {%- set seen_key = true -%} + {%- endif %}> + {{ value }} + </option> + {% endfor %} + {% if foreign is not same as(false) and not seen_key %} + <option value="{{ foreign }}" selected="selected"> + {{ foreign }} + </option> + {% endif %} +</select> diff --git a/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig b/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig new file mode 100644 index 0000000..b72e530 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/column_comparison_operators.twig @@ -0,0 +1,3 @@ +<select id="ColumnOperator{{ search_index }}" name="criteriaColumnOperators[{{ search_index }}]"> + {{ type_operators|raw }} +</select> diff --git a/srcs/phpmyadmin/templates/table/search/fields_table.twig b/srcs/phpmyadmin/templates/table/search/fields_table.twig new file mode 100644 index 0000000..8b74939 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/fields_table.twig @@ -0,0 +1,33 @@ +<table class="data"{{ search_type == 'zoom' ? ' id="tableFieldsId"' }}> + <thead> + <tr> + {% if geom_column_flag %} + <th>{% trans 'Function' %}</th> + {% endif %} + <th>{% trans 'Column' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Collation' %}</th> + <th>{% trans 'Operator' %}</th> + <th>{% trans 'Value' %}</th> + </tr> + </thead> + <tbody> + {% if search_type == 'zoom' %} + {% include 'table/search/rows_zoom.twig' with { + 'self': self, + 'column_names': column_names, + 'keys': keys, + 'criteria_column_names': criteria_column_names, + 'criteria_column_types': criteria_column_types + } only %} + {% else %} + {% include 'table/search/rows_normal.twig' with { + 'self': self, + 'geom_column_flag': geom_column_flag, + 'column_names': column_names, + 'column_types': column_types, + 'column_collations': column_collations + } only %} + {% endif %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/table/search/form_tag.twig b/srcs/phpmyadmin/templates/table/search/form_tag.twig new file mode 100644 index 0000000..1017abd --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/form_tag.twig @@ -0,0 +1,4 @@ +<form method="post" action="{{ script_name }}" name="insertForm" id="{{ form_id }}" class="ajax lock-page"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="goto" value="{{ goto }}"> + <input type="hidden" name="back" value="{{ script_name }}"> diff --git a/srcs/phpmyadmin/templates/table/search/geom_func.twig b/srcs/phpmyadmin/templates/table/search/geom_func.twig new file mode 100644 index 0000000..f7a7415 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/geom_func.twig @@ -0,0 +1,19 @@ +{# Displays 'Function' column if it is present #} +<td> + {% set geom_types = get_gis_datatypes() %} + {% if column_types[column_index] in geom_types %} + <select class="geom_func" name="geom_func[{{ column_index }}]"> + {# get the relevant list of GIS functions #} + {% set funcs = get_gis_functions(column_types[column_index], true, true) %} + + {% for func_name, func in funcs %} + {% set name = func['display'] is defined ? func['display'] : func_name %} + <option value="{{ name }}"> + {{ name }} + </option> + {% endfor %} + </select> + {% else %} + + {% endif %} +</td> diff --git a/srcs/phpmyadmin/templates/table/search/input_box.twig b/srcs/phpmyadmin/templates/table/search/input_box.twig new file mode 100644 index 0000000..5c30535 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/input_box.twig @@ -0,0 +1,97 @@ +{# Get inputbox based on different column types (Foreign key, geometrical, enum) #} +{% if foreigners and search_column_in_foreigners(foreigners, column_name) %} + {% if foreign_data['disp_row'] is iterable %} + <select name="criteriaValues[{{ column_index }}]" + id="{{ column_id }}{{ column_index }}"> + {{ foreign_dropdown( + foreign_data['disp_row'], + foreign_data['foreign_field'], + foreign_data['foreign_display'], + '', + foreign_max_limit + ) }} + </select> + {% elseif foreign_data['foreign_link'] == true %} + <input type="text" + id="{{ column_id }}{{ column_index }}" + name="criteriaValues[{{ column_index }}]" + id="field_{{ column_name_hash }}[{{ column_index }}]" + class="textfield" + {% if criteria_values[column_index] is defined %} + value="{{ criteria_values[column_index] }}" + {% endif %}> + <a class="ajax browse_foreign" href="browse_foreigners.php" data-post=" + {{- get_common({'db': db, 'table': table}, '') -}} + &field={{ column_name|url_encode }}&fieldkey= + {{- column_index }}&fromsearch=1"> + {{ titles['Browse']|replace({"'": "\\'"})|raw }} + </a> + {% endif %} +{% elseif column_type in get_gis_datatypes() %} + <input type="text" + name="criteriaValues[{{ column_index }}]" + size="40" + class="textfield" + id="field_{{ column_index }}"> + {% if in_fbs %} + {% set edit_url = 'gis_data_editor.php' ~ get_common() %} + {% set edit_str = get_icon('b_edit', 'Edit/Insert'|trans) %} + <span class="open_search_gis_editor"> + {{ link_or_button(edit_url, edit_str, [], '_blank') }} + </span> + {% endif %} +{% elseif column_type starts with 'enum' + or (column_type starts with 'set' and in_zoom_search_edit) %} + {% set in_zoom_search_edit = false %} + {% set value = column_type|e|slice(5, -1)|replace({''': ''})|split(', ') %} + {% set cnt_value = value|length %} + {# + Enum in edit mode --> dropdown + Enum in search mode --> multiselect + Set in edit mode --> multiselect + Set in search mode --> input (skipped here, so the 'else' section would handle it) + #} + {% if (column_type starts with 'enum' and not in_zoom_search_edit) + or (column_type starts with 'set' and in_zoom_search_edit) %} + <select name="criteriaValues[{{ column_index }}]" + id="{{ column_id }}{{ column_index }}"> + {% else %} + <select name="criteriaValues[{{ column_index }}]" + id="{{ column_id }}{{ column_index }}" + multiple="multiple" + size="{{ min(3, cnt_value) }}"> + {% endif %} + {# Add select options #} + <option value=""></option> + {% for i in 0..cnt_value - 1 %} + {% if criteria_values[column_index] is defined + and criteria_values[column_index] is iterable + and value[i] in criteria_values[column_index] %} + <option value="{{ value[i]|raw }}" selected> + {{ value[i]|raw }} + </option> + {% else %} + <option value="{{ value[i]|raw }}"> + {{ value[i]|raw }} + </option> + {% endif %} + {% endfor %} + </select> +{% else %} + {% set the_class = 'textfield' %} + {% if column_type == 'date' %} + {% set the_class = the_class ~ ' datefield' %} + {% elseif column_type == 'datetime' or column_type starts with 'timestamp' %} + {% set the_class = the_class ~ ' datetimefield' %} + {% elseif column_type starts with 'bit' %} + {% set the_class = the_class ~ ' bit' %} + {% endif %} + <input type="text" + name="criteriaValues[{{ column_index }}]" + size="40" + class="{{ the_class }}" + id="{{ column_id }}{{ column_index }}" + {% if criteria_values[column_index] is defined %} + value="{{ criteria_values[column_index] }}" + {%- endif %}> +{% endif %} diff --git a/srcs/phpmyadmin/templates/table/search/replace_preview.twig b/srcs/phpmyadmin/templates/table/search/replace_preview.twig new file mode 100644 index 0000000..e7a2423 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/replace_preview.twig @@ -0,0 +1,39 @@ +<form method="post" + action="tbl_find_replace.php" + name="previewForm" + id="previewForm"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="replace" value="true"> + <input type="hidden" name="columnIndex" value="{{ column_index }}"> + <input type="hidden" name="findString" value="{{ find }}"> + <input type="hidden" name="replaceWith" value="{{ replace_with }}"> + <input type="hidden" name="useRegex" value="{{ use_regex }}"> + + <fieldset id="fieldset_find_replace_preview"> + <legend>{% trans 'Find and replace - preview' %}</legend> + <table id="previewTable"> + <thead> + <tr> + <th>{% trans 'Count' %}</th> + <th>{% trans 'Original string' %}</th> + <th>{% trans 'Replaced string' %}</th> + </tr> + </thead> + <tbody> + {% if result is iterable %} + {% for row in result %} + <tr> + <td class="right">{{ row[2] }}</td>{# count #} + <td>{{ row[0] }}</td>{# original #} + <td>{{ row[1] }}</td>{# replaced #} + </tr> + {% endfor %} + {% endif %} + </tbody> + </table> + </fieldset> + + <fieldset class="tblFooters"> + <input class="btn btn-secondary" type="submit" name="replace" value="{% trans 'Replace' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/table/search/rows_normal.twig b/srcs/phpmyadmin/templates/table/search/rows_normal.twig new file mode 100644 index 0000000..5e21efa --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/rows_normal.twig @@ -0,0 +1,39 @@ +{% for column_index in 0..column_names|length - 1 %} + <tr class="noclick"> + {# If 'Function' column is present trying to change comment #} + {% if geom_column_flag %} + {% include 'table/search/geom_func.twig' with { + 'column_index': column_index, + 'column_types': column_types + } only %} + {% endif %} + {# Displays column's name, type, collation and value #} + <th> + {{ column_names[column_index] }} + </th> + {% set properties = self.getColumnProperties(column_index, column_index) %} + <td dir="ltr"> + {{ properties['type'] }} + </td> + <td> + {{ properties['collation'] }} + </td> + <td> + {{ properties['func']|raw }} + </td> + {# here, the data-type attribute is needed for a date/time picker #} + <td data-type="{{ properties['type'] }}"> + {{ properties['value']|raw }} + {# Displays hidden fields #} + <input type="hidden" + name="criteriaColumnNames[{{ column_index }}]" + value="{{ column_names[column_index] }}"> + <input type="hidden" + name="criteriaColumnTypes[{{ column_index }}]" + value="{{ column_types[column_index] }}"> + <input type="hidden" + name="criteriaColumnCollations[{{ column_index }}]" + value="{{ column_collations[column_index] }}"> + </td> + </tr> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/table/search/rows_zoom.twig b/srcs/phpmyadmin/templates/table/search/rows_zoom.twig new file mode 100644 index 0000000..dc46f1d --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/rows_zoom.twig @@ -0,0 +1,74 @@ +{# Get already set search criteria (if any) #} +{% set type = [] %} +{% set collation = [] %} +{% set func = [] %} +{% set value = [] %} + +{% for i in 0..3 %} + {# After X-Axis and Y-Axis column rows, display additional criteria option #} + {% if i == 2 %} + <tr> + <td> + {% trans 'Additional search criteria' %} + </td> + </tr> + {% endif %} + <tr class="noclick"> + <th> + <select name="criteriaColumnNames[]" id="tableid_{{ i }}" > + <option value="pma_null"> + {% trans 'None' %} + </option> + {% for j in 0..column_names|length - 1 %} + {% if criteria_column_names[i] is defined + and criteria_column_names[i] == column_names[j] %} + <option value="{{ column_names[j] }}" selected="selected"> + {{ column_names[j] }} + </option> + {% else %} + <option value="{{ column_names[j] }}"> + {{ column_names[j] }} + </option> + {% endif %} + {% endfor %} + </select> + </th> + {% if criteria_column_names[i] is defined + and criteria_column_names[i] != 'pma_null' %} + {% set key = keys[criteria_column_names[i]] %} + {% set properties = self.getColumnProperties(i, key) %} + {% set type = type|merge({i: properties['type']}) %} + {% set collation = collation|merge({i: properties['collation']}) %} + {% set func = func|merge({i: properties['func']}) %} + {% set value = value|merge({i: properties['value']}) %} + {% endif %} + {# Column type #} + <td dir="ltr"> + {{ type[i] is defined ? type[i] }} + </td> + {# Column Collation #} + <td> + {{ collation[i] is defined ? collation[i] }} + </td> + {# Select options for column operators #} + <td> + {{ func[i] is defined ? func[i]|raw }} + </td> + {# Inputbox for search criteria value #} + <td> + </td> + <td> + {{ value[i] is defined ? value[i]|raw }} + {# Displays hidden fields #} + <input type="hidden" + name="criteriaColumnTypes[{{ i }}]" + id="types_{{ i }}" + {%- if criteria_column_types[i] is defined %} + value="{{ criteria_column_types[i] }}" + {%- endif %}> + <input type="hidden" + name="criteriaColumnCollations[{{ i }}]" + id="collations_{{ i }}"> + </td> + </tr> +{% endfor %} diff --git a/srcs/phpmyadmin/templates/table/search/selection_form.twig b/srcs/phpmyadmin/templates/table/search/selection_form.twig new file mode 100644 index 0000000..2ba4d60 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/selection_form.twig @@ -0,0 +1,226 @@ +{% if search_type == 'zoom' %} + {% include 'table/search/form_tag.twig' with { + 'script_name': 'tbl_zoom_select.php', + 'form_id': 'zoom_search_form', + 'db': db, + 'table': table, + 'goto': goto + } only %} + <fieldset id="fieldset_zoom_search"> + <fieldset id="inputSection"> + <legend> + {% trans 'Do a "query by example" (wildcard: "%") for two different columns' %} + </legend> + {% include 'table/search/fields_table.twig' with { + 'self': self, + 'search_type': search_type, + 'geom_column_flag': geom_column_flag, + 'column_names': column_names, + 'column_types': column_types, + 'column_collations': column_collations, + 'keys' : keys, + 'criteria_column_names': criteria_column_names, + 'criteria_column_types': criteria_column_types + } only %}<table class="data"> + {# Select options for data label #} + <tr> + <td> + <label for="dataLabel"> + {% trans 'Use this column to label each point' %} + </label> + </td> + <td> + <select name="dataLabel" id="dataLabel" > + <option value = ""> + {% trans 'None' %} + </option> + {% for i in 0..column_names|length - 1 %} + {% if data_label is defined and data_label == column_names[i]|e %} + <option value="{{ column_names[i] }}" selected="selected"> + {{ column_names[i] }} + </option> + {% else %} + <option value="{{ column_names[i] }}" > + {{ column_names[i] }} + </option> + {% endif %} + {% endfor %} + </select> + </td> + </tr> + {# Inputbox for changing default maximum rows to plot #} + <tr> + <td> + <label for="maxRowPlotLimit"> + {% trans 'Maximum rows to plot' %} + </label> + </td> + <td> + <input type="number" + name="maxPlotLimit" + id="maxRowPlotLimit" + required="required" + value="{{ max_plot_limit }}"> + </td> + </tr> + </table> + </fieldset> + </fieldset> +{% elseif search_type == 'normal' %} + {% include 'table/search/form_tag.twig' with { + 'script_name': 'tbl_select.php', + 'form_id': 'tbl_search_form', + 'db': db, + 'table': table, + 'goto': goto + } only %} + <fieldset id="fieldset_table_search"> + <fieldset id="fieldset_table_qbe"> + <legend> + {% trans 'Do a "query by example" (wildcard: "%")' %} + </legend> + <div class="responsivetable jsresponsive"> + {% include 'table/search/fields_table.twig' with { + 'self': self, + 'search_type': search_type, + 'geom_column_flag': geom_column_flag, + 'column_names': column_names, + 'column_types': column_types, + 'column_collations': column_collations, + 'criteria_column_names': criteria_column_names, + 'criteria_column_types': criteria_column_types + } only %} + </div> + <div id="gis_editor"></div> + <div id="popup_background"></div> + </fieldset> + {% include 'div_for_slider_effect.twig' with { + 'id': 'searchoptions', + 'message': 'Options'|trans, + 'initial_sliders_state': default_sliders_state + } only %} + + {# Displays columns select list for selecting distinct columns in the search #} + <fieldset id="fieldset_select_fields"> + <legend> + {% trans 'Select columns (at least one):' %} + </legend> + <select name="columnsToDisplay[]" + size="{{ min(column_names|length, 10) }}" + multiple="multiple"> + {% for each_field in column_names %} + <option value="{{ each_field }}" + selected="selected"> + {{ each_field }} + </option> + {% endfor %} + </select> + <input type="checkbox" name="distinct" value="DISTINCT" id="oDistinct"> + <label for="oDistinct">DISTINCT</label> + </fieldset> + + {# Displays input box for custom 'Where' clause to be used in the search #} + <fieldset id="fieldset_search_conditions"> + <legend> + <em>{% trans 'Or' %}</em> + {% trans 'Add search conditions (body of the "where" clause):' %} + </legend> + {{ show_mysql_docu('Functions') }} + <input type="text" name="customWhereClause" class="textfield" size="64"> + </fieldset> + + {# Displays option of changing default number of rows displayed per page #} + <fieldset id="fieldset_limit_rows"> + <legend>{% trans 'Number of rows per page' %}</legend> + <input type="number" + name="session_max_rows" + required="required" + min="1" + value="{{ max_rows }}" + class="textfield"> + </fieldset> + + {# Displays option for ordering search results by a column value (Asc or Desc) #} + <fieldset id="fieldset_display_order"> + <legend>{% trans 'Display order:' %}</legend> + <select name="orderByColumn"><option value="--nil--"></option> + {% for each_field in column_names %} + <option value="{{ each_field }}"> + {{ each_field }} + </option> + {% endfor %} + </select> + + {{ get_radio_fields( + 'order', + { + 'ASC': 'Ascending'|trans, + 'DESC': 'Descending'|trans + }, + 'ASC', + false, + true, + 'formelement' + ) }} + + </fieldset> + <div class="clearfloat"></div> + </fieldset> +{% elseif search_type == 'replace' %} + {% include 'table/search/form_tag.twig' with { + 'script_name': 'tbl_find_replace.php', + 'form_id': 'find_replace_form', + 'db': db, + 'table': table, + 'goto': goto + } only %} + <fieldset id="fieldset_find_replace"> + <fieldset id="fieldset_find"> + <legend> + {% trans 'Find and replace' %} + </legend>{% trans 'Find:' %} + <input type="text" value="" name="find" required> + {% trans 'Replace with:' %} + <input type="text" value="" name="replaceWith"> + + {% trans 'Column:' %} + <select name="columnIndex"> + {% for i in 0..column_names|length - 1 %} + {% set type = types[column_names[i]] %} + + {% if sql_types.getTypeClass(type) == 'CHAR' %} + <option value="{{ i }}"> + {{- column_names[i] -}} + </option> + {% endif %} + {% endfor %} + </select> + + {% include 'checkbox.twig' with { + 'html_field_id': 'useRegex', + 'html_field_name': 'useRegex', + 'label': 'Use regular expression'|trans, + 'checked': false, + 'onclick': false + } only %} + </fieldset> + </fieldset> +{% else %} + {% include 'table/search/form_tag.twig' with { + 'script_name': '', + 'form_id': '', + 'db': db, + 'table': table, + 'goto': goto + } only %} +{% endif %} + +{# Displays selection form's footer elements #} + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" + name="{{ search_type == 'zoom' ? 'zoom_submit' : 'submit' }}" + {{ search_type == 'zoom' ? 'id="inputFormSubmitId"' }} + value="{% trans 'Go' %}"> + </fieldset> +</form> +<div id="sqlqueryresultsouter"></div> diff --git a/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig b/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig new file mode 100644 index 0000000..7543f85 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/search/zoom_result_form.twig @@ -0,0 +1,86 @@ +<form method="post" action="tbl_zoom_select.php" name="displayResultForm" id="zoom_display_form" class="ajax"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="goto" value="{{ goto }}"> + <input type="hidden" name="back" value="tbl_zoom_select.php"> + + <fieldset id="displaySection"> + <legend>{% trans 'Browse/Edit the points' %}</legend> + + {# JSON encode the data(query result) #} + <center> + {% if zoom_submit and data is not empty %} + <div id="resizer"> + <center> + <a id="help_dialog" href="#"> + {% trans 'How to use' %} + </a> + </center> + <div id="querydata" class="hide"> + {{ data_json }} + </div> + <div id="querychart"></div> + <button class="button-reset"> + {% trans 'Reset zoom' %} + </button> + </div> + {% endif %} + </center> + + {# Displays rows in point edit form #} + <div id="dataDisplay" class="hide"> + <table> + <thead> + <tr> + <th>{% trans 'Column' %}</th> + <th>{% trans 'Null' %}</th> + <th>{% trans 'Value' %}</th> + </tr> + </thead> + <tbody> + {% for column_index in 0..column_names|length - 1 %} + {% set field_popup = column_names[column_index] %} + {% set foreign_data = get_foreign_data( + foreigners, + field_popup, + false, + '', + '' + ) %} + <tr class="noclick"> + <th>{{ column_names[column_index] }}</th> + {# Null checkbox if column can be null #} + <th> + {% if column_null_flags[column_index] == 'YES' %} + <input type="checkbox" class="checkbox_null" + name="criteriaColumnNullFlags[{{ column_index }}]" + id="edit_fields_null_id_{{ column_index }}"> + {% endif %} + </th> + {# Column's Input box #} + <th> + {% include 'table/search/input_box.twig' with { + 'str': '', + 'column_type': column_types[column_index], + 'column_id': column_types[column_index] ? 'edit_fieldID_' : 'fieldID_', + 'in_zoom_search_edit': true, + 'foreigners': foreigners, + 'column_name': field_popup, + 'column_name_hash': column_name_hashes[field_popup], + 'foreign_data': foreign_data, + 'table': table, + 'column_index': column_index, + 'foreign_max_limit': foreign_max_limit, + 'criteria_values': '', + 'db': db, + 'titles': titles, + 'in_fbs': false + } only %} + </th> + </tr> + {% endfor %} + </tbody> + </table> + </div> + <input type="hidden" id="queryID" name="sql_query"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig b/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig new file mode 100644 index 0000000..d9c629c --- /dev/null +++ b/srcs/phpmyadmin/templates/table/structure/action_row_in_structure_table.twig @@ -0,0 +1,31 @@ +<li class="{{ class }}"> +{% if type == 'text' + or type == 'blob' + or tbl_storage_engine == 'ARCHIVE' + or has_field %} + {{ titles['No' ~ action]|raw }} +{% else %} + <a rel="samepage" class="ajax add_key print_ignore + {%- if has_link_class %} + add_primary_key_anchor + {%- elseif action == 'Index' %} + add_index_anchor + {%- elseif action == 'Unique' %} + add_unique_anchor + {%- elseif action == 'Spatial' %} + add_spatial_anchor + {%- endif %}" href="tbl_structure.php" data-post="{{ url_query|raw -}} + &add_key=1&sql_query= + {{- ('ALTER TABLE ' ~ + backquote(table) ~ + (is_primary ? (primary ? ' DROP PRIMARY KEY,')) ~ + ' ' ~ + syntax ~ + '(' ~ + backquote(row['Field']) ~ + ');')|url_encode -}} + &message_to_show={{ message|format(row['Field']|e)|url_encode }}"> + {{ titles[action]|raw }} + </a> +{% endif %} +</li> diff --git a/srcs/phpmyadmin/templates/table/structure/display_partitions.twig b/srcs/phpmyadmin/templates/table/structure/display_partitions.twig new file mode 100644 index 0000000..b10a0bc --- /dev/null +++ b/srcs/phpmyadmin/templates/table/structure/display_partitions.twig @@ -0,0 +1,145 @@ +<div id="partitions"> + <fieldset> + <legend> + {% trans 'Partitions' %} + {{ show_mysql_docu('partitioning') }} + </legend> + {% if partitions is empty %} + {{ 'No partitioning defined!'|trans|notice }} + {% else %} + <p> + {% trans 'Partitioned by:' %} + <code>{{ partition_method }}({{ partition_expression }})</code> + </p> + {% if has_sub_partitions %} + <p> + {% trans 'Sub partitioned by:' %} + <code>{{ sub_partition_method }}({{ sub_partition_expression }})</code> + <p> + {% endif %} + <table> + <thead> + <tr> + <th colspan="2">#</th> + <th>{% trans 'Partition' %}</th> + {% if has_description %} + <th>{% trans 'Expression' %}</th> + {% endif %} + <th>{% trans 'Rows' %}</th> + <th>{% trans 'Data length' %}</th> + <th>{% trans 'Index length' %}</th> + <th>{% trans 'Comment' %}</th> + <th colspan="{{ range_or_list ? '7' : '6' }}"> + {% trans 'Action' %} + </th> + </tr> + </thead> + <tbody> + {% for partition in partitions %} + <tr class="noclick{{ has_sub_partitions ? ' marked' }}"> + {% if has_sub_partitions %} + <td>{{ partition.getOrdinal() }}</td> + <td></td> + {% else %} + <td colspan="2">{{ partition.getOrdinal() }}</td> + {% endif %} + <th>{{ partition.getName() }}</th> + {% if has_description %} + <td> + <code> + {{- partition.getExpression() -}} + {{- partition.getMethod() == 'LIST' ? ' IN (' : ' < ' -}} + {{- partition.getDescription() -}} + {{- partition.getMethod() == 'LIST' ? ')' -}} + </code> + </td> + {% endif %} + <td class="value">{{ partition.getRows() }}</td> + <td class="value"> + {% set data_length = format_byte_down( + partition.getDataLength(), + 3, + 1 + ) %} + <span>{{ data_length[0] }}</span> + <span class="unit">{{ data_length[1] }}</span> + </td> + <td class="value"> + {% set index_length = format_byte_down( + partition.getIndexLength(), + 3, + 1 + ) %} + <span>{{ index_length[0] }}</span> + <span class="unit">{{ index_length[1] }}</span> + </td> + <td>{{ partition.getComment() }}</td> + {% for action, icon in action_icons %} + <td> + <a href="tbl_structure.php" data-post="{{ url_query -}} + &partition_maintenance=1&sql_query= + {{- ("ALTER TABLE " ~ backquote(table) ~ " " ~ action + ~ " PARTITION " ~ partition.getName())|url_encode }}" + id="partition_action_{{ action }}" + name="partition_action_{{ action }}" + class="ajax"> + {{ icon|raw }} + </a> + </td> + {% endfor %} + + {% if has_sub_partitions %} + {% for sub_partition in partition.getSubPartitions() %} + <tr class="noclick"> + <td></td> + <td>{{ sub_partition.getOrdinal() }}</td> + <td>{{ sub_partition.getName() }}</td> + {% if has_description %} + <td></td> + {% endif %} + <td class="value">{{ sub_partition.getRows() }}</td> + <td class="value"> + {% set data_length = format_byte_down( + sub_partition.getDataLength(), + 3, + 1 + ) %} + <span>{{ data_length[0] }}</span> + <span class="unit">{{ data_length[1] }}</span> + </td> + <td class="value"> + {% set index_length = format_byte_down( + sub_partition.getIndexLength(), + 3, + 1 + ) %} + <span>{{ index_length[0] }}</span> + <span class="unit">{{ index_length[1] }}</span> + </td> + <td>{{ sub_partition.getComment() }}</td> + <td colspan="{{ range_or_list ? '7' : '6' }}"></td> + </tr> + {% endfor %} + {% endif %} + </tr> + {% endfor %} + </tbody> + </table> + {% endif %} + </fieldset> + <fieldset class="tblFooters print_ignore"> + <form action="tbl_structure.php" method="post"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="edit_partitioning" value="true"> + {% if partitions is empty %} + <input class="btn btn-secondary" type="submit" name="edit_partitioning" value="{% trans 'Partition table' %}"> + {% else %} + {{ link_or_button(remove_url, 'Remove partitioning'|trans, { + 'class': 'button ajax', + 'id': 'remove_partitioning' + }) }} + <input class="btn btn-secondary" type="submit" name="edit_partitioning" value="{% trans 'Edit partitioning' %}"> + {% endif %} + </form> + </fieldset> +</div> diff --git a/srcs/phpmyadmin/templates/table/structure/display_structure.twig b/srcs/phpmyadmin/templates/table/structure/display_structure.twig new file mode 100644 index 0000000..16e11db --- /dev/null +++ b/srcs/phpmyadmin/templates/table/structure/display_structure.twig @@ -0,0 +1,516 @@ +{% extends 'table/page_with_secondary_tabs.twig' %} +{% block content %} +<form method="post" action="tbl_structure.php" name="fieldsForm" id="fieldsForm" + class="ajax{{ hide_structure_actions ? ' HideStructureActions' }}"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="table_type" value= + {%- if db_is_system_schema -%} + "information_schema" + {%- elseif tbl_is_view -%} + "view" + {%- else -%} + "table" + {%- endif %}> + <div class="responsivetable"> + <table id="tablestructure" class="data topmargin"> + {# Table header #} + <thead> + <tr> + <th class="print_ignore"></th> + <th>#</th> + <th>{% trans 'Name' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Collation' %}</th> + <th>{% trans 'Attributes' %}</th> + <th>{% trans 'Null' %}</th> + <th>{% trans 'Default' %}</th> + {% if show_column_comments -%} + <th>{% trans 'Comments' %}</th> + {%- endif %} + <th>{% trans 'Extra' %}</th> + {# @see table/structure.js, function moreOptsMenuResize() #} + {% if not db_is_system_schema and not tbl_is_view %} + <th colspan="{{ show_icons('ActionLinksMode') ? '8' : '9' -}} + " class="action print_ignore">{% trans 'Action' %}</th> + {% endif %} + </tr> + </thead> + <tbody> + {# Table body #} + {% set rownum = 0 %} + {% for row in fields %} + {% set rownum = rownum + 1 %} + + {% set extracted_columnspec = extracted_columnspecs[rownum] %} + {% set field_name = row['Field']|e %} + {# For column comments #} + {% set comments = row_comments[rownum] %} + {# Underline commented fields and display a hover-title (CSS only) #} + + <tr> + <td class="center print_ignore"> + <input type="checkbox" class="checkall" name="selected_fld[]" value="{{ row['Field'] }}" id="checkbox_row_{{ rownum }}"> + </td> + <td class="right">{{ rownum }}</td> + <th class="nowrap"> + <label for="checkbox_row_{{ rownum }}"> + {% if displayed_fields[rownum].comment is defined %} + <span class="commented_column" title="{{ displayed_fields[rownum].comment }}">{{ displayed_fields[rownum].text }}</span> + {% else %} + {{ displayed_fields[rownum].text }} + {% endif %} + {{ displayed_fields[rownum].icon|raw }} + </label> + </th> + <td{{ 'set' != extracted_columnspec['type'] and 'enum' != extracted_columnspec['type'] ? ' class="nowrap"' }}> + <bdo dir="ltr" lang="en"> + {{ extracted_columnspec['displayed_type']|raw }} + {% if relation_commwork and relation_mimework and browse_mime + and mime_map[row['Field']]['mimetype'] is defined %} + <br>{% trans 'Media (MIME) type:' %} {{ mime_map[row['Field']]['mimetype']|replace({'_': '/'})|lower }} + {% endif %} + </bdo> + </td> + <td> + {% if row['Collation'] is not empty %} + <dfn title="{{ collations[row['Collation']].description }}">{{ collations[row['Collation']].name }}</dfn> + {% endif %} + </td> + <td class="column_attribute nowrap">{{ attributes[rownum] }}</td> + <td>{{ row['Null'] == 'YES' ? 'Yes'|trans : 'No'|trans }}</td> + <td class="nowrap"> + {% if row['Default'] is not null %} + {% if extracted_columnspec['type'] == 'bit' %} + {{ row['Default']|convert_bit_default_value }} + {% else %} + {{ row['Default'] }} + {% endif %} + {% elseif row['Null'] == 'YES' %} + <em>NULL</em> + {% else %} + <em>{% trans %}None{% context %}None for default{% endtrans %}</em> + {% endif %} + </td> + {% if show_column_comments %} + <td> + {{ comments }} + </td> + {% endif %} + <td class="nowrap">{{ row['Extra']|upper }}</td> + {% if not tbl_is_view and not db_is_system_schema %} + <td class="edit center print_ignore"> + <a class="change_column_anchor ajax" href="tbl_structure.php + {{- url_query }}&field={{ row['Field']|url_encode }}&change_column=1"> + {{ titles['Change']|raw }} + </a> + </td> + <td class="drop center print_ignore"> + <a class="drop_column_anchor ajax" href="sql.php" data-post="{{ url_query }}&sql_query= + {{- ('ALTER TABLE ' ~ backquote(table) + ~ ' DROP ' ~ backquote(row['Field']) ~ ';')|url_encode -}} + &dropped_column={{ row['Field']|url_encode }}&purge=1&message_to_show= + {{- ('Column %s has been dropped.'|trans|format(row['Field']|e))|url_encode }}"> + {{ titles['Drop']|raw }} + </a> + </td> + {% endif %} + + {% if not tbl_is_view and not db_is_system_schema %} + {% set type = extracted_columnspec['print_type'] is not empty ? extracted_columnspec['print_type'] %} + <td class="print_ignore"> + <ul class="table-structure-actions resizable-menu"> + {% if hide_structure_actions %} + <li class="submenu shown"> + <a href="#" class="tab nowrap">{{ get_icon('b_more', 'More'|trans) }}</a> + <ul> + {% endif %} + {# Add primary #} + {% include 'table/structure/action_row_in_structure_table.twig' with { + 'type': type, + 'tbl_storage_engine': tbl_storage_engine, + 'class': 'primary nowrap', + 'has_field': primary and primary.hasColumn(field_name), + 'has_link_class': true, + 'url_query': url_query, + 'primary': primary, + 'syntax': 'ADD PRIMARY KEY', + 'message': 'A primary key has been added on %s.'|trans, + 'action': 'Primary', + 'titles': titles, + 'row': row, + 'is_primary': true, + 'table': table + } only %} + + {# Add unique #} + {% include 'table/structure/action_row_in_structure_table.twig' with { + 'type': type, + 'tbl_storage_engine': tbl_storage_engine, + 'class': 'add_unique unique nowrap', + 'has_field': field_name in columns_with_unique_index, + 'has_link_class': false, + 'url_query': url_query, + 'primary': primary, + 'syntax': 'ADD UNIQUE', + 'message': 'An index has been added on %s.'|trans, + 'action': 'Unique', + 'titles': titles, + 'row': row, + 'is_primary': false, + 'table': table + } only %} + + {# Add index #} + {% include 'table/structure/action_row_in_structure_table.twig' with { + 'type': type, + 'tbl_storage_engine': tbl_storage_engine, + 'class': 'add_index nowrap', + 'has_field': false, + 'has_link_class': false, + 'url_query': url_query, + 'primary': primary, + 'syntax': 'ADD INDEX', + 'message': 'An index has been added on %s.'|trans, + 'action': 'Index', + 'titles': titles, + 'row': row, + 'is_primary': false, + 'table': table + } only %} + + {# Add spatial #} + {% set spatial_types = [ + 'geometry', + 'point', + 'linestring', + 'polygon', + 'multipoint', + 'multilinestring', + 'multipolygon', + 'geomtrycollection' + ] %} + {% include 'table/structure/action_row_in_structure_table.twig' with { + 'type': type, + 'tbl_storage_engine': tbl_storage_engine, + 'class': 'spatial nowrap', + 'has_field': type not in spatial_types and + (tbl_storage_engine == 'MYISAM' or mysql_int_version >= 50705), + 'has_link_class': false, + 'url_query': url_query, + 'primary': primary, + 'syntax': 'ADD SPATIAL', + 'message': 'An index has been added on %s.'|trans, + 'action': 'Spatial', + 'titles': titles, + 'row': row, + 'is_primary': false, + 'table': table + } only %} + + {# FULLTEXT is possible on TEXT, CHAR and VARCHAR #} + <li class="fulltext nowrap"> + {% if tbl_storage_engine is not empty and ( + tbl_storage_engine == 'MYISAM' + or tbl_storage_engine == 'ARIA' + or tbl_storage_engine == 'MARIA' + or (tbl_storage_engine == 'INNODB' and mysql_int_version >= 50604) + ) and ('text' in type or 'char' in type) %} + <a rel="samepage" class="ajax add_key add_fulltext_anchor" href="tbl_structure.php" + data-post="{{- url_query|raw }}&add_key=1&sql_query= + {{- ('ALTER TABLE ' ~ backquote(table) + ~ ' ADD FULLTEXT(' ~ backquote(row['Field']) + ~ ');')|url_encode }}&message_to_show= + {{- ('An index has been added on %s.'|trans|format(row['Field']|e))|url_encode }}"> + {{ titles['IdxFulltext']|raw }} + </a> + {% else %} + {{ titles['NoIdxFulltext']|raw }} + {% endif %} + </li> + + {# Distinct value action #} + <li class="browse nowrap"> + <a href="sql.php" data-post="{{ url_query|raw }}&sql_query= + {{- ('SELECT COUNT(*) AS ' ~ backquote('Rows'|trans) + ~ ', ' ~ backquote(row['Field']) + ~ ' FROM ' ~ backquote(table) + ~ ' GROUP BY ' ~ backquote(row['Field']) + ~ ' ORDER BY ' ~ backquote(row['Field']))|url_encode -}} + &is_browse_distinct=1"> + {{ titles['DistinctValues']|raw }} + </a> + </li> + {% if central_columns_work %} + <li class="browse nowrap"> + {% if row['Field'] in central_list %} + <a href="#" class="central_columns remove_button"> + {{ get_icon('centralColumns_delete', 'Remove from central columns'|trans) }} + </a> + {% else %} + <a href="#" class="central_columns add_button"> + {{ get_icon('centralColumns_add', 'Add to central columns'|trans) }} + </a> + {% endif %} + </li> + {% endif %} + {% if hide_structure_actions %} + </ul> + </li> + {% endif %} + </ul> + </td> + {% endif %} + </tr> + {% endfor %} + </tbody> + </table> + </div> + <div class="print_ignore"> + {% include 'select_all.twig' with { + 'pma_theme_image': pma_theme_image, + 'text_dir': text_dir, + 'form_name': 'fieldsForm' + } only %} + + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Browse'|trans, + 'b_browse', + 'browse' + ) }} + + {% if not tbl_is_view and not db_is_system_schema %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit change_columns_anchor ajax', + 'Change'|trans, + 'b_edit', + 'change' + ) }} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Drop'|trans, + 'b_drop', + 'drop' + ) }} + + {% if tbl_storage_engine != 'ARCHIVE' %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Primary'|trans, + 'b_primary', + 'primary' + ) }} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Unique'|trans, + 'b_unique', + 'unique' + ) }} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Index'|trans, + 'b_index', + 'index' + ) }} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Fulltext'|trans, + 'b_ftext', + 'ftext' + ) }} + + {% if tbl_storage_engine is not empty and ( + tbl_storage_engine == 'MYISAM' + or tbl_storage_engine == 'ARIA' + or tbl_storage_engine == 'MARIA') %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Fulltext'|trans, + 'b_ftext', + 'ftext' + ) }} + {% endif %} + + {% if central_columns_work %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Add to central columns'|trans, + 'centralColumns_add', + 'add_to_central_columns' + ) }} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Remove from central columns'|trans, + 'centralColumns_delete', + 'remove_from_central_columns' + ) }} + {% endif %} + {% endif %} + {% endif %} + </div> +</form> +<hr class="print_ignore"> +<div id="move_columns_dialog" class="hide" title="{% trans 'Move columns' %}"> + <p>{% trans 'Move the columns by dragging them up and down.' %}</p> + <form action="tbl_structure.php" name="move_column_form" id="move_column_form"> + <div> + {{ get_hidden_inputs(db, table) }} + <ul></ul> + </div> + </form> +</div> +{# Work on the table #} +<div id="structure-action-links"> + {% if tbl_is_view and not db_is_system_schema %} + {% set edit_view_url = 'view_create.php' ~ edit_view_url %} + {{ link_or_button( + edit_view_url, + get_icon('b_edit', 'Edit view'|trans, true) + ) }} + {% endif %} + <a href="#" id="printView">{{ get_icon('b_print', 'Print'|trans, true) }}</a> + {% if not tbl_is_view and not db_is_system_schema %} + {# Only display propose table structure for MySQL < 8.0 #} + {% if mysql_int_version < 80000 or is_mariadb %} + <a href="sql.php" data-post="{{ url_query|raw }}&session_max_rows=all&sql_query= + {{- ('SELECT * FROM ' ~ backquote(table) ~ ' PROCEDURE ANALYSE()')|url_encode -}} + " style="margin-right: 0;"> + {{ get_icon( + 'b_tblanalyse', + 'Propose table structure'|trans, + true + ) }} + </a> + {{ show_mysql_docu('procedure_analyse') }} + {% endif %} + {% if is_active %} + <a href="tbl_tracking.php{{ url_query|raw }}"> + {{ get_icon('eye', 'Track table'|trans, true) }} + </a> + {% endif %} + <a href="#" id="move_columns_anchor"> + {{ get_icon('b_move', 'Move columns'|trans, true) }} + </a> + <a href="normalization.php{{ url_query|raw }}"> + {{ get_icon('normalize', 'Normalize'|trans, true) }} + </a> + {% endif %} + {% if tbl_is_view and not db_is_system_schema %} + {% if is_active %} + <a href="tbl_tracking.php{{ url_query|raw }}"> + {{ get_icon('eye', 'Track view'|trans, true) }} + </a> + {% endif %} + {% endif %} +</div> +{% if not tbl_is_view and not db_is_system_schema %} + <form method="post" action="tbl_addfield.php" id="addColumns" name="addColumns"> + {{ get_hidden_inputs(db, table) }} + {% if show_icons('ActionLinksMode') %} + {{ get_image('b_insrow', 'Add column'|trans) }} + {% endif %} + {% set num_fields -%} + <input type="number" name="num_fields" value="1" onfocus="this.select()" min="1" required> + {%- endset %} + {{ 'Add %s column(s)'|trans|format(num_fields)|raw }} + <input type="hidden" name="field_where" value="after"> + {# I tried displaying the drop-down inside the label but with Firefox the drop-down was blinking #} + <select name="after_field"> + <option value="first" data-pos="first"> + {% trans 'at beginning of table' %} + </option> + {% for one_column_name in columns_list %} + <option value="{{ one_column_name }}" + {{- loop.revindex0 == 0 ? ' selected="selected"' }}> + {{ 'after %s'|trans|format(one_column_name) }} + </option> + {% endfor %} + </select> + <input class="btn btn-primary" type="submit" value="{% trans 'Go' %}"> + </form> +{% endif %} + +{# Displays indexes #} +{% if not tbl_is_view and not db_is_system_schema + and 'ARCHIVE' != tbl_storage_engine %} + {{ displayIndexesHtml|raw }} +{% endif %} + +{# Display partition details #} +{% if have_partitioning %} + {# Detect partitioning #} + {% if partition_names is not empty and partition_names[0] is not null %} + {% set first_partition = partitions[0] %} + {% set range_or_list = first_partition.getMethod() == 'RANGE' + or first_partition.getMethod() == 'RANGE COLUMNS' + or first_partition.getMethod() == 'LIST' + or first_partition.getMethod() == 'LIST COLUMNS' %} + {% set sub_partitions = first_partition.getSubPartitions() %} + {% set has_sub_partitions = first_partition.hasSubPartitions() %} + {% if has_sub_partitions %} + {% set first_sub_partition = sub_partitions[0] %} + {% endif %} + + {% set action_icons = { + 'ANALYZE': get_icon('b_search', 'Analyze'|trans), + 'CHECK': get_icon('eye', 'Check'|trans), + 'OPTIMIZE': get_icon('normalize', 'Optimize'|trans), + 'REBUILD': get_icon('s_tbl', 'Rebuild'|trans), + 'REPAIR': get_icon('b_tblops', 'Repair'|trans), + 'TRUNCATE': get_icon('b_empty', 'Truncate'|trans), + } %} + {% if range_or_list %} + {% set action_icons = action_icons|merge({'DROP': get_icon('b_drop', 'Drop'|trans)}) %} + {% endif %} + + {# open Slider Effect div #} + {% include 'div_for_slider_effect.twig' with { + 'id': 'partitions-2', + 'message': 'Partitions'|trans, + 'initial_sliders_state': default_sliders_state + } only %} + + {% set remove_sql = 'ALTER TABLE ' ~ backquote(table) ~ ' REMOVE PARTITIONING' %} + {% set remove_url = 'sql.php' ~ url_query ~ '&sql_query=' ~ remove_sql|url_encode %} + + {% include 'table/structure/display_partitions.twig' with { + 'db': db, + 'table': table, + 'url_query': url_query, + 'partitions': partitions, + 'partition_method': first_partition.getMethod(), + 'partition_expression': first_partition.getExpression(), + 'has_description': first_partition.getDescription() is not empty, + 'has_sub_partitions': has_sub_partitions, + 'sub_partition_method': has_sub_partitions ? first_sub_partition.getMethod(), + 'sub_partition_expression': has_sub_partitions ? first_sub_partition.getExpression(), + 'action_icons': action_icons, + 'range_or_list': range_or_list, + 'remove_url': remove_url + } only %} + {% else %} + {% include 'table/structure/display_partitions.twig' with { + 'db': db, + 'table': table + } only %} + {% endif %} + {# For closing Slider effect div #} + </div> +{% endif %} + +{# Displays Space usage and row statistics #} +{% if show_stats %} + {{ table_stats|raw }} +{% endif %} +<div class="clearfloat"></div> +{% endblock %} diff --git a/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig b/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig new file mode 100644 index 0000000..01c74ae --- /dev/null +++ b/srcs/phpmyadmin/templates/table/structure/display_table_stats.twig @@ -0,0 +1,169 @@ +<div id="tablestatistics"> + <fieldset> + <legend>{% trans 'Information' %}</legend> + {% if showtable['TABLE_COMMENT'] %} + <p> + <strong>{% trans 'Table comments:' %}</strong> + {{ showtable['TABLE_COMMENT'] }} + </p> + {% endif %} + <a id="showusage"></a> + + {% if not tbl_is_view and not db_is_system_schema %} + <table id="tablespaceusage" class="width100 data"> + <caption class="tblHeaders">{% trans 'Space usage' %}</caption> + <tbody> + <tr> + <th class="name">{% trans 'Data' %}</th> + <td class="value">{{ data_size }}</td> + <td class="unit">{{ data_unit }}</td> + </tr> + + {% if index_size is defined %} + <tr> + <th class="name">{% trans 'Index' %}</th> + <td class="value">{{ index_size }}</td> + <td class="unit">{{ index_unit }}</td> + </tr> + {% endif %} + + {% if free_size is defined %} + <tr> + <th class="name">{% trans 'Overhead' %}</th> + <td class="value">{{ free_size }}</td> + <td class="unit">{{ free_unit }}</td> + </tr> + <tr> + <th class="name">{% trans 'Effective' %}</th> + <td class="value">{{ effect_size }}</td> + <td class="unit">{{ effect_unit }}</td> + </tr> + {% endif %} + + {% if tot_size is defined and mergetable == false %} + <tr> + <th class="name">{% trans 'Total' %}</th> + <td class="value">{{ tot_size }}</td> + <td class="unit">{{ tot_unit }}</td> + </tr> + {% endif %} + + {# Optimize link if overhead #} + {% if free_size is defined + and (tbl_storage_engine == 'MYISAM' + or tbl_storage_engine == 'ARIA' + or tbl_storage_engine == 'MARIA' + or tbl_storage_engine == 'BDB') + or (tbl_storage_engine == 'INNODB' and innodb_file_per_table == true) %} + <tr class="tblFooters print_ignore"> + <td colspan="3" class="center"> + <a href="sql.php" data-post="{{ url_query }}&pos=0&sql_query= + {{- ('OPTIMIZE TABLE ' ~ backquote(table))|url_encode }}"> + {{ get_icon('b_tbloptimize', 'Optimize table'|trans) }} + </a> + </td> + </tr> + {% endif %} + </tbody> + </table> + {% endif %} + + {% set avg_size = avg_size is defined ? avg_size : null %} + {% set avg_unit = avg_unit is defined ? avg_unit : null %} + <table id="tablerowstats" class="width100 data"> + <caption class="tblHeaders">{% trans 'Row statistics' %}</caption> + <tbody> + {% if showtable['Row_format'] is defined %} + <tr> + <th class="name">{% trans 'Format' %}</th> + {% if showtable['Row_format'] == 'Fixed' %} + <td class="value">{% trans 'static' %}</td> + {% elseif showtable['Row_format'] == 'Dynamic' %} + <td class="value">{% trans 'dynamic' %}</td> + {% else %} + <td class="value">{{ showtable['Row_format'] }}</td> + {% endif %} + </tr> + {% endif %} + + {% if showtable['Create_options'] is not empty %} + <tr> + <th class="name">{% trans 'Options' %}</th> + {% if showtable['Create_options'] == 'partitioned' %} + <td class="value">{% trans 'partitioned' %}</td> + {% else %} + <td class="value">{{ showtable['Create_options'] }}</td> + {% endif %} + </tr> + {% endif %} + + {% if table_collation is not empty %} + <tr> + <th class="name">{% trans 'Collation' %}</th> + <td class="value"> + <dfn title="{{ table_collation.description }}"> + {{ table_collation.name }} + </dfn> + </td> + </tr> + {% endif %} + + {% if not is_innodb and showtable['Rows'] is defined %} + <tr> + <th class="name">{% trans 'Rows' %}</th> + <td class="value">{{ format_number(showtable['Rows'], 0) }}</td> + </tr> + {% endif %} + + {% if not is_innodb + and showtable['Avg_row_length'] is defined + and showtable['Avg_row_length'] > 0 %} + <tr> + <th class="name">{% trans 'Row length' %}</th> + {% set avg_row_length = format_byte_down(showtable['Avg_row_length'], 6, 1) %} + <td class="value">{{ avg_row_length[0] }} {{ avg_row_length[1] }}</td> + </tr> + {% endif %} + + {% if not is_innodb + and showtable['Data_length'] is defined + and showtable['Rows'] is defined + and showtable['Rows'] > 0 + and mergetable == false %} + <tr> + <th class="name">{% trans 'Row size' %}</th> + <td class="value">{{ avg_size }} {{ avg_unit }}</td> + </tr> + {% endif %} + + {% if showtable['Auto_increment'] is defined %} + <tr> + <th class="name">{% trans 'Next autoindex' %}</th> + <td class="value">{{ format_number(showtable['Auto_increment'], 0) }}</td> + </tr> + {% endif %} + + {% if showtable['Create_time'] is defined %} + <tr> + <th class="name">{% trans 'Creation' %}</th> + <td class="value">{{ localised_date(showtable['Create_time']|date('U')) }}</td> + </tr> + {% endif %} + + {% if showtable['Update_time'] is defined %} + <tr> + <th class="name">{% trans 'Last update' %}</th> + <td class="value">{{ localised_date(showtable['Update_time']|date('U')) }}</td> + </tr> + {% endif %} + + {% if showtable['Check_time'] is defined %} + <tr> + <th class="name">{% trans 'Last check' %}</th> + <td class="value">{{ localised_date(showtable['Check_time']|date('U')) }}</td> + </tr> + {% endif %} + </tbody> + </table> + </fieldset> +</div> diff --git a/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig b/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig new file mode 100644 index 0000000..7cf5e8d --- /dev/null +++ b/srcs/phpmyadmin/templates/table/structure/partition_definition_form.twig @@ -0,0 +1,14 @@ +<form action="tbl_structure.php" method="post"> + {{ get_hidden_inputs(db, table) }} + <input type="hidden" name="edit_partitioning" value="true"> + + <fieldset> + <legend>{% trans 'Edit partitioning' %}</legend> + {% include 'columns_definitions/partitions.twig' with { + 'partition_details': partition_details + } only %} + </fieldset> + <fieldset class="tblFooters"> + <input class="btn btn-primary" type="submit" name="save_partitioning" value="{% trans 'Save' %}"> + </fieldset> +</form> diff --git a/srcs/phpmyadmin/templates/table/tracking/main.twig b/srcs/phpmyadmin/templates/table/tracking/main.twig new file mode 100644 index 0000000..ff6c5c4 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/tracking/main.twig @@ -0,0 +1,132 @@ +{% if selectable_tables_num_rows > 0 %} + <form method="post" action="tbl_tracking.php{{ url_query|raw }}"> + {{ get_hidden_inputs(db, table) }} + <select name="table" class="autosubmit"> + {% for entry in selectable_tables_entries %} + <option value="{{ entry.table_name }}" + {{- entry.table_name == selected_table ? ' selected' }}> + {{ entry.db_name }}.{{ entry.table_name }} + {% if entry.is_tracked %} + ({% trans 'active' %}) + {% else %} + ({% trans 'not active' %}) + {% endif %} + </option> + {% endfor %} + </select> + <input type="hidden" name="show_versions_submit" value="1"> + </form> +{% endif %} +<br> +{% if last_version > 0 %} + <form method="post" action="tbl_tracking.php" name="versionsForm" id="versionsForm" class="ajax"> + {{ get_hidden_inputs(db, table) }} + <table id="versions" class="data"> + <thead> + <tr> + <th></th> + <th>{% trans 'Version' %}</th> + <th>{% trans 'Created' %}</th> + <th>{% trans 'Updated' %}</th> + <th>{% trans 'Status' %}</th> + <th>{% trans 'Action' %}</th> + <th>{% trans 'Show' %}</th> + </tr> + </thead> + <tbody> + {% for version in versions %} + <tr> + <td class="center"> + <input type="checkbox" name="selected_versions[]" + class="checkall" id="selected_versions_{{- version['version']|escape }}" + value="{{- version['version']|escape }}"> + </td> + <td class="floatright"> + <label for="selected_versions_{{- version['version']|escape }}"> + <b>{{ version['version']|escape }}</b> + </label> + </td> + <td>{{ version['date_created']|escape }}</td> + <td>{{ version['date_updated']|escape }}</td> + {% if version['tracking_active'] == 1 %} + {% set last_version_status = 1 %} + <td>{% trans 'active' %}</td> + {% else %} + {% set last_version_status = 0 %} + <td>{% trans 'not active' %}</td> + {% endif %} + <td> + <a class="delete_version_anchor ajax" href="tbl_tracking.php" data-post=" + {{- get_common(url_params|merge({ + 'version': version['version'], + 'submit_delete_version': true + }), '') }}"> + {{ get_icon('b_drop', 'Delete version'|trans) }} + </a> + </td> + <td> + <a href="tbl_tracking.php" data-post=" + {{- get_common(url_params|merge({ + 'version': version['version'], + 'report': 'true' + }), '') }}"> + {{ get_icon('b_report', 'Tracking report'|trans) }} + </a> + <a href="tbl_tracking.php" data-post=" + {{- get_common(url_params|merge({ + 'version': version['version'], + 'snapshot': 'true' + }), '') }}"> + {{ get_icon('b_props', 'Structure snapshot'|trans) }} + </a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% include 'select_all.twig' with { + 'pma_theme_image': pmaThemeImage, + 'text_dir': text_dir, + 'form_name': 'versionsForm', + } only %} + {{ get_button_or_image( + 'submit_mult', + 'mult_submit', + 'Delete version'|trans, + 'b_drop', + 'delete_version' + ) }} + </form> + {% set last_version_element = versions|first %} + <div> + <form method="post" action="tbl_tracking.php{{ url_query|raw }}"> + {{ get_hidden_inputs(db, table) }} + <fieldset> + <legend> + {% if last_version_element['tracking_active'] == 0 %} + {% set legend = 'Activate tracking for %s'|trans %} + {% set value = 'activate_now' %} + {% set button = 'Activate now'|trans %} + {% else %} + {% set legend = 'Deactivate tracking for %s'|trans %} + {% set value = 'deactivate_now' %} + {% set button = 'Deactivate now'|trans %} + {% endif %} + + {{ legend|format(db ~ '.' ~ table) }} + </legend> + <input type="hidden" name="version" value="{{ last_version }}"> + <input type="hidden" name="toggle_activation" value="{{ value }}"> + <input class="btn btn-secondary" type="submit" value="{{ button }}"> + </fieldset> + </form> + </div> +{% endif %} +{% include 'create_tracking_version.twig' with { + 'url_query': url_query, + 'last_version': last_version, + 'db': db, + 'selected': [table], + 'type': type, + 'default_statements': default_statements, +} only %} diff --git a/srcs/phpmyadmin/templates/table/tracking/report_table.twig b/srcs/phpmyadmin/templates/table/tracking/report_table.twig new file mode 100644 index 0000000..fe00526 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/tracking/report_table.twig @@ -0,0 +1,27 @@ +<table id="{{ table_id }}" class="data"> + <thead> + <tr> + <th>{% trans %}#{% context %}Number{% endtrans %}</th> + <th>{% trans 'Date' %}</th> + <th>{% trans 'Username' %}</th> + <th>{{ header_message }}</th> + <th>{% trans 'Action' %}</th> + </tr> + </thead> + <tbody> + {% for entry in entries %} + <tr class="noclick"> + <td class="right"><small>{{ entry.line_number }}</small></td> + <td><small>{{ entry.date }}</small></td> + <td><small>{{ entry.username }}</small></td> + <td>{{ entry.formated_statement|raw }}</td> + <td class="nowrap"> + <a class="delete_entry_anchor ajax" href="tbl_tracking.php" data-post=" + {{- entry.url_params|raw }}"> + {{ drop_image_or_text|raw }} + </a> + </td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig new file mode 100644 index 0000000..4ef8c21 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_columns.twig @@ -0,0 +1,56 @@ +<h3>{% trans 'Structure' %}</h3> +<table id="tablestructure" class="data"> + <thead> + <tr> + <th>{% trans %}#{% context %}Number{% endtrans %}</th> + <th>{% trans 'Column' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Collation' %}</th> + <th>{% trans 'Null' %}</th> + <th>{% trans 'Default' %}</th> + <th>{% trans 'Extra' %}</th> + <th>{% trans 'Comment' %}</th> + </tr> + </thead> + <tbody> + {% set index = 1 %} + {% for field in columns %} + <tr class="noclick"> + <td>{{ index }}</td> + {% set index = index + 1 %} + <td> + <strong> + {{ field['Field'] }} + {% if field['Key'] == 'PRI' %} + {{ get_image('b_primary', 'Primary'|trans) }} + {% elseif field['Key'] is not empty %} + {{ get_image('bd_primary', 'Index'|trans) }} + {% endif %} + </strong> + </td> + <td>{{ field['Type'] }}</td> + <td>{{ field['Collation'] }}</td> + <td>{{ field['Null'] == 'YES' ? 'Yes'|trans : 'No'|trans }}</td> + <td> + {% if field['Default'] is defined %} + {% set extracted_columnspec = extract_column_spec(field['Type']) %} + {% if extracted_columnspec['type'] == 'bit' %} + {# here, $field['Default'] contains something like b'010' #} + {{ field['Default']|convert_bit_default_value }} + {% else %} + {{ field['Default'] }} + {% endif %} + {% else %} + {% if field['Null'] == 'YES' %} + <em>NULL</em> + {% else %} + <em>{% trans %}None{% context %}None for default{% endtrans %}</em> + {% endif %} + {% endif %} + </td> + <td>{{ field['Extra'] }}</td> + <td>{{ field['Comment'] }}</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig new file mode 100644 index 0000000..a919252 --- /dev/null +++ b/srcs/phpmyadmin/templates/table/tracking/structure_snapshot_indexes.twig @@ -0,0 +1,33 @@ +<h3>{% trans 'Indexes' %}</h3> +<table id="tablestructure_indexes" class="data"> + <thead> + <tr> + <th>{% trans 'Keyname' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Unique' %}</th> + <th>{% trans 'Packed' %}</th> + <th>{% trans 'Column' %}</th> + <th>{% trans 'Cardinality' %}</th> + <th>{% trans 'Collation' %}</th> + <th>{% trans 'Null' %}</th> + <th>{% trans 'Comment' %}</th> + </tr> + </thead> + <tbody> + {% for index in indexes %} + <tr class="noclick"> + <td> + <strong>{{ index['Key_name'] }}</strong> + </td> + <td>{{ index['Index_type'] }}</td> + <td>{{ index['Non_unique'] == 0 ? 'Yes'|trans : 'No'|trans }}</td> + <td>{{ index['Packed'] != '' ? 'Yes'|trans : 'No'|trans }}</td> + <td>{{ index['Column_name'] }}</td> + <td>{{ index['Cardinality'] }}</td> + <td>{{ index['Collation'] }}</td> + <td>{{ index['Null'] }}</td> + <td>{{ index['Comment'] }}</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/test/add_data.twig b/srcs/phpmyadmin/templates/test/add_data.twig new file mode 100644 index 0000000..d562612 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/add_data.twig @@ -0,0 +1,2 @@ +{{ variable1 }} +{{ variable2 }} diff --git a/srcs/phpmyadmin/templates/test/echo.twig b/srcs/phpmyadmin/templates/test/echo.twig new file mode 100644 index 0000000..9c5fc60 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/echo.twig @@ -0,0 +1 @@ +{{ variable -}} diff --git a/srcs/phpmyadmin/templates/test/gettext/gettext.twig b/srcs/phpmyadmin/templates/test/gettext/gettext.twig new file mode 100644 index 0000000..4fcf61b --- /dev/null +++ b/srcs/phpmyadmin/templates/test/gettext/gettext.twig @@ -0,0 +1 @@ +{% trans "Text" %} diff --git a/srcs/phpmyadmin/templates/test/gettext/notes.twig b/srcs/phpmyadmin/templates/test/gettext/notes.twig new file mode 100644 index 0000000..e5a38e4 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/gettext/notes.twig @@ -0,0 +1,5 @@ +{% trans %} +Text +{% notes %} +Notes +{% endtrans %} diff --git a/srcs/phpmyadmin/templates/test/gettext/pgettext.twig b/srcs/phpmyadmin/templates/test/gettext/pgettext.twig new file mode 100644 index 0000000..5365027 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/gettext/pgettext.twig @@ -0,0 +1,5 @@ +{% trans %} +Text +{% context %} +Text context +{% endtrans %} diff --git a/srcs/phpmyadmin/templates/test/gettext/plural.twig b/srcs/phpmyadmin/templates/test/gettext/plural.twig new file mode 100644 index 0000000..5bc44e9 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/gettext/plural.twig @@ -0,0 +1,5 @@ +{% trans %} +One table +{% plural table_count %} +{{ count }} tables +{% endtrans %} diff --git a/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig b/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig new file mode 100644 index 0000000..0c6da18 --- /dev/null +++ b/srcs/phpmyadmin/templates/test/gettext/plural_notes.twig @@ -0,0 +1,7 @@ +{% trans %} +One table +{% plural table_count %} +{{ count }} tables +{% notes %} +Number of tables +{% endtrans %} diff --git a/srcs/phpmyadmin/templates/test/static.twig b/srcs/phpmyadmin/templates/test/static.twig new file mode 100644 index 0000000..703390d --- /dev/null +++ b/srcs/phpmyadmin/templates/test/static.twig @@ -0,0 +1 @@ +static content
\ No newline at end of file diff --git a/srcs/phpmyadmin/templates/theme_preview.twig b/srcs/phpmyadmin/templates/theme_preview.twig new file mode 100644 index 0000000..f8308ff --- /dev/null +++ b/srcs/phpmyadmin/templates/theme_preview.twig @@ -0,0 +1,16 @@ +<div class="theme_preview"> + <h2> + {{ name }} ({{ version }}) + </h2> + <p> + <a class="take_theme" name="{{ id }}" href="index.php{{ get_common(url_params) }}"> + {% if screen is not empty %} + <img src="{{ screen }}" alt="{{ name }}" title="{{ name }}"> + <br> + {% else %} + {% trans 'No preview available.' %} + {% endif %} + [ <strong>{% trans 'Take it' %}</strong> ] + </a> + </p> +</div> diff --git a/srcs/phpmyadmin/templates/themes.twig b/srcs/phpmyadmin/templates/themes.twig new file mode 100644 index 0000000..c03089c --- /dev/null +++ b/srcs/phpmyadmin/templates/themes.twig @@ -0,0 +1,7 @@ +<h1>phpMyAdmin - {% trans 'Theme' %}</h1> +<p> + <a href="{{ 'https://www.phpmyadmin.net/themes/'|link }}#pma_{{ version }}" rel="noopener noreferrer" target="_blank"> + {% trans 'Get more themes!' %} + </a> +</p> +{{ previews|raw }} diff --git a/srcs/phpmyadmin/templates/toggle_button.twig b/srcs/phpmyadmin/templates/toggle_button.twig new file mode 100644 index 0000000..85a8320 --- /dev/null +++ b/srcs/phpmyadmin/templates/toggle_button.twig @@ -0,0 +1,24 @@ +<div class='wrapper toggleAjax hide'> + <div class='toggleButton'> + <div title="{% trans 'Click to toggle' %}" class='container {{ state }}'> + <img src="{{ pma_theme_image }}toggle-{{ text_dir }}.png"> + <table class='nospacing nopadding'> + <tbody> + <tr> + <td class='toggleOn'> + <span class='hide'>{{ link_on|raw }}</span> + <div>{{ toggle_on }}</div> + </td> + <td><div> </div></td> + <td class='toggleOff'> + <span class='hide'>{{ link_off|raw }}</span> + <div>{{ toggle_off }}</div> + </td> + </tr> + </tbody> + </table> + <span class='hide callback'>{{ callback }}</span> + <span class='hide text_direction'>{{ text_dir }}</span> + </div> + </div> +</div> diff --git a/srcs/phpmyadmin/templates/transformation_overview.twig b/srcs/phpmyadmin/templates/transformation_overview.twig new file mode 100644 index 0000000..d6690fa --- /dev/null +++ b/srcs/phpmyadmin/templates/transformation_overview.twig @@ -0,0 +1,49 @@ +<h2>{% trans 'Available media (MIME) types' %}</h2> + +<ul> + {% for mime_type in mime_types %} + <li> + {{ mime_type.is_empty ? '<em>' }} + {{ mime_type.name }} + {{ mime_type.is_empty ? '</em>' }} + </li> + {% endfor %} +</ul> + +<h2 id="transformation">{% trans 'Available browser display transformations' %}</h2> + +<table> + <thead> + <tr> + <th>{% trans 'Browser display transformation' %}</th> + <th>{% trans %}Description{% context %}for media (MIME) type transformation{% endtrans %}</th> + </tr> + </thead> + <tbody> + {% for transformation in transformations.transformation %} + <tr> + <td>{{ transformation.name }}</td> + <td>{{ transformation.description }}</td> + </tr> + {% endfor %} + </tbody> +</table> + +<h2 id="input_transformation">{% trans 'Available input transformations' %}</h2> + +<table> + <thead> + <tr> + <th>{% trans 'Input transformation' %}</th> + <th>{% trans %}Description{% context %}for media (MIME) type transformation{% endtrans %}</th> + </tr> + </thead> + <tbody> + {% for transformation in transformations.input_transformation %} + <tr> + <td>{{ transformation.name }}</td> + <td>{{ transformation.description }}</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/srcs/phpmyadmin/templates/view_create.twig b/srcs/phpmyadmin/templates/view_create.twig new file mode 100644 index 0000000..857762f --- /dev/null +++ b/srcs/phpmyadmin/templates/view_create.twig @@ -0,0 +1,120 @@ +<!-- CREATE VIEW options --> +<div id="div_view_options"> + <form method="post" action="view_create.php"> + {{ get_hidden_inputs(url_params) }} + <fieldset> + <legend> + {% if ajax_dialog %} + {% trans 'Details' %} + {% else %} + {% if view['operation'] == 'create' %} + {% trans 'Create view' %} + {% else %} + {% trans 'Edit view' %} + {% endif %} + {% endif %} + </legend> + <table class="rte_table"> + {% if view['operation'] == 'create' %} + <tr> + <td class="nowrap"><label for="or_replace">OR REPLACE</label></td> + <td> + <input type="checkbox" name="view[or_replace]" id="or_replace" + {% if (view['or_replace']) %} checked="checked" {% endif %} + value="1"> + </td> + </tr> + {% endif %} + + <tr> + <td class="nowrap"><label for="algorithm">ALGORITHM</label></td> + <td> + <select name="view[algorithm]" id="algorithm"> + {% for option in view_algorithm_options %} + <option value="{{ option }}" + {% if view['algorithm'] == option %} + selected="selected" + {% endif %} + >{{ option }}</option> + {% endfor %} + </select> + </td> + </tr> + + <tr> + <td class="nowrap">{% trans 'Definer' %}</td> + <td><input type="text" maxlength="100" size="50" name="view[definer]" value="{{ view['definer'] }}"></td> + </tr> + + <tr> + <td class="nowrap">SQL SECURITY</td> + <td> + <select name="view[sql_security]"> + <option value=""></option> + {% for option in view_security_options %} + <option value="{{ option }}" + {% if option == view['sql_security'] %} selected="selected" {% endif %} + >{{ option }}</option> + {% endfor %} + </select> + </td> + </tr> + + {% if view['operation'] == 'create' %} + <tr> + <td class="nowrap">{% trans 'VIEW name' %}</td> + <td> + <input type="text" size="20" name="view[name]" onfocus="this.select()" maxlength="64" value="{{ view['name'] }}"> + </td> + </tr> + {% else %} + <tr> + <td> + <input type="hidden" name="view[name]" value="{{ view['name'] }}"> + </td> + </tr> + {% endif %} + + <tr> + <td class="nowrap">{% trans 'Column names' %}</td> + <td> + <input type="text" maxlength="100" size="50" name="view[column_names]" onfocus="this.select()" value="{{ view['column_names'] }}"> + </td> + </tr> + + <tr> + <td class="nowrap">AS</td> + <td> + <textarea name="view[as]" rows="15" cols="40" dir="{{ text_dir }}" onclick="Functions.selectContent(this, sqlBoxLocked, true)">{{ view['as'] }}</textarea><br> + <input type="button" value="Format" id="format" class="btn btn-secondary button sqlbutton"> + <span id="querymessage"></span> + </td> + </tr> + + <tr> + <td class="nowrap">WITH CHECK OPTION</td> + <td> + <select name="view[with]"> + <option value=""></option> + {% for option in view_with_options %} + <option value="{{ option }}" + {% if option == view['with'] %} selected="selected" {% endif %} + >{{ option }}</option> + {% endfor %} + </select> + </td> + </tr> + + </table> + </fieldset> + + <input type="hidden" name="ajax_request" value="1" /> + <input type="hidden" name="{{ (view['operation'] == 'create') ? 'createview' : 'alterview' }}" value="1" /> + + {% if ajax_dialog == false %} + <input type="hidden" name="ajax_dialog" value="1" /> + <input type="submit" name="" value="{% trans 'Go' %}" /> + {% endif %} + + </form> +</div> |
