Merge pull request #871 from cytopia/release/v1.11.0

Release/v1.11.0
This commit is contained in:
cytopia 2022-03-22 21:46:18 +01:00 committed by GitHub
commit ad66ef3dc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4309 changed files with 292490 additions and 368918 deletions

View File

@ -13,8 +13,8 @@ error_reporting(-1);
putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1');
$DEVILBOX_VERSION = 'v1.10.5';
$DEVILBOX_DATE = '2022-03-16';
$DEVILBOX_VERSION = 'v1.11.0';
$DEVILBOX_DATE = '2022-03-22';
$DEVILBOX_API_PAGE = 'devilbox-api/status.json';
//

View File

@ -55,13 +55,13 @@ class OpCacheService
'debounce_rate' => 250
];
private function __construct($options = [])
private function __construct($options = array())
{
$this->options = array_merge($this->defaults, $options);
$this->data = $this->compileState();
}
public static function init($options = [])
public static function init($options = array())
{
$self = new self($options);
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
@ -150,7 +150,7 @@ class OpCacheService
$status = opcache_get_status();
$config = opcache_get_configuration();
$files = [];
$files = array();
if (!empty($status['scripts']) && $this->getOption('allow_filelist')) {
uasort($status['scripts'], function($a, $b) {
return $a['hits'] < $b['hits'];
@ -192,7 +192,7 @@ class OpCacheService
]
);
$directives = [];
$directives = array();
ksort($config['directives']);
foreach ($config['directives'] as $k => $v) {
$directives[] = ['k' => $k, 'v' => $v];

View File

@ -0,0 +1,190 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(true); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>Support</h1>
<br/>
<p>I am currently the sole creator and maintainer of the Devilbox and all of its required projects.<br/>If you find this useful or if it makes your daily programming life easier, consider donating to keep this project alive.</p>
<ul>
<li><a target="_blank" href="https://github.com/sponsors/cytopia"><strong>GitHub sponsorship</strong></a></li>
<li><a target="_blank" href="https://www.patreon.com/devilbox"><strong>Patreon</strong></a></li>
</ul>
<br/>
<div class="row">
<div class="col-md-6">
<h2>Core projects</h2>
<p>The following core projects were created and are maintained in order to make the Devilbox work.</p>
<table class="table table-striped ">
<thead class="thead-inverse ">
<tr>
<th>Repository</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/devilbox">devilbox</a></td>
<td>The Devilbox</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.2">docker-php-fpm-5.2</a></td>
<td>Legacy PHP 5.2 base images (amd64 and i386)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.3">docker-php-fpm-5.3</a></td>
<td>Legacy PHP 5.3 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.4">docker-php-fpm-5.4</a></td>
<td>Legacy PHP 5.4 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.5">docker-php-fpm-5.5</a></td>
<td>Legacy PHP 5.5 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.0">docker-php-fpm-8.0</a></td>
<td>PHP 8.0 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.1">docker-php-fpm-8.1</a></td>
<td>PHP 8.1 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.2">docker-php-fpm-8.2</a></td>
<td>Upcoming PHP 8.2 base images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm">docker-php-fpm</a></td>
<td>PHP-FPM Devilbox images</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-mysql">docker-mysql</a></td>
<td>MySQL, MariaDB and PerconaDB images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-apache-2.2">docker-apache-2.2</a></td>
<td>Apache 2.2 images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-apache-2.4">docker-apache-2.4</a></td>
<td>Apache 2.4 images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-nginx-stable">docker-nginx-stable</a></td>
<td>Nginx stable images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-nginx-mainline">docker-nginx-mainline</a></td>
<td>Nginx mainline images (amd64 and arm64)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-haproxy">docker-haproxy</a></td>
<td>HA Proxy image</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-ngrok">docker-ngrok</a></td>
<td>Ngrok image</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-varnish">docker-varnish</a></td>
<td>Varnish image</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-python-flask">docker-python-flask</a></td>
<td>Python Flask image</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<h2>Supporting projects</h2>
<p>The following supporting projects were created and are maintained in order to keep the Devilbox eco system running.</p>
<table class="table table-striped ">
<thead class="thead-inverse ">
<tr>
<th>Repository</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/cert-gen">cert-gen</a></td>
<td>CA and cert generation tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/vhost-gen">vhost-gen</a></td>
<td>HTTPD agnostic vhost creation tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/watcherd">watcherd</a></td>
<td>OS agnostic filesystem change poller tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/makefiles">makefiles</a></td>
<td>Unified build Makefiles</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/github-actions">github-actions</a></td>
<td>Re-usable GitHub Action Workflows</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/shell-command-retry-action">shell-command-retry-action</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-tag-action">docker-tag-action</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/git-ref-matrix-action">git-ref-matrix-action</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-python-sphinx">docker-python-sphinx</a></td>
<td>Dockerized Sphinx documentation builder</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/xdebug">xdebug</a></td>
<td>IP addr alias MacOS plist for Xdebug</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-ansible">docker-ansible</a></td>
<td>Ansible images for PHP-FPM Dockerfile creation</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/linkcheck">linkcheck</a></td>
<td>Broken linkchecker for documentation</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-linkcheck">docker-linkcheck</a></td>
<td>Dockerized version of linkcheck</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-1.99s">docker-php-1.99s</a></td>
<td>Just for the lulz</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,458 +0,0 @@
phpMyAdmin - ChangeLog
======================
5.0.4 (2020-10-15)
- issue #16245 Fix failed Zoom search clears existing values
- issue Fixed a PHP error when reporting a particular JS error
- issue #16326 Fixed latitude and longitude swap for geometries in edit mode
- issue #16032 Fix CREATE TABLE not being tracked when auto tracking is enabled
- issue #16397 Fix compatibility problems with older PHP versions (also issue #16399)
- issue #16396 Fix broken two-factor authentication
5.0.3 (2020-10-09)
- issue #15983 Require twig ^2.9
- issue Fix option to import files locally appearing as not available
- issue #16048 Fix to allow NULL as a default bit value
- issue #16062 Fix "htmlspecialchars() expects parameter 1 to be string, null given" on Export xml
- issue #16078 Fix no charts in monitor when using a decimal separator ","
- issue #16041 Fix IN(...) clause doesn't permit multiple values on "Search" page
- issue #14411 Support double tap to edit on mobile
- issue #16043 Fix php error "Use of undefined constant MYSQLI_TYPE_JSON" when using the mysqlnd extension
- issue #14611 Fix fatal JS error on index creation after using Enter key to submit the form
- issue #16012 Set "axis-order" to swap lon and lat on MySQL >= 8.1
- issue #16104 Fixed overwriting a bookmarked query causes a PHP fatal error
- issue Fix typo in a condition in the Sql class
- issue #15996 Fix local setup doc links pointing to a wrong location
- issue #16093 Fix error importing utf-8 with bom sql file
- issue #16089 2FA UX enhancement: autofocus 2FA input
- issue #16127 Fix table column description PHP error when ['DisableIS'] = true;
- issue #16130 Fix local documentation links display when a PHP extension is missing
- issue Fix some twig code deprecations for php 8
- issue Fix ENUM and SET display when editing procedures and functions
- issue Keep full query state on "auto refresh" process list
- issue Keep columns order on "auto refresh" process list
- issue Fixed editing a failed query from the error message
- issue #16166 Fix the alter user privileges query to make it MySQL 8.0.11+ compatible
- issue Fix copy table to another database when the nbr of DBs is > $cfg['MaxDbList']
- issue #16157 Fix relations of tables having spaces or special chars not showing in the Designer
- issue #16052 Fix a very rare JS error occuring on mousemove event
- issue #16162 Make a foreign key link clickable in a new tab after the value was saved and replaced
- issue #16163 Fixed a PHP notice "Undefined index: column_info" on views
- issue #14478 Fix the data stream when exporting data in file mode
- issue #16184 Fix templates/ directory not found error
- issue #16184 Remove chdir logic to fix PHP fatal error "Uncaught TypeError: chdir()"
- issue Support for Twig 3
- issue Allow phpmyadmin/twig-i18n-extension ^3.0
- issue #16201 Trim spaces for integer values in table search
- issue #16076 Fixed cannot edit or export TIMESTAMP column with default CURRENT_TIMESTAMP in MySQL >= 8.0.13
- issue #16226 Fix error 500 after copying a table
- issue #16222 Fixed can't use the search page when the table name has special characters
- issue #16248 Fix zoom search is not performing input validation on INT columns
- issue #16248 Fix javascript error when typing in INT fields on zoom search page
- issue Fix type errors when using saved searches
- issue #16261 Fix missing headings on modals of "User Accounts -> Export"
- issue #16146 Fixed sorting did not keep the selector of number of rows
- issue #16194 Fixed SQL query does not appear in case of editing view where definer is not you on MySQL 8
- issue #16255 Fix tinyint(1) shown as INT on Search page
- issue #16256 Fix "Warning: error_reporting() has been disabled for security reasons" on php 7.x
- issue #15367 Fix "Change or reconfigure primary server" link
- issue #15367 Fix first replica links, start, stop, ignore links
- issue #16058 Add "PMA_single_signon_HMAC_secret" for signon auths to make special links work and udate examples
- issue #16269 Support ReCaptcha v2 checkbox width "$cfg['CaptchaMethod'] = 'checkbox';"
- issue #14644 Use Doctum instead of Sami
- issue #16086 Fix "Browse" headings shift when scrolling
- issue #15328 Fix no message after import of zipped shapefile without php-zip
- issue #14326 Fix PHP error when exporting without php-zip
- issue #16318 Fix Profiling doesn't sum the number of calls
- issue #16319 Fixed a Russian translation mistake on search results total text
- issue #15634 Only use session_set_cookie_params once on PHP >= 7.3.0 versions for single signon auth
- issue #14698 Fixed database named as 'New' (language variable) causes PHP fatal error
- issue #16355 Make textareas both sides resizable
- issue #16366 Fix column definition form not showing default value
- issue #16342 Fixed multi-table query (db_multi_table_query.php) alias show the same alias for all columns
- issue #15109 Fixed using ST_GeomFromText + GUI on insert throws an error
- issue #16325 Fixed editing Geometry data throws error on using the GUI
- issue [security] Fix XSS vulnerability with the transformation feature (PMASA-2020-5)
- issue [security] Fix SQL injection vulnerability with search feature (PMASA-2020-6)
5.0.2 (2020-03-20)
- issue Fixed deprecation warning "implode(): Passing glue string after array is deprecated." function on export page
- issue #15767 Fixed can not copy user account since 5.0 - "error #1133"
- issue #15772 Fixed error code 500 during pagination of the tables in a database
- issue #16009 Fix php error "Trying to access array offset on value of type null" on column distinct values feature
- issue #15741 Fix fatal javascript error on clicking "Pick from Central Columns"
- issue #15773 Fixed a view named "views" adds an expand button
- issue #15432 Fixed names of the pages in the designer should be unique
- issue #14310 Fixed column selector "See more" removes "Preview SQL" and "Save" area
- issue Fixed wrong jQuery function call in table search page
- issue #15761 Fix uncaught TypeError when using "$cfg['ServerDefault'] = 0;"
- issue #15780 Fixed unexpected UI of action links (text only mode)
- issue #15674 Replace twig/extensions with phpmyadmin/twig-i18n-extension
- issue #15799 Change location of profiling state documentation to fix column ordering
- issue #15720 Fix designer adding all available tables to a designer page after adding a new relationship
- issue #15791 Replace facebook/webdriver by php-webdriver/webdriver
- issue #15802 Removed SET AUTOCOMMIT=0 from SQL export
- issue #15818 Fix table borders missing on theme original since 5.0.0
- issue #13864 Fix ENUM's radiobuttons reset on "Continue insertion with" changes
- issue #15811 Fixed browse foreign values doesn't show a modal with grid edit
- issue #15817 Fix "new table" layout issue on original theme
- issue #15798 Fixed not needed prompt before abandoning changes on SQL tab after only changing a checkbox
- issue #15833 Fix php TypeError when submitting unchanged data
- issue Fix php notice "Trying to access array offset on value of type bool" on Designer
- issue #13326 Added integer validations on search page
- issue #15200 Fixed server-side HTTPS detection misses support for Forwarded HTTP Extension (RFC 7239)
- issue #15831 Fixed DB names starting with "b" being cut off in <option>, User account page
- issue #15850 Fixed display content from "information_schema.PROCESSLIST"
- issue #15836 Fixed "has no type" error on export and import pages for "Chinese traditional" users
- issue #15863 Fixed designer move menu icon not changing directions and tables menu list resize button
- issue #15854 Fixed black borders for full screen mode on Designer
- issue #15899 Fix "Uncaught TypeError: mb_strtoupper()" on the relational view of a view
- issue Fixed some php uncaught errors and notices on user missing extension
- issue #15926 Fixed PhpMyAdmin\Core::getRealSize('8000M') returns a float instead of an int
- issue #15410 Fixed auto increment reset issue where the last value of AI was saved an could destroy the "good" value
- issue #15187 Fixed editing a row and using 'insert as new row' uses primary key 0 instead of NULL
- issue #15877 Fixed php error "preg_match() expects parameter 2 to be string, null given" on some specific tables
- issue #15795 Fix broken link on "MySQL said" error message
- issue #15781 Fix illegal string offset error on structure page of 'information_schema' database
- issue #15745 Fix version 5.0.1 suggests 4.9.4 as latest stable version
- issue #15958 Fix uncaught TypeError when sorting database tables by size or by rows
- issue #15830 Fix strftime issue on windows for Japanese users on "Structure" tab
- issue Windows testsuite fixes
- issue #15879 Added missing CSS class on "simulate query" button
- issue #15401 Fixed php notice "Undefined index HMAC_secret" for users upgrading phpMyAdmin without a log-out
- issue #15810 Fixed unexpected heading on add a new procedure, trigger, function, routine modals
- issue #15970 Removed wrong html a tag on "Replication status" header
- issue Add missing css classes on some buttons
- issue #15937 Make modals draggability/expand (down) work after a screen zoom change
- issue Fix php notice "Undefined index: on_delete" while creating a foreign key
- issue #15876 Fixed select "IN (...)" is a simple select instead of a multiple select
- issue Fix maxlength for User and Host on replication add user form
- issue #15282 Fixed MySQL 8.0 password syntax error when creating a replication user
- issue #15986 Fixed php fatal error "Uncaught TypeError: array_flip() expects parameter 1 to be array, null given"
- issue Fixed php fatal error "Uncaught TypeError: htmlspecialchars() expects parameter 1 to be string, int given"
- issue Support phpunit 9.0
- issue Fix error in NavigationTree where $key might be sent as an int instead of a str to urlencode
- issue #16022 Fix uncaught TypeError on browse foreigners
- issue Fix failure if relational display field value is NULL - "Display column for relationships"
- issue #16033 Remove vendor bin files from non source version of phpMyAdmin
- issue #15898 [security] Fix escape tbl_storage_engine argument used on tbl_create.php
- issue #15224 Don't fire keyboard shortcuts while SQL query area is focused (on a mobile for example)
- issue [security] Fix SQL injection with certain usernames (PMASA-2020-2)
- issue [security] Fix SQL injection in particular search situations (PMASA-2020-3)
- issue [security] Fix SQL injection and XSS flaw (PMASA-2020-4)
- issue Deprecate "options" for the external transformation; options must now be hard-coded along with the program name directly in the file.
5.0.1 (2020-01-07)
- issue #15719 Fixed error 500 when browsing a table when $cfg['LimitChars'] used a string and not an int value
- issue #14936 Fixed display NULL on numeric fields has showing empty string since 5.0.0
- issue #15722 Fix get Database structure fails with PHP error on replicated server
- issue #15723 Fix can't browse certain tables since 5.0.0 update
- issue Prevent line wrap in DB structure size column
- issue Remove extra line break from downloaded blob content
- issue #15725 Fixed error 500 when exporting - set time limit when $cfg['ExecTimeLimit'] used a string and not an int value
- issue #15726 Fixed double delete icons on enum editor
- issue #15717 Fixed warning popup not dissapearing on table stucture when using actions without any column selection
- issue #15693 Fixed focus of active tab is lost by clicking refresh option on browse tab
- issue #15734 Fix Uncaught TypeError: http_build_query() in setup
- issue Fix double slash in path when $cfg['TempDir'] has a trailing slash
- issue #14875 Fix shp file import tests where failing when php dbase extension was enabled
- issue #14299 Fix JS error "PMA_makegrid is not defined" when clicking on a table from the "Insert" tab opened in a new tab
- issue #15351 Fixed 2FA setting removed each time the user edits another configuration setting
- issue [security] Fix SQL injection vulnerability on the user accounts page (PMASA-2020-1)
5.0.0 (2019-12-26)
- issue #13896 Drop support for PHP 5.5, PHP 5.6, PHP 7.0 and HHVM
- issue #14007 Enable columns names by default for CSV exports
- issue #13919 Remove font size feature
- issue #12373 Add Metro theme
- issue #14155 Add move columns preview SQL button
- issue #14296 Enable strict mode in PHP files
- issue #13627 Increase field width for editing varchar fields
- issue #12603 Show warning for users with the default values for controluser and controlpass
- issue #14589 Fix rendering of column comments in Safari, improve display in all browsers
- issue #14330 New features for csv import plugin
- issue #14417 Automatically add index while editing an existing row and setting auto increment
- issue #13057 Add export option to drop user security definers from views
- issue #14404 Drop view and or replace added to exporting view
- issue #14594 Database "Search" selects all tables by default
- issue #12158 Auto expand the single database
- issue #13067 Inconsistency with submit buttons
- issue #14683 Improper message in Show Hidden Navigation Tree Items
- issue #14695 Remove unlabeled default collation from the bottom of the database list; this information is available elsewhere
- issue #14677 Security confirm() before running UPDATE statement without WHERE condition
- issue #13023 Show errors at the bottom of the page and add copy query button for errors in processing sql queries
- issue #14633 Use Sass instead of PHP to compile CSS
- issue #14765 Add initial support for Bootstrap 4
- issue #14829 Change table column comment field from input to textarea
- issue #14725 Console: ctrl+l clear line and ctrl+u clear console
- issue #14837 Use charset 'windows-1252' when format is MS Excel
- issue #15030 Move 'More settings' link from 'Appearance settings' to 'General settings'
- issue #15029 Remove the redundant 'i' help/tool tip in page settings "Query History Length" area
- issue #13424 Importing CSV now uses file name as the table name instead of 'TABLE #'
- issue #14926 Add an Edit link for each view in tables list
- issue #14890 Display column details in navigation bar
- issue #14977 Add title for group in navigation bar
- issue #14927 Show InnoDB table overhead (free space)
- issue #15072 Add 'Close' button to the Monitor Instructions modal
- issue #15174 Improved filter method in server variables page
- issue #15266 Add an external dependency injection system
- issue #15350 Change MIME type references to Media (MIME) type
- issue Fixed url.php crashing because it's not loading the DatabaseInterface service
- issue #15540 Fixed uncaught TypeError: htmlspecialchars() in NavigationTree
- issue Fix twig deprecation notices for php 8.0
- issue #15435 Fix ReCAPTCHA couldn't find user-provided function: Functions.recaptchaCallback
- issue #15623 Fix width of picker modal and remove date picker for int fields
- issue #14732 Fixed can't rename primary key with auto increment
- issue #15677 Fix show process-list triggers a php exception
- issue #15697 Fix uncaught php error: "Call to a member function get() on null" in db_export.php when exporting a table from the list
4.9.7 (2020-10-15)
- issue #16397 Fix compatibility problems with older PHP versions (also issue #16399)
- issue #16396 Fix broken two-factor authentication
4.9.6 (2020-10-09)
- issue [security] Fix XSS vulnerability with the transformation feature (PMASA-2020-5)
- issue [security] Fix SQL injection vulnerability with search feature (PMASA-2020-6)
4.9.5 (2020-03-20)
- issue [security] Fix SQL injection with certain usernames (PMASA-2020-2)
- issue [security] Fix SQL injection in particular search situations (PMASA-2020-3)
- issue [security] Fix SQL injection and XSS flaw (PMASA-2020-4)
- issue Deprecate "options" for the external transformation; options must now be hard-coded along with the program name directly in the file.
4.9.4 (2020-01-07)
- issue #15724 Fix 2FA was disabled by a bug
- issue [security] Fix SQL injection vulnerability on the user accounts page (PMASA-2020-1)
4.9.3 (2019-12-26)
- issue #15570 Fix page contents go underneath of floating menubar in some cases
- issue #15591 Fix php notice 'Undefined index: foreign_keys_data' on relations view when the user has column access
- issue #15592 Fix php warning "error_reporting() has been disabled for security reasons"
- issue #15434 Fix middle click on table sort column name shows a blank page
- issue Fix php notice "Undefined index table_create_time" when setting displayed columns on results of a view
- issue #15571 Fix fatal error when trying to edit row with row checked and button under the table
- issue #15633 Fix designer set display field broken for php 5.x versions
- issue #15621 Support CloudFront-Forwarded-Proto header for Amazon CloudFront proxy
- issue Fix php 8.0 php notices - Undefined index on login page
- issue #15640 Fix php 7.4 error when trying to access array offset on value of type null on table browse
- issue #15641 Fix replication actions where broken (start slave, stop slave, reset, ...)
- issue #15608 Fix DisableIS is broken when with controluser configured (database list broken)
- issue #15614 Fix undefined offset on index page for MySQL 5.7.8 (server charset)
- issue #15692 Fix JavaScript error when user has not enough privilege to view query statistics.
- issue #14248 Fixed date selection in search menu missing higher Z-index value
- issue Fix Uncaught php TypeError on php 8.0 when adding a column to table create form
- issue #15682 Fix calendar not taking current time as default value
- issue #15636 Fix php error trying to access array offset on value o type null on replication GUI
- issue #15695 Fix input field for the time in datetime picker is disabled
4.9.2 (2019-11-21)
- issue #14184 Change the cookie name from phpMyAdmin to phpMyAdmin_https for HTTPS, fixes many "Failed to set session cookie" errors
- issue #15304 Fix ssl_use php error
- issue #14804 Fix undefined index: ssl_* variables
- issue #14245 Fix mysql 8.0.3 and above fails on advisor
- issue #15499 Fix unparenthesized php deprecation
- issue #15482 Fix URL encoding plus sign (+) in the table or DB name when configuring foreign keys
- issue #14898 Fixed bottom table in list in left panel blocked by horizontal scroll bar
- issue #15161 Fix text area overflows its parent element on "Query" page
- issue #15511 Fixed exporting users after a delete will delete all selected users on "Users" page
- issue #14598 Fixed checking referencial integrity on "Operations" page
- issue #14433 Fix "You do not have privileges to manipulate with the users!" on root superadmin
- issue #15391 Fix GIS polygon of a geometry field is not drawn on "GIS visualization"
- issue #15311 Fix adjust privileges on copy database fails with MariaDB
- issue #15477 Fix display referential integrity check for InnoDB
- issue #15236 Support phpunit 8 in our test suite to help packaging phpMyAdmin on Debian
- issue #15522 Fix missing image error fills logs, removed ic_b_info icon from icon list
- issue #15537 Fixed some issues with the sort by key selectors
- issue #15546 Fix operators precedence in DatabaseInterface class
- issue #14906 Test test suite on 32-bit systems
- issue Fix Long2IP transformation issue with PHP 7.1
- issue #14951 Fix moving columns with DEFAULT NULL doesn't work on MariaDB 10.2+
- issue #14951 Fix moving columns with INT AND DEFAULT CURRENT_TIMESTAMP doesn't work on MariaDB
- issue #12241 Fixed table alias is removed when exporting a query
- issue #15316 Fixed cross join clause is removed on export
- issue #14809 Fix error "is_uploaded_file() expects parameter 1 to be string" when inserting blobs from files
- issue #15127 Fix white square when refreshing designer or browsing other pages
- issue #13912 Detect when phpMyAdmin storage tables are not accessible, help users browse corrupt DBs
- issue #15465 Display profiling when query outputs no rows
- issue Fix setting and removing display field on Designer
- issue Added a warning when trying to set a display field on Designer and configuration storage is not setup
- issue #15327 Fix shift-click in Export misses a checkbox
- issue [security] Fix improperly sanitized data when showing the Git branch (thanks to Ali Hubail for this report)
- issue [security] Fix security weaknesses in Designer feature,including a flaw where an attacker could trigger an SQL injection attack (PMASA-2019-5)
4.9.1 (2019-09-20)
- issue #15313 Added support for Twig 2
- issue #15315 Fix cannot edit or export column with default CURRENT_TIMESTAMP in MySQL >= 8.0.13
- issue Fix a TypeError in Import class with PHP 8
- issue #14270 Fix Middle-click on foreign key link broken
- issue #14363 Fix broken relational links in tables
- issue #14987 Fix weird error for empty collation
- issue #15334 Fix export of GIS visualisation not working (PNG, PDF, SVG)
- issue #14918 Use hex for the phpMyAdmin session token
- issue Added GB18030 Chinese collations description
- issue Added Russian, Swedish, Slovak and Chinese UCA 9.0.0 collations description
- issue Added description for the _ks (kana-sensitive) collation suffix
- issue Added description for the _nopad (NO PAD) collation suffix
- issue #15404 Remove array/string curly braces access
- issue #15427 Fixed "FilterLanguages" option does not work (configuration)
- issue #15202 Fixed creating user with single quote in password results in no password user
- issue #14950 Fixed left database overview "add column" triggers error
- issue #15363 Fix remove unexpected quotes on text fields (structure and insert)
- issue Fix NULL wrongly checked on field change
- issue #15388 Fix allow to rollback an empty statement
- issue #14291 Fixed incorrect linkage from one table's value to another table
- issue #15446 Fix tables added from other databases are not collapsing in the designer section
- issue #14945 Fix designer page save fails if dB name contains period
- issue Display an error when trying to import in designer a table that's already imported
- issue Fix many bugs when adding new tables to designer
- issue Update CodeMirror to v5.48.4
- issue Update jQuery Migrate to v3.1.0
- issue Update jQuery Validation to v1.19.1
- issue Update jQuery to v3.4.1
- issue Update js-cookie to v2.2.1
- issue Remove fieldset closing tag when setting global privileges
- issue #15425 Fix backslash in column name resulting an error in editing
- issue #15380 Fix Status - Advisor error
- issue #15439 Fix designer page status not updated when added a new table from another database
- issue #15440 Fix page number is not being updated in the URL after saving a designer's page
- issue Fix reloading a designer's page
- issue Fix designer full screen mode button and text stuck when exiting full-screen mode
- issue Reduced possibility of causing heavy server traffic between the database and web servers
- issue Fix a situation where a server could be deleted while an administator is using the setup script
4.9.0.1 (2019-06-04)
- issue #14478 phpMyAdmin no longer streams the export data
- issue #14514 Tables with SYSTEM VERSIONING show up as views instead of tables
- issue #14515 Values cannot be edited in SYSTEM VERSIONING tables with INVISIBLE timestamps
- issue Fix header icon on server plugins page
- issue #14298 Fixed error 500 on MultiTableQuery page when a empty query is passed
- issue #14402 Fixed fatal javascript error while adding index to a new column
- issue #14896 Fixed issue with plus/minus icon when refreshing an expanded database
- issue #14922 Fixed json encode error in export
- issue #13975 Fixed missing query time in German (fix decimal number format issue)
- issue #14503 Fixed JavaScript events not activating on input (sql bookmark issue)
- issue #14898 Fixed Bottom table is blocked in database list (left panel)
- issue #14425 Fixed Null Checkbox automatically unmarked
- issue #14870 Display correct date and time in Zip files
- issue #14763 Fixed the loading symbol not appearing when refreshing the navigation
- issue #14607 Count rows only if needed
- issue #14832 Show Designer combo boxes when adding a constraint
- issue #14948 Fix change password is not showing password strength difference at the second attempt
- issue #14868 Fix edit view
- issue #14943 Fixed loading Forever when creating new view without filling any field
- issue #14843 Fix Bookmark::get() id matching SQL
- issue #14734 Fixed invalid default value for bit field
- issue #14311 Fixed undefined index in setup script
- issue #14991 Fixed TypeError in GIS editor
- issue Fixed GIS data editor for multi server setup
- issue #14312 Fixed type error in setup script when adding new server
- issue #14053 Fix missed padding on query results
- issue #14826 Fixed javascript error PMA_messages is not defined
- issue Show error message if config-set fails and not "loading..." forever
- issue #14359 Prevent multiple error modals, and error-report request spamming from script
- issue Fixed error reporting javascript errors on multi server setup
- issue Fixed wrong property name on TableStructureController
- issue #14811 Fix SHOW FULL TABLES FROM when a table is locked
- issue #14916 Fix bug when creating or editing views
- issue #14931 Fixed php error when using a query like SELECT 1 INTO @a; SELECT @a; in inline query edit
- issue #15074 Make the server logo visible on theme "original"
- issue #15077 Fixed incorrect page numbers
- issue #14205 Fixed "No tables found in database" when you delete all tables from last page
- issue #14957 Virtuality is not selected when editing generated column (added virtuality(stored) option for mariadb)
- issue #14853 Insert page should not allow entering things into virtual columns
- issue #15110 Fixed TypeError e.preventDefaulut is not a function
- issue #15115 Improved label in Settings export, clarifying that it's a JSON file
- issue #14816 Fixed [designer] Cannot read property 'style' of null
- issue Fixed [designer] Add new tables with database/table list modal
- issue Fixed query format on multi server setup
- issue Fixed remove partitioning on multi server setup
- issue Fixed normalization
- issue Fixed 'RESET SLAVE' button on replication slave
- issue Fixed sending a php error report on multi server setup
- issue Fixed downloading of monitor parameters for IE 11, Edge, Chrome and others
- issue #15141 Fixed php notice Undefined index: designer_settings
- issue #12729 Fixed sticky table header over dropdown menu
- issue #15140 Fixed edit link does not work on failed insert
- issue #14334 Fixed export table structure shows rows fields
- issue #15010 Fixed empty SQL preview modal on tbl_relation
- issue #14673 Fixed innodb & MySQL 8: DYNAMIC & COMPRESSED ROW_FORMAT missing
- issue Fixed empty success message when adding a new INDEX from left panel
- issue #15150 Fixed generate password hidden on second open of change password modal
- issue Fixed import XML data with leading zeros
- issue #15036 Fixed missing input fields checks for MaxSizeForInputField
- issue #15119 Fixed uninterpreted HTML on Settings->Export page
- issue #15159 Fixed missing query time and database in console
- issue #13713 Fixed column comments in the floating table header
- issue #15177 Fixed label alignment on login page
- issue #15210 Fixed a typo in the english name of the Albanian language
- issue Fixed issue when resetting charset in import.php
- issue #14460 Fixed forms where submitted multiple times on CTRL + ENTER
- issue #15038 Fixed console height was allowing a negative values
- issue #15219 Fixed 'No Password' option does not switch automatically to 'Use Text Field' in add user account
- issue Fixed importing the exported config on Server status monitor page
- issue #15228 Fixed php notice 'Undefined index: foreign_keys_data' on designer when the user has column access
- issue #12900 Fixed designer page saving gives error when configuration storage is not set up
- issue #15229 Fixed php notice, added support for 'DELETE HISTORY' table privilege (MariaDB >= 10.3.4)
- issue #14527 Fixed import settings function not working
- issue #14908 Fixed uninterpreted HTML on Settings->Import (missing data error descriptions)
- issue #14800 Fixed status->Processes doesn't show full query process list page
- issue #14833 Fixed sort by Time not working in process list page
- issue #14982 Fixed setting "null" keep an "enum" value
- issue #14401 Fixed insert rows keypress Enter behavior
- issue #15146 Fixed error reports can not be sent because they are too large
- issue #15205 Fixed useless backquotes on sql preview modal when deleting an index
- issue #13178 Fixed issues with uppercase table and database names (lower_case_table_names=1)
- issue #14383 Fixed warning when browsing certain tables (GIS data)
- issue #12865 Fixed MySQL 8.0.0 issues with GIS display
- issue #15059 Fixed "Server charset" in "Database server" tab showing wrong information
- issue #14614 Fixed mysql error "#2014 - Commands out of sync; you can't run this command now" on sql query
- issue #15238 Fixed phpMyAdmin 4.8.5 doesn't show privileges of procedures (raw html displayed instead)
- issue #13726 Fixed can not copy user on Percona Server 5.7
- issue #15239 Fixed javascript error while fetching latest version info and switching pages
- issue #14301 Fixed javascript error when editing a JSON data type column
- issue #15240 Fixed apply a Settings form with errors shows a JSON response after using return back
- issue #15043 Fixed multiple errors printing on Settings page
- issue #15037 Fixed unexpected behavior of reset button on Settings
- issue #15157 Fixed 'Settings' tab not marked as active when browsing 2FA settings
- issue #14934 Fixed all fields readonly on Edit/Insert screens
- issue #14588 Fixed export of geometry objects, GIS objects are now exported as hex
- issue #14412 Better handling of errors with Signon authentication type
- issue Added support for AUTO_INCREMENT when using ROCKSDB, on Operations page
- issue #15276 Fixed partitioning is missing in Structure page UI (MySQL 8.0)
- issue #14252 Fixed DisableIS and database tree list (new database missing when refreshing the list)
- issue #14621 Removed "Propose table structure" on MySQL 8.0
- issue Fixed editing of virtual columns on PerconaDB
- issue #13854 Fixed column options are ignored for GENERATED/VIRTUAL/STORED columns
- issue #15262 Fixed incorrect display of charset column (raw html)
- issue Added explicit parentheses in nested ternary operators
- issue #15287 Fix auto_increment field is too small
- issue #15283 Fix tries to change collation on views when changing collation on all tables/fields
- issue Fixed empty PMA_gotoWhitelist JavaScript array
- issue #15079 Fixed responsive behaviour of instruction dialog box
- issue #10846 Fixed javascript error when renaming a table
- issue Updated sql-parser to version 4.3.2
- issue [security] SQL injection in Designer (PMASA-2019-3)
- issue [security] CSRF attack on 'cookie' login form (PMASA-2019-4)
4.8.5 (2019-01-25)
- issue Developer debug data was saved to the PHP error log
- issue #14217 Fix issue when adding user on MySQL 8.0.11
- issue #13788 Exporting a view structure based on another view with a sub-query throws no database selected error
- issue #14635 Fix PHP error in GitRevision, error in processing request, error code 200
- issue #14787 Cannot execute stored procedure
- issue Add Burmese language
- issue #14794 Not responding to click, frozen interface, plugin Text_Plain_Sql error
- issue #14786 Table level Operations functions missing
- issue #14791 PHP warning, db_export.php#L91 urldecode()
- issue #14775 Export to SQL format not available for tables
- issue #14782 Error message shown instead of two-factor QR code when adding 2fa to a user
- issue [security] Arbitrary file read/delete relating to MySQL LOAD DATA LOCAL INFILE and an evil server instance (PMASA-2019-1)
- issue [security] SQL injection in Designer (PMASA-2019-2)
--- Older ChangeLogs can be found on our project website ---
https://www.phpmyadmin.net/old-stuff/ChangeLogs/
# vim: et ts=4 sw=4 sts=4
# vim: ft=changelog fenc=utf-8
# vim: fde=getline(v\:lnum-1)=~'^\\s*$'&&getline(v\:lnum)=~'\\S'?'>1'\:1&&v\:lnum>4&&getline(v\:lnum)!~'^#'
# vim: fdn=1 fdm=expr

View File

@ -1,52 +0,0 @@
phpMyAdmin - Readme
===================
Version 5.0.4
A web interface for MySQL and MariaDB.
https://www.phpmyadmin.net/
Summary
-------
phpMyAdmin is intended to handle the administration of MySQL over the web.
For a summary of features, list of requirements, and installation instructions,
please see the documentation in the ./doc/ folder or at https://docs.phpmyadmin.net/
Copyright
---------
Copyright © 1998 onwards -- the phpMyAdmin team
Certain libraries are copyrighted by their respective authors;
see the full copyright list for details.
For full copyright information, please see ./doc/copyright.rst
License
-------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2, as published by the
Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Licensing of current contributions
----------------------------------
Beginning on 2013-12-01, new contributions to this codebase are all licensed
under terms compatible with GPLv2-or-later. phpMyAdmin is currently
transitioning older code to GPLv2-or-later, but work is not yet complete.
Enjoy!
------
The phpMyAdmin team

View File

@ -1 +0,0 @@
Thu Oct 15 18:06:40 UTC 2020

View File

@ -1,74 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Generic AJAX endpoint for getting information about database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\AjaxController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
$_GET['ajax_request'] = 'true';
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
$response->setAjax(true);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var AjaxController $controller */
$controller = $containerBuilder->get(AjaxController::class);
if (empty($_POST['type'])) {
Core::fatalError(__('Bad type!'));
}
switch ($_POST['type']) {
case 'list-databases':
$response->addJSON($controller->databases());
break;
case 'list-tables':
Util::checkParameters(['db'], true);
$response->addJSON($controller->tables([
'db' => $_POST['db'],
]));
break;
case 'list-columns':
Util::checkParameters(['db', 'table'], true);
$response->addJSON($controller->columns([
'db' => $_POST['db'],
'table' => $_POST['table'],
]));
break;
case 'config-get':
Util::checkParameters(['key'], true);
$response->addJSON($controller->getConfig([
'key' => $_POST['key'],
]));
break;
case 'config-set':
Util::checkParameters(['key', 'value'], true);
$result = $controller->setConfig([
'key' => $_POST['key'],
'value' => $_POST['value'],
]);
if ($result !== true) {
$response->setRequestStatus(false);
$response->addJSON('message', $result);
}
break;
default:
Core::fatalError(__('Bad type!'));
}

View File

@ -1,62 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* display selection for relational field values
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\BrowseForeigners;
use PhpMyAdmin\Controllers\BrowseForeignersController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
Util::checkParameters(['db', 'table', 'field'], true);
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
/* Register BrowseForeignersController dependencies */
$containerBuilder->set(
'browse_foreigners',
new BrowseForeigners(
(int) $GLOBALS['cfg']['LimitChars'],
(int) $GLOBALS['cfg']['MaxRows'],
(int) $GLOBALS['cfg']['RepeatCells'],
(bool) $GLOBALS['cfg']['ShowAll'],
$GLOBALS['pmaThemeImage'],
$template
)
);
/** @var BrowseForeignersController $controller */
$controller = $containerBuilder->get(BrowseForeignersController::class);
$response->getFooter()->setMinimal();
$header = $response->getHeader();
$header->disableMenuAndConsole();
$header->setBodyId('body_browse_foreigners');
$response->addHTML($controller->index([
'db' => $_POST['db'] ?? null,
'table' => $_POST['table'] ?? null,
'field' => $_POST['field'] ?? null,
'fieldkey' => $_POST['fieldkey'] ?? null,
'data' => $_POST['data'] ?? null,
'foreign_showAll' => $_POST['foreign_showAll'] ?? null,
'foreign_filter' => $_POST['foreign_filter'] ?? null,
]));

View File

@ -1,112 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Simple script to set correct charset for changelog
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/**
* Gets core libraries and defines some variables
*/
require ROOT_PATH . 'libraries/common.inc.php';
/** @var Template $template */
$template = $containerBuilder->get('template');
$response = Response::getInstance();
$response->disable();
$response->getHeader()->sendHttpHeaders();
$filename = CHANGELOG_FILE;
/**
* Read changelog.
*/
// Check if the file is available, some distributions remove these.
if (@is_readable($filename)) {
// Test if the if is in a compressed format
if (substr($filename, -3) == '.gz') {
ob_start();
readgzfile($filename);
$changelog = ob_get_contents();
ob_end_clean();
} else {
$changelog = file_get_contents($filename);
}
} else {
printf(
__(
'The %s file is not available on this system, please visit ' .
'%s for more information.'
),
$filename,
'<a href="https://www.phpmyadmin.net/">phpmyadmin.net</a>'
);
exit;
}
/**
* Whole changelog in variable.
*/
$changelog = htmlspecialchars($changelog);
$github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
$faq_url = 'https://docs.phpmyadmin.net/en/latest/faq.html';
$replaces = [
'@(https?://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
=> '<a href="url.php?url=\\1">\\1</a>',
// mail address
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*@.*)&gt;/i'
=> '\\1 <a href="mailto:\\3">\\2</a>',
// FAQ entries
'/FAQ ([0-9]+)\.([0-9a-z]+)/i'
=> '<a href="url.php?url=' . $faq_url . '#faq\\1-\\2">FAQ \\1.\\2</a>',
// GitHub issues
'/issue\s*#?([0-9]{4,5}) /i'
=> '<a href="url.php?url=' . $github_url . 'issues/\\1">issue #\\1</a> ',
// CVE/CAN entries
'/((CAN|CVE)-[0-9]+-[0-9]+)/'
=> '<a href="url.php?url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
// PMASAentries
'/(PMASA-[0-9]+-[0-9]+)/'
=> '<a href="url.php?url=https://www.phpmyadmin.net/security/\\1/">\\1</a>',
// Highlight releases (with links)
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/'
=> '<a id="\\1_\\2_\\3"></a>'
. '<a href="url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
. '\\1.\\2.\\3.0 \\4</a>',
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/'
=> '<a id="\\1_\\2_\\3_\\4"></a>'
. '<a href="url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
. '\\1.\\2.\\3.\\4 \\5</a>',
// Highlight releases (not linkable)
'/( ### )(.*)/'
=> '\\1<b>\\2</b>',
// Links target and rel
'/a href="/' => 'a target="_blank" rel="noopener noreferrer" href="',
];
header('Content-type: text/html; charset=utf-8');
echo $template->render('changelog', [
'changelog' => preg_replace(array_keys($replaces), $replaces, $changelog),
]);

View File

@ -1,47 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays status of phpMyAdmin configuration storage
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
// If request for creating the pmadb
if (isset($_POST['create_pmadb']) && $relation->createPmaDatabase()) {
$relation->fixPmaTables('phpmyadmin');
}
// If request for creating all PMA tables.
if (isset($_POST['fixall_pmadb'])) {
$relation->fixPmaTables($GLOBALS['db']);
}
$cfgRelation = $relation->getRelationsParam();
// If request for creating missing PMA tables.
if (isset($_POST['fix_pmadb'])) {
$relation->fixPmaTables($cfgRelation['db']);
}
$response->addHTML(
$relation->getRelationsParamDiagnostic($cfgRelation)
);

View File

@ -1,112 +0,0 @@
{
"name": "phpmyadmin/phpmyadmin",
"type": "project",
"description": "A web interface for MySQL and MariaDB",
"keywords": ["phpmyadmin","mysql","web"],
"homepage": "https://www.phpmyadmin.net/",
"support": {
"forum": "https://www.phpmyadmin.net/support/",
"issues": "https://github.com/phpmyadmin/phpmyadmin/issues",
"wiki": "https://wiki.phpmyadmin.net/",
"docs": "https://docs.phpmyadmin.net/",
"source": "https://github.com/phpmyadmin/phpmyadmin"
},
"license": "GPL-2.0-only",
"authors": [
{
"name": "The phpMyAdmin Team",
"email": "developers@phpmyadmin.net",
"homepage": "https://www.phpmyadmin.net/team/"
}
],
"non-feature-branches": ["RELEASE_.*"],
"autoload": {
"psr-4": {
"PhpMyAdmin\\": "libraries/classes"
}
},
"autoload-dev": {
"psr-4": {
"PhpMyAdmin\\Tests\\": "test/classes",
"PhpMyAdmin\\Tests\\Selenium\\": "test/selenium/"
}
},
"repositories": [
{
"type": "composer",
"url": "https://www.phpmyadmin.net"
}
],
"require": {
"php": "^7.1.3",
"ext-hash": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mysqli": "*",
"ext-pcre": "*",
"ext-xml": "*",
"google/recaptcha": "^1.1",
"phpmyadmin/motranslator": "^4.0",
"phpmyadmin/shapefile": "^2.0",
"phpmyadmin/sql-parser": "^5.0",
"phpmyadmin/twig-i18n-extension": "^2.0 || ^3.0",
"phpseclib/phpseclib": "^2.0",
"symfony/config": "^4.2.8",
"symfony/dependency-injection": "^4.2.8",
"symfony/expression-language": "^4.2",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
"symfony/yaml": "^4.2.8",
"twig/twig": "^2.9 || ^3",
"williamdes/mariadb-mysql-kbs": "^1.2"
},
"conflict": {
"phpseclib/phpseclib": "2.0.8",
"tecnickcom/tcpdf": "<6.2",
"pragmarx/google2fa": ">=6.1",
"pragmarx/google2fa-qrcode": "<1.0.1",
"samyoul/u2f-php-server": "<1.1"
},
"suggest": {
"ext-openssl": "Cookie encryption",
"ext-curl": "Updates checking",
"ext-opcache": "Better performance",
"ext-zlib": "For gz import and export",
"ext-bz2": "For bzip2 import and export",
"ext-zip": "For zip import and export",
"ext-gd2": "For image transformations",
"ext-mbstring": "For best performance",
"tecnickcom/tcpdf": "For PDF support",
"pragmarx/google2fa-qrcode": "For 2FA authentication",
"samyoul/u2f-php-server": "For FIDO U2F authentication"
},
"require-dev": {
"php-webdriver/webdriver": "^1.7.1",
"phpmyadmin/coding-standard": "^1.0",
"phpstan/phpstan": "^0.11.5",
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.0",
"pragmarx/google2fa-qrcode": "^1.0.1",
"samyoul/u2f-php-server": "^1.1",
"squizlabs/php_codesniffer": "^3.0",
"tecnickcom/tcpdf": "^6.3"
},
"extra": {
"branch-alias": {
"dev-master": "5.0.x-dev"
}
},
"scripts": {
"phpcbf": "phpcbf",
"phpcs": "phpcs",
"phpstan": "phpstan analyse",
"phpunit": "phpunit",
"test": [
"@phpcs",
"@phpstan",
"@phpunit"
]
},
"config":{
"sort-packages": true
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Central Columns view/edit
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
use PhpMyAdmin\CentralColumns;
use PhpMyAdmin\Controllers\Database\CentralColumnsController;
use PhpMyAdmin\Core;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var CentralColumns $centralColumns */
$centralColumns = $containerBuilder->get('central_columns');
/** @var CentralColumnsController $controller */
$controller = $containerBuilder->get(CentralColumnsController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
if (isset($_POST['edit_save'])) {
echo $controller->editSave([
'col_name' => $_POST['col_name'] ?? null,
'orig_col_name' => $_POST['orig_col_name'] ?? null,
'col_default' => $_POST['col_default'] ?? null,
'col_default_sel' => $_POST['col_default_sel'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
'col_isNull' => $_POST['col_isNull'] ?? null,
'col_length' => $_POST['col_length'] ?? null,
'col_attribute' => $_POST['col_attribute'] ?? null,
'col_type' => $_POST['col_type'] ?? null,
'collation' => $_POST['collation'] ?? null,
]);
exit;
} elseif (isset($_POST['add_new_column'])) {
$tmp_msg = $controller->addNewColumn([
'col_name' => $_POST['col_name'] ?? null,
'col_default' => $_POST['col_default'] ?? null,
'col_default_sel' => $_POST['col_default_sel'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
'col_isNull' => $_POST['col_isNull'] ?? null,
'col_length' => $_POST['col_length'] ?? null,
'col_attribute' => $_POST['col_attribute'] ?? null,
'col_type' => $_POST['col_type'] ?? null,
'collation' => $_POST['collation'] ?? null,
]);
}
if (isset($_POST['populateColumns'])) {
$response->addHTML($controller->populateColumns([
'selectedTable' => $_POST['selectedTable'],
]));
exit;
}
if (isset($_POST['getColumnList'])) {
$response->addJSON('message', $controller->getColumnList([
'cur_table' => $_POST['cur_table'] ?? null,
]));
exit;
}
if (isset($_POST['add_column'])) {
$tmp_msg = $controller->addColumn([
'table-select' => $_POST['table-select'] ?? null,
'column-select' => $_POST['column-select'] ?? null,
]);
}
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('database/central_columns.js');
if (isset($_POST['edit_central_columns_page'])) {
$response->addHTML($controller->editPage([
'selected_fld' => $_POST['selected_fld'] ?? null,
'db' => $_POST['db'] ?? null,
]));
exit;
}
if (isset($_POST['multi_edit_central_column_save'])) {
$message = $controller->updateMultipleColumn([
'db' => $_POST['db'] ?? null,
'orig_col_name' => $_POST['orig_col_name'] ?? null,
'field_name' => $_POST['field_name'] ?? null,
'field_default_type' => $_POST['field_default_type'] ?? null,
'field_default_value' => $_POST['field_default_value'] ?? null,
'field_length' => $_POST['field_length'] ?? null,
'field_attribute' => $_POST['field_attribute'] ?? null,
'field_type' => $_POST['field_type'] ?? null,
'field_collation' => $_POST['field_collation'] ?? null,
'field_null' => $_POST['field_null'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
]);
if (! is_bool($message)) {
$response->setRequestStatus(false);
$response->addJSON('message', $message);
}
}
if (isset($_POST['delete_save'])) {
$tmp_msg = $controller->deleteSave([
'db' => $_POST['db'] ?? null,
'col_name' => $_POST['col_name'] ?? null,
]);
}
$response->addHTML($controller->index([
'pos' => $_POST['pos'] ?? null,
'total_rows' => $_POST['total_rows'] ?? null,
]));
$pos = 0;
if (Core::isValid($_POST['pos'], 'integer')) {
$pos = (int) $_POST['pos'];
}
$num_cols = $centralColumns->getColumnsCount(
$db,
$pos,
(int) $GLOBALS['cfg']['MaxRows']
);
$message = Message::success(
sprintf(__('Showing rows %1$s - %2$s.'), $pos + 1, $pos + $num_cols)
);
if (isset($tmp_msg) && $tmp_msg !== true) {
$message = $tmp_msg;
}

View File

@ -1,31 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Renders data dictionary
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\DataDictionaryController;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
Util::checkParameters(['db']);
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DataDictionaryController $controller */
$controller = $containerBuilder->get(DataDictionaryController::class);
$header = $response->getHeader();
$header->enablePrintView();
$response->addHTML($controller->index());

View File

@ -1,236 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* phpMyAdmin designer general code
*
* @package PhpMyAdmin-Designer
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Designer;
use PhpMyAdmin\Database\Designer\Common;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Designer $databaseDesigner */
$databaseDesigner = $containerBuilder->get('designer');
/** @var Common $designerCommon */
$designerCommon = $containerBuilder->get('designer_common');
if (isset($_POST['dialog'])) {
if ($_POST['dialog'] == 'edit') {
$html = $databaseDesigner->getHtmlForEditOrDeletePages($_POST['db'], 'editPage');
} elseif ($_POST['dialog'] == 'delete') {
$html = $databaseDesigner->getHtmlForEditOrDeletePages($_POST['db'], 'deletePage');
} elseif ($_POST['dialog'] == 'save_as') {
$html = $databaseDesigner->getHtmlForPageSaveAs($_POST['db']);
} elseif ($_POST['dialog'] == 'export') {
$html = $databaseDesigner->getHtmlForSchemaExport(
$_POST['db'],
$_POST['selected_page']
);
} elseif ($_POST['dialog'] == 'add_table') {
// Pass the db and table to the getTablesInfo so we only have the table we asked for
$script_display_field = $designerCommon->getTablesInfo($_POST['db'], $_POST['table']);
$tab_column = $designerCommon->getColumnsInfo($script_display_field);
$tables_all_keys = $designerCommon->getAllKeys($script_display_field);
$tables_pk_or_unique_keys = $designerCommon->getPkOrUniqueKeys($script_display_field);
$html = $databaseDesigner->getDatabaseTables(
$_POST['db'],
$script_display_field,
[],
-1,
$tab_column,
$tables_all_keys,
$tables_pk_or_unique_keys
);
}
if (! empty($html)) {
$response->addHTML($html);
}
return;
}
if (isset($_POST['operation'])) {
if ($_POST['operation'] == 'deletePage') {
$success = $designerCommon->deletePage($_POST['selected_page']);
$response->setRequestStatus($success);
} elseif ($_POST['operation'] == 'savePage') {
if ($_POST['save_page'] == 'same') {
$page = $_POST['selected_page'];
} else { // new
if ($designerCommon->getPageExists($_POST['selected_value'])) {
$response->addJSON(
'message',
/* l10n: The user tries to save a page with an existing name in Designer */
__(
sprintf(
"There already exists a page named \"%s\" please rename it to something else.",
htmlspecialchars($_POST['selected_value'])
)
)
);
$response->setRequestStatus(false);
return;
} else {
$page = $designerCommon->createNewPage($_POST['selected_value'], $_POST['db']);
$response->addJSON('id', $page);
}
}
$success = $designerCommon->saveTablePositions($page);
$response->setRequestStatus($success);
} elseif ($_POST['operation'] == 'setDisplayField') {
[
$success,
$message,
] = $designerCommon->saveDisplayField(
$_POST['db'],
$_POST['table'],
$_POST['field']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'addNewRelation') {
list($success, $message) = $designerCommon->addNewRelation(
$_POST['db'],
$_POST['T1'],
$_POST['F1'],
$_POST['T2'],
$_POST['F2'],
$_POST['on_delete'],
$_POST['on_update'],
$_POST['DB1'],
$_POST['DB2']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'removeRelation') {
list($success, $message) = $designerCommon->removeRelation(
$_POST['T1'],
$_POST['F1'],
$_POST['T2'],
$_POST['F2']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'save_setting_value') {
$success = $designerCommon->saveSetting($_POST['index'], $_POST['value']);
$response->setRequestStatus($success);
}
return;
}
require ROOT_PATH . 'libraries/db_common.inc.php';
$script_display_field = $designerCommon->getTablesInfo();
$display_page = -1;
$selected_page = null;
if (isset($_GET['query'])) {
$display_page = $designerCommon->getDefaultPage($_GET['db']);
} elseif (! empty($_GET['page'])) {
$display_page = $_GET['page'];
} else {
$display_page = $designerCommon->getLoadingPage($_GET['db']);
}
if ($display_page != -1) {
$selected_page = $designerCommon->getPageName($display_page);
}
$tab_pos = $designerCommon->getTablePositions($display_page);
$fullTableNames = [];
foreach ($script_display_field as $designerTable) {
$fullTableNames[] = $designerTable->getDbTableString();
}
foreach ($tab_pos as $position) {
if (! in_array($position['dbName'] . '.' . $position['tableName'], $fullTableNames)) {
foreach ($designerCommon->getTablesInfo($position['dbName'], $position['tableName']) as $designerTable) {
$script_display_field[] = $designerTable;
}
}
}
$tab_column = $designerCommon->getColumnsInfo($script_display_field);
$script_tables = $designerCommon->getScriptTabs($script_display_field);
$tables_pk_or_unique_keys = $designerCommon->getPkOrUniqueKeys($script_display_field);
$tables_all_keys = $designerCommon->getAllKeys($script_display_field);
$classes_side_menu = $databaseDesigner->returnClassNamesFromMenuButtons();
$script_contr = $designerCommon->getScriptContr($script_display_field);
$params = ['lang' => $GLOBALS['lang']];
if (isset($_GET['db'])) {
$params['db'] = $_GET['db'];
}
$response = Response::getInstance();
$response->getFooter()->setMinimal();
$header = $response->getHeader();
$header->setBodyId('designer_body');
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.fullscreen.js');
$scripts->addFile('designer/database.js');
$scripts->addFile('designer/objects.js');
$scripts->addFile('designer/page.js');
$scripts->addFile('designer/history.js');
$scripts->addFile('designer/move.js');
$scripts->addFile('designer/init.js');
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = PhpMyAdmin\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
// Embed some data into HTML, later it will be read
// by designer/init.js and converted to JS variables.
$response->addHTML(
$databaseDesigner->getHtmlForMain(
$db,
$_GET['db'],
$script_display_field,
$script_tables,
$script_contr,
$script_display_field,
$display_page,
isset($_GET['query']),
$selected_page,
$classes_side_menu,
$tab_pos,
$tab_column,
$tables_all_keys,
$tables_pk_or_unique_keys
)
);
$response->addHTML('<div id="PMA_disable_floating_menubar"></div>');

View File

@ -1,80 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Events management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\EventsController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$_PMA_RTE = 'EVN';
/** @var EventsController $controller */
$controller = $containerBuilder->get(EventsController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index();

View File

@ -1,173 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* dumps a database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export as DisplayExport;
use PhpMyAdmin\Export;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $table, $url_query, $containerBuilder;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
PageSettings::showGroup('Export');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export.js');
/** @var Export $export */
$export = $containerBuilder->get('export');
// $sub_part is used in Util::getDbInfo() to see if we are coming from
// db_export.php, in which case we don't obey $cfg['MaxTableList']
$sub_part = '_export';
require_once ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_export.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
/**
* Displays the form
*/
$export_page_title = __('View dump (schema) of database');
// exit if no tables in db found
if ($num_tables < 1) {
$response->addHTML(
Message::error(__('No tables found in database.'))->getDisplay()
);
exit;
} // end if
$multi_values = '<div class="export_table_list_container">';
if (isset($_POST['structure_or_data_forced'])) {
$force_val = htmlspecialchars($_POST['structure_or_data_forced']);
} else {
$force_val = 0;
}
$multi_values .= '<input type="hidden" name="structure_or_data_forced" value="'
. $force_val . '">';
$multi_values .= '<table class="export_table_select">'
. '<thead><tr><th></th>'
. '<th>' . __('Tables') . '</th>'
. '<th class="export_structure">' . __('Structure') . '</th>'
. '<th class="export_data">' . __('Data') . '</th>'
. '</tr><tr>'
. '<td></td>'
. '<td class="export_table_name all">' . __('Select all') . '</td>'
. '<td class="export_structure all">'
. '<input type="checkbox" id="table_structure_all"></td>'
. '<td class="export_data all"><input type="checkbox" id="table_data_all">'
. '</td>'
. '</tr></thead>'
. '<tbody>';
$multi_values .= "\n";
// when called by libraries/mult_submits.inc.php
if (! empty($_POST['selected_tbl']) && empty($table_select)) {
$table_select = $_POST['selected_tbl'];
}
foreach ($tables as $each_table) {
if (isset($_POST['table_select']) && is_array($_POST['table_select'])) {
$is_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_select']
);
} elseif (isset($table_select)) {
$is_checked = $export->getCheckedClause(
$each_table['Name'],
$table_select
);
} else {
$is_checked = ' checked="checked"';
}
if (isset($_POST['table_structure']) && is_array($_POST['table_structure'])) {
$structure_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_structure']
);
} else {
$structure_checked = $is_checked;
}
if (isset($_POST['table_data']) && is_array($_POST['table_data'])) {
$data_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_data']
);
} else {
$data_checked = $is_checked;
}
$table_html = htmlspecialchars($each_table['Name']);
$multi_values .= '<tr class="marked">';
$multi_values .= '<td><input type="checkbox" name="table_select[]"'
. ' value="' . $table_html . '"' . $is_checked . ' class="checkall"></td>';
$multi_values .= '<td class="export_table_name">'
. str_replace(' ', '&nbsp;', $table_html) . '</td>';
$multi_values .= '<td class="export_structure">'
. '<input type="checkbox" name="table_structure[]"'
. ' value="' . $table_html . '"' . $structure_checked . '></td>';
$multi_values .= '<td class="export_data">'
. '<input type="checkbox" name="table_data[]"'
. ' value="' . $table_html . '"' . $data_checked . '></td>';
$multi_values .= '</tr>';
} // end for
$multi_values .= "\n";
$multi_values .= '</tbody></table></div>';
if (! isset($sql_query)) {
$sql_query = '';
}
if (! isset($num_tables)) {
$num_tables = 0;
}
if (! isset($unlim_num_rows)) {
$unlim_num_rows = 0;
}
if ($multi_values === null) {
$multi_values = '';
}
$response = Response::getInstance();
$displayExport = new DisplayExport();
$response->addHTML(
$displayExport->getDisplay(
'database',
$db,
$table,
$sql_query,
$num_tables,
$unlim_num_rows,
$multi_values
)
);

View File

@ -1,56 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database import page
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\Display\Import;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $table;
require_once ROOT_PATH . 'libraries/common.inc.php';
PageSettings::showGroup('Import');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('import.js');
$import = new Import();
/**
* Gets tables information and displays top links
*/
require ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = PhpMyAdmin\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
$response = Response::getInstance();
$response->addHTML(
$import->get(
'database',
$db,
$table,
$max_upload_size
)
);

View File

@ -1,51 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Handles database multi-table querying
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\MultiTableQueryController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var MultiTableQueryController $controller */
$controller = $containerBuilder->get(MultiTableQueryController::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
if (isset($_POST['sql_query'])) {
$controller->displayResults([
'sql_query' => $_POST['sql_query'],
'db' => $_REQUEST['db'] ?? null,
]);
} elseif (isset($_GET['tables'])) {
$response->addJSON($controller->table([
'tables' => $_GET['tables'],
'db' => $_REQUEST['db'] ?? null,
]));
} else {
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.md5.js');
$scripts->addFile('database/multi_table_query.js');
$scripts->addFile('database/query_generator.js');
$response->addHTML($controller->index($template));
}

View File

@ -1,321 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* handles miscellaneous db operations:
* - move/rename
* - copy
* - changing collation
* - changing comment
* - adding tables
* - viewing PDF schemas
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\CheckUserPrivileges;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\CreateTable;
use PhpMyAdmin\Message;
use PhpMyAdmin\Operations;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\Export\ExportSql;
use PhpMyAdmin\Relation;
use PhpMyAdmin\RelationCleanup;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $cfg, $db, $server, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$checkUserPrivileges = new CheckUserPrivileges($dbi);
$checkUserPrivileges->getPrivileges();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/operations.js');
$sql_query = '';
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
$operations = new Operations($dbi, $relation);
$relationCleanup = new RelationCleanup($dbi, $relation);
/**
* Rename/move or copy database
*/
if (strlen($db) > 0
&& (! empty($_POST['db_rename']) || ! empty($_POST['db_copy']))
) {
if (! empty($_POST['db_rename'])) {
$move = true;
} else {
$move = false;
}
if (! isset($_POST['newname']) || strlen($_POST['newname']) === 0) {
$message = Message::error(__('The database name is empty!'));
} else {
// lower_case_table_names=1 `DB` becomes `db`
if ($dbi->getLowerCaseNames() === '1') {
$_POST['newname'] = mb_strtolower(
$_POST['newname']
);
}
if ($_POST['newname'] === $_REQUEST['db']) {
$message = Message::error(
__('Cannot copy database to the same name. Change the name and try again.')
);
} else {
$_error = false;
if ($move || ! empty($_POST['create_database_before_copying'])) {
$operations->createDbBeforeCopy();
}
// here I don't use DELIMITER because it's not part of the
// language; I have to send each statement one by one
// to avoid selecting alternatively the current and new db
// we would need to modify the CREATE definitions to qualify
// the db name
$operations->runProcedureAndFunctionDefinitions($db);
// go back to current db, just in case
$dbi->selectDb($db);
$tables_full = $dbi->getTablesFull($db);
// remove all foreign key constraints, otherwise we can get errors
/** @var ExportSql $export_sql_plugin */
$export_sql_plugin = Plugins::getPlugin(
"export",
"sql",
'libraries/classes/Plugins/Export/',
[
'single_table' => isset($single_table),
'export_type' => 'database',
]
);
// create stand-in tables for views
$views = $operations->getViewsAndCreateSqlViewStandIn(
$tables_full,
$export_sql_plugin,
$db
);
// copy tables
$sqlConstratints = $operations->copyTables(
$tables_full,
$move,
$db
);
// handle the views
if (! $_error) {
$operations->handleTheViews($views, $move, $db);
}
unset($views);
// now that all tables exist, create all the accumulated constraints
if (! $_error && count($sqlConstratints) > 0) {
$operations->createAllAccumulatedConstraints($sqlConstratints);
}
unset($sqlConstratints);
if ($dbi->getVersion() >= 50100) {
// here DELIMITER is not used because it's not part of the
// language; each statement is sent one by one
$operations->runEventDefinitionsForDb($db);
}
// go back to current db, just in case
$dbi->selectDb($db);
// Duplicate the bookmarks for this db (done once for each db)
$operations->duplicateBookmarks($_error, $db);
if (! $_error && $move) {
if (isset($_POST['adjust_privileges'])
&& ! empty($_POST['adjust_privileges'])
) {
$operations->adjustPrivilegesMoveDb($db, $_POST['newname']);
}
/**
* cleanup pmadb stuff for this db
*/
$relationCleanup->database($db);
// if someday the RENAME DATABASE reappears, do not DROP
$local_query = 'DROP DATABASE '
. Util::backquote($db) . ';';
$sql_query .= "\n" . $local_query;
$dbi->query($local_query);
$message = Message::success(
__('Database %1$s has been renamed to %2$s.')
);
$message->addParam($db);
$message->addParam($_POST['newname']);
} elseif (! $_error) {
if (isset($_POST['adjust_privileges'])
&& ! empty($_POST['adjust_privileges'])
) {
$operations->adjustPrivilegesCopyDb($db, $_POST['newname']);
}
$message = Message::success(
__('Database %1$s has been copied to %2$s.')
);
$message->addParam($db);
$message->addParam($_POST['newname']);
} else {
$message = Message::error();
}
$reload = true;
/* Change database to be used */
if (! $_error && $move) {
$db = $_POST['newname'];
} elseif (! $_error) {
if (isset($_POST['switch_to_new'])
&& $_POST['switch_to_new'] == 'true'
) {
$_SESSION['pma_switch_to_new'] = true;
$db = $_POST['newname'];
} else {
$_SESSION['pma_switch_to_new'] = false;
}
}
}
}
/**
* Database has been successfully renamed/moved. If in an Ajax request,
* generate the output with {@link PhpMyAdmin\Response} and exit
*/
if ($response->isAjax()) {
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('newname', $_POST['newname']);
$response->addJSON(
'sql_query',
Util::getMessage(null, $sql_query)
);
$response->addJSON('db', $db);
exit;
}
}
/**
* Settings for relations stuff
*/
$cfgRelation = $relation->getRelationsParam();
/**
* Check if comments were updated
* (must be done before displaying the menu tabs)
*/
if (isset($_POST['comment'])) {
$relation->setDbComment($db, $_POST['comment']);
}
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_operations.php';
// Gets the database structure
$sub_part = '_structure';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
echo "\n";
if (isset($message)) {
echo Util::getMessage($message, $sql_query);
unset($message);
}
$db_collation = $dbi->getDbCollation($db);
$is_information_schema = $dbi->isSystemSchema($db);
if (! $is_information_schema) {
if ($cfgRelation['commwork']) {
/**
* database comment
*/
$response->addHTML($operations->getHtmlForDatabaseComment($db));
}
$response->addHTML('<div>');
$response->addHTML(CreateTable::getHtml($db));
$response->addHTML('</div>');
/**
* rename database
*/
if ($db != 'mysql') {
$response->addHTML($operations->getHtmlForRenameDatabase($db, $db_collation));
}
// Drop link if allowed
// Don't even try to drop information_schema.
// You won't be able to. Believe me. You won't.
// Don't allow to easily drop mysql database, RFE #1327514.
if (($dbi->isSuperuser() || $cfg['AllowUserDropDatabase'])
&& ! $db_is_system_schema
&& $db != 'mysql'
) {
$response->addHTML($operations->getHtmlForDropDatabaseLink($db));
}
/**
* Copy database
*/
$response->addHTML($operations->getHtmlForCopyDatabase($db, $db_collation));
/**
* Change database charset
*/
$response->addHTML($operations->getHtmlForChangeDatabaseCharset($db, $db_collation));
if (! $cfgRelation['allworks']
&& $cfg['PmaNoRelation_DisableWarning'] == false
) {
$message = Message::notice(
__(
'The phpMyAdmin configuration storage has been deactivated. ' .
'%sFind out why%s.'
)
);
$message->addParamHtml('<a href="./chk_rel.php" data-post="' . $url_query . '">');
$message->addParamHtml('</a>');
/* Show error if user has configured something, notice elsewhere */
if (! empty($cfg['Servers'][$server]['pmadb'])) {
$message->isError(true);
}
} // end if
} // end if (!$is_information_schema)

View File

@ -1,192 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* query by example the whole database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Qbe;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Message;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\SavedSearches;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $pmaThemeImage, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
/** @var Template $template */
$template = $containerBuilder->get('template');
// Gets the relation settings
$cfgRelation = $relation->getRelationsParam();
$savedSearchList = [];
$savedSearch = null;
$currentSearchId = null;
if ($cfgRelation['savedsearcheswork']) {
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/qbe.js');
//Get saved search list.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
if (! empty($_POST['searchId'])) {
$savedSearch->setId($_POST['searchId']);
}
//Action field is sent.
if (isset($_POST['action'])) {
$savedSearch->setSearchName($_POST['searchName']);
if ('create' === $_POST['action']) {
$saveResult = $savedSearch->setId(null)
->setCriterias($_POST)
->save();
} elseif ('update' === $_POST['action']) {
$saveResult = $savedSearch->setCriterias($_POST)
->save();
} elseif ('delete' === $_POST['action']) {
$deleteResult = $savedSearch->delete();
//After deletion, reset search.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
$_POST = [];
} elseif ('load' === $_POST['action']) {
if (empty($_POST['searchId'])) {
//when not loading a search, reset the object.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
$_POST = [];
} else {
$loadResult = $savedSearch->load();
}
}
//Else, it's an "update query"
}
$savedSearchList = $savedSearch->getList();
$currentSearchId = $savedSearch->getId();
}
/**
* A query has been submitted -> (maybe) execute it
*/
$message_to_display = false;
if (isset($_POST['submit_sql']) && ! empty($sql_query)) {
if (0 !== stripos($sql_query, "SELECT")) {
$message_to_display = true;
} else {
$goto = 'db_sql.php';
$sql = new Sql();
$sql->executeQueryAndSendQueryResponse(
null, // analyzed_sql_results
false, // is_gotofile
$_POST['db'], // db
null, // table
false, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
}
$sub_part = '_qbe';
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_qbe.php';
$url_params['goto'] = 'db_qbe.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
if ($message_to_display) {
Message::error(
__('You have to choose at least one column to display!')
)
->display();
}
unset($message_to_display);
// create new qbe search instance
$db_qbe = new Qbe($relation, $template, $dbi, $db, $savedSearchList, $savedSearch);
$secondaryTabs = [
'multi' => [
'link' => 'db_multi_table_query.php',
'text' => __('Multi-table query'),
],
'qbe' => [
'link' => 'db_qbe.php',
'text' => __('Query by example'),
],
];
$response->addHTML(
$template->render('secondary_tabs', [
'url_params' => $url_params,
'sub_tabs' => $secondaryTabs,
])
);
$url = 'db_designer.php' . Url::getCommon(
array_merge(
$url_params,
['query' => 1]
)
);
$response->addHTML(
Message::notice(
sprintf(
__('Switch to %svisual builder%s'),
'<a href="' . $url . '">',
'</a>'
)
)
);
/**
* Displays the Query by example form
*/
$response->addHTML($db_qbe->getSelectionForm());

View File

@ -1,87 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Routines management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\CheckUserPrivileges;
use PhpMyAdmin\Controllers\Database\RoutinesController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
/** @var CheckUserPrivileges $checkUserPrivileges */
$checkUserPrivileges = $containerBuilder->get('check_user_privileges');
$checkUserPrivileges->getPrivileges();
$_PMA_RTE = 'RTN';
/** @var RoutinesController $controller */
$controller = $containerBuilder->get(RoutinesController::class);
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index([
'type' => $_REQUEST['type'] ?? null,
]);

View File

@ -1,85 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* searches the entire database
*
* @todo make use of UNION when searching multiple tables
* @todo display executed query, optional?
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Search;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/search.js');
$scripts->addFile('vendor/stickyfill.min.js');
$scripts->addFile('sql.js');
$scripts->addFile('makegrid.js');
require ROOT_PATH . 'libraries/db_common.inc.php';
// If config variable $GLOBALS['cfg']['UseDbSearch'] is on false : exit.
if (! $GLOBALS['cfg']['UseDbSearch']) {
Util::mysqlDie(
__('Access denied!'),
'',
false,
$err_url
);
} // end if
$url_query .= '&amp;goto=db_search.php';
$url_params['goto'] = 'db_search.php';
// Create a database search instance
$db_search = new Search($dbi, $db, $template);
// Display top links if we are not in an Ajax request
if (! $response->isAjax()) {
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
// Main search form has been submitted, get results
if (isset($_POST['submit_search'])) {
$response->addHTML($db_search->getSearchResults());
}
// If we are in an Ajax request, we need to exit after displaying all the HTML
if ($response->isAjax() && empty($_REQUEST['ajax_page_request'])) {
exit;
}
// Display the search form
$response->addHTML($db_search->getMainHtml());

View File

@ -1,49 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database SQL executor
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\SqlController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\SqlQueryForm;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $containerBuilder;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var SqlController $controller */
$controller = $containerBuilder->get(SqlController::class);
/** @var SqlQueryForm $sqlQueryForm */
$sqlQueryForm = $containerBuilder->get('sql_query_form');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('vendor/stickyfill.min.js');
$scripts->addFile('sql.js');
$response->addHTML(
$controller->index(
[
'delimiter' => $_POST['delimiter'] ?? null,
],
$sqlQueryForm
)
);

View File

@ -1,41 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Table/Column autocomplete in SQL editors
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
if ($GLOBALS['cfg']['EnableAutocompleteForTablesAndColumns']) {
$db = isset($_POST['db']) ? $_POST['db'] : $GLOBALS['db'];
$sql_autocomplete = [];
if ($db) {
$tableNames = $dbi->getTables($db);
foreach ($tableNames as $tableName) {
$sql_autocomplete[$tableName] = $dbi->getColumns(
$db,
$tableName
);
}
}
} else {
$sql_autocomplete = true;
}
$response->addJSON("tables", json_encode($sql_autocomplete));

View File

@ -1,27 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Format SQL for SQL editors
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/**
* Loading common files. Used to check for authorization, localization and to
* load the parsing library.
*/
require_once ROOT_PATH . 'libraries/common.inc.php';
$query = ! empty($_POST['sql']) ? $_POST['sql'] : '';
$query = PhpMyAdmin\SqlParser\Utils\Formatter::format($query);
$response = Response::getInstance();
$response->addJSON("sql", $query);

View File

@ -1,62 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database structure manipulation
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\StructureController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
require_once ROOT_PATH . 'libraries/db_common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var StructureController $controller */
$controller = $containerBuilder->get(StructureController::class);
if ($response->isAjax() && ! empty($_REQUEST['favorite_table'])) {
$json = $controller->addRemoveFavoriteTablesAction([
'favorite_table' => $_REQUEST['favorite_table'],
'favoriteTables' => $_REQUEST['favoriteTables'] ?? null,
'sync_favorite_tables' => $_REQUEST['sync_favorite_tables'] ?? null,
'add_favorite' => $_REQUEST['add_favorite'] ?? null,
'remove_favorite' => $_REQUEST['remove_favorite'] ?? null,
]);
if ($json !== null) {
$response->addJSON($json);
}
} elseif ($response->isAjax()
&& isset($_REQUEST['real_row_count'])
&& (bool) $_REQUEST['real_row_count'] === true
) {
$response->addJSON($controller->handleRealRowCountRequestAction([
'real_row_count_all' => $_REQUEST['real_row_count_all'] ?? null,
'table' => $_REQUEST['table'] ?? null,
]));
} else {
$response->getHeader()->getScripts()->addFiles([
'database/structure.js',
'table/change.js',
]);
$response->addHTML($controller->index([
'submit_mult' => $_POST['submit_mult'] ?? null,
'selected_tbl' => $_POST['selected_tbl'] ?? null,
'mult_btn' => $_POST['mult_btn'] ?? null,
'sort' => $_REQUEST['sort'] ?? null,
'sort_order' => $_REQUEST['sort_order'] ?? null,
]));
}

View File

@ -1,129 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Tracking configuration for database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Display\CreateTable;
use PhpMyAdmin\Message;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $pmaThemeImage, $text_dir, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
//Get some js files needed for Ajax requests
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('database/tracking.js');
/** @var Tracking $tracking */
$tracking = $containerBuilder->get('tracking');
/**
* If we are not in an Ajax request, then do the common work and show the links etc.
*/
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=tbl_tracking.php&amp;back=db_tracking.php';
$url_params['goto'] = 'tbl_tracking.php';
$url_params['back'] = 'db_tracking.php';
// Get the database structure
$sub_part = '_structure';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
if (isset($_POST['delete_tracking']) && isset($_POST['table'])) {
Tracker::deleteTracking($db, $_POST['table']);
Message::success(
__('Tracking data deleted successfully.')
)->display();
} elseif (isset($_POST['submit_create_version'])) {
$tracking->createTrackingForMultipleTables($_POST['selected']);
Message::success(
sprintf(
__(
'Version %1$s was created for selected tables,'
. ' tracking is active for them.'
),
htmlspecialchars($_POST['version'])
)
)->display();
} elseif (isset($_POST['submit_mult'])) {
if (! empty($_POST['selected_tbl'])) {
if ($_POST['submit_mult'] == 'delete_tracking') {
foreach ($_POST['selected_tbl'] as $table) {
Tracker::deleteTracking($db, $table);
}
Message::success(
__('Tracking data deleted successfully.')
)->display();
} elseif ($_POST['submit_mult'] == 'track') {
echo $tracking->getHtmlForDataDefinitionAndManipulationStatements(
'db_tracking.php' . $url_query,
0,
$db,
$_POST['selected_tbl']
);
exit;
}
} else {
Message::notice(
__('No tables selected.')
)->display();
}
}
// Get tracked data about the database
$data = Tracker::getTrackedData($db, '', '1');
// No tables present and no log exist
if ($num_tables == 0 && count($data['ddlog']) === 0) {
echo '<p>' , __('No tables found in database.') , '</p>' , "\n";
if (empty($db_is_system_schema)) {
echo CreateTable::getHtml($db);
}
exit;
}
// ---------------------------------------------------------------------------
echo $tracking->getHtmlForDbTrackingTables(
$db,
$url_query,
$pmaThemeImage,
$text_dir
);
// If available print out database log
if (count($data['ddlog']) > 0) {
$log = '';
foreach ($data['ddlog'] as $entry) {
$log .= '# ' . $entry['date'] . ' ' . $entry['username'] . "\n"
. $entry['statement'] . "\n";
}
echo Util::getMessage(__('Database Log'), $log);
}

View File

@ -1,80 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Triggers management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\TriggersController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$_PMA_RTE = 'TRI';
/** @var TriggersController $controller */
$controller = $containerBuilder->get(TriggersController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index();

View File

@ -1,422 +0,0 @@
.. _glossary:
Glossary
========
From Wikipedia, the free encyclopedia
.. glossary::
.htaccess
the default name of Apache's directory-level configuration file.
.. seealso:: <https://en.wikipedia.org/wiki/.htaccess>
ACL
Access Control List
Blowfish
a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.
.. seealso:: <https://en.wikipedia.org/wiki/Blowfish_(cipher)>
Browser
a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.
.. seealso:: <https://en.wikipedia.org/wiki/Web_browser>
bzip2
a free software/open-source data compression algorithm and program developed by Julian Seward.
.. seealso:: <https://en.wikipedia.org/wiki/Bzip2>
CGI
Common Gateway Interface is an important World Wide Web technology that
enables a client web browser to request data from a program executed on
the Web server.
.. seealso:: <https://en.wikipedia.org/wiki/Common_Gateway_Interface>
Changelog
a log or record of changes made to a project.
.. seealso:: <https://en.wikipedia.org/wiki/Changelog>
Client
a computer system that accesses a (remote) service on another computer by some kind of network.
.. seealso:: <https://en.wikipedia.org/wiki/Client_(computing)>
column
a set of data values of a particularly simple type, one for each row of the table.
.. seealso:: <https://en.wikipedia.org/wiki/Column_(database)>
Cookie
a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.
.. seealso:: <https://en.wikipedia.org/wiki/HTTP_cookie>
CSV
Comma-separated values
.. seealso:: <https://en.wikipedia.org/wiki/Comma-separated_values>
DB
look at :term:`database`
database
an organized collection of data.
.. seealso:: <https://en.wikipedia.org/wiki/Database>
Engine
look at :term:`Storage Engines`
extension
a PHP module that extends PHP with additional functionality.
.. seealso:: <https://en.wikipedia.org/wiki/Software_extension>
FAQ
Frequently Asked Questions is a list of commonly asked question and there
answers.
.. seealso:: <https://en.wikipedia.org/wiki/FAQ>
Field
one part of divided data/columns.
.. seealso:: <https://en.wikipedia.org/wiki/Field_(computer_science)>
foreign key
a column or group of columns in a database row that points to a key column
or group of columns forming a key of another database row in some
(usually different) table.
.. seealso:: <https://en.wikipedia.org/wiki/Foreign_key>
GD
Graphics Library by Thomas Boutell and others for dynamically manipulating images.
.. seealso:: <https://en.wikipedia.org/wiki/GD_Graphics_Library>
GD2
look at :term:`GD`
GZip
gzip is short for GNU zip, a GNU free software file compression program.
.. seealso:: <https://en.wikipedia.org/wiki/Gzip>
host
any machine connected to a computer network, a node that has a hostname.
.. seealso:: <https://en.wikipedia.org/wiki/Host>
hostname
the unique name by which a network-attached device is known on a network.
.. seealso:: <https://en.wikipedia.org/wiki/Hostname>
HTTP
HyperText Transfer Protocol is the primary method used to transfer or
convey information on the World Wide Web.
.. seealso:: <https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol>
https
a :term:`HTTP`-connection with additional security measures.
.. seealso:: <https://en.wikipedia.org/wiki/Https:_URI_scheme>
IEC
International Electrotechnical Commission
IIS
Internet Information Services is a set of Internet-based services for
servers using Microsoft Windows.
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Information_Services>
Index
a feature that allows quick access to the rows in a table.
.. seealso:: <https://en.wikipedia.org/wiki/Index_(database)>
IP
Internet Protocol is a data-oriented protocol used by source and
destination hosts for communicating data across a packet-switched
internetwork.
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Protocol>
IP Address
a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.
.. seealso:: <https://en.wikipedia.org/wiki/IP_Address>
IPv6
IPv6 (Internet Protocol version 6) is the latest revision of the
Internet Protocol (:term:`IP`), designed to deal with the
long-anticipated problem of its predecessor IPv4 running out of addresses.
.. seealso:: <https://en.wikipedia.org/wiki/IPv6>
ISAPI
Internet Server Application Programming Interface is the API of Internet Information Services (IIS).
.. seealso:: <https://en.wikipedia.org/wiki/ISAPI>
ISP
An Internet service provider is a business or organization that offers users
access to the Internet and related services.
.. seealso:: <https://en.wikipedia.org/wiki/ISP>
ISO
International Standards Organization
JPEG
a most commonly used standard method of lossy compression for photographic images.
.. seealso:: <https://en.wikipedia.org/wiki/JPEG>
JPG
look at :term:`JPEG`
Key
look at :term:`Index`
LATEX
a document preparation system for the TEX typesetting program.
.. seealso:: <https://en.wikipedia.org/wiki/LaTeX>
Mac
Apple Macintosh is a line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.
.. seealso:: <https://en.wikipedia.org/wiki/Mac>
Mac OS X
the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.
.. seealso:: <https://en.wikipedia.org/wiki/Mac_OS_X>
mbstring
The PHP `mbstring` functions provide support for languages represented by multi-byte character sets, most notably UTF-8.
If you have troubles installing this extension, please follow :ref:`faqmysql`, it provides useful hints.
.. seealso:: <https://www.php.net/manual/en/book.mbstring.php>
Media type
A media type (formerly known as MIME type) is a two-part identifier
for file formats and format contents transmitted on the Internet.
.. seealso:: <https://en.wikipedia.org/wiki/Media_type>
MIME
Multipurpose Internet Mail Extensions is
an Internet Standard for the format of e-mail.
.. seealso:: <https://en.wikipedia.org/wiki/MIME>
module
some sort of extension for the Apache Webserver.
.. seealso:: <https://en.wikipedia.org/wiki/Apache_HTTP_Server>
mod_proxy_fcgi
an Apache module implementing a Fast CGI interface; PHP can be run as a CGI module, FastCGI, or
directly as an Apache module.
MySQL
a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).
.. seealso:: <https://en.wikipedia.org/wiki/MySQL>
mysqli
the improved MySQL client PHP extension.
.. seealso:: <https://www.php.net/manual/en/book.mysqli.php>
mysql
the MySQL client PHP extension.
.. seealso:: <https://www.php.net/manual/en/book.mysql.php>
OpenDocument
an open standard for office documents.
.. seealso:: <https://en.wikipedia.org/wiki/OpenDocument>
OS X
look at :term:`Mac OS X`.
.. seealso:: <https://en.wikipedia.org/wiki/OS_X>
PDF
Portable Document Format is a file format developed by Adobe Systems for
representing two-dimensional documents in a device-independent and
resolution-independent format.
.. seealso:: <https://en.wikipedia.org/wiki/Portable_Document_Format>
PEAR
the PHP Extension and Application Repository.
.. seealso:: <https://pear.php.net/>
PCRE
Perl Compatible Regular Expressions is the perl-compatible regular
expression functions for PHP
.. seealso:: <https://www.php.net/pcre>
PHP
short for "PHP: Hypertext Preprocessor", is an open-source, reflective
programming language used mainly for developing server-side applications
and dynamic web content, and more recently, a broader range of software
applications.
.. seealso:: <https://en.wikipedia.org/wiki/PHP>
port
a connection through which data is sent and received.
.. seealso:: <https://en.wikipedia.org/wiki/Port_(computing)>
primary key
A primary key is an index over one or more fields in a table with
unique values for every single row in this table. Every table should have
a primary key for easier accessing/identifying data in this table. There
can only be one primary key per table and it is named always **PRIMARY**.
In fact, a primary key is just an :term:`unique key` with the name
**PRIMARY**. If no primary key is defined MySQL will use first *unique
key* as primary key if there is one.
You can create the primary key when creating the table (in phpMyAdmin
just check the primary key radio buttons for each field you wish to be
part of the primary key).
You can also add a primary key to an existing table with `ALTER` `TABLE`
or `CREATE` `INDEX` (in phpMyAdmin you can just click on 'add index' on
the table structure page below the listed fields).
RFC
Request for Comments (RFC) documents are a series of memoranda
encompassing new research, innovations, and methodologies applicable to
Internet technologies.
.. seealso:: <https://en.wikipedia.org/wiki/Request_for_Comments>
RFC 1952
GZIP file format specification version 4.3
.. seealso:: :rfc:`1952`
Row (record, tuple)
represents a single, implicitly structured data item in a table.
.. seealso:: <https://en.wikipedia.org/wiki/Row_(database)>
Server
a computer system that provides services to other computing systems over a network.
.. seealso:: <https://en.wikipedia.org/wiki/Server_(computing)>
Storage Engines
MySQL can use several different formats for storing data on disk, these
are called storage engines or table types. phpMyAdmin allows a user to
change their storage engine for a particular table through the operations
tab.
Common table types are InnoDB and MyISAM, though many others exist and
may be desirable in some situations.
.. seealso:: <https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html>
socket
a form of inter-process communication.
.. seealso:: <https://en.wikipedia.org/wiki/Unix_domain_socket>
SSL
Secure Sockets Layer is a cryptographic protocol which provides secure
communication on the Internet.
.. seealso:: <https://en.wikipedia.org/wiki/Secure_Sockets_Layer>
Stored procedure
a subroutine available to applications accessing a relational database system
.. seealso:: <https://en.wikipedia.org/wiki/Stored_procedure>
SQL
Structured Query Language
.. seealso:: <https://en.wikipedia.org/wiki/SQL>
table
a set of data elements (cells) that is organized, defined and stored as
horizontal rows and vertical columns where each item can be uniquely
identified by a label or key or by it's position in relation to other
items.
.. seealso:: <https://en.wikipedia.org/wiki/Table_(database)>
tar
a type of archive file format: the Tape ARchive format.
.. seealso:: <https://en.wikipedia.org/wiki/Tar_(file_format)>
TCP
Transmission Control Protocol is one of the core protocols of the
Internet protocol suite.
.. seealso:: <https://en.wikipedia.org/wiki/TCP>
TCPDF
PHP library to generate PDF files.
.. seealso:: <https://tcpdf.org/>
trigger
a procedural code that is automatically executed in response to certain events on a particular table or view in a database
.. seealso:: <https://en.wikipedia.org/wiki/Database_trigger>
unique key
A unique key is an index over one or more fields in a table which has a
unique value for each row. The first unique key will be treated as
:term:`primary key` if there is no *primary key* defined.
URL
Uniform Resource Locator is a sequence of characters, conforming to a
standardized format, that is used for referring to resources, such as
documents and images on the Internet, by their location.
.. seealso:: <https://en.wikipedia.org/wiki/URL>
Webserver
A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.
.. seealso:: <https://en.wikipedia.org/wiki/Webserver>
XML
Extensible Markup Language is a W3C-recommended general-purpose markup
language for creating special-purpose markup languages, capable of
describing many different kinds of data.
.. seealso:: <https://en.wikipedia.org/wiki/XML>
ZIP
a popular data compression and archival format.
.. seealso:: <https://en.wikipedia.org/wiki/ZIP_(file_format)>
Zlib
an open-source, cross-platform data compression library by Jean-loup Gailly and Mark Adler.
.. seealso:: <https://en.wikipedia.org/wiki/Zlib>

View File

@ -1,143 +0,0 @@
.. _transformations:
Transformations
===============
.. note::
You need to have configured the :ref:`linked-tables` for using transformations
feature.
.. _transformationsintro:
Introduction
++++++++++++
To enable transformations, you have to setup the ``column_info``
table and the proper directives. Please see the :ref:`config` on how to do so.
You can apply different transformations to the contents of each
column. The transformation will take the content of each column and
transform it with certain rules defined in the selected
transformation.
Say you have a column 'filename' which contains a filename. Normally
you would see in phpMyAdmin only this filename. Using transformations
you can transform that filename into a HTML link, so you can click
inside of the phpMyAdmin structure on the column's link and will see
the file displayed in a new browser window. Using transformation
options you can also specify strings to append/prepend to a string or
the format you want the output stored in.
For a general overview of all available transformations and their
options, you can consult your *<www.your-host.com>/<your-install-
dir>/transformation\_overview.php* installation.
For a tutorial on how to effectively use transformations, see our
`Link section <https://www.phpmyadmin.net/docs/>`_ on the
official phpMyAdmin homepage.
.. _transformationshowto:
Usage
+++++
Go to your *tbl\_structure.php* page (i.e. reached through clicking on
the 'Structure' link for a table). There click on "Change" (or change
icon) and there you will see three new fields at the end of the line.
They are called ':term:`Media type`', 'Browser transformation' and
'Transformation options'.
* The field ':term:`Media type`' is a drop-down field. Select the :term:`Media type` that
corresponds to the column's contents. Please note that transformations
are inactive as long as no :term:`Media type` is selected.
* The field 'Browser transformation' is a drop-down field. You can
choose from a hopefully growing amount of pre-defined transformations.
See below for information on how to build your own transformation.
There are global transformations and mimetype-bound transformations.
Global transformations can be used for any mimetype. They will take
the mimetype, if necessary, into regard. Mimetype-bound
transformations usually only operate on a certain mimetype. There are
transformations which operate on the main mimetype (like 'image'),
which will most likely take the subtype into regard, and those who
only operate on a specific subtype (like 'image/jpeg'). You can use
transformations on mimetypes for which the function was not defined
for. There is no security check for you selected the right
transformation, so take care of what the output will be like.
* The field 'Transformation options' is a free-type textfield. You have
to enter transform-function specific options here. Usually the
transforms can operate with default options, but it is generally a
good idea to look up the overview to see which options are necessary.
Much like the ENUM/SET-Fields, you have to split up several options
using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is
because internally the options will be parsed as an array, leaving the
first value the first element in the array, and so forth. If you want
to specify a MIME character set you can define it in the
transformation\_options. You have to put that outside of the pre-
defined options of the specific mime-transform, as the last value of
the set. Use the format "'; charset=XXX'". If you use a transform, for
which you can specify 2 options and you want to append a character
set, enter "'first parameter','second parameter','charset=us-ascii'".
You can, however use the defaults for the parameters: "'','','charset
=us-ascii'". The default options can be configured using
:config:option:`$cfg['DefaultTransformations']`
.. _transformationsfiles:
File structure
++++++++++++++
All specific transformations for mimetypes are defined through class
files in the directory 'libraries/classes/Plugins/Transformations/'. Each of
them extends a certain transformation abstract class declared in
libraries/classes/Plugins/Transformations/Abs.
They are stored in files to ease up customization and easy adding of
new transformations.
Because the user cannot enter own mimetypes, it is kept sure that
transformations always work. It makes no sense to apply a
transformation to a mimetype the transform-function doesn't know to
handle.
There is a file called ':file:`libraries/classes/Plugins/Transformations.php`' that provides some
basic functions which can be included by any other transform function.
The file name convention is ``[Mimetype]_[Subtype]_[Transformation
Name].php``, while the abstract class that it extends has the
name ``[Transformation Name]TransformationsPlugin``. All of the
methods that have to be implemented by a transformations plug-in are:
#. getMIMEType() and getMIMESubtype() in the main class;
#. getName(), getInfo() and applyTransformation() in the abstract class
it extends.
The getMIMEType(), getMIMESubtype() and getName() methods return the
name of the MIME type, MIME Subtype and transformation accordingly.
getInfo() returns the transformation's description and possible
options it may receive and applyTransformation() is the method that
does the actual work of the transformation plug-in.
Please see the :file:`libraries/classes/Plugins/Transformations/TEMPLATE` and
:file:`libraries/classes/Plugins/Transformations/TEMPLATE\_ABSTRACT` files for adding
your own transformation plug-in. You can also generate a new
transformation plug-in (with or without the abstract transformation
class), by using
:file:`scripts/transformations_generator_plugin.sh` or
:file:`scripts/transformations_generator_main_class.sh`.
The applyTransformation() method always gets passed three variables:
#. **$buffer** - Contains the text inside of the column. This is the
text, you want to transform.
#. **$options** - Contains any user-passed options to a transform
function as an array.
#. **$meta** - Contains an object with information about your column. The
data is drawn from the output of the `mysql\_fetch\_field()
<https://www.php.net/mysql_fetch_field>`_ function. This means, all
object properties described on the `manual page
<https://www.php.net/mysql_fetch_field>`_ are available in this
variable and can be used to transform a column accordingly to
unsigned/zerofill/not\_null/... properties. The $meta->mimetype
variable contains the original :term:`Media type` of the column (i.e.
'text/plain', 'image/jpeg' etc.)

View File

@ -1,32 +0,0 @@
Distributing and packaging phpMyAdmin
=====================================
This document is intended to give pieces of advice to people who want to
redistribute phpMyAdmin inside other software packages such as Linux
distribution or some all in one package including web server and MySQL
server.
Generally, you can customize some basic aspects (paths to some files and
behavior) in :file:`libraries/vendor_config.php`.
For example, if you want setup script to generate a config file in var, change
``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you
will also probably want to skip directory writable check, so set
``SETUP_DIR_WRITABLE`` to false.
External libraries
------------------
phpMyAdmin includes several external libraries, you might want to
replace them with system ones if they are available, but please note
that you should test whether the version you provide is compatible with the
one we ship.
Currently known list of external libraries:
js/vendor
jQuery js framework libraries and various js libraries.
vendor/
The download kit includes various Composer packages as
dependencies.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

View File

@ -1,10 +0,0 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '5.0.4',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

View File

@ -1,808 +0,0 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilities for all documentation.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$(document).on("click", 'a.comment-close', function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$(document).on("click", 'a.vote', function(event) {
event.preventDefault();
handleVote($(this));
});
$(document).on("click", 'a.reply', function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.close-reply', function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.sort-option', function(event) {
event.preventDefault();
handleReSort($(this));
});
$(document).on("click", 'a.show-proposal', function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-proposal', function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.show-propose-change', function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-propose-change', function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.accept-comment', function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.delete-comment', function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.comment-markup', function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(var i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<code>``code``</code>, \
code blocks: <code>::</code> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

View File

@ -1,292 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Charts &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Import and export" href="import_export.html" />
<link rel="prev" title="Relations" href="relations.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="import_export.html" title="Import and export"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="relations.html" title="Relations"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="charts">
<span id="id1"></span><h1>Charts<a class="headerlink" href="#charts" title="Permalink to this headline"></a></h1>
<div class="versionadded">
<p><span class="versionmodified">New in version 3.4.0.</span></p>
</div>
<p>Since phpMyAdmin version 3.4.0, you can easily generate charts from a SQL query
by clicking the “Display chart” link in the “Query results operations” area.</p>
<img alt="_images/query_result_operations.png" src="_images/query_result_operations.png" />
<p>A window layer “Display chart” is shown in which you can customize the chart with the following options.</p>
<ul class="simple">
<li>Chart type: Allows you to choose the type of chart. Supported types are bar charts, column charts, line charts, spline charts, area charts, pie charts and timeline charts (only the chart types applicable for current series selection are offered).</li>
<li>X-axis: Allows to choose the field for the main axis.</li>
<li>Series: Allows to choose series for the chart. You can choose multiple series.</li>
<li>Title: Allows specifying a title for the chart which is displayed above the chart.</li>
<li>X-axis and Y-axis labels: Allows specifying labels for axes.</li>
<li>Start row and a number of rows: Allows generating charts only for a specified number of rows of the results set.</li>
</ul>
<img alt="_images/chart.png" src="_images/chart.png" />
<div class="section" id="chart-implementation">
<h2>Chart implementation<a class="headerlink" href="#chart-implementation" title="Permalink to this headline"></a></h2>
<p>Charts in phpMyAdmin are drawn using <a class="reference external" href="http://www.jqplot.com/">jqPlot</a> jQuery library.</p>
</div>
<div class="section" id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h2>
<div class="section" id="pie-chart">
<h3>Pie chart<a class="headerlink" href="#pie-chart" title="Permalink to this headline"></a></h3>
<p>Query results for a simple pie chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="s1">&#39;Food&#39;</span> <span class="k">AS</span> <span class="s1">&#39;expense&#39;</span><span class="p">,</span>
<span class="mi">1250</span> <span class="k">AS</span> <span class="s1">&#39;amount&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Accommodation&#39;</span><span class="p">,</span> <span class="mi">500</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Travel&#39;</span><span class="p">,</span> <span class="mi">720</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Misc&#39;</span><span class="p">,</span> <span class="mi">220</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="65%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">expense</th>
<th class="head">amount</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Food</td>
<td>1250</td>
</tr>
<tr class="row-odd"><td>Accommodation</td>
<td>500</td>
</tr>
<tr class="row-even"><td>Travel</td>
<td>720</td>
</tr>
<tr class="row-odd"><td>Misc</td>
<td>220</td>
</tr>
</tbody>
</table>
<p>Choosing expense as the X-axis and amount in series:</p>
<img alt="_images/pie_chart.png" src="_images/pie_chart.png" />
</div>
<div class="section" id="bar-and-column-chart">
<h3>Bar and column chart<a class="headerlink" href="#bar-and-column-chart" title="Permalink to this headline"></a></h3>
<p>Both bar charts and column chats support stacking. Upon selecting one of these types a checkbox is displayed to select stacking.</p>
<p>Query results for a simple bar or column chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span>
<span class="s1">&#39;ACADEMY DINOSAUR&#39;</span> <span class="k">AS</span> <span class="s1">&#39;title&#39;</span><span class="p">,</span>
<span class="mi">0</span><span class="p">.</span><span class="mi">99</span> <span class="k">AS</span> <span class="s1">&#39;rental_rate&#39;</span><span class="p">,</span>
<span class="mi">20</span><span class="p">.</span><span class="mi">99</span> <span class="k">AS</span> <span class="s1">&#39;replacement_cost&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;ACE GOLDFINGER&#39;</span><span class="p">,</span> <span class="mi">4</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">12</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;ADAPTATION HOLES&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">18</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;AFFAIR PREJUDICE&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">26</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;AFRICAN EGG&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">22</span><span class="p">.</span><span class="mi">99</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="35%" />
<col width="27%" />
<col width="37%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">title</th>
<th class="head">rental_rate</th>
<th class="head">replacement_cost</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>ACADEMY DINOSAUR</td>
<td>0.99</td>
<td>20.99</td>
</tr>
<tr class="row-odd"><td>ACE GOLDFINGER</td>
<td>4.99</td>
<td>12.99</td>
</tr>
<tr class="row-even"><td>ADAPTATION HOLES</td>
<td>2.99</td>
<td>18.99</td>
</tr>
<tr class="row-odd"><td>AFFAIR PREJUDICE</td>
<td>2.99</td>
<td>26.99</td>
</tr>
<tr class="row-even"><td>AFRICAN EGG</td>
<td>2.99</td>
<td>22.99</td>
</tr>
</tbody>
</table>
<p>Choosing title as the X-axis and rental_rate and replacement_cost as series:</p>
<img alt="_images/column_chart.png" src="_images/column_chart.png" />
</div>
<div class="section" id="scatter-chart">
<h3>Scatter chart<a class="headerlink" href="#scatter-chart" title="Permalink to this headline"></a></h3>
<p>Scatter charts are useful in identifying the movement of one or more variable(s) compared to another variable.</p>
<p>Using the same data set from bar and column charts section and choosing replacement_cost as the X-axis and rental_rate in series:</p>
<img alt="_images/scatter_chart.png" src="_images/scatter_chart.png" />
</div>
<div class="section" id="line-spline-and-timeline-charts">
<h3>Line, spline and timeline charts<a class="headerlink" href="#line-spline-and-timeline-charts" title="Permalink to this headline"></a></h3>
<p>These charts can be used to illustrate trends in underlying data. Spline charts draw smooth lines while timeline charts draw X-axis taking the distances between the dates/time into consideration.</p>
<p>Query results for a simple line, spline or timeline chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span>
<span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-08&#39;</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">&#39;date&#39;</span><span class="p">,</span>
<span class="mi">2056</span> <span class="k">AS</span> <span class="s1">&#39;revenue&#39;</span><span class="p">,</span>
<span class="mi">1378</span> <span class="k">AS</span> <span class="s1">&#39;cost&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-09&#39;</span><span class="p">),</span> <span class="mi">1898</span><span class="p">,</span> <span class="mi">2301</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-15&#39;</span><span class="p">),</span> <span class="mi">1560</span><span class="p">,</span> <span class="mi">600</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-17&#39;</span><span class="p">),</span> <span class="mi">3457</span><span class="p">,</span> <span class="mi">1565</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="44%" />
<col width="33%" />
<col width="22%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">date</th>
<th class="head">revenue</th>
<th class="head">cost</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>2016-01-08</td>
<td>2056</td>
<td>1378</td>
</tr>
<tr class="row-odd"><td>2006-01-09</td>
<td>1898</td>
<td>2301</td>
</tr>
<tr class="row-even"><td>2006-01-15</td>
<td>1560</td>
<td>600</td>
</tr>
<tr class="row-odd"><td>2006-01-17</td>
<td>3457</td>
<td>1565</td>
</tr>
</tbody>
</table>
<img alt="_images/line_chart.png" src="_images/line_chart.png" />
<img alt="_images/spline_chart.png" src="_images/spline_chart.png" />
<img alt="_images/timeline_chart.png" src="_images/timeline_chart.png" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Charts</a><ul>
<li><a class="reference internal" href="#chart-implementation">Chart implementation</a></li>
<li><a class="reference internal" href="#examples">Examples</a><ul>
<li><a class="reference internal" href="#pie-chart">Pie chart</a></li>
<li><a class="reference internal" href="#bar-and-column-chart">Bar and column chart</a></li>
<li><a class="reference internal" href="#scatter-chart">Scatter chart</a></li>
<li><a class="reference internal" href="#line-spline-and-timeline-charts">Line, spline and timeline charts</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="relations.html"
title="previous chapter">Relations</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="import_export.html"
title="next chapter">Import and export</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/charts.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="import_export.html" title="Import and export"
>next</a> |</li>
<li class="right" >
<a href="relations.html" title="Relations"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,110 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Developers Information &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Security policy" href="security.html" />
<link rel="prev" title="FAQ - Frequently Asked Questions" href="faq.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="security.html" title="Security policy"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="developers-information">
<span id="developers"></span><h1>Developers Information<a class="headerlink" href="#developers-information" title="Permalink to this headline"></a></h1>
<p>phpMyAdmin is Open Source, so youre invited to contribute to it. Many
great features have been written by other people and you too can help
to make phpMyAdmin a useful tool.</p>
<p>You can check out all the possibilities to contribute in the
<a class="reference external" href="https://www.phpmyadmin.net/contribute/">contribute section on our website</a>.</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="faq.html"
title="previous chapter">FAQ - Frequently Asked Questions</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="security.html"
title="next chapter">Security policy</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/developers.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="security.html" title="Security policy"
>next</a> |</li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,628 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Glossary &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="prev" title="Credits" href="credits.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="credits.html" title="Credits"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="glossary">
<span id="id1"></span><h1>Glossary<a class="headerlink" href="#glossary" title="Permalink to this headline"></a></h1>
<p>From Wikipedia, the free encyclopedia</p>
<dl class="glossary docutils">
<dt id="term-htaccess">.htaccess</dt>
<dd><p class="first">the default name of Apaches directory-level configuration file.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/.htaccess">https://en.wikipedia.org/wiki/.htaccess</a>&gt;</p>
</div>
</dd>
<dt id="term-acl">ACL</dt>
<dd>Access Control List</dd>
<dt id="term-blowfish">Blowfish</dt>
<dd><p class="first">a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Blowfish_(cipher)">https://en.wikipedia.org/wiki/Blowfish_(cipher)</a>&gt;</p>
</div>
</dd>
<dt id="term-browser">Browser</dt>
<dd><p class="first">a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Web_browser">https://en.wikipedia.org/wiki/Web_browser</a>&gt;</p>
</div>
</dd>
<dt id="term-bzip2">bzip2</dt>
<dd><p class="first">a free software/open-source data compression algorithm and program developed by Julian Seward.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Bzip2">https://en.wikipedia.org/wiki/Bzip2</a>&gt;</p>
</div>
</dd>
<dt id="term-cgi">CGI</dt>
<dd><p class="first">Common Gateway Interface is an important World Wide Web technology that
enables a client web browser to request data from a program executed on
the Web server.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Common_Gateway_Interface">https://en.wikipedia.org/wiki/Common_Gateway_Interface</a>&gt;</p>
</div>
</dd>
<dt id="term-changelog">Changelog</dt>
<dd><p class="first">a log or record of changes made to a project.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Changelog">https://en.wikipedia.org/wiki/Changelog</a>&gt;</p>
</div>
</dd>
<dt id="term-client">Client</dt>
<dd><p class="first">a computer system that accesses a (remote) service on another computer by some kind of network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Client_(computing)">https://en.wikipedia.org/wiki/Client_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-column">column</dt>
<dd><p class="first">a set of data values of a particularly simple type, one for each row of the table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Column_(database)">https://en.wikipedia.org/wiki/Column_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-cookie">Cookie</dt>
<dd><p class="first">a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/HTTP_cookie">https://en.wikipedia.org/wiki/HTTP_cookie</a>&gt;</p>
</div>
</dd>
<dt id="term-csv">CSV</dt>
<dd><p class="first">Comma-separated values</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Comma-separated_values">https://en.wikipedia.org/wiki/Comma-separated_values</a>&gt;</p>
</div>
</dd>
<dt id="term-db">DB</dt>
<dd>look at <a class="reference internal" href="#term-database"><span class="xref std std-term">database</span></a></dd>
<dt id="term-database">database</dt>
<dd><p class="first">an organized collection of data.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Database">https://en.wikipedia.org/wiki/Database</a>&gt;</p>
</div>
</dd>
<dt id="term-engine">Engine</dt>
<dd>look at <a class="reference internal" href="#term-storage-engines"><span class="xref std std-term">Storage Engines</span></a></dd>
<dt id="term-extension">extension</dt>
<dd><p class="first">a PHP module that extends PHP with additional functionality.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Software_extension">https://en.wikipedia.org/wiki/Software_extension</a>&gt;</p>
</div>
</dd>
<dt id="term-faq">FAQ</dt>
<dd><p class="first">Frequently Asked Questions is a list of commonly asked question and there
answers.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/FAQ">https://en.wikipedia.org/wiki/FAQ</a>&gt;</p>
</div>
</dd>
<dt id="term-field">Field</dt>
<dd><p class="first">one part of divided data/columns.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Field_(computer_science)">https://en.wikipedia.org/wiki/Field_(computer_science)</a>&gt;</p>
</div>
</dd>
<dt id="term-foreign-key">foreign key</dt>
<dd><p class="first">a column or group of columns in a database row that points to a key column
or group of columns forming a key of another database row in some
(usually different) table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Foreign_key">https://en.wikipedia.org/wiki/Foreign_key</a>&gt;</p>
</div>
</dd>
<dt id="term-gd">GD</dt>
<dd><p class="first">Graphics Library by Thomas Boutell and others for dynamically manipulating images.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/GD_Graphics_Library">https://en.wikipedia.org/wiki/GD_Graphics_Library</a>&gt;</p>
</div>
</dd>
<dt id="term-gd2">GD2</dt>
<dd>look at <a class="reference internal" href="#term-gd"><span class="xref std std-term">GD</span></a></dd>
<dt id="term-gzip">GZip</dt>
<dd><p class="first">gzip is short for GNU zip, a GNU free software file compression program.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Gzip">https://en.wikipedia.org/wiki/Gzip</a>&gt;</p>
</div>
</dd>
<dt id="term-host">host</dt>
<dd><p class="first">any machine connected to a computer network, a node that has a hostname.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Host">https://en.wikipedia.org/wiki/Host</a>&gt;</p>
</div>
</dd>
<dt id="term-hostname">hostname</dt>
<dd><p class="first">the unique name by which a network-attached device is known on a network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Hostname">https://en.wikipedia.org/wiki/Hostname</a>&gt;</p>
</div>
</dd>
<dt id="term-http">HTTP</dt>
<dd><p class="first">HyperText Transfer Protocol is the primary method used to transfer or
convey information on the World Wide Web.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol">https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol</a>&gt;</p>
</div>
</dd>
<dt id="term-https">https</dt>
<dd><p class="first">a <a class="reference internal" href="#term-http"><span class="xref std std-term">HTTP</span></a>-connection with additional security measures.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Https:_URI_scheme">https://en.wikipedia.org/wiki/Https:_URI_scheme</a>&gt;</p>
</div>
</dd>
<dt id="term-iec">IEC</dt>
<dd>International Electrotechnical Commission</dd>
<dt id="term-iis">IIS</dt>
<dd><p class="first">Internet Information Services is a set of Internet-based services for
servers using Microsoft Windows.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Internet_Information_Services">https://en.wikipedia.org/wiki/Internet_Information_Services</a>&gt;</p>
</div>
</dd>
<dt id="term-index">Index</dt>
<dd><p class="first">a feature that allows quick access to the rows in a table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Index_(database)">https://en.wikipedia.org/wiki/Index_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-ip">IP</dt>
<dd><p class="first">Internet Protocol is a data-oriented protocol used by source and
destination hosts for communicating data across a packet-switched
internetwork.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Internet_Protocol">https://en.wikipedia.org/wiki/Internet_Protocol</a>&gt;</p>
</div>
</dd>
<dt id="term-ip-address">IP Address</dt>
<dd><p class="first">a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/IP_Address">https://en.wikipedia.org/wiki/IP_Address</a>&gt;</p>
</div>
</dd>
<dt id="term-ipv6">IPv6</dt>
<dd><p class="first">IPv6 (Internet Protocol version 6) is the latest revision of the
Internet Protocol (<a class="reference internal" href="#term-ip"><span class="xref std std-term">IP</span></a>), designed to deal with the
long-anticipated problem of its predecessor IPv4 running out of addresses.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/IPv6">https://en.wikipedia.org/wiki/IPv6</a>&gt;</p>
</div>
</dd>
<dt id="term-isapi">ISAPI</dt>
<dd><p class="first">Internet Server Application Programming Interface is the API of Internet Information Services (IIS).</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ISAPI">https://en.wikipedia.org/wiki/ISAPI</a>&gt;</p>
</div>
</dd>
<dt id="term-isp">ISP</dt>
<dd><p class="first">An Internet service provider is a business or organization that offers users
access to the Internet and related services.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ISP">https://en.wikipedia.org/wiki/ISP</a>&gt;</p>
</div>
</dd>
<dt id="term-iso">ISO</dt>
<dd>International Standards Organization</dd>
<dt id="term-jpeg">JPEG</dt>
<dd><p class="first">a most commonly used standard method of lossy compression for photographic images.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/JPEG">https://en.wikipedia.org/wiki/JPEG</a>&gt;</p>
</div>
</dd>
<dt id="term-jpg">JPG</dt>
<dd>look at <a class="reference internal" href="#term-jpeg"><span class="xref std std-term">JPEG</span></a></dd>
<dt id="term-key">Key</dt>
<dd>look at <a class="reference internal" href="#term-index"><span class="xref std std-term">Index</span></a></dd>
<dt id="term-latex">LATEX</dt>
<dd><p class="first">a document preparation system for the TEX typesetting program.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/LaTeX">https://en.wikipedia.org/wiki/LaTeX</a>&gt;</p>
</div>
</dd>
<dt id="term-mac">Mac</dt>
<dd><p class="first">Apple Macintosh is a line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Mac">https://en.wikipedia.org/wiki/Mac</a>&gt;</p>
</div>
</dd>
<dt id="term-mac-os-x">Mac OS X</dt>
<dd><p class="first">the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Mac_OS_X">https://en.wikipedia.org/wiki/Mac_OS_X</a>&gt;</p>
</div>
</dd>
<dt id="term-mbstring">mbstring</dt>
<dd><p class="first">The PHP <cite>mbstring</cite> functions provide support for languages represented by multi-byte character sets, most notably UTF-8.</p>
<p>If you have troubles installing this extension, please follow <a class="reference internal" href="faq.html#faqmysql"><span class="std std-ref">1.20 I receive an error about missing mysqli and mysql extensions.</span></a>, it provides useful hints.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mbstring.php">https://www.php.net/manual/en/book.mbstring.php</a>&gt;</p>
</div>
</dd>
<dt id="term-media-type">Media type</dt>
<dd><p class="first">A media type (formerly known as MIME type) is a two-part identifier
for file formats and format contents transmitted on the Internet.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Media_type">https://en.wikipedia.org/wiki/Media_type</a>&gt;</p>
</div>
</dd>
<dt id="term-mime">MIME</dt>
<dd><p class="first">Multipurpose Internet Mail Extensions is
an Internet Standard for the format of e-mail.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/MIME">https://en.wikipedia.org/wiki/MIME</a>&gt;</p>
</div>
</dd>
<dt id="term-module">module</dt>
<dd><p class="first">some sort of extension for the Apache Webserver.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Apache_HTTP_Server">https://en.wikipedia.org/wiki/Apache_HTTP_Server</a>&gt;</p>
</div>
</dd>
<dt id="term-mod-proxy-fcgi">mod_proxy_fcgi</dt>
<dd>an Apache module implementing a Fast CGI interface; PHP can be run as a CGI module, FastCGI, or
directly as an Apache module.</dd>
<dt id="term-mysql">MySQL</dt>
<dd><p class="first">a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/MySQL">https://en.wikipedia.org/wiki/MySQL</a>&gt;</p>
</div>
</dd>
<dt id="term-mysqli">mysqli</dt>
<dd><p class="first">the improved MySQL client PHP extension.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mysqli.php">https://www.php.net/manual/en/book.mysqli.php</a>&gt;</p>
</div>
</dd>
<dt id="term-47">mysql</dt>
<dd><p class="first">the MySQL client PHP extension.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mysql.php">https://www.php.net/manual/en/book.mysql.php</a>&gt;</p>
</div>
</dd>
<dt id="term-opendocument">OpenDocument</dt>
<dd><p class="first">an open standard for office documents.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/OpenDocument">https://en.wikipedia.org/wiki/OpenDocument</a>&gt;</p>
</div>
</dd>
<dt id="term-os-x">OS X</dt>
<dd><p class="first">look at <a class="reference internal" href="#term-mac-os-x"><span class="xref std std-term">Mac OS X</span></a>.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/OS_X">https://en.wikipedia.org/wiki/OS_X</a>&gt;</p>
</div>
</dd>
<dt id="term-pdf">PDF</dt>
<dd><p class="first">Portable Document Format is a file format developed by Adobe Systems for
representing two-dimensional documents in a device-independent and
resolution-independent format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Portable_Document_Format">https://en.wikipedia.org/wiki/Portable_Document_Format</a>&gt;</p>
</div>
</dd>
<dt id="term-pear">PEAR</dt>
<dd><p class="first">the PHP Extension and Application Repository.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://pear.php.net/">https://pear.php.net/</a>&gt;</p>
</div>
</dd>
<dt id="term-pcre">PCRE</dt>
<dd><p class="first">Perl Compatible Regular Expressions is the perl-compatible regular
expression functions for PHP</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/pcre">https://www.php.net/pcre</a>&gt;</p>
</div>
</dd>
<dt id="term-php">PHP</dt>
<dd><p class="first">short for “PHP: Hypertext Preprocessor”, is an open-source, reflective
programming language used mainly for developing server-side applications
and dynamic web content, and more recently, a broader range of software
applications.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/PHP">https://en.wikipedia.org/wiki/PHP</a>&gt;</p>
</div>
</dd>
<dt id="term-port">port</dt>
<dd><p class="first">a connection through which data is sent and received.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Port_(computing)">https://en.wikipedia.org/wiki/Port_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-primary-key">primary key</dt>
<dd><p class="first">A primary key is an index over one or more fields in a table with
unique values for every single row in this table. Every table should have
a primary key for easier accessing/identifying data in this table. There
can only be one primary key per table and it is named always <strong>PRIMARY</strong>.
In fact, a primary key is just an <a class="reference internal" href="#term-unique-key"><span class="xref std std-term">unique key</span></a> with the name
<strong>PRIMARY</strong>. If no primary key is defined MySQL will use first <em>unique
key</em> as primary key if there is one.</p>
<p>You can create the primary key when creating the table (in phpMyAdmin
just check the primary key radio buttons for each field you wish to be
part of the primary key).</p>
<p class="last">You can also add a primary key to an existing table with <cite>ALTER</cite> <cite>TABLE</cite>
or <cite>CREATE</cite> <cite>INDEX</cite> (in phpMyAdmin you can just click on add index on
the table structure page below the listed fields).</p>
</dd>
<dt id="term-rfc">RFC</dt>
<dd><p class="first">Request for Comments (RFC) documents are a series of memoranda
encompassing new research, innovations, and methodologies applicable to
Internet technologies.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Request_for_Comments">https://en.wikipedia.org/wiki/Request_for_Comments</a>&gt;</p>
</div>
</dd>
<dt id="term-rfc-1952">RFC 1952</dt>
<dd><p class="first">GZIP file format specification version 4.3</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><span class="target" id="index-0"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc1952.html"><strong>RFC 1952</strong></a></p>
</div>
</dd>
<dt id="term-row-record-tuple">Row (record, tuple)</dt>
<dd><p class="first">represents a single, implicitly structured data item in a table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Row_(database)">https://en.wikipedia.org/wiki/Row_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-server">Server</dt>
<dd><p class="first">a computer system that provides services to other computing systems over a network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Server_(computing)">https://en.wikipedia.org/wiki/Server_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-storage-engines">Storage Engines</dt>
<dd><p class="first">MySQL can use several different formats for storing data on disk, these
are called storage engines or table types. phpMyAdmin allows a user to
change their storage engine for a particular table through the operations
tab.</p>
<p>Common table types are InnoDB and MyISAM, though many others exist and
may be desirable in some situations.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html">https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html</a>&gt;</p>
</div>
</dd>
<dt id="term-socket">socket</dt>
<dd><p class="first">a form of inter-process communication.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Unix_domain_socket">https://en.wikipedia.org/wiki/Unix_domain_socket</a>&gt;</p>
</div>
</dd>
<dt id="term-ssl">SSL</dt>
<dd><p class="first">Secure Sockets Layer is a cryptographic protocol which provides secure
communication on the Internet.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Secure_Sockets_Layer">https://en.wikipedia.org/wiki/Secure_Sockets_Layer</a>&gt;</p>
</div>
</dd>
<dt id="term-stored-procedure">Stored procedure</dt>
<dd><p class="first">a subroutine available to applications accessing a relational database system</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Stored_procedure">https://en.wikipedia.org/wiki/Stored_procedure</a>&gt;</p>
</div>
</dd>
<dt id="term-sql">SQL</dt>
<dd><p class="first">Structured Query Language</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/SQL">https://en.wikipedia.org/wiki/SQL</a>&gt;</p>
</div>
</dd>
<dt id="term-table">table</dt>
<dd><p class="first">a set of data elements (cells) that is organized, defined and stored as
horizontal rows and vertical columns where each item can be uniquely
identified by a label or key or by its position in relation to other
items.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Table_(database)">https://en.wikipedia.org/wiki/Table_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-tar">tar</dt>
<dd><p class="first">a type of archive file format: the Tape ARchive format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Tar_(file_format)">https://en.wikipedia.org/wiki/Tar_(file_format)</a>&gt;</p>
</div>
</dd>
<dt id="term-tcp">TCP</dt>
<dd><p class="first">Transmission Control Protocol is one of the core protocols of the
Internet protocol suite.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/TCP">https://en.wikipedia.org/wiki/TCP</a>&gt;</p>
</div>
</dd>
<dt id="term-tcpdf">TCPDF</dt>
<dd><p class="first">PHP library to generate PDF files.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://tcpdf.org/">https://tcpdf.org/</a>&gt;</p>
</div>
</dd>
<dt id="term-trigger">trigger</dt>
<dd><p class="first">a procedural code that is automatically executed in response to certain events on a particular table or view in a database</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Database_trigger">https://en.wikipedia.org/wiki/Database_trigger</a>&gt;</p>
</div>
</dd>
<dt id="term-unique-key">unique key</dt>
<dd>A unique key is an index over one or more fields in a table which has a
unique value for each row. The first unique key will be treated as
<a class="reference internal" href="#term-primary-key"><span class="xref std std-term">primary key</span></a> if there is no <em>primary key</em> defined.</dd>
<dt id="term-url">URL</dt>
<dd><p class="first">Uniform Resource Locator is a sequence of characters, conforming to a
standardized format, that is used for referring to resources, such as
documents and images on the Internet, by their location.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/URL">https://en.wikipedia.org/wiki/URL</a>&gt;</p>
</div>
</dd>
<dt id="term-webserver">Webserver</dt>
<dd><p class="first">A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Webserver">https://en.wikipedia.org/wiki/Webserver</a>&gt;</p>
</div>
</dd>
<dt id="term-xml">XML</dt>
<dd><p class="first">Extensible Markup Language is a W3C-recommended general-purpose markup
language for creating special-purpose markup languages, capable of
describing many different kinds of data.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/XML">https://en.wikipedia.org/wiki/XML</a>&gt;</p>
</div>
</dd>
<dt id="term-zip">ZIP</dt>
<dd><p class="first">a popular data compression and archival format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ZIP_(file_format)">https://en.wikipedia.org/wiki/ZIP_(file_format)</a>&gt;</p>
</div>
</dd>
<dt id="term-zlib">Zlib</dt>
<dd><p class="first">an open-source, cross-platform data compression library by Jean-loup Gailly and Mark Adler.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Zlib">https://en.wikipedia.org/wiki/Zlib</a>&gt;</p>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="credits.html"
title="previous chapter">Credits</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/glossary.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="credits.html" title="Credits"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,188 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Introduction &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Requirements" href="require.html" />
<link rel="prev" title="Welcome to phpMyAdmins documentation!" href="index.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="require.html" title="Requirements"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to phpMyAdmins documentation!"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="introduction">
<span id="intro"></span><h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h1>
<p>phpMyAdmin is a free software tool written in PHP that is intended to handle the
administration of a MySQL or MariaDB database server. You can use phpMyAdmin to
perform most administration tasks, including creating a database, running queries,
and adding user accounts.</p>
<div class="section" id="supported-features">
<h2>Supported features<a class="headerlink" href="#supported-features" title="Permalink to this headline"></a></h2>
<p>Currently phpMyAdmin can:</p>
<ul class="simple">
<li>create, browse, edit, and drop databases, tables, views, columns, and indexes</li>
<li>display multiple results sets through stored procedures or queries</li>
<li>create, copy, drop, rename and alter databases, tables, columns and
indexes</li>
<li>maintenance server, databases and tables, with proposals on server
configuration</li>
<li>execute, edit and bookmark any <a class="reference internal" href="glossary.html#term-sql"><span class="xref std std-term">SQL</span></a>-statement, even batch-queries</li>
<li>load text files into tables</li>
<li>create <a class="footnote-reference" href="#f1" id="id1">[1]</a> and read dumps of tables</li>
<li>export <a class="footnote-reference" href="#f1" id="id2">[1]</a> data to various formats: <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a>, <a class="reference internal" href="glossary.html#term-xml"><span class="xref std std-term">XML</span></a>, <a class="reference internal" href="glossary.html#term-pdf"><span class="xref std std-term">PDF</span></a>,
<a class="reference internal" href="glossary.html#term-iso"><span class="xref std std-term">ISO</span></a>/<a class="reference internal" href="glossary.html#term-iec"><span class="xref std std-term">IEC</span></a> 26300 - <a class="reference internal" href="glossary.html#term-opendocument"><span class="xref std std-term">OpenDocument</span></a> Text and Spreadsheet, Microsoft
Word 2000, and LATEX formats</li>
<li>import data and <a class="reference internal" href="glossary.html#term-47"><span class="xref std std-term">MySQL</span></a> structures from <a class="reference internal" href="glossary.html#term-opendocument"><span class="xref std std-term">OpenDocument</span></a> spreadsheets, as
well as <a class="reference internal" href="glossary.html#term-xml"><span class="xref std std-term">XML</span></a>, <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a>, and <a class="reference internal" href="glossary.html#term-sql"><span class="xref std std-term">SQL</span></a> files</li>
<li>administer multiple servers</li>
<li>add, edit, and remove MySQL user accounts and privileges</li>
<li>check referential integrity in MyISAM tables</li>
<li>using Query-by-example (QBE), create complex queries automatically
connecting required tables</li>
<li>create <a class="reference internal" href="glossary.html#term-pdf"><span class="xref std std-term">PDF</span></a> graphics of your
database layout</li>
<li>search globally in a database or a subset of it</li>
<li>transform stored data into any format using a set of predefined
functions, like displaying BLOB-data as image or download-link</li>
<li>track changes on databases, tables and views</li>
<li>support InnoDB tables and foreign keys</li>
<li>support mysqli, the improved MySQL extension see <a class="reference internal" href="faq.html#faq1-17"><span class="std std-ref">1.17 Which Database versions does phpMyAdmin support?</span></a></li>
<li>create, edit, call, export and drop stored procedures and functions</li>
<li>create, edit, export and drop events and triggers</li>
<li>communicate in <a class="reference external" href="https://www.phpmyadmin.net/translations/">80 different languages</a></li>
</ul>
</div>
<div class="section" id="shortcut-keys">
<h2>Shortcut keys<a class="headerlink" href="#shortcut-keys" title="Permalink to this headline"></a></h2>
<p>Currently phpMyAdmin supports following shortcuts:</p>
<ul class="simple">
<li>k - Toggle console</li>
<li>h - Go to home page</li>
<li>s - Open settings</li>
<li>d + s - Go to database structure (Provided you are in database related page)</li>
<li>d + f - Search database (Provided you are in database related page)</li>
<li>t + s - Go to table structure (Provided you are in table related page)</li>
<li>t + f - Search table (Provided you are in table related page)</li>
<li>backspace - Takes you to older page.</li>
</ul>
</div>
<div class="section" id="a-word-about-users">
<h2>A word about users<a class="headerlink" href="#a-word-about-users" title="Permalink to this headline"></a></h2>
<p>Many people have difficulty understanding the concept of user
management with regards to phpMyAdmin. When a user logs in to
phpMyAdmin, that username and password are passed directly to MySQL.
phpMyAdmin does no account management on its own (other than allowing
one to manipulate the MySQL user account information); all users must
be valid MySQL users.</p>
<p class="rubric">Footnotes</p>
<table class="docutils footnote" frame="void" id="f1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id2">2</a>)</em> phpMyAdmin can compress (<a class="reference internal" href="glossary.html#term-zip"><span class="xref std std-term">ZIP</span></a>, <a class="reference internal" href="glossary.html#term-gzip"><span class="xref std std-term">GZip</span></a> or <a class="reference internal" href="glossary.html#term-rfc-1952"><span class="xref std std-term">RFC 1952</span></a>
formats) dumps and <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a> exports if you use PHP with
<a class="reference internal" href="glossary.html#term-zlib"><span class="xref std std-term">Zlib</span></a> support (<code class="docutils literal notranslate"><span class="pre">--with-zlib</span></code>).
Proper support may also need changes in <code class="file docutils literal notranslate"><span class="pre">php.ini</span></code>.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Introduction</a><ul>
<li><a class="reference internal" href="#supported-features">Supported features</a></li>
<li><a class="reference internal" href="#shortcut-keys">Shortcut keys</a></li>
<li><a class="reference internal" href="#a-word-about-users">A word about users</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Welcome to phpMyAdmins documentation!</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="require.html"
title="next chapter">Requirements</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/intro.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="require.html" title="Requirements"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to phpMyAdmins documentation!"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,150 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Other sources of information &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="FAQ - Frequently Asked Questions" href="faq.html" />
<link rel="prev" title="Custom Themes" href="themes.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="themes.html" title="Custom Themes"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="other-sources-of-information">
<h1>Other sources of information<a class="headerlink" href="#other-sources-of-information" title="Permalink to this headline"></a></h1>
<div class="section" id="printed-book">
<h2>Printed Book<a class="headerlink" href="#printed-book" title="Permalink to this headline"></a></h2>
<p>The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
Effective MySQL Management by Marc Delisle. You can get information on that
book and other officially endorsed <a class="reference external" href="https://www.phpmyadmin.net/docs/">books at the phpMyAdmin site</a>.</p>
</div>
<div class="section" id="tutorials">
<h2>Tutorials<a class="headerlink" href="#tutorials" title="Permalink to this headline"></a></h2>
<p>Third party tutorials and articles which you might find interesting:</p>
<div class="section" id="cesky-czech">
<h3>Česky (Czech)<a class="headerlink" href="#cesky-czech" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://cihar.com/publications/linuxsoft/">Seriál o phpMyAdminovi</a></li>
</ul>
</div>
<div class="section" id="english">
<h3>English<a class="headerlink" href="#english" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://garv.in/tops/texte/mimetutorial">Having fun with phpMyAdmins MIME-transformations &amp; PDF-features</a></li>
<li><a class="reference external" href="http://www.php-editors.com/articles/sql_phpmyadmin.php">Learning SQL Using phpMyAdmin (old tutorial)</a></li>
</ul>
</div>
<div class="section" id="russian">
<h3>Русский (Russian)<a class="headerlink" href="#russian" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://php-myadmin.ru/">Russian server about phpMyAdmin</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Other sources of information</a><ul>
<li><a class="reference internal" href="#printed-book">Printed Book</a></li>
<li><a class="reference internal" href="#tutorials">Tutorials</a><ul>
<li><a class="reference internal" href="#cesky-czech">Česky (Czech)</a></li>
<li><a class="reference internal" href="#english">English</a></li>
<li><a class="reference internal" href="#russian">Русский (Russian)</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="themes.html"
title="previous chapter">Custom Themes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="faq.html"
title="next chapter">FAQ - Frequently Asked Questions</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/other.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
>next</a> |</li>
<li class="right" >
<a href="themes.html" title="Custom Themes"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,165 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Requirements &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Installation" href="setup.html" />
<link rel="prev" title="Introduction" href="intro.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="setup.html" title="Installation"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="requirements">
<span id="require"></span><h1>Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h1>
<div class="section" id="web-server">
<h2>Web server<a class="headerlink" href="#web-server" title="Permalink to this headline"></a></h2>
<p>Since phpMyAdmins interface is based entirely in your browser, youll need a
web server (such as Apache, nginx, <a class="reference internal" href="glossary.html#term-iis"><span class="xref std std-term">IIS</span></a>) to install phpMyAdmins files into.</p>
</div>
<div class="section" id="php">
<h2>PHP<a class="headerlink" href="#php" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>You need PHP 7.1.3 or newer, with <code class="docutils literal notranslate"><span class="pre">session</span></code> support, the Standard PHP Library
(SPL) extension, hash, ctype, and JSON support.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">mbstring</span></code> extension (see <a class="reference internal" href="glossary.html#term-mbstring"><span class="xref std std-term">mbstring</span></a>) is strongly recommended
for performance reasons.</li>
<li>To support uploading of ZIP files, you need the PHP <code class="docutils literal notranslate"><span class="pre">zip</span></code> extension.</li>
<li>You need GD2 support in PHP to display inline thumbnails of JPEGs
(“image/jpeg: inline”) with their original aspect ratio.</li>
<li>When using the cookie authentication (the default), the <a class="reference external" href="https://www.php.net/openssl">openssl</a> extension is strongly suggested.</li>
<li>To support upload progress bars, see <a class="reference internal" href="faq.html#faq2-9"><span class="std std-ref">2.9 Seeing an upload progress bar</span></a>.</li>
<li>To support XML and Open Document Spreadsheet importing, you need the
<a class="reference external" href="https://www.php.net/libxml">libxml</a> extension.</li>
<li>To support reCAPTCHA on the login page, you need the
<a class="reference external" href="https://www.php.net/openssl">openssl</a> extension.</li>
<li>To support displaying phpMyAdmins latest version, you need to enable
<code class="docutils literal notranslate"><span class="pre">allow_url_open</span></code> in your <code class="file docutils literal notranslate"><span class="pre">php.ini</span></code> or to have the
<a class="reference external" href="https://www.php.net/curl">curl</a> extension.</li>
</ul>
<div class="admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="faq.html#faq1-31"><span class="std std-ref">1.31 Which PHP versions does phpMyAdmin support?</span></a>, <a class="reference internal" href="setup.html#authentication-modes"><span class="std std-ref">Using authentication modes</span></a></p>
</div>
</div>
<div class="section" id="database">
<h2>Database<a class="headerlink" href="#database" title="Permalink to this headline"></a></h2>
<p>phpMyAdmin supports MySQL-compatible databases.</p>
<ul class="simple">
<li>MySQL 5.5 or newer</li>
<li>MariaDB 5.5 or newer</li>
</ul>
<div class="admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="faq.html#faq1-17"><span class="std std-ref">1.17 Which Database versions does phpMyAdmin support?</span></a></p>
</div>
</div>
<div class="section" id="web-browser">
<h2>Web browser<a class="headerlink" href="#web-browser" title="Permalink to this headline"></a></h2>
<p>To access phpMyAdmin you need a web browser with cookies and JavaScript
enabled.</p>
<p>You need a browser which is supported by jQuery 2.0, see
&lt;<a class="reference external" href="https://jquery.com/browser-support/">https://jquery.com/browser-support/</a>&gt;.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Requirements</a><ul>
<li><a class="reference internal" href="#web-server">Web server</a></li>
<li><a class="reference internal" href="#php">PHP</a></li>
<li><a class="reference internal" href="#database">Database</a></li>
<li><a class="reference internal" href="#web-browser">Web browser</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="intro.html"
title="previous chapter">Introduction</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="setup.html"
title="next chapter">Installation</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/require.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="setup.html" title="Installation"
>next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,94 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,237 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Transformations &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Bookmarks" href="bookmarks.html" />
<link rel="prev" title="Two-factor authentication" href="two_factor.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="bookmarks.html" title="Bookmarks"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="two_factor.html" title="Two-factor authentication"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="transformations">
<span id="id1"></span><h1>Transformations<a class="headerlink" href="#transformations" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You need to have configured the <a class="reference internal" href="setup.html#linked-tables"><span class="std std-ref">phpMyAdmin configuration storage</span></a> for using transformations
feature.</p>
</div>
<div class="section" id="introduction">
<span id="transformationsintro"></span><h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>To enable transformations, you have to setup the <code class="docutils literal notranslate"><span class="pre">column_info</span></code>
table and the proper directives. Please see the <a class="reference internal" href="config.html#config"><span class="std std-ref">Configuration</span></a> on how to do so.</p>
<p>You can apply different transformations to the contents of each
column. The transformation will take the content of each column and
transform it with certain rules defined in the selected
transformation.</p>
<p>Say you have a column filename which contains a filename. Normally
you would see in phpMyAdmin only this filename. Using transformations
you can transform that filename into a HTML link, so you can click
inside of the phpMyAdmin structure on the columns link and will see
the file displayed in a new browser window. Using transformation
options you can also specify strings to append/prepend to a string or
the format you want the output stored in.</p>
<p>For a general overview of all available transformations and their
options, you can consult your <em>&lt;www.your-host.com&gt;/&lt;your-install-
dir&gt;/transformation_overview.php</em> installation.</p>
<p>For a tutorial on how to effectively use transformations, see our
<a class="reference external" href="https://www.phpmyadmin.net/docs/">Link section</a> on the
official phpMyAdmin homepage.</p>
</div>
<div class="section" id="usage">
<span id="transformationshowto"></span><h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline"></a></h2>
<p>Go to your <em>tbl_structure.php</em> page (i.e. reached through clicking on
the Structure link for a table). There click on “Change” (or change
icon) and there you will see three new fields at the end of the line.
They are called <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a>, Browser transformation and
Transformation options.</p>
<ul class="simple">
<li>The field <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> is a drop-down field. Select the <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> that
corresponds to the columns contents. Please note that transformations
are inactive as long as no <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> is selected.</li>
<li>The field Browser transformation is a drop-down field. You can
choose from a hopefully growing amount of pre-defined transformations.
See below for information on how to build your own transformation.
There are global transformations and mimetype-bound transformations.
Global transformations can be used for any mimetype. They will take
the mimetype, if necessary, into regard. Mimetype-bound
transformations usually only operate on a certain mimetype. There are
transformations which operate on the main mimetype (like image),
which will most likely take the subtype into regard, and those who
only operate on a specific subtype (like image/jpeg). You can use
transformations on mimetypes for which the function was not defined
for. There is no security check for you selected the right
transformation, so take care of what the output will be like.</li>
<li>The field Transformation options is a free-type textfield. You have
to enter transform-function specific options here. Usually the
transforms can operate with default options, but it is generally a
good idea to look up the overview to see which options are necessary.
Much like the ENUM/SET-Fields, you have to split up several options
using the format a,b,c,…(NOTE THE MISSING BLANKS). This is
because internally the options will be parsed as an array, leaving the
first value the first element in the array, and so forth. If you want
to specify a MIME character set you can define it in the
transformation_options. You have to put that outside of the pre-
defined options of the specific mime-transform, as the last value of
the set. Use the format “’; charset=XXX”. If you use a transform, for
which you can specify 2 options and you want to append a character
set, enter “first parameter,second parameter,charset=us-ascii”.
You can, however use the defaults for the parameters: “’‘,,charset
=us-ascii”. The default options can be configured using
<span class="target" id="index-0"></span><a class="reference internal" href="config.html#cfg_DefaultTransformations"><code class="xref config config-option docutils literal notranslate"><span class="pre">$cfg['DefaultTransformations']</span></code></a></li>
</ul>
</div>
<div class="section" id="file-structure">
<span id="transformationsfiles"></span><h2>File structure<a class="headerlink" href="#file-structure" title="Permalink to this headline"></a></h2>
<p>All specific transformations for mimetypes are defined through class
files in the directory libraries/classes/Plugins/Transformations/. Each of
them extends a certain transformation abstract class declared in
libraries/classes/Plugins/Transformations/Abs.</p>
<p>They are stored in files to ease up customization and easy adding of
new transformations.</p>
<p>Because the user cannot enter own mimetypes, it is kept sure that
transformations always work. It makes no sense to apply a
transformation to a mimetype the transform-function doesnt know to
handle.</p>
<p>There is a file called <code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations.php</span></code> that provides some
basic functions which can be included by any other transform function.</p>
<p>The file name convention is <code class="docutils literal notranslate"><span class="pre">[Mimetype]_[Subtype]_[Transformation</span>
<span class="pre">Name].php</span></code>, while the abstract class that it extends has the
name <code class="docutils literal notranslate"><span class="pre">[Transformation</span> <span class="pre">Name]TransformationsPlugin</span></code>. All of the
methods that have to be implemented by a transformations plug-in are:</p>
<ol class="arabic simple">
<li>getMIMEType() and getMIMESubtype() in the main class;</li>
<li>getName(), getInfo() and applyTransformation() in the abstract class
it extends.</li>
</ol>
<p>The getMIMEType(), getMIMESubtype() and getName() methods return the
name of the MIME type, MIME Subtype and transformation accordingly.
getInfo() returns the transformations description and possible
options it may receive and applyTransformation() is the method that
does the actual work of the transformation plug-in.</p>
<p>Please see the <code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations/TEMPLATE</span></code> and
<code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations/TEMPLATE_ABSTRACT</span></code> files for adding
your own transformation plug-in. You can also generate a new
transformation plug-in (with or without the abstract transformation
class), by using
<code class="file docutils literal notranslate"><span class="pre">scripts/transformations_generator_plugin.sh</span></code> or
<code class="file docutils literal notranslate"><span class="pre">scripts/transformations_generator_main_class.sh</span></code>.</p>
<p>The applyTransformation() method always gets passed three variables:</p>
<ol class="arabic simple">
<li><strong>$buffer</strong> - Contains the text inside of the column. This is the
text, you want to transform.</li>
<li><strong>$options</strong> - Contains any user-passed options to a transform
function as an array.</li>
<li><strong>$meta</strong> - Contains an object with information about your column. The
data is drawn from the output of the <a class="reference external" href="https://www.php.net/mysql_fetch_field">mysql_fetch_field()</a> function. This means, all
object properties described on the <a class="reference external" href="https://www.php.net/mysql_fetch_field">manual page</a> are available in this
variable and can be used to transform a column accordingly to
unsigned/zerofill/not_null/… properties. The $meta-&gt;mimetype
variable contains the original <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> of the column (i.e.
text/plain, image/jpeg etc.)</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Transformations</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#usage">Usage</a></li>
<li><a class="reference internal" href="#file-structure">File structure</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="two_factor.html"
title="previous chapter">Two-factor authentication</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="bookmarks.html"
title="next chapter">Bookmarks</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/transformations.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="bookmarks.html" title="Bookmarks"
>next</a> |</li>
<li class="right" >
<a href="two_factor.html" title="Two-factor authentication"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,172 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Two-factor authentication &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Transformations" href="transformations.html" />
<link rel="prev" title="Configuring phpMyAdmin" href="settings.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="transformations.html" title="Transformations"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="settings.html" title="Configuring phpMyAdmin"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="two-factor-authentication">
<span id="fa"></span><h1>Two-factor authentication<a class="headerlink" href="#two-factor-authentication" title="Permalink to this headline"></a></h1>
<div class="versionadded">
<p><span class="versionmodified">New in version 4.8.0.</span></p>
</div>
<p>Since phpMyAdmin 4.8.0 you can configure two-factor authentication to be
used when logging in. To use this, you first need to configure the
<a class="reference internal" href="setup.html#linked-tables"><span class="std std-ref">phpMyAdmin configuration storage</span></a>. Once this is done, every user can opt-in for the second
authentication factor in the <span class="guilabel">Settings</span>.</p>
<p>When running phpMyAdmin from the Git source repository, the dependencies must be installed
manually; the typical way of doing so is with the command:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>composer require pragmarx/google2fa-qrcode
</pre></div>
</div>
<p>Or when using a hardware security key with FIDO U2F:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>composer require samyoul/u2f-php-server
</pre></div>
</div>
<div class="section" id="authentication-application-2fa">
<h2>Authentication Application (2FA)<a class="headerlink" href="#authentication-application-2fa" title="Permalink to this headline"></a></h2>
<p>Using an application for authentication is a quite common approach based on HOTP and
<a class="reference external" href="https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm">TOTP</a>.
It is based on transmitting a private key from phpMyAdmin to the authentication
application and the application is then able to generate one time codes based
on this key. The easiest way to enter the key in to the application from phpMyAdmin is
through scanning a QR code.</p>
<p>There are dozens of applications available for mobile phones to implement these
standards, the most widely used include:</p>
<ul class="simple">
<li><a class="reference external" href="https://freeotp.github.io/">FreeOTP for iOS, Android and Pebble</a></li>
<li><a class="reference external" href="https://authy.com/">Authy for iOS, Android, Chrome, OS X</a></li>
<li><a class="reference external" href="https://apps.apple.com/us/app/google-authenticator/id388497605">Google Authenticator for iOS</a></li>
<li><a class="reference external" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator for Android</a></li>
<li><a class="reference external" href="https://lastpass.com/auth/">LastPass Authenticator for iOS, Android, OS X, Windows</a></li>
</ul>
</div>
<div class="section" id="hardware-security-key-fido-u2f">
<h2>Hardware Security Key (FIDO U2F)<a class="headerlink" href="#hardware-security-key-fido-u2f" title="Permalink to this headline"></a></h2>
<p>Using hardware tokens is considered to be more secure than a software based
solution. phpMyAdmin supports <a class="reference external" href="https://en.wikipedia.org/wiki/Universal_2nd_Factor">FIDO U2F</a>
tokens.</p>
<p>There are several manufacturers of these tokens, for example:</p>
<ul class="simple">
<li><a class="reference external" href="https://www.yubico.com/fido-u2f/">youbico FIDO U2F Security Key</a></li>
<li><a class="reference external" href="https://www.hypersecu.com/hyperfido">HyperFIDO</a></li>
<li><a class="reference external" href="https://trezor.io/?offer_id=12&amp;aff_id=1592&amp;source=phpmyadmin">Trezor Hardware Wallet</a> can act as an <a class="reference external" href="https://wiki.trezor.io/User_manual:Two-factor_Authentication_with_U2F">U2F token</a></li>
<li><a class="reference external" href="https://www.dongleauth.info/dongles/">List of Two Factor Auth (2FA) Dongles</a></li>
</ul>
</div>
<div class="section" id="simple-two-factor-authentication">
<span id="simple2fa"></span><h2>Simple two-factor authentication<a class="headerlink" href="#simple-two-factor-authentication" title="Permalink to this headline"></a></h2>
<p>This authentication is included for testing and demonstration purposes only as
it really does not provide two-factor authentication, it just asks the user to confirm login by
clicking on the button.</p>
<p>It should not be used in the production and is disabled unless
<span class="target" id="index-0"></span><a class="reference internal" href="config.html#cfg_DBG_simple2fa"><code class="xref config config-option docutils literal notranslate"><span class="pre">$cfg['DBG']['simple2fa']</span></code></a> is set.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Two-factor authentication</a><ul>
<li><a class="reference internal" href="#authentication-application-2fa">Authentication Application (2FA)</a></li>
<li><a class="reference internal" href="#hardware-security-key-fido-u2f">Hardware Security Key (FIDO U2F)</a></li>
<li><a class="reference internal" href="#simple-two-factor-authentication">Simple two-factor authentication</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="settings.html"
title="previous chapter">Configuring phpMyAdmin</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="transformations.html"
title="next chapter">Transformations</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/two_factor.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="transformations.html" title="Transformations"
>next</a> |</li>
<li class="right" >
<a href="settings.html" title="Configuring phpMyAdmin"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,138 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Distributing and packaging phpMyAdmin &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Copyright" href="copyright.html" />
<link rel="prev" title="Security policy" href="security.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="copyright.html" title="Copyright"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="security.html" title="Security policy"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="distributing-and-packaging-phpmyadmin">
<h1>Distributing and packaging phpMyAdmin<a class="headerlink" href="#distributing-and-packaging-phpmyadmin" title="Permalink to this headline"></a></h1>
<p>This document is intended to give pieces of advice to people who want to
redistribute phpMyAdmin inside other software packages such as Linux
distribution or some all in one package including web server and MySQL
server.</p>
<p>Generally, you can customize some basic aspects (paths to some files and
behavior) in <code class="file docutils literal notranslate"><span class="pre">libraries/vendor_config.php</span></code>.</p>
<p>For example, if you want setup script to generate a config file in var, change
<code class="docutils literal notranslate"><span class="pre">SETUP_CONFIG_FILE</span></code> to <code class="file docutils literal notranslate"><span class="pre">/var/lib/phpmyadmin/config.inc.php</span></code> and you
will also probably want to skip directory writable check, so set
<code class="docutils literal notranslate"><span class="pre">SETUP_DIR_WRITABLE</span></code> to false.</p>
<div class="section" id="external-libraries">
<h2>External libraries<a class="headerlink" href="#external-libraries" title="Permalink to this headline"></a></h2>
<p>phpMyAdmin includes several external libraries, you might want to
replace them with system ones if they are available, but please note
that you should test whether the version you provide is compatible with the
one we ship.</p>
<p>Currently known list of external libraries:</p>
<dl class="docutils">
<dt>js/vendor</dt>
<dd>jQuery js framework libraries and various js libraries.</dd>
<dt>vendor/</dt>
<dd>The download kit includes various Composer packages as
dependencies.</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Distributing and packaging phpMyAdmin</a><ul>
<li><a class="reference internal" href="#external-libraries">External libraries</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="security.html"
title="previous chapter">Security policy</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="copyright.html"
title="next chapter">Copyright</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/vendors.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="copyright.html" title="Copyright"
>next</a> |</li>
<li class="right" >
<a href="security.html" title="Security policy"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,140 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Handle error report submission
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\ErrorReport;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
use PhpMyAdmin\UserPreferences;
use PhpMyAdmin\Utils\HttpRequest;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
if (! isset($_POST['exception_type'])
|| ! in_array($_POST['exception_type'], ['js', 'php'])
) {
die('Oops, something went wrong!!');
}
$response = Response::getInstance();
/** @var ErrorReport $errorReport */
$errorReport = $containerBuilder->get('error_report');
if (isset($_POST['send_error_report'])
&& ($_POST['send_error_report'] == true
|| $_POST['send_error_report'] == '1')
) {
if ($_POST['exception_type'] == 'php') {
/**
* Prevent infinite error submission.
* Happens in case error submissions fails.
* If reporting is done in some time interval,
* just clear them & clear json data too.
*/
if (isset($_SESSION['prev_error_subm_time'])
&& isset($_SESSION['error_subm_count'])
&& $_SESSION['error_subm_count'] >= 3
&& ($_SESSION['prev_error_subm_time'] - time()) <= 3000
) {
$_SESSION['error_subm_count'] = 0;
$_SESSION['prev_errors'] = '';
$response->addJSON('stopErrorReportLoop', '1');
} else {
$_SESSION['prev_error_subm_time'] = time();
$_SESSION['error_subm_count'] = (
isset($_SESSION['error_subm_count'])
? ($_SESSION['error_subm_count'] + 1)
: 0
);
}
}
$reportData = $errorReport->getData($_POST['exception_type']);
// report if and only if there were 'actual' errors.
if (count($reportData) > 0) {
$server_response = $errorReport->send($reportData);
if (! is_string($server_response)) {
$success = false;
} else {
$decoded_response = json_decode($server_response, true);
$success = ! empty($decoded_response) ?
$decoded_response["success"] : false;
}
/* Message to show to the user */
if ($success) {
if ((isset($_POST['automatic'])
&& $_POST['automatic'] === "true")
|| $GLOBALS['cfg']['SendErrorReports'] == 'always'
) {
$msg = __(
'An error has been detected and an error report has been '
. 'automatically submitted based on your settings.'
);
} else {
$msg = __('Thank you for submitting this report.');
}
} else {
$msg = __(
'An error has been detected and an error report has been '
. 'generated but failed to be sent.'
)
. ' '
. __(
'If you experience any '
. 'problems please submit a bug report manually.'
);
}
$msg .= ' ' . __('You may want to refresh the page.');
/* Create message object */
if ($success) {
$msg = Message::notice($msg);
} else {
$msg = Message::error($msg);
}
/* Add message to response */
if ($response->isAjax()) {
if ($_POST['exception_type'] == 'js') {
$response->addJSON('message', $msg);
} else {
$response->addJSON('errSubmitMsg', $msg);
}
} elseif ($_POST['exception_type'] == 'php') {
$jsCode = 'Functions.ajaxShowMessage("<div class=\"error\">'
. $msg
. '</div>", false);';
$response->getFooter()->getScripts()->addCode($jsCode);
}
if ($_POST['exception_type'] == 'php') {
// clear previous errors & save new ones.
$GLOBALS['error_handler']->savePreviousErrors();
}
/* Persist always send settings */
if (isset($_POST['always_send'])
&& $_POST['always_send'] === "true"
) {
$userPreferences = new UserPreferences();
$userPreferences->persistOption("SendErrorReports", "always", "ask");
}
}
} elseif (! empty($_POST['get_settings'])) {
$response->addJSON('report_setting', $GLOBALS['cfg']['SendErrorReports']);
} elseif ($_POST['exception_type'] == 'js') {
$response->addHTML($errorReport->getForm());
} else {
// clear previous errors & save new ones.
$GLOBALS['error_handler']->savePreviousErrors();
}

View File

@ -1,178 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Single signon for phpMyAdmin using OpenID
*
* This is just example how to use single signon with phpMyAdmin, it is
* not intended to be perfect code and look, only shows how you can
* integrate this functionality in your application.
*
* It uses OpenID pear package, see https://pear.php.net/package/OpenID
*
* User first authenticates using OpenID and based on content of $AUTH_MAP
* the login information is passed to phpMyAdmin in session data.
*
* @package PhpMyAdmin
* @subpackage Example
*/
declare(strict_types=1);
if (false === @include_once 'OpenID/RelyingParty.php') {
exit;
}
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/**
* Map of authenticated users to MySQL user/password pairs.
*/
$AUTH_MAP = [
'https://launchpad.net/~username' => [
'user' => 'root',
'password' => '',
],
];
/**
* Simple function to show HTML page with given content.
*
* @param string $contents Content to include in page
*
* @return void
*/
function Show_page($contents)
{
header('Content-Type: text/html; charset=utf-8');
echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";
?>
<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin OpenID signon example</title>
</head>
<body>
<?php
if (isset($_SESSION) && isset($_SESSION['PMA_single_signon_error_message'])) {
echo '<p class="error">' , $_SESSION['PMA_single_signon_message'] , '</p>';
unset($_SESSION['PMA_single_signon_message']);
}
echo $contents;
?>
</body>
</html>
<?php
}
/**
* Display error and exit
*
* @param Exception $e Exception object
*
* @return void
*/
function Die_error($e)
{
$contents = "<div class='relyingparty_results'>\n";
$contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
$contents .= "</div class='relyingparty_results'>";
Show_page($contents);
exit;
}
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
@session_start();
// Determine realm and return_to
$base = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$base .= 's';
}
$base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];
$realm = $base . '/';
$returnTo = $base . dirname($_SERVER['PHP_SELF']);
if ($returnTo[strlen($returnTo) - 1] != '/') {
$returnTo .= '/';
}
$returnTo .= 'openid.php';
/* Display form */
if (! count($_GET) && ! count($_POST) || isset($_GET['phpMyAdmin'])) {
/* Show simple form */
$content = '<form action="openid.php" method="post">
OpenID: <input type="text" name="identifier"><br>
<input type="submit" name="start">
</form>
</body>
</html>';
Show_page($content);
exit;
}
/* Grab identifier */
if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
$identifier = $_POST['identifier'];
} elseif (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
$identifier = $_SESSION['identifier'];
} else {
$identifier = null;
}
/* Create OpenID object */
try {
$o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
} catch (Exception $e) {
Die_error($e);
}
/* Redirect to OpenID provider */
if (isset($_POST['start'])) {
try {
$authRequest = $o->prepare();
} catch (Exception $e) {
Die_error($e);
}
$url = $authRequest->getAuthorizeURL();
header("Location: $url");
exit;
} else {
/* Grab query string */
if (! count($_POST)) {
list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);
} else {
// I hate php sometimes
$queryString = file_get_contents('php://input');
}
/* Check reply */
try {
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
} catch (Exception $e) {
Die_error($e);
}
$id = $message->get('openid.claimed_id');
if (! empty($id) && isset($AUTH_MAP[$id])) {
$_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user'];
$_SESSION['PMA_single_signon_password'] = $AUTH_MAP[$id]['password'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {
Show_page('<p>User not allowed!</p>');
exit;
}
}

View File

@ -1,77 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Single signon for phpMyAdmin
*
* This is just example how to use session based single signon with
* phpMyAdmin, it is not intended to be perfect code and look, only
* shows how you can integrate this functionality in your application.
*
* @package PhpMyAdmin
* @subpackage Example
*/
declare(strict_types=1);
/* Use cookies for session */
ini_set('session.use_cookies', 'true');
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
@session_start();
/* Was data posted? */
if (isset($_POST['user'])) {
/* Store there credentials */
$_SESSION['PMA_single_signon_user'] = $_POST['user'];
$_SESSION['PMA_single_signon_password'] = $_POST['password'];
$_SESSION['PMA_single_signon_host'] = $_POST['host'];
$_SESSION['PMA_single_signon_port'] = $_POST['port'];
/* Update another field of server configuration */
$_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
$id = session_id();
/* Close that session */
@session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {
/* Show simple form */
header('Content-Type: text/html; charset=utf-8');
echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";
?>
<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin single signon example</title>
</head>
<body>
<?php
if (isset($_SESSION['PMA_single_signon_error_message'])) {
echo '<p class="error">';
echo $_SESSION['PMA_single_signon_error_message'];
echo '</p>';
}
?>
<form action="signon.php" method="post">
Username: <input type="text" name="user"><br>
Password: <input type="password" name="password"><br>
Host: (will use the one from config.inc.php by default)
<input type="text" name="host"><br>
Port: (will use the one from config.inc.php by default)
<input type="text" name="port"><br>
<input type="submit">
</form>
</body>
</html>
<?php
}
?>

View File

@ -1,650 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Main export handling code
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\Export;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\SelectStatement;
use PhpMyAdmin\SqlParser\Utils\Misc;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $sql_query;
include_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export_output.js');
/** @var Export $export */
$export = $containerBuilder->get('export');
//check if it's the GET request to check export time out
if (isset($_GET['check_time_out'])) {
if (isset($_SESSION['pma_export_error'])) {
$err = $_SESSION['pma_export_error'];
unset($_SESSION['pma_export_error']);
echo "timeout";
} else {
echo "success";
}
exit;
}
/**
* Sets globals from $_POST
*
* - Please keep the parameters in order of their appearance in the form
* - Some of these parameters are not used, as the code below directly
* verifies from the superglobal $_POST or $_REQUEST
* TODO: this should be removed to avoid passing user input to GLOBALS
* without checking
*/
$post_params = [
'db',
'table',
'what',
'single_table',
'export_type',
'export_method',
'quick_or_custom',
'db_select',
'table_select',
'table_structure',
'table_data',
'limit_to',
'limit_from',
'allrows',
'lock_tables',
'output_format',
'filename_template',
'maxsize',
'remember_template',
'charset',
'compression',
'as_separate_files',
'knjenc',
'xkana',
'htmlword_structure_or_data',
'htmlword_null',
'htmlword_columns',
'mediawiki_headers',
'mediawiki_structure_or_data',
'mediawiki_caption',
'pdf_structure_or_data',
'odt_structure_or_data',
'odt_relation',
'odt_comments',
'odt_mime',
'odt_columns',
'odt_null',
'codegen_structure_or_data',
'codegen_format',
'excel_null',
'excel_removeCRLF',
'excel_columns',
'excel_edition',
'excel_structure_or_data',
'yaml_structure_or_data',
'ods_null',
'ods_structure_or_data',
'ods_columns',
'json_structure_or_data',
'json_pretty_print',
'json_unicode',
'xml_structure_or_data',
'xml_export_events',
'xml_export_functions',
'xml_export_procedures',
'xml_export_tables',
'xml_export_triggers',
'xml_export_views',
'xml_export_contents',
'texytext_structure_or_data',
'texytext_columns',
'texytext_null',
'phparray_structure_or_data',
'sql_include_comments',
'sql_header_comment',
'sql_dates',
'sql_relation',
'sql_mime',
'sql_use_transaction',
'sql_disable_fk',
'sql_compatibility',
'sql_structure_or_data',
'sql_create_database',
'sql_drop_table',
'sql_procedure_function',
'sql_create_table',
'sql_create_view',
'sql_create_trigger',
'sql_view_current_user',
'sql_if_not_exists',
'sql_or_replace_view',
'sql_auto_increment',
'sql_backquotes',
'sql_truncate',
'sql_delayed',
'sql_ignore',
'sql_type',
'sql_insert_syntax',
'sql_max_query_size',
'sql_hex_for_binary',
'sql_utc_time',
'sql_drop_database',
'sql_views_as_tables',
'sql_metadata',
'csv_separator',
'csv_enclosed',
'csv_escaped',
'csv_terminated',
'csv_null',
'csv_removeCRLF',
'csv_columns',
'csv_structure_or_data',
// csv_replace should have been here but we use it directly from $_POST
'latex_caption',
'latex_structure_or_data',
'latex_structure_caption',
'latex_structure_continued_caption',
'latex_structure_label',
'latex_relation',
'latex_comments',
'latex_mime',
'latex_columns',
'latex_data_caption',
'latex_data_continued_caption',
'latex_data_label',
'latex_null',
'aliases',
];
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
$table = $GLOBALS['table'];
PhpMyAdmin\Util::checkParameters(['what', 'export_type']);
// sanitize this parameter which will be used below in a file inclusion
$what = Core::securePath($_POST['what']);
// export class instance, not array of properties, as before
/** @var ExportPlugin $export_plugin */
$export_plugin = Plugins::getPlugin(
"export",
$what,
'libraries/classes/Plugins/Export/',
[
'export_type' => $export_type,
'single_table' => isset($single_table),
]
);
// Check export type
if (empty($export_plugin)) {
Core::fatalError(__('Bad type!'));
}
/**
* valid compression methods
*/
$compression_methods = [];
if ($GLOBALS['cfg']['ZipDump'] && function_exists('gzcompress')) {
$compression_methods[] = 'zip';
}
if ($GLOBALS['cfg']['GZipDump'] && function_exists('gzencode')) {
$compression_methods[] = 'gzip';
}
/**
* init and variable checking
*/
$compression = '';
$onserver = false;
$save_on_server = false;
$buffer_needed = false;
$back_button = '';
$refreshButton = '';
$save_filename = '';
$file_handle = '';
$err_url = '';
$filename = '';
$separate_files = '';
// Is it a quick or custom export?
if (isset($_POST['quick_or_custom'])
&& $_POST['quick_or_custom'] == 'quick'
) {
$quick_export = true;
} else {
$quick_export = false;
}
if ($_POST['output_format'] == 'astext') {
$asfile = false;
} else {
$asfile = true;
if (isset($_POST['as_separate_files'])
&& ! empty($_POST['as_separate_files'])
) {
if (isset($_POST['compression'])
&& ! empty($_POST['compression'])
&& $_POST['compression'] == 'zip'
) {
$separate_files = $_POST['as_separate_files'];
}
}
if (in_array($_POST['compression'], $compression_methods)) {
$compression = $_POST['compression'];
$buffer_needed = true;
}
if (($quick_export && ! empty($_POST['quick_export_onserver']))
|| (! $quick_export && ! empty($_POST['onserver']))
) {
if ($quick_export) {
$onserver = $_POST['quick_export_onserver'];
} else {
$onserver = $_POST['onserver'];
}
// Will we save dump on server?
$save_on_server = ! empty($cfg['SaveDir']) && $onserver;
}
}
/**
* If we are sending the export file (as opposed to just displaying it
* as text), we have to bypass the usual PhpMyAdmin\Response mechanism
*/
if (isset($_POST['output_format']) && $_POST['output_format'] == 'sendit' && ! $save_on_server) {
$response->disable();
//Disable all active buffers (see: ob_get_status(true) at this point)
do {
if (ob_get_length() > 0 || ob_get_level() > 0) {
$hasBuffer = ob_end_clean();
} else {
$hasBuffer = false;
}
} while ($hasBuffer);
}
$tables = [];
// Generate error url and check for needed variables
if ($export_type == 'server') {
$err_url = 'server_export.php' . Url::getCommon();
} elseif ($export_type == 'database' && strlen($db) > 0) {
$err_url = 'db_export.php' . Url::getCommon(['db' => $db]);
// Check if we have something to export
if (isset($table_select)) {
$tables = $table_select;
} else {
$tables = [];
}
} elseif ($export_type == 'table' && strlen($db) > 0 && strlen($table) > 0) {
$err_url = 'tbl_export.php' . Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
} else {
Core::fatalError(__('Bad parameters!'));
}
// Merge SQL Query aliases with Export aliases from
// export page, Export page aliases are given more
// preference over SQL Query aliases.
$parser = new Parser($sql_query);
$aliases = [];
if (! empty($parser->statements[0])
&& ($parser->statements[0] instanceof SelectStatement)
) {
$aliases = Misc::getAliases($parser->statements[0], $db);
}
if (! empty($_POST['aliases'])) {
$aliases = $export->mergeAliases($aliases, $_POST['aliases']);
$_SESSION['tmpval']['aliases'] = $_POST['aliases'];
}
/**
* Increase time limit for script execution and initializes some variables
*/
Util::setTimeLimit();
if (! empty($cfg['MemoryLimit'])) {
ini_set('memory_limit', $cfg['MemoryLimit']);
}
register_shutdown_function([$export, 'shutdown']);
// Start with empty buffer
$dump_buffer = '';
$dump_buffer_len = 0;
// Array of dump_buffers - used in separate file exports
$dump_buffer_objects = [];
// We send fake headers to avoid browser timeout when buffering
$time_start = time();
// Defines the default <CR><LF> format.
// For SQL always use \n as MySQL wants this on all platforms.
if ($what == 'sql') {
$crlf = "\n";
} else {
$crlf = PHP_EOL;
}
$output_kanji_conversion = Encoding::canConvertKanji();
// Do we need to convert charset?
$output_charset_conversion = $asfile
&& Encoding::isSupported()
&& isset($charset) && $charset != 'utf-8';
// Use on the fly compression?
$GLOBALS['onfly_compression'] = $GLOBALS['cfg']['CompressOnFly']
&& $compression == 'gzip';
if ($GLOBALS['onfly_compression']) {
$GLOBALS['memory_limit'] = $export->getMemoryLimit();
}
// Generate filename and mime type if needed
if ($asfile) {
if (empty($remember_template)) {
$remember_template = '';
}
list($filename, $mime_type) = $export->getFilenameAndMimetype(
$export_type,
$remember_template,
$export_plugin,
$compression,
$filename_template
);
} else {
$mime_type = '';
}
// Open file on server if needed
if ($save_on_server) {
list($save_filename, $message, $file_handle) = $export->openFile(
$filename,
$quick_export
);
// problem opening export file on server?
if (! empty($message)) {
$export->showPage($db, $table, $export_type);
}
} else {
/**
* Send headers depending on whether the user chose to download a dump file
* or not
*/
if ($asfile) {
// Download
// (avoid rewriting data containing HTML with anchors and forms;
// this was reported to happen under Plesk)
ini_set('url_rewriter.tags', '');
$filename = Sanitize::sanitizeFilename($filename);
Core::downloadHeader($filename, $mime_type);
} else {
// HTML
if ($export_type == 'database') {
$num_tables = count($tables);
if ($num_tables === 0) {
$message = PhpMyAdmin\Message::error(
__('No tables found in database.')
);
$active_page = 'db_export.php';
include ROOT_PATH . 'db_export.php';
exit;
}
}
list($html, $back_button, $refreshButton) = $export->getHtmlForDisplayedExportHeader(
$export_type,
$db,
$table
);
echo $html;
unset($html);
} // end download
}
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
// Fake loop just to allow skip of remain of this code by break, I'd really
// need exceptions here :-)
do {
// Re - initialize
$dump_buffer = '';
$dump_buffer_len = 0;
// Add possibly some comments to export
if (! $export_plugin->exportHeader()) {
break;
}
// Will we need relation & co. setup?
$do_relation = isset($GLOBALS[$what . '_relation']);
$do_comments = isset($GLOBALS[$what . '_include_comments'])
|| isset($GLOBALS[$what . '_comments']);
$do_mime = isset($GLOBALS[$what . '_mime']);
if ($do_relation || $do_comments || $do_mime) {
$cfgRelation = $relation->getRelationsParam();
}
// Include dates in export?
$do_dates = isset($GLOBALS[$what . '_dates']);
$whatStrucOrData = $GLOBALS[$what . '_structure_or_data'];
/**
* Builds the dump
*/
if ($export_type == 'server') {
if (! isset($db_select)) {
$db_select = '';
}
$export->exportServer(
$db_select,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
} elseif ($export_type == 'database') {
if (! isset($table_structure) || ! is_array($table_structure)) {
$table_structure = [];
}
if (! isset($table_data) || ! is_array($table_data)) {
$table_data = [];
}
if (! empty($_POST['structure_or_data_forced'])) {
$table_structure = $tables;
$table_data = $tables;
}
if (isset($lock_tables)) {
$export->lockTables($db, $tables, "READ");
try {
$export->exportDatabase(
$db,
$tables,
$whatStrucOrData,
$table_structure,
$table_data,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
} finally {
$export->unlockTables();
}
} else {
$export->exportDatabase(
$db,
$tables,
$whatStrucOrData,
$table_structure,
$table_data,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
}
} else {
// We export just one table
// $allrows comes from the form when "Dump all rows" has been selected
if (! isset($allrows)) {
$allrows = '';
}
if (! isset($limit_to)) {
$limit_to = '0';
}
if (! isset($limit_from)) {
$limit_from = '0';
}
if (isset($lock_tables)) {
try {
$export->lockTables($db, [$table], "READ");
$export->exportTable(
$db,
$table,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$allrows,
$limit_to,
$limit_from,
$sql_query,
$aliases
);
} finally {
$export->unlockTables();
}
} else {
$export->exportTable(
$db,
$table,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$allrows,
$limit_to,
$limit_from,
$sql_query,
$aliases
);
}
}
if (! $export_plugin->exportFooter()) {
break;
}
} while (false);
// End of fake loop
if ($save_on_server && ! empty($message)) {
$export->showPage($db, $table, $export_type);
}
/**
* Send the dump as a file...
*/
if (empty($asfile)) {
echo $export->getHtmlForDisplayedExportFooter($back_button, $refreshButton);
return;
} // end if
// Convert the charset if required.
if ($output_charset_conversion) {
$dump_buffer = Encoding::convertString(
'utf-8',
$GLOBALS['charset'],
$dump_buffer
);
}
// Compression needed?
if ($compression) {
if (! empty($separate_files)) {
$dump_buffer = $export->compress(
$dump_buffer_objects,
$compression,
$filename
);
} else {
$dump_buffer = $export->compress($dump_buffer, $compression, $filename);
}
}
/* If we saved on server, we have to close file now */
if ($save_on_server) {
$message = $export->closeFile(
$file_handle,
$dump_buffer,
$save_filename
);
$export->showPage($db, $table, $export_type);
} else {
echo $dump_buffer;
}

View File

@ -1,139 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Editor for Geometry data types.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\Gis\GisFactory;
use PhpMyAdmin\Gis\GisVisualization;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Template $template */
$template = $containerBuilder->get('template');
if (! isset($_POST['field'])) {
Util::checkParameters(['field']);
}
// Get data if any posted
$gis_data = [];
if (Core::isValid($_POST['gis_data'], 'array')) {
$gis_data = $_POST['gis_data'];
}
$gis_types = [
'POINT',
'MULTIPOINT',
'LINESTRING',
'MULTILINESTRING',
'POLYGON',
'MULTIPOLYGON',
'GEOMETRYCOLLECTION',
];
// Extract type from the initial call and make sure that it's a valid one.
// Extract from field's values if available, if not use the column type passed.
if (! isset($gis_data['gis_type'])) {
if (isset($_POST['type']) && $_POST['type'] != '') {
$gis_data['gis_type'] = mb_strtoupper($_POST['type']);
}
if (isset($_POST['value']) && trim($_POST['value']) != '') {
$start = (substr($_POST['value'], 0, 1) == "'") ? 1 : 0;
$gis_data['gis_type'] = mb_substr(
$_POST['value'],
$start,
mb_strpos($_POST['value'], "(") - $start
);
}
if (! isset($gis_data['gis_type'])
|| (! in_array($gis_data['gis_type'], $gis_types))
) {
$gis_data['gis_type'] = $gis_types[0];
}
}
$geom_type = $gis_data['gis_type'];
// Generate parameters from value passed.
$gis_obj = GisFactory::factory($geom_type);
if (isset($_POST['value'])) {
$gis_data = array_merge(
$gis_data,
$gis_obj->generateParams($_POST['value'])
);
}
// Generate Well Known Text
$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '') ? $gis_data['srid'] : 0;
$wkt = $gis_obj->generateWkt($gis_data, 0);
$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0');
$result = "'" . $wkt . "'," . $srid;
// Generate SVG based visualization
$visualizationSettings = [
'width' => 450,
'height' => 300,
'spatialColumn' => 'wkt',
'mysqlVersion' => $GLOBALS['dbi']->getVersion(),
'isMariaDB' => $GLOBALS['dbi']->isMariaDB(),
];
$data = [
[
'wkt' => $wkt_with_zero,
'srid' => $srid,
],
];
$visualization = GisVisualization::getByData($data, $visualizationSettings)
->toImage('svg');
$open_layers = GisVisualization::getByData($data, $visualizationSettings)
->asOl();
// If the call is to update the WKT and visualization make an AJAX response
if (isset($_POST['generate']) && $_POST['generate'] == true) {
$extra_data = [
'result' => $result,
'visualization' => $visualization,
'openLayers' => $open_layers,
];
$response = Response::getInstance();
$response->addJSON($extra_data);
exit;
}
$geom_count = 1;
if ($geom_type == 'GEOMETRYCOLLECTION') {
$geom_count = isset($gis_data[$geom_type]['geom_count'])
? intval($gis_data[$geom_type]['geom_count']) : 1;
if (isset($gis_data[$geom_type]['add_geom'])) {
$geom_count++;
}
}
$templateOutput = $template->render('gis_data_editor_form', [
'width' => $visualizationSettings['width'],
'height' => $visualizationSettings['height'],
'pma_theme_image' => $GLOBALS['pmaThemeImage'],
'field' => $_POST['field'],
'input_name' => $_POST['input_name'],
'srid' => $srid,
'visualization' => $visualization,
'open_layers' => $open_layers,
'gis_types' => $gis_types,
'geom_type' => $geom_type,
'geom_count' => $geom_count,
'gis_data' => $gis_data,
'result' => $result,
]);
Response::getInstance()->addJSON('gis_editor', $templateOutput);

View File

@ -1,809 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Core script for import, this is just the glue around all other stuff
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Bookmark;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\File;
use PhpMyAdmin\Import;
use PhpMyAdmin\ParseAnalyze;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ImportPlugin;
use PhpMyAdmin\Response;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
define('PMA_ENABLE_LDI', 1);
}
global $db, $pmaThemeImage, $table;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var import $import */
$import = $containerBuilder->get('import');
if (isset($_POST['show_as_php'])) {
$GLOBALS['show_as_php'] = $_POST['show_as_php'];
}
// If there is a request to 'Simulate DML'.
if (isset($_POST['simulate_dml'])) {
$import->handleSimulateDmlRequest();
exit;
}
$sql = new Sql();
// If it's a refresh console bookmarks request
if (isset($_GET['console_bookmark_refresh'])) {
$response->addJSON(
'console_message_bookmark',
PhpMyAdmin\Console::getBookmarkContent()
);
exit;
}
// If it's a console bookmark add request
if (isset($_POST['console_bookmark_add'])) {
if (isset($_POST['label']) && isset($_POST['db'])
&& isset($_POST['bookmark_query']) && isset($_POST['shared'])
) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$bookmarkFields = [
'bkm_database' => $_POST['db'],
'bkm_user' => $cfgBookmark['user'],
'bkm_sql_query' => $_POST['bookmark_query'],
'bkm_label' => $_POST['label'],
];
$isShared = ($_POST['shared'] == 'true' ? true : false);
$bookmark = Bookmark::createBookmark(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$bookmarkFields,
$isShared
);
if ($bookmark !== false && $bookmark->save()) {
$response->addJSON('message', __('Succeeded'));
$response->addJSON('data', $bookmarkFields);
$response->addJSON('isShared', $isShared);
} else {
$response->addJSON('message', __('Failed'));
}
die();
} else {
$response->addJSON('message', __('Incomplete params'));
die();
}
}
$format = '';
/**
* Sets globals from $_POST
*/
$post_params = [
'charset_of_file',
'format',
'import_type',
'is_js_confirmed',
'MAX_FILE_SIZE',
'message_to_show',
'noplugin',
'skip_queries',
'local_import_file',
];
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
// reset import messages for ajax request
$_SESSION['Import_message']['message'] = null;
$_SESSION['Import_message']['go_back_url'] = null;
// default values
$GLOBALS['reload'] = false;
// Use to identify current cycle is executing
// a multiquery statement or stored routine
if (! isset($_SESSION['is_multi_query'])) {
$_SESSION['is_multi_query'] = false;
}
$ajax_reload = [];
$import_text = '';
// Are we just executing plain query or sql file?
// (eg. non import, but query box/window run)
if (! empty($sql_query)) {
// apply values for parameters
if (! empty($_POST['parameterized'])
&& ! empty($_POST['parameters'])
&& is_array($_POST['parameters'])
) {
$parameters = $_POST['parameters'];
foreach ($parameters as $parameter => $replacement) {
$quoted = preg_quote($parameter, '/');
// making sure that :param does not apply values to :param1
$sql_query = preg_replace(
'/' . $quoted . '([^a-zA-Z0-9_])/',
$dbi->escapeString($replacement) . '${1}',
$sql_query
);
// for parameters the appear at the end of the string
$sql_query = preg_replace(
'/' . $quoted . '$/',
$dbi->escapeString($replacement),
$sql_query
);
}
}
// run SQL query
$import_text = $sql_query;
$import_type = 'query';
$format = 'sql';
$_SESSION['sql_from_query_box'] = true;
// If there is a request to ROLLBACK when finished.
if (isset($_POST['rollback_query'])) {
$import->handleRollbackRequest($import_text);
}
// refresh navigation and main panels
if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) {
$GLOBALS['reload'] = true;
$ajax_reload['reload'] = true;
}
// refresh navigation panel only
if (preg_match(
'/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$sql_query
)) {
$ajax_reload['reload'] = true;
}
// do a dynamic reload if table is RENAMED
// (by sending the instruction to the AJAX response handler)
if (preg_match(
'/^RENAME\s+TABLE\s+(.*?)\s+TO\s+(.*?)($|;|\s)/i',
$sql_query,
$rename_table_names
)) {
$ajax_reload['reload'] = true;
$ajax_reload['table_name'] = PhpMyAdmin\Util::unQuote(
$rename_table_names[2]
);
}
$sql_query = '';
} elseif (! empty($sql_file)) {
// run uploaded SQL file
$import_file = $sql_file;
$import_type = 'queryfile';
$format = 'sql';
unset($sql_file);
} elseif (! empty($_POST['id_bookmark'])) {
// run bookmark
$import_type = 'query';
$format = 'sql';
}
// If we didn't get any parameters, either user called this directly, or
// upload limit has been reached, let's assume the second possibility.
if ($_POST == [] && $_GET == []) {
$message = PhpMyAdmin\Message::error(
__(
'You probably tried to upload a file that is too large. Please refer ' .
'to %sdocumentation%s for a workaround for this limit.'
)
);
$message->addParam('[doc@faq1-16]');
$message->addParam('[/doc]');
// so we can obtain the message
$_SESSION['Import_message']['message'] = $message->getDisplay();
$_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto'];
$response->setRequestStatus(false);
$response->addJSON('message', $message);
exit; // the footer is displayed automatically
}
// Add console message id to response output
if (isset($_POST['console_message_id'])) {
$response->addJSON('console_message_id', $_POST['console_message_id']);
}
/**
* Sets globals from $_POST patterns, for import plugins
* We only need to load the selected plugin
*/
if (! in_array(
$format,
[
'csv',
'ldi',
'mediawiki',
'ods',
'shp',
'sql',
'xml',
]
)
) {
// this should not happen for a normal user
// but only during an attack
Core::fatalError('Incorrect format parameter');
}
$post_patterns = [
'/^force_file_/',
'/^' . $format . '_/',
];
Core::setPostAsGlobal($post_patterns);
// Check needed parameters
PhpMyAdmin\Util::checkParameters(['import_type', 'format']);
// We don't want anything special in format
$format = Core::securePath($format);
if (strlen($table) > 0 && strlen($db) > 0) {
$urlparams = [
'db' => $db,
'table' => $table,
];
} elseif (strlen($db) > 0) {
$urlparams = ['db' => $db];
} else {
$urlparams = [];
}
// Create error and goto url
if ($import_type == 'table') {
$goto = 'tbl_import.php';
} elseif ($import_type == 'database') {
$goto = 'db_import.php';
} elseif ($import_type == 'server') {
$goto = 'server_import.php';
} elseif (empty($goto) || ! preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) {
if (strlen($table) > 0 && strlen($db) > 0) {
$goto = 'tbl_structure.php';
} elseif (strlen($db) > 0) {
$goto = 'db_structure.php';
} else {
$goto = 'server_sql.php';
}
}
$err_url = $goto . Url::getCommon($urlparams);
$_SESSION['Import_message']['go_back_url'] = $err_url;
// Avoid setting selflink to 'import.php'
// problem similar to bug 4276
if (basename($_SERVER['SCRIPT_NAME']) === 'import.php') {
$_SERVER['SCRIPT_NAME'] = $goto;
}
if (strlen($db) > 0) {
$dbi->selectDb($db);
}
Util::setTimeLimit();
if (! empty($cfg['MemoryLimit'])) {
ini_set('memory_limit', $cfg['MemoryLimit']);
}
$timestamp = time();
if (isset($_POST['allow_interrupt'])) {
$maximum_time = ini_get('max_execution_time');
} else {
$maximum_time = 0;
}
// set default values
$timeout_passed = false;
$error = false;
$read_multiply = 1;
$finished = false;
$offset = 0;
$max_sql_len = 0;
$file_to_unlink = '';
$sql_query = '';
$sql_query_disabled = false;
$go_sql = false;
$executed_queries = 0;
$run_query = true;
$charset_conversion = false;
$reset_charset = false;
$bookmark_created = false;
$result = false;
$msg = 'Sorry an unexpected error happened!';
// Bookmark Support: get a query back from bookmark if required
if (! empty($_POST['id_bookmark'])) {
$id_bookmark = (int) $_POST['id_bookmark'];
switch ($_POST['action_bookmark']) {
case 0: // bookmarked query that have to be run
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark,
'id',
isset($_POST['action_bookmark_all'])
);
if (! empty($_POST['bookmark_variable'])) {
$import_text = $bookmark->applyVariables(
$_POST['bookmark_variable']
);
} else {
$import_text = $bookmark->getQuery();
}
// refresh navigation and main panels
if (preg_match(
'/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$import_text
)) {
$GLOBALS['reload'] = true;
$ajax_reload['reload'] = true;
}
// refresh navigation panel only
if (preg_match(
'/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$import_text
)
) {
$ajax_reload['reload'] = true;
}
break;
case 1: // bookmarked query that have to be displayed
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark
);
$import_text = $bookmark->getQuery();
if ($response->isAjax()) {
$message = PhpMyAdmin\Message::success(__('Showing bookmark'));
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('sql_query', $import_text);
$response->addJSON('action_bookmark', $_POST['action_bookmark']);
exit;
} else {
$run_query = false;
}
break;
case 2: // bookmarked query that have to be deleted
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark
);
if (! empty($bookmark)) {
$bookmark->delete();
if ($response->isAjax()) {
$message = PhpMyAdmin\Message::success(
__('The bookmark has been deleted.')
);
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('action_bookmark', $_POST['action_bookmark']);
$response->addJSON('id_bookmark', $id_bookmark);
exit;
} else {
$run_query = false;
$error = true; // this is kind of hack to skip processing the query
}
}
break;
}
} // end bookmarks reading
// Do no run query if we show PHP code
if (isset($GLOBALS['show_as_php'])) {
$run_query = false;
$go_sql = true;
}
// We can not read all at once, otherwise we can run out of memory
$memory_limit = trim(ini_get('memory_limit'));
// 2 MB as default
if (empty($memory_limit)) {
$memory_limit = 2 * 1024 * 1024;
}
// In case no memory limit we work on 10MB chunks
if ($memory_limit == -1) {
$memory_limit = 10 * 1024 * 1024;
}
// Calculate value of the limit
$memoryUnit = mb_strtolower(substr((string) $memory_limit, -1));
if ('m' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024;
} elseif ('k' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024;
} elseif ('g' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024 * 1024;
} else {
$memory_limit = (int) $memory_limit;
}
// Just to be sure, there might be lot of memory needed for uncompression
$read_limit = $memory_limit / 8;
// handle filenames
if (isset($_FILES['import_file'])) {
$import_file = $_FILES['import_file']['tmp_name'];
$import_file_name = $_FILES['import_file']['name'];
}
if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
// sanitize $local_import_file as it comes from a POST
$local_import_file = Core::securePath($local_import_file);
$import_file = PhpMyAdmin\Util::userDir($cfg['UploadDir'])
. $local_import_file;
/*
* Do not allow symlinks to avoid security issues
* (user can create symlink to file he can not access,
* but phpMyAdmin can).
*/
if (@is_link($import_file)) {
$import_file = 'none';
}
} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
$import_file = 'none';
}
// Do we have file to import?
if ($import_file != 'none' && ! $error) {
/**
* Handle file compression
*/
$import_handle = new File($import_file);
$import_handle->checkUploadedFile();
if ($import_handle->isError()) {
$import->stop($import_handle->getError());
}
$import_handle->setDecompressContent(true);
$import_handle->open();
if ($import_handle->isError()) {
$import->stop($import_handle->getError());
}
} elseif (! $error) {
if (! isset($import_text) || empty($import_text)) {
$message = PhpMyAdmin\Message::error(
__(
'No data was received to import. Either no file name was ' .
'submitted, or the file size exceeded the maximum size permitted ' .
'by your PHP configuration. See [doc@faq1-16]FAQ 1.16[/doc].'
)
);
$import->stop($message);
}
}
// so we can obtain the message
//$_SESSION['Import_message'] = $message->getDisplay();
// Convert the file's charset if necessary
if (Encoding::isSupported() && isset($charset_of_file)) {
if ($charset_of_file != 'utf-8') {
$charset_conversion = true;
}
} elseif (isset($charset_of_file) && $charset_of_file != 'utf-8') {
$dbi->query('SET NAMES \'' . $charset_of_file . '\'');
// We can not show query in this case, it is in different charset
$sql_query_disabled = true;
$reset_charset = true;
}
// Something to skip? (because timeout has passed)
if (! $error && isset($_POST['skip'])) {
$original_skip = $skip = intval($_POST['skip']);
while ($skip > 0 && ! $finished) {
$import->getNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progressivity, otherwise we eat all memory!
$read_multiply = 1;
$skip -= $read_limit;
}
unset($skip);
}
// This array contain the data like numberof valid sql queries in the statement
// and complete valid sql statement (which affected for rows)
$sql_data = [
'valid_sql' => [],
'valid_queries' => 0,
];
if (! $error) {
/**
* @var ImportPlugin $import_plugin
*/
$import_plugin = Plugins::getPlugin(
"import",
$format,
'libraries/classes/Plugins/Import/',
$import_type
);
if ($import_plugin == null) {
$message = PhpMyAdmin\Message::error(
__('Could not load import plugins, please check your installation!')
);
$import->stop($message);
} else {
// Do the real import
$default_fk_check = PhpMyAdmin\Util::handleDisableFKCheckInit();
try {
$import_plugin->doImport($sql_data);
PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check);
} catch (Exception $e) {
PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check);
throw $e;
}
}
}
if (isset($import_handle)) {
$import_handle->close();
}
// Cleanup temporary file
if ($file_to_unlink != '') {
unlink($file_to_unlink);
}
// Reset charset back, if we did some changes
if ($reset_charset) {
$dbi->query('SET CHARACTER SET ' . $GLOBALS['charset_connection']);
$dbi->setCollation($collation_connection);
}
// Show correct message
if (! empty($id_bookmark) && $_POST['action_bookmark'] == 2) {
$message = PhpMyAdmin\Message::success(__('The bookmark has been deleted.'));
$display_query = $import_text;
$error = false; // unset error marker, it was used just to skip processing
} elseif (! empty($id_bookmark) && $_POST['action_bookmark'] == 1) {
$message = PhpMyAdmin\Message::notice(__('Showing bookmark'));
} elseif ($bookmark_created) {
$special_message = '[br]' . sprintf(
__('Bookmark %s has been created.'),
htmlspecialchars($_POST['bkm_label'])
);
} elseif ($finished && ! $error) {
// Do not display the query with message, we do it separately
$display_query = ';';
if ($import_type != 'query') {
$message = PhpMyAdmin\Message::success(
'<em>'
. _ngettext(
'Import has been successfully finished, %d query executed.',
'Import has been successfully finished, %d queries executed.',
$executed_queries
)
. '</em>'
);
$message->addParam($executed_queries);
if (! empty($import_notice)) {
$message->addHtml($import_notice);
}
if (! empty($local_import_file)) {
$message->addText('(' . $local_import_file . ')');
} else {
$message->addText('(' . $_FILES['import_file']['name'] . ')');
}
}
}
// Did we hit timeout? Tell it user.
if ($timeout_passed) {
$urlparams['timeout_passed'] = '1';
$urlparams['offset'] = $GLOBALS['offset'];
if (isset($local_import_file)) {
$urlparams['local_import_file'] = $local_import_file;
}
$importUrl = $err_url = $goto . Url::getCommon($urlparams);
$message = PhpMyAdmin\Message::error(
__(
'Script timeout passed, if you want to finish import,'
. ' please %sresubmit the same file%s and import will resume.'
)
);
$message->addParamHtml('<a href="' . $importUrl . '">');
$message->addParamHtml('</a>');
if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) {
$message->addText(
__(
'However on last run no data has been parsed,'
. ' this usually means phpMyAdmin won\'t be able to'
. ' finish this import unless you increase php time limits.'
)
);
}
}
// if there is any message, copy it into $_SESSION as well,
// so we can obtain it by AJAX call
if (isset($message)) {
$_SESSION['Import_message']['message'] = $message->getDisplay();
}
// Parse and analyze the query, for correct db and table name
// in case of a query typed in the query window
// (but if the query is too large, in case of an imported file, the parser
// can choke on it so avoid parsing)
$sqlLength = mb_strlen($sql_query);
if ($sqlLength <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
list(
$analyzed_sql_results,
$db,
$table_from_sql
) = ParseAnalyze::sqlQuery($sql_query, $db);
// @todo: possibly refactor
extract($analyzed_sql_results);
if ($table != $table_from_sql && ! empty($table_from_sql)) {
$table = $table_from_sql;
}
}
// There was an error?
if (isset($my_die)) {
foreach ($my_die as $key => $die) {
PhpMyAdmin\Util::mysqlDie(
$die['error'],
$die['sql'],
false,
$err_url,
$error
);
}
}
if ($go_sql) {
if (! empty($sql_data) && ($sql_data['valid_queries'] > 1)) {
$_SESSION['is_multi_query'] = true;
$sql_queries = $sql_data['valid_sql'];
} else {
$sql_queries = [$sql_query];
}
$html_output = '';
foreach ($sql_queries as $sql_query) {
// parse sql query
list(
$analyzed_sql_results,
$db,
$table_from_sql
) = ParseAnalyze::sqlQuery($sql_query, $db);
// @todo: possibly refactor
extract($analyzed_sql_results);
// Check if User is allowed to issue a 'DROP DATABASE' Statement
if ($sql->hasNoRightsToDropDatabase(
$analyzed_sql_results,
$cfg['AllowUserDropDatabase'],
$dbi->isSuperuser()
)) {
PhpMyAdmin\Util::mysqlDie(
__('"DROP DATABASE" statements are disabled.'),
'',
false,
$_SESSION['Import_message']['go_back_url']
);
return;
} // end if
if ($table != $table_from_sql && ! empty($table_from_sql)) {
$table = $table_from_sql;
}
$html_output .= $sql->executeQueryAndGetQueryResponse(
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark - see below
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
// sql_query_for_bookmark is not included in Sql::executeQueryAndGetQueryResponse
// since only one bookmark has to be added for all the queries submitted through
// the SQL tab
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$sql->storeTheQueryAsBookmark(
$db,
$cfgBookmark['user'],
$_POST['sql_query'],
$_POST['bkm_label'],
isset($_POST['bkm_replace'])
);
}
$response->addJSON('ajax_reload', $ajax_reload);
$response->addHTML($html_output);
exit;
} elseif ($result) {
// Save a Bookmark with more than one queries (if Bookmark label given).
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$sql->storeTheQueryAsBookmark(
$db,
$cfgBookmark['user'],
$_POST['sql_query'],
$_POST['bkm_label'],
isset($_POST['bkm_replace'])
);
}
$response->setRequestStatus(true);
$response->addJSON('message', PhpMyAdmin\Message::success($msg));
$response->addJSON(
'sql_query',
PhpMyAdmin\Util::getMessage($msg, $sql_query, 'success')
);
} elseif ($result === false) {
$response->setRequestStatus(false);
$response->addJSON('message', PhpMyAdmin\Message::error($msg));
} else {
$active_page = $goto;
include ROOT_PATH . $goto;
}
// If there is request for ROLLBACK in the end.
if (isset($_POST['rollback_query'])) {
$dbi->query('ROLLBACK');
}

View File

@ -1,129 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Import progress bar backend
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\Display\ImportAjax;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/* PHP 5.4 stores upload progress data only in the default session.
* After calling session_name(), we won't find the progress data anymore.
*
* https://bugs.php.net/bug.php?id=64075
*
* The bug should be somewhere in
* https://github.com/php/php-src/blob/master/ext/session/session.c#L2342
*
* Until this is fixed, we need to load the default session to load the data,
* export the upload progress information from there,
* and re-import after switching to our session.
*
* However, since https://github.com/phpmyadmin/phpmyadmin/commit/063a2d99
* we have deactivated this feature, so the corresponding code is now
* commented out.
*/
/*
if (ini_get('session.upload_progress.enabled')) {
$sessionupload = array();
define('UPLOAD_PREFIX', ini_get('session.upload_progress.prefix'));
session_start();
foreach ($_SESSION as $key => $value) {
// only copy session-prefixed data
if (substr($key, 0, strlen(UPLOAD_PREFIX))
== UPLOAD_PREFIX) {
$sessionupload[$key] = $value;
}
}
// PMA will kill all variables, so let's use a constant
define('SESSIONUPLOAD', serialize($sessionupload));
session_write_close();
// The cookie name is not good anymore since PR #15273
session_name('phpMyAdmin');
session_id($_COOKIE['phpMyAdmin']);
}
*/
define('PMA_MINIMUM_COMMON', 1);
require_once ROOT_PATH . 'libraries/common.inc.php';
list(
$SESSION_KEY,
$upload_id,
$plugins
) = ImportAjax::uploadProgressSetup();
/*
if (defined('SESSIONUPLOAD')) {
// write sessionupload back into the loaded PMA session
$sessionupload = unserialize(SESSIONUPLOAD);
foreach ($sessionupload as $key => $value) {
$_SESSION[$key] = $value;
}
// remove session upload data that are not set anymore
foreach ($_SESSION as $key => $value) {
if (substr($key, 0, strlen(UPLOAD_PREFIX))
== UPLOAD_PREFIX
&& ! isset($sessionupload[$key])
) {
unset($_SESSION[$key]);
}
}
}
*/
// $_GET["message"] is used for asking for an import message
if (isset($_GET["message"]) && $_GET["message"]) {
// AJAX requests can't be cached!
Core::noCacheHeader();
header('Content-type: text/html');
// wait 0.3 sec before we check for $_SESSION variable,
// which is set inside import.php
usleep(300000);
$maximumTime = ini_get('max_execution_time');
$timestamp = time();
// wait until message is available
while ($_SESSION['Import_message']['message'] == null) {
// close session before sleeping
session_write_close();
// sleep
usleep(250000); // 0.25 sec
// reopen session
session_start();
if ((time() - $timestamp) > $maximumTime) {
$_SESSION['Import_message']['message'] = PhpMyAdmin\Message::error(
__('Could not load the progress of the import.')
)->getDisplay();
break;
}
}
if (isset($_SESSION['Import_message']['message'])) {
echo $_SESSION['Import_message']['message'];
}
if (isset($_SESSION['Import_message']['go_back_url'])) {
echo '<fieldset class="tblFooters">' , "\n";
echo ' [ <a href="' , $_SESSION['Import_message']['go_back_url']
. '">' , __('Back') , '</a> ]' , "\n";
echo '</fieldset>' , "\n";
}
} else {
ImportAjax::status($_GET["id"]);
}

View File

@ -1,120 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Main loader script
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\HomeController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $server;
require_once ROOT_PATH . 'libraries/common.inc.php';
/**
* pass variables to child pages
*/
$drops = [
'lang',
'server',
'collation_connection',
'db',
'table',
];
foreach ($drops as $each_drop) {
if (array_key_exists($each_drop, $_GET)) {
unset($_GET[$each_drop]);
}
}
unset($drops, $each_drop);
/**
* Black list of all scripts to which front-end must submit data.
* Such scripts must not be loaded on home page.
*/
$target_blacklist = [
'import.php',
'export.php',
];
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& 0 !== strpos($_REQUEST['target'], "index")
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'], [], true)
) {
include ROOT_PATH . $_REQUEST['target'];
exit;
}
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var HomeController $controller */
$controller = $containerBuilder->get(HomeController::class);
if (isset($_REQUEST['ajax_request']) && ! empty($_REQUEST['access_time'])) {
exit;
}
if (isset($_POST['set_theme'])) {
$controller->setTheme([
'set_theme' => $_POST['set_theme'],
]);
header('Location: index.php' . Url::getCommonRaw());
} elseif (isset($_POST['collation_connection'])) {
$controller->setCollationConnection([
'collation_connection' => $_POST['collation_connection'],
]);
header('Location: index.php' . Url::getCommonRaw());
} elseif (! empty($_REQUEST['db'])) {
// See FAQ 1.34
$page = null;
if (! empty($_REQUEST['table'])) {
$page = Util::getScriptNameForOption(
$GLOBALS['cfg']['DefaultTabTable'],
'table'
);
} else {
$page = Util::getScriptNameForOption(
$GLOBALS['cfg']['DefaultTabDatabase'],
'database'
);
}
include ROOT_PATH . $page;
} elseif ($response->isAjax() && ! empty($_REQUEST['recent_table'])) {
$response->addJSON($controller->reloadRecentTablesList());
} elseif ($GLOBALS['PMA_Config']->isGitRevision()
&& isset($_REQUEST['git_revision'])
&& $response->isAjax()
) {
$response->addHTML($controller->gitRevision());
} else {
// Handles some variables that may have been sent by the calling script
$GLOBALS['db'] = '';
$GLOBALS['table'] = '';
$show_query = '1';
if ($server > 0) {
include ROOT_PATH . 'libraries/server_common.inc.php';
}
$response->addHTML($controller->index());
}

View File

@ -1,973 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* global isStorageSupported */ // js/config.js
/* global ErrorReport */ // js/error_report.js
/* global MicroHistory */ // js/microhistory.js
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
*/
var AJAX = {
/**
* @var bool active Whether we are busy
*/
active: false,
/**
* @var object source The object whose event initialized the request
*/
source: null,
/**
* @var object xhr A reference to the ajax request that is currently running
*/
xhr: null,
/**
* @var object lockedTargets, list of locked targets
*/
lockedTargets: {},
/**
* @var function Callback to execute after a successful request
* Used by PMA_commonFunctions from common.js
*/
callback: function () {},
/**
* @var bool debug Makes noise in your Firebug console
*/
debug: false,
/**
* @var object $msgbox A reference to a jQuery object that links to a message
* box that is generated by Functions.ajaxShowMessage()
*/
$msgbox: null,
/**
* Given the filename of a script, returns a hash to be
* used to refer to all the events registered for the file
*
* @param key string key The filename for which to get the event name
*
* @return int
*/
hash: function (key) {
var newKey = key;
/* http://burtleburtle.net/bob/hash/doobs.html#one */
newKey += '';
var len = newKey.length;
var hash = 0;
var i = 0;
for (; i < len; ++i) {
hash += newKey.charCodeAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return Math.abs(hash);
},
/**
* Registers an onload event for a file
*
* @param file string file The filename for which to register the event
* @param func function func The function to execute when the page is ready
*
* @return self For chaining
*/
registerOnload: function (file, func) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Registers a teardown event for a file. This is useful to execute functions
* that unbind events for page elements that are about to be removed.
*
* @param string file The filename for which to register the event
* @param function func The function to execute when
* the page is about to be torn down
*
* @return self For chaining
*/
registerTeardown: function (file, func) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Called when a page has finished loading, once for every
* file that registered to the onload event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireOnload: function (file) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).trigger(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* Called just before a page is torn down, once for every
* file that registered to the teardown event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireTeardown: function (file) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).triggerHandler(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* function to handle lock page mechanism
*
* @param event the event object
*
* @return void
*/
lockPageHandler: function (event) {
// don't consider checkbox event
if (typeof event.target !== 'undefined') {
if (event.target.type === 'checkbox') {
return;
}
}
var newHash = null;
var oldHash = null;
var lockId;
// CodeMirror lock
if (event.data.value === 3) {
newHash = event.data.content;
oldHash = true;
lockId = 'cm';
} else {
// Don't lock on enter.
if (0 === event.charCode) {
return;
}
lockId = $(this).data('lock-id');
if (typeof lockId === 'undefined') {
return;
}
/*
* @todo Fix Code mirror does not give correct full value (query)
* in textarea, it returns only the change in content.
*/
if (event.data.value === 1) {
newHash = AJAX.hash($(this).val());
} else {
newHash = AJAX.hash($(this).is(':checked'));
}
oldHash = $(this).data('val-hash');
}
// Set lock if old value !== new value
// otherwise release lock
if (oldHash !== newHash) {
AJAX.lockedTargets[lockId] = true;
} else {
delete AJAX.lockedTargets[lockId];
}
// Show lock icon if locked targets is not empty.
// otherwise remove lock icon
if (!jQuery.isEmptyObject(AJAX.lockedTargets)) {
$('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString());
} else {
$('#lock_page_icon').html('');
}
},
/**
* resets the lock
*
* @return void
*/
resetLock: function () {
AJAX.lockedTargets = {};
$('#lock_page_icon').html('');
},
handleMenu: {
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(Functions.mainMenuResizerCallback);
}
},
/**
* Event handler for clicks on links and form submissions
*
* @param object e Event data
*
* @return void
*/
requestHandler: function (event) {
// In some cases we don't want to handle the request here and either
// leave the browser deal with it natively (e.g: file download)
// or leave an existing ajax event handler present elsewhere deal with it
var href = $(this).attr('href');
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey)) {
return true;
} else if ($(this).attr('target')) {
return true;
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
// reset the lockedTargets object, as specified AJAX operation has finished
AJAX.resetLock();
return true;
} else if (href && href.match(/^#/)) {
return true;
} else if (href && href.match(/^mailto/)) {
return true;
} else if ($(this).hasClass('ui-datepicker-next') ||
$(this).hasClass('ui-datepicker-prev')
) {
return true;
}
if (typeof event !== 'undefined') {
event.preventDefault();
event.stopImmediatePropagation();
}
// triggers a confirm dialog if:
// the user has performed some operations on loaded page
// the user clicks on some link, (won't trigger for buttons)
// the click event is not triggered by script
if (typeof event !== 'undefined' && event.type === 'click' &&
event.isTrigger !== true &&
!jQuery.isEmptyObject(AJAX.lockedTargets)
) {
if (confirm(Messages.strConfirmNavigation) === false) {
return false;
} else {
if (isStorageSupported('localStorage')) {
window.localStorage.removeItem('autoSavedSql');
} else {
Cookies.set('autoSavedSql', '');
}
}
}
AJAX.resetLock();
var isLink = !! href || false;
var previousLinkAborted = false;
if (AJAX.active === true) {
// Cancel the old request if abortable, when the user requests
// something else. Otherwise silently bail out, as there is already
// a request well in progress.
if (AJAX.xhr) {
// In case of a link request, attempt aborting
AJAX.xhr.abort();
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
// If aborted
AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest);
AJAX.active = false;
AJAX.xhr = null;
previousLinkAborted = true;
} else {
// If can't abort
return false;
}
} else {
// In case submitting a form, don't attempt aborting
return false;
}
}
AJAX.source = $(this);
$('html, body').animate({ scrollTop: 0 }, 'fast');
var url = isLink ? href : $(this).attr('action');
var argsep = CommonParams.get('arg_separator');
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
var dataPost = AJAX.source.getPostData();
if (! isLink) {
params += argsep + $(this).serialize();
} else if (dataPost) {
params += argsep + dataPost;
isLink = false;
}
if (! (history && history.pushState)) {
// Add a list of menu hashes that we have in the cache to the request
params += MicroHistory.menus.getRequestParam();
}
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('Loading: ' + url); // no need to translate
}
if (isLink) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
// Save reference for the new link request
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
if (history && history.pushState) {
var state = {
url : href
};
if (previousLinkAborted) {
// hack: there is already an aborted entry on stack
// so just modify the aborted one
history.replaceState(state, null, href);
} else {
history.pushState(state, null, href);
}
}
} else {
/**
* Manually fire the onsubmit event for the form, if any.
* The event was saved in the jQuery data object by an onload
* handler defined below. Workaround for bug #3583316
*/
var onsubmit = $(this).data('onsubmit');
// Submit the request if there is no onsubmit handler
// or if it returns a value that evaluates to true
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
if ($(this).attr('id') === 'login_form') {
$.post(url, params, AJAX.loginResponseHandler);
} else {
$.post(url, params, AJAX.responseHandler);
}
}
}
},
/**
* Response handler to handle login request from login modal after session expiration
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param object data Event data
*
* @return void
*/
loginResponseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
Functions.ajaxRemoveMessage(AJAX.$msgbox);
CommonParams.set('token', data.new_token);
AJAX.scriptHandler.load([]);
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof data.success !== 'undefined' && data.success) {
// reload page if user trying to login has changed
if (CommonParams.get('user') !== data.params.user) {
window.location = 'index.php';
Functions.ajaxShowMessage(Messages.strLoading, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
// remove the login modal if the login is successful otherwise show error.
if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) {
if ($('#modalOverlay').length) {
$('#modalOverlay').remove();
}
$('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration');
AJAX.fireTeardown('functions.js');
AJAX.fireOnload('functions.js');
}
if (typeof data.new_token !== 'undefined') {
$('input[name=token]').val(data.new_token);
}
} else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) {
$('#modalOverlay').replaceWith(data.error);
} else {
Functions.ajaxShowMessage(data.error, false);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* Called after the request that was initiated by this.requestHandler()
* has completed successfully or with a caught error. For completely
* failed requests or requests with uncaught errors, see the .ajaxError
* handler at the bottom of this file.
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param object e Event data
*
* @return void
*/
responseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
if (typeof data.success !== 'undefined' && data.success) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
Functions.ajaxRemoveMessage(AJAX.$msgbox);
if (data.redirect) {
Functions.ajaxShowMessage(data.redirect, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
AJAX.scriptHandler.reset(function () {
if (data.reloadNavigation) {
Navigation.reload();
}
if (data.title) {
$('title').replaceWith(data.title);
}
if (data.menu) {
if (history && history.pushState) {
var state = {
url : data.selflink,
menu : data.menu
};
history.replaceState(state, null);
AJAX.handleMenu.replace(data.menu);
} else {
MicroHistory.menus.replace(data.menu);
MicroHistory.menus.add(data.menuHash, data.menu);
}
} else if (data.menuHash) {
if (! (history && history.pushState)) {
MicroHistory.menus.replace(MicroHistory.menus.get(data.menuHash));
}
}
if (data.disableNaviSettings) {
Navigation.disableSettings();
} else {
Navigation.ensureSettings(data.selflink);
}
// Remove all containers that may have
// been added outside of #page_content
$('body').children()
.not('#pma_navigation')
.not('#floating_menubar')
.not('#page_nav_icons')
.not('#page_content')
.not('#selflink')
.not('#pma_header')
.not('#pma_footer')
.not('#pma_demo')
.not('#pma_console_container')
.not('#prefs_autoload')
.remove();
// Replace #page_content with new content
if (data.message && data.message.length > 0) {
$('#page_content').replaceWith(
'<div id=\'page_content\'>' + data.message + '</div>'
);
Functions.highlightSql($('#page_content'));
Functions.checkNumberOfFields();
}
if (data.selflink) {
var source = data.selflink.split('?')[0];
// Check for faulty links
var $selflinkReplace = {
'import.php': 'tbl_sql.php',
'tbl_chart.php': 'sql.php',
'tbl_gis_visualization.php': 'sql.php'
};
if ($selflinkReplace[source]) {
var replacement = $selflinkReplace[source];
data.selflink = data.selflink.replace(source, replacement);
}
$('#selflink').find('> a').attr('href', data.selflink);
}
if (data.params) {
CommonParams.setAll(data.params);
}
if (data.scripts) {
AJAX.scriptHandler.load(data.scripts);
}
if (data.selflink && data.scripts && data.menuHash && data.params) {
if (! (history && history.pushState)) {
MicroHistory.add(
data.selflink,
data.scripts,
data.menuHash,
data.params,
AJAX.source.attr('rel')
);
}
}
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof AJAX.callback === 'function') {
AJAX.callback.call();
}
AJAX.callback = function () {};
});
} else {
Functions.ajaxShowMessage(data.error, false);
Functions.ajaxRemoveMessage(AJAX.$msgbox);
var $ajaxError = $('<div></div>');
$ajaxError.attr({ 'id': 'ajaxError' });
$('#page_content').append($ajaxError);
$ajaxError.html(data.error);
$('html, body').animate({ scrollTop: $(document).height() }, 200);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* This object is in charge of downloading scripts,
* keeping track of what's downloaded and firing
* the onload event for them when the page is ready.
*/
scriptHandler: {
/**
* @var array scripts The list of files already downloaded
*/
scripts: [],
/**
* @var string scriptsVersion version of phpMyAdmin from which the
* scripts have been loaded
*/
scriptsVersion: null,
/**
* @var array scriptsToBeLoaded The list of files that
* need to be downloaded
*/
scriptsToBeLoaded: [],
/**
* @var array scriptsToBeFired The list of files for which
* to fire the onload and unload events
*/
scriptsToBeFired: [],
scriptsCompleted: false,
/**
* Records that a file has been downloaded
*
* @param string file The filename
* @param string fire Whether this file will be registering
* onload/teardown events
*
* @return self For chaining
*/
add: function (file, fire) {
this.scripts.push(file);
if (fire) {
// Record whether to fire any events for the file
// This is necessary to correctly tear down the initial page
this.scriptsToBeFired.push(file);
}
return this;
},
/**
* Download a list of js files in one request
*
* @param array files An array of filenames and flags
*
* @return void
*/
load: function (files, callback) {
var self = this;
var i;
// Clear loaded scripts if they are from another version of phpMyAdmin.
// Depends on common params being set before loading scripts in responseHandler
if (self.scriptsVersion === null) {
self.scriptsVersion = CommonParams.get('PMA_VERSION');
} else if (self.scriptsVersion !== CommonParams.get('PMA_VERSION')) {
self.scripts = [];
self.scriptsVersion = CommonParams.get('PMA_VERSION');
}
self.scriptsCompleted = false;
self.scriptsToBeFired = [];
// We need to first complete list of files to load
// as next loop will directly fire requests to load them
// and that triggers removal of them from
// self.scriptsToBeLoaded
for (i in files) {
self.scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
self.scriptsToBeFired.push(files[i].name);
}
}
for (i in files) {
var script = files[i].name;
// Only for scripts that we don't already have
if ($.inArray(script, self.scripts) === -1) {
this.add(script);
this.appendScript(script, callback);
} else {
self.done(script, callback);
}
}
// Trigger callback if there is nothing else to load
self.done(null, callback);
},
/**
* Called whenever all files are loaded
*
* @return void
*/
done: function (script, callback) {
if (typeof ErrorReport !== 'undefined') {
ErrorReport.wrapGlobalFunctions();
}
if ($.inArray(script, this.scriptsToBeFired)) {
AJAX.fireOnload(script);
}
if ($.inArray(script, this.scriptsToBeLoaded)) {
this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1);
}
if (script === null) {
this.scriptsCompleted = true;
}
/* We need to wait for last signal (with null) or last script load */
AJAX.active = (this.scriptsToBeLoaded.length > 0) || ! this.scriptsCompleted;
/* Run callback on last script */
if (! AJAX.active && typeof callback === 'function') {
callback();
}
},
/**
* Appends a script element to the head to load the scripts
*
* @return void
*/
appendScript: function (name, callback) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var self = this;
script.type = 'text/javascript';
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(CommonParams.get('PMA_VERSION'));
script.async = false;
script.onload = function () {
self.done(name, callback);
};
head.appendChild(script);
},
/**
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param function callback The callback to call after resetting
*
* @return void
*/
reset: function (callback) {
for (var i in this.scriptsToBeFired) {
AJAX.fireTeardown(this.scriptsToBeFired[i]);
}
this.scriptsToBeFired = [];
/**
* Re-attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
if (! (history && history.pushState)) {
MicroHistory.update();
}
callback();
}
}
};
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
AJAX.registerOnload('functions.js', function () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $pageContent = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$pageContent.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input>', {
'type' : 'hidden',
'name' : buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$pageContent.on(
'keyup change',
'form.lock-page textarea, ' +
'form.lock-page input[type="text"], ' +
'form.lock-page input[type="number"], ' +
'form.lock-page select',
{ value:1 },
AJAX.lockPageHandler
);
$pageContent.on(
'change',
'form.lock-page input[type="checkbox"], ' +
'form.lock-page input[type="radio"]',
{ value:2 },
AJAX.lockPageHandler
);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function () {
AJAX.resetLock();
});
});
/**
* Page load event handler
*/
$(function () {
var menuContent = $('<div></div>')
.append($('#serverinfo').clone())
.append($('#topmenucontainer').clone())
.html();
if (history && history.pushState) {
// set initial state reload
var initState = ('state' in window.history && window.history.state !== null);
var initURL = $('#selflink').find('> a').attr('href') || location.href;
var state = {
url : initURL,
menu : menuContent
};
history.replaceState(state, null);
$(window).on('popstate', function (event) {
var initPop = (! initState && location.href === initURL);
initState = true;
// check if popstate fired on first page itself
if (initPop) {
return;
}
var state = event.originalEvent.state;
if (state && state.menu) {
AJAX.$msgbox = Functions.ajaxShowMessage();
var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true';
var url = state.url || location.href;
$.get(url, params, AJAX.responseHandler);
// TODO: Check if sometimes menu is not retrieved from server,
// Not sure but it seems menu was missing only for printview which
// been removed lately, so if it's right some dead menu checks/fallbacks
// may need to be removed from this file and Header.php
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
}
});
} else {
// Fallback to microhistory mechanism
AJAX.scriptHandler
.load([{ 'name' : 'microhistory.js', 'fire' : 1 }], function () {
// The cache primer is set by the footer class
if (MicroHistory.primer.url) {
MicroHistory.menus.add(
MicroHistory.primer.menuHash,
menuContent
);
}
$(function () {
// Queue up this event twice to make sure that we get a copy
// of the page after all other onload events have been fired
if (MicroHistory.primer.url) {
MicroHistory.add(
MicroHistory.primer.url,
MicroHistory.primer.scripts,
MicroHistory.primer.menuHash
);
}
});
});
}
});
/**
* Attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).on('click', 'a', AJAX.requestHandler);
$(document).on('submit', 'form', AJAX.requestHandler);
/**
* Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).ajaxError(function (event, request) {
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + Functions.escapeHtml(Messages.strErrorConnection) + '</div>';
}
Functions.ajaxShowMessage(
'<div class="error">' +
Messages.strErrorProcessingRequest +
details +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
}
});

View File

@ -1,677 +0,0 @@
/**
* Chart type enumerations
*/
var ChartType = {
LINE : 'line',
SPLINE : 'spline',
AREA : 'area',
BAR : 'bar',
COLUMN : 'column',
PIE : 'pie',
TIMELINE: 'timeline',
SCATTER: 'scatter'
};
/**
* Column type enumeration
*/
var ColumnType = {
STRING : 'string',
NUMBER : 'number',
BOOLEAN : 'boolean',
DATE : 'date'
};
/**
* Abstract chart factory which defines the contract for chart factories
*/
var ChartFactory = function () {
};
ChartFactory.prototype = {
createChart : function () {
throw new Error('createChart must be implemented by a subclass');
}
};
/**
* Abstract chart which defines the contract for charts
*
* @param elementId
* id of the div element the chart is drawn in
*/
var Chart = function (elementId) {
this.elementId = elementId;
};
Chart.prototype = {
draw : function () {
throw new Error('draw must be implemented by a subclass');
},
redraw : function () {
throw new Error('redraw must be implemented by a subclass');
},
destroy : function () {
throw new Error('destroy must be implemented by a subclass');
},
toImageString : function () {
throw new Error('toImageString must be implemented by a subclass');
}
};
/**
* Abstract representation of charts that operates on DataTable where,<br>
* <ul>
* <li>First column provides index to the data.</li>
* <li>Each subsequent columns are of type
* <code>ColumnType.NUMBER<code> and represents a data series.</li>
* </ul>
* Line chart, area chart, bar chart, column chart are typical examples.
*
* @param elementId
* id of the div element the chart is drawn in
*/
var BaseChart = function (elementId) {
Chart.call(this, elementId);
};
BaseChart.prototype = new Chart();
BaseChart.prototype.constructor = BaseChart;
BaseChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length < 2) {
throw new Error('Minimum of two columns are required for this chart');
}
for (var i = 1; i < columns.length; i++) {
if (columns[i].type !== ColumnType.NUMBER) {
throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
}
}
return true;
};
/**
* Abstract pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var PieChart = function (elementId) {
BaseChart.call(this, elementId);
};
PieChart.prototype = new BaseChart();
PieChart.prototype.constructor = PieChart;
PieChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length > 2) {
throw new Error('Pie charts can draw only one series');
}
return BaseChart.prototype.validateColumns.call(this, dataTable);
};
/**
* Abstract timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var TimelineChart = function (elementId) {
BaseChart.call(this, elementId);
};
TimelineChart.prototype = new BaseChart();
TimelineChart.prototype.constructor = TimelineChart;
TimelineChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.DATE) {
throw new Error('First column of timeline chart need to be a date column');
}
}
return result;
};
/**
* Abstract scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var ScatterChart = function (elementId) {
BaseChart.call(this, elementId);
};
ScatterChart.prototype = new BaseChart();
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.NUMBER) {
throw new Error('First column of scatter chart need to be a numeric column');
}
}
return result;
};
/**
* The data table contains column information and data for the chart.
*/
// eslint-disable-next-line no-unused-vars
var DataTable = function () {
var columns = [];
var data = null;
this.addColumn = function (type, name) {
columns.push({
'type' : type,
'name' : name
});
};
this.getColumns = function () {
return columns;
};
this.setData = function (rows) {
data = rows;
fillMissingValues();
};
this.getData = function () {
return data;
};
var fillMissingValues = function () {
if (columns.length === 0) {
throw new Error('Set columns first');
}
var row;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row.length > columns.length) {
row.splice(columns.length - 1, row.length - columns.length);
} else if (row.length < columns.length) {
for (var j = row.length; j < columns.length; j++) {
row.push(null);
}
}
}
};
};
/** *****************************************************************************
* JQPlot specific code
******************************************************************************/
/**
* Abstract JQplot chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotChart = function (elementId) {
Chart.call(this, elementId);
this.plot = null;
this.validator = null;
};
JQPlotChart.prototype = new Chart();
JQPlotChart.prototype.constructor = JQPlotChart;
JQPlotChart.prototype.draw = function (data, options) {
if (this.validator.validateColumns(data)) {
this.plot = $.jqplot(this.elementId, this.prepareData(data), this
.populateOptions(data, options));
}
};
JQPlotChart.prototype.destroy = function () {
if (this.plot !== null) {
this.plot.destroy();
}
};
JQPlotChart.prototype.redraw = function (options) {
if (this.plot !== null) {
this.plot.replot(options);
}
};
JQPlotChart.prototype.toImageString = function () {
if (this.plot !== null) {
return $('#' + this.elementId).jqplotToImageStr({});
}
};
JQPlotChart.prototype.populateOptions = function () {
throw new Error('populateOptions must be implemented by a subclass');
};
JQPlotChart.prototype.prepareData = function () {
throw new Error('prepareData must be implemented by a subclass');
};
/**
* JQPlot line chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotLineChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = BaseChart.prototype;
};
JQPlotLineChart.prototype = new JQPlotChart();
JQPlotLineChart.prototype.constructor = JQPlotLineChart;
JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
formatString:'%d'
},
series : []
};
$.extend(true, optional, options);
if (optional.series.length === 0) {
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
}
if (optional.axes.xaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var j = 0; j < data.length; j++) {
optional.axes.xaxis.ticks.push(data[j][0].toString());
}
}
return optional;
};
JQPlotLineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push(row[j]);
}
}
return retData;
};
/**
* JQPlot spline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotSplineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotSplineChart.prototype = new JQPlotLineChart();
JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
rendererOptions : {
smooth : true
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotScatterChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = ScatterChart.prototype;
};
JQPlotScatterChart.prototype = new JQPlotChart();
JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%d, %d'
},
series : []
};
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
var compulsory = {
seriesDefaults : {
showLine: false,
markerOptions: {
size: 7,
style: 'x'
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotScatterChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row[0]) {
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push([row[0], row[j]]);
}
}
}
return retData;
};
/**
* JQPlot timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotTimelineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
this.validator = TimelineChart.prototype;
};
JQPlotTimelineChart.prototype = new JQPlotLineChart();
JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
axes : {
xaxis : {
tickOptions : {
formatString: '%b %#d, %y'
}
}
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var d;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
d = row[0];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
if (d !== null) {
retRow.push([d.getTime(), row[j]]);
}
}
}
return retData;
};
/**
* JQPlot area chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotAreaChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotAreaChart.prototype = new JQPlotLineChart();
JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
fill : true
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot column chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotColumnChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotColumnChart.prototype = new JQPlotLineChart();
JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot bar chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotBarChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotBarChart.prototype = new JQPlotLineChart();
JQPlotBarChart.prototype.constructor = JQPlotBarChart;
JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
yaxis : {
label : columns[0].name,
labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
xaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'x',
formatString:'%d'
},
series : [],
seriesDefaults : {
fillToZero : true
}
};
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
rendererOptions : {
barDirection : 'horizontal'
}
}
};
$.extend(true, optional, options, compulsory);
if (optional.axes.yaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var i = 0; i < data.length; i++) {
optional.axes.yaxis.ticks.push(data[i][0].toString());
}
}
if (optional.series.length === 0) {
for (var j = 1; j < columns.length; j++) {
optional.series.push({
label : columns[j].name.toString()
});
}
}
return optional;
};
/**
* JQPlot pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotPieChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = PieChart.prototype;
};
JQPlotPieChart.prototype = new JQPlotChart();
JQPlotPieChart.prototype.constructor = JQPlotPieChart;
JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%s, %d',
useAxesFormatters: false
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer,
},
};
var compulsory = {
seriesDefaults : {
shadow: false,
renderer : $.jqplot.PieRenderer,
rendererOptions: { sliceMargin: 1, showDataLabels: true }
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotPieChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
for (var i = 0; i < data.length; i++) {
row = data[i];
retData.push([row[0], row[1]]);
}
return [retData];
};
/**
* Chart factory that returns JQPlotCharts
*/
var JQPlotChartFactory = function () {
};
JQPlotChartFactory.prototype = new ChartFactory();
JQPlotChartFactory.prototype.createChart = function (type, elementId) {
var chart = null;
switch (type) {
case ChartType.LINE:
chart = new JQPlotLineChart(elementId);
break;
case ChartType.SPLINE:
chart = new JQPlotSplineChart(elementId);
break;
case ChartType.TIMELINE:
chart = new JQPlotTimelineChart(elementId);
break;
case ChartType.AREA:
chart = new JQPlotAreaChart(elementId);
break;
case ChartType.BAR:
chart = new JQPlotBarChart(elementId);
break;
case ChartType.COLUMN:
chart = new JQPlotColumnChart(elementId);
break;
case ChartType.PIE:
chart = new JQPlotPieChart(elementId);
break;
case ChartType.SCATTER:
chart = new JQPlotScatterChart(elementId);
break;
}
return chart;
};

View File

@ -1,40 +0,0 @@
CodeMirror.sqlLint = function (text, updateLinting, options, cm) {
// Skipping check if text box is empty.
if (text.trim() === '') {
updateLinting(cm, []);
return;
}
function handleResponse (response) {
var found = [];
for (var idx in response) {
found.push({
// eslint-disable-next-line new-cap
from: CodeMirror.Pos(
response[idx].fromLine, response[idx].fromColumn
),
// eslint-disable-next-line new-cap
to: CodeMirror.Pos(
response[idx].toLine, response[idx].toColumn
),
messageHTML: response[idx].message,
severity : response[idx].severity
});
}
updateLinting(cm, found);
}
$.ajax({
method: 'POST',
url: 'lint.php',
dataType: 'json',
data: {
'sql_query': text,
'server': CommonParams.get('server'),
'options': options.lintOptions,
'no_history': true,
},
success: handleResponse
});
};

View File

@ -1,160 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
$(function () {
Functions.checkNumberOfFields();
});
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
var CommonParams = (function () {
/**
* @var hash params An associative array of key value pairs
* @access private
*/
var params = {};
// The returned object is the public part of the module
return {
/**
* Saves all the key value pair that
* are provided in the input array
*
* @param obj hash The input array
*
* @return void
*/
setAll: function (obj) {
var updateNavigation = false;
for (var i in obj) {
if (params[i] !== undefined && params[i] !== obj[i]) {
if (i === 'db' || i === 'table') {
updateNavigation = true;
}
}
params[i] = obj[i];
}
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
},
/**
* Retrieves a value given its key
* Returns empty string for undefined values
*
* @param name string The key
*
* @return string
*/
get: function (name) {
return params[name];
},
/**
* Saves a single key value pair
*
* @param name string The key
* @param value string The value
*
* @return self For chainability
*/
set: function (name, value) {
var updateNavigation = false;
if (name === 'db' || name === 'table' &&
params[name] !== value
) {
updateNavigation = true;
}
params[name] = value;
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
return this;
},
/**
* Returns the url query string using the saved parameters
*
* @return string
*/
getUrlQuery: function () {
var common = this.get('common_query');
var separator = '?';
var argsep = CommonParams.get('arg_separator');
if (common.length > 0) {
separator = argsep;
}
return Functions.sprintf(
'%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s',
this.get('common_query'),
separator,
encodeURIComponent(this.get('server')),
encodeURIComponent(this.get('db')),
encodeURIComponent(this.get('table'))
);
}
};
}());
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
// eslint-disable-next-line no-unused-vars
var CommonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param newDb string new_db The name of the new database
*
* @return void
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({ 'db': newDb, 'table': '' });
}
},
/**
* Opens a database in the main part of the page
*
* @param newDb string The name of the new database
*
* @return void
*/
openDb: function (newDb) {
CommonParams
.set('db', newDb)
.set('table', '');
this.refreshMain(
CommonParams.get('opendb_url')
);
},
/**
* Refreshes the main frame
*
* @param mixed url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
*
* @return void
*/
refreshMain: function (url, callback) {
var newUrl = url;
if (! newUrl) {
newUrl = $('#selflink').find('a').attr('href') || window.location.pathname;
newUrl = newUrl.substring(0, newUrl.indexOf('?'));
}
newUrl += CommonParams.getUrlQuery();
$('<a></a>', { href: newUrl })
.appendTo('body')
.trigger('click')
.remove();
AJAX.callback = callback;
}
};

View File

@ -1,885 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions used in configuration forms and on user preferences pages
*/
var configInlineParams;
var configScriptLoaded;
/**
* checks whether browser supports web storage
*
* @param type the type of storage i.e. localStorage or sessionStorage
*
* @returns bool
*/
function isStorageSupported (type, warn) {
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
Functions.ajaxShowMessage(Messages.strNoLocalStorage, false);
}
}
return false;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('config.js', function () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tabs_contents').off();
$('#import_local_storage, #export_local_storage').off('click');
$('form.prefs-form').off('change').off('submit');
$(document).off('click', 'div.click-hide-message');
$('#prefs_autoload').find('a').off('click');
});
AJAX.registerOnload('config.js', function () {
var $topmenuUpt = $('#topmenu2.user_prefs_tabs');
$topmenuUpt.find('li.active a').attr('rel', 'samepage');
$topmenuUpt.find('li:not(.active) a').attr('rel', 'newpage');
});
// default values for fields
var defaultValues = {};
/**
* Returns field type
*
* @param {Element} field
*/
function getFieldType (field) {
var $field = $(field);
var tagName = $field.prop('tagName');
if (tagName === 'INPUT') {
return $field.attr('type');
} else if (tagName === 'SELECT') {
return 'select';
} else if (tagName === 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* Enables or disables the "restore default value" button
*
* @param {Element} field
* @param {boolean} display
*/
function setRestoreDefaultBtn (field, display) {
var $el = $(field).closest('td').find('.restore-default img');
$el[display ? 'show' : 'hide']();
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element} field
*/
function markField (field) {
var $field = $(field);
var type = getFieldType($field);
var isDefault = checkFieldDefault($field, type);
// checkboxes uses parent <span> for marking
var $fieldMarker = (type === 'checkbox') ? $field.parent() : $field;
setRestoreDefaultBtn($field, !isDefault);
$fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
}
/**
* Sets field value
*
* value must be of type:
* o undefined (omitted) - restore default value (form default, not PMA default)
* o String - if field_type is 'text'
* o boolean - if field_type is 'checkbox'
* o Array of values - if field_type is 'select'
*
* @param {Element} field
* @param {String} fieldType see {@link #getFieldType}
* @param {String|Boolean} value
*/
function setFieldValue (field, fieldType, value) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
$field.val(value);
break;
case 'checkbox':
$field.prop('checked', value);
break;
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
for (i = 0; i < imax; i++) {
options[i].selected = (value.indexOf(options[i].value) !== -1);
}
break;
}
markField($field);
}
/**
* Gets field value
*
* Will return one of:
* o String - if type is 'text'
* o boolean - if type is 'checkbox'
* o Array of values - if type is 'select'
*
* @param {Element} field
* @param {String} fieldType returned by {@link #getFieldType}
* @type Boolean|String|String[]
*/
function getFieldValue (field, fieldType) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
return $field.prop('value');
case 'checkbox':
return $field.prop('checked');
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
var items = [];
for (i = 0; i < imax; i++) {
if (options[i].selected) {
items.push(options[i].value);
}
}
return items;
}
return null;
}
/**
* Returns values for all fields in fieldsets
*/
// eslint-disable-next-line no-unused-vars
function getAllValues () {
var $elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type;
var value;
for (var i = 0; i < $elements.length; i++) {
type = getFieldType($elements[i]);
value = getFieldValue($elements[i], type);
if (typeof value !== 'undefined') {
// we only have single selects, fatten array
if (type === 'select') {
value = value[0];
}
values[$elements[i].name] = value;
}
}
return values;
}
/**
* Checks whether field has its default value
*
* @param {Element} field
* @param {String} type
* @return boolean
*/
function checkFieldDefault (field, type) {
var $field = $(field);
var fieldId = $field.attr('id');
if (typeof defaultValues[fieldId] === 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue($field, type);
if (type !== 'select') {
isDefault = currentValue === defaultValues[fieldId];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length !== defaultValues[fieldId].length) {
isDefault = false;
} else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] !== defaultValues[fieldId][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Returns element's id prefix
* @param {Element} element
*/
// eslint-disable-next-line no-unused-vars
function getIdPrefix (element) {
return $(element).attr('id').replace(/[^-]+$/, '');
}
// ------------------------------------------------------------------
// Form validation and field operations
//
// form validator assignments
var validate = {};
// form validator list
var validators = {
// regexp: numeric value
regExpNumeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
regExpPcreExtract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*/
validatePositiveNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = this.value !== '0' && validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_p;
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*/
validateNonNegativeNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_nneg;
},
/**
* Validates port number
*/
validatePortNumber: function () {
if (this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value) && this.value !== '0';
return result && this.value <= 65535 ? true : Messages.error_incorrect_port;
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*/
validateByRegex: function (isKeyUp, regexp) {
if (isKeyUp && this.value === '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators.regExpPcreExtract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null;
return valid ? true : Messages.error_invalid_value;
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {int} maxValue
*/
validateUpperBound: function (isKeyUp, maxValue) {
var val = parseInt(this.value, 10);
if (isNaN(val)) {
return true;
}
return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue);
},
// field validators
field: {
},
// fieldset validators
fieldset: {
}
};
/**
* Registers validator for given field
*
* @param {String} id field id
* @param {String} type validator (key in validators object)
* @param {boolean} onKeyUp whether fire on key up
* @param {Array} params validation function parameters
*/
// eslint-disable-next-line no-unused-vars
function registerFieldValidator (id, type, onKeyUp, params) {
if (typeof validators[type] === 'undefined') {
return;
}
if (typeof validate[id] === 'undefined') {
validate[id] = [];
}
if (validate[id].length === 0) {
validate[id].push([type, params, onKeyUp]);
}
}
/**
* Returns validation functions associated with form field
*
* @param {String} fieldId form field id
* @param {boolean} onKeyUpOnly see registerFieldValidator
* @type Array
* @return array of [function, parameters to be passed to function]
*/
function getFieldValidators (fieldId, onKeyUpOnly) {
// look for field bound validator
var name = fieldId && fieldId.match(/[^-]+$/)[0];
if (typeof validators.field[name] !== 'undefined') {
return [[validators.field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[fieldId] !== 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[fieldId].length; i < imax; i++) {
if (onKeyUpOnly && !validate[fieldId][i][2]) {
continue;
}
functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* PhpMyAdmin\Config\FormDisplayTemplate::displayInput()!
*
* @param {Object} errorList list of errors in the form {field id: error array}
*/
function displayErrors (errorList) {
var tempIsEmpty = function (item) {
return item !== '';
};
for (var fieldId in errorList) {
var errors = errorList[fieldId];
var $field = $('#' + fieldId);
var isFieldset = $field.attr('tagName') === 'FIELDSET';
var $errorCnt;
if (isFieldset) {
$errorCnt = $field.find('dl.errors');
} else {
$errorCnt = $field.siblings('.inline_errors');
}
// remove empty errors (used to clear error list)
errors = $.grep(errors, tempIsEmpty);
// CSS error class
if (!isFieldset) {
// checkboxes uses parent <span> for marking
var $fieldMarker = ($field.attr('type') === 'checkbox') ? $field.parent() : $field;
$fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error');
}
if (errors.length) {
// if error container doesn't exist, create it
if ($errorCnt.length === 0) {
if (isFieldset) {
$errorCnt = $('<dl class="errors"></dl>');
$field.find('table').before($errorCnt);
} else {
$errorCnt = $('<dl class="inline_errors"></dl>');
$field.closest('td').append($errorCnt);
}
}
var html = '';
for (var i = 0, imax = errors.length; i < imax; i++) {
html += '<dd>' + errors[i] + '</dd>';
}
$errorCnt.html(html);
} else if ($errorCnt !== null) {
// remove useless error container
$errorCnt.remove();
}
}
}
/**
* Validates fields and fieldsets and call displayError function as required
*/
function setDisplayError () {
var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
// run all field validators
var errors = {};
for (var i = 0; i < elements.length; i++) {
validateField(elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
}
/**
* Validates fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validateFieldset (fieldset, isKeyUp, errors) {
var $fieldset = $(fieldset);
if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') {
var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]);
for (var fieldId in fieldsetErrors) {
if (typeof errors[fieldId] === 'undefined') {
errors[fieldId] = [];
}
if (typeof fieldsetErrors[fieldId] === 'string') {
fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]];
}
$.merge(errors[fieldId], fieldsetErrors[fieldId]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validateField (field, isKeyUp, errors) {
var args;
var result;
var $field = $(field);
var fieldId = $field.attr('id');
errors[fieldId] = [];
var functions = getFieldValidators(fieldId, isKeyUp);
for (var i = 0; i < functions.length; i++) {
if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) {
args = functions[i][1].slice(0);
} else {
args = [];
}
args.unshift(isKeyUp);
result = functions[i][0].apply($field[0], args);
if (result !== true) {
if (typeof result === 'string') {
result = [result];
}
$.merge(errors[fieldId], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validateFieldAndFieldset (field, isKeyUp) {
var $field = $(field);
var errors = {};
validateField($field, isKeyUp, errors);
validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors);
displayErrors(errors);
}
function loadInlineConfig () {
if (!Array.isArray(configInlineParams)) {
return;
}
for (var i = 0; i < configInlineParams.length; ++i) {
if (typeof configInlineParams[i] === 'function') {
configInlineParams[i]();
}
}
}
function setupValidation () {
validate = {};
configScriptLoaded = true;
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
loadInlineConfig();
}
// register validators and mark custom values
var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
$elements.each(function () {
markField(this);
var $el = $(this);
$el.on('change', function () {
validateFieldAndFieldset(this, false);
markField(this);
});
var tagName = $el.attr('tagName');
// text fields can be validated after each change
if (tagName === 'INPUT' && $el.attr('type') === 'text') {
$el.on('keyup', function () {
validateFieldAndFieldset($el, true);
markField($el);
});
}
// disable textarea spellcheck
if (tagName === 'TEXTAREA') {
$el.attr('spellcheck', false);
}
});
// check whether we've refreshed a page and browser remembered modified
// form values
var $checkPageRefresh = $('#check_page_refresh');
if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') {
// run all field validators
var errors = {};
for (var i = 0; i < $elements.length; i++) {
validateField($elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
} else if ($checkPageRefresh) {
$checkPageRefresh.val('1');
}
}
AJAX.registerOnload('config.js', function () {
setupValidation();
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Tabbed forms
//
/**
* Sets active tab
*
* @param {String} tabId
*/
function setTab (tabId) {
$('ul.tabs').each(function () {
var $this = $(this);
if (!$this.find('li a[href="#' + tabId + '"]').length) {
return;
}
$this.find('li').removeClass('active').find('a[href="#' + tabId + '"]').parent().addClass('active');
$this.parent().find('div.tabs_contents fieldset').hide().filter('#' + tabId).show();
var hashValue = 'tab_' + tabId;
location.hash = hashValue;
$this.parent().find('input[name=tab_hash]').val(hashValue);
});
}
function setupConfigTabs () {
var forms = $('form.config-form');
forms.each(function () {
var $this = $(this);
var $tabs = $this.find('ul.tabs');
if (!$tabs.length) {
return;
}
// add tabs events and activate one tab (the first one or indicated by location hash)
$tabs.find('li').removeClass('active');
$tabs.find('a')
.on('click', function (e) {
e.preventDefault();
setTab($(this).attr('href').substr(1));
})
.filter(':first')
.parent()
.addClass('active');
$this.find('div.tabs_contents fieldset').hide().filter(':first').show();
});
}
function adjustPrefsNotification () {
var $prefsAutoLoad = $('#prefs_autoload');
var $tableNameControl = $('#table_name_col_no');
var $prefsAutoShowing = ($prefsAutoLoad.css('display') !== 'none');
if ($prefsAutoShowing && $tableNameControl.length) {
$tableNameControl.css('top', '55px');
}
}
AJAX.registerOnload('config.js', function () {
setupConfigTabs();
adjustPrefsNotification();
// tab links handling, check each 200ms
// (works with history in FF, further browser support here would be an overkill)
var prevHash;
var tabCheckFnc = function () {
if (location.hash !== prevHash) {
prevHash = location.hash;
if (prevHash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
var hash = prevHash.substr(5).split('&')[0];
if ($('#' + hash).length) {
setTab(hash);
}
}
}
};
tabCheckFnc();
setInterval(tabCheckFnc, 200);
});
//
// END: Tabbed forms
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Form reset buttons
//
AJAX.registerOnload('config.js', function () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
}
setDisplayError();
});
});
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
/**
* Restores field's default value
*
* @param {String} fieldId
*/
function restoreField (fieldId) {
var $field = $('#' + fieldId);
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
return;
}
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
}
function setupRestoreField () {
$('div.tabs_contents')
.on('mouseenter', '.restore-default, .set-value', function () {
$(this).css('opacity', 1);
})
.on('mouseleave', '.restore-default, .set-value', function () {
$(this).css('opacity', 0.25);
})
.on('click', '.restore-default, .set-value', function (e) {
e.preventDefault();
var href = $(this).attr('href');
var fieldSel;
if ($(this).hasClass('restore-default')) {
fieldSel = href;
restoreField(fieldSel.substr(1));
} else {
fieldSel = href.match(/^[^=]+/)[0];
var value = href.match(/=(.+)$/)[1];
setFieldValue($(fieldSel), 'text', value);
}
$(fieldSel).trigger('change');
})
.find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({ display: 'inline-block', opacity: 0.25 });
}
AJAX.registerOnload('config.js', function () {
setupRestoreField();
});
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
AJAX.registerOnload('config.js', function () {
offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
return;
}
// enable JavaScript dependent fields
$radios
.prop('disabled', false)
.add('#export_text_file, #import_text_file')
.on('click', function () {
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
var lsSupported = isStorageSupported('localStorage', true);
var lsExists = lsSupported ? (window.localStorage.config || false) : false;
$('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide();
$('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide();
if (lsExists) {
updatePrefsDate();
}
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!lsExists && $form.attr('name') === 'prefs_import' &&
$('#import_local_storage')[0].checked
) {
disabled = true;
}
$form.find('input[type=submit]').prop('disabled', disabled);
}).submit(function (e) {
var $form = $(this);
if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) {
e.preventDefault();
// use AJAX to read JSON settings and save them
savePrefsToLocalStorage($form);
} else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
// set 'json' input and submit form
$form.find('input[name=json]').val(window.localStorage.config);
}
});
$(document).on('click', 'div.click-hide-message', function () {
$(this)
.hide()
.parent('.group')
.css('height', '')
.next('form')
.show();
});
});
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
function savePrefsToLocalStorage (form) {
var $form = $(form);
var submit = $form.find('input[type=submit]');
submit.prop('disabled', true);
$.ajax({
url: 'prefs_manage.php',
cache: false,
type: 'POST',
data: {
'ajax_request': true,
'server': CommonParams.get('server'),
'submit_get_json': true
},
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
window.localStorage.config = data.prefs;
window.localStorage.configMtime = data.mtime;
window.localStorage.configMtimeLocal = (new Date()).toUTCString();
updatePrefsDate();
$('div.localStorage-empty').hide();
$('div.localStorage-exists').show();
var group = $form.parent('.group');
group.css('height', group.height() + 'px');
$form.hide('fast');
$form.prev('.click-hide-message').show('fast');
} else {
Functions.ajaxShowMessage(data.error);
}
},
complete: function () {
submit.prop('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
function updatePrefsDate () {
var d = new Date(window.localStorage.configMtimeLocal);
var msg = Messages.strSavedOn.replace(
'@DATE@',
Functions.formatDateTime(d)
);
$('#opts_import_local_storage').find('div.localStorage-exists').html(msg);
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
*/
function offerPrefsAutoimport () {
var hasConfig = (isStorageSupported('localStorage')) && (window.localStorage.config || false);
var $cnt = $('#prefs_autoload');
if (!$cnt.length || !hasConfig) {
return;
}
$cnt.find('a').on('click', function (e) {
e.preventDefault();
var $a = $(this);
if ($a.attr('href') === '#no') {
$cnt.remove();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
} else if ($a.attr('href') === '#delete') {
$cnt.remove();
localStorage.clear();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
}
$cnt.find('input[name=json]').val(window.localStorage.config);
$cnt.find('form').trigger('submit');
});
$cnt.show();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var styleElement = document.getElementById('cfs-style');
// check if styleElement has already been removed
// to avoid frequently reported js error
if (typeof(styleElement) !== 'undefined' && styleElement !== null) {
styleElement.parentNode.removeChild(styleElement);
}
} else {
top.location = self.location;
}

View File

@ -1,241 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview events handling from central columns page
* @name Central columns
*
* @requires jQuery
*/
/**
* AJAX scripts for db_central_columns.php
*
* Actions ajaxified here:
* Inline Edit and save of a result row
* Delete a row
* Multiple edit and delete option
*
*/
AJAX.registerTeardown('database/central_columns.js', function () {
$('.edit').off('click');
$('.edit_save_form').off('click');
$('.edit_cancel_form').off('click');
$('.del_row').off('click');
$(document).off('keyup', '.filter_rows');
$('.edit_cancel_form').off('click');
$('#table-select').off('change');
$('#column-select').off('change');
$('#add_col_div').find('>a').off('click');
$('#add_new').off('submit');
$('#multi_edit_central_columns').off('submit');
$('select.default_type').off('change');
$('button[name=\'delete_central_columns\']').off('click');
$('button[name=\'edit_central_columns\']').off('click');
});
AJAX.registerOnload('database/central_columns.js', function () {
$('#tableslistcontainer input,#tableslistcontainer select,#tableslistcontainer .default_value,#tableslistcontainer .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
$('#tableslistcontainer').find('.checkall_box').show();
if ($('#table_columns').find('tbody tr').length > 0) {
$('#table_columns').tablesorter({
headers: {
0: { sorter: false },
1: { sorter: false }, // hidden column
4: { sorter: 'integer' }
}
});
}
$('#tableslistcontainer').find('button[name="delete_central_columns"]').on('click', function (event) {
event.preventDefault();
var multiDeleteColumns = $('.checkall:checkbox:checked').serialize();
if (multiDeleteColumns === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
Functions.ajaxShowMessage();
$('#del_col_name').val(multiDeleteColumns);
$('#del_form').trigger('submit');
});
$('#tableslistcontainer').find('button[name="edit_central_columns"]').on('click', function (event) {
event.preventDefault();
var editColumnList = $('.checkall:checkbox:checked').serialize();
if (editColumnList === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
var argsep = CommonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db'));
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('db_central_columns.php', editColumnData, AJAX.responseHandler);
});
$('#multi_edit_central_columns').submit(function (event) {
event.preventDefault();
event.stopPropagation();
var argsep = CommonParams.get('arg_separator');
var multiColumnEditData = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db'));
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('db_central_columns.php', multiColumnEditData, AJAX.responseHandler);
});
$('#add_new').find('td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find('input,select:first').attr('name', $(this).attr('name'));
}
});
$('#field_0_0').attr('required','required');
$('#add_new input[type="text"], #add_new input[type="number"], #add_new select')
.css({
'width' : '10em',
'-moz-box-sizing' : 'border-box'
});
window.scrollTo(0, 0);
$(document).on('keyup', '.filter_rows', function () {
// get the column names
var cols = $('th.column_heading').map(function () {
return $.trim($(this).text());
}).get();
$.uiTableFilter($('#table_columns'), $(this).val(), cols, null, 'td span');
});
$('.edit').on('click', function () {
var rownum = $(this).parent().data('rownum');
$('#save_' + rownum).show();
$(this).hide();
$('#f_' + rownum + ' td span').hide();
$('#f_' + rownum + ' input, #f_' + rownum + ' select, #f_' + rownum + ' .open_enum_editor').show();
var attributeVal = $('#f_' + rownum + ' td[name=col_attribute] span').html();
$('#f_' + rownum + ' select[name=field_attribute\\[' + rownum + '\\] ] option[value="' + attributeVal + '"]').attr('selected','selected');
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').siblings('.default_value').show();
} else {
$('#f_' + rownum + ' .default_type').siblings('.default_value').hide();
}
});
$('.del_row').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var $td = $(this);
var question = Messages.strDeleteCentralColumnWarning;
$td.confirm(question, null, function () {
var rownum = $td.data('rownum');
$('#del_col_name').val('selected_fld%5B%5D=' + $('#checkbox_row_' + rownum).val());
$('#del_form').trigger('submit');
});
});
$('.edit_cancel_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
});
$('.edit_save_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#f_' + rownum + ' td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find(':input[type!="hidden"],select:first')
.attr('name', $(this).attr('name'));
}
});
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').attr('name','col_default_sel');
} else {
$('#f_' + rownum + ' .default_value').attr('name','col_default_val');
}
var datastring = $('#f_' + rownum + ' :input').serialize();
$.ajax({
type: 'POST',
url: 'db_central_columns.php',
data: datastring + CommonParams.get('arg_separator') + 'ajax_request=true',
dataType: 'json',
success: function (data) {
if (data.message !== '1') {
Functions.ajaxShowMessage(
'<div class="error">' +
data.message +
'</div>',
false
);
} else {
$('#f_' + rownum + ' td input[id=checkbox_row_' + rownum + ']').val($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_name] span').text($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_type] span').text($('#f_' + rownum + ' select[name=col_type]').val()).html();
$('#f_' + rownum + ' td[name=col_length] span').text($('#f_' + rownum + ' input[name=col_length]').val()).html();
$('#f_' + rownum + ' td[name=collation] span').text($('#f_' + rownum + ' select[name=collation]').val()).html();
$('#f_' + rownum + ' td[name=col_attribute] span').text($('#f_' + rownum + ' select[name=col_attribute]').val()).html();
$('#f_' + rownum + ' td[name=col_isNull] span').text($('#f_' + rownum + ' input[name=col_isNull]').is(':checked') ? 'Yes' : 'No').html();
$('#f_' + rownum + ' td[name=col_extra] span').text($('#f_' + rownum + ' input[name=col_extra]').is(':checked') ? 'auto_increment' : '').html();
$('#f_' + rownum + ' td[name=col_default] span').text($('#f_' + rownum + ' :input[name=col_default]').val()).html();
}
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
},
error: function () {
Functions.ajaxShowMessage(
'<div class="error">' +
Messages.strErrorProcessingRequest +
'</div>',
false
);
}
});
});
$('#table-select').on('change', function () {
var selectValue = $(this).val();
var defaultColumnSelect = $('#column-select').find('option:first');
var href = 'db_central_columns.php';
var params = {
'ajax_request' : true,
'server' : CommonParams.get('server'),
'db' : CommonParams.get('db'),
'selectedTable' : selectValue,
'populateColumns' : true
};
$('#column-select').html('<option value="">' + Messages.strLoading + '</option>');
if (selectValue !== '') {
$.post(href, params, function (data) {
$('#column-select').empty().append(defaultColumnSelect);
$('#column-select').append(data.message);
});
}
});
$('#add_column').submit(function (e) {
var selectvalue = $('#column-select').val();
if (selectvalue === '') {
e.preventDefault();
e.stopPropagation();
}
});
$('#add_col_div').find('>a').on('click', function () {
$('#add_new').slideToggle('slow');
var $addColDivLinkSpan = $('#add_col_div').find('>a span');
if ($addColDivLinkSpan.html() === '+') {
$addColDivLinkSpan.html('-');
} else {
$addColDivLinkSpan.html('+');
}
});
$('#add_new').submit(function () {
$('#add_new').toggle();
});
$('#tableslistcontainer').find('select.default_type').on('change', function () {
if ($(this).val() === 'USER_DEFINED') {
$(this).siblings('.default_value').attr('name','col_default');
$(this).attr('name','col_default_sel');
} else {
$(this).attr('name','col_default');
$(this).siblings('.default_value').attr('name','col_default_val');
}
});
});

View File

@ -1,222 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
* @requires js/database/query_generator.js
*
*/
/* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js
/**
* js file for handling AJAX and other events in db_multi_table_query.php
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/multi_table_query.js', function () {
$('.tableNameSelect').each(function () {
$(this).off('change');
});
$('#update_query_button').off('click');
$('#add_column_button').off('click');
});
AJAX.registerOnload('database/multi_table_query.js', function () {
var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both');
$('.CodeMirror-line').css('text-align', 'left');
editor.setSize(-1, 50);
var columnCount = 3;
Functions.initSlider();
addNewColumnCallbacks();
$('#update_query_button').on('click', function () {
var columns = [];
var tableAliases = {};
$('.tableNameSelect').each(function () {
var $show = $(this).siblings('.show_col').first();
if ($(this).val() !== '' && $show.prop('checked')) {
var tableAlias = $(this).siblings('.table_alias').first().val();
var columnAlias = $(this).siblings('.col_alias').first().val();
if (tableAlias !== '') {
columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]);
} else {
columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]);
}
columns[columns.length - 1].push(columnAlias);
if ($(this).val() in tableAliases) {
if (!(tableAliases[$(this).val()].includes(tableAlias))) {
tableAliases[$(this).val()].push(tableAlias);
}
} else {
tableAliases[$(this).val()] = [tableAlias];
}
}
});
if (Object.keys(tableAliases).length === 0) {
Functions.ajaxShowMessage('Nothing selected', false, 'error');
return;
}
var foreignKeys;
$.ajax({
type: 'GET',
async: false,
url: 'db_multi_table_query.php',
data: {
'server': sessionStorage.server,
'db': $('#db_name').val(),
'tables': Object.keys(tableAliases),
'ajax_request': '1',
'token': CommonParams.get('token')
},
success: function (response) {
foreignKeys = response.foreignKeyConstrains;
}
});
var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.';
if (columns[0][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[0][1]) + '`';
}
if (columns[0][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`';
}
for (var i = 1; i < columns.length; i++) {
query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.';
if (columns[i][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[i][1]) + '`';
}
if (columns[i][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`';
}
}
query += '\nFROM ';
query += generateFromBlock(tableAliases, foreignKeys);
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 0) {
query += '\nWHERE ';
query += generateWhereBlock();
}
query += ';';
editor.getDoc().setValue(query);
});
$('#submit_query').on('click', function () {
var query = editor.getDoc().getValue();
// Verifying that the query is not empty
if (query === '') {
Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error');
return;
}
var data = {
'db': $('#db_name').val(),
'sql_query': query,
'ajax_request': '1',
'token': CommonParams.get('token')
};
$.ajax({
type: 'POST',
url: 'db_multi_table_query.php',
data: data,
success: function (data) {
var $resultsDom = $(data.message);
$resultsDom.find('.ajax:not(.pageselector)').each(function () {
$(this).on('click', function (event) {
event.preventDefault();
});
});
$resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () {
$(this).on('change click select focus', function (event) {
event.preventDefault();
});
});
$('#sql_results').html($resultsDom);
$('#page_content').find('a').first().trigger('click');
}
});
});
$('#add_column_button').on('click', function () {
columnCount++;
var $newColumnDom = $($('#new_column_layout').html()).clone();
$newColumnDom.find('div').first().find('div').first().attr('id', columnCount.toString());
$newColumnDom.find('a').first().remove();
$newColumnDom.find('.pma_auto_slider').first().unwrap();
$newColumnDom.find('.pma_auto_slider').first().attr('title', 'criteria');
$('#add_column_button').parent().before($newColumnDom);
Functions.initSlider();
addNewColumnCallbacks();
});
function addNewColumnCallbacks () {
$('.tableNameSelect').each(function () {
$(this).on('change', function () {
var $sibs = $(this).siblings('.columnNameSelect');
if ($sibs.length === 0) {
$sibs = $(this).parent().parent().find('.columnNameSelect');
}
$sibs.first().html($('#' + $.md5($(this).val())).html());
});
});
$('.removeColumn').each(function () {
$(this).on('click', function () {
$(this).parent().remove();
});
});
$('a.ajax').each(function () {
$(this).on('click', function (event, from) {
if (from === null) {
var $checkbox = $(this).siblings('.criteria_col').first();
$checkbox.prop('checked', !$checkbox.prop('checked'));
}
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 1) {
$(this).siblings('.slide-wrapper').first().find('.logical_operator').first().css('display','table-row');
}
});
});
$('.criteria_col').each(function () {
$(this).on('change', function () {
var $anchor = $(this).siblings('a.ajax').first();
$anchor.trigger('click', ['Trigger']);
});
});
$('.criteria_rhs').each(function () {
$(this).on('change', function () {
var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first();
var $rhsText = $(this).parent().parent().siblings('.rhs_text').first();
if ($(this).val() === 'text') {
$rhsCol.css('display', 'none');
$rhsText.css('display', 'table-row');
} else if ($(this).val() === 'anotherColumn') {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'table-row');
} else {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'none');
}
});
});
}
});

View File

@ -1,167 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in server privilege pages
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for db_operations.php
*
* Actions Ajaxified here:
* Rename Database
* Copy Database
* Change Charset
* Drop Database
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/operations.js', function () {
$(document).off('submit', '#rename_db_form.ajax');
$(document).off('submit', '#copy_db_form.ajax');
$(document).off('submit', '#change_db_charset_form.ajax');
$(document).off('click', '#drop_db_anchor.ajax');
});
AJAX.registerOnload('database/operations.js', function () {
/**
* Ajax event handlers for 'Rename Database'
*/
$(document).on('submit', '#rename_db_form.ajax', function (event) {
event.preventDefault();
var oldDbName = CommonParams.get('db');
var newDbName = $('#new_db_name').val();
if (newDbName === oldDbName) {
Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error');
return false;
}
var $form = $(this);
var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName);
Functions.prepareForAjaxRequest($form);
$form.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strRenamingDatabases, false);
$.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
CommonParams.set('db', data.newname);
Navigation.reload(function () {
$('#pma_navigation_tree')
.find('a:not(\'.expander\')')
.each(function () {
var $thisAnchor = $(this);
if ($thisAnchor.text() === data.newname) {
// simulate a click on the new db name
// in navigation
$thisAnchor.trigger('click');
}
});
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
}); // end Rename Database
/**
* Ajax Event Handler for 'Copy Database'
*/
$(document).on('submit', '#copy_db_form.ajax', function (event) {
event.preventDefault();
Functions.ajaxShowMessage(Messages.strCopyingDatabase, false);
var $form = $(this);
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
// use messages that stay on screen
$('div.success, div.error').fadeOut();
if (typeof data !== 'undefined' && data.success === true) {
if ($('#checkbox_switch').is(':checked')) {
CommonParams.set('db', data.newname);
CommonActions.refreshMain(false, function () {
Functions.ajaxShowMessage(data.message);
});
} else {
CommonParams.set('db', data.db);
Functions.ajaxShowMessage(data.message);
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end copy database
/**
* Change tables columns visible only if change tables is checked
*/
$('#span_change_all_tables_columns_collations').hide();
$('#checkbox_change_all_tables_collations').on('click', function () {
$('#span_change_all_tables_columns_collations').toggle();
});
/**
* Ajax Event handler for 'Change Charset' of the database
*/
$(document).on('submit', '#change_db_charset_form.ajax', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
Functions.ajaxShowMessage(Messages.strChangingCharset);
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'submitcollation=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end change charset
/**
* Ajax event handlers for Drop Database
*/
$(document).on('click', '#drop_db_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strDropDatabaseStrongWarning + ' ';
question += Functions.sprintf(
Messages.strDoYouReally,
'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`')
);
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$(this).confirm(question, $(this).attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
// Database deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('db', '');
CommonActions.refreshMain(
'server_databases.php',
function () {
Functions.ajaxShowMessage(data.message);
}
);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
});
});

View File

@ -1,87 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for db_qbe.php
*
* Actions Ajaxified here:
* Select saved search
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/qbe.js', function () {
$(document).off('change', 'select[name^=criteriaColumn]');
$(document).off('change', '#searchId');
$(document).off('click', '#saveSearch');
$(document).off('click', '#updateSearch');
$(document).off('click', '#deleteSearch');
});
AJAX.registerOnload('database/qbe.js', function () {
Functions.getSqlEditor($('#textSqlquery'), {}, 'none');
$('#tblQbe').width($('#tblQbe').parent().width());
$('#tblQbeFooters').width($('#tblQbeFooters').parent().width());
$('#tblQbe').resize(function () {
var newWidthTblQbe = $('#textSqlquery').next().width();
$('#tblQbe').width(newWidthTblQbe);
$('#tblQbeFooters').width(newWidthTblQbe);
});
/**
* Ajax handler to check the corresponding 'show' checkbox when column is selected
*/
$(document).on('change', 'select[name^=criteriaColumn]', function () {
if ($(this).val()) {
var index = (/\d+/).exec($(this).attr('name'));
$('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true);
}
});
/**
* Ajax event handlers for 'Select saved search'
*/
$(document).on('change', '#searchId', function () {
$('#action').val('load');
$('#formQBE').trigger('submit');
});
/**
* Ajax event handlers for 'Create bookmark'
*/
$(document).on('click', '#saveSearch', function () {
$('#action').val('create');
});
/**
* Ajax event handlers for 'Update bookmark'
*/
$(document).on('click', '#updateSearch', function () {
$('#action').val('update');
});
/**
* Ajax event handlers for 'Delete bookmark'
*/
$(document).on('click', '#deleteSearch', function () {
var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text());
if (!confirm(question)) {
return false;
}
$('#action').val('delete');
});
var windowwidth = $(window).width();
$('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
});

View File

@ -1,131 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/* global sprintf */ // js/vendor/sprintf.js
function getFormatsText () {
return {
'=': ' = \'%s\'',
'>': ' > \'%s\'',
'>=': ' >= \'%s\'',
'<': ' < \'%s\'',
'<=': ' <= \'%s\'',
'!=': ' != \'%s\'',
'LIKE': ' LIKE \'%s\'',
'LIKE %...%': ' LIKE \'%%%s%%\'',
'NOT LIKE': ' NOT LIKE \'%s\'',
'BETWEEN': ' BETWEEN \'%s\'',
'NOT BETWEEN': ' NOT BETWEEN \'%s\'',
'IS NULL': ' \'%s\' IS NULL',
'IS NOT NULL': ' \'%s\' IS NOT NULL',
'REGEXP': ' REGEXP \'%s\'',
'REGEXP ^...$': ' REGEXP \'^%s$\'',
'NOT REGEXP': ' NOT REGEXP \'%s\''
};
}
function generateCondition (criteriaDiv, table) {
var query = '`' + Functions.escapeBacktick(table.val()) + '`.';
query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`';
if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') {
var formatsText = getFormatsText();
query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val()));
} else {
query += ' ' + criteriaDiv.find('.criteria_op').first().val();
query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.';
query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`';
}
return query;
}
// eslint-disable-next-line no-unused-vars
function generateWhereBlock () {
var count = 0;
var query = '';
$('.tableNameSelect').each(function () {
var criteriaDiv = $(this).siblings('.slide-wrapper').first();
var useCriteria = $(this).siblings('.criteria_col').first();
if ($(this).val() !== '' && useCriteria.prop('checked')) {
if (count > 0) {
criteriaDiv.find('input.logical_op').each(function () {
if ($(this).prop('checked')) {
query += ' ' + $(this).val() + ' ';
}
});
}
query += generateCondition(criteriaDiv, $(this));
count++;
}
});
return query;
}
function generateJoin (newTable, tableAliases, fk) {
var query = '';
query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`';
if (tableAliases[fk.TABLE_NAME][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`';
query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`';
} else {
query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`';
}
query += '.`' + fk.COLUMN_NAME + '`';
if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') {
query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`';
} else {
query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`';
}
query += '.`' + fk.REFERENCED_COLUMN_NAME + '`';
return query;
}
function existReference (table, fk, usedTables) {
var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME);
var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME);
return isReferredBy || isReferencedBy;
}
function tryJoinTable (table, tableAliases, usedTables, foreignKeys) {
for (var i = 0; i < foreignKeys.length; i++) {
var fk = foreignKeys[i];
if (existReference(table, fk, usedTables)) {
return generateJoin(table, tableAliases, fk);
}
}
return '';
}
function appendTable (table, tableAliases, usedTables, foreignKeys) {
var query = tryJoinTable (table, tableAliases, usedTables, foreignKeys);
if (query === '') {
if (usedTables.length > 0) {
query += '\n\t, ';
}
query += '`' + Functions.escapeBacktick(table) + '`';
if (tableAliases[table][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`';
}
}
usedTables.push(table);
return query;
}
// eslint-disable-next-line no-unused-vars
function generateFromBlock (tableAliases, foreignKeys) {
var usedTables = [];
var query = '';
for (var table in tableAliases) {
if (tableAliases.hasOwnProperty(table)) {
query += appendTable(table, tableAliases, usedTables, foreignKeys);
}
}
return query;
}

View File

@ -1,248 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* JavaScript functions used on Database Search page
*
* @requires jQuery
* @requires js/functions.js
*
* @package PhpMyAdmin
*/
/* global makeGrid */ // js/makegrid.js
/**
* AJAX script for the Database Search page.
*
* Actions ajaxified here:
* Retrieve result of SQL query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/search.js', function () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
$('#togglesearchresultlink').off('click');
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$(document).off('submit', '#db_search_form.ajax');
});
AJAX.registerOnload('database/search.js', function () {
/** Hide the table link in the initial search result */
var icon = Functions.getImage('s_tbl', '', { 'id': 'table-image' }).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').on('click', function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
});
/**
* Prepare a div containing a link for toggle the search results
*/
$('#togglesearchresultsdiv')
/** don't show it until we have results on-screen */
.hide();
/**
* Changing the displayed text according to
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink')
.html(Messages.strHideSearchResults)
.on('click', function () {
var $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === Messages.strHideSearchResults) {
$link.text(Messages.strShowSearchResults);
} else {
$link.text(Messages.strHideSearchResults);
}
/** avoid default click action */
return false;
});
/**
* Prepare a div containing a link for toggle the search form,
* otherwise it's incorrectly displayed after a couple of clicks
*/
$('#togglesearchformdiv')
.hide(); // don't show it until we have results on-screen
/**
* Changing the displayed text according to
* the hide/show criteria in search form
*/
$('#togglequerybox')
.hide()
.on('click', function () {
var $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === Messages.strHideQueryBox) {
$link.text(Messages.strShowQueryBox);
} else {
$link.text(Messages.strHideQueryBox);
}
/** avoid default click action */
return false;
});
/** don't show it until we have results on-screen */
/**
* Changing the displayed text according to
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink')
.html(Messages.strShowSearchCriteria)
.on('click', function () {
var $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
var tableName = $(this).data('table-name');
$('#table-link').attr({ 'href' : $(this).attr('href') }).text(tableName);
var url = $(this).attr('href') + '#searchresults';
var browseSql = $(this).data('browse-sql');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browseSql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
Functions.ajaxRemoveMessage($msg);
$('.table_results').each(function () {
makeGrid(this, true, true, true, true);
});
$('#browse-results').show();
Functions.highlightSql($('#browse-results'));
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function (e) {
e.preventDefault();
/** Hides the results shown by the browse criteria */
$('#table-info').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = Functions.sprintf(
Messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
Functions.ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').trigger('click');
$('#togglequerybox').html(Messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
Functions.ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val();
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
$('#searchresults').html(data.message);
$('#togglesearchresultlink')
// always start with the Show message
.text(Messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
$('#searchresults').show();
$('#db_search_form')
// workaround for Chrome problem (bug #3168569)
.slideToggle()
.hide();
$('#togglesearchformlink')
// always start with the Show message
.text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
} else {
// error message (zero rows)
$('#searchresults').html(data.error).show();
}
Functions.ajaxRemoveMessage($msgbox);
});
});
}); // end $()

View File

@ -1,429 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview functions used on the database structure page
* @name Database Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
var DatabaseStructure = {};
/**
* AJAX scripts for db_structure.php
*
* Actions ajaxified here:
* Drop Database
* Truncate Table
* Drop Table
*
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/structure.js', function () {
$(document).off('click', 'a.truncate_table_anchor.ajax');
$(document).off('click', 'a.drop_table_anchor.ajax');
$(document).off('click', '#real_end_input');
$(document).off('click', 'a.favorite_table_anchor.ajax');
$(document).off('click', '#printView');
$('a.real_row_count').off('click');
$('a.row_count_sum').off('click');
$('select[name=submit_mult]').off('change');
});
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
DatabaseStructure.adjustTotals = function () {
var byteUnits = [
Messages.strB,
Messages.strKiB,
Messages.strMiB,
Messages.strGiB,
Messages.strTiB,
Messages.strPiB,
Messages.strEiB
];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody:first tr');
// New summary values for the table
var tableSum = $allTr.length;
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.]/g, '');
var intRow = parseInt(strRows, 10);
if (! isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $.trim($this.find('.tbl_size span:not(.unit)').text());
var strSizeUnit = $.trim($this.find('.tbl_size span.unit').text());
var strOverhead = $.trim($this.find('.tbl_overhead span:not(.unit)').text());
var strOverheadUnit = $.trim($this.find('.tbl_overhead span.unit').text());
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var sizeMagnitude = 0;
var overheadMagnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
sizeMagnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overheadMagnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]);
};
/**
* Gets the real row count for a table or DB.
* @param object $target Target for appending the real count value.
*/
DatabaseStructure.fetchRealRowCount = function ($target) {
var $throbber = $('#pma_navigation').find('.throbber')
.first()
.clone()
.css({ visibility: 'visible', display: 'inline-block' })
.on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all),
function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]')
.text(table.row_count);
}
);
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
},
error: function () {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
});
};
AJAX.registerOnload('database/structure.js', function () {
/**
* function to open the confirmation dialog for making table consistent with central list
*
* @param string msg message text to be displayed to user
* @param function success function to be called on success
*
*/
var jqConfirm = function (msg, success) {
var dialogObj = $('<div class=\'hide\'>' + msg + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[Messages.strContinue] = function () {
success();
$(this).dialog('close');
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
$(dialogObj).dialog({
resizable: false,
modal: true,
title: Messages.confirmTitle,
buttons: buttonOptions
});
};
/**
* Event handler on select of "Make consistent with central list"
*/
$('select[name=submit_mult]').on('change', function (event) {
if ($(this).val() === 'make_consistent_with_central_list') {
event.preventDefault();
event.stopPropagation();
jqConfirm(
Messages.makeConsistentMessage, function () {
$('#tablesForm').trigger('submit');
}
);
return false;
} else if ($(this).val() === 'copy_tbl' || $(this).val() === 'add_prefix_tbl' || $(this).val() === 'replace_prefix_tbl' || $(this).val() === 'copy_tbl_change_prefix') {
event.preventDefault();
event.stopPropagation();
if ($('input[name="selected_tbl[]"]:checked').length === 0) {
return false;
}
var formData = $('#tablesForm').serialize();
var modalTitle = '';
if ($(this).val() === 'copy_tbl') {
modalTitle = Messages.strCopyTablesTo;
} else if ($(this).val() === 'add_prefix_tbl') {
modalTitle = Messages.strAddPrefix;
} else if ($(this).val() === 'replace_prefix_tbl') {
modalTitle = Messages.strReplacePrefix;
} else if ($(this).val() === 'copy_tbl_change_prefix') {
modalTitle = Messages.strCopyPrefix;
}
$.ajax({
type: 'POST',
url: 'db_structure.php',
dataType: 'html',
data: formData
}).done(function (data) {
var dialogObj = $('<div class=\'hide\'>' + data + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[Messages.strContinue] = function () {
$('#ajax_form').trigger('submit');
$(this).dialog('close');
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
$(dialogObj).dialog({
minWidth: 500,
resizable: false,
modal: true,
title: modalTitle,
buttons: buttonOptions
});
});
} else {
$('#tablesForm').trigger('submit');
}
});
/**
* Ajax Event handler for 'Truncate Table'
*/
$(document).on('click', 'a.truncate_table_anchor.ajax', function (event) {
event.preventDefault();
/**
* @var $this_anchor Object referring to the anchor clicked
*/
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $thisAnchor.parents('tr').children('th').children('a').text();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strTruncateTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') +
Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
// Adjust table statistics
var $tr = $thisAnchor.closest('tr');
$tr.find('.tbl_rows').text('0');
$tr.find('.tbl_size, .tbl_overhead').text('-');
// Fetch inner span of this anchor
// and replace the icon with its disabled version
var span = $thisAnchor.html().replace(/b_empty/, 'bd_empty');
// To disable further attempts to truncate the table,
// replace the a element with its inner span (modified)
$thisAnchor
.replaceWith(span)
.removeClass('truncate_table_anchor');
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Truncate Table Ajax action
/**
* Ajax Event handler for 'Drop Table' or 'Drop View'
*/
$(document).on('click', 'a.drop_table_anchor.ajax', function (event) {
event.preventDefault();
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $thisAnchor.parents('tr');
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $currRow.children('th').children('a').text();
/**
* @var is_view Boolean telling if we have a view
*/
var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view');
/**
* @var question String containing the question to be asked for confirmation
*/
var question;
if (! isView) {
question = Messages.strDropTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`');
} else {
question =
Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`');
}
question += Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
$currRow.hide('medium').remove();
DatabaseStructure.adjustTotals();
Navigation.reload();
Functions.ajaxRemoveMessage($msg);
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Drop Table Ajax action
/**
* Attach Event Handler for 'Print' link
*/
$(document).on('click', '#printView', function (event) {
event.preventDefault();
// Take to preview mode
Functions.printPreview();
}); // end of Print View action
// Calculate Real End for InnoDB
/**
* Ajax Event handler for calculating the real end for a InnoDB table
*
*/
$(document).on('click', '#real_end_input', function (event) {
event.preventDefault();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strOperationTakesLongTime;
$(this).confirm(question, '', function () {
return true;
});
return false;
}); // end Calculate Real End for InnoDB
// Add tooltip to favorite icons.
$('.favorite_table_anchor').each(function () {
Functions.tooltip(
$(this),
'a',
$(this).attr('title')
);
});
// Get real row count via Ajax.
$('a.real_row_count').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
// Get all real row count.
$('a.row_count_sum').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
});

View File

@ -1,93 +0,0 @@
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('database/tracking.js', function () {
$('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]');
$('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_tracking_anchor.ajax');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('database/tracking.js', function () {
var $versions = $('#versions');
$versions.find('tr:first th').append($('<div class="sorticon"></div>'));
$versions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: 'integer' },
5: { sorter: false },
6: { sorter: false },
7: { sorter: false }
}
});
var $noVersions = $('#noversions');
$noVersions.find('tr:first th').append($('<div class="sorticon"></div>'));
$noVersions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: false }
}
});
var $body = $('body');
/**
* Handles multi submit for tracked tables
*/
$body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_tracking') {
var question = Messages.strDeleteTrackingDataMultiple;
$button.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $form;
$.post(url, submitData, AJAX.responseHandler);
});
} else {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
/**
* Handles multi submit for untracked tables
*/
$body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Delete tracking'
*/
$body.on('click', 'a.delete_tracking_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeleteTrackingData;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
});

View File

@ -1,859 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in this file builds history tab and generates query.
*
* @requires jQuery
* @requires move.js
* @version $Id$
*/
/* global contr */ // js/designer/init.js
/* global fromArray:writable */ // js/designer/move.js
/* global pmaThemeImage */ // js/messages.php
var DesignerHistory = {};
var historyArray = []; // Global array to store history objects
var selectField = []; // Global array to store information for columns which are used in select clause
var gIndex;
var vqbEditor = null;
/**
* To display details of objects(where,rename,Having,aggregate,groupby,orderby,having)
*
* @param index index of historyArray where change is to be made
*
**/
DesignerHistory.detail = function (index) {
var type = historyArray[index].getType();
var str;
if (type === 'Where') {
str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
if (type === 'Rename') {
str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo();
}
if (type === 'Aggregate') {
str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
}
if (type === 'GroupBy') {
str = 'GroupBy ' + historyArray[index].getColumnName();
}
if (type === 'OrderBy') {
str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder();
}
if (type === 'Having') {
str = 'Having ';
if (historyArray[index].getObj().getOperator() !== 'None') {
str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else {
str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
}
return str;
};
/**
* Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab,
* clubbing all objects of same tables together
* This function is called whenever changes are made in historyArray[]
*
*
* @param {int} init starting index of unsorted array
* @param {int} finit last index of unsorted array
*
**/
DesignerHistory.display = function (init, finit) {
var str;
var i;
var j;
var k;
var sto;
var temp;
// this part sorts the history array based on table name,this is needed for clubbing all object of same name together.
for (i = init; i < finit; i++) {
sto = historyArray[i];
temp = historyArray[i].getTab();// + '.' + historyArray[i].getObjNo(); for Self JOINS
for (j = 0; j < i; j++) {
if (temp > (historyArray[j].getTab())) {// + '.' + historyArray[j].getObjNo())) { //for Self JOINS
for (k = i; k > j; k--) {
historyArray[k] = historyArray[k - 1];
}
historyArray[j] = sto;
break;
}
}
}
// this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects.
str = ''; // string to store Html code for history tab
for (i = 0; i < historyArray.length; i++) {
temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
str += '<div class="toggle_container">\n';
while ((historyArray[i].getTab()) === temp) { // + '.' + historyArray[i].getObjNo()) === temp) {
str += '<div class="block"> <table width ="250">';
str += '<thead><tr><td>';
if (historyArray[i].getAndOr()) {
str += '<img src="' + pmaThemeImage + 'designer/or_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="OR"></td>';
} else {
str += '<img src="' + pmaThemeImage + 'designer/and_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="AND"></td>';
}
str += '<td style="padding-left: 5px;" class="right">' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '</td>' +
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') {
var detailDescGroupBy = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDescGroupBy + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
} else {
var detailDesc = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDesc + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyEdit(' + i + ')>' + Functions.getImage('b_edit', Messages.strEdit) + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
}
str += '</tr></thead>';
i++;
if (i >= historyArray.length) {
break;
}
str += '</table></div>';
}
i--;
str += '</div>';
}
return str;
};
/**
* To change And/Or relation in history tab
*
*
* @param {int} index of historyArray where change is to be made
*
**/
DesignerHistory.andOr = function (index) {
if (historyArray[index].getAndOr()) {
historyArray[index].setAndOr(0);
} else {
historyArray[index].setAndOr(1);
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* Deletes entry in historyArray
*
* @param index index of historyArray[] which is to be deleted
*
**/
DesignerHistory.historyDelete = function (index) {
for (var k = 0; k < fromArray.length; k++) {
if (fromArray[k] === historyArray[index].getTab()) {
fromArray.splice(k, 1);
break;
}
}
historyArray.splice(index, 1);
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* To show where,rename,aggregate,having forms to edit a object
*
* @param{int} index index of historyArray where change is to be made
*
**/
DesignerHistory.historyEdit = function (index) {
gIndex = index;
var type = historyArray[index].getType();
if (type === 'Where') {
document.getElementById('eQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('query_where').style.left = '530px';
document.getElementById('query_where').style.top = '130px';
document.getElementById('query_where').style.position = 'absolute';
document.getElementById('query_where').style.zIndex = '103';
document.getElementById('query_where').style.visibility = 'visible';
document.getElementById('query_where').style.display = 'block';
}
if (type === 'Having') {
document.getElementById('hQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('hoperator').value = historyArray[index].getObj().getOperator();
document.getElementById('query_having').style.left = '530px';
document.getElementById('query_having').style.top = '130px';
document.getElementById('query_having').style.position = 'absolute';
document.getElementById('query_having').style.zIndex = '103';
document.getElementById('query_having').style.visibility = 'visible';
document.getElementById('query_having').style.display = 'block';
}
if (type === 'Rename') {
document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo();
document.getElementById('query_rename_to').style.left = '530px';
document.getElementById('query_rename_to').style.top = '130px';
document.getElementById('query_rename_to').style.position = 'absolute';
document.getElementById('query_rename_to').style.zIndex = '103';
document.getElementById('query_rename_to').style.visibility = 'visible';
document.getElementById('query_rename_to').style.display = 'block';
}
if (type === 'Aggregate') {
document.getElementById('e_operator').value = historyArray[index].getObj().getOperator();
document.getElementById('query_Aggregate').style.left = '530px';
document.getElementById('query_Aggregate').style.top = '130px';
document.getElementById('query_Aggregate').style.position = 'absolute';
document.getElementById('query_Aggregate').style.zIndex = '103';
document.getElementById('query_Aggregate').style.visibility = 'visible';
document.getElementById('query_Aggregate').style.display = 'block';
}
};
/**
* Make changes in historyArray when Edit button is clicked
* checks for the type of object and then sets the new value
*
* @param index index of historyArray where change is to be made
**/
DesignerHistory.edit = function (type) {
if (type === 'Rename') {
if (document.getElementById('e_rename').value !== '') {
historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value);
document.getElementById('e_rename').value = '';
}
document.getElementById('query_rename_to').style.visibility = 'hidden';
}
if (type === 'Aggregate') {
if (document.getElementById('e_operator').value !== '---') {
historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value);
document.getElementById('e_operator').value = '---';
}
document.getElementById('query_Aggregate').style.visibility = 'hidden';
}
if (type === 'Where') {
if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value);
}
document.getElementById('query_where').style.visibility = 'hidden';
}
if (type === 'Having') {
if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value);
historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value);
}
document.getElementById('query_having').style.visibility = 'hidden';
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* history object closure
*
* @param nColumnName name of the column on which conditions are put
* @param nObj object details(where,rename,orderby,groupby,aggregate)
* @param nTab table name of the column on which conditions are applied
* @param nObjNo object no used for inner join
* @param nType type of object
*
**/
DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) {
var andOr;
var obj;
var tab;
var columnName;
var objNo;
var type;
this.setColumnName = function (nColumnName) {
columnName = nColumnName;
};
this.getColumnName = function () {
return columnName;
};
this.setAndOr = function (nAndOr) {
andOr = nAndOr;
};
this.getAndOr = function () {
return andOr;
};
this.getRelation = function () {
return andOr;
};
this.setObj = function (nObj) {
obj = nObj;
};
this.getObj = function () {
return obj;
};
this.setTab = function (nTab) {
tab = nTab;
};
this.getTab = function () {
return tab;
};
this.setObjNo = function (nObjNo) {
objNo = nObjNo;
};
this.getObjNo = function () {
return objNo;
};
this.setType = function (nType) {
type = nType;
};
this.getType = function () {
return type;
};
this.setObjNo(nObjNo);
this.setTab(nTab);
this.setAndOr(0);
this.setObj(nObj);
this.setColumnName(nColumnName);
this.setType(nType);
};
/**
* where object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
*
**/
DesignerHistory.Where = function (nRelationOperator, nQuery) {
var relationOperator;
var query;
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
};
/**
* Orderby object closure
*
* @param nOrder order, ASC or DESC
*/
DesignerHistory.OrderBy = function (nOrder) {
var order;
this.setOrder = function (nOrder) {
order = nOrder;
};
this.getOrder = function () {
return order;
};
this.setOrder(nOrder);
};
/**
* Having object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
* @param nOperator operator
**/
DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) {
var relationOperator;
var query;
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.getOperator = function () {
return operator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
this.setOperator(nOperator);
};
/**
* rename object closure,makes an object with all information of rename
*
* @param nRenameTo new name information
*
**/
DesignerHistory.Rename = function (nRenameTo) {
var renameTo;
this.setRenameTo = function (nRenameTo) {
renameTo = nRenameTo;
};
this.getRenameTo = function () {
return renameTo;
};
this.setRenameTo(nRenameTo);
};
/**
* aggregate object closure
*
* @param nOperator aggregte operator
*
**/
DesignerHistory.Aggregate = function (nOperator) {
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.getOperator = function () {
return operator;
};
this.setOperator(nOperator);
};
/**
* This function returns unique element from an array
*
* @param arrayName array from which duplicate elem are to be removed.
* @return unique array
*/
DesignerHistory.unique = function (arrayName) {
var newArray = [];
uniquetop:
for (var i = 0; i < arrayName.length; i++) {
for (var j = 0; j < newArray.length; j++) {
if (newArray[j] === arrayName[i]) {
continue uniquetop;
}
}
newArray[newArray.length] = arrayName[i];
}
return newArray;
};
/**
* This function takes in array and a value as input and returns 1 if values is present in array
* else returns -1
*
* @param arrayName array
* @param value value which is to be searched in the array
*/
DesignerHistory.found = function (arrayName, value) {
for (var i = 0; i < arrayName.length; i++) {
if (arrayName[i] === value) {
return 1;
}
}
return -1;
};
/**
* This function concatenates two array
*
* @params add array elements of which are pushed in
* @params arr array in which elements are added
*/
DesignerHistory.addArray = function (add, arr) {
for (var i = 0; i < add.length; i++) {
arr.push(add[i]);
}
return arr;
};
/**
* This function removes all elements present in one array from the other.
*
* @params rem array from which each element is removed from other array.
* @params arr array from which elements are removed.
*
*/
DesignerHistory.removeArray = function (rem, arr) {
for (var i = 0; i < rem.length; i++) {
for (var j = 0; j < arr.length; j++) {
if (rem[i] === arr[j]) {
arr.splice(j, 1);
}
}
}
return arr;
};
/**
* This function builds the groupby clause from history object
*
*/
DesignerHistory.queryGroupBy = function () {
var i;
var str = '';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'GroupBy') {
str += '`' + historyArray[i].getColumnName() + '`, ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Having clause from the history object.
*
*/
DesignerHistory.queryHaving = function () {
var i;
var and = '(';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'Having') {
if (historyArray[i].getObj().getOperator() !== 'None') {
and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator();
and += ' ' + historyArray[i].getObj().getQuery() + ', ';
} else {
and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', ';
}
}
}
if (and === '(') {
and = '';
} else {
and = and.substr(0, and.length - 2) + ')';
}
return and;
};
/**
* This function builds the orderby clause from the history object.
*
*/
DesignerHistory.queryOrderBy = function () {
var i;
var str = '';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'OrderBy') {
str += '`' + historyArray[i].getColumnName() + '` ' +
historyArray[i].getObj().getOrder() + ', ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Where clause from the history object.
*
*/
DesignerHistory.queryWhere = function () {
var i;
var and = '(';
var or = '(';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'Where') {
if (historyArray[i].getAndOr() === 0) {
and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
and += ' AND ';
} else {
or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
or += ' OR ';
}
}
}
if (or !== '(') {
or = or.substring(0, (or.length - 4)) + ')';
} else {
or = '';
}
if (and !== '(') {
and = and.substring(0, (and.length - 5)) + ')';
} else {
and = '';
}
if (or !== '') {
and = and + ' OR ' + or + ' )';
}
return and;
};
DesignerHistory.checkAggregate = function (idThis) {
var i;
for (i = 0; i < historyArray.length; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Aggregate') {
return historyArray[i].getObj().getOperator() + '(' + idThis + ')';
}
}
return '';
};
DesignerHistory.checkRename = function (idThis) {
var i;
for (i = 0; i < historyArray.length; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Rename') {
return ' AS `' + historyArray[i].getObj().getRenameTo() + '`';
}
}
return '';
};
/**
* This function builds from clause of query
* makes automatic joins.
*
*
*/
DesignerHistory.queryFrom = function () {
var i;
var tabLeft = [];
var tabUsed = [];
var tTabLeft = [];
var temp;
var query = '';
var quer = '';
var parts = [];
var tArray = [];
tArray = fromArray;
var K = 0;
var k;
var key;
var key2;
var key3;
var parts1;
// the constraints that have been used in the LEFT JOIN
var constraintsAdded = [];
for (i = 0; i < historyArray.length; i++) {
fromArray.push(historyArray[i].getTab());
}
fromArray = DesignerHistory.unique(fromArray);
tabLeft = fromArray;
temp = tabLeft.shift();
quer = '`' + temp + '`';
tabUsed.push(temp);
// if master table (key2) matches with tab used get all keys and check if tab_left matches
// after this check if master table (key2) matches with tab left then check if any foreign matches with master .
for (i = 0; i < 2; i++) {
for (K in contr) {
for (key in contr[K]) {// contr name
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabUsed, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabLeft, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
K = 0;
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
for (K in contr) {
for (key in contr[K]) {
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabLeft, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabUsed, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
}
for (k in tabLeft) {
quer += ' , `' + tabLeft[k] + '`';
}
query = quer + query;
fromArray = tArray;
return query;
};
/**
* This function is the main function for query building.
* uses history object details for this.
*
* @uses DesignerHistory.queryWhere()
* @uses DesignerHistory.queryGroupBy()
* @uses DesignerHistory.queryHaving()
* @uses DesignerHistory.queryOrderBy()
*/
DesignerHistory.buildQuery = function () {
var qSelect = 'SELECT ';
var temp;
if (selectField.length > 0) {
for (var i = 0; i < selectField.length; i++) {
temp = DesignerHistory.checkAggregate(selectField[i]);
if (temp !== '') {
qSelect += temp;
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += temp + ', ';
} else {
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += selectField[i] + temp + ', ';
}
}
qSelect = qSelect.substring(0, qSelect.length - 2);
} else {
qSelect += '* ';
}
qSelect += '\nFROM ' + DesignerHistory.queryFrom();
var qWhere = DesignerHistory.queryWhere();
if (qWhere !== '') {
qSelect += '\nWHERE ' + qWhere;
}
var qGroupBy = DesignerHistory.queryGroupBy();
if (qGroupBy !== '') {
qSelect += '\nGROUP BY ' + qGroupBy;
}
var qHaving = DesignerHistory.queryHaving();
if (qHaving !== '') {
qSelect += '\nHAVING ' + qHaving;
}
var qOrderBy = DesignerHistory.queryOrderBy();
if (qOrderBy !== '') {
qSelect += '\nORDER BY ' + qOrderBy;
}
/**
* @var button_options Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {};
buttonOptions[Messages.strClose] = function () {
$(this).dialog('close');
};
buttonOptions[Messages.strSubmit] = function () {
if (vqbEditor) {
var $elm = $ajaxDialog.find('textarea');
vqbEditor.save();
$elm.val(vqbEditor.getValue());
}
$('#vqb_form').trigger('submit');
};
var $ajaxDialog = $('#box').dialog({
appendTo: '#page_content',
width: 500,
buttons: buttonOptions,
modal: true,
title: 'SELECT'
});
// Attach syntax highlighted editor to query dialog
/**
* @var $elm jQuery object containing the reference
* to the query textarea.
*/
var $elm = $ajaxDialog.find('textarea');
if (! vqbEditor) {
vqbEditor = Functions.getSqlEditor($elm);
}
if (vqbEditor) {
vqbEditor.setValue(qSelect);
vqbEditor.focus();
} else {
$elm.val(qSelect);
$elm.trigger('focus');
}
};
AJAX.registerTeardown('designer/history.js', function () {
vqbEditor = null;
historyArray = [];
selectField = [];
$('#ok_edit_rename').off('click');
$('#ok_edit_having').off('click');
$('#ok_edit_Aggr').off('click');
$('#ok_edit_where').off('click');
});
AJAX.registerOnload('designer/history.js', function () {
$('#ok_edit_rename').on('click', function () {
DesignerHistory.edit('Rename');
});
$('#ok_edit_having').on('click', function () {
DesignerHistory.edit('Having');
});
$('#ok_edit_Aggr').on('click', function () {
DesignerHistory.edit('Aggregate');
});
$('#ok_edit_where').on('click', function () {
DesignerHistory.edit('Where');
});
$('#ab').accordion({ collapsible : true, active : 'none' });
});

View File

@ -1,75 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Initialises the data required to run Designer, then fires it up.
*/
/* global DesignerOfflineDB */ // js/designer/database.js
/* global DesignerHistory */ // js/designer/history.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerPage */ // js/designer/page.js
/* global designerConfig */ // templates/database/designer/main.twig
/* eslint-disable no-unused-vars */
var jTabs;
var hTabs;
var contr;
var displayField;
var server;
var selectedPage;
/* eslint-enable no-unused-vars */
var db;
var designerTablesEnabled;
AJAX.registerTeardown('designer/init.js', function () {
$('.trigger').off('click');
});
AJAX.registerOnload('designer/init.js', function () {
$('.trigger').on('click', function () {
$('.panel').toggle('fast');
$(this).toggleClass('active');
$('#ab').accordion('refresh');
return false;
});
jTabs = designerConfig.scriptTables.j_tabs;
hTabs = designerConfig.scriptTables.h_tabs;
contr = designerConfig.scriptContr;
displayField = designerConfig.scriptDisplayField;
server = designerConfig.server;
db = designerConfig.db;
selectedPage = designerConfig.displayPage;
designerTablesEnabled = designerConfig.tablesEnabled;
DesignerMove.main();
if (! designerTablesEnabled) {
DesignerOfflineDB.open(function (success) {
if (success) {
DesignerPage.showTablesInLandingPage(db);
}
});
}
$('#query_Aggregate_Button').on('click', function () {
document.getElementById('query_Aggregate').style.display = 'none';
});
$('#query_having_button').on('click', function () {
document.getElementById('query_having').style.display = 'none';
});
$('#query_rename_to_button').on('click', function () {
document.getElementById('query_rename_to').style.display = 'none';
});
$('#build_query_button').on('click', function () {
DesignerHistory.buildQuery('SQL Query on Database', 0);
});
$('#query_where_button').on('click', function () {
document.getElementById('query_where').style.display = 'none';
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,169 +0,0 @@
/* global DesignerOfflineDB */ // js/designer/database.js
// eslint-disable-next-line no-unused-vars
/* global db, selectedPage:writable */ // js/designer/init.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerObjects */ // js/designer/objects.js
var DesignerPage = {};
DesignerPage.showTablesInLandingPage = function (db) {
DesignerPage.loadFirstPage(db, function (page) {
if (page) {
DesignerPage.loadHtmlForPage(page.pgNr);
selectedPage = page.pgNr;
} else {
DesignerPage.showNewPageTables(true);
}
});
};
DesignerPage.saveToNewPage = function (db, pageName, tablePositions, callback) {
DesignerPage.createNewPage(db, pageName, function (page) {
if (page) {
var tblCords = [];
var saveCallback = function (id) {
tblCords.push(id);
if (tablePositions.length === tblCords.length) {
page.tblCords = tblCords;
DesignerOfflineDB.addObject('pdf_pages', page);
}
};
for (var pos = 0; pos < tablePositions.length; pos++) {
tablePositions[pos].pdfPgNr = page.pgNr;
DesignerPage.saveTablePositions(tablePositions[pos], saveCallback);
}
if (typeof callback !== 'undefined') {
callback(page);
}
}
});
};
DesignerPage.saveToSelectedPage = function (db, pageId, pageName, tablePositions, callback) {
DesignerPage.deletePage(pageId);
DesignerPage.saveToNewPage(db, pageName, tablePositions, function (page) {
if (typeof callback !== 'undefined') {
callback(page);
}
selectedPage = page.pgNr;
});
};
DesignerPage.createNewPage = function (db, pageName, callback) {
var newPage = new DesignerObjects.PdfPage(db, pageName);
DesignerOfflineDB.addObject('pdf_pages', newPage, function (pgNr) {
newPage.pgNr = pgNr;
if (typeof callback !== 'undefined') {
callback(newPage);
}
});
};
DesignerPage.saveTablePositions = function (positions, callback) {
DesignerOfflineDB.addObject('table_coords', positions, callback);
};
DesignerPage.createPageList = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var html = '';
for (var p = 0; p < pages.length; p++) {
var page = pages[p];
if (page.dbName === db) {
html += '<option value="' + page.pgNr + '">';
html += Functions.escapeHtml(page.pageDescr) + '</option>';
}
}
if (typeof callback !== 'undefined') {
callback(html);
}
});
};
DesignerPage.deletePage = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
if (page) {
for (var i = 0; i < page.tblCords.length; i++) {
DesignerOfflineDB.deleteObject('table_coords', page.tblCords[i]);
}
DesignerOfflineDB.deleteObject('pdf_pages', pageId, callback);
}
});
};
DesignerPage.loadFirstPage = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var firstPage = null;
for (var i = 0; i < pages.length; i++) {
var page = pages[i];
if (page.dbName === db) {
// give preference to a page having same name as the db
if (page.pageDescr === db) {
callback(page);
return;
}
if (firstPage === null) {
firstPage = page;
}
}
}
callback(firstPage);
});
};
DesignerPage.showNewPageTables = function (check) {
var allTables = $('#id_scroll_tab').find('td input:checkbox');
allTables.prop('checked', check);
for (var tab = 0; tab < allTables.length; tab++) {
var input = allTables[tab];
if (input.value) {
var element = document.getElementById(input.value);
element.style.top = DesignerPage.getRandom(550, 20) + 'px';
element.style.left = DesignerPage.getRandom(700, 20) + 'px';
DesignerMove.visibleTab(input, input.value);
}
}
selectedPage = -1;
$('#page_name').text(Messages.strUntitled);
DesignerMove.markUnsaved();
};
DesignerPage.loadHtmlForPage = function (pageId) {
DesignerPage.showNewPageTables(false);
DesignerPage.loadPageObjects(pageId, function (page, tblCords) {
$('#name-panel').find('#page_name').text(page.pageDescr);
DesignerMove.markSaved();
for (var t = 0; t < tblCords.length; t++) {
var tbId = db + '.' + tblCords[t].tableName;
var table = document.getElementById(tbId);
table.style.top = tblCords[t].y + 'px';
table.style.left = tblCords[t].x + 'px';
var checkbox = document.getElementById('check_vis_' + tbId);
checkbox.checked = true;
DesignerMove.visibleTab(checkbox, checkbox.value);
}
selectedPage = page.pgNr;
});
};
DesignerPage.loadPageObjects = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
var tblCords = [];
var count = page.tblCords.length;
for (var i = 0; i < count; i++) {
DesignerOfflineDB.loadObject('table_coords', page.tblCords[i], function (tblCord) {
tblCords.push(tblCord);
if (tblCords.length === count) {
if (typeof callback !== 'undefined') {
callback(page, tblCords);
}
}
});
}
});
};
DesignerPage.getRandom = function (max, min) {
var val = Math.random() * (max - min) + min;
return Math.floor(val);
};

View File

@ -1,367 +0,0 @@
/**
* Definition of links to MySQL documentation.
*/
// eslint-disable-next-line no-unused-vars
var mysqlDocKeyword = {
/* Multi word */
'CHARACTER SET': ['charset'],
'SHOW AUTHORS': ['show-authors'],
'SHOW BINARY LOGS': ['show-binary-logs'],
'SHOW BINLOG EVENTS': ['show-binlog-events'],
'SHOW CHARACTER SET': ['show-character-set'],
'SHOW COLLATION': ['show-collation'],
'SHOW COLUMNS': ['show-columns'],
'SHOW CONTRIBUTORS': ['show-contributors'],
'SHOW CREATE DATABASE': ['show-create-database'],
'SHOW CREATE EVENT': ['show-create-event'],
'SHOW CREATE FUNCTION': ['show-create-function'],
'SHOW CREATE PROCEDURE': ['show-create-procedure'],
'SHOW CREATE TABLE': ['show-create-table'],
'SHOW CREATE TRIGGER': ['show-create-trigger'],
'SHOW CREATE VIEW': ['show-create-view'],
'SHOW DATABASES': ['show-databases'],
'SHOW ENGINE': ['show-engine'],
'SHOW ENGINES': ['show-engines'],
'SHOW ERRORS': ['show-errors'],
'SHOW EVENTS': ['show-events'],
'SHOW FUNCTION CODE': ['show-function-code'],
'SHOW FUNCTION STATUS': ['show-function-status'],
'SHOW GRANTS': ['show-grants'],
'SHOW INDEX': ['show-index'],
'SHOW MASTER STATUS': ['show-master-status'],
'SHOW OPEN TABLES': ['show-open-tables'],
'SHOW PLUGINS': ['show-plugins'],
'SHOW PRIVILEGES': ['show-privileges'],
'SHOW PROCEDURE CODE': ['show-procedure-code'],
'SHOW PROCEDURE STATUS': ['show-procedure-status'],
'SHOW PROCESSLIST': ['show-processlist'],
'SHOW PROFILE': ['show-profile'],
'SHOW PROFILES': ['show-profiles'],
'SHOW RELAYLOG EVENTS': ['show-relaylog-events'],
'SHOW SLAVE HOSTS': ['show-slave-hosts'],
'SHOW SLAVE STATUS': ['show-slave-status'],
'SHOW STATUS': ['show-status'],
'SHOW TABLE STATUS': ['show-table-status'],
'SHOW TABLES': ['show-tables'],
'SHOW TRIGGERS': ['show-triggers'],
'SHOW VARIABLES': ['show-variables'],
'SHOW WARNINGS': ['show-warnings'],
'LOAD DATA INFILE': ['load-data'],
'LOAD XML': ['load-xml'],
'LOCK TABLES': ['lock-tables'],
'UNLOCK TABLES': ['lock-tables'],
'ALTER DATABASE': ['alter-database'],
'ALTER EVENT': ['alter-event'],
'ALTER LOGFILE GROUP': ['alter-logfile-group'],
'ALTER FUNCTION': ['alter-function'],
'ALTER PROCEDURE': ['alter-procedure'],
'ALTER SERVER': ['alter-server'],
'ALTER TABLE': ['alter-table'],
'ALTER TABLESPACE': ['alter-tablespace'],
'ALTER VIEW': ['alter-view'],
'CREATE DATABASE': ['create-database'],
'CREATE EVENT': ['create-event'],
'CREATE FUNCTION': ['create-function'],
'CREATE INDEX': ['create-index'],
'CREATE LOGFILE GROUP': ['create-logfile-group'],
'CREATE PROCEDURE': ['create-procedure'],
'CREATE SERVER': ['create-server'],
'CREATE TABLE': ['create-table'],
'CREATE TABLESPACE': ['create-tablespace'],
'CREATE TRIGGER': ['create-trigger'],
'CREATE VIEW': ['create-view'],
'DROP DATABASE': ['drop-database'],
'DROP EVENT': ['drop-event'],
'DROP FUNCTION': ['drop-function'],
'DROP INDEX': ['drop-index'],
'DROP LOGFILE GROUP': ['drop-logfile-group'],
'DROP PROCEDURE': ['drop-procedure'],
'DROP SERVER': ['drop-server'],
'DROP TABLE': ['drop-table'],
'DROP TABLESPACE': ['drop-tablespace'],
'DROP TRIGGER': ['drop-trigger'],
'DROP VIEW': ['drop-view'],
'RENAME TABLE': ['rename-table'],
'TRUNCATE TABLE': ['truncate-table'],
/* Statements */
'SELECT': ['select'],
'SET': ['set'],
'EXPLAIN': ['explain'],
'DESCRIBE': ['describe'],
'DELETE': ['delete'],
'SHOW': ['show'],
'UPDATE': ['update'],
'INSERT': ['insert'],
'REPLACE': ['replace'],
'CALL': ['call'],
'DO': ['do'],
'HANDLER': ['handler'],
'COLLATE': ['charset-collations'],
/* Functions */
'ABS': ['mathematical-functions', 'function_abs'],
'ACOS': ['mathematical-functions', 'function_acos'],
'ADDDATE': ['date-and-time-functions', 'function_adddate'],
'ADDTIME': ['date-and-time-functions', 'function_addtime'],
'AES_DECRYPT': ['encryption-functions', 'function_aes_decrypt'],
'AES_ENCRYPT': ['encryption-functions', 'function_aes_encrypt'],
'AND': ['logical-operators', 'operator_and'],
'ASCII': ['string-functions', 'function_ascii'],
'ASIN': ['mathematical-functions', 'function_asin'],
'ATAN2': ['mathematical-functions', 'function_atan2'],
'ATAN': ['mathematical-functions', 'function_atan'],
'AVG': ['group-by-functions', 'function_avg'],
'BENCHMARK': ['information-functions', 'function_benchmark'],
'BIN': ['string-functions', 'function_bin'],
'BINARY': ['cast-functions', 'operator_binary'],
'BIT_AND': ['group-by-functions', 'function_bit_and'],
'BIT_COUNT': ['bit-functions', 'function_bit_count'],
'BIT_LENGTH': ['string-functions', 'function_bit_length'],
'BIT_OR': ['group-by-functions', 'function_bit_or'],
'BIT_XOR': ['group-by-functions', 'function_bit_xor'],
'CASE': ['control-flow-functions', 'operator_case'],
'CAST': ['cast-functions', 'function_cast'],
'CEIL': ['mathematical-functions', 'function_ceil'],
'CEILING': ['mathematical-functions', 'function_ceiling'],
'CHAR_LENGTH': ['string-functions', 'function_char_length'],
'CHAR': ['string-functions', 'function_char'],
'CHARACTER_LENGTH': ['string-functions', 'function_character_length'],
'CHARSET': ['information-functions', 'function_charset'],
'COALESCE': ['comparison-operators', 'function_coalesce'],
'COERCIBILITY': ['information-functions', 'function_coercibility'],
'COLLATION': ['information-functions', 'function_collation'],
'COMPRESS': ['encryption-functions', 'function_compress'],
'CONCAT_WS': ['string-functions', 'function_concat_ws'],
'CONCAT': ['string-functions', 'function_concat'],
'CONNECTION_ID': ['information-functions', 'function_connection_id'],
'CONV': ['mathematical-functions', 'function_conv'],
'CONVERT_TZ': ['date-and-time-functions', 'function_convert_tz'],
'Convert': ['cast-functions', 'function_convert'],
'COS': ['mathematical-functions', 'function_cos'],
'COT': ['mathematical-functions', 'function_cot'],
'COUNT': ['group-by-functions', 'function_count'],
'CRC32': ['mathematical-functions', 'function_crc32'],
'CURDATE': ['date-and-time-functions', 'function_curdate'],
'CURRENT_DATE': ['date-and-time-functions', 'function_current_date'],
'CURRENT_TIME': ['date-and-time-functions', 'function_current_time'],
'CURRENT_TIMESTAMP': ['date-and-time-functions', 'function_current_timestamp'],
'CURRENT_USER': ['information-functions', 'function_current_user'],
'CURTIME': ['date-and-time-functions', 'function_curtime'],
'DATABASE': ['information-functions', 'function_database'],
'DATE_ADD': ['date-and-time-functions', 'function_date_add'],
'DATE_FORMAT': ['date-and-time-functions', 'function_date_format'],
'DATE_SUB': ['date-and-time-functions', 'function_date_sub'],
'DATE': ['date-and-time-functions', 'function_date'],
'DATEDIFF': ['date-and-time-functions', 'function_datediff'],
'DAY': ['date-and-time-functions', 'function_day'],
'DAYNAME': ['date-and-time-functions', 'function_dayname'],
'DAYOFMONTH': ['date-and-time-functions', 'function_dayofmonth'],
'DAYOFWEEK': ['date-and-time-functions', 'function_dayofweek'],
'DAYOFYEAR': ['date-and-time-functions', 'function_dayofyear'],
'DECLARE': ['declare', 'declare'],
'DECODE': ['encryption-functions', 'function_decode'],
'DEFAULT': ['miscellaneous-functions', 'function_default'],
'DEGREES': ['mathematical-functions', 'function_degrees'],
'DES_DECRYPT': ['encryption-functions', 'function_des_decrypt'],
'DES_ENCRYPT': ['encryption-functions', 'function_des_encrypt'],
'DIV': ['arithmetic-functions', 'operator_div'],
'ELT': ['string-functions', 'function_elt'],
'ENCODE': ['encryption-functions', 'function_encode'],
'ENCRYPT': ['encryption-functions', 'function_encrypt'],
'EXP': ['mathematical-functions', 'function_exp'],
'EXPORT_SET': ['string-functions', 'function_export_set'],
'EXTRACT': ['date-and-time-functions', 'function_extract'],
'ExtractValue': ['xml-functions', 'function_extractvalue'],
'FIELD': ['string-functions', 'function_field'],
'FIND_IN_SET': ['string-functions', 'function_find_in_set'],
'FLOOR': ['mathematical-functions', 'function_floor'],
'FORMAT': ['string-functions', 'function_format'],
'FOUND_ROWS': ['information-functions', 'function_found_rows'],
'FROM_DAYS': ['date-and-time-functions', 'function_from_days'],
'FROM_UNIXTIME': ['date-and-time-functions', 'function_from_unixtime'],
'GET_FORMAT': ['date-and-time-functions', 'function_get_format'],
'GET_LOCK': ['miscellaneous-functions', 'function_get_lock'],
'GREATEST': ['comparison-operators', 'function_greatest'],
'GROUP_CONCAT': ['group-by-functions', 'function_group_concat'],
'HEX': ['string-functions', 'function_hex'],
'HOUR': ['date-and-time-functions', 'function_hour'],
'IF': ['control-flow-functions', 'function_if'],
'IFNULL': ['control-flow-functions', 'function_ifnull'],
'IN': ['comparison-operators', 'function_in'],
'INET_ATON': ['miscellaneous-functions', 'function_inet_aton'],
'INET_NTOA': ['miscellaneous-functions', 'function_inet_ntoa'],
'INSTR': ['string-functions', 'function_instr'],
'INTERVAL': ['comparison-operators', 'function_interval'],
'IS_FREE_LOCK': ['miscellaneous-functions', 'function_is_free_lock'],
'IS_USED_LOCK': ['miscellaneous-functions', 'function_is_used_lock'],
'IS': ['comparison-operators', 'operator_is'],
'ISNULL': ['comparison-operators', 'function_isnull'],
'LAST_DAY': ['date-and-time-functions', 'function_last_day'],
'LAST_INSERT_ID': ['information-functions', 'function_last_insert_id'],
'LCASE': ['string-functions', 'function_lcase'],
'LEAST': ['comparison-operators', 'function_least'],
'LEFT': ['string-functions', 'function_left'],
'LENGTH': ['string-functions', 'function_length'],
'LIKE': ['string-comparison-functions', 'operator_like'],
'LN': ['mathematical-functions', 'function_ln'],
'LOAD_FILE': ['string-functions', 'function_load_file'],
'LOCALTIME': ['date-and-time-functions', 'function_localtime'],
'LOCALTIMESTAMP': ['date-and-time-functions', 'function_localtimestamp'],
'LOCATE': ['string-functions', 'function_locate'],
'LOG10': ['mathematical-functions', 'function_log10'],
'LOG2': ['mathematical-functions', 'function_log2'],
'LOG': ['mathematical-functions', 'function_log'],
'LOWER': ['string-functions', 'function_lower'],
'LPAD': ['string-functions', 'function_lpad'],
'LTRIM': ['string-functions', 'function_ltrim'],
'MAKE_SET': ['string-functions', 'function_make_set'],
'MAKEDATE': ['date-and-time-functions', 'function_makedate'],
'MAKETIME': ['date-and-time-functions', 'function_maketime'],
'MASTER_POS_WAIT': ['miscellaneous-functions', 'function_master_pos_wait'],
'MATCH': ['fulltext-search', 'function_match'],
'MAX': ['group-by-functions', 'function_max'],
'MD5': ['encryption-functions', 'function_md5'],
'MICROSECOND': ['date-and-time-functions', 'function_microsecond'],
'MID': ['string-functions', 'function_mid'],
'MIN': ['group-by-functions', 'function_min'],
'MINUTE': ['date-and-time-functions', 'function_minute'],
'MOD': ['mathematical-functions', 'function_mod'],
'MONTH': ['date-and-time-functions', 'function_month'],
'MONTHNAME': ['date-and-time-functions', 'function_monthname'],
'NAME_CONST': ['miscellaneous-functions', 'function_name_const'],
'NOT': ['logical-operators', 'operator_not'],
'NOW': ['date-and-time-functions', 'function_now'],
'NULLIF': ['control-flow-functions', 'function_nullif'],
'OCT': ['mathematical-functions', 'function_oct'],
'OCTET_LENGTH': ['string-functions', 'function_octet_length'],
'OLD_PASSWORD': ['encryption-functions', 'function_old_password'],
'OR': ['logical-operators', 'operator_or'],
'ORD': ['string-functions', 'function_ord'],
'PASSWORD': ['encryption-functions', 'function_password'],
'PERIOD_ADD': ['date-and-time-functions', 'function_period_add'],
'PERIOD_DIFF': ['date-and-time-functions', 'function_period_diff'],
'PI': ['mathematical-functions', 'function_pi'],
'POSITION': ['string-functions', 'function_position'],
'POW': ['mathematical-functions', 'function_pow'],
'POWER': ['mathematical-functions', 'function_power'],
'QUARTER': ['date-and-time-functions', 'function_quarter'],
'QUOTE': ['string-functions', 'function_quote'],
'RADIANS': ['mathematical-functions', 'function_radians'],
'RAND': ['mathematical-functions', 'function_rand'],
'REGEXP': ['regexp', 'operator_regexp'],
'RELEASE_LOCK': ['miscellaneous-functions', 'function_release_lock'],
'REPEAT': ['string-functions', 'function_repeat'],
'REVERSE': ['string-functions', 'function_reverse'],
'RIGHT': ['string-functions', 'function_right'],
'RLIKE': ['regexp', 'operator_rlike'],
'ROUND': ['mathematical-functions', 'function_round'],
'ROW_COUNT': ['information-functions', 'function_row_count'],
'RPAD': ['string-functions', 'function_rpad'],
'RTRIM': ['string-functions', 'function_rtrim'],
'SCHEMA': ['information-functions', 'function_schema'],
'SEC_TO_TIME': ['date-and-time-functions', 'function_sec_to_time'],
'SECOND': ['date-and-time-functions', 'function_second'],
'SESSION_USER': ['information-functions', 'function_session_user'],
'SHA': ['encryption-functions', 'function_sha1'],
'SHA1': ['encryption-functions', 'function_sha1'],
'SIGN': ['mathematical-functions', 'function_sign'],
'SIN': ['mathematical-functions', 'function_sin'],
'SLEEP': ['miscellaneous-functions', 'function_sleep'],
'SOUNDEX': ['string-functions', 'function_soundex'],
'SPACE': ['string-functions', 'function_space'],
'SQRT': ['mathematical-functions', 'function_sqrt'],
'STD': ['group-by-functions', 'function_std'],
'STDDEV_POP': ['group-by-functions', 'function_stddev_pop'],
'STDDEV_SAMP': ['group-by-functions', 'function_stddev_samp'],
'STDDEV': ['group-by-functions', 'function_stddev'],
'STR_TO_DATE': ['date-and-time-functions', 'function_str_to_date'],
'STRCMP': ['string-comparison-functions', 'function_strcmp'],
'SUBDATE': ['date-and-time-functions', 'function_subdate'],
'SUBSTR': ['string-functions', 'function_substr'],
'SUBSTRING_INDEX': ['string-functions', 'function_substring_index'],
'SUBSTRING': ['string-functions', 'function_substring'],
'SUBTIME': ['date-and-time-functions', 'function_subtime'],
'SUM': ['group-by-functions', 'function_sum'],
'SYSDATE': ['date-and-time-functions', 'function_sysdate'],
'SYSTEM_USER': ['information-functions', 'function_system_user'],
'TAN': ['mathematical-functions', 'function_tan'],
'TIME_FORMAT': ['date-and-time-functions', 'function_time_format'],
'TIME_TO_SEC': ['date-and-time-functions', 'function_time_to_sec'],
'TIME': ['date-and-time-functions', 'function_time'],
'TIMEDIFF': ['date-and-time-functions', 'function_timediff'],
'TIMESTAMP': ['date-and-time-functions', 'function_timestamp'],
'TIMESTAMPADD': ['date-and-time-functions', 'function_timestampadd'],
'TIMESTAMPDIFF': ['date-and-time-functions', 'function_timestampdiff'],
'TO_DAYS': ['date-and-time-functions', 'function_to_days'],
'TRIM': ['string-functions', 'function_trim'],
'TRUNCATE': ['mathematical-functions', 'function_truncate'],
'UCASE': ['string-functions', 'function_ucase'],
'UNCOMPRESS': ['encryption-functions', 'function_uncompress'],
'UNCOMPRESSED_LENGTH': ['encryption-functions', 'function_uncompressed_length'],
'UNHEX': ['string-functions', 'function_unhex'],
'UNIX_TIMESTAMP': ['date-and-time-functions', 'function_unix_timestamp'],
'UpdateXML': ['xml-functions', 'function_updatexml'],
'UPPER': ['string-functions', 'function_upper'],
'USER': ['information-functions', 'function_user'],
'UTC_DATE': ['date-and-time-functions', 'function_utc_date'],
'UTC_TIME': ['date-and-time-functions', 'function_utc_time'],
'UTC_TIMESTAMP': ['date-and-time-functions', 'function_utc_timestamp'],
'UUID_SHORT': ['miscellaneous-functions', 'function_uuid_short'],
'UUID': ['miscellaneous-functions', 'function_uuid'],
'VALUES': ['miscellaneous-functions', 'function_values'],
'VAR_POP': ['group-by-functions', 'function_var_pop'],
'VAR_SAMP': ['group-by-functions', 'function_var_samp'],
'VARIANCE': ['group-by-functions', 'function_variance'],
'VERSION': ['information-functions', 'function_version'],
'WEEK': ['date-and-time-functions', 'function_week'],
'WEEKDAY': ['date-and-time-functions', 'function_weekday'],
'WEEKOFYEAR': ['date-and-time-functions', 'function_weekofyear'],
'XOR': ['logical-operators', 'operator_xor'],
'YEAR': ['date-and-time-functions', 'function_year'],
'YEARWEEK': ['date-and-time-functions', 'function_yearweek'],
'SOUNDS_LIKE': ['string-functions', 'operator_sounds-like'],
'IS_NOT_NULL': ['comparison-operators', 'operator_is-not-null'],
'IS_NOT': ['comparison-operators', 'operator_is-not'],
'IS_NULL': ['comparison-operators', 'operator_is-null'],
'NOT_LIKE': ['string-comparison-functions', 'operator_not-like'],
'NOT_REGEXP': ['regexp', 'operator_not-regexp'],
'COUNT_DISTINCT': ['group-by-functions', 'function_count-distinct'],
'NOT_IN': ['comparison-operators', 'function_not-in']
};
// eslint-disable-next-line no-unused-vars
var mysqlDocBuiltin = {
'TINYINT': ['numeric-types'],
'SMALLINT': ['numeric-types'],
'MEDIUMINT': ['numeric-types'],
'INT': ['numeric-types'],
'BIGINT': ['numeric-types'],
'DECIMAL': ['numeric-types'],
'FLOAT': ['numeric-types'],
'DOUBLE': ['numeric-types'],
'REAL': ['numeric-types'],
'BIT': ['numeric-types'],
'BOOLEAN': ['numeric-types'],
'SERIAL': ['numeric-types'],
'DATE': ['date-and-time-types'],
'DATETIME': ['date-and-time-types'],
'TIMESTAMP': ['date-and-time-types'],
'TIME': ['date-and-time-types'],
'YEAR': ['date-and-time-types'],
'CHAR': ['string-types'],
'VARCHAR': ['string-types'],
'TINYTEXT': ['string-types'],
'TEXT': ['string-types'],
'MEDIUMTEXT': ['string-types'],
'LONGTEXT': ['string-types'],
'BINARY': ['string-types'],
'VARBINARY': ['string-types'],
'TINYBLOB': ['string-types'],
'MEDIUMBLOB': ['string-types'],
'BLOB': ['string-types'],
'LONGBLOB': ['string-types'],
'ENUM': ['string-types'],
'SET': ['string-types']
};

View File

@ -1,392 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
/**
* Class to handle PMA Drag and Drop Import
* feature
*/
var DragDropImport = {
/**
* @var int, count of total uploads in this view
*/
uploadCount: 0,
/**
* @var int, count of live uploads
*/
liveUploadCount: 0,
/**
* @var string array, allowed extensions
*/
allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
/**
* @var string array, allowed extensions for compressed files
*/
allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
/**
* @var obj array to store message returned by import_status.php
*/
importStatus: [],
/**
* Checks if any dropped file has valid extension or not
*
* @param file filename
*
* @return string, extension for valid extension, '' otherwise
*/
getExtension: function (file) {
var arr = file.split('.');
var ext = arr[arr.length - 1];
// check if compressed
if (jQuery.inArray(ext.toLowerCase(),
DragDropImport.allowedCompressedExtensions) !== -1) {
ext = arr[arr.length - 2];
}
// Now check for extension
if (jQuery.inArray(ext.toLowerCase(),
DragDropImport.allowedExtensions) !== -1) {
return ext;
}
return '';
},
/**
* Shows upload progress for different sql uploads
*
* @param: hash (string), hash for specific file upload
* @param: percent (float), file upload percentage
*
* @return void
*/
setProgress: function (hash, percent) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.children('progress').val(percent);
},
/**
* Function to upload the file asynchronously
*
* @param formData FormData object for a specific file
* @param hash hash of the current file upload
*
* @return void
*/
sendFileToServer: function (formData, hash) {
var uploadURL = './import.php'; // Upload URL
var jqXHR = $.ajax({
xhr: function () {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// Set progress
DragDropImport.setProgress(hash, percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: 'POST',
contentType:false,
processData: false,
cache: false,
data: formData,
success: function (data) {
DragDropImport.importFinished(hash, false, data.success);
if (!data.success) {
DragDropImport.importStatus[DragDropImport.importStatus.length] = {
hash: hash,
message: data.error
};
}
}
});
// -- provide link to cancel the upload
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize').html('<span hash="' +
hash + '" class="pma_drop_file_status" task="cancel">' +
Messages.dropImportMessageCancel + '</span>');
// -- add event listener to this link to abort upload operation
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.on('click', function () {
if ($(this).attr('task') === 'cancel') {
jqXHR.abort();
$(this).html('<span>' + Messages.dropImportMessageAborted + '</span>');
DragDropImport.importFinished(hash, true, false);
} else if ($(this).children('span').html() ===
Messages.dropImportMessageFailed) {
// -- view information
var $this = $(this);
$.each(DragDropImport.importStatus,
function (key, value) {
if (value.hash === hash) {
$('.pma_drop_result:visible').remove();
var filename = $this.parent('span').attr('data-filename');
$('body').append('<div class="pma_drop_result"><h2>' +
Messages.dropImportImportResultHeader + ' - ' +
filename + '<span class="close">x</span></h2>' + value.message + '</div>');
$('.pma_drop_result').draggable(); // to make this dialog draggable
}
});
}
});
},
/**
* Triggered when an object is dragged into the PMA UI
*
* @param event obj
*
* @return void
*/
dragEnter : function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
if (CommonParams.get('db') === '') {
$('.pma_drop_handler').html(Messages.dropImportSelectDB);
} else {
$('.pma_drop_handler').html(Messages.dropImportDropFiles);
}
$('.pma_drop_handler').fadeIn();
},
/**
* Check if dragged element contains Files
*
* @param event the event object
*
* @return bool
*/
hasFiles: function (event) {
return !(typeof event.originalEvent.dataTransfer.types === 'undefined' ||
$.inArray('Files', event.originalEvent.dataTransfer.types) < 0 ||
$.inArray(
'application/x-moz-nativeimage',
event.originalEvent.dataTransfer.types
) >= 0);
},
/**
* Triggered when dragged file is being dragged over PMA UI
*
* @param event obj
*
* @return void
*/
dragOver: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
$('.pma_drop_handler').fadeIn();
},
/**
* Triggered when dragged objects are left
*
* @param event obj
*
* @return void
*/
dragLeave: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
var $dropHandler = $('.pma_drop_handler');
$dropHandler.clearQueue().stop();
$dropHandler.fadeOut();
$dropHandler.html(Messages.dropImportDropFiles);
},
/**
* Called when upload has finished
*
* @param string, unique hash for a certain upload
* @param bool, true if upload was aborted
* @param bool, status of sql upload, as sent by server
*
* @return void
*/
importFinished: function (hash, aborted, status) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.children('progress').hide();
var icon = 'icon ic_s_success';
// -- provide link to view upload status
if (!aborted) {
if (status) {
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.html('<span>' + Messages.dropImportMessageSuccess + '</a>');
} else {
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.html('<span class="underline">' + Messages.dropImportMessageFailed +
'</a>');
icon = 'icon ic_s_error';
}
} else {
icon = 'icon ic_s_notice';
}
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.attr('task', 'info');
// Set icon
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.prepend('<img src="./themes/dot.gif" title="finished" class="' +
icon + '"> ');
// Decrease liveUploadCount by one
$('.pma_import_count').html(--DragDropImport.liveUploadCount);
if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
},
/**
* Triggered when dragged objects are dropped to UI
* From this function, the AJAX Upload operation is initiated
*
* @param event object
*
* @return void
*/
drop: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
var dbname = CommonParams.get('db');
var server = CommonParams.get('server');
// if no database is selected -- no
if (dbname !== '') {
var files = event.originalEvent.dataTransfer.files;
if (!files || files.length === 0) {
// No files actually transferred
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
return;
}
$('.pma_sql_import_status').slideDown();
for (var i = 0; i < files.length; i++) {
var ext = (DragDropImport.getExtension(files[i].name));
var hash = AJAX.hash(++DragDropImport.uploadCount);
var $sqlImportStatusDiv = $('.pma_sql_import_status div');
$sqlImportStatusDiv.append('<li data-hash="' + hash + '">' +
((ext !== '') ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') +
Functions.escapeHtml(files[i].name) + '<span class="filesize" data-filename="' +
Functions.escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) +
' kb</span></li>');
// scroll the UI to bottom
$sqlImportStatusDiv.scrollTop(
$sqlImportStatusDiv.scrollTop() + 50
); // 50 hardcoded for now
if (ext !== '') {
// Increment liveUploadCount by one
$('.pma_import_count').html(++DragDropImport.liveUploadCount);
$('.pma_sql_import_status h2 .close').fadeOut();
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.append('<br><progress max="100" value="2"></progress>');
// uploading
var fd = new FormData();
fd.append('import_file', files[i]);
fd.append('noplugin', Math.random().toString(36).substring(2, 12));
fd.append('db', dbname);
fd.append('server', server);
fd.append('token', CommonParams.get('token'));
fd.append('import_type', 'database');
// todo: method to find the value below
fd.append('MAX_FILE_SIZE', '4194304');
// todo: method to find the value below
fd.append('charset_of_file','utf-8');
// todo: method to find the value below
fd.append('allow_interrupt', 'yes');
fd.append('skip_queries', '0');
fd.append('format',ext);
fd.append('sql_compatibility','NONE');
fd.append('sql_no_auto_value_on_zero','something');
fd.append('ajax_request','true');
fd.append('hash', hash);
// init uploading
DragDropImport.sendFileToServer(fd, hash);
} else if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
}
}
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
}
};
/**
* Called when some user drags, dragover, leave
* a file to the PMA UI
* @param object Event data
* @return void
*/
$(document).on('dragenter', DragDropImport.dragEnter);
$(document).on('dragover', DragDropImport.dragOver);
$(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave);
// when file is dropped to PMA UI
$(document).on('drop', 'body', DragDropImport.drop);
// minimizing-maximising the sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
if ($(this).attr('toggle') === 'off') {
$('.pma_sql_import_status div').css('height','270px');
$(this).attr('toggle','on');
$(this).html('-'); // to minimize
} else {
$('.pma_sql_import_status div').css('height','0px');
$(this).attr('toggle','off');
$(this).html('+'); // to maximise
}
});
// closing sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .close', function () {
$('.pma_sql_import_status').fadeOut(function () {
$('.pma_sql_import_status div').html('');
DragDropImport.importStatus = []; // clear the message array
});
});
// Closing the import result box
$(document).on('click', '.pma_drop_result h2 .close', function () {
$(this).parent('h2').parent('div').remove();
});

View File

@ -1,327 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* global TraceKit */ // js/vendor/tracekit.js
/**
* general function, usually for data manipulation pages
*
*/
var ErrorReport = {
/**
* @var object stores the last exception info
*/
lastException: null,
/**
* handles thrown error exceptions based on user preferences
*
* @return void
*/
errorHandler: function (exception) {
// issue: 14359
if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) {
return;
}
if (exception.name === null || typeof(exception.name) === 'undefined') {
exception.name = ErrorReport.extractExceptionName(exception);
}
ErrorReport.lastException = exception;
$.post('error_report.php', {
'ajax_request': true,
'server': CommonParams.get('server'),
'get_settings': true,
'exception_type': 'js'
}, function (data) {
if (data.success !== true) {
Functions.ajaxShowMessage(data.error, false);
return;
}
if (data.report_setting === 'ask') {
ErrorReport.showErrorNotification();
} else if (data.report_setting === 'always') {
var reportData = ErrorReport.getReportData(exception);
var postData = $.extend(reportData, {
'send_error_report': true,
'automatic': true
});
$.post('error_report.php', postData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, false);
}
});
}
});
},
/**
* Shows the modal dialog previewing the report
*
* @param exception object error report info
*
* @return void
*/
showReportDialog: function (exception) {
var reportData = ErrorReport.getReportData(exception);
/* Remove the hidden dialogs if there are*/
if ($('#error_report_dialog').length !== 0) {
$('#error_report_dialog').remove();
}
var $div = $('<div id="error_report_dialog"></div>');
$div.css('z-index', '1000');
var buttonOptions = {};
buttonOptions[Messages.strSendErrorReport] = function () {
var $dialog = $(this);
var postData = $.extend(reportData, {
'send_error_report': true,
'description': $('#report_description').val(),
'always_send': $('#always_send_checkbox')[0].checked
});
$.post('error_report.php', postData, function (data) {
$dialog.dialog('close');
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, 3000);
}
});
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
};
$.post('error_report.php', reportData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
// Show dialog if the request was successful
$div
.append(data.message)
.dialog({
title: Messages.strSubmitErrorReport,
width: 650,
modal: true,
buttons: buttonOptions,
close: function () {
$(this).remove();
}
});
}
});
},
/**
* Shows the small notification that asks for user permission
*
* @return void
*/
showErrorNotification: function () {
ErrorReport.removeErrorNotification();
var $div = $(
'<div style="position:fixed;bottom:0;left:0;right:0;margin:0;' +
'z-index:1000" class="error" id="error_notification"></div>'
).append(
Functions.getImage('s_error') + Messages.strErrorOccurred
);
var $buttons = $('<div class="floatright"></div>');
var buttonHtml = '<button class="btn btn-primary" id="show_error_report">';
buttonHtml += Messages.strShowReportDetails;
buttonHtml += '</button>';
buttonHtml += '<a id="change_error_settings">';
buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings);
buttonHtml += '</a>';
buttonHtml += '<a href="#" id="ignore_error">';
buttonHtml += Functions.getImage('b_close', Messages.strIgnore);
buttonHtml += '</a>';
$buttons.html(buttonHtml);
$div.append($buttons);
$div.appendTo(document.body);
$(document).on('click', '#change_error_settings', ErrorReport.redirectToSettings);
$(document).on('click', '#show_error_report', ErrorReport.createReportDialog);
$(document).on('click', '#ignore_error', ErrorReport.removeErrorNotification);
},
/**
* Removes the notification if it was displayed before
*
* @return void
*/
removeErrorNotification: function (e) {
if (e) {
// don't remove the hash fragment by navigating to #
e.preventDefault();
}
$('#error_notification').fadeOut(function () {
$(this).remove();
});
},
/**
* Extracts Exception name from message if it exists
*
* @return String
*/
extractExceptionName: function (exception) {
if (exception.message === null || typeof(exception.message) === 'undefined') {
return '';
}
var reg = /([a-zA-Z]+):/;
var regexResult = reg.exec(exception.message);
if (regexResult && regexResult.length === 2) {
return regexResult[1];
}
return '';
},
/**
* Shows the modal dialog previewing the report
*
* @return void
*/
createReportDialog: function () {
ErrorReport.removeErrorNotification();
ErrorReport.showReportDialog(ErrorReport.lastException);
},
/**
* Redirects to the settings page containing error report
* preferences
*
* @return void
*/
redirectToSettings: function () {
window.location.href = 'prefs_forms.php';
},
/**
* Returns the report data to send to the server
*
* @param exception object exception info
*
* @return object
*/
getReportData: function (exception) {
if (exception && exception.stack && exception.stack.length) {
for (var i = 0; i < exception.stack.length; i++) {
var stack = exception.stack[i];
if (stack.context && stack.context.length) {
for (var j = 0; j < stack.context.length; j++) {
if (stack.context[j].length > 80) {
stack.context[j] = stack.context[j].substring(-1, 75) + '//...';
}
}
}
}
}
var reportData = {
'server': CommonParams.get('server'),
'ajax_request': true,
'exception': exception,
'url': window.location.href,
'exception_type': 'js'
};
if (AJAX.scriptHandler.scripts.length > 0) {
reportData.scripts = AJAX.scriptHandler.scripts.map(
function (script) {
return script;
}
);
}
return reportData;
},
/**
* Wraps all global functions that start with PMA_
*
* @return void
*/
wrapGlobalFunctions: function () {
for (var key in window) {
if (key.indexOf('PMA_') === 0) {
var global = window[key];
if (typeof(global) === 'function') {
window[key] = ErrorReport.wrapFunction(global);
}
}
}
},
/**
* Wraps given function in error reporting code and returns wrapped function
*
* @param func function to be wrapped
*
* @return function
*/
wrapFunction: function (func) {
if (!func.wrapped) {
var newFunc = function () {
try {
return func.apply(this, arguments);
} catch (x) {
TraceKit.report(x);
}
};
newFunc.wrapped = true;
// Set guid of wrapped function same as original function, so it can be removed
// See bug#4146 (problem with jquery draggable and sortable)
newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++;
return newFunc;
} else {
return func;
}
},
/**
* Automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
wrapAjaxOnloadCallback: function () {
var oldOnload = AJAX.registerOnload;
AJAX.registerOnload = function (file, func) {
var wrappedFunction = ErrorReport.wrapFunction(func);
oldOnload.call(this, file, wrappedFunction);
};
},
/**
* Automatically wraps the callback in $.fn.on
*
* @return void
*/
wrapJqueryOnCallback: function () {
var oldOn = $.fn.on;
$.fn.on = function () {
for (var i = 1; i <= 3; i++) {
if (typeof(arguments[i]) === 'function') {
arguments[i] = ErrorReport.wrapFunction(arguments[i]);
break;
}
}
return oldOn.apply(this, arguments);
};
},
/**
* Wraps all global functions that start with PMA_
* also automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
setUpErrorReporting: function () {
ErrorReport.wrapGlobalFunctions();
ErrorReport.wrapAjaxOnloadCallback();
ErrorReport.wrapJqueryOnCallback();
}
};
AJAX.registerOnload('error_report.js', function () {
TraceKit.report.subscribe(ErrorReport.errorHandler);
ErrorReport.setUpErrorReporting();
ErrorReport.wrapGlobalFunctions();
});

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
AJAX.registerOnload('export_output.js', function () {
$(document).on('keydown', function (e) {
if ((e.which || e.keyCode) === 116) {
e.preventDefault();
$('#export_refresh_form').trigger('submit');
}
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,402 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview functions used in GIS data editor
*
* @requires jQuery
*
*/
/* global addZoomPanControllers, loadSVG, selectVisualization, styleOSM, zoomAndPan */ // js/table/gis_visualization.js
/* global pmaThemeImage */ // js/messages.php
// eslint-disable-next-line no-unused-vars
var gisEditorLoaded = false;
/**
* Closes the GIS data editor and perform necessary clean up work.
*/
function closeGISEditor () {
$('#popup_background').fadeOut('fast');
$('#gis_editor').fadeOut('fast', function () {
$(this).empty();
});
}
/**
* Prepares the HTML received via AJAX.
*/
function prepareJSVersion () {
// Change the text on the submit button
$('#gis_editor').find('input[name=\'gis_data[save]\']')
.val(Messages.strCopy)
.insertAfter($('#gis_data_textarea'))
.before('<br><br>');
// Add close and cancel links
$('#gis_data_editor').prepend('<a class="close_gis_editor" href="#">' + Messages.strClose + '</a>');
$('<a class="cancel_gis_editor" href="#"> ' + Messages.strCancel + '</a>')
.insertAfter($('input[name=\'gis_data[save]\']'));
// Remove the unnecessary text
$('div#gis_data_output p').remove();
// Remove 'add' buttons and add links
$('#gis_editor').find('input.add').each(function () {
var $button = $(this);
$button.addClass('addJs').removeClass('add');
var classes = $button.attr('class');
$button.replaceWith(
'<a class="' + classes +
'" name="' + $button.attr('name') +
'" href="#">+ ' + $button.val() + '</a>'
);
});
}
/**
* Returns the HTML for a data point.
*
* @param pointNumber point number
* @param prefix prefix of the name
* @returns the HTML for a data point
*/
function addDataPoint (pointNumber, prefix) {
return '<br>' +
Functions.sprintf(Messages.strPointN, (pointNumber + 1)) + ': ' +
'<label for="x">' + Messages.strX + '</label>' +
'<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value="">' +
'<label for="y">' + Messages.strY + '</label>' +
'<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value="">';
}
/**
* Initialize the visualization in the GIS data editor.
*/
function initGISEditorVisualization () {
// Loads either SVG or OSM visualization based on the choice
selectVisualization();
// Adds necessary styles to the div that coontains the openStreetMap
styleOSM();
// Loads the SVG element and make a reference to it
loadSVG();
// Adds controllers for zooming and panning
addZoomPanControllers();
zoomAndPan();
}
/**
* Loads JavaScript files and the GIS editor.
*
* @param value current value of the geometry field
* @param field field name
* @param type geometry type
* @param inputName name of the input field
* @param token token
*/
// eslint-disable-next-line no-unused-vars
function loadJSAndGISEditor (value, field, type, inputName) {
var head = document.getElementsByTagName('head')[0];
var script;
// Loads a set of small JS file needed for the GIS editor
var smallScripts = ['js/vendor/jquery/jquery.svg.js',
'js/vendor/jquery/jquery.mousewheel.js',
'js/vendor/jquery/jquery.event.drag-2.2.js',
'js/table/gis_visualization.js'];
for (var i = 0; i < smallScripts.length; i++) {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = smallScripts[i];
head.appendChild(script);
}
// OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
// Load the JS and do a callback to load the content for the GIS Editor.
script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState === 'complete') {
loadGISEditor(value, field, type, inputName);
}
};
script.onload = function () {
loadGISEditor(value, field, type, inputName);
};
script.onerror = function () {
loadGISEditor(value, field, type, inputName);
};
script.src = 'js/vendor/openlayers/OpenLayers.js';
head.appendChild(script);
gisEditorLoaded = true;
}
/**
* Loads the GIS editor via AJAX
*
* @param value current value of the geometry field
* @param field field name
* @param type geometry type
* @param inputName name of the input field
*/
function loadGISEditor (value, field, type, inputName) {
var $gisEditor = $('#gis_editor');
$.post('gis_data_editor.php', {
'field' : field,
'value' : value,
'type' : type,
'input_name' : inputName,
'get_gis_editor' : true,
'ajax_request': true,
'server': CommonParams.get('server')
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$gisEditor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
}
/**
* Opens up the dialog for the GIS data editor.
*/
// eslint-disable-next-line no-unused-vars
function openGISEditor () {
// Center the popup
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupWidth = windowWidth * 0.9;
var popupHeight = windowHeight * 0.9;
var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
var $gisEditor = $('#gis_editor');
var $backgrouond = $('#popup_background');
$gisEditor.css({ 'top': popupOffsetTop, 'left': popupOffsetLeft, 'width': popupWidth, 'height': popupHeight });
$backgrouond.css({ 'opacity' : '0.7' });
$gisEditor.append(
'<div id="gis_data_editor">' +
'<img class="ajaxIcon" id="loadingMonitorIcon" src="' +
pmaThemeImage + 'ajax_clock_small.gif" alt="">' +
'</div>'
);
// Make it appear
$backgrouond.fadeIn('fast');
$gisEditor.fadeIn('fast');
}
/**
* Prepare and insert the GIS data in Well Known Text format
* to the input field.
*/
function insertDataAndClose () {
var $form = $('form#gis_data_editor_form');
var inputName = $form.find('input[name=\'input_name\']').val();
var argsep = CommonParams.get('arg_separator');
$.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('input[name=\'' + inputName + '\']').val(data.result);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
closeGISEditor();
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('gis_data_editor.js', function () {
$(document).off('click', '#gis_editor input[name=\'gis_data[save]\']');
$(document).off('submit', '#gis_editor');
$(document).off('change', '#gis_editor input[type=\'text\']');
$(document).off('change', '#gis_editor select.gis_type');
$(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor');
$(document).off('click', '#gis_editor a.addJs.addPoint');
$(document).off('click', '#gis_editor a.addLine.addJs');
$(document).off('click', '#gis_editor a.addJs.addPolygon');
$(document).off('click', '#gis_editor a.addJs.addGeom');
});
AJAX.registerOnload('gis_data_editor.js', function () {
/**
* Prepares and insert the GIS data to the input field on clicking 'copy'.
*/
$(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Prepares and insert the GIS data to the input field on pressing 'enter'.
*/
$(document).on('submit', '#gis_editor', function (event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Trigger asynchronous calls on data change and update the output.
*/
$(document).on('change', '#gis_editor input[type=\'text\']', function () {
var $form = $('form#gis_data_editor_form');
var argsep = CommonParams.get('arg_separator');
$.post('gis_data_editor.php', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('#gis_data_textarea').val(data.result);
$('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
$('#openlayersmap').empty();
/* TODO: the gis_data_editor should rather return JSON than JS code to eval */
// eslint-disable-next-line no-eval
eval(data.openLayers);
initGISEditorVisualization();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
});
/**
* Update the form on change of the GIS type.
*/
$(document).on('change', '#gis_editor select.gis_type', function () {
var $gisEditor = $('#gis_editor');
var $form = $('form#gis_data_editor_form');
var argsep = CommonParams.get('arg_separator');
$.post('gis_data_editor.php', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$gisEditor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
});
/**
* Handles closing of the GIS data editor.
*/
$(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () {
closeGISEditor();
});
/**
* Handles adding data points
*/
$(document).on('click', '#gis_editor a.addJs.addPoint', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
var prefix = name.substr(0, name.length - 11);
// Find the number of points
var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']');
var noOfPoints = parseInt($noOfPointsInput.val(), 10);
// Add the new data point
var html = addDataPoint(noOfPoints, prefix);
$a.before(html);
$noOfPointsInput.val(noOfPoints + 1);
});
/**
* Handles adding linestrings and inner rings
*/
$(document).on('click', '#gis_editor a.addLine.addJs', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
var prefix = name.substr(0, name.length - 10);
var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
// Find the number of lines
var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']');
var noOfLines = parseInt($noOfLinesInput.val(), 10);
// Add the new linesting of inner ring based on the type
var html = '<br>';
var noOfPoints;
if (type === 'MULTILINESTRING') {
html += Messages.strLineString + ' ' + (noOfLines + 1) + ':';
noOfPoints = 2;
} else {
html += Messages.strInnerRing + ' ' + noOfLines + ':';
noOfPoints = 4;
}
html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '">';
for (var i = 0; i < noOfPoints; i++) {
html += addDataPoint(i, (prefix + '[' + noOfLines + ']'));
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' +
Messages.strAddPoint + '</a><br>';
$a.before(html);
$noOfLinesInput.val(noOfLines + 1);
});
/**
* Handles adding polygons
*/
$(document).on('click', '#gis_editor a.addJs.addPolygon', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
var prefix = name.substr(0, name.length - 13);
// Find the number of polygons
var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']');
var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
// Add the new polygon
var html = Messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br>';
html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1">' +
'<br>' + Messages.strOuterRing + ':' +
'<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4">';
for (var i = 0; i < 4; i++) {
html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]'));
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' +
Messages.strAddPoint + '</a><br>' +
'<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' +
Messages.strAddInnerRing + '</a><br><br>';
$a.before(html);
$noOfPolygonsInput.val(noOfPolygons + 1);
});
/**
* Handles adding geoms
*/
$(document).on('click', '#gis_editor a.addJs.addGeom', function () {
var $a = $(this);
var prefix = 'gis_data[GEOMETRYCOLLECTION]';
// Find the number of geoms
var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']');
var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
var html1 = Messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br>';
var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone();
$geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
var html2 = '<br>' + Messages.strPoint + ' :' +
'<label for="x"> ' + Messages.strX + ' </label>' +
'<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value="">' +
'<label for="y"> ' + Messages.strY + ' </label>' +
'<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value="">' +
'<br><br>';
$a.before(html1);
$geomType.insertBefore($a);
$a.before(html2);
$noOfGeomsInput.val(noOfGeoms + 1);
});
});

View File

@ -1,171 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions used in the import tab
*
*/
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
function changePluginOpts () {
$('#format_specific_opts').find('div.format_specific_options').each(function () {
$(this).hide();
});
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').fadeIn('slow');
if (selectedPluginName === 'csv') {
$('#import_notification').text(Messages.strImportCSV);
} else {
$('#import_notification').text('');
}
}
/**
* Toggles the hiding and showing of each plugin's options and sets the selected value
* in the plugin dropdown list according to the format of the selected file
*/
function matchFile (fname) {
var fnameArray = fname.toLowerCase().split('.');
var len = fnameArray.length;
if (len !== 0) {
var extension = fnameArray[len - 1];
if (extension === 'gz' || extension === 'bz2' || extension === 'zip') {
len--;
}
// Only toggle if the format of the file can be imported
if ($('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).length === 1) {
$('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).prop('selected', true);
changePluginOpts();
}
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('import.js', function () {
$('#plugins').off('change');
$('#input_import_file').off('change');
$('#select_local_import_file').off('change');
$('#input_import_file').off('change').off('focus');
$('#select_local_import_file').off('focus');
$('#text_csv_enclosed').add('#text_csv_escaped').off('keyup');
});
AJAX.registerOnload('import.js', function () {
// import_file_form validation.
$(document).on('submit', '#import_file_form', function () {
var radioLocalImport = $('#radio_local_import_file');
var radioImport = $('#radio_import_file');
var fileMsg = '<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> ' + Messages.strImportDialogMessage + '</div>';
var wrongTblNameMsg = '<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">' + Messages.strTableNameDialogMessage + '</div>';
var wrongDBNameMsg = '<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">' + Messages.strDBNameDialogMessage + '</div>';
if (radioLocalImport.length !== 0) {
// remote upload.
if (radioImport.is(':checked') && $('#input_import_file').val() === '') {
$('#input_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
if (radioLocalImport.is(':checked')) {
if ($('#select_local_import_file').length === 0) {
Functions.ajaxShowMessage('<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> ' + Messages.strNoImportFile + ' </div>', false);
return false;
}
if ($('#select_local_import_file').val() === '') {
$('#select_local_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
}
} else {
// local upload.
if ($('#input_import_file').val() === '') {
$('#input_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
if ($('#text_csv_new_tbl_name').length > 0) {
var newTblName = $('#text_csv_new_tbl_name').val();
if (newTblName.length > 0 && $.trim(newTblName).length === 0) {
Functions.ajaxShowMessage(wrongTblNameMsg, false);
return false;
}
}
if ($('#text_csv_new_db_name').length > 0) {
var newDBName = $('#text_csv_new_db_name').val();
if (newDBName.length > 0 && $.trim(newDBName).length === 0) {
Functions.ajaxShowMessage(wrongDBNameMsg, false);
return false;
}
}
}
// show progress bar.
$('#upload_form_status').css('display', 'inline');
$('#upload_form_status_info').css('display', 'inline');
});
// Initially display the options for the selected plugin
changePluginOpts();
// Whenever the selected plugin changes, change the options displayed
$('#plugins').on('change', function () {
changePluginOpts();
});
$('#input_import_file').on('change', function () {
matchFile($(this).val());
});
$('#select_local_import_file').on('change', function () {
matchFile($(this).val());
});
/*
* When the "Browse the server" form is clicked or the "Select from the web server upload directory"
* form is clicked, the radio button beside it becomes selected and the other form becomes disabled.
*/
$('#input_import_file').on('focus change', function () {
$('#radio_import_file').prop('checked', true);
$('#radio_local_import_file').prop('checked', false);
});
$('#select_local_import_file').on('focus', function () {
$('#radio_local_import_file').prop('checked', true);
$('#radio_import_file').prop('checked', false);
});
/**
* Set up the interface for Javascript-enabled browsers since the default is for
* Javascript-disabled browsers
*/
$('#scroll_to_options_msg').hide();
$('#format_specific_opts').find('div.format_specific_options')
.css({
'border': 0,
'margin': 0,
'padding': 0
})
.find('h3')
.remove();
// $("form[name=import] *").unwrap();
/**
* for input element text_csv_enclosed and text_csv_escaped allow just one character to enter.
* as mysql allows just one character for these fields,
* if first character is escape then allow two including escape character.
*/
$('#text_csv_enclosed').add('#text_csv_escaped').on('keyup', function () {
if ($(this).val().length === 2 && $(this).val().charAt(0) !== '\\') {
$(this).val($(this).val().substring(0, 1));
return false;
}
return true;
});
});

View File

@ -1,810 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used for index manipulation pages
* @name Table Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
/* global fulltextIndexes:writable, indexes:writable, primaryIndexes:writable, spatialIndexes:writable, uniqueIndexes:writable */ // js/functions.js
var Indexes = {};
/**
* Returns the array of indexes based on the index choice
*
* @param indexChoice index choice
*/
Indexes.getIndexArray = function (indexChoice) {
var sourceArray = null;
switch (indexChoice.toLowerCase()) {
case 'primary':
sourceArray = primaryIndexes;
break;
case 'unique':
sourceArray = uniqueIndexes;
break;
case 'index':
sourceArray = indexes;
break;
case 'fulltext':
sourceArray = fulltextIndexes;
break;
case 'spatial':
sourceArray = spatialIndexes;
break;
default:
return null;
}
return sourceArray;
};
/**
* Hides/shows the inputs and submits appropriately depending
* on whether the index type chosen is 'SPATIAL' or not.
*/
Indexes.checkIndexType = function () {
/**
* @var Object Dropdown to select the index choice.
*/
var $selectIndexChoice = $('#select_index_choice');
/**
* @var Object Dropdown to select the index type.
*/
var $selectIndexType = $('#select_index_type');
/**
* @var Object Table header for the size column.
*/
var $sizeHeader = $('#index_columns').find('thead tr th:nth-child(2)');
/**
* @var Object Inputs to specify the columns for the index.
*/
var $columnInputs = $('select[name="index[columns][names][]"]');
/**
* @var Object Inputs to specify sizes for columns of the index.
*/
var $sizeInputs = $('input[name="index[columns][sub_parts][]"]');
/**
* @var Object Footer containg the controllers to add more columns
*/
var $addMore = $('#index_frm').find('.add_more');
if ($selectIndexChoice.val() === 'SPATIAL') {
// Disable and hide the size column
$sizeHeader.hide();
$sizeInputs.each(function () {
$(this)
.prop('disabled', true)
.parent('td').hide();
});
// Disable and hide the columns of the index other than the first one
var initial = true;
$columnInputs.each(function () {
var $columnInput = $(this);
if (! initial) {
$columnInput
.prop('disabled', true)
.parent('td').hide();
} else {
initial = false;
}
});
// Hide controllers to add more columns
$addMore.hide();
} else {
// Enable and show the size column
$sizeHeader.show();
$sizeInputs.each(function () {
$(this)
.prop('disabled', false)
.parent('td').show();
});
// Enable and show the columns of the index
$columnInputs.each(function () {
$(this)
.prop('disabled', false)
.parent('td').show();
});
// Show controllers to add more columns
$addMore.show();
}
if ($selectIndexChoice.val() === 'SPATIAL' ||
$selectIndexChoice.val() === 'FULLTEXT') {
$selectIndexType.val('').prop('disabled', true);
} else {
$selectIndexType.prop('disabled', false);
}
};
/**
* Sets current index information into form parameters.
*
* @param array source_array Array containing index columns
* @param string index_choice Choice of index
*
* @return void
*/
Indexes.setIndexFormParameters = function (sourceArray, indexChoice) {
if (indexChoice === 'index') {
$('input[name="indexes"]').val(JSON.stringify(sourceArray));
} else {
$('input[name="' + indexChoice + '_indexes"]').val(JSON.stringify(sourceArray));
}
};
/**
* Removes a column from an Index.
*
* @param string col_index Index of column in form
*
* @return void
*/
Indexes.removeColumnFromIndex = function (colIndex) {
// Get previous index details.
var previousIndex = $('select[name="field_key[' + colIndex + ']"]')
.attr('data-index');
if (previousIndex.length) {
previousIndex = previousIndex.split(',');
var sourceArray = Indexes.getIndexArray(previousIndex[0]);
if (sourceArray === null) {
return;
}
// Remove column from index array.
var sourceLength = sourceArray[previousIndex[1]].columns.length;
for (var i = 0; i < sourceLength; i++) {
if (sourceArray[previousIndex[1]].columns[i].col_index === colIndex) {
sourceArray[previousIndex[1]].columns.splice(i, 1);
}
}
// Remove index completely if no columns left.
if (sourceArray[previousIndex[1]].columns.length === 0) {
sourceArray.splice(previousIndex[1], 1);
}
// Update current index details.
$('select[name="field_key[' + colIndex + ']"]').attr('data-index', '');
// Update form index parameters.
Indexes.setIndexFormParameters(sourceArray, previousIndex[0].toLowerCase());
}
};
/**
* Adds a column to an Index.
*
* @param array source_array Array holding corresponding indexes
* @param string array_index Index of an INDEX in array
* @param string index_choice Choice of Index
* @param string col_index Index of column on form
*
* @return void
*/
Indexes.addColumnToIndex = function (sourceArray, arrayIndex, indexChoice, colIndex) {
if (colIndex >= 0) {
// Remove column from other indexes (if any).
Indexes.removeColumnFromIndex(colIndex);
}
var indexName = $('input[name="index[Key_name]"]').val();
var indexComment = $('input[name="index[Index_comment]"]').val();
var keyBlockSize = $('input[name="index[Key_block_size]"]').val();
var parser = $('input[name="index[Parser]"]').val();
var indexType = $('select[name="index[Index_type]"]').val();
var columns = [];
$('#index_columns').find('tbody').find('tr').each(function () {
// Get columns in particular order.
var colIndex = $(this).find('select[name="index[columns][names][]"]').val();
var size = $(this).find('input[name="index[columns][sub_parts][]"]').val();
columns.push({
'col_index': colIndex,
'size': size
});
});
// Update or create an index.
sourceArray[arrayIndex] = {
'Key_name': indexName,
'Index_comment': indexComment,
'Index_choice': indexChoice.toUpperCase(),
'Key_block_size': keyBlockSize,
'Parser': parser,
'Index_type': indexType,
'columns': columns
};
// Display index name (or column list)
var displayName = indexName;
if (displayName === '') {
var columnNames = [];
$.each(columns, function () {
columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val());
});
displayName = '[' + columnNames.join(', ') + ']';
}
$.each(columns, function () {
var id = 'index_name_' + this.col_index + '_8';
var $name = $('#' + id);
if ($name.length === 0) {
$name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>');
$name.insertAfter($('select[name="field_key[' + this.col_index + ']"]'));
}
var $text = $('<small>').text(displayName);
$name.html($text);
});
if (colIndex >= 0) {
// Update index details on form.
$('select[name="field_key[' + colIndex + ']"]')
.attr('data-index', indexChoice + ',' + arrayIndex);
}
Indexes.setIndexFormParameters(sourceArray, indexChoice.toLowerCase());
};
/**
* Get choices list for a column to create a composite index with.
*
* @param string index_choice Choice of index
* @param array source_array Array hodling columns for particular index
*
* @return jQuery Object
*/
Indexes.getCompositeIndexList = function (sourceArray, colIndex) {
// Remove any previous list.
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
// Html list.
var $compositeIndexList = $(
'<ul id="composite_index_list">' +
'<div>' + Messages.strCompositeWith + '</div>' +
'</ul>'
);
// Add each column to list available for composite index.
var sourceLength = sourceArray.length;
var alreadyPresent = false;
for (var i = 0; i < sourceLength; i++) {
var subArrayLen = sourceArray[i].columns.length;
var columnNames = [];
for (var j = 0; j < subArrayLen; j++) {
columnNames.push(
$('input[name="field_name[' + sourceArray[i].columns[j].col_index + ']"]').val()
);
if (colIndex === sourceArray[i].columns[j].col_index) {
alreadyPresent = true;
}
}
$compositeIndexList.append(
'<li>' +
'<input type="radio" name="composite_with" ' +
(alreadyPresent ? 'checked="checked"' : '') +
' id="composite_index_' + i + '" value="' + i + '">' +
'<label for="composite_index_' + i + '">' + columnNames.join(', ') +
'</lablel>' +
'</li>'
);
}
return $compositeIndexList;
};
/**
* Shows 'Add Index' dialog.
*
* @param array source_array Array holding particluar index
* @param string array_index Index of an INDEX in array
* @param array target_columns Columns for an INDEX
* @param string col_index Index of column on form
* @param object index Index detail object
* @param bool showDialog Whether to show index creation dialog or not
*
* @return void
*/
Indexes.showAddIndexDialog = function (sourceArray, arrayIndex, targetColumns, colIndex, index, showDialog) {
var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true;
// Prepare post-data.
var $table = $('input[name="table"]');
var table = $table.length > 0 ? $table.val() : '';
var postData = {
'server': CommonParams.get('server'),
'db': $('input[name="db"]').val(),
'table': table,
'ajax_request': 1,
'create_edit_table': 1,
'index': index
};
var columns = {};
for (var i = 0; i < targetColumns.length; i++) {
var columnName = $('input[name="field_name[' + targetColumns[i] + ']"]').val();
var columnType = $('select[name="field_type[' + targetColumns[i] + ']"]').val().toLowerCase();
columns[columnName] = [columnType, targetColumns[i]];
}
postData.columns = JSON.stringify(columns);
var buttonOptions = {};
buttonOptions[Messages.strGo] = function () {
var isMissingValue = false;
$('select[name="index[columns][names][]"]').each(function () {
if ($(this).val() === '') {
isMissingValue = true;
}
});
if (! isMissingValue) {
Indexes.addColumnToIndex(
sourceArray,
arrayIndex,
index.Index_choice,
colIndex
);
} else {
Functions.ajaxShowMessage(
'<div class="error"><img src="themes/dot.gif" title="" alt=""' +
' class="icon ic_s_error"> ' + Messages.strMissingColumn +
' </div>', false
);
return false;
}
$(this).remove();
};
buttonOptions[Messages.strCancel] = function () {
if (colIndex >= 0) {
// Handle state on 'Cancel'.
var $selectList = $('select[name="field_key[' + colIndex + ']"]');
if (! $selectList.attr('data-index').length) {
$selectList.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previousIndex = $selectList.attr('data-index').split(',');
$selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]')
.attr('selected', 'selected');
}
}
$(this).dialog('close');
};
var $msgbox = Functions.ajaxShowMessage();
$.post('tbl_indexes.php', postData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxRemoveMessage($msgbox);
var $div = $('<div></div>');
if (showDialogLocal) {
// Show dialog if the request was successful
if ($('#addIndex').length > 0) {
$('#addIndex').remove();
}
$div
.append(data.message)
.dialog({
title: Messages.strAddIndex,
width: 450,
minHeight: 250,
create: function () {
$(this).keypress(function (e) {
if (e.which === 13 || e.keyCode === 13 || window.event.keyCode === 13) {
e.preventDefault();
buttonOptions[Messages.strGo]();
$(this).remove();
}
});
},
open: function () {
Functions.checkIndexName('index_frm');
Functions.showHints($div);
Functions.initSlider();
$('#index_columns').find('td').each(function () {
$(this).css('width', $(this).width() + 'px');
});
$('#index_columns').find('tbody').sortable({
axis: 'y',
containment: $('#index_columns').find('tbody'),
tolerance: 'pointer'
});
// We dont need the slider at this moment.
$(this).find('fieldset.tblFooters').remove();
},
modal: true,
buttons: buttonOptions,
close: function () {
$(this).remove();
}
});
} else {
$div
.append(data.message);
$div.css({ 'display' : 'none' });
$div.appendTo($('body'));
$div.attr({ 'id' : 'addIndex' });
var isMissingValue = false;
$('select[name="index[columns][names][]"]').each(function () {
if ($(this).val() === '') {
isMissingValue = true;
}
});
if (! isMissingValue) {
Indexes.addColumnToIndex(
sourceArray,
arrayIndex,
index.Index_choice,
colIndex
);
} else {
Functions.ajaxShowMessage(
'<div class="error"><img src="themes/dot.gif" title="" alt=""' +
' class="icon ic_s_error"> ' + Messages.strMissingColumn +
' </div>', false
);
return false;
}
}
}
});
};
/**
* Creates a advanced index type selection dialog.
*
* @param array source_array Array holding a particular type of indexes
* @param string index_choice Choice of index
* @param string col_index Index of new column on form
*
* @return void
*/
Indexes.indexTypeSelectionDialog = function (sourceArray, indexChoice, colIndex) {
var $singleColumnRadio = $('<input type="radio" id="single_column" name="index_choice"' +
' checked="checked">' +
'<label for="single_column">' + Messages.strCreateSingleColumnIndex + '</label>');
var $compositeIndexRadio = $('<input type="radio" id="composite_index"' +
' name="index_choice">' +
'<label for="composite_index">' + Messages.strCreateCompositeIndex + '</label>');
var $dialogContent = $('<fieldset id="advance_index_creator"></fieldset>');
$dialogContent.append('<legend>' + indexChoice.toUpperCase() + '</legend>');
// For UNIQUE/INDEX type, show choice for single-column and composite index.
$dialogContent.append($singleColumnRadio);
$dialogContent.append($compositeIndexRadio);
var buttonOptions = {};
// 'OK' operation.
buttonOptions[Messages.strGo] = function () {
if ($('#single_column').is(':checked')) {
var index = {
'Key_name': (indexChoice === 'primary' ? 'PRIMARY' : ''),
'Index_choice': indexChoice.toUpperCase()
};
Indexes.showAddIndexDialog(sourceArray, (sourceArray.length), [colIndex], colIndex, index);
}
if ($('#composite_index').is(':checked')) {
if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0
) {
Functions.ajaxShowMessage(
'<div class="error"><img src="themes/dot.gif" title=""' +
' alt="" class="icon ic_s_error"> ' +
Messages.strFormEmpty +
' </div>',
false
);
return false;
}
var arrayIndex = $('input[name="composite_with"]:checked').val();
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
targetColumns.push(colIndex);
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex,
sourceArray[arrayIndex]);
}
$(this).remove();
};
buttonOptions[Messages.strCancel] = function () {
// Handle state on 'Cancel'.
var $selectList = $('select[name="field_key[' + colIndex + ']"]');
if (! $selectList.attr('data-index').length) {
$selectList.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previousIndex = $selectList.attr('data-index').split(',');
$selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]')
.attr('selected', 'selected');
}
$(this).remove();
};
$('<div></div>').append($dialogContent).dialog({
minWidth: 525,
minHeight: 200,
modal: true,
title: Messages.strAddIndex,
resizable: false,
buttons: buttonOptions,
open: function () {
$('#composite_index').on('change', function () {
if ($(this).is(':checked')) {
$dialogContent.append(Indexes.getCompositeIndexList(sourceArray, colIndex));
}
});
$('#single_column').on('change', function () {
if ($(this).is(':checked')) {
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
}
});
},
close: function () {
$('#composite_index').off('change');
$('#single_column').off('change');
$(this).remove();
}
});
};
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('indexes.js', function () {
$(document).off('click', '#save_index_frm');
$(document).off('click', '#preview_index_frm');
$(document).off('change', '#select_index_choice');
$(document).off('click', 'a.drop_primary_key_index_anchor.ajax');
$(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax');
$(document).off('click', '#index_frm input[type=submit]');
$('body').off('change', 'select[name*="field_key"]');
$(document).off('click', '.show_index_dialog');
});
/**
* @description <p>Ajax scripts for table index page</p>
*
* Actions ajaxified here:
* <ul>
* <li>Showing/hiding inputs depending on the index type chosen</li>
* <li>create/edit/drop indexes</li>
* </ul>
*/
AJAX.registerOnload('indexes.js', function () {
// Re-initialize variables.
primaryIndexes = [];
uniqueIndexes = [];
indexes = [];
fulltextIndexes = [];
spatialIndexes = [];
// for table creation form
var $engineSelector = $('.create_table_form select[name=tbl_storage_engine]');
if ($engineSelector.length) {
Functions.hideShowConnection($engineSelector);
}
var $form = $('#index_frm');
if ($form.length > 0) {
Functions.showIndexEditDialog($form);
}
$(document).on('click', '#save_index_frm', function (event) {
event.preventDefault();
var $form = $('#index_frm');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage(Messages.strProcessingRequest);
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
$(document).on('click', '#preview_index_frm', function (event) {
event.preventDefault();
Functions.previewSql($('#index_frm'));
});
$(document).on('change', '#select_index_choice', function (event) {
event.preventDefault();
Indexes.checkIndexType();
Functions.checkIndexName('index_frm');
});
/**
* Ajax Event handler for 'Drop Index'
*/
$(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) {
event.preventDefault();
var $anchor = $(this);
/**
* @var $currRow Object containing reference to the current field's row
*/
var $currRow = $anchor.parents('tr');
/** @var Number of columns in the key */
var rows = $anchor.parents('td').attr('rowspan') || 1;
/** @var Rows that should be hidden */
var $rowsToHide = $currRow;
for (var i = 1, $lastRow = $currRow.next(); i < rows; i++, $lastRow = $lastRow.next()) {
$rowsToHide = $rowsToHide.add($lastRow);
}
var question = Functions.escapeHtml(
$currRow.children('td')
.children('.drop_primary_key_index_msg')
.val()
);
Functions.confirmPreviewSql(question, $anchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strDroppingPrimaryKeyIndex, false);
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxRemoveMessage($msg);
var $tableRef = $rowsToHide.closest('table');
if ($rowsToHide.length === $tableRef.find('tbody > tr').length) {
// We are about to remove all rows from the table
$tableRef.hide('medium', function () {
$('div.no_indexes_defined').show('medium');
$rowsToHide.remove();
});
$tableRef.siblings('div.notice').hide('medium');
} else {
// We are removing some of the rows only
$rowsToHide.hide('medium', function () {
$(this).remove();
});
}
if ($('.result_query').length) {
$('.result_query').remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>')
.html(data.sql_query)
.prependTo('#structure_content');
Functions.highlightSql($('#page_content'));
}
CommonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
Navigation.reload();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
});
}); // end Drop Primary Key/Index
/**
*Ajax event handler for index edit
**/
$(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) {
event.preventDefault();
var url;
var title;
if ($(this).find('a').length === 0) {
// Add index
var valid = Functions.checkFormElementInRange(
$(this).closest('form')[0],
'added_fields',
'Column count has to be larger than zero.'
);
if (! valid) {
return;
}
url = $(this).closest('form').serialize();
title = Messages.strAddIndex;
} else {
// Edit index
url = $(this).find('a').getPostData();
title = Messages.strEditIndex;
}
url += CommonParams.get('arg_separator') + 'ajax_request=true';
Functions.indexEditorDialog(url, title, function () {
// refresh the page using ajax
CommonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
});
});
/**
* Ajax event handler for advanced index creation during table creation
* and column addition.
*/
$('body').on('change', 'select[name*="field_key"]', function (e, showDialog) {
var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true;
// Index of column on Table edit and create page.
var colIndex = /\d+/.exec($(this).attr('name'));
colIndex = colIndex[0];
// Choice of selected index.
var indexChoice = /[a-z]+/.exec($(this).val());
indexChoice = indexChoice[0];
// Array containing corresponding indexes.
var sourceArray = null;
if (indexChoice === 'none') {
Indexes.removeColumnFromIndex(colIndex);
var id = 'index_name_' + '0' + '_8';
var $name = $('#' + id);
if ($name.length === 0) {
$name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>');
$name.insertAfter($('select[name="field_key[' + '0' + ']"]'));
}
$name.html('');
return false;
}
// Select a source array.
sourceArray = Indexes.getIndexArray(indexChoice);
if (sourceArray === null) {
return;
}
if (sourceArray.length === 0) {
var index = {
'Key_name': (indexChoice === 'primary' ? 'PRIMARY' : ''),
'Index_choice': indexChoice.toUpperCase()
};
Indexes.showAddIndexDialog(sourceArray, 0, [colIndex], colIndex, index, showDialogLocal);
} else {
if (indexChoice === 'primary') {
var arrayIndex = 0;
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
targetColumns.push(colIndex);
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex,
sourceArray[arrayIndex], showDialogLocal);
} else {
// If there are multiple columns selected for an index, show advanced dialog.
Indexes.indexTypeSelectionDialog(sourceArray, indexChoice, colIndex);
}
}
});
$(document).on('click', '.show_index_dialog', function (e) {
e.preventDefault();
// Get index details.
var previousIndex = $(this).prev('select')
.attr('data-index')
.split(',');
var indexChoice = previousIndex[0];
var arrayIndex = previousIndex[1];
var sourceArray = Indexes.getIndexArray(indexChoice);
if (sourceArray !== null) {
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, -1, sourceArray[arrayIndex]);
}
});
$('#index_frm').on('submit', function () {
if (typeof(this.elements['index[Key_name]'].disabled) !== 'undefined') {
this.elements['index[Key_name]'].disabled = false;
}
});
});

View File

@ -1,49 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* jqplot formatter for byte values
*
* @package phpMyAdmin
*/
(function ($) {
'use strict';
var formatByte = function (value, index) {
var val = value;
var i = index;
var units = [
Messages.strB,
Messages.strKiB,
Messages.strMiB,
Messages.strGiB,
Messages.strTiB,
Messages.strPiB,
Messages.strEiB
];
while (val >= 1024 && i <= 6) {
val /= 1024;
i++;
}
var format = '%.1f';
if (Math.floor(val) === val) {
format = '%.0f';
}
return $.jqplot.sprintf(
format + ' ' + units[i], val
);
};
/**
* The index indicates what unit the incoming data will be in.
* 0 for bytes, 1 for kilobytes and so on...
*/
$.jqplot.byteFormatter = function (index) {
var i = index || 0;
return function (format, value) {
var val = value;
if (typeof val === 'number') {
val = parseFloat(val) || 0;
return formatByte(val, i);
} else {
return String(val);
}
};
};
}(jQuery));

View File

@ -1,140 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
// global var that holds: 0- if ctrl key is not pressed 1- if ctrl key is pressed
var ctrlKeyHistory = 0;
/**
* Allows moving around inputs/select by Ctrl+arrows
*
* @param object event data
*/
function onKeyDownArrowsHandler (event) {
var e = event || window.event;
var o = (e.srcElement || e.target);
if (!o) {
return;
}
if (o.tagName !== 'TEXTAREA' && o.tagName !== 'INPUT' && o.tagName !== 'SELECT') {
return;
}
if ((e.which !== 17) && (e.which !== 37) && (e.which !== 38) && (e.which !== 39) && (e.which !== 40)) {
return;
}
if (!o.id) {
return;
}
if (e.type === 'keyup') {
if (e.which === 17) {
ctrlKeyHistory = 0;
}
return;
} else if (e.type === 'keydown') {
if (e.which === 17) {
ctrlKeyHistory = 1;
}
}
if (ctrlKeyHistory !== 1) {
return;
}
e.preventDefault();
var pos = o.id.split('_');
if (pos[0] !== 'field' || typeof pos[2] === 'undefined') {
return;
}
var x = pos[2];
var y = pos[1];
switch (e.keyCode) {
case 38:
// up
y--;
break;
case 40:
// down
y++;
break;
case 37:
// left
x--;
break;
case 39:
// right
x++;
break;
default:
return;
}
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox/') > -1;
var id = 'field_' + y + '_' + x;
var nO = document.getElementById(id);
if (! nO) {
id = 'field_' + y + '_' + x + '_0';
nO = document.getElementById(id);
}
// skip non existent fields
if (! nO) {
return;
}
// for firefox select tag
var lvalue = o.selectedIndex;
var nOvalue = nO.selectedIndex;
nO.focus();
if (isFirefox) {
var ffcheck = 0;
var ffversion;
for (ffversion = 3 ; ffversion < 25 ; ffversion++) {
var isFirefoxV24 = navigator.userAgent.toLowerCase().indexOf('firefox/' + ffversion) > -1;
if (isFirefoxV24) {
ffcheck = 1;
break;
}
}
if (ffcheck === 1) {
if (e.which === 38 || e.which === 37) {
nOvalue++;
} else if (e.which === 40 || e.which === 39) {
nOvalue--;
}
nO.selectedIndex = nOvalue;
} else {
if (e.which === 38 || e.which === 37) {
lvalue++;
} else if (e.which === 40 || e.which === 39) {
lvalue--;
}
o.selectedIndex = lvalue;
}
}
if (nO.tagName !== 'SELECT') {
nO.select();
}
e.returnValue = false;
}
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('keydown keyup', '#table_columns');
$(document).off('keydown keyup', 'table.insertRowTable');
});
AJAX.registerOnload('keyhandler.js', function () {
$(document).on('keydown keyup', '#table_columns', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
$(document).on('keydown keyup', 'table.insertRowTable', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,221 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Handles the resizing of a menu according to the available screen width
*
* Uses themes/original/css/resizable-menu.css.php
*
* To initialise:
* $('#myMenu').menuResizer(function () {
* // This function will be called to find out how much
* // available horizontal space there is for the menu
* return $('body').width() - 5; // Some extra margin for good measure
* });
*
* To trigger a resize operation:
* $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize()
*
* To restore the menu to a state like before it was initialized:
* $('#myMenu').menuResizer('destroy');
*
* @package PhpMyAdmin
*/
(function ($) {
function MenuResizer ($container, widthCalculator) {
var self = this;
self.$container = $container;
self.widthCalculator = widthCalculator;
var windowWidth = $(window).width();
if (windowWidth < 768) {
$('#pma_navigation_resizer').css({ 'width': '0px' });
}
// Sets the image for the left and right scroll indicator
$('.scrollindicator--left').html($(Functions.getImage('b_left').toString()));
$('.scrollindicator--right').html($(Functions.getImage('b_right').toString()));
// Set the width of the navigation bar without scroll indicator
$('.navigationbar').css({ 'width': widthCalculator.call($container) - 60 });
// Scroll the navigation bar on click
$('.scrollindicator--right').on('click', function () {
$('.navigationbar').scrollLeft($('.navigationbar').scrollLeft() + 70);
});
$('.scrollindicator--left').on('click', function () {
$('.navigationbar').scrollLeft($('.navigationbar').scrollLeft() - 70);
});
// create submenu container
var link = $('<a></a>', { href: '#', 'class': 'tab nowrap' })
.text(Messages.strMore)
.on('click', false); // same as event.preventDefault()
var img = $container.find('li img');
if (img.length) {
$(Functions.getImage('b_more').toString()).prependTo(link);
}
var $submenu = $('<li></li>', { 'class': 'submenu' })
.append(link)
.append($('<ul></ul>'))
.on('mouseenter', function () {
if ($(this).find('ul .tabactive').length === 0) {
$(this)
.addClass('submenuhover')
.find('> a')
.addClass('tabactive');
}
})
.on('mouseleave', function () {
if ($(this).find('ul .tabactive').length === 0) {
$(this)
.removeClass('submenuhover')
.find('> a')
.removeClass('tabactive');
}
});
$container.children('.clearfloat').remove();
$container.append($submenu).append('<div class=\'clearfloat\'></div>');
setTimeout(function () {
self.resize();
}, 4);
}
MenuResizer.prototype.resize = function () {
var wmax = this.widthCalculator.call(this.$container);
var windowWidth = $(window).width();
var $submenu = this.$container.find('.submenu:last');
var submenuW = $submenu.outerWidth(true);
var $submenuUl = $submenu.find('ul');
var $li = this.$container.find('> li');
var $li2 = $submenuUl.find('li');
var moreShown = $li2.length > 0;
// Calculate the total width used by all the shown tabs
var totalLen = moreShown ? submenuW : 0;
var l = $li.length - 1;
var i;
for (i = 0; i < l; i++) {
totalLen += $($li[i]).outerWidth(true);
}
var hasVScroll = document.body.scrollHeight > document.body.clientHeight;
if (hasVScroll) {
windowWidth += 15;
}
if (windowWidth < 768) {
wmax = 2000;
}
// Now hide menu elements that don't fit into the menubar
var hidden = false; // Whether we have hidden any tabs
while (totalLen >= wmax && --l >= 0) { // Process the tabs backwards
hidden = true;
var el = $($li[l]);
var elWidth = el.outerWidth(true);
el.data('width', elWidth);
if (! moreShown) {
totalLen -= elWidth;
el.prependTo($submenuUl);
totalLen += submenuW;
moreShown = true;
} else {
totalLen -= elWidth;
el.prependTo($submenuUl);
}
}
// If we didn't hide any tabs, then there might be some space to show some
if (! hidden) {
// Show menu elements that do fit into the menubar
for (i = 0, l = $li2.length; i < l; i++) {
totalLen += $($li2[i]).data('width');
// item fits or (it is the last item
// and it would fit if More got removed)
if (totalLen < wmax ||
(i === $li2.length - 1 && totalLen - submenuW < wmax)
) {
$($li2[i]).insertBefore($submenu);
} else {
break;
}
}
}
// Show/hide the "More" tab as needed
if (windowWidth < 768) {
$('.navigationbar').css({ 'width': windowWidth - 80 - $('#pma_navigation').width() });
$submenu.removeClass('shown');
$('.navigationbar').css({ 'overflow': 'hidden' });
} else {
$('.navigationbar').css({ 'width': 'auto' });
$('.navigationbar').css({ 'overflow': 'visible' });
if ($submenuUl.find('li').length > 0) {
$submenu.addClass('shown');
} else {
$submenu.removeClass('shown');
}
}
if (this.$container.find('> li').length === 1) {
// If there is only the "More" tab left, then we need
// to align the submenu to the left edge of the tab
$submenuUl.removeClass().addClass('only');
} else {
// Otherwise we align the submenu to the right edge of the tab
$submenuUl.removeClass().addClass('notonly');
}
if ($submenu.find('.tabactive').length) {
$submenu
.addClass('active')
.find('> a')
.removeClass('tab')
.addClass('tabactive');
} else {
$submenu
.removeClass('active')
.find('> a')
.addClass('tab')
.removeClass('tabactive');
}
};
MenuResizer.prototype.destroy = function () {
var $submenu = this.$container.find('li.submenu').removeData();
$submenu.find('li').appendTo(this.$container);
$submenu.remove();
};
/** Public API */
var methods = {
init: function (widthCalculator) {
return this.each(function () {
var $this = $(this);
if (! $this.data('menuResizer')) {
$this.data(
'menuResizer',
new MenuResizer($this, widthCalculator)
);
}
});
},
resize: function () {
return this.each(function () {
var self = $(this).data('menuResizer');
if (self) {
self.resize();
}
});
},
destroy: function () {
return this.each(function () {
var self = $(this).data('menuResizer');
if (self) {
self.destroy();
}
});
}
};
/** Extend jQuery */
$.fn.menuResizer = function (method) {
if (methods[method]) {
return methods[method].call(this);
} else if (typeof method === 'function') {
return methods.init.apply(this, [method]);
} else {
$.error('Method ' + method + ' does not exist on jQuery.menuResizer');
}
};
}(jQuery));

File diff suppressed because it is too large Load Diff

View File

@ -1,339 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* global GotoWhitelist */ // js/whitelist.php
/**
* An implementation of a client-side page cache.
* This object also uses the cache to provide a simple microhistory,
* that is the ability to use the back and forward buttons in the browser
*/
var MicroHistory = {
/**
* @var int The maximum number of pages to keep in the cache
*/
MAX: 6,
/**
* @var object A hash used to prime the cache with data about the initially
* loaded page. This is set in the footer, and then loaded
* by a double-queued event further down this file.
*/
primer: {},
/**
* @var array Stores the content of the cached pages
*/
pages: [],
/**
* @var int The index of the currently loaded page
* This is used to know at which point in the history we are
*/
current: 0,
/**
* Saves a new page in the cache
*
* @param string hash The hash part of the url that is being loaded
* @param array scripts A list of scripts that is required for the page
* @param string menu A hash that links to a menu stored
* in a dedicated menu cache
* @param array params A list of parameters used by CommonParams()
* @param string rel A relationship to the current page:
* 'samepage': Forces the response to be treated as
* the same page as the current one
* 'newpage': Forces the response to be treated as
* a new page
* undefined: Default behaviour, 'samepage' if the
* selflinks of the two pages are the same.
* 'newpage' otherwise
*
* @return void
*/
add: function (hash, scripts, menu, params, rel) {
if (this.pages.length > MicroHistory.MAX) {
// Trim the cache, to the maximum number of allowed entries
// This way we will have a cached menu for every page
for (var i = 0; i < this.pages.length - this.MAX; i++) {
delete this.pages[i];
}
}
while (this.current < this.pages.length) {
// trim the cache if we went back in the history
// and are now going forward again
this.pages.pop();
}
if (rel === 'newpage' ||
(
typeof rel === 'undefined' && (
typeof this.pages[this.current - 1] === 'undefined' ||
this.pages[this.current - 1].hash !== hash
)
)
) {
this.pages.push({
hash: hash,
content: $('#page_content').html(),
scripts: scripts,
selflink: $('#selflink').html(),
menu: menu,
params: params
});
MicroHistory.setUrlHash(this.current, hash);
this.current++;
}
},
/**
* Restores a page from the cache. This is called when the hash
* part of the url changes and it's structure appears to be valid
*
* @param string index Which page from the history to load
*
* @return void
*/
navigate: function (index) {
var localIndex = index;
if (typeof this.pages[localIndex] === 'undefined' ||
typeof this.pages[localIndex].content === 'undefined' ||
typeof this.pages[localIndex].menu === 'undefined' ||
! MicroHistory.menus.get(this.pages[localIndex].menu)
) {
Functions.ajaxShowMessage(
'<div class="error">' + Messages.strInvalidPage + '</div>',
false
);
} else {
AJAX.active = true;
var record = this.pages[localIndex];
AJAX.scriptHandler.reset(function () {
$('#page_content').html(record.content);
$('#selflink').html(record.selflink);
MicroHistory.menus.replace(MicroHistory.menus.get(record.menu));
CommonParams.setAll(record.params);
AJAX.scriptHandler.load(record.scripts);
MicroHistory.current = ++localIndex;
});
}
},
/**
* Resaves the content of the current page in the cache.
* Necessary in order not to show the user some outdated version of the page
*
* @return void
*/
update: function () {
var page = this.pages[this.current - 1];
if (page) {
page.content = $('#page_content').html();
}
},
/**
* @var object Dedicated menu cache
*/
menus: {
/**
* Returns the number of items in an associative array
*
* @return int
*/
size: function (obj) {
var size = 0;
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
size++;
}
}
return size;
},
/**
* @var hash Stores the content of the cached menus
*/
data: {},
/**
* Saves a new menu in the cache
*
* @param string hash The hash (trimmed md5) of the menu to be saved
* @param string content The HTML code of the menu to be saved
*
* @return void
*/
add: function (hash, content) {
if (this.size(this.data) > MicroHistory.MAX) {
// when the cache grows, we remove the oldest entry
var oldest;
var key;
var init = 0;
for (var i in this.data) {
if (this.data[i]) {
if (! init || this.data[i].timestamp.getTime() < oldest.getTime()) {
oldest = this.data[i].timestamp;
key = i;
init = 1;
}
}
}
delete this.data[key];
}
this.data[hash] = {
content: content,
timestamp: new Date()
};
},
/**
* Retrieves a menu given its hash
*
* @param string hash The hash of the menu to be retrieved
*
* @return string
*/
get: function (hash) {
if (this.data[hash]) {
return this.data[hash].content;
} else {
// This should never happen as long as the number of stored menus
// is larger or equal to the number of pages in the page cache
return '';
}
},
/**
* Prepares part of the parameter string used during page requests,
* this is necessary to tell the server which menus we have in the cache
*
* @return string
*/
getRequestParam: function () {
var param = '';
var menuHashes = [];
for (var i in this.data) {
menuHashes.push(i);
}
var menuHashesParam = menuHashes.join('-');
if (menuHashesParam) {
param = CommonParams.get('arg_separator') + 'menuHashes=' + menuHashesParam;
}
return param;
},
/**
* Replaces the menu with new content
*
* @return void
*/
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(Functions.mainMenuResizerCallback);
}
}
};
/**
* URL hash management module.
* Allows direct bookmarking and microhistory.
*/
MicroHistory.setUrlHash = (function (jQuery, window) {
'use strict';
/**
* Indictaes whether we have already completed
* the initialisation of the hash
*
* @access private
*/
var ready = false;
/**
* Stores a hash that needed to be set when we were not ready
*
* @access private
*/
var savedHash = '';
/**
* Flag to indicate if the change of hash was triggered
* by a user pressing the back/forward button or if
* the change was triggered internally
*
* @access private
*/
var userChange = true;
// Fix favicon disappearing in Firefox when setting location.hash
function resetFavicon () {
if (navigator.userAgent.indexOf('Firefox') > -1) {
// Move the link tags for the favicon to the bottom
// of the head element to force a reload of the favicon
$('head > link[href="favicon\\.ico"]').appendTo('head');
}
}
/**
* Sets the hash part of the URL
*
* @access public
*/
function setUrlHash (index, hash) {
/*
* Known problem:
* Setting hash leads to reload in webkit:
* http://www.quirksmode.org/bugreports/archives/2005/05/Safari_13_visual_anomaly_with_windowlocationhref.html
*
* so we expect that users are not running an ancient Safari version
*/
userChange = false;
if (ready) {
window.location.hash = 'PMAURL-' + index + ':' + hash;
resetFavicon();
} else {
savedHash = 'PMAURL-' + index + ':' + hash;
}
}
/**
* Start initialisation
*/
var urlHash = window.location.hash;
if (urlHash.substring(0, 8) === '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colonPosition = urlHash.indexOf(':');
var questionMarkPosition = urlHash.indexOf('?');
if (colonPosition !== -1 && questionMarkPosition !== -1 && colonPosition < questionMarkPosition) {
var hashUrl = urlHash.substring(colonPosition + 1, questionMarkPosition);
if (GotoWhitelist.indexOf(hashUrl) !== -1) {
window.location = urlHash.substring(
colonPosition + 1
);
}
}
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
jQuery(function () {
/* Check if we should set URL */
if (savedHash !== '') {
window.location.hash = savedHash;
savedHash = '';
resetFavicon();
}
// Indicate that we're done initialising
ready = true;
});
}
/**
* Register an event handler for when the url hash changes
*/
jQuery(function () {
jQuery(window).hashchange(function () {
if (userChange === false) {
// Ignore internally triggered hash changes
userChange = true;
} else if (/^#PMAURL-\d+:/.test(window.location.hash)) {
// Change page if the hash changed was triggered by a user action
var index = window.location.hash.substring(
8, window.location.hash.indexOf(':')
);
MicroHistory.navigate(index);
}
});
});
/**
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
}(jQuery, window));

View File

@ -1,85 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview Implements the shiftkey + click remove column
* from order by clause funcationality
* @name columndelete
*
* @requires jQuery
*/
function captureURL (url) {
var newUrl = '' + url;
var URL = {};
// Exclude the url part till HTTP
newUrl = newUrl.substr(newUrl.search('sql.php'), newUrl.length);
// The url part between ORDER BY and &session_max_rows needs to be replaced.
URL.head = newUrl.substr(0, newUrl.indexOf('ORDER+BY') + 9);
URL.tail = newUrl.substr(newUrl.indexOf('&session_max_rows'), newUrl.length);
return URL;
}
/**
* This function is for navigating to the generated URL
*
* @param object target HTMLAnchor element
* @param object parent HTMLDom Object
*/
function removeColumnFromMultiSort (target, parent) {
var URL = captureURL(target);
var begin = target.indexOf('ORDER+BY') + 8;
var end = target.indexOf(CommonParams.get('arg_separator') + 'session_max_rows');
// get the names of the columns involved
var betweenPart = target.substr(begin, end - begin);
var columns = betweenPart.split('%2C+');
// If the given column is not part of the order clause exit from this function
var index = parent.find('small').length ? parent.find('small').text() : '';
if (index === '') {
return '';
}
// Remove the current clicked column
columns.splice(index - 1, 1);
// If all the columns have been removed dont submit a query with nothing
// After order by clause.
if (columns.length === 0) {
var head = URL.head;
head = head.slice(0,head.indexOf('ORDER+BY'));
URL.head = head;
// removing the last sort order should have priority over what
// is remembered via the RememberSorting directive
URL.tail += CommonParams.get('arg_separator') + 'discard_remembered_sort=1';
}
URL.head = URL.head.substring(URL.head.indexOf('?') + 1);
var middlePart = columns.join('%2C+');
var params = URL.head + middlePart + URL.tail;
return params;
}
AJAX.registerOnload('keyhandler.js', function () {
$('th.draggable.column_heading.pointer.marker a').on('click', function (event) {
var url = $(this).parent().find('input').val();
var argsep = CommonParams.get('arg_separator');
var params;
if (event.ctrlKey || event.altKey) {
event.preventDefault();
params = removeColumnFromMultiSort(url, $(this).parent());
if (params) {
AJAX.source = $(this);
Functions.ajaxShowMessage();
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
} else if (event.shiftKey) {
event.preventDefault();
AJAX.source = $(this);
Functions.ajaxShowMessage();
params = url.substring(url.indexOf('?') + 1);
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
});
});
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('click', 'th.draggable.column_heading.pointer.marker a');
});

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