Merged branch official/master. Resolved merge conflicts introduced due to merging of Piotr and Martynas's branches

This commit is contained in:
ninadsp
2010-08-28 01:53:52 +05:30
172 changed files with 233085 additions and 159854 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ phpmyadmin.wpj
.settings .settings
.buildpath .buildpath
.cache .cache
.idea
*.sw[op] *.sw[op]
# Locales # Locales
locale locale

View File

@@ -104,6 +104,14 @@ $Id$
thanks to Isaac Bennetch - ibennetch thanks to Isaac Bennetch - ibennetch
- patch #3038312 [export] JSON export, - patch #3038312 [export] JSON export,
thanks to Hauke Henningsen - blubberkeks152 thanks to Hauke Henningsen - blubberkeks152
- rfe #1494550 [interface] Editor for SET/ENUM fields.
- rfe #2649375 [interface] Simplified interface to backup/restore.
- rfe #2973909 Users preferences
- [relations] Dropped WYSIWYG-PDF configuration variable.
- rfe #806035, #686260 [relations] Export relations to Dia, SVG and others
+ [interface] Added charts to status tab, profiling page and query results
3.3.7.0 (not yet released)
3.3.6.0 (not yet released) 3.3.6.0 (not yet released)
- bug #3033063 [core] Navi gets wrong db name - bug #3033063 [core] Navi gets wrong db name

View File

@@ -1139,6 +1139,27 @@ CREATE DATABASE,ALTER DATABASE,DROP DATABASE</pre>
<br/><br/> <br/><br/>
</dd> </dd>
<dt id="userconfig">
<span id="cfg_Servers_userconfig">$cfg['Servers'][$i]['userconfig']</span> string
</dt>
<dd>
Since release 3.4.x phpMyAdmin allows users to set most preferences by themselves
and store them in the database.
<br /><br />
If you don't allow for storing preferences in <a href="#pmadb">pmadb</a>, users can
still personalize phpMyAdmin, but settings will be saved in browser's local storage,
or, it is is unavailable, until the end of session.
<br /><br />
To allow the usage of this functionality:
<ul>
<li>set up <a href="#pmadb">pmadb</a> and the phpMyAdmin
configuration storage</li>
<li>put the table name in <tt>$cfg['Servers'][$i]['userconfig']</tt></li>
</ul>
</dd>
<dt id="designer_coords"> <dt id="designer_coords">
<span id="cfg_Servers_designer_coords">$cfg['Servers'][$i]['designer_coords']</span> string <span id="cfg_Servers_designer_coords">$cfg['Servers'][$i]['designer_coords']</span> string
@@ -1183,7 +1204,7 @@ CREATE DATABASE,ALTER DATABASE,DROP DATABASE</pre>
<span id="cfg_Servers_AllowDeny_order">$cfg['Servers'][$i]['AllowDeny']['order']</span> string <span id="cfg_Servers_AllowDeny_order">$cfg['Servers'][$i]['AllowDeny']['order']</span> string
</dt> </dt>
<dd>If your rule order is empty, then <abbr title="Internet Protocol">IP</abbr> <dd>If your rule order is empty, then <abbr title="Internet Protocol">IP</abbr>
authentication is disabled.<br /><br /> authorization is disabled.<br /><br />
If your rule order is set to <tt>'deny,allow'</tt> then the system applies If your rule order is set to <tt>'deny,allow'</tt> then the system applies
all deny rules followed by allow rules. Access is allowed by default. Any all deny rules followed by allow rules. Access is allowed by default. Any
@@ -1195,7 +1216,7 @@ CREATE DATABASE,ALTER DATABASE,DROP DATABASE</pre>
default. Any client which does not match an Allow directive or does default. Any client which does not match an Allow directive or does
match a Deny directive will be denied access to the server.<br /><br /> match a Deny directive will be denied access to the server.<br /><br />
If your rule order is set to 'explicit', the authentication is If your rule order is set to 'explicit', authorization is
performed in a similar fashion to rule order 'deny,allow', with the performed in a similar fashion to rule order 'deny,allow', with the
added restriction that your host/username combination <b>must</b> be added restriction that your host/username combination <b>must</b> be
listed in the <i>allow</i> rules, and not listed in the <i>deny</i> listed in the <i>allow</i> rules, and not listed in the <i>deny</i>
@@ -2021,12 +2042,14 @@ setfacl -d -m "g:www-data:rwx" tmp
identify what they mean. identify what they mean.
</dd> </dd>
<dt id="cfg_Export">$cfg['Export']['method'] string</dt> <dt id="cfg_Export_method">$cfg['Export']['method'] string</dt>
<dd> <dd>
Defines how the export form is displayed when it loads. Valid values are: Defines how the export form is displayed when it loads. Valid values are:
<ul>
<li><tt>quick</tt> to display the minimum number of options to configure</li> <li><tt>quick</tt> to display the minimum number of options to configure</li>
<li><tt>custom</tt> to display every available option to configure</li> <li><tt>custom</tt> to display every available option to configure</li>
<li><tt>custom-no-form</tt> same as <tt>custom</tt> but does not display the option of using quick export</li> <li><tt>custom-no-form</tt> same as <tt>custom</tt> but does not display the option of using quick export</li>
</ul>
</dd> </dd>
<dt id="cfg_Import">$cfg['Import'] array</dt> <dt id="cfg_Import">$cfg['Import'] array</dt>
@@ -2117,32 +2140,6 @@ setfacl -d -m "g:www-data:rwx" tmp
any row counting. any row counting.
</dd> </dd>
<dt id="wysiwyg">
<span id="cfg_WYSIWYG-PDF">$cfg['WYSIWYG-PDF'] </span>boolean</dt>
<dd>Utilizes a WYSIWYG editing control to easily place elements of a
<abbr title="Portable Document Format">PDF</abbr>
page. By clicking on the button 'toggle scratchboard' on the page
where you edit x/y coordinates of those elements you can activate a
scratchboard where all your elements are placed. By clicking on an
element, you can move them around in the pre-defined area and the x/y
coordinates will get updated dynamically. Likewise, when entering a
new position directly into the input field, the new position in the
scratchboard changes after your cursor leaves the input field.<br />
You have to click on the 'OK'-button below the tables to save the new
positions. If you want to place a new element, first add it to the
table of elements and then you can drag the new element around.<br />
By changing the paper size and the orientation you can change the size
of the scratchboard as well. You can do so by just changing the
dropdown field below, and the scratchboard will resize automatically,
without interfering with the current placement of the elements.<br />
If ever an element gets out of range you can either enlarge the paper
size or click on the 'reset' button to place all elements below each
other.<br />
<b>NOTE:</b> You have to use a recent browser like IE6 or Mozilla to
get this control to work. The basic Drag&amp;Drop script functionality
was kindly borrowed from www.youngpup.net and is underlying so
specific license.</dd>
<dt id="cfg_NaturalOrder">$cfg['NaturalOrder'] boolean</dt> <dt id="cfg_NaturalOrder">$cfg['NaturalOrder'] boolean</dt>
<dd>Sorts database and table names according to natural order (for example, <dd>Sorts database and table names according to natural order (for example,
t1, t2, t10). Currently implemented in the left panel (Light mode) t1, t2, t10). Currently implemented in the left panel (Light mode)
@@ -2153,6 +2150,11 @@ setfacl -d -m "g:www-data:rwx" tmp
closed state. A value of <tt>'open'</tt> does the reverse. To completely closed state. A value of <tt>'open'</tt> does the reverse. To completely
disable all visual sliders, use <tt>'disabled'</tt>.</dd> disable all visual sliders, use <tt>'disabled'</tt>.</dd>
<dt id="cfg_UserprefsDisallow">$cfg['UserprefsDisallow'] array</dt>
<dd>Contains names of configuration options (keys in <tt>$cfg</tt> array)
that users can't set through user preferences. For possible values, refer
to <tt>libraries/config/user_preferences.forms.php</tt>.</dd>
<dt id="cfg_TitleTable">$cfg['TitleTable'] string</dt> <dt id="cfg_TitleTable">$cfg['TitleTable'] string</dt>
<dt id="cfg_TitleDatabase">$cfg['TitleDatabase'] string</dt> <dt id="cfg_TitleDatabase">$cfg['TitleDatabase'] string</dt>
<dt id="cfg_TitleServer">$cfg['TitleServer'] string</dt> <dt id="cfg_TitleServer">$cfg['TitleServer'] string</dt>
@@ -2627,8 +2629,7 @@ setfacl -d -m "g:www-data:rwx" tmp
<a href="#faq1_5">1.5 Using phpMyAdmin on <a href="#faq1_5">1.5 Using phpMyAdmin on
<abbr title="Internet Information Services">IIS</abbr>, I'm facing crashes <abbr title="Internet Information Services">IIS</abbr>, I'm facing crashes
and/or many error messages with the and/or many error messages with the
<abbr title="HyperText Transfer Protocol">HTTP</abbr> or advanced authentication <abbr title="HyperText Transfer Protocol">HTTP</abbr>.</a></h4>
mode.</a></h4>
<p> This is a known problem with the PHP <p> This is a known problem with the PHP
<abbr title="Internet Server Application Programming Interface">ISAPI</abbr> <abbr title="Internet Server Application Programming Interface">ISAPI</abbr>
@@ -2673,23 +2674,7 @@ setfacl -d -m "g:www-data:rwx" tmp
</ul> </ul>
<h4 id="faq1_9"> <h4 id="faq1_9">
<a href="#faq1_9">1.9 I'm having troubles when uploading files. In <a href="#faq1_9">1.9 (withdrawn).</a></h4>
general file uploads don't work on my system and uploaded files have a
<tt>Content-Type:</tt> header in the first line.</a></h4>
<p> It's not really phpMyAdmin related but RedHat 7.0. You have a RedHat 7.0
and you updated your PHP RPM to php-4.0.4pl1-3.i386.rpm, didn't you?<br />
So the problem is that this package has a serious bug that was corrected
ages ago in PHP (2001-01-28: see
<a href="http://www.php.net/bugs.php?id=8966">PHP's bug tracking system</a>
for more details). The problem is that the bugged package is still
available though it was corrected (see
<a href="http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=24933">RedHat's BugZilla</a>
for more details).<br />
So please download
<a href="http://www.redhat.com/swr/i386/php-4.0.4pl1-9.i386.html">the fixed package (4.0.4pl1-9)</a>
and the problem should go away.<br />
And that fixes the \r\n problem with file uploads!</p>
<h4 id="faq1_10"> <h4 id="faq1_10">
<a href="#faq1_10">1.10 I'm having troubles when uploading files with <a href="#faq1_10">1.10 I'm having troubles when uploading files with
@@ -2721,20 +2706,10 @@ setfacl -d -m "g:www-data:rwx" tmp
reset the permissions</a>.</p> reset the permissions</a>.</p>
<h4 id="faq1_13"> <h4 id="faq1_13">
<a href="#faq1_13">1.13 I get an error 'No <a href="#faq1_13">1.13 (withdrawn).</a></h4>
<abbr title="structured query language">SQL</abbr> query' when trying to
execute a bookmark.</a></h4>
<p> If PHP does not have read/write access to its <tt>upload_tmp_dir</tt>, it
cannot access the uploaded query.</p>
<h4 id="faq1_14"> <h4 id="faq1_14">
<a href="#faq1_14">1.14 I get an error 'No <a href="#faq1_14">1.14 (withdrawn).</a></h4>
<abbr title="structured query language">SQL</abbr> query' when trying to
submit a query from the convenient text area.</a></h4>
<p> Check the <tt>post_max_size</tt> directive from your PHP configuration file
and try to increase it.</p>
<h4 id="faq1_15"> <h4 id="faq1_15">
<a href="#faq1_15">1.15 I have problems with <i>mysql.user</i> column names.</a> <a href="#faq1_15">1.15 I have problems with <i>mysql.user</i> column names.</a>
@@ -3483,7 +3458,7 @@ have either the <a href="http://pecl.php.net/package/APC">APC</a> extension
<h4 id="faq3_15"> <h4 id="faq3_15">
<a href="#faq3_15">3.15 When I import an Excel spreadsheet, some cells with calculations do not display correctly.</a></h4> <a href="#faq3_15">3.15 When I import an Excel spreadsheet, some cells with calculations do not display correctly.</a></h4>
<p> <p>
phpMyAdmin uses the <a href="http://www.codeplex.com/PHPExcel/" target="_blank">PHPExcel</a> library to parse Excel XLS and XLSX spreadsheets. phpMyAdmin uses the <a href="http://www.codeplex.com/PHPExcel/">PHPExcel</a> library to parse Excel XLS and XLSX spreadsheets.
Therefore, any limitations that are listed on their page regarding Excel calculations will also apply here. Therefore, any limitations that are listed on their page regarding Excel calculations will also apply here.
<br /><br /> <br /><br />
PHPExcel will be kept up to date so as to make all improvements available to phpMyAdmin users. PHPExcel will be kept up to date so as to make all improvements available to phpMyAdmin users.
@@ -4336,6 +4311,40 @@ chmod o+rwx tmp
<dd>phpMyAdmin with version</dd> <dd>phpMyAdmin with version</dd>
</dl> </dl>
<h4 id="wysiwyg">
<a href="#wysiwyg">6.28 How can I easily edit relational schema for export?</a></h4>
<p>
By clicking on the button 'toggle scratchboard' on the page
where you edit x/y coordinates of those elements you can activate a
scratchboard where all your elements are placed. By clicking on an
element, you can move them around in the pre-defined area and the x/y
coordinates will get updated dynamically. Likewise, when entering a
new position directly into the input field, the new position in the
scratchboard changes after your cursor leaves the input field.
</p>
<p>
You have to click on the 'OK'-button below the tables to save the new
positions. If you want to place a new element, first add it to the
table of elements and then you can drag the new element around.
</p>
<p>
By changing the paper size and the orientation you can change the size
of the scratchboard as well. You can do so by just changing the
dropdown field below, and the scratchboard will resize automatically,
without interfering with the current placement of the elements.
</p>
<p>
If ever an element gets out of range you can either enlarge the paper
size or click on the 'reset' button to place all elements below each
other.
</p>
<h4 id="faq6_29">
<a href="#faq6_29">6.28 Why can't I get a chart from my query result table?</a></h4>
<p> Not every table can be put to the chart. Only tables with one, two or three columns can be visualised as a chart. Moreover the table must be in a special format for chart script to understand it. Currently supported formats can be found in the <a href="http://wiki.phpmyadmin.net/pma/Devel:Charts#Data_formats_for_query_results_chart">wiki</a>.</p>
<h3 id="faqproject">phpMyAdmin project</h3> <h3 id="faqproject">phpMyAdmin project</h3>
<h4 id="faq7_1"> <h4 id="faq7_1">
@@ -4806,9 +4815,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
<li>BLOBstreaming support</li> <li>BLOBstreaming support</li>
</ul></li> </ul></li>
<li>Piotr Przybylski (Google Summer of Code 2008) <li>Piotr Przybylski (Google Summer of Code 2008 and 2010)
<ul> <ul>
<li>improved setup script</li> <li>improved setup script</li>
<li>user preferences</li>
</ul></li> </ul></li>
<li>Derek Schaefer (Google Summer of Code 2009) <li>Derek Schaefer (Google Summer of Code 2009)
@@ -4831,6 +4841,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
<li>Replication support</li> <li>Replication support</li>
</ul></li> </ul></li>
<li>Muhammad Adnan (Google Summer of Code 2010)
<ul>
<li>Relation schema export to multiple formats</li>
</ul></li>
<li>Lori Lee (Google Summer of Code 2010)
<ul>
<li>User interface improvements</li>
<li>ENUM/SET editor</li>
<li>Simplified interface for export/import</li>
</ul></li>
<li>Barrie Leslie <li>Barrie Leslie
<ul> <ul>
<li>BLOBstreaming support with PBMS PHP extension</li> <li>BLOBstreaming support with PBMS PHP extension</li>

View File

@@ -49,6 +49,7 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
// $cfg['Servers'][$i]['history'] = 'pma_history'; // $cfg['Servers'][$i]['history'] = 'pma_history';
// $cfg['Servers'][$i]['tracking'] = 'pma_tracking'; // $cfg['Servers'][$i]['tracking'] = 'pma_tracking';
// $cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords'; // $cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';
// $cfg['Servers'][$i]['userconfig'] = 'pma_userconfig';
/* Contrib / Swekey authentication */ /* Contrib / Swekey authentication */
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf'; // $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';

View File

@@ -538,15 +538,15 @@ if ($cfgRelation['pdfwork'] && $num_tables > 0) { ?>
WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''; WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'';
$test_rs = PMA_query_as_controluser($test_query, null, PMA_DBI_QUERY_STORE); $test_rs = PMA_query_as_controluser($test_query, null, PMA_DBI_QUERY_STORE);
if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) { /*
include('./libraries/display_pdf_schema.lib.php'); * Export Relational Schema View
} // end if */
echo '<fieldset><a href="pdf_pages.php?' . $url_query . '">'; echo '<fieldset><a href="schema_edit.php?' . $url_query . '">';
if ($cfg['PropertiesIconic']) { if ($cfg['PropertiesIconic']) {
echo '<img class="icon" src="' . $pmaThemeImage . 'b_edit.png"' echo '<img class="icon" src="' . $pmaThemeImage . 'b_edit.png"'
.' alt="" width="16" height="16" />'; .' alt="" width="16" height="16" />';
} }
echo __('Edit PDF Pages') . '</a></fieldset>'; echo __('Edit or export relational schema') . '</a></fieldset>';
} // end if } // end if
/** /**

View File

@@ -256,15 +256,18 @@ if ($asfile) {
$pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']); $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']);
if ($export_type == 'server') { if ($export_type == 'server') {
if (isset($remember_template)) { if (isset($remember_template)) {
$GLOBALS['PMA_Config']->setCookie('pma_server_filename_template', $filename_template); $GLOBALS['PMA_Config']->setUserValue('pma_server_filename_template',
'Export/file_template_server', $filename_template);
} }
} elseif ($export_type == 'database') { } elseif ($export_type == 'database') {
if (isset($remember_template)) { if (isset($remember_template)) {
$GLOBALS['PMA_Config']->setCookie('pma_db_filename_template', $filename_template); $GLOBALS['PMA_Config']->setUserValue('pma_db_filename_template',
'Export/file_template_database', $filename_template);
} }
} else { } else {
if (isset($remember_template)) { if (isset($remember_template)) {
$GLOBALS['PMA_Config']->setCookie('pma_table_filename_template', $filename_template); $GLOBALS['PMA_Config']->setUserValue('pma_table_filename_template',
'Export/file_template_table', $filename_template);
} }
} }
$filename = PMA_expandUserString($filename_template); $filename = PMA_expandUserString($filename_template);

748
js/config.js Normal file
View File

@@ -0,0 +1,748 @@
/**
* Functions used in configuration forms and on user preferences pages
*/
// default values for fields
var defaultValues = {};
// language strings
var PMA_messages = {};
/**
* Returns field type
*
* @param {Element} field
*/
function getFieldType(field) {
field = $(field);
var tagName = field.attr('tagName');
if (tagName == 'INPUT') {
return field.attr('type');
} else if (tagName == 'SELECT') {
return 'select';
} else if (tagName == 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* 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} field_type see {@link #getFieldType}
* @param {String|Boolean} [value]
*/
function setFieldValue(field, field_type, value) {
field = $(field);
switch (field_type) {
case 'text':
field.attr('value', (value != undefined ? value : field.attr('defaultValue')));
break;
case 'checkbox':
field.attr('checked', (value != undefined ? value : field.attr('defaultChecked')));
break;
case 'select':
var options = field.attr('options');
var i, imax = options.length;
if (value == undefined) {
for (i = 0; i < imax; i++) {
options[i].selected = options[i].defaultSelected;
}
} else {
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} field_type returned by {@link #getFieldType}
* @type Boolean|String|String[]
*/
function getFieldValue(field, field_type) {
field = $(field);
switch (field_type) {
case 'text':
return field.attr('value');
case 'checkbox':
return field.attr('checked');
case 'select':
var options = field.attr('options');
var i, imax = options.length, 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
*/
function getAllValues() {
var elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type, 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) {
field = $(field);
var field_id = field.attr('id');
if (typeof defaultValues[field_id] == 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue(field, type);
if (type != 'select') {
isDefault = currentValue == defaultValues[field_id];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length != defaultValues[field_id].length) {
isDefault = false;
}
else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] != defaultValues[field_id][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Returns element's id prefix
* @param {Element} element
*/
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
_regexp_numeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
_regexp_pcre_extract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*/
validate_positive_number: function (isKeyUp) {
if (isKeyUp && this.value == '') {
return true;
}
var result = this.value != '0' && validators._regexp_numeric.test(this.value);
return result ? true : PMA_messages['error_nan_p'];
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*/
validate_non_negative_number: function (isKeyUp) {
if (isKeyUp && this.value == '') {
return true;
}
var result = validators._regexp_numeric.test(this.value);
return result ? true : PMA_messages['error_nan_nneg'];
},
/**
* Validates port number
*
* @param {boolean} isKeyUp
*/
validate_port_number: function(isKeyUp) {
if (this.value == '') {
return true;
}
var result = validators._regexp_numeric.test(this.value) && this.value != '0';
return result && this.value <= 65535 ? true : PMA_messages['error_incorrect_port'];
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*/
validate_by_regex: function(isKeyUp, regexp) {
if (isKeyUp && this.value == '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators._regexp_pcre_extract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) != null;
return valid ? true : PMA_messages['error_invalid_value'];
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {int} max_value
*/
validate_upper_bound: function(isKeyUp, max_value) {
var val = parseInt(this.value);
if (isNaN(val)) {
return true;
}
return val <= max_value ? true : PMA_messages['error_value_lte'].replace('%s', max_value);
},
// 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
*/
function validateField(id, type, onKeyUp, params) {
if (typeof validators[type] == 'undefined') {
return;
}
if (typeof validate[id] == 'undefined') {
validate[id] = [];
}
validate[id].push([type, params, onKeyUp]);
}
/**
* Returns valdiation functions associated with form field
*
* @param {String} field_id form field id
* @param {boolean} onKeyUpOnly see validateField
* @type Array
* @return array of [function, paramseters to be passed to function]
*/
function getFieldValidators(field_id, onKeyUpOnly) {
// look for field bound validator
var name = field_id.match(/[^-]+$/)[0];
if (typeof validators._field[name] != 'undefined') {
return [[validators._field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[field_id] != 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[field_id].length; i < imax; i++) {
if (onKeyUpOnly && !validate[field_id][i][2]) {
continue;
}
functions.push([validators[validate[field_id][i][0]], validate[field_id][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* display_input() in FormDisplay.tpl.php!
*
* @param {Object} error_list list of errors in the form {field id: error array}
*/
function displayErrors(error_list) {
for (var field_id in error_list) {
var errors = error_list[field_id];
var field = $('#'+field_id);
var isFieldset = field.attr('tagName') == 'FIELDSET';
var errorCnt = isFieldset
? field.find('dl.errors')
: field.siblings('.inline_errors');
// remove empty errors (used to clear error list)
errors = $.grep(errors, function(item) {
return item != '';
});
// 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" />');
field.find('table').before(errorCnt);
} else {
errorCnt = $('<dl class="inline_errors" />');
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 fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validate_fieldset(fieldset, isKeyUp, errors) {
fieldset = $(fieldset);
if (fieldset.length && typeof validators._fieldset[fieldset.attr('id')] != 'undefined') {
var fieldset_errors = validators._fieldset[fieldset.attr('id')].apply(fieldset[0], [isKeyUp]);
for (var field_id in fieldset_errors) {
if (typeof errors[field_id] == 'undefined') {
errors[field_id] = [];
}
if (typeof fieldset_errors[field_id] == 'string') {
fieldset_errors[field_id] = [fieldset_errors[field_id]];
}
$.merge(errors[field_id], fieldset_errors[field_id]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validate_field(field, isKeyUp, errors) {
field = $(field);
var field_id = field.attr('id');
errors[field_id] = [];
var functions = getFieldValidators(field_id, isKeyUp);
for (var i = 0; i < functions.length; i++) {
var args = functions[i][1] != null
? functions[i][1].slice(0)
: [];
args.unshift(isKeyUp);
var result = functions[i][0].apply(field[0], args);
if (result !== true) {
if (typeof result == 'string') {
result = [result];
}
$.merge(errors[field_id], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validate_field_and_fieldset(field, isKeyUp) {
field = $(field);
var errors = {};
validate_field(field, isKeyUp, errors);
validate_fieldset(field.closest('fieldset'), isKeyUp, errors);
displayErrors(errors);
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element} field
*/
function markField(field) {
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');
}
/**
* 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']();
}
$(function() {
// register validators and mark custom values
var elements = $('input[id], select[id], textarea[id]');
$('input[id], select[id], textarea[id]').each(function(){
markField(this);
var el = $(this);
el.bind('change', function() {
validate_field_and_fieldset(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.keyup(function() {
validate_field_and_fieldset(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 check_page_refresh = $('#check_page_refresh');
if (check_page_refresh.length == 0 || check_page_refresh.val() == '1') {
// run all field validators
var errors = {};
for (var i = 0; i < elements.length; i++) {
validate_field(elements[i], false, errors);
}
// run all fieldset validators
$('fieldset').each(function(){
validate_fieldset(this, false, errors);
});
displayErrors(errors);
} else if (check_page_refresh) {
check_page_refresh.val('1');
}
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Tabbed forms
//
/**
* Sets active tab
*
* @param {String} tab_id
*/
function setTab(tab_id) {
$('.tabs a').removeClass('active').filter('[href=' + tab_id + ']').addClass('active');
$('.tabs_contents fieldset').hide().filter(tab_id).show();
location.hash = 'tab_' + tab_id.substr(1);
$('.config-form input[name=tab_hash]').val(location.hash);
}
$(function() {
var tabs = $('.tabs');
if (!tabs.length) {
return;
}
// add tabs events and activate one tab (the first one or indicated by location hash)
tabs.find('a')
.click(function(e) {
e.preventDefault();
setTab($(this).attr('href'));
})
.filter(':first')
.addClass('active');
$('.tabs_contents fieldset').hide().filter(':first').show();
// tab links handling, check each 200ms
// (works with history in FF, further browser support here would be an overkill)
var prev_hash;
var tab_check_fnc = function() {
if (location.hash != prev_hash) {
prev_hash = location.hash;
if (location.hash.match(/^#tab_.+/) && $('#' + location.hash.substr(5)).length) {
setTab('#' + location.hash.substr(5));
}
}
};
tab_check_fnc();
setInterval(tab_check_fnc, 200);
});
//
// END: Tabbed forms
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Form reset buttons
//
$(function() {
$('input[type=button][name=submit_reset]').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]));
}
});
});
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
/**
* Restores field's default value
*
* @param {String} field_id
*/
function restoreField(field_id) {
var field = $('#'+field_id);
if (field.length == 0 || defaultValues[field_id] == undefined) {
return;
}
setFieldValue(field, getFieldType(field), defaultValues[field_id]);
}
$(function() {
$('.tabs_contents')
.delegate('.restore-default, .set-value', 'mouseenter', function(){$(this).css('opacity', 1)})
.delegate('.restore-default, .set-value', 'mouseleave', function(){$(this).css('opacity', 0.25)})
.delegate('.restore-default, .set-value', 'click', function(e) {
e.preventDefault();
var href = $(this).attr('href');
var field_sel;
if ($(this).hasClass('restore-default')) {
field_sel = href;
restoreField(field_sel.substr(1));
} else {
field_sel = href.match(/^[^=]+/)[0];
var value = href.match(/=(.+)$/)[1];
setFieldValue($(field_sel), 'text', value);
}
$(field_sel).trigger('change');
})
.find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({display: 'inline-block', opacity: 0.25});
});
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
$(function() {
offerPrefsAutoimport();
var radios = $('#import_local_storage, #export_local_storage');
if (!radios.length) {
return;
}
// enable JavaScript dependent fields
radios
.attr('disabled', false)
.add('#export_text_file, #import_text_file')
.click(function(){
var enable_id = $(this).attr('id');
var disable_id = enable_id.match(/local_storage$/)
? enable_id.replace(/local_storage$/, 'text_file')
: enable_id.replace(/text_file$/, 'local_storage');
$('#opts_'+disable_id).addClass('disabled').find('input').attr('disabled', true);
$('#opts_'+enable_id).removeClass('disabled').find('input').attr('disabled', false);
});
// detect localStorage state
var ls_supported = window.localStorage || false;
var ls_exists = ls_supported ? (window.localStorage['config'] || false) : false;
$('.localStorage-'+(ls_supported ? 'un' : '')+'supported').hide();
$('.localStorage-'+(ls_exists ? 'empty' : 'exists')).hide();
if (ls_exists) {
updatePrefsDate();
}
$('form.prefs-form').change(function(){
var form = $(this);
var disabled = false;
if (!ls_supported) {
disabled = form.find('input[type=radio][value$=local_storage]').attr('checked');
} else if (!ls_exists && form.attr('name') == 'prefs_import'
&& $('#import_local_storage')[0].checked) {
disabled = true;
}
form.find('input[type=submit]').attr('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']);
}
});
$('.click-hide-message').live('click', function(){
var div = $(this);
div.hide().parent('.group').css('height', '');
div.next('form').show();
});
});
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
function savePrefsToLocalStorage(form)
{
form = $(form);
var submit = form.find('input[type=submit]');
submit.attr('disabled', true);
$.ajax({
url: 'prefs_manage.php',
cache: false,
type: 'POST',
data: {
token: form.find('input[name=token]').val(),
submit_get_json: true
},
success: function(response) {
window.localStorage['config'] = response.prefs;
window.localStorage['config_mtime'] = response.mtime;
window.localStorage['config_mtime_local'] = (new Date()).toUTCString();
updatePrefsDate();
$('.localStorage-empty').hide();
$('.localStorage-exists').show();
var group = form.parent('.group');
group.css('height', group.height() + 'px');
form.hide('fast');
form.prev('.click-hide-message').show('fast');
},
complete: function() {
submit.attr('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
function updatePrefsDate()
{
var d = new Date(window.localStorage['config_mtime_local']);
var msg = PMA_messages['strSavedOn'].replace('@DATE@', formatDate(d));
$('#opts_import_local_storage .localStorage-exists').html(msg);
}
/**
* Returns date formatted as YYYY-MM-DD HH:II
*
* @param {Date} d
*/
function formatDate(d)
{
return d.getFullYear() + '-'
+ (d.getMonth() < 10 ? '0'+d.getMonth() : d.getMonth())
+ '-' + (d.getDate() < 10 ? '0'+d.getDate() : d.getDate())
+ ' ' + (d.getHours() < 10 ? '0'+d.getHours() : d.getHours())
+ ':' + (d.getMinutes() < 10 ? '0'+d.getMinutes() : d.getMinutes());
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported
*/
function offerPrefsAutoimport()
{
var has_config = (window.localStorage || false) && (window.localStorage['config'] || false);
var cnt = $('#prefs_autoload');
if (!cnt.length || !has_config) {
return;
}
cnt.find('a').click(function(e) {
e.preventDefault();
var a = $(this);
if (a.attr('href') == '#no') {
cnt.remove();
$.post('main.php', {
token: cnt.find('input[name=token]').val(),
prefs_autoload: 'hide'});
return;
}
cnt.find('input[name=json]').val(window.localStorage['config']);
cnt.find('form').submit();
});
cnt.show();
}
//
// END: User preferences import/export
// ------------------------------------------------------------------

View File

@@ -1400,7 +1400,7 @@ function getElement(e,f){
} }
/** /**
* Refresh the WYSIWYG-PDF scratchboard after changes have been made * Refresh the WYSIWYG scratchboard after changes have been made
*/ */
function refreshDragOption(e) { function refreshDragOption(e) {
var elm = $('#' + e); var elm = $('#' + e);
@@ -1410,13 +1410,16 @@ function refreshDragOption(e) {
} }
/** /**
* Refresh/resize the WYSIWYG-PDF scratchboard * Refresh/resize the WYSIWYG scratchboard
*/ */
function refreshLayout() { function refreshLayout() {
var elm = $('#pdflayout') var elm = $('#pdflayout')
var orientation = $('#orientation_opt').val(); var orientation = $('#orientation_opt').val();
var paper = $('#paper_opt').val(); if($('#paper_opt').length==1){
var paper = $('#paper_opt').val();
}else{
var paper = 'A4';
}
if (orientation == 'P') { if (orientation == 'P') {
posa = 'x'; posa = 'x';
posb = 'y'; posb = 'y';
@@ -1429,7 +1432,7 @@ function refreshLayout() {
} }
/** /**
* Show/hide the WYSIWYG-PDF scratchboard * Show/hide the WYSIWYG scratchboard
*/ */
function ToggleDragDrop(e) { function ToggleDragDrop(e) {
var elm = $('#' + e); var elm = $('#' + e);
@@ -1706,6 +1709,47 @@ $(document).ready(function(){
insertQuery(evt.target.id); insertQuery(evt.target.id);
return false; return false;
}); });
$("#export_type").change(function(){
if($("#export_type").val()=='svg'){
$("#show_grid_opt").attr("disabled","disabled");
$("#orientation_opt").attr("disabled","disabled");
$("#with_doc").attr("disabled","disabled");
$("#show_table_dim_opt").removeAttr("disabled");
$("#all_table_same_wide").removeAttr("disabled");
$("#paper_opt").removeAttr("disabled","disabled");
$("#show_color_opt").removeAttr("disabled","disabled");
//$(this).css("background-color","yellow");
}else if($("#export_type").val()=='dia'){
$("#show_grid_opt").attr("disabled","disabled");
$("#with_doc").attr("disabled","disabled");
$("#show_table_dim_opt").attr("disabled","disabled");
$("#all_table_same_wide").attr("disabled","disabled");
$("#paper_opt").removeAttr("disabled","disabled");
$("#show_color_opt").removeAttr("disabled","disabled");
$("#orientation_opt").removeAttr("disabled","disabled");
}else if($("#export_type").val()=='eps'){
$("#show_grid_opt").attr("disabled","disabled");
$("#orientation_opt").removeAttr("disabled");
$("#with_doc").attr("disabled","disabled");
$("#show_table_dim_opt").attr("disabled","disabled");
$("#all_table_same_wide").attr("disabled","disabled");
$("#paper_opt").attr("disabled","disabled");
$("#show_color_opt").attr("disabled","disabled");
}else if($("#export_type").val()=='pdf'){
$("#show_grid_opt").removeAttr("disabled");
$("#orientation_opt").removeAttr("disabled");
$("#with_doc").removeAttr("disabled","disabled");
$("#show_table_dim_opt").removeAttr("disabled","disabled");
$("#all_table_same_wide").removeAttr("disabled","disabled");
$("#paper_opt").removeAttr("disabled","disabled");
$("#show_color_opt").removeAttr("disabled","disabled");
}else{
// nothing
}
});
$('#sqlquery').focus(); $('#sqlquery').focus();
if ($('#input_username')) { if ($('#input_username')) {
if ($('#input_username').val() == '') { if ($('#input_username').val() == '') {
@@ -2455,3 +2499,99 @@ $(document).ready(function() {
}); });
}); });
}); });
function menuResize()
{
var cnt = $('#topmenu');
var wmax = cnt.width() - 5; // 5 px margin for jumping menu in Chrome
var submenu = cnt.find('.submenu');
var submenu_w = submenu.outerWidth(true);
var submenu_ul = submenu.find('ul');
var li = cnt.find('> li');
var li2 = submenu_ul.find('li');
var more_shown = li2.length > 0;
var w = more_shown ? submenu_w : 0;
// hide menu items
var hide_start = 0;
for (var i = 0; i < li.length-1; i++) { // li.length-1: skip .submenu element
var el = $(li[i]);
var el_width = el.outerWidth(true);
el.data('width', el_width);
w += el_width;
if (w > wmax) {
w -= el_width;
if (w + submenu_w < wmax) {
hide_start = i;
} else {
hide_start = i-1;
w -= $(li[i-1]).data('width');
}
break;
}
}
if (hide_start > 0) {
for (var i = hide_start; i < li.length-1; i++) {
$(li[i])[more_shown ? 'prependTo' : 'appendTo'](submenu_ul);
}
submenu.show();
} else if (more_shown) {
w -= submenu_w;
// nothing hidden, maybe something can be restored
for (var i = 0; i < li2.length; i++) {
//console.log(li2[i], submenu_w);
w += $(li2[i]).data('width');
// item fits or (it is the last item and it would fit if More got removed)
if (w+submenu_w < wmax || (i == li2.length-1 && w < wmax)) {
$(li2[i]).insertBefore(submenu);
if (i == li2.length-1) {
submenu.hide();
}
continue;
}
break;
}
}
if (submenu.find('.tabactive').length) {
submenu.addClass('active').find('> a').removeClass('tab').addClass('tabactive');
} else {
submenu.removeClass('active').find('> a').addClass('tab').removeClass('tabactive');
}
}
$(function() {
var topmenu = $('#topmenu');
if (topmenu.length == 0) {
return;
}
// create submenu container
var link = $('<a />', {href: '#', 'class': 'tab'})
.text(PMA_messages['strMore'])
.click(function(e) {
e.preventDefault();
});
var img = topmenu.find('li:first-child img');
if (img.length) {
img.clone().attr('src', img.attr('src').replace(/\/[^\/]+$/, '/b_more.png')).prependTo(link);
}
var submenu = $('<li />', {'class': 'submenu'})
.append(link)
.append($('<ul />'))
.mouseenter(function() {
if ($(this).find('ul .tabactive').length == 0) {
$(this).addClass('submenuhover').find('> a').addClass('tabactive');
}
})
.mouseleave(function() {
if ($(this).find('ul .tabactive').length == 0) {
$(this).removeClass('submenuhover').find('> a').removeClass('tabactive');
}
})
.hide();
topmenu.append(submenu);
// populate submenu and register resize event
$(window).resize(menuResize);
menuResize();
});

View File

@@ -106,6 +106,9 @@ $js_messages['strGeneratePassword'] = __('Generate password');
$js_messages['strGenerate'] = __('Generate'); $js_messages['strGenerate'] = __('Generate');
$js_messages['strChangePassword'] = __('Change Password'); $js_messages['strChangePassword'] = __('Change Password');
/* navigation tabs */
$js_messages['strMore'] = __('More');
echo "var PMA_messages = new Array();\n"; echo "var PMA_messages = new Array();\n";
foreach ($js_messages as $name => $js_message) { foreach ($js_messages as $name => $js_message) {
PMA_printJsValue("PMA_messages['" . $name . "']", $js_message); PMA_printJsValue("PMA_messages['" . $name . "']", $js_message);

164
js/pMap.js Normal file
View File

@@ -0,0 +1,164 @@
/**
* Holds the definition and the creation of the imageMap object
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
* responsible for showing tooltips above the image chart
*/
var imageMap = {
'mouseMoved': function(event, cont) {
// return if no imageMap set
// this can happen if server has no json
if (!this.imageMap) {
return;
}
// get mouse coordinated relative to image
var mouseX = event.pageX - cont.offsetLeft;
var mouseY = event.pageY - cont.offsetTop;
//console.log("X: " + mouseX + ", Y: " + mouseY);
/* Check if we are flying over a map zone
* Lets use the following method to check if a given
* point is in any convex polygon.
* http://www.programmingforums.org/post168124-3.html
*/
var found = false;
for (var key = 0; key < this.imageMap.length; key++)
{
var seriesName = this.imageMap[key]['n'];
var seriesValue = this.imageMap[key]['v'];
var signSum = 0;
for (var i = 0; i < this.imageMap[key]['p'].length; i++)
{
var index1;
var index2;
if (i == this.imageMap[key]['p'].length - 1)
{
index1 = i;
index2 = 0;
}
else
{
index1 = i;
index2 = i+1;
}
var result = this.getDeterminant(
this.imageMap[key]['p'][index1][0],
this.imageMap[key]['p'][index1][1],
this.imageMap[key]['p'][index2][0],
this.imageMap[key]['p'][index2][1],
mouseX,
mouseY
);
if (result > 0) { signSum += 1; } else { signSum += -1; }
}
if (Math.abs(signSum) == this.imageMap[key]['p'].length)
{
found = true;
if (this.currentKey != key)
{
this.tooltip.show();
this.tooltip.title(seriesName);
this.tooltip.text(seriesValue);
this.currentKey = key;
}
this.tooltip.move(mouseX + 20, mouseY + 20);
}
}
if (!found && this.currentKey != -1 )
{
this.tooltip.hide();
this.currentKey = -1;
}
},
'getDeterminant': function (X1, Y1, X2, Y2, X3, Y3) {
return (X2*Y3 - X3*Y2) - (X1*Y3 - X3*Y1) + (X1*Y2 - X2*Y1);
},
'loadImageMap': function(map) {
this.imageMap = JSON.parse(map);
for (key in this.imageMap)
{
// FIXME
// without this loop image map does not work
// on IE8 in the status page
}
},
'init': function() {
this.tooltip.init();
$("div#chart").bind('mousemove',function(e) {
imageMap.mouseMoved(e, this);
});
this.tooltip.attach("div#chart");
this.currentKey = -1;
},
'tooltip': {
'init': function () {
this.el = $('<div></div>');
this.el.css('position', 'absolute');
this.el.css('font-family', 'tahoma');
this.el.css('background-color', '#373737');
this.el.css('color', '#BEBEBE');
this.el.css('padding', '3px');
var title = $('<p></p>');
title.attr('id', 'title');
title.css('margin', '0px');
title.css('padding', '3px');
title.css('background-color', '#606060');
title.css('text-align', 'center');
title.html('Title');
this.el.append(title);
var text = $('<p></p>');
text.attr('id', 'text');
text.css('margin', '0');
text.html('Text');
this.el.append(text);
this.hide();
},
'attach': function (element) {
$(element).prepend(this.el);
},
'move': function (x, y) {
this.el.css('margin-left', x);
this.el.css('margin-top', y);
},
'hide': function () {
this.el.css('display', 'none');
},
'show': function () {
this.el.css('display', 'block');
},
'title': function (title) {
this.el.find("p#title").html(title);
},
'text': function (text) {
this.el.find("p#text").html(text.replace(/;/g, "<br />"));
}
}
};
$(document).ready(function() {
imageMap.init();
});

View File

@@ -23,6 +23,11 @@ class PMA_Config
*/ */
var $default_source = './libraries/config.default.php'; var $default_source = './libraries/config.default.php';
/**
* @var array default configuration settings
*/
var $default = array();
/** /**
* @var array configuration settings * @var array configuration settings
*/ */
@@ -320,6 +325,7 @@ class PMA_Config
$this->default_server = $cfg['Servers'][1]; $this->default_server = $cfg['Servers'][1];
unset($cfg['Servers']); unset($cfg['Servers']);
$this->default = $cfg;
$this->settings = PMA_array_merge_recursive($this->settings, $cfg); $this->settings = PMA_array_merge_recursive($this->settings, $cfg);
$this->error_config_default_file = false; $this->error_config_default_file = false;
@@ -408,6 +414,176 @@ class PMA_Config
return true; return true;
} }
/**
* Loads user preferences and merges them with current config
* must be called after control connection has been estabilished
*
* @uses $GLOBALS['cfg']
* @uses $GLOBALS['collation_connection']
* @uses $GLOBALS['lang']
* @uses $_SESSION['cache']['server_$server']['config_mtime']
* @uses $_SESSION['cache']['server_$server']['userprefs']
* @uses $_SESSION['cache']['server_$server']['userprefs_mtime']
* @uses $_SESSION['PMA_Theme_Manager']
* @uses PMA_apply_userprefs()
* @uses PMA_array_merge_recursive()
* @uses PMA_load_userprefs()
* @return boolean
*/
function loadUserPreferences()
{
// index.php should load these settings, so that phpmyadmin.css.php
// will have everything avaiable in session cache
$server = isset($GLOBALS['server'])
? $GLOBALS['server']
: (!empty($GLOBALS['cfg']['ServerDefault']) ? $GLOBALS['cfg']['ServerDefault'] : 0);
$cache_key = 'server_' . $server;
if ($server > 0 && !defined('PMA_MINIMUM_COMMON')) {
$config_mtime = max($this->default_source_mtime, $this->source_mtime);
// cache user preferences, use database only when needed
if (!isset($_SESSION['cache'][$cache_key]['userprefs'])
|| $_SESSION['cache'][$cache_key]['config_mtime'] < $config_mtime) {
// load required libraries
require_once './libraries/user_preferences.lib.php';
$prefs = PMA_load_userprefs();
$_SESSION['cache'][$cache_key]['userprefs'] = PMA_apply_userprefs($prefs['config_data']);
$_SESSION['cache'][$cache_key]['userprefs_mtime'] = $prefs['mtime'];
$_SESSION['cache'][$cache_key]['userprefs_type'] = $prefs['type'];
$_SESSION['cache'][$cache_key]['config_mtime'] = $config_mtime;
}
} else if ($server == 0 || !isset($_SESSION['cache'][$cache_key]['userprefs'])) {
$this->set('user_preferences', false);
return;
}
$config_data = $_SESSION['cache'][$cache_key]['userprefs'];
// type is 'db' or 'session'
$this->set('user_preferences', $_SESSION['cache'][$cache_key]['userprefs_type']);
$this->set('user_preferences_mtime', $_SESSION['cache'][$cache_key]['userprefs_mtime']);
// backup some settings
$org_fontsize = $this->settings['fontsize'];
// load config array
$this->settings = PMA_array_merge_recursive($this->settings, $config_data);
$GLOBALS['cfg'] = PMA_array_merge_recursive($GLOBALS['cfg'], $config_data);
if (defined('PMA_MINIMUM_COMMON')) {
return;
}
// settings below start really working on next page load, but
// changes are made only in index.php so everything is set when
// in frames
// save theme
$tmanager = $_SESSION['PMA_Theme_Manager'];
if ($tmanager->getThemeCookie() || isset($_REQUEST['set_theme'])) {
if ((!isset($config_data['ThemeDefault']) && $tmanager->theme->getId() != 'original')
|| isset($config_data['ThemeDefault']) && $config_data['ThemeDefault'] != $tmanager->theme->getId()) {
// new theme was set in common.inc.php
$this->setUserValue(null, 'ThemeDefault', $tmanager->theme->getId(), 'original');
}
} else {
// no cookie - read default from settings
if ($this->settings['ThemeDefault'] != $tmanager->theme->getId()
&& $tmanager->checkTheme($this->settings['ThemeDefault'])) {
$tmanager->setActiveTheme($this->settings['ThemeDefault']);
$tmanager->setThemeCookie();
}
}
// save font size
if ((!isset($config_data['fontsize']) && $org_fontsize != '82%')
|| isset($config_data['fontsize']) && $org_fontsize != $config_data['fontsize']) {
$this->setUserValue(null, 'fontsize', $org_fontsize, '82%');
}
// save language
if (isset($_COOKIE['pma_lang']) || isset($_POST['lang'])) {
if ((!isset($config_data['lang']) && $GLOBALS['lang'] != 'en')
|| isset($config_data['lang']) && $GLOBALS['lang'] != $config_data['lang']) {
$this->setUserValue(null, 'lang', $GLOBALS['lang'], 'en');
}
} else {
// read language from settings
if (isset($config_data['lang']) && PMA_langSet($config_data['lang'])) {
$this->setCookie('pma_lang', $GLOBALS['lang']);
}
}
// save connection collation
if (isset($_COOKIE['pma_collation_connection']) || isset($_POST['collation_connection'])) {
if ((!isset($config_data['collation_connection']) && $GLOBALS['collation_connection'] != 'utf8_general_ci')
|| isset($config_data['collation_connection']) && $GLOBALS['collation_connection'] != $config_data['collation_connection']) {
$this->setUserValue(null, 'collation_connection', $GLOBALS['collation_connection'], 'utf8_general_ci');
}
} else {
// read collation from settings
if (isset($config_data['collation_connection'])) {
$GLOBALS['collation_connection'] = $config_data['collation_connection'];
$this->setCookie('pma_collation_connection', $GLOBALS['collation_connection']);
}
}
}
/**
* Sets config value which is stored in user preferences (if available) or in a cookie.
*
* If user preferences are not yet initialized, option is applied to global config and
* added to a update queue, which is processed by {@link loadUserPreferences()}
*
* @uses $GLOBALS['cfg']
* @uses PMA_array_read()
* @uses PMA_array_write()
* @uses PMA_persist_option()
* @param string $cookie_name can be null
* @param string $cfg_path
* @param mixed $new_cfg_value
* @param mixed $default_value
*/
function setUserValue($cookie_name, $cfg_path, $new_cfg_value, $default_value = null)
{
// use permanent user preferences if possible
$prefs_type = $this->get('user_preferences');
if ($prefs_type) {
require_once './libraries/user_preferences.lib.php';
if ($default_value === null) {
$default_value = PMA_array_read($cfg_path, $this->default);
}
PMA_persist_option($cfg_path, $new_cfg_value, $default_value);
}
if ($prefs_type != 'db' && $cookie_name) {
// fall back to cookies
if ($default_value === null) {
$default_value = PMA_array_read($cfg_path, $this->settings);
}
$this->setCookie($cookie_name, $new_cfg_value, $default_value);
}
PMA_array_write($cfg_path, $GLOBALS['cfg'], $new_cfg_value);
PMA_array_write($cfg_path, $this->settings, $new_cfg_value);
}
/**
* Reads value stored by {@link setUserValue()}
*
* @param string $cookie_name
* @param mixed $cfg_value
* @return mixed
*/
function getUserValue($cookie_name, $cfg_value)
{
$cookie_exists = isset($_COOKIE) && !empty($_COOKIE[$cookie_name]);
$prefs_type = $this->get('user_preferences');
if ($prefs_type == 'db') {
// permanent user preferences value exists, remove cookie
if ($cookie_exists) {
$this->removeCookie($cookie_name);
}
} else if ($cookie_exists) {
return $_COOKIE[$cookie_name];
}
// return value from $cfg array
return $cfg_value;
}
/** /**
* set source * set source
* @param string $source * @param string $source
@@ -537,6 +713,7 @@ class PMA_Config
$fontsize + $fontsize +
$this->source_mtime + $this->source_mtime +
$this->default_source_mtime + $this->default_source_mtime +
$this->get('user_preferences_mtime') +
$_SESSION['PMA_Theme']->mtime_info + $_SESSION['PMA_Theme']->mtime_info +
$_SESSION['PMA_Theme']->filesize_info) $_SESSION['PMA_Theme']->filesize_info)
. (isset($_SESSION['tmp_user_values']['custom_color']) ? substr($_SESSION['tmp_user_values']['custom_color'],1,6) : ''); . (isset($_SESSION['tmp_user_values']['custom_color']) ? substr($_SESSION['tmp_user_values']['custom_color'],1,6) : '');
@@ -726,10 +903,10 @@ class PMA_Config
{ {
$new_fontsize = ''; $new_fontsize = '';
if (isset($_GET['fontsize'])) { if (isset($_GET['set_fontsize'])) {
$new_fontsize = $_GET['fontsize']; $new_fontsize = $_GET['set_fontsize'];
} elseif (isset($_POST['fontsize'])) { } elseif (isset($_POST['set_fontsize'])) {
$new_fontsize = $_POST['fontsize']; $new_fontsize = $_POST['set_fontsize'];
} elseif (isset($_COOKIE['pma_fontsize'])) { } elseif (isset($_COOKIE['pma_fontsize'])) {
$new_fontsize = $_COOKIE['pma_fontsize']; $new_fontsize = $_COOKIE['pma_fontsize'];
} }
@@ -1011,7 +1188,7 @@ class PMA_Config
$options = PMA_Config::_getFontsizeOptions($current_size); $options = PMA_Config::_getFontsizeOptions($current_size);
$return = '<label for="select_fontsize">' . __('Font size') . ':</label>' . "\n"; $return = '<label for="select_fontsize">' . __('Font size') . ':</label>' . "\n";
$return .= '<select name="fontsize" id="select_fontsize" onchange="this.form.submit();">' . "\n"; $return .= '<select name="set_fontsize" id="select_fontsize" onchange="this.form.submit();">' . "\n";
foreach ($options as $option) { foreach ($options as $option) {
$return .= '<option value="' . $option . '"'; $return .= '<option value="' . $option . '"';
if ($option == $current_size) { if ($option == $current_size) {

View File

@@ -318,7 +318,7 @@ class PMA_Error extends PMA_Message
if (in_array($function, $include_functions)) { if (in_array($function, $include_functions)) {
echo PMA_Error::relPath($arg); echo PMA_Error::relPath($arg);
} elseif (is_scalar($arg)) { } elseif (is_scalar($arg)) {
echo gettype($arg) . ' ' . $arg; echo gettype($arg) . ' ' . htmlspecialchars($arg);
} else { } else {
echo gettype($arg); echo gettype($arg);
} }

View File

@@ -721,7 +721,7 @@ class PMA_Message
static public function format() static public function format()
{ {
$params = func_get_args(); $params = func_get_args();
if (is_array($params[1])) { if (isset($params[1]) && is_array($params[1])) {
array_unshift($params[1], $params[0]); array_unshift($params[1], $params[0]);
$params = $params[1]; $params = $params[1];
} }

257
libraries/chart.lib.php Normal file
View File

@@ -0,0 +1,257 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Chart functions used to generate various types of charts.
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
define('ERR_NO_GD', 0);
define('ERR_NO_JSON', 1);
require_once './libraries/chart/pma_pchart_pie.php';
require_once './libraries/chart/pma_pchart_single_bar.php';
require_once './libraries/chart/pma_pchart_multi_bar.php';
require_once './libraries/chart/pma_pchart_stacked_bar.php';
require_once './libraries/chart/pma_pchart_single_line.php';
require_once './libraries/chart/pma_pchart_multi_line.php';
require_once './libraries/chart/pma_pchart_single_radar.php';
require_once './libraries/chart/pma_pchart_multi_radar.php';
/**
* Formats a chart for the status page.
* @param array $data data for the status chart
* @return string HTML and JS code for the chart
*/
function PMA_chart_status($data)
{
// format keys which will be shown in the chart
$chartData = array();
foreach($data as $dataKey => $dataValue) {
$key = ucwords(str_replace(array('Com_', '_'), array('', ' '), $dataKey));
$value = (int)$dataValue;
$chartData[$key] = $value;
}
$chart = new PMA_pChart_Pie(
$chartData,
array('titleText' => __('Query statistics'))
);
$chartCode = $chart->toString();
PMA_handle_chart_err($chart->getErrors());
echo $chartCode;
}
/**
* Formats a chart for the profiling page.
* @param array $data data for the status chart
* @return string HTML and JS code for the chart
*/
function PMA_chart_profiling($data)
{
$chartData = array();
foreach($data as $dataValue) {
$value = (int)($dataValue['Duration'] * 1000000);
$key = ucwords($dataValue['Status']);
$chartData[$key] = $value;
}
$chart = new PMA_pChart_Pie(
$chartData,
array('titleText' => __('Query execution time comparison (in microseconds)'))
);
$chartCode = $chart->toString();
PMA_handle_chart_err($chart->getErrors());
echo $chartCode;
}
/**
* Formats a chart for the query results page.
* @param array $data data for the status chart
* @param array $chartSettings settings used to generate the chart
* @return string HTML and JS code for the chart
*/
function PMA_chart_results($data, &$chartSettings)
{
$chartData = array();
$chart = null;
// set default title if not already set
if (empty($chartSettings['titleText'])) {
$chartSettings['titleText'] = __('Query results');
}
// set default type if not already set
if (empty($chartSettings['type'])) {
$chartSettings['type'] = 'bar';
}
// set default type if not already set
if (empty($chartSettings['continuous'])) {
$chartSettings['continuous'] = 'off';
}
// set default bar type if needed
if ($chartSettings['type'] == 'bar' && empty($chartSettings['barType'])) {
$chartSettings['barType'] = 'stacked';
}
// default for legend
$chartSettings['legend'] = false;
// default for muti series
$chartSettings['multi'] = false;
if (!isset($data[0])) {
// empty data
return __('No data found for the chart.');
}
if (count($data[0]) == 1 || count($data[0]) == 2) {
// One or two columns in every row.
// This data is suitable for a simple bar chart.
if ($chartSettings['type'] == 'pie') {
// loop through the rows, data for pie chart has to be formated
// in a different way then in other charts.
foreach ($data as $rowKey => $row) {
$values = array_values($row);
if (count($row) == 1) {
$chartData[$rowKey] = $values[0];
}
else {
$chartData[$values[1]] = $values[0];
}
}
$chartSettings['legend'] = true;
$chart = new PMA_pChart_pie($chartData, $chartSettings);
}
else {
// loop through the rows
foreach ($data as $rowKey => $row) {
// loop through the columns in the row
foreach ($row as $valueKey => $value) {
$chartData[$valueKey][] = $value;
}
// if only one column, we need to add
// placeholder data for x axis
if (count($row) == 1) {
$chartData[''][] = $rowKey;
}
}
switch ($chartSettings['type']) {
case 'bar':
default:
$chart = new PMA_pChart_single_bar($chartData, $chartSettings);
break;
case 'line':
$chart = new PMA_pChart_single_line($chartData, $chartSettings);
break;
case 'radar':
$chart = new PMA_pChart_single_radar($chartData, $chartSettings);
break;
}
}
}
else if (count($data[0]) == 3) {
// Three columns (x axis, y axis, series) in every row.
// This data is suitable for a stacked bar chart.
$chartSettings['multi'] = true;
$keys = array_keys($data[0]);
$yAxisKey = $keys[0];
$xAxisKey = $keys[1];
$seriesKey = $keys[2];
// get all the series labels
$seriesLabels = array();
foreach ($data as $row) {
$seriesLabels[] = $row[$seriesKey];
}
$seriesLabels = array_unique($seriesLabels);
// loop through the rows
$currentXLabel = $data[0][$xAxisKey];
foreach ($data as $row) {
// save the label
// use the same value as the key and the value to get rid of duplicate results
$chartData[$xAxisKey][$row[$xAxisKey]] = $row[$xAxisKey];
// make sure to set value to every serie
$currentSeriesLabel = (string)$row[$seriesKey];
foreach ($seriesLabels as $seriesLabelsValue) {
if ($currentSeriesLabel == $seriesLabelsValue) {
// the value os for this serie
$chartData[$yAxisKey][$seriesLabelsValue][$row[$xAxisKey]] = (int)$row[$yAxisKey];
}
else if (!isset($chartData[$yAxisKey][$seriesLabelsValue][$row[$xAxisKey]])) {
// if the value for this serie is not set, set it to 0
$chartData[$yAxisKey][$seriesLabelsValue][$row[$xAxisKey]] = 0;
}
}
}
$chartSettings['legend'] = true;
// determine the chart type
switch ($chartSettings['type']) {
case 'bar':
default:
// determine the bar chart type
switch ($chartSettings['barType']) {
case 'stacked':
default:
$chart = new PMA_pChart_stacked_bar($chartData, $chartSettings);
break;
case 'multi':
$chart = new PMA_pChart_multi_bar($chartData, $chartSettings);
break;
}
break;
case 'line':
$chart = new PMA_pChart_multi_line($chartData, $chartSettings);
break;
case 'radar':
$chart = new PMA_pChart_multi_radar($chartData, $chartSettings);
break;
}
}
else {
// unknown data format
return '';
}
$chartCode = $chart->toString();
$chartSettings = $chart->getSettings();
$chartErrors = $chart->getErrors();
PMA_handle_chart_err($chartErrors);
return $chartCode;
}
/**
* Simple handler of chart errors.
* @param array $errors all occured errors
*/
function PMA_handle_chart_err($errors)
{
if (in_array(ERR_NO_GD, $errors)) {
PMA_warnMissingExtension('GD', false, __('GD extension is needed for charts.'));
}
else if (in_array(ERR_NO_JSON, $errors)) {
PMA_warnMissingExtension('JSON', false, __('JSON encoder is needed for chart tooltips.'));
}
}
?>

Binary file not shown.

View File

@@ -0,0 +1,119 @@
<?php
/*
pCache - Faster renderding using data cache
Copyright (C) 2008 Jean-Damien POGOLOTTI
Version 1.1.2 last updated on 06/17/08
http://pchart.sourceforge.net
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 1,2,3 of the License, or
(at your option) any later version.
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 <http://www.gnu.org/licenses/>.
Class initialisation :
pCache($CacheFolder="Cache/")
Cache management :
IsInCache($Data)
GetFromCache($ID,$Data)
WriteToCache($ID,$Data,$Picture)
DeleteFromCache($ID,$Data)
ClearCache()
Inner functions :
GetHash($ID,$Data)
*/
/* pCache class definition */
class pCache
{
var $HashKey = "";
var $CacheFolder = "Cache/";
/* Create the pCache object */
function pCache($CacheFolder="Cache/")
{
$this->CacheFolder = $CacheFolder;
}
/* This function is clearing the cache folder */
function ClearCache()
{
if ($handle = opendir($this->CacheFolder))
{
while (false !== ($file = readdir($handle)))
{
if ( $file != "." && $file != ".." )
unlink($this->CacheFolder.$file);
}
closedir($handle);
}
}
/* This function is checking if we have an offline version of this chart */
function IsInCache($ID,$Data,$Hash="")
{
if ( $Hash == "" )
$Hash = $this->GetHash($ID,$Data);
if ( file_exists($this->CacheFolder.$Hash) )
return(TRUE);
else
return(FALSE);
}
/* This function is making a copy of drawn chart in the cache folder */
function WriteToCache($ID,$Data,$Picture)
{
$Hash = $this->GetHash($ID,$Data);
$FileName = $this->CacheFolder.$Hash;
imagepng($Picture->Picture,$FileName);
}
/* This function is removing any cached copy of this chart */
function DeleteFromCache($ID,$Data)
{
$Hash = $this->GetHash($ID,$Data);
$FileName = $this->CacheFolder.$Hash;
if ( file_exists($FileName ) )
unlink($FileName);
}
/* This function is retrieving the cached picture if applicable */
function GetFromCache($ID,$Data)
{
$Hash = $this->GetHash($ID,$Data);
if ( $this->IsInCache("","",$Hash ) )
{
$FileName = $this->CacheFolder.$Hash;
header('Content-type: image/png');
@readfile($FileName);
exit();
}
}
/* This function is building the graph unique hash key */
function GetHash($ID,$Data)
{
$mKey = "$ID";
foreach($Data as $key => $Values)
{
$tKey = "";
foreach($Values as $Serie => $Value)
$tKey = $tKey.$Serie.$Value;
$mKey = $mKey.md5($tKey);
}
return(md5($mKey));
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,260 @@
<?php
/*
pData - Simplifying data population for pChart
Copyright (C) 2008 Jean-Damien POGOLOTTI
Version 1.13 last updated on 08/17/08
http://pchart.sourceforge.net
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 1,2,3 of the License, or
(at your option) any later version.
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 <http://www.gnu.org/licenses/>.
Class initialisation :
pData()
Data populating methods :
ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1)
AddPoint($Value,$Serie="Serie1",$Description="")
Series manipulation methods :
AddSerie($SerieName="Serie1")
AddAllSeries()
RemoveSerie($SerieName="Serie1")
SetAbsciseLabelSerie($SerieName = "Name")
SetSerieName($Name,$SerieName="Serie1")
+ SetSerieSymbol($Name,$Symbol)
SetXAxisName($Name="X Axis")
SetYAxisName($Name="Y Axis")
SetXAxisFormat($Format="number")
SetYAxisFormat($Format="number")
SetXAxisUnit($Unit="")
SetYAxisUnit($Unit="")
removeSerieName($SerieName)
removeAllSeries()
Data retrieval methods :
GetData()
GetDataDescription()
*/
/* pData class definition */
class pData
{
var $Data;
var $DataDescription;
function pData()
{
$this->Data = array();
$this->DataDescription = "";
$this->DataDescription["Position"] = "Name";
$this->DataDescription["Format"]["X"] = "number";
$this->DataDescription["Format"]["Y"] = "number";
$this->DataDescription["Unit"]["X"] = NULL;
$this->DataDescription["Unit"]["Y"] = NULL;
}
function ImportFromCSV($FileName,$Delimiter=",",$DataColumns=-1,$HasHeader=FALSE,$DataName=-1)
{
$handle = @fopen($FileName,"r");
if ($handle)
{
$HeaderParsed = FALSE;
while (!feof($handle))
{
$buffer = fgets($handle, 4096);
$buffer = str_replace(chr(10),"",$buffer);
$buffer = str_replace(chr(13),"",$buffer);
$Values = split($Delimiter,$buffer);
if ( $buffer != "" )
{
if ( $HasHeader == TRUE && $HeaderParsed == FALSE )
{
if ( $DataColumns == -1 )
{
$ID = 1;
foreach($Values as $key => $Value)
{ $this->SetSerieName($Value,"Serie".$ID); $ID++; }
}
else
{
$SerieName = "";
foreach($DataColumns as $key => $Value)
$this->SetSerieName($Values[$Value],"Serie".$Value);
}
$HeaderParsed = TRUE;
}
else
{
if ( $DataColumns == -1 )
{
$ID = 1;
foreach($Values as $key => $Value)
{ $this->AddPoint(intval($Value),"Serie".$ID); $ID++; }
}
else
{
$SerieName = "";
if ( $DataName != -1 )
$SerieName = $Values[$DataName];
foreach($DataColumns as $key => $Value)
$this->AddPoint($Values[$Value],"Serie".$Value,$SerieName);
}
}
}
}
fclose($handle);
}
}
function AddPoint($Value,$Serie="Serie1",$Description="")
{
if (is_array($Value) && count($Value) == 1)
$Value = array_pop($Value);
$ID = 0;
for($i=0;$i<=count($this->Data);$i++)
{ if(isset($this->Data[$i][$Serie])) { $ID = $i+1; } }
if ( count($Value) == 1 )
{
$this->Data[$ID][$Serie] = $Value;
if ( $Description != "" )
$this->Data[$ID]["Name"] = $Description;
elseif (!isset($this->Data[$ID]["Name"]))
$this->Data[$ID]["Name"] = $ID;
}
else
{
foreach($Value as $key => $Val)
{
$this->Data[$ID][$Serie] = $Val;
if (!isset($this->Data[$ID]["Name"]))
$this->Data[$ID]["Name"] = $ID;
$ID++;
}
}
}
function AddSerie($SerieName="Serie1")
{
if ( !isset($this->DataDescription["Values"]) )
{
$this->DataDescription["Values"][] = $SerieName;
}
else
{
$Found = FALSE;
foreach($this->DataDescription["Values"] as $key => $Value )
if ( $Value == $SerieName ) { $Found = TRUE; }
if ( !$Found )
$this->DataDescription["Values"][] = $SerieName;
}
}
function AddAllSeries()
{
unset($this->DataDescription["Values"]);
if ( isset($this->Data[0]) )
{
foreach($this->Data[0] as $Key => $Value)
{
if ( $Key != "Name" )
$this->DataDescription["Values"][] = $Key;
}
}
}
function RemoveSerie($SerieName="Serie1")
{
if ( !isset($this->DataDescription["Values"]) )
return(0);
$Found = FALSE;
foreach($this->DataDescription["Values"] as $key => $Value )
{
if ( $Value == $SerieName )
unset($this->DataDescription["Values"][$key]);
}
}
function SetAbsciseLabelSerie($SerieName = "Name")
{
$this->DataDescription["Position"] = $SerieName;
}
function SetSerieName($Name,$SerieName="Serie1")
{
$this->DataDescription["Description"][$SerieName] = $Name;
}
function SetXAxisName($Name="X Axis")
{
$this->DataDescription["Axis"]["X"] = $Name;
}
function SetYAxisName($Name="Y Axis")
{
$this->DataDescription["Axis"]["Y"] = $Name;
}
function SetXAxisFormat($Format="number")
{
$this->DataDescription["Format"]["X"] = $Format;
}
function SetYAxisFormat($Format="number")
{
$this->DataDescription["Format"]["Y"] = $Format;
}
function SetXAxisUnit($Unit="")
{
$this->DataDescription["Unit"]["X"] = $Unit;
}
function SetYAxisUnit($Unit="")
{
$this->DataDescription["Unit"]["Y"] = $Unit;
}
function SetSerieSymbol($Name,$Symbol)
{
$this->DataDescription["Symbol"][$Name] = $Symbol;
}
function removeSerieName($SerieName)
{
if ( isset($this->DataDescription["Description"][$SerieName]) )
unset($this->DataDescription["Description"][$SerieName]);
}
function removeAllSeries()
{
foreach($this->DataDescription["Values"] as $Key => $Value)
unset($this->DataDescription["Values"][$Key]);
}
function GetData()
{
return($this->Data);
}
function GetDataDescription()
{
return($this->DataDescription);
}
}
?>

View File

@@ -0,0 +1,184 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the base class that all charts inherit from and some widely used
* constants.
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
define('RED', 0);
define('GREEN', 1);
define('BLUE', 2);
/**
* The base class that all charts inherit from.
* @abstract
* @package phpMyAdmin
*/
abstract class PMA_chart
{
/**
* @var array All the default settigs values are here.
*/
protected $settings = array(
// Default title for every chart.
'titleText' => 'Chart',
// The style of the chart title.
'titleColor' => '#FAFAFA',
// Colors for the different slices in the pie chart.
'colors' => array(
'#BCE02E',
'#E0642E',
'#E0D62E',
'#2E97E0',
'#B02EE0',
'#E02E75',
'#5CE02E',
'#E0B02E',
'#000000',
'#0022E0',
'#726CB1',
'#481A36',
'#BAC658',
'#127224',
'#825119',
'#238C74',
'#4C489B',
'#87C9BF',
),
// Chart background color.
'bgColor' => '#84AD83',
// The width of the chart.
'width' => 520,
// The height of the chart.
'height' => 325,
// Default X Axis label. If empty, label will be taken from the data.
'xLabel' => '',
// Default Y Axis label. If empty, label will be taken from the data.
'yLabel' => '',
);
/**
* @var array Options that the user has specified
*/
private $userSpecifiedSettings = null;
/**
* @var array Error codes will be stored here
*/
protected $errors = array();
/**
* Store user specified options
* @param array $options users specified options
*/
function __construct($options = null)
{
$this->userSpecifiedSettings = $options;
}
/**
* All the variable initialization has to be done here.
*/
protected function init()
{
$this->handleOptions();
}
/**
* A function which handles passed parameters. Useful if desired
* chart needs to be a little bit different from the default one.
*/
private function handleOptions()
{
if (is_null($this->userSpecifiedSettings)) {
return;
}
$this->settings = array_merge($this->settings, $this->userSpecifiedSettings);
}
protected function getTitleText()
{
return $this->settings['titleText'];
}
protected function getTitleColor($component)
{
return $this->hexStrToDecComp($this->settings['titleColor'], $component);
}
protected function getColors()
{
return $this->settings['colors'];
}
protected function getWidth()
{
return $this->settings['width'];
}
protected function getHeight()
{
return $this->settings['height'];
}
protected function getBgColor($component)
{
return $this->hexStrToDecComp($this->settings['bgColor'], $component);
}
protected function setXLabel($label)
{
$this->settings['xLabel'] = $label;
}
protected function getXLabel()
{
return $this->settings['xLabel'];
}
protected function setYLabel($label)
{
$this->settings['yLabel'] = $label;
}
protected function getYLabel()
{
return $this->settings['yLabel'];
}
public function getSettings()
{
return $this->settings;
}
public function getErrors()
{
return $this->errors;
}
/**
* Get one the dec color component from the hex color string
* @param string $colorString color string, i.e. #5F22A99
* @param int $component color component to get, i.e. 0 gets red.
*/
protected function hexStrToDecComp($colorString, $component)
{
return hexdec(substr($colorString, ($component * 2) + 1, 2));
}
}
?>

View File

@@ -0,0 +1,399 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the base class that all charts using pChart inherit from and some
* widely used constants
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
define('TOP', 0);
define('RIGHT', 1);
define('BOTTOM', 2);
define('LEFT', 3);
require_once 'pma_chart.php';
require_once 'pChart/pData.class';
require_once 'pChart/pChart.class';
/**
* Base class for every chart implemented using pChart.
* @abstract
* @package phpMyAdmin
*/
abstract class PMA_pChart_chart extends PMA_chart
{
/**
* @var String title text
*/
protected $titleText;
/**
* @var array data for the chart
*/
protected $data;
/**
* @var object pData object that holds the description of the data
*/
protected $dataSet;
/**
* @var object pChart object that holds the chart
*/
protected $chart;
/**
* @var array holds base64 encoded chart image parts
*/
protected $partsEncoded = array();
public function __construct($data, $options = null)
{
parent::__construct($options);
$this->data = $data;
$this->settings['fontPath'] = './libraries/chart/pChart/fonts/';
$this->settings['scale'] = SCALE_ADDALLSTART0;
$this->settings['labelHeight'] = 20;
$this->settings['fontSize'] = 8;
$this->settings['continuous'] = 'off';
// as in CSS (top, right, bottom, left)
$this->setAreaMargins(array(20, 20, 40, 60));
// when graph area gradient is used, this is the color of the graph
// area border
$this->settings['graphAreaColor'] = '#D5D9DD';
// the background color of the graph area
$this->settings['graphAreaGradientColor'] = '#A3CBA7';
// the color of the grid lines in the graph area
$this->settings['gridColor'] = '#E6E6E6';
// the color of the scale and the labels
$this->settings['scaleColor'] = '#D5D9DD';
$this->settings['titleBgColor'] = '#000000';
}
protected function init()
{
parent::init();
// create pChart object
$this->chart = new pChart($this->getWidth(), $this->getHeight());
// create pData object
$this->dataSet = new pData;
$this->chart->reportWarnings('GD');
$this->chart->ErrorFontName = $this->getFontPath().'tahoma.ttf';
// initialize colors
foreach ($this->getColors() as $key => $color) {
$this->chart->setColorPalette(
$key,
hexdec(substr($color, 1, 2)),
hexdec(substr($color, 3, 2)),
hexdec(substr($color, 5, 2))
);
}
$this->chart->setFontProperties($this->getFontPath().'tahoma.ttf', $this->getFontSize());
$this->chart->setImageMap(true, 'mapid');
}
/**
* data is put to the $dataSet object according to what type chart is
* @abstract
*/
abstract protected function prepareDataSet();
/**
* all components of the chart are drawn
*/
protected function prepareChart()
{
$this->drawBackground();
$this->drawChart();
}
/**
* draws the background
*/
protected function drawBackground()
{
$this->drawCommon();
$this->drawTitle();
$this->setGraphAreaDimensions();
$this->drawGraphArea();
}
/**
* draws the part of the background which is common to most of the charts
*/
protected function drawCommon()
{
$this->chart->drawGraphAreaGradient(
$this->getBgColor(RED),
$this->getBgColor(GREEN),
$this->getBgColor(BLUE),
50,TARGET_BACKGROUND);
$this->chart->addBorder(2);
}
/**
* draws the chart title
*/
protected function drawTitle()
{
// Draw the title
$this->chart->drawTextBox(
0,
0,
$this->getWidth(),
$this->getLabelHeight(),
$this->getTitleText(),
0,
$this->getTitleColor(RED),
$this->getTitleColor(GREEN),
$this->getTitleColor(BLUE),
ALIGN_CENTER,
True,
$this->getTitleBgColor(RED),
$this->getTitleBgColor(GREEN),
$this->getTitleBgColor(BLUE),
30
);
}
/**
* calculates and sets the dimensions that will be used for the actual graph
*/
protected function setGraphAreaDimensions()
{
$this->chart->setGraphArea(
$this->getAreaMargin(LEFT),
$this->getLabelHeight() + $this->getAreaMargin(TOP),
$this->getWidth() - $this->getAreaMargin(RIGHT),
$this->getHeight() - $this->getAreaMargin(BOTTOM)
);
}
/**
* draws graph area (the area where all bars, lines, points will be seen)
*/
protected function drawGraphArea()
{
$this->chart->drawGraphArea(
$this->getGraphAreaColor(RED),
$this->getGraphAreaColor(GREEN),
$this->getGraphAreaColor(BLUE),
FALSE
);
$this->chart->drawScale(
$this->dataSet->GetData(),
$this->dataSet->GetDataDescription(),
$this->getScale(),
$this->getScaleColor(RED),
$this->getScaleColor(GREEN),
$this->getScaleColor(BLUE),
TRUE,0,2,TRUE
);
$this->chart->drawGraphAreaGradient(
$this->getGraphAreaGradientColor(RED),
$this->getGraphAreaGradientColor(GREEN),
$this->getGraphAreaGradientColor(BLUE),
50
);
$this->chart->drawGrid(
4,
TRUE,
$this->getGridColor(RED),
$this->getGridColor(GREEN),
$this->getGridColor(BLUE),
20
);
}
/**
* draws the chart
* @abstract
*/
protected abstract function drawChart();
/**
* Renders the chart, base 64 encodes the output and puts it into
* array partsEncoded.
*
* Parameter can be used to slice the chart vertically into parts. This
* solves an issue where some browsers (IE8) accept base64 images only up
* to some length.
*
* @param integer $parts number of parts to render.
* Default value 1 means that all the
* chart will be in one piece.
*/
protected function render($parts = 1)
{
$fullWidth = 0;
for ($i = 0; $i < $parts; $i++) {
// slicing is vertical so part height is the full height
$partHeight = $this->chart->YSize;
// there will be some rounding erros, will compensate later
$partWidth = round($this->chart->XSize / $parts);
$fullWidth += $partWidth;
$partX = $partWidth * $i;
if ($i == $parts - 1) {
// if this is the last part, compensate for the rounding errors
$partWidth += $this->chart->XSize - $fullWidth;
}
// get a part from the full chart image
$part = imagecreatetruecolor($partWidth, $partHeight);
imagecopy($part, $this->chart->Picture, 0, 0, $partX, 0, $partWidth, $partHeight);
// render part and save it to variable
ob_start();
imagepng($part, NULL, 9, PNG_ALL_FILTERS);
$output = ob_get_contents();
ob_end_clean();
// base64 encode the current part
$partEncoded = base64_encode($output);
$this->partsEncoded[$i] = $partEncoded;
}
}
/**
* get the HTML and JS code for the configured chart
* @return string HTML and JS code for the chart
*/
public function toString()
{
if (!function_exists('gd_info')) {
array_push($this->errors, ERR_NO_GD);
return '';
}
$this->init();
$this->prepareDataSet();
$this->prepareChart();
//$this->chart->debugImageMap();
//$this->chart->printErrors('GD');
// check if a user wanted a chart in one part
if ($this->isContinuous()) {
$this->render(1);
}
else {
$this->render(20);
}
$returnData = '<div id="chart">';
foreach ($this->partsEncoded as $part) {
$returnData .= '<img src="data:image/png;base64,'.$part.'" />';
}
$returnData .= '</div>';
// add tooltips only if json is available
if (function_exists('json_encode')) {
$returnData .= '
<script type="text/javascript">
//<![CDATA[
imageMap.loadImageMap(\''.json_encode($this->getImageMap()).'\');
//]]>
</script>
';
}
else {
array_push($this->errors, ERR_NO_JSON);
}
return $returnData;
}
protected function getLabelHeight()
{
return $this->settings['labelHeight'];
}
protected function setAreaMargins($areaMargins)
{
$this->settings['areaMargins'] = $areaMargins;
}
protected function getAreaMargin($side)
{
return $this->settings['areaMargins'][$side];
}
protected function getFontPath()
{
return $this->settings['fontPath'];
}
protected function getScale()
{
return $this->settings['scale'];
}
protected function getFontSize()
{
return $this->settings['fontSize'];
}
protected function isContinuous()
{
return $this->settings['continuous'] == 'on';
}
protected function getImageMap()
{
return $this->chart->getImageMap();
}
protected function getGraphAreaColor($component)
{
return $this->hexStrToDecComp($this->settings['graphAreaColor'], $component);
}
protected function getGraphAreaGradientColor($component)
{
return $this->hexStrToDecComp($this->settings['graphAreaGradientColor'], $component);
}
protected function getGridColor($component)
{
return $this->hexStrToDecComp($this->settings['gridColor'], $component);
}
protected function getScaleColor($component)
{
return $this->hexStrToDecComp($this->settings['scaleColor'], $component);
}
protected function getTitleBgColor($component)
{
return $this->hexStrToDecComp($this->settings['titleBgColor'], $component);
}
}
?>

View File

@@ -0,0 +1,118 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_chart.php';
/**
* Base class for every chart that uses multiple series.
* All of these charts will require legend box.
* @abstract
* @package phpMyAdmin
*/
abstract class PMA_pChart_multi extends PMA_pChart_chart
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
// as in CSS (top, right, bottom, left)
$this->setLegendMargins(array(20, 10, 0, 0));
}
/**
* data set preparation for multi serie graphs
*/
protected function prepareDataSet()
{
$values = array_values($this->data);
$keys = array_keys($this->data);
// Dataset definition
$this->dataSet->AddPoint($values[0], "Keys");
$i = 0;
foreach ($values[1] as $seriesName => $seriesData) {
$this->dataSet->AddPoint($seriesData, "Values".$i);
$this->dataSet->SetSerieName($seriesName, "Values".$i);
$i++;
}
$this->dataSet->AddAllSeries();
$this->dataSet->RemoveSerie("Keys");
$this->dataSet->SetAbsciseLabelSerie("Keys");
$xLabel = $this->getXLabel();
if (empty($xLabel)) {
$this->setXLabel($keys[0]);
}
$yLabel = $this->getYLabel();
if (empty($yLabel)) {
$this->setYLabel($keys[1]);
}
$this->dataSet->SetXAxisName($this->getXLabel());
$this->dataSet->SetYAxisName($this->getYLabel());
}
/**
* set graph area dimensions with respect to legend box size
*/
protected function setGraphAreaDimensions()
{
$this->chart->setGraphArea(
$this->getAreaMargin(LEFT),
$this->getLabelHeight() + $this->getAreaMargin(TOP),
$this->getWidth() - $this->getAreaMargin(RIGHT) - $this->getLegendBoxWidth() - $this->getLegendMargin(LEFT) - $this->getLegendMargin(RIGHT),
$this->getHeight() - $this->getAreaMargin(BOTTOM)
);
}
/**
* multi serie charts need a legend. draw it
*/
protected function drawChart()
{
$this->drawLegend();
}
/**
* draws a legend
*/
protected function drawLegend()
{
// Draw the legend
$this->chart->drawLegend(
$this->getWidth() - $this->getLegendMargin(RIGHT) - $this->getLegendBoxWidth(),
$this->getLabelHeight() + $this->getLegendMargin(TOP),
$this->dataSet->GetDataDescription(),
250,250,250,50,50,50
);
}
protected function setLegendMargins($legendMargins)
{
if (!isset($this->settings['legendMargins'])) {
$this->settings['legendMargins'] = $legendMargins;
}
}
protected function getLegendMargin($side)
{
return $this->settings['legendMargins'][$side];
}
protected function getLegendBoxWidth()
{
$legendSize = $this->chart->getLegendBoxSize($this->dataSet->GetDataDescription());
return $legendSize[0];
}
}
?>

View File

@@ -0,0 +1,38 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_multi.php';
/**
* implements multi bar chart
* @package phpMyAdmin
*/
class PMA_pChart_multi_bar extends PMA_pChart_multi
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
$this->settings['scale'] = SCALE_NORMAL;
}
/**
* draws multi bar graph
*/
protected function drawChart()
{
parent::drawChart();
// Draw the bar chart
$this->chart->drawBarGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 70);
}
}
?>

View File

@@ -0,0 +1,39 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_multi.php';
/**
* implements multi line chart
* @package phpMyAdmin
*/
class PMA_pChart_multi_line extends PMA_pChart_multi
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
$this->settings['scale'] = SCALE_NORMAL;
}
/**
* draws multi line chart
*/
protected function drawChart()
{
parent::drawChart();
// Draw the bar chart
$this->chart->drawLineGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription());
$this->chart->drawPlotGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 3, 1, -1, -1, -1, TRUE);
}
}
?>

View File

@@ -0,0 +1,100 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_multi.php';
/**
* implements multi radar chart
* @package phpMyAdmin
*/
class PMA_pChart_multi_radar extends PMA_pChart_multi
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
$this->normalizeValues();
}
/**
* Get the largest value from the data and normalize all the other values.
*/
private function normalizeValues()
{
$maxValue = 0;
$keys = array_keys($this->data);
$valueKey = $keys[1];
// get the max value
foreach ($this->data[$valueKey] as $values) {
if (max($values) > $maxValue) {
$maxValue = max($values);
}
}
// normalize all the values according to the max value
foreach ($this->data[$valueKey] as &$values) {
foreach ($values as &$value) {
$value = $value / $maxValue * 10;
}
}
}
/**
* graph area for the radar chart does not include grid lines
*/
protected function drawGraphArea()
{
$this->chart->drawGraphArea(
$this->getGraphAreaColor(RED),
$this->getGraphAreaColor(GREEN),
$this->getGraphAreaColor(BLUE),
FALSE
);
$this->chart->drawGraphAreaGradient(
$this->getGraphAreaGradientColor(RED),
$this->getGraphAreaGradientColor(GREEN),
$this->getGraphAreaGradientColor(BLUE),
50
);
}
/**
* draw multi radar chart
*/
protected function drawChart()
{
parent::drawChart();
// when drawing radar graph we can specify the border from the top of
// graph area. We want border to be dynamic, so that either the top
// or the side of the radar is some distance away from the top or the
// side of the graph area.
$areaWidth = $this->chart->GArea_X2 - $this->chart->GArea_X1;
$areaHeight = $this->chart->GArea_Y2 - $this->chart->GArea_Y1;
if ($areaHeight > $areaWidth) {
$borderOffset = ($areaHeight - $areaWidth) / 2;
}
else {
$borderOffset = 0;
}
// the least ammount that radar is away from the graph area side.
$borderOffset += 40;
// Draw the radar chart
$this->chart->drawRadarAxis($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), TRUE, $borderOffset,
120, 120, 120, 230, 230, 230, -1, 2);
$this->chart->drawFilledRadar($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 50, $borderOffset);
}
}
?>

View File

@@ -0,0 +1,101 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_multi.php';
/**
* implements pie chart
* @package phpMyAdmin
*/
class PMA_pChart_Pie extends PMA_pChart_multi
{
public function __construct($data, $options = null)
{
// limit data size, no more than 18 pie slices
$data = array_slice($data, 0, 18, true);
parent::__construct($data, $options);
$this->setAreaMargins(array(20, 10, 20, 20));
}
/**
* prepare data set for the pie chart
*/
protected function prepareDataSet()
{
// Dataset definition
$this->dataSet->AddPoint(array_values($this->data), "Values");
$this->dataSet->AddPoint(array_keys($this->data), "Keys");
$this->dataSet->AddAllSeries();
$this->dataSet->SetAbsciseLabelSerie("Keys");
}
/**
* graph area for the pie chart does not include grid lines
*/
protected function drawGraphArea()
{
$this->chart->drawGraphArea(
$this->getGraphAreaColor(RED),
$this->getGraphAreaColor(GREEN),
$this->getGraphAreaColor(BLUE),
FALSE
);
$this->chart->drawGraphAreaGradient(
$this->getGraphAreaGradientColor(RED),
$this->getGraphAreaGradientColor(GREEN),
$this->getGraphAreaGradientColor(BLUE),
50
);
}
/**
* draw the pie chart
*/
protected function drawChart()
{
parent::drawChart();
// draw pie chart in the middle of graph area
$middleX = ($this->chart->GArea_X1 + $this->chart->GArea_X2) / 2;
$middleY = ($this->chart->GArea_Y1 + $this->chart->GArea_Y2) / 2;
$this->chart->drawPieGraph(
$this->dataSet->GetData(),
$this->dataSet->GetDataDescription(),
$middleX,
// pie graph is skewed. Upper part is shorter than the
// lower part. This is why we set an offset to the
// Y middle coordiantes.
$middleY - 15,
120, PIE_PERCENTAGE, FALSE, 60, 30, 10, 1);
}
/**
* draw legend for the pie chart
*/
protected function drawLegend()
{
$this->chart->drawPieLegend(
$this->getWidth() - $this->getLegendMargin(RIGHT) - $this->getLegendBoxWidth(),
$this->getLabelHeight() + $this->getLegendMargin(TOP),
$this->dataSet->GetData(),
$this->dataSet->GetDataDescription(),
250, 250, 250);
}
protected function getLegendBoxWidth()
{
$legendSize = $this->chart->getPieLegendBoxSize($this->dataSet->GetData());
return $legendSize[0];
}
}
?>

View File

@@ -0,0 +1,57 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_chart.php';
/**
* Base class for every chart that uses only one series.
* @abstract
* @package phpMyAdmin
*/
abstract class PMA_pChart_single extends PMA_pChart_chart
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
}
/**
* data set preparation for single serie charts
*/
protected function prepareDataSet()
{
$values = array_values($this->data);
$keys = array_keys($this->data);
// Dataset definition
$this->dataSet->AddPoint($values[0], "Values");
$this->dataSet->AddPoint($values[1], "Keys");
//$this->dataSet->AddAllSeries();
$this->dataSet->AddSerie("Values");
$this->dataSet->SetAbsciseLabelSerie("Keys");
$yLabel = $this->getYLabel();
if (empty($yLabel)) {
$this->setYLabel($keys[0]);
}
$xLabel = $this->getXLabel();
if (empty($xLabel)) {
$this->setXLabel($keys[1]);
}
$this->dataSet->SetXAxisName($this->getXLabel());
$this->dataSet->SetYAxisName($this->getYLabel());
$this->dataSet->SetSerieName($this->getYLabel(), "Values");
}
}
?>

View File

@@ -0,0 +1,35 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_single.php';
/**
* implements single bar chart
* @package phpMyAdmin
*/
class PMA_pChart_single_bar extends PMA_pChart_single
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
}
/**
* draws single bar chart
*/
protected function drawChart()
{
// Draw the bar chart
// use stacked bar graph function, because it gives bars with alpha
$this->chart->drawStackedBarGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 70);
}
}
?>

View File

@@ -0,0 +1,35 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_single.php';
/**
* implements single line chart
* @package phpMyAdmin
*/
class PMA_pChart_single_line extends PMA_pChart_single
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
}
/**
* draws single line chart
*/
protected function drawChart()
{
// Draw the line chart
$this->chart->drawLineGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription());
$this->chart->drawPlotGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 3, 1, -1, -1, -1, TRUE);
}
}
?>

View File

@@ -0,0 +1,88 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_single.php';
/**
* implements single radar chart
* @package phpMyAdmin
*/
class PMA_pChart_single_radar extends PMA_pChart_single
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
$this->normalizeValues();
}
/**
* Get the largest value from the data and normalize all the other values.
*/
private function normalizeValues()
{
$maxValue = 0;
$keys = array_keys($this->data);
$valueKey = $keys[0];
$maxValue = max($this->data[$valueKey]);
foreach ($this->data[$valueKey] as &$value) {
$value = $value / $maxValue * 10;
}
}
/**
* graph area for the radar chart does not include grid lines
*/
protected function drawGraphArea()
{
$this->chart->drawGraphArea(
$this->getGraphAreaColor(RED),
$this->getGraphAreaColor(GREEN),
$this->getGraphAreaColor(BLUE),
FALSE
);
$this->chart->drawGraphAreaGradient(
$this->getGraphAreaGradientColor(RED),
$this->getGraphAreaGradientColor(GREEN),
$this->getGraphAreaGradientColor(BLUE),
50
);
}
/**
* draws the radar chart
*/
protected function drawChart()
{
// when drawing radar graph we can specify the border from the top of
// graph area. We want border to be dynamic, so that either the top
// or the side of the radar is some distance away from the top or the
// side of the graph area.
$areaWidth = $this->chart->GArea_X2 - $this->chart->GArea_X1;
$areaHeight = $this->chart->GArea_Y2 - $this->chart->GArea_Y1;
if ($areaHeight > $areaWidth) {
$borderOffset = ($areaHeight - $areaWidth) / 2;
}
else {
$borderOffset = 0;
}
// the least ammount that radar is away from the graph area side.
$borderOffset += 40;
$this->chart->drawRadarAxis($this->dataSet->GetData(), $this->dataSet->GetDataDescription(),
TRUE, $borderOffset, 120, 120, 120, 230, 230, 230, -1, 2);
$this->chart->drawFilledRadar($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 50, $borderOffset);
}
}
?>

View File

@@ -0,0 +1,36 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @author Martynas Mickevicius <mmartynas@gmail.com>
* @package phpMyAdmin
*/
/**
*
*/
require_once 'pma_pchart_multi.php';
/**
* implements stacked bar chart
* @package phpMyAdmin
*/
class PMA_pChart_stacked_bar extends PMA_pChart_multi
{
public function __construct($data, $options = null)
{
parent::__construct($data, $options);
}
/**
* draws stacked bar chart
*/
protected function drawChart()
{
parent::drawChart();
// Draw the bar chart
$this->chart->drawStackedBarGraph($this->dataSet->GetData(), $this->dataSet->GetDataDescription(), 70);
}
}
?>

View File

@@ -960,6 +960,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
} // end if !defined('PMA_MINIMUM_COMMON') } // end if !defined('PMA_MINIMUM_COMMON')
// load user preferences
$GLOBALS['PMA_Config']->loadUserPreferences();
// remove sensitive values from session // remove sensitive values from session
$GLOBALS['PMA_Config']->set('blowfish_secret', ''); $GLOBALS['PMA_Config']->set('blowfish_secret', '');
$GLOBALS['PMA_Config']->set('Servers', ''); $GLOBALS['PMA_Config']->set('Servers', '');

View File

@@ -1306,12 +1306,14 @@ function PMA_profilingCheckbox($sql_query)
* Displays the results of SHOW PROFILE * Displays the results of SHOW PROFILE
* *
* @param array the results * @param array the results
* @param boolean show chart
* @access public * @access public
* *
*/ */
function PMA_profilingResults($profiling_results) function PMA_profilingResults($profiling_results, $show_chart = false)
{ {
echo '<fieldset><legend>' . __('Profiling') . '</legend>' . "\n"; echo '<fieldset><legend>' . __('Profiling') . '</legend>' . "\n";
echo '<div style="float: left;">';
echo '<table>' . "\n"; echo '<table>' . "\n";
echo ' <tr>' . "\n"; echo ' <tr>' . "\n";
echo ' <th>' . __('Status') . '</th>' . "\n"; echo ' <th>' . __('Status') . '</th>' . "\n";
@@ -1323,7 +1325,17 @@ function PMA_profilingResults($profiling_results)
echo '<td>' . $one_result['Status'] . '</td>' . "\n"; echo '<td>' . $one_result['Status'] . '</td>' . "\n";
echo '<td>' . $one_result['Duration'] . '</td>' . "\n"; echo '<td>' . $one_result['Duration'] . '</td>' . "\n";
} }
echo '</table>' . "\n"; echo '</table>' . "\n";
echo '</div>';
if ($show_chart) {
require_once './libraries/chart.lib.php';
echo '<div style="float: left;">';
PMA_chart_profiling($profiling_results);
echo '</div>';
}
echo '</fieldset>' . "\n"; echo '</fieldset>' . "\n";
} }
@@ -1602,7 +1614,7 @@ function PMA_generate_html_tab($tab, $url_params = array())
$defaults = array( $defaults = array(
'text' => '', 'text' => '',
'class' => '', 'class' => '',
'active' => false, 'active' => null,
'link' => '', 'link' => '',
'sep' => '?', 'sep' => '?',
'attr' => '', 'attr' => '',
@@ -1622,7 +1634,7 @@ function PMA_generate_html_tab($tab, $url_params = array())
} elseif (! empty($tab['active']) } elseif (! empty($tab['active'])
|| PMA_isValid($GLOBALS['active_page'], 'identical', $tab['link'])) { || PMA_isValid($GLOBALS['active_page'], 'identical', $tab['link'])) {
$tab['class'] = 'active'; $tab['class'] = 'active';
} elseif (empty($GLOBALS['active_page']) } elseif (is_null($tab['active']) && empty($GLOBALS['active_page'])
&& basename($GLOBALS['PMA_PHP_SELF']) == $tab['link'] && basename($GLOBALS['PMA_PHP_SELF']) == $tab['link']
&& empty($tab['warning'])) { && empty($tab['warning'])) {
$tab['class'] = 'active'; $tab['class'] = 'active';

View File

@@ -340,6 +340,15 @@ $cfg['Servers'][$i]['designer_coords'] = '';
*/ */
$cfg['Servers'][$i]['tracking'] = ''; $cfg['Servers'][$i]['tracking'] = '';
/**
* table to store user preferences
* - leave blank to disable server storage
* SUGGESTED: 'pma_userconfig'
*
* @global string $cfg['Servers'][$i]['userconfig']
*/
$cfg['Servers'][$i]['userconfig'] = '';
/** /**
* set to false if you know that your pma_* tables are up to date. * set to false if you know that your pma_* tables are up to date.
* This prevents compatibility checks and thereby increases performance. * This prevents compatibility checks and thereby increases performance.
@@ -1063,6 +1072,13 @@ $cfg['Export'] = array();
*/ */
$cfg['Export']['format'] = 'sql'; $cfg['Export']['format'] = 'sql';
/**
* quick/custom/custom-no-form
*
* @global string $cfg['Export']['format']
*/
$cfg['Export']['method'] = 'quick';
/** /**
* none/zip/gzip/bzip2 * none/zip/gzip/bzip2
* *
@@ -1147,6 +1163,13 @@ $cfg['Export']['file_template_server'] = '@SERVER@';
*/ */
$cfg['Export']['codegen_structure_or_data'] = 'data'; $cfg['Export']['codegen_structure_or_data'] = 'data';
/**
*
*
* @global $cfg['Export']['codegen_format']
*/
$cfg['Export']['codegen_format'] = 0;
/** /**
* *
* *
@@ -1336,6 +1359,13 @@ $cfg['Export']['csv_escaped'] = '\\';
*/ */
$cfg['Export']['csv_terminated'] = 'AUTO'; $cfg['Export']['csv_terminated'] = 'AUTO';
/**
*
*
* @global string $cfg['Export']['csv_removeCRLF']
*/
$cfg['Export']['csv_removeCRLF'] = false;
/** /**
* *
* *
@@ -1357,6 +1387,13 @@ $cfg['Export']['excel_null'] = 'NULL';
*/ */
$cfg['Export']['excel_edition'] = 'win'; $cfg['Export']['excel_edition'] = 'win';
/**
*
*
* @global string $cfg['Export']['excel_removeCRLF']
*/
$cfg['Export']['excel_removeCRLF'] = false;
/** /**
* *
* *
@@ -1616,7 +1653,7 @@ $cfg['Export']['sql_hex_for_blob'] = true;
* *
* @global string $cfg['Export']['sql_type'] * @global string $cfg['Export']['sql_type']
*/ */
$cfg['Export']['sql_type'] = 'insert'; $cfg['Export']['sql_type'] = 'INSERT';
/** /**
* *
@@ -1673,6 +1710,7 @@ $cfg['Export']['pdf_report_title'] = '';
*@global string $cfg['Export']['xml_structure_or_data'] *@global string $cfg['Export']['xml_structure_or_data']
*/ */
$cfg['Export']['xml_structure_or_data'] = 'data'; $cfg['Export']['xml_structure_or_data'] = 'data';
/** /**
* Export schema for each structure * Export schema for each structure
* *
@@ -1728,6 +1766,7 @@ $cfg['Export']['xml_export_contents'] = true;
* @global string $cfg['Export']['yaml_structure_or_data'] * @global string $cfg['Export']['yaml_structure_or_data']
*/ */
$cfg['Export']['yaml_structure_or_data'] = 'data'; $cfg['Export']['yaml_structure_or_data'] = 'data';
/******************************************************************************* /*******************************************************************************
* Import defaults * Import defaults
*/ */
@@ -1759,7 +1798,7 @@ $cfg['Import']['allow_interrupt'] = true;
* *
* @global integer $cfg['Import']['skip_queries'] * @global integer $cfg['Import']['skip_queries']
*/ */
$cfg['Import']['skip_queries'] = '0'; $cfg['Import']['skip_queries'] = 0;
/** /**
* *
@@ -1782,6 +1821,13 @@ $cfg['Import']['sql_no_auto_value_on_zero'] = true;
*/ */
$cfg['Import']['csv_replace'] = false; $cfg['Import']['csv_replace'] = false;
/**
*
*
* @global boolean $cfg['Import']['csv_ignore']
*/
$cfg['Import']['csv_ignore'] = false;
/** /**
* *
* *
@@ -1831,6 +1877,13 @@ $cfg['Import']['csv_col_names'] = false;
*/ */
$cfg['Import']['ldi_replace'] = false; $cfg['Import']['ldi_replace'] = false;
/**
*
*
* @global boolean $cfg['Import']['ldi_ignore']
*/
$cfg['Import']['ldi_ignore'] = false;
/** /**
* *
* *
@@ -1915,6 +1968,13 @@ $cfg['Import']['xls_col_names'] = false;
*/ */
$cfg['Import']['xls_empty_rows'] = true; $cfg['Import']['xls_empty_rows'] = true;
/**
*
*
* @global string $cfg['Import']['xlsx_col_names']
*/
$cfg['Import']['xlsx_col_names'] = false;
/** /**
* Link to the official MySQL documentation. * Link to the official MySQL documentation.
* Be sure to include no trailing slash on the path. * Be sure to include no trailing slash on the path.
@@ -2171,7 +2231,7 @@ $cfg['DefaultDisplay'] = 'horizontal';
/** /**
* default display direction for altering/creating columns (tbl_properties) * default display direction for altering/creating columns (tbl_properties)
* (horizontal|vertical|<number>) * (horizontal|vertical|<number>)
* number indicates maximal number for which vertical model is used * number indicates maximum number for which vertical model is used
* *
* @global integer $cfg['DefaultPropDisplay'] * @global integer $cfg['DefaultPropDisplay']
*/ */
@@ -2272,14 +2332,6 @@ $cfg['MaxExactCount'] = 20000;
*/ */
$cfg['MaxExactCountViews'] = 0; $cfg['MaxExactCountViews'] = 0;
/**
* Utilize DHTML/JS capabilities to allow WYSIWYG editing of
* the PDF page editor. Requires an IE6/Gecko based browser.
*
* @global boolean $cfg['WYSIWYG-PDF']
*/
$cfg['WYSIWYG-PDF'] = true;
/** /**
* Sort table and database in natural order * Sort table and database in natural order
* *
@@ -2295,7 +2347,18 @@ $cfg['NaturalOrder'] = true;
*/ */
$cfg['InitialSlidersState'] = 'closed'; $cfg['InitialSlidersState'] = 'closed';
/**
* User preferences: disallow these settings
* For possible setting names look in libraries/config/user_preferences.forms.php
*
* @global array $cfg['UserprefsDisallow']
*/
$cfg['UserprefsDisallow'] = array();
/**
* User preferences: enable the Developer tab
*/
$cfg['UserprefsDeveloperTab'] = false;
/******************************************************************************* /*******************************************************************************
* Window title settings * Window title settings

189
libraries/config.values.php Normal file
View File

@@ -0,0 +1,189 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database with allowed values for configuration stored in the $cfg array,
* used by setup script and user preferences to generate forms.
*
* @package phpMyAdmin
*/
if (!defined('PHPMYADMIN')) {
exit;
}
/**
* Value meaning:
* o array - select field, array contains allowed values
* o string - type override
*
* Use normal array, paths won't be expanded
*/
$cfg_db = array();
$cfg_db['Servers'] = array(1 => array(
'port' => 'integer',
'connect_type' => array('tcp', 'socket'),
'extension' => array('mysql', 'mysqli'),
'auth_type' => array('config', 'http', 'signon', 'cookie'),
'AllowDeny' => array(
'order' => array('', 'deny,allow', 'allow,deny', 'explicit')),
'only_db' => 'array'));
$cfg_db['RecodingEngine'] = array('auto', 'iconv', 'recode', 'none');
$cfg_db['OBGzip'] = array('auto', true, false);
$cfg_db['MemoryLimit'] = 'short_string';
$cfg_db['ShowTooltipAliasTB'] = array('nested', true, false);
$cfg_db['DisplayDatabasesList'] = array('auto', true, false);
$cfg_db['LeftLogoLinkWindow'] = array('main', 'new');
$cfg_db['LeftDefaultTabTable'] = array(
'tbl_structure.php', // fields list
'tbl_sql.php', // SQL form
'tbl_select.php', // search page
'tbl_change.php', // insert row page
'sql.php'); // browse page
$cfg_db['LeftFrameDBSeparator'] = 'short_string';
$cfg_db['LeftFrameTableSeparator'] = 'short_string';
$cfg_db['NavigationBarIconic'] = array(true, false, 'both');
$cfg_db['Order'] = array('ASC', 'DESC', 'SMART');
$cfg_db['ProtectBinary'] = array(false, 'blob', 'all');
$cfg_db['DefaultDisplay'] = array('horizontal', 'vertical', 'horizontalflipped');
$cfg_db['CharEditing'] = array('input', 'textarea');
$cfg_db['PropertiesIconic'] = array(true, false, 'both');
$cfg_db['DefaultTabServer'] = array(
'main.php', // the welcome page (recommended for multiuser setups)
'server_databases.php', // list of databases
'server_status.php', // runtime information
'server_variables.php', // MySQL server variables
'server_privileges.php', // user management
'server_processlist.php'); // process list
$cfg_db['DefaultTabDatabase'] = array(
'db_structure.php', // tables list
'db_sql.php', // SQL form
'db_search.php', // search query
'db_operations.php'); // operations on database
$cfg_db['DefaultTabTable'] = array(
'tbl_structure.php', // fields list
'tbl_sql.php', // SQL form
'tbl_select.php', // search page
'tbl_change.php', // insert row page
'sql.php'); // browse page
$cfg_db['QueryWindowDefTab'] = array(
'sql', // SQL
'files', // Import files
'history', // SQL history
'full'); // All (SQL and SQL history)
$cfg_db['InitialSlidersState'] = array('open', 'closed');
$cfg_db['Import']['format'] = array(
'csv', // CSV
'docsql', // DocSQL
'ldi', // CSV using LOAD DATA
'sql'); // SQL
$cfg_db['Import']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
$cfg_db['Import']['sql_compatibility'] = $cfg_db['Export']['sql_compatibility'] = array(
'NONE', 'ANSI', 'DB2', 'MAXDB', 'MYSQL323', 'MYSQL40', 'MSSQL', 'ORACLE',
// removed; in MySQL 5.0.33, this produces exports that
// can't be read by POSTGRESQL (see our bug #1596328)
//'POSTGRESQL',
'TRADITIONAL');
$cfg_db['Import']['csv_terminated'] = 'short_string';
$cfg_db['Import']['csv_enclosed'] = 'short_string';
$cfg_db['Import']['csv_escaped'] = 'short_string';
$cfg_db['Import']['ldi_terminated'] = 'short_string';
$cfg_db['Import']['ldi_enclosed'] = 'short_string';
$cfg_db['Import']['ldi_escaped'] = 'short_string';
$cfg_db['Import']['ldi_local_option'] = array('auto', true, false);
$cfg_db['Export']['_sod_select'] = array(
'structure' => __('structure'),
'data' => __('data'),
'structure_and_data' => __('structure and data'));
$cfg_db['Export']['method'] = array(
'quick' => __('Quick - display only the minimal options to configure'),
'custom' => __('Custom - display all possible options to configure'),
'custom-no-form' => __('Custom - like above, but without the quick/custom choice'));
$cfg_db['Export']['format'] = array('codegen', 'csv', 'excel', 'htmlexcel',
'htmlword', 'latex', 'ods', 'odt', 'pdf', 'sql', 'texytext', 'xls', 'xml',
'yaml');
$cfg_db['Export']['compression'] = array('none', 'zip', 'gzip', 'bzip2');
$cfg_db['Export']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
$cfg_db['Export']['codegen_format'] = array('#', 'NHibernate C# DO', 'NHibernate XML');
$cfg_db['Export']['csv_separator'] = 'short_string';
$cfg_db['Export']['csv_terminated'] = 'short_string';
$cfg_db['Export']['csv_enclosed'] = 'short_string';
$cfg_db['Export']['csv_escaped'] = 'short_string';
$cfg_db['Export']['csv_null'] = 'short_string';
$cfg_db['Export']['excel_null'] = 'short_string';
$cfg_db['Export']['excel_edition'] = array('win' => 'Windows',
'mac_excel2003' => 'Excel 2003 / Macintosh', 'mac_excel2008' => 'Excel 2008 / Macintosh');
$cfg_db['Export']['sql_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['sql_type'] = array('INSERT', 'UPDATE', 'REPLACE');
$cfg_db['Export']['sql_insert_syntax'] = array(
'complete' => __('complete inserts'),
'extended' => __('extended inserts'),
'both' => __('both of the above'),
'none' => __('neither of the above'));
$cfg_db['Export']['xls_null'] = 'short_string';
$cfg_db['Export']['xlsx_null'] = 'short_string';
$cfg_db['Export']['htmlword_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['htmlword_null'] = 'short_string';
$cfg_db['Export']['ods_null'] = 'short_string';
$cfg_db['Export']['odt_null'] = 'short_string';
$cfg_db['Export']['odt_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['texytext_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['texytext_null'] = 'short_string';
/**
* Default values overrides
* Use only full paths
*/
$cfg_db['_overrides'] = array();
$cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
? 'mysqli' : 'mysql';
/**
* Basic validator assignments (functions from libraries/config/validate.lib.php and 'validators'
* object in js/config.js)
* Use only full paths and form ids
*/
$cfg_db['_validators'] = array(
'CharTextareaCols' => 'validate_positive_number',
'CharTextareaRows' => 'validate_positive_number',
'DefaultPropDisplay' => array(array('validate_by_regex', '/^(?:horizontal|vertical|\d+)$/')),
'ExecTimeLimit' => 'validate_non_negative_number',
'Export/sql_max_query_size' => 'validate_positive_number',
'ForeignKeyMaxLimit' => 'validate_positive_number',
'Import/csv_enclosed' => array(array('validate_by_regex', '/^.?$/')),
'Import/csv_escaped' => array(array('validate_by_regex', '/^.$/')),
'Import/csv_terminated' => array(array('validate_by_regex', '/^.$/')),
'Import/ldi_enclosed' => array(array('validate_by_regex', '/^.?$/')),
'Import/ldi_escaped' => array(array('validate_by_regex', '/^.$/')),
'Import/ldi_terminated' => array(array('validate_by_regex', '/^.$/')),
'Import/skip_queries' => 'validate_non_negative_number',
'InsertRows' => 'validate_positive_number',
'LeftFrameTableLevel' => 'validate_positive_number',
'LimitChars' => 'validate_positive_number',
'LoginCookieValidity' => 'validate_positive_number',
'LoginCookieStore' => 'validate_non_negative_number',
'MaxDbList' => 'validate_positive_number',
'MaxCharactersInDisplayedSQL' => 'validate_positive_number',
'MaxRows' => 'validate_positive_number',
'MaxTableList' => 'validate_positive_number',
'MemoryLimit' => array(array('validate_by_regex', '/^\d+(?:[kmg])?$/i')),
'QueryHistoryMax' => 'validate_positive_number',
'QueryWindowWidth' => 'validate_positive_number',
'QueryWindowHeight' => 'validate_positive_number',
'RepeatCells' => 'validate_non_negative_number',
'Server' => 'validate_server',
'Server_pmadb' => 'validate_pmadb',
'Servers/1/port' => 'validate_port_number',
'Servers/1/hide_db' => 'validate_regex',
'TextareaCols' => 'validate_positive_number',
'TextareaRows' => 'validate_positive_number',
'TrustedProxies' => 'validate_trusted_proxies');
/**
* Additional validators used for user preferences
*/
$cfg_db['_userValidators'] = array(
'MaxDbList' => array(array('validate_upper_bound', 'value:MaxDbList')),
'MaxTableList' => array(array('validate_upper_bound', 'value:MaxTableList')),
'QueryHistoryMax' => array(array('validate_upper_bound', 'value:QueryHistoryMax')),);
?>

View File

@@ -0,0 +1,486 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Config file management
*
* @package phpMyAdmin
*/
/**
* Config file management class.
* Stores its data in $_SESSION
*
* @package phpMyAdmin
*/
class ConfigFile
{
/**
* Stores default PMA config from config.default.php
* @var array
*/
private $cfg;
/**
* Stores allowed values for non-standard fields
* @var array
*/
private $cfgDb;
/**
* Keys which will be always written to config file
* @var array
*/
private $persistKeys = array();
/**
* Changes keys while updating config in {@link updateWithGlobalConfig()} or reading
* by {@link getConfig()} or {@link getConfigArray()}
* @var array
*/
private $cfgUpdateReadMapping = array();
/**
* Key filter for {@link set()}
* @var array|null
*/
private $setFilter;
/**
* Instance id (key in $_SESSION array, separate for each server - ConfigFile{server id})
* @var string
*/
private $id;
/**
* Result for {@link _flattenArray()}
* @var array
*/
private $_flattenArrayResult;
/**
* ConfigFile instance
* @var ConfigFile
*/
private static $_instance;
/**
* Private constructor, use {@link getInstance()}
*
* @uses PMA_array_write()
*/
private function __construct()
{
// load default config values
$cfg = &$this->cfg;
require './libraries/config.default.php';
$cfg['fontsize'] = '82%';
// load additional config information
$cfg_db = &$this->cfgDb;
require './libraries/config.values.php';
// apply default values overrides
if (count($cfg_db['_overrides'])) {
foreach ($cfg_db['_overrides'] as $path => $value) {
PMA_array_write($path, $cfg, $value);
}
}
$this->id = 'ConfigFile' . $GLOBALS['server'];
if (!isset($_SESSION[$this->id])) {
$_SESSION[$this->id] = array();
}
}
/**
* Returns class instance
*
* @return ConfigFile
*/
public static function getInstance()
{
if (is_null(self::$_instance)) {
self::$_instance = new ConfigFile();
}
return self::$_instance;
}
/**
* Sets names of config options which will be placed in config file even if they are set
* to their default values (use only full paths)
*
* @param array $keys
*/
public function setPersistKeys($keys)
{
// checking key presence is much faster than searching so move values to keys
$this->persistKeys = array_flip($keys);
}
/**
* Returns flipped array set by {@link setPersistKeys()}
*
* @return array
*/
public function getPersistKeysMap()
{
return $this->persistKeys;
}
/**
* By default ConfigFile allows setting of all configuration keys, use this method
* to set up a filter on {@link set()} method
*
* @param array|null $keys array of allowed keys or null to remove filter
*/
public function setAllowedKeys($keys)
{
if ($keys === null) {
$this->setFilter = null;
return;
}
// checking key presence is much faster than searching so move values to keys
$this->setFilter = array_flip($keys);
}
/**
* Sets path mapping for updating config in {@link updateWithGlobalConfig()} or reading
* by {@link getConfig()} or {@link getConfigArray()}
* @var array
*/
public function setCfgUpdateReadMapping(array $mapping)
{
$this->cfgUpdateReadMapping = $mapping;
}
/**
* Resets configuration data
*/
public function resetConfigData()
{
$_SESSION[$this->id] = array();
}
/**
* Sets configuration data (overrides old data)
*
* @param array $cfg
*/
public function setConfigData(array $cfg)
{
$_SESSION[$this->id] = $cfg;
}
/**
* Sets config value
*
* @uses PMA_array_remove()
* @uses PMA_array_write()
* @param string $path
* @param mixed $value
* @param string $canonical_path
*/
public function set($path, $value, $canonical_path = null)
{
if ($canonical_path === null) {
$canonical_path = $this->getCanonicalPath($path);
}
// apply key whitelist
if ($this->setFilter !== null && !isset($this->setFilter[$canonical_path])) {
return;
}
// remove if the path isn't protected and it's empty or has a default value
$default_value = $this->getDefault($canonical_path);
if (!isset($this->persistKeys[$canonical_path])
&& (($value === $default_value) || (empty($value) && empty($default_value)))) {
PMA_array_remove($path, $_SESSION[$this->id]);
} else {
PMA_array_write($path, $_SESSION[$this->id], $value);
}
}
/**
* Flattens multidimensional array, changes indices to paths (eg. 'key/subkey').
* Used as array_walk() callback.
*
* @param mixed $value
* @param mixed $key
* @param mixed $prefix
*/
private function _flattenArray($value, $key, $prefix)
{
// no recursion for numeric arrays
if (is_array($value) && !isset($value[0])) {
$prefix .= $key . '/';
array_walk($value, array($this, '_flattenArray'), $prefix);
} else {
$this->_flattenArrayResult[$prefix . $key] = $value;
}
}
/**
* Returns default config in a flattened array
*
* @return array
*/
public function getFlatDefaultConfig()
{
$this->_flattenArrayResult = array();
array_walk($this->cfg, array($this, '_flattenArray'), '');
$flat_cfg = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
return $flat_cfg;
}
/**
* Updates config with values read from given array
* (config will contain differences to defaults from config.defaults.php).
*
* @param array $cfg
*/
public function updateWithGlobalConfig(array $cfg)
{
// load config array and flatten it
$this->_flattenArrayResult = array();
array_walk($cfg, array($this, '_flattenArray'), '');
$flat_cfg = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
// save values
// map for translating a few user preferences paths, should be complemented
// by code reading from generated config to perform inverse mapping
foreach ($flat_cfg as $path => $value) {
if (isset($this->cfgUpdateReadMapping[$path])) {
$path = $this->cfgUpdateReadMapping[$path];
}
$this->set($path, $value, $path);
}
}
/**
* Returns config value or $default if it's not set
*
* @uses PMA_array_read()
* @param string $path
* @param mixed $default
* @return mixed
*/
public function get($path, $default = null)
{
return PMA_array_read($path, $_SESSION[$this->id], $default);
}
/**
* Returns default config value or $default it it's not set ie. it doesn't
* exist in config.default.php ($cfg) and config.values.php
* ($_cfg_db['_overrides'])
*
* @uses PMA_array_read()
* @param string $canonical_path
* @param mixed $default
* @return mixed
*/
public function getDefault($canonical_path, $default = null)
{
return PMA_array_read($canonical_path, $this->cfg, $default);
}
/**
* Returns config value, if it's not set uses the default one; returns
* $default if the path isn't set and doesn't contain a default value
*
* @uses PMA_array_read()
* @param string $path
* @param mixed $default
* @return mixed
*/
public function getValue($path, $default = null)
{
$v = PMA_array_read($path, $_SESSION[$this->id], null);
if ($v !== null) {
return $v;
}
$path = $this->getCanonicalPath($path);
return $this->getDefault($path, $default);
}
/**
* Returns canonical path
*
* @param string $path
* @return string
*/
public function getCanonicalPath($path) {
return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
}
/**
* Returns config database entry for $path ($cfg_db in config_info.php)
*
* @uses PMA_array_read()
* @param string $path
* @param mixed $default
* @return mixed
*/
public function getDbEntry($path, $default = null)
{
return PMA_array_read($path, $this->cfgDb, $default);
}
/**
* Returns server count
*
* @return int
*/
public function getServerCount()
{
return isset($_SESSION[$this->id]['Servers'])
? count($_SESSION[$this->id]['Servers'])
: 0;
}
/**
* Returns server list
*
* @return array|null
*/
public function getServers()
{
return isset($_SESSION[$this->id]['Servers'])
? $_SESSION[$this->id]['Servers']
: null;
}
/**
* Returns DSN of given server
*
* @param integer $server
* @return string
*/
function getServerDSN($server)
{
if (!isset($_SESSION[$this->id]['Servers'][$server])) {
return '';
}
$path = 'Servers/' . $server;
$dsn = $this->getValue("$path/extension") . '://';
if ($this->getValue("$path/auth_type") == 'config') {
$dsn .= $this->getValue("$path/user");
if (!$this->getValue("$path/nopassword")) {
$dsn .= ':***';
}
$dsn .= '@';
}
if ($this->getValue("$path/connect_type") == 'tcp') {
$dsn .= $this->getValue("$path/host");
$port = $this->getValue("$path/port");
if ($port) {
$dsn .= ':' . $port;
}
} else {
$dsn .= $this->getValue("$path/socket");
}
return $dsn;
}
/**
* Returns server name
*
* @param int $id
* @return string
*/
public function getServerName($id)
{
if (!isset($_SESSION[$this->id]['Servers'][$id])) {
return '';
}
$verbose = $this->get("Servers/$id/verbose");
if (!empty($verbose)) {
return $verbose;
}
$host = $this->get("Servers/$id/host");
return empty($host) ? 'localhost' : $host;
}
/**
* Removes server
*
* @param int $server
*/
public function removeServer($server)
{
if (!isset($_SESSION[$this->id]['Servers'][$server])) {
return;
}
$last_server = $this->getServerCount();
for ($i = $server; $i < $last_server; $i++) {
$_SESSION[$this->id]['Servers'][$i] = $_SESSION[$this->id]['Servers'][$i+1];
}
unset($_SESSION[$this->id]['Servers'][$last_server]);
if (isset($_SESSION[$this->id]['ServerDefault'])
&& $_SESSION[$this->id]['ServerDefault'] >= 0) {
unset($_SESSION[$this->id]['ServerDefault']);
}
}
/**
* Returns config file path, relative to phpMyAdmin's root path
*
* @return string
*/
public function getFilePath()
{
// Load paths
if (!defined('SETUP_CONFIG_FILE')) {
require_once './libraries/vendor_config.php';
}
return SETUP_CONFIG_FILE;
}
/**
* Returns configuration array (full, multidimensional format)
*
* @return array
*/
public function getConfig()
{
$c = $_SESSION[$this->id];
foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
PMA_array_write($map_to, $c, PMA_array_read($map_from, $c));
PMA_array_remove($map_from, $c);
}
return $c;
}
/**
* Returns configuration array (flat format)
*
* @return array
*/
public function getConfigArray()
{
$this->_flattenArrayResult = array();
array_walk($_SESSION[$this->id], array($this, '_flattenArray'), '');
$c = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
$persistKeys = array_diff(array_keys($this->persistKeys), array_keys($c));
foreach ($persistKeys as $k) {
$c[$k] = $this->getDefault($k);
}
foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
if (!isset($c[$map_from])) {
continue;
}
$c[$map_to] = $c[$map_from];
unset($c[$map_from]);
}
return $c;
}
}
?>

View File

@@ -1,17 +1,16 @@
<?php <?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/** /**
* Form handling code. * Form handling code.
* *
* @package phpMyAdmin-setup * @package phpMyAdmin
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
* @version $Id$
*/ */
/** /**
* Base class for forms, loads default configuration options, checks allowed * Base class for forms, loads default configuration options, checks allowed
* values etc. * values etc.
* *
* @package phpMyAdmin-setup * @package phpMyAdmin
*/ */
class Form class Form
{ {
@@ -45,22 +44,17 @@ class Form
*/ */
private $fieldsTypes; private $fieldsTypes;
/**
* Cached forms
* @var array
*/
private static $_forms;
/** /**
* Constructor, reads default config values * Constructor, reads default config values
* *
* @param string $form_name * @param string $form_name
* @param array $form
* @param int $index arbitrary index, stored in Form::$index * @param int $index arbitrary index, stored in Form::$index
*/ */
public function __construct($form_name, $index = null) public function __construct($form_name, array $form, $index = null)
{ {
$this->index = $index; $this->index = $index;
$this->loadForm($form_name); $this->loadForm($form_name, $form);
} }
/** /**
@@ -80,6 +74,8 @@ class Form
/** /**
* Returns allowed values for select fields * Returns allowed values for select fields
* *
* @uses ConfigFile::getDbEntry()
* @uses ConfigFile::getInstance()
* @param string $option_path * @param string $option_path
* @return array * @return array
*/ */
@@ -94,12 +90,33 @@ class Form
trigger_error("$option_path - not a static value list", E_USER_ERROR); trigger_error("$option_path - not a static value list", E_USER_ERROR);
return array(); return array();
} }
// convert array('#', 'a', 'b') to array('a', 'b')
if (isset($value[0]) && $value[0] === '#') {
// remove first element ('#')
array_shift($value);
} else {
// convert value list array('a', 'b') to array('a' => 'a', 'b' => 'b')
$has_string_keys = false;
$keys = array();
for ($i = 0; $i < count($value); $i++) {
if (!isset($value[$i])) {
$has_string_keys = true;
break;
}
$keys[] = is_bool($value[$i]) ? (int)$value[$i] : $value[$i];
}
if (!$has_string_keys) {
$value = array_combine($keys, $value);
}
}
// $value has keys and value names, return it
return $value; return $value;
} }
/** /**
* array_walk callback function, reads path of form fields from * array_walk callback function, reads path of form fields from
* array (see file comment in forms.inc.php) * array (see file comment in setup.forms.php or user_preferences.forms.inc)
* *
* @param mixed $value * @param mixed $value
* @param mixed $key * @param mixed $key
@@ -108,41 +125,33 @@ class Form
private function _readFormPathsCallback($value, $key, $prefix) private function _readFormPathsCallback($value, $key, $prefix)
{ {
if (is_array($value)) { if (is_array($value)) {
$prefix .= (empty($prefix) ? '' : '/') . $key; $prefix .= $key . '/';
array_walk($value, array($this, '_readFormPathsCallback'), $prefix); array_walk($value, array($this, '_readFormPathsCallback'), $prefix);
} else { } else {
if (!is_int($key)) { if (!is_int($key)) {
$this->default[$prefix . '/' . $key] = $value; $this->default[$prefix . $key] = $value;
$value = $key; $value = $key;
} }
$this->fields[] = $prefix . '/' . $value; $this->fields[] = $prefix . $value;
} }
} }
/** /**
* Reads form paths to {@link $fields} * Reads form paths to {@link $fields}
*
* @param array $form
*/ */
protected function readFormPaths() protected function readFormPaths($form)
{ {
if (is_null(self::$_forms)) {
$forms =& self::$_forms;
require './setup/lib/forms.inc.php';
}
if (!isset(self::$_forms[$this->name])) {
return;
}
// flatten form fields' paths and save them to $fields // flatten form fields' paths and save them to $fields
$this->fields = array(); $this->fields = array();
array_walk(self::$_forms[$this->name], array($this, '_readFormPathsCallback'), ''); array_walk($form, array($this, '_readFormPathsCallback'), '');
// $this->fields is an array of the form: [0..n] => 'field path' // $this->fields is an array of the form: [0..n] => 'field path'
// change numeric indexes to contain field names (last part of the path) // change numeric indexes to contain field names (last part of the path)
$paths = $this->fields; $paths = $this->fields;
$this->fields = array(); $this->fields = array();
foreach ($paths as $path) { foreach ($paths as $path) {
$path = ltrim($path, '/');
$key = ltrim(substr($path, strrpos($path, '/')), '/'); $key = ltrim(substr($path, strrpos($path, '/')), '/');
$this->fields[$key] = $path; $this->fields[$key] = $path;
} }
@@ -151,11 +160,19 @@ class Form
/** /**
* Reads fields' types to $this->fieldsTypes * Reads fields' types to $this->fieldsTypes
*
* @uses ConfigFile::getDbEntry()
* @uses ConfigFile::getDefault()
* @uses ConfigFile::getInstance()
*/ */
protected function readTypes() protected function readTypes()
{ {
$cf = ConfigFile::getInstance(); $cf = ConfigFile::getInstance();
foreach ($this->fields as $name => $path) { foreach ($this->fields as $name => $path) {
if (strpos($name, ':group:') === 0) {
$this->fieldsTypes[$name] = 'group';
continue;
}
$v = $cf->getDbEntry($path); $v = $cf->getDbEntry($path);
if ($v !== null) { if ($v !== null) {
$type = is_array($v) ? 'select' : $v; $type = is_array($v) ? 'select' : $v;
@@ -171,12 +188,13 @@ class Form
* config file * config file
* *
* @param string $form_name * @param string $form_name
* @param array $form
*/ */
public function loadForm($form_name) public function loadForm($form_name, $form)
{ {
$this->name = $form_name; $this->name = $form_name;
$this->readFormPaths(); $this->readFormPaths($form);
$this->readTypes(); $this->readTypes();
} }
} }
?> ?>

View File

@@ -1,4 +1,5 @@
<?php <?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/** /**
* Form management class, displays and processes forms * Form management class, displays and processes forms
* *
@@ -8,16 +9,14 @@
* o translated_path - work_path modified for HTML field name, a path with * o translated_path - work_path modified for HTML field name, a path with
* slashes changed to hyphens, eg. Servers-4-verbose * slashes changed to hyphens, eg. Servers-4-verbose
* *
* @package phpMyAdmin-setup * @package phpMyAdmin
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
* @version $Id$
*/ */
/** /**
* Core libraries. * Core libraries.
*/ */
require_once './setup/lib/FormDisplay.tpl.php'; require_once './libraries/config/FormDisplay.tpl.php';
require_once './setup/lib/validate.lib.php'; require_once './libraries/config/validate.lib.php';
require_once './libraries/js_escape.lib.php'; require_once './libraries/js_escape.lib.php';
/** /**
@@ -28,7 +27,7 @@ class FormDisplay
{ {
/** /**
* Form list * Form list
* @var array * @var Form[]
*/ */
private $forms = array(); private $forms = array();
@@ -58,25 +57,49 @@ class FormDisplay
* Will be looked up in $GLOBALS: str{value} or strSetup{value} * Will be looked up in $GLOBALS: str{value} or strSetup{value}
* @var array * @var array
*/ */
private $js_lang_strings = array('error_nan_p', 'error_nan_nneg', private $js_lang_strings = array();
'error_incorrect_port');
/** /**
* Tells whether forms have been validated * Tells whether forms have been validated
* @var bool * @var bool
*/ */
private $is_valdiated = true; private $is_validated = true;
/**
* Dictionary with user preferences keys
* @var array
*/
private $userprefs_keys;
/**
* Dictionary with disallowed user preferences keys
* @var array
*/
private $userprefs_disallow;
public function __construct()
{
$this->js_lang_strings = array(
'error_nan_p' => __('Not a positive number'),
'error_nan_nneg' => __('Not a non-negative number'),
'error_incorrect_port' => __('Not a valid port number'),
'error_invalid_value' => __('Incorrect value'),
'error_value_lte' => __('Value must be equal or lower than %s'));
// initialize validators
PMA_config_get_validators();
}
/** /**
* Registers form in form manager * Registers form in form manager
* *
* @param string $form_name * @param string $form_name
* @param array $form
* @param int $server_id 0 if new server, validation; >= 1 if editing a server * @param int $server_id 0 if new server, validation; >= 1 if editing a server
*/ */
public function registerForm($form_name, $server_id = null) public function registerForm($form_name, array $form, $server_id = null)
{ {
$this->forms[$form_name] = new Form($form_name, $server_id); $this->forms[$form_name] = new Form($form_name, $form, $server_id);
$this->is_valdiated = false; $this->is_validated = false;
foreach ($this->forms[$form_name]->fields as $path) { foreach ($this->forms[$form_name]->fields as $path) {
$work_path = $server_id === null $work_path = $server_id === null
? $path ? $path
@@ -90,12 +113,12 @@ class FormDisplay
* Processes forms, returns true on successful save * Processes forms, returns true on successful save
* *
* @param bool $allow_partial_save allows for partial form saving on failed validation * @param bool $allow_partial_save allows for partial form saving on failed validation
* @param bool $check_form_submit whether check for $_POST['submit_save']
* @return boolean * @return boolean
*/ */
public function process($allow_partial_save = true) public function process($allow_partial_save = true, $check_form_submit = true)
{ {
// gather list of forms to save if ($check_form_submit && !isset($_POST['submit_save'])) {
if (!isset($_POST['submit_save'])) {
return false; return false;
} }
@@ -108,10 +131,14 @@ class FormDisplay
/** /**
* Runs validation for all registered forms * Runs validation for all registered forms
*
* @uses ConfigFile::getInstance()
* @uses ConfigFile::getValue()
* @uses PMA_config_validate()
*/ */
private function _validate() private function _validate()
{ {
if ($this->is_valdiated) { if ($this->is_validated) {
return; return;
} }
@@ -130,7 +157,7 @@ class FormDisplay
} }
// run validation // run validation
$errors = validate($paths, $values, false); $errors = PMA_config_validate($paths, $values, false);
// change error keys from canonical paths to work paths // change error keys from canonical paths to work paths
if (is_array($errors) && count($errors) > 0) { if (is_array($errors) && count($errors) > 0) {
@@ -145,13 +172,25 @@ class FormDisplay
$this->errors[$work_path] = $error_list; $this->errors[$work_path] = $error_list;
} }
} }
$this->is_valdiated = true; $this->is_validated = true;
} }
/** /**
* Outputs HTML for forms * Outputs HTML for forms
* *
* @uses ConfigFile::getInstance()
* @uses ConfigFile::get()
* @uses display_fieldset_bottom()
* @uses display_fieldset_top()
* @uses display_form_bottom()
* @uses display_form_top()
* @uses display_js()
* @uses display_tabs_bottom()
* @uses display_tabs_top()
* @uses js_validate()
* @uses PMA_config_get_validators()
* @uses PMA_jsFormat()
* @uses PMA_lang()
* @param bool $tabbed_form * @param bool $tabbed_form
* @param bool $show_restore_default whether show "restore default" button besides the input field * @param bool $show_restore_default whether show "restore default" button besides the input field
*/ */
@@ -162,7 +201,7 @@ class FormDisplay
$js = array(); $js = array();
$js_default = array(); $js_default = array();
$tabbed_form = $tabbed_form && (count($this->forms) > 1); $tabbed_form = $tabbed_form && (count($this->forms) > 1);
$validators = ConfigFile::getInstance()->getDbEntry('_validators'); $validators = PMA_config_get_validators();
display_form_top(); display_form_top();
@@ -187,10 +226,13 @@ class FormDisplay
$this->_validate(); $this->_validate();
} }
// user preferences
$this->_loadUserprefsInfo();
// display forms // display forms
foreach ($this->forms as $form) { foreach ($this->forms as $form) {
/* @var $form Form */ /* @var $form Form */
$form_desc = isset($GLOBALS["strSetupForm_{$form->name}_desc"]) $form_desc = isset($GLOBALS["strConfigForm_{$form->name}_desc"])
? PMA_lang("Form_{$form->name}_desc") ? PMA_lang("Form_{$form->name}_desc")
: ''; : '';
$form_errors = isset($this->errors[$form->name]) $form_errors = isset($this->errors[$form->name])
@@ -201,9 +243,14 @@ class FormDisplay
foreach ($form->fields as $field => $path) { foreach ($form->fields as $field => $path) {
$work_path = array_search($path, $this->system_paths); $work_path = array_search($path, $this->system_paths);
$translated_path = $this->translated_paths[$work_path]; $translated_path = $this->translated_paths[$work_path];
// always true/false for user preferences display
// otherwise null
$userprefs_allow = isset($this->userprefs_keys[$path])
? !isset($this->userprefs_disallow[$path])
: null;
// display input // display input
$this->_displayFieldInput($form, $field, $path, $work_path, $this->_displayFieldInput($form, $field, $path, $work_path,
$translated_path, $show_restore_default, $js_default); $translated_path, $show_restore_default, $userprefs_allow, $js_default);
// register JS validators for this field // register JS validators for this field
if (isset($validators[$path])) { if (isset($validators[$path])) {
js_validate($translated_path, $validators[$path], $js); js_validate($translated_path, $validators[$path], $js);
@@ -221,35 +268,45 @@ class FormDisplay
if (!$js_lang_sent) { if (!$js_lang_sent) {
$js_lang_sent = true; $js_lang_sent = true;
$js_lang = array(); $js_lang = array();
foreach ($this->js_lang_strings as $str) { foreach ($this->js_lang_strings as $strName => $strValue) {
$lang = isset($GLOBALS["strSetup$str"]) $js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\'';
? $GLOBALS["strSetup$str"]
: filter_input($GLOBALS["str$str"]); // null if not set
$js_lang[] = "'$str': '" . PMA_jsFormat($lang, false) . '\'';
} }
$js[] = '$.extend(PMA_messages, {' . implode(",\n\t", $js_lang) . '})'; $js[] = "$.extend(PMA_messages, {\n\t" . implode(",\n\t", $js_lang) . '})';
} }
$js[] = '$.extend(defaultValues, {' . implode(",\n\t", $js_default) . '})'; $js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})';
display_js($js); display_js($js);
} }
/** /**
* Prepares data for input field display and outputs HTML code * Prepares data for input field display and outputs HTML code
* *
* @uses ConfigFile::get()
* @uses ConfigFile::getDefault()
* @uses ConfigFile::getInstance()
* @uses display_group_footer()
* @uses display_group_header()
* @uses display_input()
* @uses Form::getOptionType()
* @uses Form::getOptionValueList()
* @uses PMA_escapeJsString()
* @uses PMA_lang_desc()
* @uses PMA_lang_name()
* @param Form $form * @param Form $form
* @param string $field field name as it appears in $form * @param string $field field name as it appears in $form
* @param string $system_path field path, eg. Servers/1/verbose * @param string $system_path field path, eg. Servers/1/verbose
* @param string $work_path work path, eg. Servers/4/verbose * @param string $work_path work path, eg. Servers/4/verbose
* @param string $translated_path work path changed so that it can be used as XHTML id * @param string $translated_path work path changed so that it can be used as XHTML id
* @param bool $show_restore_default whether show "restore default" button besides the input field * @param bool $show_restore_default whether show "restore default" button besides the input field
* @param mixed $userprefs_allow whether user preferences are enabled for this field
* (null - no support, true/false - enabled/disabled)
* @param array &$js_default array which stores JavaScript code to be displayed * @param array &$js_default array which stores JavaScript code to be displayed
*/ */
private function _displayFieldInput(Form $form, $field, $system_path, $work_path, private function _displayFieldInput(Form $form, $field, $system_path, $work_path,
$translated_path, $show_restore_default, array &$js_default) $translated_path, $show_restore_default, $userprefs_allow, array &$js_default)
{ {
$name = PMA_lang_name($system_path); $name = PMA_lang_name($system_path);
$description = PMA_lang_desc($system_path); $description = PMA_lang_name($system_path, 'desc', '');
$cf = ConfigFile::getInstance(); $cf = ConfigFile::getInstance();
$value = $cf->get($work_path); $value = $cf->get($work_path);
@@ -263,7 +320,9 @@ class FormDisplay
$opts = array( $opts = array(
'doc' => $this->getDocLink($system_path), 'doc' => $this->getDocLink($system_path),
'wiki' => $this->getWikiLink($system_path), 'wiki' => $this->getWikiLink($system_path),
'show_restore_default' => $show_restore_default); 'show_restore_default' => $show_restore_default,
'userprefs_allow' => $userprefs_allow,
'userprefs_comment' => PMA_lang_name($system_path, 'cmt', ''));
if (isset($form->default[$system_path])) { if (isset($form->default[$system_path])) {
$opts['setvalue'] = $form->default[$system_path]; $opts['setvalue'] = $form->default[$system_path];
} }
@@ -275,28 +334,33 @@ class FormDisplay
case 'string': case 'string':
$type = 'text'; $type = 'text';
break; break;
case 'double': case 'short_string':
$type = 'text'; $type = 'short_text';
break; break;
case 'double':
case 'integer': case 'integer':
$type = 'text'; $type = 'number_text';
break; break;
case 'boolean': case 'boolean':
$type = 'checkbox'; $type = 'checkbox';
break; break;
case 'select': case 'select':
$type = 'select'; $type = 'select';
$opts['values'] = array(); $opts['values'] = $form->getOptionValueList($form->fields[$field]);
$values = $form->getOptionValueList($form->fields[$field]);
foreach ($values as $v) {
$opts['values'][$v] = $v;
}
break; break;
case 'array': case 'array':
$type = 'list'; $type = 'list';
$value = (array) $value; $value = (array) $value;
$value_default = (array) $value_default; $value_default = (array) $value_default;
break; break;
case 'group':
$text = substr($field, 7);
if ($text != 'end') {
display_group_header($text);
} else {
display_group_footer();
}
return;
case 'NULL': case 'NULL':
trigger_error("Field $system_path has no type", E_USER_WARNING); trigger_error("Field $system_path has no type", E_USER_WARNING);
return; return;
@@ -310,11 +374,14 @@ class FormDisplay
} }
} }
} }
$this->_setComments($system_path, $opts);
// send default value to form's JS // send default value to form's JS
$js_line = '\'' . $translated_path . '\': '; $js_line = '\'' . $translated_path . '\': ';
switch ($type) { switch ($type) {
case 'text': case 'text':
case 'short_text':
case 'number_text':
$js_line .= '\'' . PMA_escapeJsString($value_default) . '\''; $js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
break; break;
case 'checkbox': case 'checkbox':
@@ -338,6 +405,9 @@ class FormDisplay
/** /**
* Displays errors * Displays errors
*
* @uses display_errors()
* @uses PMA_lang_name()
*/ */
public function displayErrors() public function displayErrors()
{ {
@@ -351,7 +421,7 @@ class FormDisplay
$path = $this->system_paths[$system_path]; $path = $this->system_paths[$system_path];
$name = PMA_lang_name($path); $name = PMA_lang_name($path);
} else { } else {
$name = $GLOBALS["strSetupForm_$system_path"]; $name = $GLOBALS["strConfigForm_$system_path"];
} }
display_errors($name, $error_list); display_errors($name, $error_list);
} }
@@ -359,6 +429,11 @@ class FormDisplay
/** /**
* Reverts erroneous fields to their default values * Reverts erroneous fields to their default values
*
* @uses ConfigFile::getDefault()
* @uses ConfigFile::getInstance()
* @uses ConfigFile::set()
*
*/ */
public function fixErrors() public function fixErrors()
{ {
@@ -386,11 +461,17 @@ class FormDisplay
*/ */
private function _validateSelect(&$value, array $allowed) private function _validateSelect(&$value, array $allowed)
{ {
foreach ($allowed as $v) { $value_cmp = is_bool($value)
if ($value == $v) { ? (int) $value
settype($value, gettype($v)); : $value;
return true; foreach ($allowed as $vk => $v) {
} // equality comparison only if both values are numeric or not numeric
// (allows to skip 0 == 'string' equalling to true) or identity (for string-string)
if (($vk == $value && !(is_numeric($value_cmp) xor is_numeric($vk)))
|| $vk === $value) {
settype($value, gettype($v));
return true;
}
} }
return false; return false;
} }
@@ -398,6 +479,13 @@ class FormDisplay
/** /**
* Validates and saves form data to session * Validates and saves form data to session
* *
* @uses ConfigFile::get()
* @uses ConfigFile::getInstance()
* @uses ConfigFile::getServerCount()
* @uses ConfigFile::set()
* @uses Form::getOptionType()
* @uses Form::getOptionValueList()
* @uses PMA_lang_name()
* @param array|string $forms array of form names * @param array|string $forms array of form names
* @param bool $allow_partial_save allows for partial form saving on failed validation * @param bool $allow_partial_save allows for partial form saving on failed validation
* @return boolean true on success (no errors and all saved) * @return boolean true on success (no errors and all saved)
@@ -410,6 +498,11 @@ class FormDisplay
$values = array(); $values = array();
$to_save = array(); $to_save = array();
$is_setup_script = defined('PMA_SETUP') && PMA_SETUP;
if ($is_setup_script) {
$this->_loadUserprefsInfo();
}
$this->errors = array(); $this->errors = array();
foreach ($forms as $form) { foreach ($forms as $form) {
/* @var $form Form */ /* @var $form Form */
@@ -426,23 +519,38 @@ class FormDisplay
foreach ($form->fields as $field => $system_path) { foreach ($form->fields as $field => $system_path) {
$work_path = array_search($system_path, $this->system_paths); $work_path = array_search($system_path, $this->system_paths);
$key = $this->translated_paths[$work_path]; $key = $this->translated_paths[$work_path];
$type = $form->getOptionType($field);
// skip groups
if ($type == 'group') {
continue;
}
// ensure the value is set // ensure the value is set
if (!isset($_POST[$key])) { if (!isset($_POST[$key])) {
// checkboxes aren't set by browsers if they're off // checkboxes aren't set by browsers if they're off
if ($form->getOptionType($field) == 'boolean') { if ($type == 'boolean') {
$_POST[$key] = false; $_POST[$key] = false;
} else { } else {
$this->errors[$form->name][] = PMA_lang( $this->errors[$form->name][] = sprintf(
'error_missing_field_data', __('Missing data for %s'),
'<i>' . PMA_lang_name($system_path) . '</i>'); '<i>' . PMA_lang_name($system_path) . '</i>');
$result = false; $result = false;
continue; continue;
} }
} }
// user preferences allow/disallow
if ($is_setup_script && isset($this->userprefs_keys[$system_path])) {
if (isset($this->userprefs_disallow[$system_path])
&& isset($_POST[$key . '-userprefs-allow'])) {
unset($this->userprefs_disallow[$system_path]);
} else if (!isset($_POST[$key . '-userprefs-allow'])) {
$this->userprefs_disallow[$system_path] = true;
}
}
// cast variables to correct type // cast variables to correct type
$type = $form->getOptionType($field);
switch ($type) { switch ($type) {
case 'double': case 'double':
settype($_POST[$key], 'float'); settype($_POST[$key], 'float');
@@ -461,11 +569,14 @@ class FormDisplay
} }
break; break;
case 'string': case 'string':
case 'short_string':
$_POST[$key] = trim($_POST[$key]); $_POST[$key] = trim($_POST[$key]);
break; break;
case 'array': case 'array':
// eliminate empty values and ensure we have an array // eliminate empty values and ensure we have an array
$post_values = explode("\n", $_POST[$key]); $post_values = is_array($_POST[$key])
? $_POST[$key]
: explode("\n", $_POST[$key]);
$_POST[$key] = array(); $_POST[$key] = array();
foreach ($post_values as $v) { foreach ($post_values as $v) {
$v = trim($v); $v = trim($v);
@@ -509,6 +620,9 @@ class FormDisplay
} }
$cf->set($work_path, $values[$path], $path); $cf->set($work_path, $values[$path], $path);
} }
if ($is_setup_script) {
$cf->set('UserprefsDisallow', array_keys($this->userprefs_disallow));
}
} }
// don't look for non-critical errors // don't look for non-critical errors
@@ -540,7 +654,7 @@ class FormDisplay
if ($test == 'Import' || $test == 'Export') { if ($test == 'Import' || $test == 'Export') {
return ''; return '';
} }
return '../Documentation.html#cfg_' . self::_getOptName($path); return 'Documentation.html#cfg_' . $this->_getOptName($path);
} }
/** /**
@@ -551,7 +665,7 @@ class FormDisplay
*/ */
public function getWikiLink($path) public function getWikiLink($path)
{ {
$opt_name = self::_getOptName($path); $opt_name = $this->_getOptName($path);
if (substr($opt_name, 0, 7) == 'Servers') { if (substr($opt_name, 0, 7) == 'Servers') {
$opt_name = substr($opt_name, 8); $opt_name = substr($opt_name, 8);
if (strpos($opt_name, 'AllowDeny') === 0) { if (strpos($opt_name, 'AllowDeny') === 0) {
@@ -577,9 +691,88 @@ class FormDisplay
* @param string $path * @param string $path
* @return string * @return string
*/ */
private static function _getOptName($path) private function _getOptName($path)
{ {
return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path); return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path);
}
/**
* Fills out {@link userprefs_keys} and {@link userprefs_disallow}
*
* @uses PMA_read_userprefs_fieldnames()
*/
private function _loadUserprefsInfo()
{
if ($this->userprefs_keys === null) {
$this->userprefs_keys = array_flip(PMA_read_userprefs_fieldnames());
// read real config for user preferences display
$userprefs_disallow = defined('PMA_SETUP') && PMA_SETUP
? ConfigFile::getInstance()->get('UserprefsDisallow', array())
: $GLOBALS['cfg']['UserprefsDisallow'];
$this->userprefs_disallow = array_flip($userprefs_disallow);
}
}
/**
* Sets field comments and warnings based on current environment
*
* @param string $system_path
* @param array $opts
*/
private function _setComments($system_path, array &$opts)
{
// RecodingEngine - mark unavailable types
if ($system_path == 'RecodingEngine') {
$comment = '';
if (!function_exists('iconv')) {
$opts['values']['iconv'] .= ' (' . __('unavailable') . ')';
$comment = sprintf(__('"%s" requires %s extension'), 'iconv', 'iconv');
}
if (!function_exists('recode_string')) {
$opts['values']['recode'] .= ' (' . __('unavailable') . ')';
$comment .= ($comment ? ", " : '') . sprintf(__('"%s" requires %s extension'),
'recode', 'recode');
}
$opts['comment'] = $comment;
$opts['comment_warning'] = true;
}
// ZipDump, GZipDump, BZipDump - check function availability
if ($system_path == 'ZipDump' || $system_path == 'GZipDump' || $system_path == 'BZipDump') {
$comment = '';
$funcs = array(
'ZipDump' => array('zip_open', 'gzcompress'),
'GZipDump' => array('gzopen', 'gzencode'),
'BZipDump' => array('bzopen', 'bzcompress'));
if (!function_exists($funcs[$system_path][0])) {
$comment = sprintf(__('import will not work, missing function (%s)'),
$funcs[$system_path][0]);
}
if (!function_exists($funcs[$system_path][1])) {
$comment .= ($comment ? '; ' : '') . sprintf(__('export will not work, missing function (%s)'),
$funcs[$system_path][1]);
}
$opts['comment'] = $comment;
$opts['comment_warning'] = true;
}
if ($system_path == 'SQLQuery/Validate' && !$GLOBALS['cfg']['SQLValidator']['use']) {
$opts['comment'] = __('SQL Validator is disabled');
$opts['comment_warning'] = true;
}
if ($system_path == 'SQLValidator/use') {
if (!class_exists('SOAPClient')) {
@include_once 'SOAP/Client.php';
if (!class_exists('SOAP_Client')) {
$opts['comment'] = __('SOAP extension not found');
$opts['comment_warning'] = true;
}
}
}
if (!defined('PMA_SETUP') || !PMA_SETUP) {
if (($system_path == 'MaxDbList' || $system_path == 'MaxTableList'
|| $system_path == 'QueryHistoryMax')) {
$opts['comment'] = sprintf(__('maximum %s'), $GLOBALS['cfg'][$system_path]);
}
}
} }
} }
?> ?>

View File

@@ -0,0 +1,429 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Form templates
*
* @package phpMyAdmin
*/
/**
* Displays top part of the form
*
* @uses PMA_generate_common_hidden_inputs()
* @uses PMA_getHiddenFields()
* @param string $action default: $_SERVER['REQUEST_URI']
* @param string $method 'post' or 'get'
* @param array $hidden_fields array of form hidden fields (key: field name)
*/
function display_form_top($action = null, $method = 'post', $hidden_fields = null)
{
static $has_check_page_refresh = false;
if ($action === null) {
$action = $_SERVER['REQUEST_URI'];
}
if ($method != 'post') {
$method = 'get';
}
?>
<form method="<?php echo $method ?>" action="<?php echo htmlspecialchars($action) ?>" class="config-form">
<input type="hidden" name="tab_hash" value="" />
<?php
// we do validation on page refresh when browser remembers field values,
// add a field with known value which will be used for checks
if (!$has_check_page_refresh) {
$has_check_page_refresh = true;
echo '<input type="hidden" name="check_page_refresh" id="check_page_refresh"'
. ' value="" />' . "\n";
}
echo PMA_generate_common_hidden_inputs('', '', 0, 'server') . "\n";
echo PMA_getHiddenFields((array)$hidden_fields);
}
/**
* Displays form tabs which are given by an array indexed by fieldset id
* ({@link display_fieldset_top}), with values being tab titles.
*
* @param array $tabs
*/
function display_tabs_top($tabs)
{
?>
<ul class="tabs">
<?php foreach ($tabs as $tab_id => $tab_name): ?>
<li><a href="#<?php echo $tab_id ?>"><?php echo $tab_name ?></a></li>
<?php endforeach; ?>
</ul>
<br clear="right" />
<div class="tabs_contents">
<?php
}
/**
* Displays top part of a fieldset
*
* @param string $title
* @param string $description
* @param array $errors
* @param array $attributes
*/
function display_fieldset_top($title = '', $description = '', $errors = null, $attributes = array())
{
global $_FormDisplayGroup;
$_FormDisplayGroup = false;
$attributes = array_merge(array('class' => 'optbox'), $attributes);
foreach ($attributes as $k => &$attr) {
$attr = $k . '="' . htmlspecialchars($attr) . '"';
}
echo '<fieldset ' . implode(' ', $attributes) . '>';
echo '<legend>' . $title . '</legend>';
if (!empty($description)) {
echo '<p>' . $description . '</p>';
}
// this must match with displayErrors() in scripts.js
if (is_array($errors) && count($errors) > 0) {
echo '<dl class="errors">';
foreach ($errors as $error) {
echo '<dd>' . $error . '</dd>';
}
echo '</dl>';
}
?>
<table width="100%" cellspacing="0">
<?php
}
/**
* Displays input field
*
* $opts keys:
* o doc - (string) documentation link
* o errors - error array
* o setvalue - (string) shows button allowing to set poredefined value
* o show_restore_default - (boolean) whether show "restore default" button
* o userprefs_allow - whether user preferences are enabled for this field (null - no support,
* true/false - enabled/disabled)
* o userprefs_comment - (string) field comment
* o values - key - value paris for <select> fields
* o values_escaped - (boolean) tells whether values array is already escaped (defaults to false)
* o values_disabled - (array)list of disabled values (keys from values)
* o comment - (string) tooltip comment
* o comment_warning - (bool) whether this comments warns about something
* o wiki - (string) wiki link
*
* @uses $GLOBALS['_FormDisplayGroup']
* @uses $GLOBALS['cfg']['ThemePath']
* @uses $_SESSION['PMA_Theme']
* @uses display_group_footer()
* @param string $path
* @param string $name
* @param string $description
* @param string $type
* @param mixed $value
* @param bool $value_is_default
* @param array $opts
*/
function display_input($path, $name, $description = '', $type, $value, $value_is_default = true, $opts = null)
{
global $_FormDisplayGroup;
static $base_dir, $img_path;
$is_setup_script = defined('PMA_SETUP') && PMA_SETUP;
if ($base_dir === null) {
$base_dir = $is_setup_script ? '../' : '';
$img_path = $is_setup_script
? '../' . ltrim($GLOBALS['cfg']['ThemePath'], './') . '/original/img/'
: $_SESSION['PMA_Theme']->img_path;
}
$has_errors = isset($opts['errors']) && !empty($opts['errors']);
$option_is_disabled = !$is_setup_script && isset($opts['userprefs_allow']) && !$opts['userprefs_allow'];
$name_id = 'name="' . htmlspecialchars($path) . '" id="' . htmlspecialchars($path) . '"';
$field_class = $type == 'checkbox' ? 'checkbox' : '';
if (!$value_is_default) {
$field_class .= ($field_class == '' ? '' : ' ') . ($has_errors ? 'custom field-error' : 'custom');
}
$field_class = $field_class ? ' class="' . $field_class . '"' : '';
$tr_class = $_FormDisplayGroup ? 'group-field' : '';
if (isset($opts['setvalue']) && $opts['setvalue'] == ':group') {
unset($opts['setvalue']);
$tr_class = 'group-header-field';
if ($_FormDisplayGroup) {
display_group_footer();
}
$_FormDisplayGroup = true;
}
if ($option_is_disabled) {
$tr_class .= ($tr_class ? ' ' : '') . 'disabled-field';
}
$tr_class = $tr_class ? ' class="' . $tr_class . '"' : '';
?>
<tr<?php echo $tr_class ?>>
<th>
<label for="<?php echo htmlspecialchars($path) ?>"><?php echo $name ?></label>
<?php if (!empty($opts['doc']) || !empty($opts['wiki'])) { ?>
<span class="doc">
<?php if (!empty($opts['doc'])) { ?><a href="<?php echo $base_dir . $opts['doc'] ?>" target="documentation"><img class="icon" src="<?php echo $img_path ?>b_help.png" width="11" height="11" alt="Doc" title="<?php echo __('Documentation') ?>" /></a><?php } ?>
<?php if (!empty($opts['wiki'])){ ?><a href="<?php echo $opts['wiki'] ?>" target="wiki"><img class="icon" src="<?php echo $img_path ?>b_info.png" width="11" height="11" alt="Wiki" title="Wiki" /></a><?php } ?>
</span>
<?php } ?>
<?php if ($option_is_disabled) { ?>
<span class="disabled-notice" title="<?php echo __('This setting is disabled, it will not be applied to your configuration') ?>"><?php echo __('Disabled') ?></span>
<?php } ?>
<?php if (!empty($description)) { ?><small><?php echo $description ?></small><?php } ?>
</th>
<td>
<?php
switch ($type) {
case 'text':
echo '<input type="text" size="60" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'short_text':
echo '<input type="text" size="25" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'number_text':
echo '<input type="text" size="15" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'checkbox':
echo '<span' . $field_class . '><input type="checkbox" ' . $name_id
. ($value ? ' checked="checked"' : '') . ' /></span>';
break;
case 'select':
echo '<select ' . $name_id . $field_class . '>';
$escape = !(isset($opts['values_escaped']) && $opts['values_escaped']);
$values_disabled = isset($opts['values_disabled'])
? array_flip($opts['values_disabled']) : array();
foreach ($opts['values'] as $opt_value_key => $opt_value) {
// set names for boolean values
if (is_bool($opt_value)) {
$opt_value = strtolower($opt_value ? __('Yes') : __('No'));
}
// escape if necessary
if ($escape) {
$display = htmlspecialchars($opt_value);
$display_value = htmlspecialchars($opt_value_key);
} else {
$display = $opt_value;
$display_value = $opt_value_key;
}
// compare with selected value
// boolean values are cast to integers when used as array keys
$selected = is_bool($value)
? (int) $value === $opt_value_key
: $opt_value_key === $value;
echo '<option value="' . $display_value . '"'
. ($selected ? ' selected="selected"' : '')
. (isset($values_disabled[$opt_value_key]) ? ' disabled="disabled"' : '')
. '>' . $display . '</option>';
}
echo '</select>';
break;
case 'list':
echo '<textarea cols="40" rows="5" ' . $name_id . $field_class . '>'
. htmlspecialchars(implode("\n", $value))
. '</textarea>';
break;
}
if (isset($opts['comment']) && $opts['comment']) {
$class = 'field-comment-mark';
if (isset($opts['comment_warning']) && $opts['comment_warning']) {
$class .= ' field-comment-warning';
}
?>
<span class="<?php echo $class ?>" title="<?php echo htmlspecialchars($opts['comment']) ?>">i</span>
<?php
}
if ($is_setup_script && isset($opts['userprefs_comment']) && $opts['userprefs_comment']) {
?>
<a class="userprefs-comment" title="<?php echo htmlspecialchars($opts['userprefs_comment']) ?>"><img alt="comment" src="<?php echo $img_path ?>b_tblops.png" width="16" height="16" /></a>
<?php
}
if (isset($opts['setvalue']) && $opts['setvalue']) {
?>
<a class="set-value" href="#<?php echo htmlspecialchars("$path={$opts['setvalue']}") ?>" title="<?php echo sprintf(__('Set value: %s'), htmlspecialchars($opts['setvalue'])) ?>" style="display:none"><img alt="set-value" src="<?php echo $img_path ?>b_edit.png" width="16" height="16" /></a>
<?php
}
if (isset($opts['show_restore_default']) && $opts['show_restore_default']) {
?>
<a class="restore-default" href="#<?php echo $path ?>" title="<?php echo __('Restore default value') ?>" style="display:none"><img alt="restore-default" src="<?php echo $img_path ?>s_reload.png" width="16" height="16" /></a>
<?php
}
// this must match with displayErrors() in scripts/config.js
if ($has_errors) {
echo "\n <dl class=\"inline_errors\">";
foreach ($opts['errors'] as $error) {
echo '<dd>' . htmlspecialchars($error) . '</dd>';
}
echo '</dl>';
}
?>
</td>
<?php
if ($is_setup_script && isset($opts['userprefs_allow'])) {
?>
<td class="userprefs-allow" title="<?php echo __('Allow users to customize this value') ?>">
<input type="checkbox" name="<?php echo $path ?>-userprefs-allow" <?php if ($opts['userprefs_allow']) echo 'checked="checked"' ?> />
</td>
<?php
} else if ($is_setup_script) {
echo '<td>&nbsp;</td>';
}
?>
</tr>
<?php
}
/**
* Display group header
*
* @uses $GLOBALS['_FormDisplayGroup']
* @uses display_group_footer()
* @param string $header_text
*/
function display_group_header($header_text)
{
global $_FormDisplayGroup;
if ($_FormDisplayGroup) {
display_group_footer();
}
$_FormDisplayGroup = true;
if (!$header_text) {
return;
}
$colspan = 2;
if (defined('PMA_SETUP') && PMA_SETUP) {
$colspan++;
}
?>
<tr class="group-header">
<th colspan="<?php echo $colspan ?>">
<?php echo $header_text ?>
</th>
</tr>
<?php
}
/**
* Display group footer
*
* @uses $GLOBALS['_FormDisplayGroup']
*/
function display_group_footer()
{
global $_FormDisplayGroup;
$_FormDisplayGroup = false;
}
/**
* Displays bottom part of a fieldset
*/
function display_fieldset_bottom()
{
$colspan = 2;
if (defined('PMA_SETUP') && PMA_SETUP) {
$colspan++;
}
?>
<tr>
<td colspan="<?php echo $colspan ?>" class="lastrow">
<input type="submit" name="submit_save" value="<?php echo __('Save') ?>" class="green" />
<input type="button" name="submit_reset" value="<?php echo __('Reset') ?>" />
</td>
</tr>
</table>
</fieldset>
<?php
}
/**
* Displays simple bottom part of a fieldset (without submit buttons)
*/
function display_fieldset_bottom_simple()
{
?>
</table>
</fieldset>
<?php
}
/**
* Closes form tabs
*/
function display_tabs_bottom()
{
echo "</div>\n";
}
/**
* Displays bottom part of the form
*/
function display_form_bottom()
{
echo "</form>\n";
}
/**
* Appends JS validation code to $js_array
*
* @uses PMA_escapeJsString()
* @param string $field_id
* @param string|array $validator
* @param array $js_array
*/
function js_validate($field_id, $validators, &$js_array)
{
foreach ((array)$validators as $validator) {
$validator = (array)$validator;
$v_name = array_shift($validator);
$v_args = array();
foreach ($validator as $arg) {
$v_args[] = PMA_escapeJsString($arg);
}
$v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : '';
$js_array[] = "validateField('$field_id', '$v_name', true$v_args)";
}
}
/**
* Displays JavaScript code
*
* @param array $js_array
*/
function display_js($js_array)
{
if (empty($js_array)) {
return;
}
?>
<script type="text/javascript">
<?php echo implode(";\n", $js_array) . ";\n" ?>
</script>
<?php
}
/**
* Displays error list
*
* @param string $name
* @param array $error_list
*/
function display_errors($name, $error_list)
{
echo '<dl>';
echo '<dt>' . htmlspecialchars($name) . '</dt>';
foreach ($error_list as $error) {
echo '<dd>' . htmlspecialchars($error) . '</dd>';
}
echo '</dl>';
}
?>

View File

@@ -0,0 +1,100 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Common config manipulation functions
*
* @package phpMyAdmin
*/
/**
* Returns sanitized language string, taking into account our special codes
* for formatting. Takes variable number of arguments.
* Based on PMA_sanitize from sanitize.lib.php.
*
* @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix
* @param mixed $args arguments for sprintf
* @return string
*/
function PMA_lang($lang_key)
{
static $search, $replace;
// some quick cache'ing
if ($search === null) {
$replace_pairs = array(
'<' => '&lt;',
'>' => '&gt;',
'[em]' => '<em>',
'[/em]' => '</em>',
'[strong]' => '<strong>',
'[/strong]' => '</strong>',
'[code]' => '<code>',
'[/code]' => '</code>',
'[kbd]' => '<kbd>',
'[/kbd]' => '</kbd>',
'[br]' => '<br />',
'[sup]' => '<sup>',
'[/sup]' => '</sup>');
if (defined('PMA_SETUP')) {
$replace_pairs['[a@Documentation.html'] = '[a@../Documentation.html';
}
$search = array_keys($replace_pairs);
$replace = array_values($replace_pairs);
}
$message = isset($GLOBALS["strConfig$lang_key"]) ? $GLOBALS["strConfig$lang_key"] : $lang_key;
$message = str_replace($search, $replace, $message);
// replace [a@"$1"]$2[/a] with <a href="$1">$2</a>
$message = preg_replace('#\[a@("?)([^\]]+)\1\]([^\[]+)\[/a\]#e',
"PMA_lang_link_replace('$2', '$3')", $message);
if (func_num_args() == 1) {
return $message;
} else {
$args = func_get_args();
array_shift($args);
return vsprintf($message, $args);
}
}
/**
* Returns translated field name/description or comment
*
* @param string $canonical_path
* @param string $type 'name', 'desc' or 'cmt'
* @param mixed $default
* @return string
*/
function PMA_lang_name($canonical_path, $type = 'name', $default = 'key')
{
$lang_key = str_replace(
array('Servers/1/', '/'),
array('Servers/', '_'),
$canonical_path) . '_' . $type;
return isset($GLOBALS["strConfig$lang_key"])
? ($type == 'desc' ? PMA_lang($lang_key) : $GLOBALS["strConfig$lang_key"])
: ($default == 'key' ? $lang_key : $default);
}
/**
* Wraps link in &lt;a&gt; tags and replaces argument separator in internal links
* to the one returned by PMA_get_arg_separator()
*
* @param string $link
* @param string $text
* @return string
*/
function PMA_lang_link_replace($link, $text)
{
static $separator;
if (!isset($separator)) {
$separator = PMA_get_arg_separator('html');
}
if (!preg_match('#^http://#', $link)) {
$link = str_replace('&amp;', $separator, $link);
}
return '<a href="' . $link . '">' . $text . '</a>';
}
?>

View File

@@ -0,0 +1,498 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Messages for phpMyAdmin.
*
* This file is here for easy transition to Gettext. You should not add any
* new messages here, use instead gettext directly in your template/PHP
* file.
*
* @package phpMyAdmin
*/
if (!function_exists('__')) {
die('Bad invocation!');
}
$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth');
$strConfigAllowArbitraryServer_name = __('Allow login to any MySQL server');
$strConfigAllowThirdPartyFraming_desc = __('Enabling this allows a page located on a different domain to call phpMyAdmin inside a frame, and is a potential [strong]security hole[/strong] allowing cross-frame scripting attacks');
$strConfigAllowThirdPartyFraming_name = __('Allow third party framing');
$strConfigAllowUserDropDatabase_name = __('Show &quot;Drop database&quot; link to normal users');
$strConfigblowfish_secret_desc = __('Secret passphrase used for encrypting cookies in [kbd]cookie[/kbd] authentication');
$strConfigblowfish_secret_name = __('Blowfish secret');
$strConfigBrowseMarkerEnable_desc = __('Highlight selected rows');
$strConfigBrowseMarkerEnable_name = __('Row marker');
$strConfigBrowsePointerEnable_desc = __('Highlight row pointed by the mouse cursor');
$strConfigBrowsePointerEnable_name = __('Highlight pointer');
$strConfigBZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Bzip2]bzip2[/a] compression for import and export operations');
$strConfigBZipDump_name = __('Bzip2');
$strConfigCharEditing_desc = __('Defines which type of editing controls should be used for CHAR and VARCHAR columns; [kbd]input[/kbd] - allows limiting of input length, [kbd]textarea[/kbd] - allows newlines in columns');
$strConfigCharEditing_name = __('CHAR columns editing');
$strConfigCharTextareaCols_desc = __('Number of columns for CHAR/VARCHAR textareas');
$strConfigCharTextareaCols_name = __('CHAR textarea columns');
$strConfigCharTextareaRows_desc = __('Number of rows for CHAR/VARCHAR textareas');
$strConfigCharTextareaRows_name = __('CHAR textarea rows');
$strConfigCheckConfigurationPermissions_name = __('Check config file permissions');
$strConfigCompressOnFly_desc = __('Compress gzip/bzip2 exports on the fly without the need for much memory; if you encounter problems with created gzip/bzip2 files disable this feature');
$strConfigCompressOnFly_name = __('Compress on the fly');
$strConfigConfigurationFile = __('Configuration file');
$strConfigConfirm_desc = __('Whether a warning (&quot;Are your really sure...&quot;) should be displayed when you\'re about to lose data');
$strConfigConfirm_name = __('Confirm DROP queries');
$strConfigCtrlArrowsMoving_name = __('Field navigation using Ctrl+Arrows');
$strConfigDBG_php_name = __('Debug PHP');
$strConfigDBG_sql_name = __('Debug SQL');
$strConfigDefaultDisplay_name = __('Default display direction');
$strConfigDefaultPropDisplay_desc = __('[kbd]horizontal[/kbd], [kbd]vertical[/kbd] or a number that indicates maximum number for which vertical model is used');
$strConfigDefaultPropDisplay_name = __('Display direction for altering/creating columns');
$strConfigDefaultTabDatabase_desc = __('Tab that is displayed when entering a database');
$strConfigDefaultTabDatabase_name = __('Default database tab');
$strConfigDefaultTabServer_desc = __('Tab that is displayed when entering a server');
$strConfigDefaultTabServer_name = __('Default server tab');
$strConfigDefaultTabTable_desc = __('Tab that is displayed when entering a table');
$strConfigDefaultTabTable_name = __('Default table tab');
$strConfigDisplayBinaryAsHex_desc = __('Show binary contents as HEX by default');
$strConfigDisplayBinaryAsHex_name = __('Show binary contents as HEX');
$strConfigDisplayDatabasesList_desc = __('Show database listing as a list instead of a drop down');
$strConfigDisplayDatabasesList_name = __('Display databases as a list');
$strConfigDisplayServersList_desc = __('Show server listing as a list instead of a drop down');
$strConfigDisplayServersList_name = __('Display servers as a list');
$strConfigEditInWindow_desc = __('Edit SQL queries in popup window');
$strConfigEditInWindow_name = __('Edit in window');
$strConfigError_Handler_display_name = __('Display errors');
$strConfigError_Handler_gather_name = __('Gather errors');
$strConfigErrorIconic_desc = __('Show icons for warning, error and information messages');
$strConfigErrorIconic_name = __('Iconic errors');
$strConfigExecTimeLimit_desc = __('Set the number of seconds a script is allowed to run ([kbd]0[/kbd] for no limit)');
$strConfigExecTimeLimit_name = __('Maximum execution time');
$strConfigExport_asfile_name = __('Save as file');
$strConfigExport_charset_name = __('Character set of the file');
$strConfigExport_codegen_format_name = __('Format');
$strConfigExport_compression_name = __('Compression');
$strConfigExport_csv_columns_name = __('Put columns names in the first row');
$strConfigExport_csv_enclosed_name = __('Columns enclosed by');
$strConfigExport_csv_escaped_name = __('Columns escaped by');
$strConfigExport_csv_null_name = __('Replace NULL by');
$strConfigExport_csv_removeCRLF_name = __('Remove CRLF characters within columns');
$strConfigExport_csv_separator_name = __('Columns terminated by');
$strConfigExport_csv_terminated_name = __('Lines terminated by');
$strConfigExport_excel_columns_name = __('Put columns names in the first row');
$strConfigExport_excel_edition_name = __('Excel edition');
$strConfigExport_excel_null_name = __('Replace NULL by');
$strConfigExport_excel_removeCRLF_name = __('Remove CRLF characters within columns');
$strConfigExport_file_template_database_name = __('Database name template');
$strConfigExport_file_template_server_name = __('Server name template');
$strConfigExport_file_template_table_name = __('Table name template');
$strConfigExport_format_name = __('Format');
$strConfigExport_htmlword_columns_name = __('Put columns names in the first row');
$strConfigExport_htmlword_null_name = __('Replace NULL by');
$strConfigExport_htmlword_structure_or_data_name = __('Dump table');
$strConfigExport_latex_caption_name = __('Include table caption');
$strConfigExport_latex_columns_name = __('Put columns names in the first row');
$strConfigExport_latex_comments_name = __('Comments');
$strConfigExport_latex_data_caption_name = __('Table caption');
$strConfigExport_latex_data_continued_caption_name = __('Continued table caption');
$strConfigExport_latex_data_label_name = __('Label key');
$strConfigExport_latex_mime_name = __('MIME type');
$strConfigExport_latex_null_name = __('Replace NULL by');
$strConfigExport_latex_relation_name = __('Relations');
$strConfigExport_latex_structure_caption_name = __('Table caption');
$strConfigExport_latex_structure_continued_caption_name = __('Continued table caption');
$strConfigExport_latex_structure_label_name = __('Label key');
$strConfigExport_latex_structure_or_data_name = __('Dump table');
$strConfigExport_method_name = __('Export method');
$strConfigExport_ods_columns_name = __('Put columns names in the first row');
$strConfigExport_ods_null_name = __('Replace NULL by');
$strConfigExport_odt_columns_name = __('Put columns names in the first row');
$strConfigExport_odt_comments_name = __('Comments');
$strConfigExport_odt_mime_name = __('MIME type');
$strConfigExport_odt_null_name = __('Replace NULL by');
$strConfigExport_odt_relation_name = __('Relations');
$strConfigExport_odt_structure_or_data_name = __('Dump table');
$strConfigExport_onserver_name = __('Save on server');
$strConfigExport_onserver_overwrite_name = __('Overwrite existing file(s)');
$strConfigExport_remember_file_template_name = __('Remember file name template');
$strConfigExport_sql_auto_increment_name = __('Add AUTO_INCREMENT value');
$strConfigExport_sql_backquotes_name = __('Enclose table and column names with backquotes');
$strConfigExport_sql_compatibility_name = __('SQL compatibility mode');
$strConfigExport_sql_create_table_statements_name = __('Syntax to use when inserting data');
$strConfigExport_sql_dates_name = __('Creation/Update/Check dates');
$strConfigExport_sql_delayed_name = __('Use delayed inserts');
$strConfigExport_sql_disable_fk_name = __('Disable foreign key checks');
$strConfigExport_sql_drop_database_name = sprintf(__('Add %s'), 'DROP DATABASE');
$strConfigExport_sql_drop_table_name = sprintf(__('Add %s'), 'DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT');
$strConfigExport_sql_hex_for_blob_name = __('Use hexadecimal for BLOB');
$strConfigExport_sql_if_not_exists_name = sprintf(__('Add %s'), 'IF NOT EXISTS');
$strConfigExport_sql_ignore_name = __('Use ignore inserts');
$strConfigExport_sql_include_comments_name = __('Comments');
$strConfigExport_sql_max_query_size_name = __('Maximal length of created query');
$strConfigExport_sql_mime_name = __('MIME type');
$strConfigExport_sql_procedure_function_name = sprintf(__('Add %s'), 'CREATE PROCEDURE / FUNCTION / EVENT');
$strConfigExport_sql_relation_name = __('Relations');
$strConfigExport_sql_structure_or_data_name = __('Dump table');
$strConfigExport_sql_type_name = __('Export type');
$strConfigExport_sql_use_transaction_name = __('Enclose export in a transaction');
$strConfigExport_sql_utc_time_name = __('Export time in UTC');
$strConfigExport_texytext_columns_name = __('Put columns names in the first row');
$strConfigExport_texytext_null_name = __('Replace NULL by');
$strConfigExport_texytext_structure_or_data_name = __('Dump table');
$strConfigExport_xls_columns_name = __('Put columns names in the first row');
$strConfigExport_xls_null_name = __('Replace NULL by');
$strConfigExport_xlsx_columns_name = __('Put columns names in the first row');
$strConfigExport_xlsx_null_name = __('Replace NULL by');
$strConfigForceSSL_desc = __('Force secured connection while using phpMyAdmin');
$strConfigForceSSL_name = __('Force SSL connection');
$strConfigForeignKeyDropdownOrder_desc = __('Sort order for items in a foreign-key dropdown box; [kbd]content[/kbd] is the referenced data, [kbd]id[/kbd] is the key value');
$strConfigForeignKeyDropdownOrder_name = __('Foreign key dropdown order');
$strConfigForeignKeyMaxLimit_desc = __('A dropdown will be used if fewer items are present');
$strConfigForeignKeyMaxLimit_name = __('Foreign key limit');
$strConfigForm_Browse = __('Browse mode');
$strConfigForm_Browse_desc = __('Customize browse mode');
$strConfigForm_CodeGen = 'CodeGen';
$strConfigForm_CodeGen_desc = __('Customize default options');
$strConfigForm_Csv = __('CSV');
$strConfigForm_Csv_desc = __('Customize default options');
$strConfigForm_Developer = __('Developer');
$strConfigForm_Developer_desc = __('Settings for phpMyAdmin developers');
$strConfigForm_Edit = __('Edit mode');
$strConfigForm_Edit_desc = __('Customize edit mode');
$strConfigForm_Export = __('Export');
$strConfigForm_Export_defaults = __('Export defaults');
$strConfigForm_Export_defaults_desc = __('Customize default export options');
$strConfigForm_Features = __('Features');
$strConfigForm_General = __('General');
$strConfigForm_General_desc = __('Set some commonly used options');
$strConfigForm_Import = __('Import');
$strConfigForm_Import_defaults = __('Import defaults');
$strConfigForm_Import_defaults_desc = __('Customize default common import options');
$strConfigForm_Import_export = __('Import / export');
$strConfigForm_Import_export_desc = __('Set import and export directories and compression options');
$strConfigForm_Latex = __('LaTeX');
$strConfigForm_Latex_desc = __('Customize default options');
$strConfigForm_Left_databases = __('Databases');
$strConfigForm_Left_databases_desc = __('Databases display options');
$strConfigForm_Left_frame = __('Navigation frame');
$strConfigForm_Left_frame_desc = __('Customize appearance of the navigation frame');
$strConfigForm_Left_servers = __('Servers');
$strConfigForm_Left_servers_desc = __('Servers display options');
$strConfigForm_Left_tables = __('Tables');
$strConfigForm_Left_tables_desc = __('Tables display options');
$strConfigForm_Main_frame = __('Main frame');
$strConfigForm_Microsoft_Office = __('Microsoft Office');
$strConfigForm_Microsoft_Office_desc = __('Customize default options');
$strConfigForm_Open_Document = __('Open Document');
$strConfigForm_Open_Document_desc = __('Customize default options');
$strConfigForm_Other_core_settings = __('Other core settings');
$strConfigForm_Other_core_settings_desc = __('Settings that didn\'t fit enywhere else');
$strConfigForm_Page_titles = __('Page titles');
$strConfigForm_Page_titles_desc = __('Specify browser\'s title bar text. Refer to [a@Documentation.html#cfg_TitleTable]documentation[/a] for magic strings that can be used to get special values.');
$strConfigForm_Query_window = __('Query window');
$strConfigForm_Query_window_desc = __('Customize query window options');
$strConfigForm_Security = __('Security');
$strConfigForm_Security_desc = __('Please note that phpMyAdmin is just a user interface and its features do not limit MySQL');
$strConfigForm_Server = __('Basic settings');
$strConfigForm_Server_auth = __('Authentication');
$strConfigForm_Server_auth_desc = __('Authentication settings');
$strConfigForm_Server_config = __('Server configuration');
$strConfigForm_Server_config_desc = __('Advanced server configuration, do not change these options unless you know what they are for');
$strConfigForm_Server_desc = __('Enter server connection parameters');
$strConfigForm_Server_pmadb = __('Configuration storage');
$strConfigForm_Server_pmadb_desc = __('Configure phpMyAdmin configuration storage to gain access to additional features, see [a@Documentation.html#linked-tables]phpMyAdmin configuration storage[/a] in documentation');
$strConfigForm_Server_tracking = __('Changes tracking');
$strConfigForm_Server_tracking_desc = __('Tracking of changes made in database. Requires configured PMA database.');
$strConfigFormset_Export = __('Customize export options');
$strConfigFormset_Features = __('Features');
$strConfigFormset_Import = __('Customize import defaults');
$strConfigFormset_Left_frame = __('Customize navigation frame');
$strConfigFormset_Main_frame = __('Customize main frame');
$strConfigFormset_Sql_queries = __('SQL queries');
$strConfigForm_Sql = __('SQL');
$strConfigForm_Sql_box = __('SQL Query box');
$strConfigForm_Sql_box_desc = __('Customize links shown in SQL Query boxes');
$strConfigForm_Sql_desc = __('Customize default options');
$strConfigForm_Sql_queries = __('SQL queries');
$strConfigForm_Sql_queries_desc = __('SQL queries settings');
$strConfigForm_Sql_validator = __('SQL Validator');
$strConfigForm_Sql_validator_desc = __('If you wish to use the SQL Validator service, you should be aware that [strong]all SQL statements are stored anonymously for statistical purposes[/strong].[br][em][a@http://sqlvalidator.mimer.com/]Mimer SQL Validator[/a], Copyright 2002 Upright Database Technology. All rights reserved.[/em]');
$strConfigForm_Startup = __('Startup');
$strConfigForm_Startup_desc = __('Customize startup page');
$strConfigForm_Tabs = __('Tabs');
$strConfigForm_Tabs_desc = __('Choose how you want tabs to work');
$strConfigForm_Text_fields = __('Text fields');
$strConfigForm_Text_fields_desc = __('Customize text input fields');
$strConfigForm_Texy = __('Texy! text');
$strConfigForm_Texy_desc = __('Customize default options');
$strConfigForm_Warnings = __('Warnings');
$strConfigForm_Warnings_desc = __('Disable some of the warnings shown by phpMyAdmin');
$strConfigGZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Gzip]gzip[/a] compression for import and export operations');
$strConfigGZipDump_name = __('GZip');
$strConfigIconvExtraParams_name = __('Extra parameters for iconv');
$strConfigIgnoreMultiSubmitErrors_desc = __('If enabled, phpMyAdmin continues computing multiple-statement queries even if one of the queries failed');
$strConfigIgnoreMultiSubmitErrors_name = __('Ignore multiple statement errors');
$strConfigImport_allow_interrupt_desc = __('Allow interrupt of import in case script detects it is close to time limit. This might be good way to import large files, however it can break transactions.');
$strConfigImport_allow_interrupt_name = __('Partial import: allow interrupt');
$strConfigImport_charset_name = __('Character set of the file');
$strConfigImport_csv_col_names_name = __('Lines terminated by');
$strConfigImport_csv_enclosed_name = __('Columns enclosed by');
$strConfigImport_csv_escaped_name = __('Columns escaped by');
$strConfigImport_csv_ignore_name = __('Ignore duplicate rows');
$strConfigImport_csv_replace_name = __('Replace table data with file');
$strConfigImport_csv_terminated_name = __('Columns terminated by');
$strConfigImport_format_desc = __('Default format; be aware that this list depends on location (database, table) and only SQL is always available');
$strConfigImport_format_name = __('Format of imported file');
$strConfigImport_ldi_enclosed_name = __('Columns enclosed by');
$strConfigImport_ldi_escaped_name = __('Columns escaped by');
$strConfigImport_ldi_ignore_name = __('Ignore duplicate rows');
$strConfigImport_ldi_local_option_name = __('Use LOCAL keyword');
$strConfigImport_ldi_replace_name = __('Replace table data with file');
$strConfigImport_ldi_terminated_name = __('Columns terminated by');
$strConfigImport_ods_col_names_name = __('Column names in first row');
$strConfigImport_ods_empty_rows_name = __('Do not import empty rows');
$strConfigImport_ods_recognize_currency_name = __('Import currencies ($5.00 to 5.00)');
$strConfigImport_ods_recognize_percentages_name = __('Import percentages as proper decimals (12.00% to .12)');
$strConfigImport_skip_queries_desc = __('Number of queries to skip from start');
$strConfigImport_skip_queries_name = __('Partial import: skip queries');
$strConfigImport_sql_compatibility_name = __('SQL compatibility mode');
$strConfigImport_sql_no_auto_value_on_zero_name = __('Do not use AUTO_INCREMENT for zero values');
$strConfigImport_xls_col_names_name = __('Column names in first row');
$strConfigImport_xlsx_col_names_name = __('Column names in first row');
$strConfigInitialSlidersState_name = __('Initial state for sliders');
$strConfigInsertRows_desc = __('How many rows can be inserted at one time');
$strConfigInsertRows_name = __('Number of inserted rows');
$strConfigLeftDefaultTabTable_name = __('Target for quick access icon');
$strConfigLeftDisplayLogo_desc = __('Show logo in left frame');
$strConfigLeftDisplayLogo_name = __('Display logo');
$strConfigLeftDisplayServers_desc = __('Display server choice at the top of the left frame');
$strConfigLeftDisplayServers_name = __('Display servers selection');
$strConfigLeftFrameDBSeparator_desc = __('String that separates databases into different tree levels');
$strConfigLeftFrameDBSeparator_name = __('Database tree separator');
$strConfigLeftFrameDBTree_desc = __('Only light version; display databases in a tree (determined by the separator defined below)');
$strConfigLeftFrameDBTree_name = __('Display databases in a tree');
$strConfigLeftFrameLight_desc = __('Disable this if you want to see all databases at once');
$strConfigLeftFrameLight_name = __('Use light version');
$strConfigLeftFrameTableLevel_name = __('Maximum table tree depth');
$strConfigLeftFrameTableSeparator_desc = __('String that separates tables into different tree levels');
$strConfigLeftFrameTableSeparator_name = __('Table tree separator');
$strConfigLeftLogoLink_desc = __('URL where logo in the navigation frame will point to');
$strConfigLeftLogoLink_name = __('Logo link URL');
$strConfigLeftLogoLinkWindow_desc = __('Open the linked page in the main window ([kbd]main[/kbd]) or in a new one ([kbd]new[/kbd])');
$strConfigLeftLogoLinkWindow_name = __('Logo link target');
$strConfigLeftPointerEnable_desc = __('Highlight server under the mouse cursor');
$strConfigLeftPointerEnable_name = __('Enable highlighting');
$strConfigLightTabs_desc = __('Use less graphically intense tabs');
$strConfigLightTabs_name = __('Light tabs');
$strConfigLimitChars_desc = __('Maximum number of characters shown in any non-numeric column on browse view');
$strConfigLimitChars_name = __('Limit column characters');
$strConfigLoginCookieDeleteAll_desc = __('If TRUE, logout deletes cookies for all servers; when set to FALSE, logout only occurs for the current server. Setting this to FALSE makes it easy to forget to log out from other servers when connected to multiple servers.');
$strConfigLoginCookieDeleteAll_name = __('Delete all cookies on logout');
$strConfigLoginCookieRecall_desc = __('Define whether the previous login should be recalled or not in cookie authentication mode');
$strConfigLoginCookieRecall_name = __('Recall user name');
$strConfigLoginCookieStore_desc = __('Defines how long (in seconds) a login cookie should be stored in browser. The default of 0 means that it will be kept for the existing session only, and will be deleted as soon as you close the browser window. This is recommended for non-trusted environments.');
$strConfigLoginCookieStore_name = __('Login cookie store');
$strConfigLoginCookieValidity_desc = __('Define how long (in seconds) a login cookie is valid');
$strConfigLoginCookieValidity_name = __('Login cookie validity');
$strConfigLongtextDoubleTextarea_desc = __('Double size of textarea for LONGTEXT fields');
$strConfigLongtextDoubleTextarea_name = __('Bigger textarea for LONGTEXT');
$strConfigMainPageIconic_name = __('Use icons on main page');
$strConfigMaxCharactersInDisplayedSQL_desc = __('Maximum number of characters used when a SQL query is displayed');
$strConfigMaxCharactersInDisplayedSQL_name = __('Maximum displayed SQL length');
$strConfigMaxDbList_cmt = __('Users cannot set a higher value');
$strConfigMaxDbList_desc = __('Maximum number of databases displayed in left frame and database list');
$strConfigMaxDbList_name = __('Maximum databases');
$strConfigMaxRows_desc = __('Number of rows displayed when browsing a result set. If the result set contains more rows, &quot;Previous&quot; and &quot;Next&quot; links will be shown.');
$strConfigMaxRows_name = __('Maximum number of rows to display');
$strConfigMaxTableList_cmt = __('Users cannot set a higher value');
$strConfigMaxTableList_desc = __('Maximum number of tables displayed in table list');
$strConfigMaxTableList_name = __('Maximum tables');
$strConfigMcryptDisableWarning_desc = __('Disable the default warning that is displayed if mcrypt is missing for cookie authentication');
$strConfigMcryptDisableWarning_name = __('mcrypt warning');
$strConfigMemoryLimit_desc = __('The number of bytes a script is allowed to allocate, eg. [kbd]32M[/kbd] ([kbd]0[/kbd] for no limit)');
$strConfigMemoryLimit_name = __('Memory limit');
$strConfigModifyDeleteAtLeft_name = __('Show left delete link');
$strConfigModifyDeleteAtRight_name = __('Show right delete link');
$strConfigNaturalOrder_desc = __('Use natural order for sorting table and database names');
$strConfigNaturalOrder_name = __('Natural order');
$strConfigNavigationBarIconic_desc = __('Use only icons, only text or both');
$strConfigNavigationBarIconic_name = __('Iconic navigation bar');
$strConfigOBGzip_desc = __('use GZip output buffering for increased speed in HTTP transfers');
$strConfigOBGzip_name = __('GZip output buffering');
$strConfigOrder_desc = __('[kbd]SMART[/kbd] - i.e. descending order for columns of type TIME, DATE, DATETIME and TIMESTAMP, ascending order otherwise');
$strConfigOrder_name = __('Default sorting order');
$strConfigPersistentConnections_desc = __('Use persistent connections to MySQL databases');
$strConfigPersistentConnections_name = __('Persistent connections');
$strConfigPmaNoRelation_DisableWarning_desc = __('Disable the default warning that is displayed on the database details Structure page if any of the required tables for the relation features could not be found');
$strConfigPmaNoRelation_DisableWarning_name = __('Missing phpMyAdmin configuration storage tables');
$strConfigPropertiesIconic_desc = __('Use only icons, only text or both');
$strConfigPropertiesIconic_name = __('Iconic table operations');
$strConfigProtectBinary_desc = __('Disallow BLOB and BINARY columns from editing');
$strConfigProtectBinary_name = __('Protect binary columns');
$strConfigQueryHistoryDB_desc = __('Enable if you want DB-based query history (requires phpMyAdmin configuration storage). If disabled, this utilizes JS-routines to display query history (lost by window close).');
$strConfigQueryHistoryDB_name = __('Permanent query history');
$strConfigQueryHistoryMax_cmt = __('Users cannot set a higher value');
$strConfigQueryHistoryMax_desc = __('How many queries are kept in history');
$strConfigQueryHistoryMax_name = __('Query history length');
$strConfigQueryWindowDefTab_desc = __('Tab displayed when opening a new query window');
$strConfigQueryWindowDefTab_name = __('Default query window tab');
$strConfigQueryWindowHeight_desc = __('Query window height (in pixels)');
$strConfigQueryWindowHeight_name = __('Query window height');
$strConfigQueryWindowWidth_desc = __('Query window width (in pixels)');
$strConfigQueryWindowWidth_name = __('Query window width');
$strConfigRecodingEngine_desc = __('Select which functions will be used for character set conversion');
$strConfigRecodingEngine_name = __('Recoding engine');
$strConfigRepeatCells_desc = __('Repeat the headers every X cells, [kbd]0[/kbd] deactivates this feature');
$strConfigRepeatCells_name = __('Repeat headers');
$strConfigReplaceHelpImg_desc = __('Show help button instead of Documentation text');
$strConfigReplaceHelpImg_name = __('Show help button');
$strConfigRestoreDefaultValue = __('Restore default value');
$strConfigSaveDir_desc = __('Directory where exports can be saved on server');
$strConfigSaveDir_name = __('Save directory');
$strConfigServers_AllowDeny_order_desc = __('Leave blank if not used');
$strConfigServers_AllowDeny_order_name = __('Host authorization order');
$strConfigServers_AllowDeny_rules_desc = __('Leave blank for defaults');
$strConfigServers_AllowDeny_rules_name = __('Host authorization rules');
$strConfigServers_AllowNoPassword_name = __('Allow logins without a password');
$strConfigServers_AllowRoot_name = __('Allow root login');
$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth');
$strConfigServers_auth_http_realm_name = __('HTTP Realm');
$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a@http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)');
$strConfigServers_auth_swekey_config_name = __('SweKey config file');
$strConfigServers_auth_type_desc = __('Authentication method to use');
$strConfigServers_auth_type_name = __('Authentication type');
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma_bookmark[/kbd]');
$strConfigServers_bookmarktable_name = __('Bookmark table');
$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma_column_info[/kbd]');
$strConfigServers_column_info_name = __('Column information table');
$strConfigServers_compress_desc = __('Compress connection to MySQL server');
$strConfigServers_compress_name = __('Compress connection');
$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure');
$strConfigServers_connect_type_name = __('Connection type');
$strConfigServers_controlpass_name = __('Control user password');
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
$strConfigServers_controluser_name = __('Control user');
$strConfigServers_CountTables_desc = __('Count tables when showing database list');
$strConfigServers_CountTables_name = __('Count tables');
$strConfigServers_designer_coords_desc = __('Leave blank for no Designer support, suggested: [kbd]pma_designer_coords[/kbd]');
$strConfigServers_designer_coords_name = __('Designer table');
$strConfigServers_DisableIS_desc = __('More information on [a@http://sf.net/support/tracker.php?aid=1849494]PMA bug tracker[/a] and [a@http://bugs.mysql.com/19588]MySQL Bugs[/a]');
$strConfigServers_DisableIS_name = __('Disable use of INFORMATION_SCHEMA');
$strConfigServers_extension_desc = __('What PHP extension to use; you should use mysqli if supported');
$strConfigServers_extension_name = __('PHP extension to use');
$strConfigServers_hide_db_desc = __('Hide databases matching regular expression (PCRE)');
$strConfigServers_hide_db_name = __('Hide databases');
$strConfigServers_history_desc = __('Leave blank for no SQL query history support, suggested: [kbd]pma_history[/kbd]');
$strConfigServers_history_name = __('SQL query history table');
$strConfigServers_host_desc = __('Hostname where MySQL server is running');
$strConfigServers_host_name = __('Server hostname');
$strConfigServers_LogoutURL_name = __('Logout URL');
$strConfigServers_nopassword_desc = __('Try to connect without password');
$strConfigServers_nopassword_name = __('Connect without password');
$strConfigServers_only_db_desc = __('You can use MySQL wildcard characters (% and _), escape them if you want to use their literal instances, i.e. use [kbd]\'my\_db\'[/kbd] and not [kbd]\'my_db\'[/kbd]. Using this option you can sort database list, just enter their names in order and use [kbd]*[/kbd] at the end to show the rest in alphabetical order.');
$strConfigServers_only_db_name = __('Show only listed databases');
$strConfigServers_password_desc = __('Leave empty if not using config auth');
$strConfigServers_password_name = __('Password for config auth');
$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma_pdf_pages[/kbd]');
$strConfigServers_pdf_pages_name = __('PDF schema: pages table');
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
$strConfigServers_pmadb_name = __('Database name');
$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default');
$strConfigServers_port_name = __('Server port');
$strConfigServers_relation_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma_relation[/kbd]');
$strConfigServers_relation_name = __('Relation table');
$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases');
$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command');
$strConfigServers_SignonSession_desc = __('See [a@http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
$strConfigServers_SignonSession_name = __('Signon session name');
$strConfigServers_SignonURL_name = __('Signon URL');
$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default');
$strConfigServers_socket_name = __('Server socket');
$strConfigServers_ssl_desc = __('Enable SSL for connection to MySQL server');
$strConfigServers_ssl_name = __('Use SSL');
$strConfigServers_table_coords_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma_table_coords[/kbd]');
$strConfigServers_table_coords_name = __('PDF schema: table coordinates');
$strConfigServers_table_info_desc = __('Table to describe the display columns, leave blank for no support; suggested: [kbd]pma_table_info[/kbd]');
$strConfigServers_table_info_name = __('Display columns table');
$strConfigServers_tracking_add_drop_database_desc = __('Whether a DROP DATABASE IF EXISTS statement will be added as first line to the log when creating a database.');
$strConfigServers_tracking_add_drop_database_name = __('Add DROP DATABASE');
$strConfigServers_tracking_add_drop_table_desc = __('Whether a DROP TABLE IF EXISTS statement will be added as first line to the log when creating a table.');
$strConfigServers_tracking_add_drop_table_name = __('Add DROP TABLE');
$strConfigServers_tracking_add_drop_view_desc = __('Whether a DROP VIEW IF EXISTS statement will be added as first line to the log when creating a view.');
$strConfigServers_tracking_add_drop_view_name = __('Add DROP VIEW');
$strConfigServers_tracking_default_statements_desc = __('Defines the list of statements the auto-creation uses for new versions.');
$strConfigServers_tracking_default_statements_name = __('Statements to track');
$strConfigServers_tracking_desc = __('Leave blank for no SQL query tracking support, suggested: [kbd]pma_tracking[/kbd]');
$strConfigServers_tracking_name = __('SQL query tracking table');
$strConfigServers_tracking_version_auto_create_desc = __('Whether the tracking mechanism creates versions for tables and views automatically.');
$strConfigServers_tracking_version_auto_create_name = __('Automatically create versions');
$strConfigServers_userconfig_desc = __('Leave blank for no user preferences storage in database, suggested: [kbd]pma_config[/kbd]');
$strConfigServers_userconfig_name = __('User preferences storage table');
$strConfigServers_user_desc = __('Leave empty if not using config auth');
$strConfigServers_user_name = __('User for config auth');
$strConfigServers_verbose_check_desc = __('Disable if you know that your pma_* tables are up to date. This prevents compatibility checks and thereby increases performance');
$strConfigServers_verbose_check_name = __('Verbose check');
$strConfigServers_verbose_desc = __('A user-friendly description of this server. Leave blank to display the hostname instead.');
$strConfigServers_verbose_name = __('Verbose name of this server');
$strConfigShowAll_desc = __('Whether a user should be displayed a &quot;show all (rows)&quot; button');
$strConfigShowAll_name = __('Allow to display all the rows');
$strConfigShowChgPassword_desc = __('Please note that enabling this has no effect with [kbd]config[/kbd] authentication mode because the password is hard coded in the configuration file; this does not limit the ability to execute the same command directly');
$strConfigShowChgPassword_name = __('Show password change form');
$strConfigShowCreateDb_name = __('Show create database form');
$strConfigShowFieldTypesInDataEditView_desc = __('Defines whether or not type fields should be initially displayed in edit/insert mode');
$strConfigShowFieldTypesInDataEditView_name = __('Show field types');
$strConfigShowFunctionFields_desc = __('Display the function fields in edit/insert mode');
$strConfigShowFunctionFields_name = __('Show function fields');
$strConfigShowPhpInfo_desc = __('Shows link to [a@http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output');
$strConfigShowPhpInfo_name = __('Show phpinfo() link');
$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed');
$strConfigShowSQL_name = __('Show SQL queries');
$strConfigShowStats_desc = __('Allow to display database and table statistics (eg. space usage)');
$strConfigShowStats_name = __('Show statistics');
$strConfigShowTooltipAliasDB_desc = __('If tooltips are enabled and a database comment is set, this will flip the comment and the real name');
$strConfigShowTooltipAliasDB_name = __('Display database comment instead of its name');
$strConfigShowTooltipAliasTB_desc = __('When setting this to [kbd]nested[/kbd], the alias of the table name is only used to split/nest the tables according to the $cfg[\'LeftFrameTableSeparator\'] directive, so only the folder is called like the alias, the table name itself stays unchanged');
$strConfigShowTooltipAliasTB_name = __('Display table comment instead of its name');
$strConfigShowTooltip_name = __('Display table comments in tooltips');
$strConfigSkipLockedTables_desc = __('Mark used tables and make it possible to show databases with locked tables');
$strConfigSkipLockedTables_name = __('Skip locked tables');
$strConfigSQLQuery_Edit_name = __('Edit');
$strConfigSQLQuery_Explain_name = __('Explain SQL');
$strConfigSQLQuery_Refresh_name = __('Refresh');
$strConfigSQLQuery_ShowAsPHP_name = __('Create PHP Code');
$strConfigSQLQuery_Validate_desc = __('Requires SQL Validator to be enabled');
$strConfigSQLQuery_Validate_name = __('Validate SQL');
$strConfigSQLValidator_password_name = __('Password');
$strConfigSQLValidator_use_desc = __('[strong]Warning:[/strong] requires PHP SOAP extension or PEAR SOAP to be installed');
$strConfigSQLValidator_use_name = __('Enable SQL Validator');
$strConfigSQLValidator_username_desc = __('If you have a custom username, specify it here (defaults to [kbd]anonymous[/kbd])');
$strConfigSQLValidator_username_name = __('Username');
$strConfigSuggestDBName_desc = __('Suggest a database name on the &quot;Create Database&quot; form (if possible) or keep the text field empty');
$strConfigSuggestDBName_name = __('Suggest new database name');
$strConfigSuhosinDisableWarning_desc = __('A warning is displayed on the main page if Suhosin is detected');
$strConfigSuhosinDisableWarning_name = __('Suhosin warning');
$strConfigTextareaCols_desc = __('Textarea size (columns) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
$strConfigTextareaCols_name = __('Textarea columns');
$strConfigTextareaRows_desc = __('Textarea size (rows) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
$strConfigTextareaRows_name = __('Textarea rows');
$strConfigTitleDatabase_desc = __('Title of browser window when a database is selected');
$strConfigTitleDatabase_name = __('Database');
$strConfigTitleDefault_desc = __('Title of browser window when nothing is selected');
$strConfigTitleDefault_name = __('Default title');
$strConfigTitleServer_desc = __('Title of browser window when a server is selected');
$strConfigTitleServer_name = __('Server');
$strConfigTitleTable_desc = __('Title of browser window when a table is selected');
$strConfigTitleTable_name = __('Table');
$strConfigTrustedProxies_desc = __('Input proxies as [kbd]IP: trusted HTTP header[/kbd]. The following example specifies that phpMyAdmin should trust a HTTP_X_FORWARDED_FOR (X-Forwarded-For) header coming from the proxy 1.2.3.4:[br][kbd]1.2.3.4: HTTP_X_FORWARDED_FOR[/kbd]');
$strConfigTrustedProxies_name = __('List of trusted proxies for IP allow/deny');
$strConfigUploadDir_desc = __('Directory on server where you can upload files for import');
$strConfigUploadDir_name = __('Upload directory');
$strConfigUseDbSearch_desc = __('Allow for searching inside the entire database');
$strConfigUseDbSearch_name = __('Use database search');
$strConfigUserprefsDeveloperTab_desc = __('When disabled, users cannot set any of the options below, regardless of the checkbox on the right');
$strConfigUserprefsDeveloperTab_name = __('Enable the Developer tab in settings');
$strConfigVerboseMultiSubmit_desc = __('Show affected rows of each statement on multiple-statement queries. See libraries/import.lib.php for defaults on how many queries a statement may contain.');
$strConfigVerboseMultiSubmit_name = __('Verbose multiple statements');
$strConfigVersionCheckLink = __('Check for latest version');
$strConfigZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/ZIP_(file_format)]ZIP[/a] compression for import and export operations');
$strConfigZipDump_name = __('ZIP');
?>

View File

@@ -0,0 +1,368 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* List of avaible forms, each form is described as an array of fields to display.
* Fields MUST have their counterparts in the $cfg array.
*
* There are two possible notations:
* $forms['Form group']['Form name'] = array('Servers' => array(1 => array('host')));
* can be written as
* $forms['Form group']['Form name'] = array('Servers/1/host');
*
* You can assign default values set by special button ("set value: ..."), eg.:
* 'Servers/1/pmadb' => 'phpmyadmin'
*
* To group options, use:
* ':group:' . __('group name') // just define a group
* or
* 'option' => ':group' // group starting from this option
* End group blocks with:
* ':group:end'
*
* @package phpMyAdmin-setup
*/
$forms = array();
$forms['_config.php'] = array(
'DefaultLang',
'ServerDefault');
$forms['Servers']['Server'] = array('Servers' => array(1 => array(
'verbose',
'host',
'port',
'socket',
'ssl',
'connect_type',
'extension',
'compress',
'nopassword')));
$forms['Servers']['Server_auth'] = array('Servers' => array(1 => array(
'auth_type',
':group:' . __('Config authentication'),
'user',
'password',
':group:end',
':group:' . __('Cookie authentication'),
'auth_swekey_config' => './swekey.conf',
':group:end',
':group:' . __('HTTP authentication'),
'auth_http_realm',
':group:end',
':group:' . __('Signon authentication'),
'SignonSession',
'SignonURL',
'LogoutURL')));
$forms['Servers']['Server_config'] = array('Servers' => array(1 => array(
'only_db',
'hide_db',
'AllowRoot',
'AllowNoPassword',
'DisableIS',
'AllowDeny/order',
'AllowDeny/rules',
'ShowDatabasesCommand',
'CountTables')));
$forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array(
'pmadb' => 'phpmyadmin',
'controluser',
'controlpass',
'verbose_check',
'bookmarktable' => 'pma_bookmark',
'relation' => 'pma_relation',
'userconfig' => 'pma_userconfig',
'table_info' => 'pma_table_info',
'column_info' => 'pma_column_info',
'history' => 'pma_history',
'tracking' => 'pma_tracking',
'table_coords' => 'pma_table_coords',
'pdf_pages' => 'pma_pdf_pages',
'designer_coords' => 'pma_designer_coords')));
$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array(
'tracking_version_auto_create',
'tracking_default_statements',
'tracking_add_drop_view',
'tracking_add_drop_table',
'tracking_add_drop_database',
)));
$forms['Features']['Import_export'] = array(
'UploadDir',
'SaveDir',
'RecodingEngine' => ':group',
'IconvExtraParams',
':group:end',
'ZipDump',
'GZipDump',
'BZipDump',
'CompressOnFly');
$forms['Features']['Security'] = array(
'blowfish_secret',
'ForceSSL',
'CheckConfigurationPermissions',
'TrustedProxies',
'AllowUserDropDatabase',
'AllowArbitraryServer',
'LoginCookieRecall',
'LoginCookieValidity',
'LoginCookieStore',
'LoginCookieDeleteAll');
$forms['Features']['Page_titles'] = array(
'TitleDefault',
'TitleTable',
'TitleDatabase',
'TitleServer');
$forms['Features']['Warnings'] = array(
'PmaNoRelation_DisableWarning',
'SuhosinDisableWarning',
'McryptDisableWarning');
$forms['Features']['Developer'] = array(
'UserprefsDeveloperTab',
'Error_Handler/display',
'Error_Handler/gather',
'DBG/sql',
'DBG/php');
$forms['Features']['Other_core_settings'] = array(
'NaturalOrder',
'InitialSlidersState',
'ErrorIconic',
'ReplaceHelpImg',
'MaxDbList',
'MaxTableList',
'OBGzip',
'PersistentConnections',
'ExecTimeLimit',
'MemoryLimit',
'SkipLockedTables',
'UseDbSearch',
'AllowThirdPartyFraming');
$forms['Sql_queries']['Sql_queries'] = array(
'ShowSQL',
'Confirm',
'QueryHistoryDB',
'QueryHistoryMax',
'IgnoreMultiSubmitErrors',
'VerboseMultiSubmit',
'MaxCharactersInDisplayedSQL',
'EditInWindow',
//'QueryWindowWidth', // overridden in theme
//'QueryWindowHeight',
'QueryWindowDefTab');
$forms['Sql_queries']['Sql_box'] = array('SQLQuery' => array(
'Edit',
'Explain',
'ShowAsPHP',
'Validate',
'Refresh'));
$forms['Sql_queries']['Sql_validator'] = array('SQLValidator' => array(
'use',
'username',
'password'));
$forms['Left_frame']['Left_frame'] = array(
'LeftFrameLight',
'LeftDisplayLogo',
'LeftLogoLink',
'LeftLogoLinkWindow',
'LeftPointerEnable');
$forms['Left_frame']['Left_servers'] = array(
'LeftDisplayServers',
'DisplayServersList');
$forms['Left_frame']['Left_databases'] = array(
'DisplayDatabasesList',
'LeftFrameDBTree',
'LeftFrameDBSeparator',
'ShowTooltipAliasDB');
$forms['Left_frame']['Left_tables'] = array(
'LeftDefaultTabTable',
'LeftFrameTableSeparator',
'LeftFrameTableLevel',
'ShowTooltip',
'ShowTooltipAliasTB');
$forms['Main_frame']['Startup'] = array(
'MainPageIconic',
'ShowCreateDb' => ':group',
'SuggestDBName',
':group:end',
'ShowStats',
'ShowServerInfo',
'ShowPhpInfo',
'ShowChgPassword');
$forms['Main_frame']['Browse'] = array(
'NavigationBarIconic',
'ShowAll',
'MaxRows',
'Order',
'BrowsePointerEnable',
'BrowseMarkerEnable',
'RepeatCells',
'LimitChars',
'ModifyDeleteAtLeft',
'ModifyDeleteAtRight',
'DefaultDisplay');
$forms['Main_frame']['Edit'] = array(
'ProtectBinary',
'ShowFunctionFields',
'ShowFieldTypesInDataEditView',
'CharEditing',
'CharTextareaCols',
'CharTextareaRows',
'TextareaCols',
'TextareaRows',
'LongtextDoubleTextarea',
'InsertRows',
'ForeignKeyDropdownOrder',
'ForeignKeyMaxLimit',
'DefaultPropDisplay');
$forms['Main_frame']['Tabs'] = array(
'LightTabs',
'PropertiesIconic',
'DefaultTabServer',
'DefaultTabDatabase',
'DefaultTabTable',
'QueryWindowDefTab');
$forms['Import']['Import_defaults'] = array('Import' => array(
'format',
'charset',
'allow_interrupt',
'skip_queries'));
$forms['Import']['Sql'] = array('Import' => array(
'sql_compatibility',
'sql_no_auto_value_on_zero'));
$forms['Import']['Csv'] = array('Import' => array(
':group:' . __('CSV'),
'csv_replace',
'csv_ignore',
'csv_terminated',
'csv_enclosed',
'csv_escaped',
'csv_col_names',
':group:end',
':group:' . __('CSV using LOAD DATA'),
'ldi_replace',
'ldi_ignore',
'ldi_terminated',
'ldi_enclosed',
'ldi_escaped',
'ldi_local_option',
':group:end'));
$forms['Import']['Microsoft_Office'] = array('Import' => array(
':group:' . __('Excel 97-2003 XLS Workbook'),
'xls_col_names',
':group:end',
':group:' . __('Excel 2007 XLSX Workbook'),
'xlsx_col_names'));
$forms['Import']['Open_Document'] = array('Import' => array(
':group:' . __('Open Document Spreadsheet'),
'ods_col_names',
'ods_empty_rows',
'ods_recognize_percentages',
'ods_recognize_currency'));
$forms['Export']['Export_defaults'] = array('Export' => array(
'method',
'format',
'compression',
'charset',
'asfile' => ':group',
'onserver',
'onserver_overwrite',
':group:end',
'remember_file_template',
'file_template_table',
'file_template_database',
'file_template_server'));
$forms['Export']['Sql'] = array('Export' => array(
'sql_include_comments' => ':group',
'sql_dates',
'sql_relation',
'sql_mime',
':group:end',
'sql_use_transaction',
'sql_disable_fk',
'sql_compatibility',
':group:' . __('Database export options'),
'sql_drop_database',
'sql_structure_or_data',
':group:end',
':group:' . __('Structure'),
'sql_drop_table',
'sql_procedure_function',
'sql_create_table_statements' => ':group',
'sql_if_not_exists',
'sql_auto_increment',
':group:end',
'sql_backquotes',
':group:end',
':group:' . __('Data'),
'sql_delayed',
'sql_ignore',
'sql_type',
'sql_insert_syntax',
'sql_max_query_size',
'sql_hex_for_blob',
'sql_utc_time'));
$forms['Export']['CodeGen'] = array('Export' => array(
'codegen_format'));
$forms['Export']['Csv'] = array('Export' => array(
':group:' . __('CSV'),
'csv_separator',
'csv_enclosed',
'csv_escaped',
'csv_terminated',
'csv_null',
'csv_removeCRLF',
'csv_columns',
':group:end',
':group:' . __('CSV for MS Excel'),
'excel_null',
'excel_removeCRLF',
'excel_columns',
'excel_edition'));
$forms['Export']['Latex'] = array('Export' => array(
'latex_caption',
'latex_structure_or_data',
':group:' . __('Structure'),
'latex_structure_caption',
'latex_structure_continued_caption',
'latex_structure_label',
'latex_relation',
'latex_comments',
'latex_mime',
':group:end',
':group:' . __('Data'),
'latex_columns',
'latex_data_caption',
'latex_data_continued_caption',
'latex_data_label',
'latex_null'));
$forms['Export']['Microsoft_Office'] = array('Export' => array(
':group:' . __('Excel 97-2003 XLS Workbook'),
'xls_null',
'xls_columns',
':group:end',
':group:' . __('Excel 2007 XLSX Workbook'),
'xlsx_null',
'xlsx_columns',
':group:end',
':group:' . __('Microsoft Word 2000'),
'htmlword_structure_or_data',
'htmlword_null',
'htmlword_columns'));
$forms['Export']['Open_Document'] = array('Export' => array(
':group:' . __('Open Document Spreadsheet'),
'ods_columns',
'ods_null',
':group:end',
':group:' . __('Open Document Text'),
'odt_structure_or_data',
':group:' . __('Structure'),
'odt_relation',
'odt_comments',
'odt_mime',
':group:end',
':group:' . __('Data'),
'odt_columns',
'odt_null'));
$forms['Export']['Texy'] = array('Export' => array(
'texytext_structure_or_data',
':group:' . __('Data'),
'texytext_null',
'texytext_columns'));
?>

View File

@@ -0,0 +1,268 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* List of avaible forms, each form is described as an array of fields to display.
* Fields MUST have their counterparts in the $cfg array.
*
* To define form field, use the notatnion below:
* $forms['Form group']['Form name'] = array('Option/path');
*
* You can assign default values set by special button ("set value: ..."), eg.:
* 'Servers/1/pmadb' => 'phpmyadmin'
*
* To group options, use:
* ':group:' . __('group name') // just define a group
* or
* 'option' => ':group' // group starting from this option
* End group blocks with:
* ':group:end'
*
* @package phpMyAdmin
*/
$forms = array();
$forms['Features']['General'] = array(
'NaturalOrder',
'InitialSlidersState',
'ErrorIconic',
'ReplaceHelpImg',
'Servers/1/only_db', // saves to Server/only_db
'Servers/1/hide_db', // saves to Server/hide_db
'SkipLockedTables',
'MaxDbList',
'MaxTableList');
$forms['Features']['Text_fields'] = array(
'CharEditing',
'CharTextareaCols',
'CharTextareaRows',
'TextareaCols',
'TextareaRows',
'LongtextDoubleTextarea');
$forms['Features']['Page_titles'] = array(
'TitleDefault',
'TitleTable',
'TitleDatabase',
'TitleServer');
$forms['Features']['Warnings'] = array(
'PmaNoRelation_DisableWarning',
'SuhosinDisableWarning',
'McryptDisableWarning');
// settings from this form are treated specially, see prefs_forms.php and user_preferences.lib.php
$forms['Features']['Developer'] = array(
'Error_Handler/display',
'Error_Handler/gather',
'DBG/sql',
'DBG/php');
$forms['Sql_queries']['Sql_queries'] = array(
'ShowSQL',
'Confirm',
'QueryHistoryMax',
'IgnoreMultiSubmitErrors',
'VerboseMultiSubmit',
'MaxCharactersInDisplayedSQL',
'EditInWindow',
//'QueryWindowWidth', // overridden in theme
//'QueryWindowHeight',
'QueryWindowDefTab');
$forms['Sql_queries']['Sql_box'] = array(
'SQLQuery/Edit',
'SQLQuery/Explain',
'SQLQuery/ShowAsPHP',
'SQLQuery/Validate',
'SQLQuery/Refresh');
$forms['Left_frame']['Left_frame'] = array(
'LeftFrameLight',
'LeftDisplayLogo',
'LeftLogoLink',
'LeftLogoLinkWindow',
'LeftPointerEnable');
$forms['Left_frame']['Left_databases'] = array(
'DisplayDatabasesList',
'LeftFrameDBTree',
'LeftFrameDBSeparator',
'ShowTooltipAliasDB');
$forms['Left_frame']['Left_tables'] = array(
'LeftDefaultTabTable',
'LeftFrameTableSeparator',
'LeftFrameTableLevel',
'ShowTooltip',
'ShowTooltipAliasTB');
$forms['Main_frame']['Startup'] = array(
'MainPageIconic',
'ShowCreateDb' => ':group',
'SuggestDBName',
':group:end',
'ShowStats',
'ShowServerInfo');
$forms['Main_frame']['Browse'] = array(
'NavigationBarIconic',
'ShowAll',
'MaxRows',
'Order',
'DisplayBinaryAsHex',
'BrowsePointerEnable',
'BrowseMarkerEnable',
'RepeatCells',
'LimitChars',
'ModifyDeleteAtLeft',
'ModifyDeleteAtRight',
'DefaultDisplay');
$forms['Main_frame']['Edit'] = array(
'ProtectBinary',
'ShowFunctionFields',
'ShowFieldTypesInDataEditView',
'InsertRows',
'ForeignKeyDropdownOrder',
'ForeignKeyMaxLimit',
'CtrlArrowsMoving',
'DefaultPropDisplay');
$forms['Main_frame']['Tabs'] = array(
'LightTabs',
'PropertiesIconic',
'DefaultTabServer',
'DefaultTabDatabase',
'DefaultTabTable');
$forms['Import']['Import_defaults'] = array(
'Import/format',
'Import/charset',
'Import/allow_interrupt',
'Import/skip_queries');
$forms['Import']['Sql'] = array(
'Import/sql_compatibility',
'Import/sql_no_auto_value_on_zero');
$forms['Import']['Csv'] = array(
':group:' . __('CSV'),
'Import/csv_replace',
'Import/csv_ignore',
'Import/csv_terminated',
'Import/csv_enclosed',
'Import/csv_escaped',
'Import/csv_col_names',
':group:end',
':group:' . __('CSV using LOAD DATA'),
'Import/ldi_replace',
'Import/ldi_ignore',
'Import/ldi_terminated',
'Import/ldi_enclosed',
'Import/ldi_escaped',
'Import/ldi_local_option');
$forms['Import']['Microsoft_Office'] = array(
':group:' . __('Excel 97-2003 XLS Workbook'),
'Import/xls_col_names',
':group:end',
':group:' . __('Excel 2007 XLSX Workbook'),
'Import/xlsx_col_names');
$forms['Import']['Open_Document'] = array(
':group:' . __('Open Document Spreadsheet'),
'Import/ods_col_names',
'Import/ods_empty_rows',
'Import/ods_recognize_percentages',
'Import/ods_recognize_currency');
$forms['Export']['Export_defaults'] = array(
'Export/method',
'Export/format',
'Export/compression',
'Export/charset',
'Export/asfile',
'Export/remember_file_template',
'Export/file_template_table',
'Export/file_template_database',
'Export/file_template_server');
$forms['Export']['Sql'] = array(
'Export/sql_include_comments' => ':group',
'Export/sql_dates',
'Export/sql_relation',
'Export/sql_mime',
':group:end',
'Export/sql_use_transaction',
'Export/sql_disable_fk',
'Export/sql_compatibility',
':group:' . __('Database export options'),
'Export/sql_drop_database',
'Export/sql_structure_or_data',
':group:end',
':group:' . __('Structure'),
'Export/sql_drop_table',
'Export/sql_procedure_function',
'Export/sql_create_table_statements' => ':group',
'Export/sql_if_not_exists',
'Export/sql_auto_increment',
':group:end',
'Export/sql_backquotes',
':group:end',
':group:' . __('Data'),
'Export/sql_delayed',
'Export/sql_ignore',
'Export/sql_type',
'Export/sql_insert_syntax',
'Export/sql_max_query_size',
'Export/sql_hex_for_blob',
'Export/sql_utc_time');
$forms['Export']['CodeGen'] = array(
'Export/codegen_format');
$forms['Export']['Csv'] = array(
':group:' . __('CSV'),
'Export/csv_separator',
'Export/csv_enclosed',
'Export/csv_escaped',
'Export/csv_terminated',
'Export/csv_null',
'Export/csv_removeCRLF',
'Export/csv_columns',
':group:end',
':group:' . __('CSV for MS Excel'),
'Export/excel_null',
'Export/excel_removeCRLF',
'Export/excel_columns',
'Export/excel_edition');
$forms['Export']['Latex'] = array(
'Export/latex_caption',
'Export/latex_structure_or_data',
':group:' . __('Structure'),
'Export/latex_structure_caption',
'Export/latex_structure_continued_caption',
'Export/latex_structure_label',
'Export/latex_relation',
'Export/latex_comments',
'Export/latex_mime',
':group:end',
':group:' . __('Data'),
'Export/latex_columns',
'Export/latex_data_caption',
'Export/latex_data_continued_caption',
'Export/latex_data_label',
'Export/latex_null');
$forms['Export']['Microsoft_Office'] = array(
':group:' . __('Excel 97-2003 XLS Workbook'),
'Export/xls_null',
'Export/xls_columns',
':group:end',
':group:' . __('Excel 2007 XLSX Workbook'),
'Export/xlsx_null',
'Export/xlsx_columns',
':group:end',
':group:' . __('Microsoft Word 2000'),
'Export/htmlword_structure_or_data',
'Export/htmlword_null',
'Export/htmlword_columns');
$forms['Export']['Open_Document'] = array(
':group:' . __('Open Document Spreadsheet'),
'Export/ods_columns',
'Export/ods_null',
':group:end',
':group:' . __('Open Document Text'),
'Export/odt_structure_or_data',
':group:' . __('Structure'),
'Export/odt_relation',
'Export/odt_comments',
'Export/odt_mime',
':group:end',
':group:' . __('Data'),
'Export/odt_columns',
'Export/odt_null');
$forms['Export']['Texy'] = array(
'Export/texytext_structure_or_data',
':group:' . __('Data'),
'Export/texytext_null',
'Export/texytext_columns');
?>

View File

@@ -1,4 +1,5 @@
<?php <?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/** /**
* Various validation functions * Various validation functions
* *
@@ -9,13 +10,48 @@
* assigned to a form element (formset name or field path). Even if there are * assigned to a form element (formset name or field path). Even if there are
* no errors, key must be set with an empty value. * no errors, key must be set with an empty value.
* *
* Valdiation functions are assigned in $cfg_db['_validators'] (config_info.inc.php). * Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
* *
* @package phpMyAdmin-setup * @package phpMyAdmin
* @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
* @version $Id$
*/ */
/**
* Returns validator list
*
* @uses ConfigFile::getDbEntry()
* @uses ConfigFile::getInstance()
* @return array
*/
function PMA_config_get_validators()
{
static $validators = null;
if ($validators === null) {
$cf = ConfigFile::getInstance();
$validators = $cf->getDbEntry('_validators', array());
if (!defined('PMA_SETUP') || !PMA_SETUP) {
$uvs = $cf->getDbEntry('_userValidators', array());
foreach ($uvs as $field => $uv_list) {
$uv_list = (array)$uv_list;
foreach ($uv_list as &$uv) {
if (!is_array($uv)) {
continue;
}
for ($i = 1; $i < count($uv); $i++) {
if (substr($uv[$i], 0, 6) == 'value:') {
$uv[$i] = PMA_array_read(substr($uv[$i], 6), $GLOBALS['cfg']);
}
}
}
$validators[$field] = isset($validators[$field])
? array_merge((array)$validators[$field], $uv_list)
: $uv_list;
}
}
}
return $validators;
}
/** /**
* Runs validation $validator_id on values $values and returns error list. * Runs validation $validator_id on values $values and returns error list.
* *
@@ -25,18 +61,21 @@
* cleanup in HTML documen * cleanup in HTML documen
* o false - when no validators match name(s) given by $validator_id * o false - when no validators match name(s) given by $validator_id
* *
* @uses ConfigFile::getCanonicalPath()
* @uses ConfigFile::getInstance()
* @uses PMA_config_get_validators()
* @param string|array $validator_id * @param string|array $validator_id
* @param array $values * @param array $values
* @param bool $isPostSource tells whether $values are directly from POST request * @param bool $isPostSource tells whether $values are directly from POST request
* @return bool|array * @return bool|array
*/ */
function validate($validator_id, &$values, $isPostSource) function PMA_config_validate($validator_id, &$values, $isPostSource)
{ {
// find validators // find validators
$cf = ConfigFile::getInstance();
$validator_id = (array) $validator_id; $validator_id = (array) $validator_id;
$validators = $cf->getDbEntry('_validators'); $validators = PMA_config_get_validators();
$vids = array(); $vids = array();
$cf = ConfigFile::getInstance();
foreach ($validator_id as &$vid) { foreach ($validator_id as &$vid) {
$vid = $cf->getCanonicalPath($vid); $vid = $cf->getCanonicalPath($vid);
if (isset($validators[$vid])) { if (isset($validators[$vid])) {
@@ -60,18 +99,25 @@ function validate($validator_id, &$values, $isPostSource)
// validate // validate
$result = array(); $result = array();
foreach ($vids as $vid) { foreach ($vids as $vid) {
$r = call_user_func($validators[$vid], $vid, $arguments); // call appropriate validation functions
// merge results foreach ((array)$validators[$vid] as $validator) {
if (is_array($r)) { $vdef = (array) $validator;
foreach ($r as $key => $error_list) { $vname = array_shift($vdef);
// skip empty values if $isPostSource is false $args = array_merge(array($vid, &$arguments), $vdef);
if (!$isPostSource && empty($error_list)) { $r = call_user_func_array($vname, $args);
continue;
// merge results
if (is_array($r)) {
foreach ($r as $key => $error_list) {
// skip empty values if $isPostSource is false
if (!$isPostSource && empty($error_list)) {
continue;
}
if (!isset($result[$key])) {
$result[$key] = array();
}
$result[$key] = array_merge($result[$key], (array)$error_list);
} }
if (!isset($result[$key])) {
$result[$key] = array();
}
$result[$key] = array_merge($result[$key], (array)$error_list);
} }
} }
} }
@@ -85,6 +131,16 @@ function validate($validator_id, &$values, $isPostSource)
return empty($new_result) ? true : $new_result; return empty($new_result) ? true : $new_result;
} }
/**
* Empty error handler, used to temporarily restore PHP internal error handler
*
* @return bool
*/
function PMA_null_error_handler()
{
return false;
}
/** /**
* Ensures that $php_errormsg variable will be registered in case of an error * Ensures that $php_errormsg variable will be registered in case of an error
* and enables output buffering (when $start = true). * and enables output buffering (when $start = true).
@@ -95,17 +151,25 @@ function validate($validator_id, &$values, $isPostSource)
*/ */
function test_php_errormsg($start = true) function test_php_errormsg($start = true)
{ {
static $old_html_errors, $old_track_errors; static $old_html_errors, $old_track_errors, $old_error_reporting;
static $old_display_errors;
if ($start) { if ($start) {
$old_html_errors = ini_get('html_errors'); $old_html_errors = ini_get('html_errors');
$old_track_errors = ini_get('track_errors'); $old_track_errors = ini_get('track_errors');
$old_display_errors = ini_get('display_errors');
$old_error_reporting = error_reporting(E_ALL);
ini_set('html_errors', false); ini_set('html_errors', false);
ini_set('track_errors', true); ini_set('track_errors', true);
ini_set('display_errors', true);
set_error_handler("PMA_null_error_handler");
ob_start(); ob_start();
} else { } else {
ob_end_clean(); ob_end_clean();
restore_error_handler();
error_reporting($old_error_reporting);
ini_set('html_errors', $old_html_errors); ini_set('html_errors', $old_html_errors);
ini_set('track_errors', $old_track_errors); ini_set('track_errors', $old_track_errors);
ini_set('display_errors', $old_display_errors);
} }
} }
@@ -131,14 +195,14 @@ function test_db_connection($extension, $connect_type, $host, $port, $socket, $u
if ($extension == 'mysql') { if ($extension == 'mysql') {
$conn = @mysql_connect($host . $socket . $port, $user, $pass); $conn = @mysql_connect($host . $socket . $port, $user, $pass);
if (!$conn) { if (!$conn) {
$error = PMA_lang('error_connection'); $error = __('Could not connect to MySQL server');
} else { } else {
mysql_close($conn); mysql_close($conn);
} }
} else { } else {
$conn = @mysqli_connect($host, $user, $pass, null, $port, $socket); $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
if (!$conn) { if (!$conn) {
$error = PMA_lang('error_connection'); $error = __('Could not connect to MySQL server');
} else { } else {
mysqli_close($conn); mysqli_close($conn);
} }
@@ -153,6 +217,7 @@ function test_db_connection($extension, $connect_type, $host, $port, $socket, $u
/** /**
* Validate server config * Validate server config
* *
* @uses test_db_connection()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
@@ -162,15 +227,15 @@ function validate_server($path, $values)
$result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => ''); $result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => '');
$error = false; $error = false;
if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) { if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) {
$result['Servers/1/user'] = PMA_lang('error_empty_user_for_config_auth'); $result['Servers/1/user'] = __('Empty username while using config authentication method');
$error = true; $error = true;
} }
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) { if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) {
$result['Servers/1/SignonSession'] = PMA_lang('error_empty_signon_session'); $result['Servers/1/SignonSession'] = __('Empty signon session name while using signon authentication method');
$error = true; $error = true;
} }
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) { if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) {
$result['Servers/1/SignonURL'] = PMA_lang('error_empty_signon_url'); $result['Servers/1/SignonURL'] = __('Empty signon URL while using signon authentication method');
$error = true; $error = true;
} }
@@ -187,13 +252,14 @@ function validate_server($path, $values)
/** /**
* Validate pmadb config * Validate pmadb config
* *
* @uses test_db_connection()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
*/ */
function validate_pmadb($path, $values) function validate_pmadb($path, $values)
{ {
$tables = array('Servers/1/bookmarktable', 'Servers/1/relation', 'Servers/1/table_info', 'Servers/1/table_coords', 'Servers/1/pdf_pages', 'Servers/1/column_info', 'Servers/1/history', 'Servers/1/designer_coords'); //$tables = array('Servers/1/bookmarktable', 'Servers/1/relation', 'Servers/1/table_info', 'Servers/1/table_coords', 'Servers/1/pdf_pages', 'Servers/1/column_info', 'Servers/1/history', 'Servers/1/designer_coords');
$result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => ''); $result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => '');
$error = false; $error = false;
@@ -203,15 +269,17 @@ function validate_pmadb($path, $values)
$result = array(); $result = array();
if ($values['Servers/1/controluser'] == '') { if ($values['Servers/1/controluser'] == '') {
$result['Servers/1/controluser'] = PMA_lang('error_empty_pmadb_user'); $result['Servers/1/controluser'] = __('Empty phpMyAdmin control user while using pmadb');
$error = true; $error = true;
} }
if ($values['Servers/1/controlpass'] == '') { if ($values['Servers/1/controlpass'] == '') {
$result['Servers/1/controlpass'] = PMA_lang('error_empty_pmadb_password'); $result['Servers/1/controlpass'] = __('Empty phpMyAdmin control user password while using pmadb');
$error = true; $error = true;
} }
if (!$error) { if (!$error) {
$test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'], $values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'], $values['Servers/1/controluser'], $values['Servers/1/controlpass'], 'Server_pmadb'); $test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'],
$values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'],
$values['Servers/1/controluser'], $values['Servers/1/controlpass'], 'Server_pmadb');
if ($test !== true) { if ($test !== true) {
$result = array_merge($result, $test); $result = array_merge($result, $test);
} }
@@ -223,6 +291,7 @@ function validate_pmadb($path, $values)
/** /**
* Validates regular expression * Validates regular expression
* *
* @uses test_php_errormsg()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
@@ -239,7 +308,6 @@ function validate_regex($path, $values)
$matches = array(); $matches = array();
preg_match($values[$path], '', $matches); preg_match($values[$path], '', $matches);
ob_end_clean();
test_php_errormsg(false); test_php_errormsg(false);
@@ -283,14 +351,14 @@ function validate_trusted_proxies($path, $values)
$matches = array(); $matches = array();
// we catch anything that may (or may not) be an IP // we catch anything that may (or may not) be an IP
if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) { if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
$result[$path][] = PMA_lang('error_incorrect_value') . ': ' . $line; $result[$path][] = __('Incorrect value') . ': ' . $line;
continue; continue;
} }
// now let's check whether we really have an IP address // now let's check whether we really have an IP address
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
&& filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) { && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$ip = htmlspecialchars(trim($matches[1])); $ip = htmlspecialchars(trim($matches[1]));
$result[$path][] = PMA_lang('error_incorrect_ip_address', $ip); $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
continue; continue;
} }
} }
@@ -298,7 +366,6 @@ function validate_trusted_proxies($path, $values)
return $result; return $result;
} }
/** /**
* Tests integer value * Tests integer value
* *
@@ -307,17 +374,17 @@ function validate_trusted_proxies($path, $values)
* @param bool $allow_neg allow negative values * @param bool $allow_neg allow negative values
* @param bool $allow_zero allow zero * @param bool $allow_zero allow zero
* @param int $max_value max allowed value * @param int $max_value max allowed value
* @param string $error_lang_key error message key: $GLOBALS["strSetup$error_lang_key"] * @param string $error_string error message key: $GLOBALS["strConfig$error_lang_key"]
* @return string empty string if test is successful * @return string empty string if test is successful
*/ */
function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_lang_key) function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_string)
{ {
if ($values[$path] === '') { if ($values[$path] === '') {
return ''; return '';
} }
if (intval($values[$path]) != $values[$path] || (!$allow_neg && $values[$path] < 0) || (!$allow_zero && $values[$path] == 0) || $values[$path] > $max_value) { if (intval($values[$path]) != $values[$path] || (!$allow_neg && $values[$path] < 0) || (!$allow_zero && $values[$path] == 0) || $values[$path] > $max_value) {
return PMA_lang($error_lang_key); return $error_string;
} }
return ''; return '';
@@ -326,36 +393,68 @@ function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error
/** /**
* Validates port number * Validates port number
* *
* @uses test_number()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
*/ */
function validate_port_number($path, $values) function validate_port_number($path, $values)
{ {
return array($path => test_number($path, $values, false, false, 65536, 'error_incorrect_port')); return array($path => test_number($path, $values, false, false, 65535, __('Not a valid port number')));
} }
/** /**
* Validates positive number * Validates positive number
* *
* @uses test_number()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
*/ */
function validate_positive_number($path, $values) function validate_positive_number($path, $values)
{ {
return array($path => test_number($path, $values, false, false, PHP_INT_MAX, 'error_nan_p')); return array($path => test_number($path, $values, false, false, PHP_INT_MAX, __('Not a positive number')));
} }
/** /**
* Validates non-negative number * Validates non-negative number
* *
* @uses test_number()
* @param string $path * @param string $path
* @param array $values * @param array $values
* @return array * @return array
*/ */
function validate_non_negative_number($path, $values) function validate_non_negative_number($path, $values)
{ {
return array($path => test_number($path, $values, false, true, PHP_INT_MAX, 'error_nan_nneg')); return array($path => test_number($path, $values, false, true, PHP_INT_MAX, __('Not a non-negative number')));
} }
?>
/**
* Validates value according to given regular expression
* Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
*
* @param string $path
* @param array $values
* @param string $regex
* @return void
*/
function validate_by_regex($path, $values, $regex)
{
$result = preg_match($regex, $values[$path]);
return array($path => ($result ? '' : __('Incorrect value')));
}
/**
* Validates upper bound for numeric inputs
*
* @param string $path
* @param array $values
* @param int $max_value
* @return array
*/
function validate_upper_bound($path, $values, $max_value)
{
$result = $values[$path] <= $max_value;
return array($path => ($result ? '' : sprintf(__('Value must be equal or lower than %s'), $max_value)));
}
?>

View File

@@ -574,4 +574,89 @@ function PMA_sendHeaderLocation($uri)
} }
} }
} }
/**
* Returns value of an element in $array given by $path.
* $path is a string describing position of an element in an associative array,
* eg. Servers/1/host refers to $array[Servers][1][host]
*
* @param string $path
* @param array $array
* @param mixed $default
* @return mixed array element or $default
*/
function PMA_array_read($path, $array, $default = null)
{
$keys = explode('/', $path);
$value =& $array;
foreach ($keys as $key) {
if (!isset($value[$key])) {
return $default;
}
$value =& $value[$key];
}
return $value;
}
/**
* Stores value in an array
*
* @param string $path
* @param array &$array
* @param mixed $value
*/
function PMA_array_write($path, &$array, $value)
{
$keys = explode('/', $path);
$last_key = array_pop($keys);
$a =& $array;
foreach ($keys as $key) {
if (!isset($a[$key])) {
$a[$key] = array();
}
$a =& $a[$key];
}
$a[$last_key] = $value;
}
/**
* Removes value from an array
*
* @param string $path
* @param array &$array
* @param mixed $value
*/
function PMA_array_remove($path, &$array)
{
$keys = explode('/', $path);
$keys_last = array_pop($keys);
$path = array();
$depth = 0;
$path[0] =& $array;
$found = true;
// go as deep as required or possible
foreach ($keys as $key) {
if (!isset($path[$depth][$key])) {
$found = false;
break;
}
$depth++;
$path[$depth] =& $path[$depth-1][$key];
}
// if element found, remove it
if ($found) {
unset($path[$depth][$keys_last]);
$depth--;
}
// remove empty nested arrays
for (; $depth >= 0; $depth--) {
if (!isset($path[$depth+1]) || count($path[$depth+1]) == 0) {
unset($path[$depth][$keys[$depth]]);
} else {
break;
}
}
}
?> ?>

View File

@@ -102,21 +102,23 @@ $tabs = array();
$tabs[] =& $tab_structure; $tabs[] =& $tab_structure;
$tabs[] =& $tab_sql; $tabs[] =& $tab_sql;
$tabs[] =& $tab_search; $tabs[] =& $tab_search;
if (PMA_Tracker::isActive()) {
$tabs[] =& $tab_tracking;
}
$tabs[] =& $tab_qbe; $tabs[] =& $tab_qbe;
$tabs[] =& $tab_export; $tabs[] =& $tab_export;
if (! $db_is_information_schema) { if (! $db_is_information_schema) {
$tabs[] =& $tab_import; $tabs[] =& $tab_import;
if ($cfgRelation['designerwork']) {
$tabs[] =& $tab_designer;
}
$tabs[] =& $tab_operation; $tabs[] =& $tab_operation;
if ($is_superuser) { if ($is_superuser) {
$tabs[] =& $tab_privileges; $tabs[] =& $tab_privileges;
} }
} }
if (PMA_Tracker::isActive()) {
$tabs[] =& $tab_tracking;
}
if (! $db_is_information_schema) {
if ($cfgRelation['designerwork']) {
$tabs[] =& $tab_designer;
}
}
$url_params['db'] = $db; $url_params['db'] = $db;

View File

@@ -317,6 +317,12 @@ function PMA_DBI_get_client_info()
function PMA_DBI_getError($link = null) function PMA_DBI_getError($link = null)
{ {
$GLOBALS['errno'] = 0; $GLOBALS['errno'] = 0;
/* Treat false same as null because of controllink */
if ($link === false) {
$link = null;
}
if (null === $link && isset($GLOBALS['userlink'])) { if (null === $link && isset($GLOBALS['userlink'])) {
$link =& $GLOBALS['userlink']; $link =& $GLOBALS['userlink'];

View File

@@ -374,6 +374,11 @@ function PMA_DBI_getError($link = null)
{ {
$GLOBALS['errno'] = 0; $GLOBALS['errno'] = 0;
/* Treat false same as null because of controllink */
if ($link === false) {
$link = null;
}
if (null === $link && isset($GLOBALS['userlink'])) { if (null === $link && isset($GLOBALS['userlink'])) {
$link =& $GLOBALS['userlink']; $link =& $GLOBALS['userlink'];
// Do not stop now. We still can get the error code // Do not stop now. We still can get the error code

View File

@@ -69,7 +69,7 @@ if(isset($_GET['export_method'])) {
$cfg['Export']['method'] = 'quick'; $cfg['Export']['method'] = 'quick';
} }
// The export method (quick, custom or custom-no-form) // The export method (quick, custom or custom-no-form)
echo '<input type="hidden" name="export_method" value="' . $cfg['Export']['method'] . '" />'; echo '<input type="hidden" name="export_method" value="' . htmlspecialchars($cfg['Export']['method']) . '" />';
if(isset($_GET['sql_query'])) { if(isset($_GET['sql_query'])) {
@@ -226,14 +226,11 @@ if(isset($_GET['sql_query'])) {
<?php <?php
echo __('File name template:'); echo __('File name template:');
$trans = new PMA_Message; $trans = new PMA_Message;
$trans->addMessage('@SERVER@ will become the'); $trans->addMessage(__('@SERVER@ will become the server name'));
$trans->addString(__('server name'));
if ($export_type == 'database' || $export_type == 'table') { if ($export_type == 'database' || $export_type == 'table') {
$trans->addMessage(', @DB@ will become the'); $trans->addMessage(__(', @DATABASE@ will become the database name'));
$trans->addString(__('database name'));
if ($export_type == 'table') { if ($export_type == 'table') {
$trans->addMessage(', @TABLE@ will become the'); $trans->addMessage(__(', @TABLE@ will become the table name'));
$trans->addString(__('table name'));
} }
} }
@@ -255,23 +252,17 @@ if(isset($_GET['sql_query'])) {
echo $_GET['filename_template']; echo $_GET['filename_template'];
} else { } else {
if ($export_type == 'database') { if ($export_type == 'database') {
if (isset($_COOKIE) && !empty($_COOKIE['pma_db_filename_template'])) { echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
echo htmlspecialchars($_COOKIE['pma_db_filename_template']); 'pma_db_filename_template',
} else { $GLOBALS['cfg']['Export']['file_template_database']));
echo $GLOBALS['cfg']['Export']['file_template_database'];
}
} elseif ($export_type == 'table') { } elseif ($export_type == 'table') {
if (isset($_COOKIE) && !empty($_COOKIE['pma_table_filename_template'])) { echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
echo htmlspecialchars($_COOKIE['pma_table_filename_template']); 'pma_table_filename_template',
} else { $GLOBALS['cfg']['Export']['file_template_table']));
echo $GLOBALS['cfg']['Export']['file_template_table'];
}
} else { } else {
if (isset($_COOKIE) && !empty($_COOKIE['pma_server_filename_template'])) { echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
echo htmlspecialchars($_COOKIE['pma_server_filename_template']); 'pma_server_filename_template',
} else { $GLOBALS['cfg']['Export']['file_template_server']));
echo $GLOBALS['cfg']['Export']['file_template_server'];
}
} }
} }
echo '"'; echo '"';

View File

@@ -1,71 +0,0 @@
<!-- PDF schema -->
<form method="post" action="pdf_schema.php">
<fieldset>
<legend>
<?php
echo PMA_generate_common_hidden_inputs($db);
if ($cfg['PropertiesIconic']) {
echo '<img class="icon" src="' . $pmaThemeImage . 'b_view.png"'
.' alt="" width="16" height="16" />';
}
echo __('Display PDF schema');
?>:
</legend>
<?php
if (isset($test_rs)) {
?>
<label for="pdf_page_number_opt"><?php echo __('Page number:'); ?></label>
<select name="pdf_page_number" id="pdf_page_number_opt">
<?php
while ($pages = @PMA_DBI_fetch_assoc($test_rs)) {
echo ' <option value="' . $pages['page_nr'] . '">'
. $pages['page_nr'] . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
} // end while
PMA_DBI_free_result($test_rs);
unset($test_rs);
?>
</select><br />
<?php } else { ?>
<input type="hidden" name="pdf_page_number" value="<?php echo htmlspecialchars($chpage); ?>" />
<?php } ?>
<input type="checkbox" name="show_grid" id="show_grid_opt" />
<label for="show_grid_opt"><?php echo __('Show grid'); ?></label><br />
<input type="checkbox" name="show_color" id="show_color_opt"
checked="checked" />
<label for="show_color_opt"><?php echo __('Show color'); ?></label><br />
<input type="checkbox" name="show_table_dimension" id="show_table_dim_opt" />
<label for="show_table_dim_opt"><?php echo __('Show dimension of tables'); ?>
</label><br />
<input type="checkbox" name="all_tab_same_wide" id="all_tab_same_wide" />
<label for="all_tab_same_wide"><?php echo __('Display all tables with the same width'); ?>
</label><br />
<input type="checkbox" name="with_doc" id="with_doc" checked="checked" />
<label for="with_doc"><?php echo __('Data Dictionary'); ?></label><br />
<input type="checkbox" name="show_keys" id="show_keys" />
<label for="show_keys"><?php echo __('Only show keys'); ?></label><br />
<label for="orientation_opt"><?php echo __('Data Dictionary Format'); ?></label>
<select name="orientation" id="orientation_opt">
<option value="L"><?php echo __('Landscape');?></option>
<option value="P"><?php echo __('Portrait');?></option>
</select><br />
<label for="paper_opt"><?php echo __('Paper size'); ?></label>
<select name="paper" id="paper_opt">
<?php
foreach ($cfg['PDFPageSizes'] AS $key => $val) {
echo '<option value="' . $val . '"';
if ($val == $cfg['PDFDefaultPageSize']) {
echo ' selected="selected"';
}
echo ' >' . $val . '</option>' . "\n";
}
?>
</select>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" />
</fieldset>
</form>

View File

@@ -2227,6 +2227,12 @@ function PMA_displayResultsOperations($the_disp_mode, $analyzed_sql) {
'tbl_export.php' . PMA_generate_common_url($_url_params), 'tbl_export.php' . PMA_generate_common_url($_url_params),
PMA_getIcon('b_tblexport.png', __('Export'), false, true), PMA_getIcon('b_tblexport.png', __('Export'), false, true),
'', true, true, '') . "\n"; '', true, true, '') . "\n";
// show chart
echo PMA_linkOrButton(
'tbl_chart.php' . PMA_generate_common_url($_url_params),
PMA_getIcon('b_chart.png', __('Display chart'), false, true),
'', true, true, '') . "\n";
} }
// CREATE VIEW // CREATE VIEW

View File

@@ -109,7 +109,7 @@ if (isset($plugin_list)) {
/* begin CREATE TABLE statements*/ /* begin CREATE TABLE statements*/
$plugin_list['sql']['options'][] = $plugin_list['sql']['options'][] =
array('type' => 'begin_subgroup', 'subgroup_header' => array('type' => 'bool', 'name' => 'create_table_statements', 'text' => __('<code>CREATE TABLE</code> options:'))); array('type' => 'begin_subgroup', 'subgroup_header' => array('type' => 'bool', 'name' => 'create_table_statements', 'text' => __('<code>CREATE TABLE</code> options:')));
$plugin_list['sql']['options'][] = $plugin_list['sql']['options'][] =
array('type' => 'bool', 'name' => 'if_not_exists', 'text' => '<code>IF NOT EXISTS</code>'); array('type' => 'bool', 'name' => 'if_not_exists', 'text' => '<code>IF NOT EXISTS</code>');
$plugin_list['sql']['options'][] = $plugin_list['sql']['options'][] =
array('type' => 'bool', 'name' => 'auto_increment', 'text' => '<code>AUTO_INCREMENT</code>'); array('type' => 'bool', 'name' => 'auto_increment', 'text' => '<code>AUTO_INCREMENT</code>');

View File

@@ -115,7 +115,15 @@ if (window.parent.refreshNavigation) {
window.parent.refreshNavigation(); window.parent.refreshNavigation();
} }
<?php <?php
} else if (isset($_GET['reload_left_frame']) && $_GET['reload_left_frame'] == '1') {
// reload left frame (used by user preferences)
?>
if (window.parent && window.parent.frame_navigation) {
window.parent.frame_navigation.location.reload();
}
<?php
} }
?> ?>
// set current db, table and sql query in the querywindow // set current db, table and sql query in the querywindow
if (window.parent.reload_querywindow) { if (window.parent.reload_querywindow) {

View File

@@ -13,10 +13,12 @@ if (! defined('PHPMYADMIN')) {
*/ */
require_once './libraries/common.inc.php'; require_once './libraries/common.inc.php';
/** /**
* If this is an Ajax request, we do not need to generate all this output. * If this is an Ajax request, we do not need to generate all this output.
*/ */
if (!$GLOBALS['is_ajax_request']) { if (!$GLOBALS['is_ajax_request']) {
if (empty($GLOBALS['is_header_sent'])) { if (empty($GLOBALS['is_header_sent'])) {
/** /**
@@ -25,6 +27,14 @@ if (!$GLOBALS['is_ajax_request']) {
require_once './libraries/ob.lib.php'; require_once './libraries/ob.lib.php';
PMA_outBufferPre(); PMA_outBufferPre();
// if database storage for user preferences is transient, offer to load
// exported settings from localStorage (detection will be done in JavaScript)
$userprefs_offer_import = $GLOBALS['PMA_Config']->get('user_preferences') == 'session'
&& !isset($_SESSION['userprefs_autoload']);
if ($userprefs_offer_import) {
$GLOBALS['js_include'][] = 'config.js';
}
// For re-usability, moved http-headers and stylesheets // For re-usability, moved http-headers and stylesheets
// to a seperate file. It can now be included by header.inc.php, // to a seperate file. It can now be included by header.inc.php,
// querywindow.php. // querywindow.php.
@@ -62,6 +72,12 @@ if (!$GLOBALS['is_ajax_request']) {
PMA_Message::notice(__('Cookies must be enabled past this point.'))->display(); PMA_Message::notice(__('Cookies must be enabled past this point.'))->display();
} }
// offer to load user preferences from localStorage
if ($userprefs_offer_import) {
require_once './libraries/user_preferences.lib.php';
PMA_userprefs_autoload_header();
}
if (!defined('PMA_DISPLAY_HEADING')) { if (!defined('PMA_DISPLAY_HEADING')) {
define('PMA_DISPLAY_HEADING', 1); define('PMA_DISPLAY_HEADING', 1);
} }
@@ -86,81 +102,80 @@ if (!$GLOBALS['is_ajax_request']) {
$separator = ' <span class="separator"> - </span>' . "\n"; $separator = ' <span class="separator"> - </span>' . "\n";
} }
if ($GLOBALS['cfg']['NavigationBarIconic'] !== true) { if ($GLOBALS['cfg']['NavigationBarIconic'] !== true) {
$item .= '%4$s: '; $item .= '%4$s: ';
} }
$item .= '%3$s</a>' . "\n"; $item .= '%3$s</a>' . "\n";
echo '<div id="serverinfo">' . "\n"; echo '<div id="serverinfo">' . "\n";
printf($item,
$GLOBALS['cfg']['DefaultTabServer'],
PMA_generate_common_url(),
htmlspecialchars($server_info),
__('Server'),
's_host.png');
if (strlen($GLOBALS['db'])) {
echo $separator;
printf($item, printf($item,
$GLOBALS['cfg']['DefaultTabDatabase'], $GLOBALS['cfg']['DefaultTabServer'],
PMA_generate_common_url($GLOBALS['db']), PMA_generate_common_url(),
$GLOBALS['db'], htmlspecialchars($server_info),
'', __('Server'),
's_tbl.png'); 's_host.png');
// if the table is being dropped, $_REQUEST['purge'] is set
// (it always contains "1")
// so do not display the table name in upper div
} elseif (strlen($GLOBALS['table']) && ! (isset($_REQUEST['purge']))) {
require_once './libraries/tbl_info.inc.php';
echo $separator; if (strlen($GLOBALS['db'])) {
printf($item,
$GLOBALS['cfg']['DefaultTabTable'],
PMA_generate_common_url($GLOBALS['db'], $GLOBALS['table']),
str_replace(' ', '&nbsp;', htmlspecialchars($GLOBALS['table'])),
(isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view'] ? __('View') : __('Table')),
(isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view'] ? 'b_views' : 's_tbl') . '.png');
/** echo $separator;
* Displays table comment printf($item,
* @uses $show_comment from libraries/tbl_info.inc.php $GLOBALS['cfg']['DefaultTabDatabase'],
* @uses $GLOBALS['avoid_show_comment'] from tbl_relation.php PMA_generate_common_url($GLOBALS['db']),
*/ $GLOBALS['db'],
if (!empty($show_comment) && !isset($GLOBALS['avoid_show_comment'])) { '',
if (strstr($show_comment, '; InnoDB free')) { 's_tbl.png');
$show_comment = preg_replace('@; InnoDB free:.*?$@', '', $show_comment); // if the table is being dropped, $_REQUEST['purge'] is set
} // (it always contains "1")
echo '<span class="table_comment" id="span_table_comment">' // so do not display the table name in upper div
.'&quot;' . htmlspecialchars($show_comment) } elseif (strlen($GLOBALS['table']) && ! (isset($_REQUEST['purge']))) {
.'&quot;</span>' . "\n"; require_once './libraries/tbl_info.inc.php';
} // end if
} else { echo $separator;
// no table selected, display database comment if present printf($item,
/** $GLOBALS['cfg']['DefaultTabTable'],
* Settings for relations stuff PMA_generate_common_url($GLOBALS['db'], $GLOBALS['table']),
*/ str_replace(' ', '&nbsp;', htmlspecialchars($GLOBALS['table'])),
require_once './libraries/relation.lib.php'; (isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view'] ? __('View') : __('Table')),
$cfgRelation = PMA_getRelationsParam(); (isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view'] ? 'b_views' : 's_tbl') . '.png');
// Get additional information about tables for tooltip is done
// in libraries/db_info.inc.php only once
if ($cfgRelation['commwork']) {
$comment = PMA_getDbComment($GLOBALS['db']);
/** /**
* Displays table comment * Displays table comment
* @uses $show_comment from libraries/tbl_info.inc.php
* @uses $GLOBALS['avoid_show_comment'] from tbl_relation.php
*/ */
if (! empty($comment)) { if (!empty($show_comment) && !isset($GLOBALS['avoid_show_comment'])) {
echo '<span class="table_comment"' if (strstr($show_comment, '; InnoDB free')) {
. ' id="span_table_comment">&quot;' $show_comment = preg_replace('@; InnoDB free:.*?$@', '', $show_comment);
. htmlspecialchars($comment) }
. '&quot;</span>' . "\n"; echo '<span class="table_comment" id="span_table_comment">'
.'&quot;' . htmlspecialchars($show_comment)
.'&quot;</span>' . "\n";
} // end if } // end if
} else {
// no table selected, display database comment if present
/**
* Settings for relations stuff
*/
require_once './libraries/relation.lib.php';
$cfgRelation = PMA_getRelationsParam();
// Get additional information about tables for tooltip is done
// in libraries/db_info.inc.php only once
if ($cfgRelation['commwork']) {
$comment = PMA_getDbComment($GLOBALS['db']);
/**
* Displays table comment
*/
if (! empty($comment)) {
echo '<span class="table_comment"'
. ' id="span_table_comment">&quot;'
. htmlspecialchars($comment)
. '&quot;</span>' . "\n";
} // end if
}
} }
} }
}
echo '</div>'; echo '</div>';
} }
/** /**
* Sets a variable to remember headers have been sent * Sets a variable to remember headers have been sent

View File

@@ -53,7 +53,7 @@ if ($GLOBALS['text_dir'] == 'ltr') {
<?php <?php
} }
?> ?>
<link rel="stylesheet" type="text/css" href="<?php echo defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : ''; ?>phpmyadmin.css.php?<?php echo PMA_generate_common_url(); ?>&amp;js_frame=<?php echo isset($print_view) ? 'print' : 'right'; ?>&amp;nocache=<?php echo $GLOBALS['PMA_Config']->getThemeUniqueValue(); ?>" /> <link rel="stylesheet" type="text/css" href="<?php echo defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : ''; ?>phpmyadmin.css.php<?php echo PMA_generate_common_url(array('server' => $GLOBALS['server'])); ?>&amp;js_frame=<?php echo isset($print_view) ? 'print' : 'right'; ?>&amp;nocache=<?php echo $GLOBALS['PMA_Config']->getThemeUniqueValue(); ?>" />
<link rel="stylesheet" type="text/css" href="<?php echo defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : ''; ?>print.css" media="print" /> <link rel="stylesheet" type="text/css" href="<?php echo defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : ''; ?>print.css" media="print" />
<link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['pmaThemePath']; ?>/jquery/jquery-ui-1.8.custom.css" /> <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['pmaThemePath']; ?>/jquery/jquery-ui-1.8.custom.css" />
<meta name="robots" content="noindex,nofollow" /> <meta name="robots" content="noindex,nofollow" />

View File

@@ -59,7 +59,7 @@ foreach ($GLOBALS['js_include'] as $js_script_file) {
// Updates the title of the frameset if possible (ns4 does not allow this) // Updates the title of the frameset if possible (ns4 does not allow this)
if (typeof(parent.document) != 'undefined' && typeof(parent.document) != 'unknown' if (typeof(parent.document) != 'undefined' && typeof(parent.document) != 'unknown'
&& typeof(parent.document.title) == 'string') { && typeof(parent.document.title) == 'string') {
parent.document.title = '<?php echo PMA_sanitize(PMA_escapeJsString($title)); ?>'; parent.document.title = '<?php echo PMA_sanitize(PMA_escapeJsString(htmlspecialchars($title))); ?>';
} }
<?php <?php

View File

@@ -29,22 +29,26 @@ if ($GLOBALS['cfg']['LeftDisplayLogo']) {
.'alt="' . $logo . '" id="imgpmalogo" />'; .'alt="' . $logo . '" id="imgpmalogo" />';
} }
echo '<div id="pmalogo">' . "\n" echo '<div id="pmalogo">' . "\n";
.'<a href="' . $GLOBALS['cfg']['LeftLogoLink']; if ($GLOBALS['cfg']['LeftLogoLink']) {
switch ($GLOBALS['cfg']['LeftLogoLinkWindow']) { echo '<a href="' . htmlspecialchars($GLOBALS['cfg']['LeftLogoLink']);
case 'new': switch ($GLOBALS['cfg']['LeftLogoLinkWindow']) {
echo '" target="_blank"'; case 'new':
break; echo '" target="_blank"';
case 'main': break;
// do not add our parameters for an external link case 'main':
if (substr(strtolower($GLOBALS['cfg']['LeftLogoLink']), 0, 4) !== 'http') { // do not add our parameters for an external link
echo '?' . $query_url . '" target="frame_content"'; if (substr(strtolower($GLOBALS['cfg']['LeftLogoLink']), 0, 4) !== '://') {
} else { echo '?' . $query_url . '" target="frame_content"';
echo '"'; } else {
} echo '" target="_blank"';
}
}
echo '>' . $logo . '</a>' . "\n";
} else {
echo $logo . "\n";
} }
echo '>' . $logo . '</a>' . "\n" echo '</div>' . "\n";
.'</div>' . "\n";
} // end of display logo } // end of display logo
?> ?>
<div id="leftframelinks"> <div id="leftframelinks">

View File

@@ -136,6 +136,10 @@ function PMA_printRelationsParamDiagnostic($cfgRelation)
PMA_printDiagMessageForFeature(__('Tracking'), 'trackingwork', $messages); PMA_printDiagMessageForFeature(__('Tracking'), 'trackingwork', $messages);
PMA_printDiagMessageForParameter('userconfig', isset($cfgRelation['userconfig']), $messages, 'userconfig');
PMA_printDiagMessageForFeature(__('User preferences'), 'userconfigwork', $messages);
echo '</table>' . "\n"; echo '</table>' . "\n";
echo '<p>' . __('Quick steps to setup advanced features:') . '</p>'; echo '<p>' . __('Quick steps to setup advanced features:') . '</p>';
@@ -212,6 +216,7 @@ function PMA__getRelationsParam()
$cfgRelation['historywork'] = false; $cfgRelation['historywork'] = false;
$cfgRelation['trackingwork'] = false; $cfgRelation['trackingwork'] = false;
$cfgRelation['designerwork'] = false; $cfgRelation['designerwork'] = false;
$cfgRelation['userconfigwork'] = false;
$cfgRelation['allworks'] = false; $cfgRelation['allworks'] = false;
$cfgRelation['user'] = null; $cfgRelation['user'] = null;
$cfgRelation['db'] = null; $cfgRelation['db'] = null;
@@ -262,6 +267,8 @@ function PMA__getRelationsParam()
$cfgRelation['history'] = $curr_table[0]; $cfgRelation['history'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['tracking']) { } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['tracking']) {
$cfgRelation['tracking'] = $curr_table[0]; $cfgRelation['tracking'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['userconfig']) {
$cfgRelation['userconfig'] = $curr_table[0];
} }
} // end while } // end while
PMA_DBI_free_result($tab_rs); PMA_DBI_free_result($tab_rs);
@@ -316,6 +323,10 @@ function PMA__getRelationsParam()
$cfgRelation['trackingwork'] = true; $cfgRelation['trackingwork'] = true;
} }
if (isset($cfgRelation['userconfig'])) {
$cfgRelation['userconfigwork'] = true;
}
// we do not absolutely need that the internal relations or the PDF // we do not absolutely need that the internal relations or the PDF
// schema feature be activated // schema feature be activated
if (isset($cfgRelation['designer_coords'])) { if (isset($cfgRelation['designer_coords'])) {
@@ -329,7 +340,7 @@ function PMA__getRelationsParam()
if ($cfgRelation['relwork'] && $cfgRelation['displaywork'] if ($cfgRelation['relwork'] && $cfgRelation['displaywork']
&& $cfgRelation['pdfwork'] && $cfgRelation['commwork'] && $cfgRelation['pdfwork'] && $cfgRelation['commwork']
&& $cfgRelation['mimework'] && $cfgRelation['historywork'] && $cfgRelation['mimework'] && $cfgRelation['historywork']
&& $cfgRelation['trackingwork'] && $cfgRelation['trackingwork'] && $cfgRelation['userconfigwork']
&& $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork']) { && $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork']) {
$cfgRelation['allworks'] = true; $cfgRelation['allworks'] = true;
} }

View File

@@ -0,0 +1,779 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
include_once("Export_Relation_Schema.class.php");
/**
* This Class inherits the XMLwriter class and
* helps in developing structure of DIA Schema Export
*
* @name PMA_DIA
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @access public
* @see http://php.net/manual/en/book.xmlwriter.php
*/
class PMA_DIA extends XMLWriter
{
public $title;
public $author;
public $font;
public $fontSize;
/**
* The "PMA_DIA" constructor
*
* Upon instantiation This starts writing the Dia XML document
*
* @return void
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
*/
function __construct()
{
$this->openMemory();
/*
* Set indenting using three spaces,
* so output is formatted
*/
$this->setIndent(TRUE);
$this->setIndentString(' ');
/*
* Create the XML document
*/
$this->startDocument('1.0','UTF-8');
}
/**
* Starts Dia Document
*
* dia document starts by first initializing dia:diagram tag
* then dia:diagramdata contains all the attributes that needed
* to define the document, then finally a Layer starts which
* holds all the objects.
*
* @param string paper The size of the paper/document
* @param float topMargin top margin of the paper/document in cm
* @param float bottomMargin bottom margin of the paper/document in cm
* @param float leftMargin left margin of the paper/document in cm
* @param float rightMargin right margin of the paper/document in cm
* @param string portrait document will be portrait or landscape
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute(),XMLWriter::writeRaw()
*/
function startDiaDoc($paper,$topMargin,$bottomMargin,$leftMargin,$rightMargin,$portrait)
{
if($portrait == 'P'){
$isPortrait='true';
}else{
$isPortrait='false';
}
$this->startElement('dia:diagram');
$this->writeAttribute('xmlns:dia', 'http://www.lysator.liu.se/~alla/dia/');
$this->startElement('dia:diagramdata');
$this->writeRaw (
'<dia:attribute name="background">
<dia:color val="#ffffff"/>
</dia:attribute>
<dia:attribute name="pagebreak">
<dia:color val="#000099"/>
</dia:attribute>
<dia:attribute name="paper">
<dia:composite type="paper">
<dia:attribute name="name">
<dia:string>#'.$paper.'#</dia:string>
</dia:attribute>
<dia:attribute name="tmargin">
<dia:real val="'.$topMargin.'"/>
</dia:attribute>
<dia:attribute name="bmargin">
<dia:real val="'.$bottomMargin.'"/>
</dia:attribute>
<dia:attribute name="lmargin">
<dia:real val="'.$leftMargin.'"/>
</dia:attribute>
<dia:attribute name="rmargin">
<dia:real val="'.$rightMargin.'"/>
</dia:attribute>
<dia:attribute name="is_portrait">
<dia:boolean val="'.$isPortrait.'"/>
</dia:attribute>
<dia:attribute name="scaling">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="fitto">
<dia:boolean val="false"/>
</dia:attribute>
</dia:composite>
</dia:attribute>
<dia:attribute name="grid">
<dia:composite type="grid">
<dia:attribute name="width_x">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="width_y">
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="visible_x">
<dia:int val="1"/>
</dia:attribute>
<dia:attribute name="visible_y">
<dia:int val="1"/>
</dia:attribute>
<dia:composite type="color"/>
</dia:composite>
</dia:attribute>
<dia:attribute name="color">
<dia:color val="#d8e5e5"/>
</dia:attribute>
<dia:attribute name="guides">
<dia:composite type="guides">
<dia:attribute name="hguides"/>
<dia:attribute name="vguides"/>
</dia:composite>
</dia:attribute>');
$this->endElement();
$this->startElement('dia:layer');
$this->writeAttribute('name', 'Background');
$this->writeAttribute('visible', 'true');
$this->writeAttribute('active', 'true');
}
/**
* Ends Dia Document
*
* @return void
* @access public
* @see XMLWriter::endElement(),XMLWriter::endDocument()
*/
function endDiaDoc()
{
$this->endElement();
$this->endDocument();
}
/**
* Output Dia Document for download
*
* @param string fileName name of the dia document
* @return void
* @access public
* @see XMLWriter::flush()
*/
function showOutput($fileName)
{
if(ob_get_clean()){
ob_end_clean();
}
header('Content-type: application/x-dia-diagram');
header('Content-Disposition: attachment; filename="'.$fileName.'.dia"');
$output = $this->flush();
print $output;
}
}
/**
* Table preferences/statistics
*
* This class preserves the table co-ordinates,fields
* and helps in drawing/generating the Tables in dia XML document.
*
* @name Table_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_DIA
*/
class Table_Stats
{
/**
* Defines properties
*/
public $tableName;
public $fields = array();
public $x, $y;
public $primary = array();
public $tableId;
public $tableColor;
/**
* The "Table_Stats" constructor
*
* @param string table_name The table name
* @param integer pageNumber The current page number (from the
* $cfg['Servers'][$i]['table_coords'] table)
* @param boolean showKeys Whether to display ONLY keys or not
* @return void
* @global object The current dia document
* @global array The relations settings
* @global string The current db name
* @see PMA_DIA
*/
function __construct($tableName, $pageNumber, $showKeys = false)
{
global $dia, $cfgRelation, $db;
$this->tableName = $tableName;
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$dia->dieSchema($pageNumber,"DIA",sprintf(__('The %s table doesn\'t exist!'), $tableName));
}
/*
* load fields
* check to see if it will load all fields or only the foreign keys
*/
if ($showKeys) {
$indexes = PMA_Index::getFromTable($this->tableName, $db);
$all_columns = array();
foreach ($indexes as $index) {
$all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns())));
}
$this->fields = array_keys($all_columns);
} else {
while ($row = PMA_DBI_fetch_row($result)) {
$this->fields[] = $row[0];
}
}
$sql = 'SELECT x, y FROM '
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($tableName) . '\''
. ' AND pdf_page_number = ' . $pageNumber;
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$dia->dieSchema($pageNumber,"DIA",sprintf(__('Please configure the coordinates for table %s'), $tableName));
}
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
$this->x = (double) $this->x;
$this->y = (double) $this->y;
/*
* displayfield
*/
$this->displayfield = PMA_getDisplayField($db, $tableName);
/*
* index
*/
$result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE);
if (PMA_DBI_num_rows($result) > 0) {
while ($row = PMA_DBI_fetch_assoc($result)) {
if ($row['Key_name'] == 'PRIMARY') {
$this->primary[] = $row['Column_name'];
}
}
}
/**
* Every object in Dia document needs an ID to identify
* so, we used a static variable to keep the things unique
*/
PMA_Dia_Relation_Schema::$objectId += 1;
$this->tableId = PMA_Dia_Relation_Schema::$objectId;
}
/**
* Do draw the table
*
* Tables are generated using object type Database - Table
* primary fields are underlined in tables. Dia object
* is used to generate the XML of Dia Document. Database Table
* Object and their attributes are involved in the combination
* of displaing Database - Table on Dia Document.
* @param boolean changeColor Whether to show color for tables text or not
if changeColor is true then an array of $listOfColors
will be used to choose the random colors for tables text
we can change/add more colors to this array
@return void
* @global object The current Dia document
* @access public
* @see PMA_DIA
*/
public function tableDraw($changeColor)
{
global $dia;
if ($changeColor) {
$listOfColors = array(
'FF0000',
'000099',
'00FF00'
);
shuffle($listOfColors);
$this->tableColor = '#'.$listOfColors[0].'';
} else {
$this->tableColor = '#000000';
}
$factor = 0.1;
$dia->startElement('dia:object');
$dia->writeAttribute('type', 'Database - Table');
$dia->writeAttribute('version', '0');
$dia->writeAttribute('id', ''.$this->tableId.'');
$dia->writeRaw(
'<dia:attribute name="obj_pos">
<dia:point val="'.($this->x * $factor).','.($this->y * $factor).'"/>
</dia:attribute>
<dia:attribute name="obj_bb">
<dia:rectangle val="'.($this->x * $factor).','.($this->y * $factor).';9.97,9.2"/>
</dia:attribute>
<dia:attribute name="meta">
<dia:composite type="dict"/>
</dia:attribute>
<dia:attribute name="elem_corner">
<dia:point val="'.($this->x * $factor).','.($this->y * $factor).'"/>
</dia:attribute>
<dia:attribute name="elem_width">
<dia:real val="5.9199999999999999"/>
</dia:attribute>
<dia:attribute name="elem_height">
<dia:real val="3.5"/>
</dia:attribute>
<dia:attribute name="text_colour">
<dia:color val="'.$this->tableColor.'"/>
</dia:attribute>
<dia:attribute name="line_colour">
<dia:color val="#000000"/>
</dia:attribute>
<dia:attribute name="fill_colour">
<dia:color val="#ffffff"/>
</dia:attribute>
<dia:attribute name="line_width">
<dia:real val="0.10000000000000001"/>
</dia:attribute>
<dia:attribute name="name">
<dia:string>#'.$this->tableName.'#</dia:string>
</dia:attribute>
<dia:attribute name="comment">
<dia:string>##</dia:string>
</dia:attribute>
<dia:attribute name="visible_comment">
<dia:boolean val="false"/>
</dia:attribute>
<dia:attribute name="tagging_comment">
<dia:boolean val="false"/>
</dia:attribute>
<dia:attribute name="underline_primary_key">
<dia:boolean val="true"/>
</dia:attribute>
<dia:attribute name="bold_primary_keys">
<dia:boolean val="true"/>
</dia:attribute>
<dia:attribute name="normal_font">
<dia:font family="monospace" style="0" name="Courier"/>
</dia:attribute>
<dia:attribute name="name_font">
<dia:font family="sans" style="80" name="Helvetica-Bold"/>
</dia:attribute>
<dia:attribute name="comment_font">
<dia:font family="sans" style="0" name="Helvetica"/>
</dia:attribute>
<dia:attribute name="normal_font_height">
<dia:real val="0.80000000000000004"/>
</dia:attribute>
<dia:attribute name="name_font_height">
<dia:real val="0.69999999999999996"/>
</dia:attribute>
<dia:attribute name="comment_font_height">
<dia:real val="0.69999999999999996"/>
</dia:attribute>'
);
$dia->startElement('dia:attribute');
$dia->writeAttribute('name', 'attributes');
foreach ($this->fields as $field) {
$dia->writeRaw(
'<dia:composite type="table_attribute">
<dia:attribute name="name">
<dia:string>#'.$field.'#</dia:string>
</dia:attribute>
<dia:attribute name="type">
<dia:string>##</dia:string>
</dia:attribute>
<dia:attribute name="comment">
<dia:string>##</dia:string>
</dia:attribute>'
);
unset($pm);
$pm = 'false';
if (in_array($field, $this->primary)) {
$pm = 'true';
}
if ($field == $this->displayfield) {
$pm = 'false';
}
$dia->writeRaw(
'<dia:attribute name="primary_key">
<dia:boolean val="'.$pm.'"/>
</dia:attribute>
<dia:attribute name="nullable">
<dia:boolean val="false"/>
</dia:attribute>
<dia:attribute name="unique">
<dia:boolean val="'.$pm.'"/>
</dia:attribute>
</dia:composite>'
);
}
$dia->endElement();
$dia->endElement();
}
}
/**
* Relation preferences/statistics
*
* This class fetches the table master and foreign fields positions
* and helps in generating the Table references and then connects
* master table's master field to foreign table's foreign key
* in dia XML document.
*
* @name Relation_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_DIA
*/
class Relation_Stats
{
/**
* Defines properties
*/
public $srcConnPointsRight;
public $srcConnPointsLeft;
public $destConnPointsRight;
public $destConnPointsLeft;
public $masterTableId;
public $foreignTableId;
public $masterTablePos;
public $foreignTablePos;
public $referenceColor;
/**
* The "Relation_Stats" constructor
*
* @param string master_table The master table name
* @param string master_field The relation field in the master table
* @param string foreign_table The foreign table name
* @param string foreigh_field The relation field in the foreign table
* @return void
* @see Relation_Stats::_getXy
*/
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
{
$src_pos = $this->_getXy($master_table, $master_field);
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
$this->srcConnPointsLeft = $src_pos[0];
$this->srcConnPointsRight = $src_pos[1];
$this->destConnPointsLeft = $dest_pos[0];
$this->destConnPointsRight = $dest_pos[1];
$this->masterTablePos = $src_pos[2];
$this->foreignTablePos = $dest_pos[2];
$this->masterTableId = $master_table->tableId;
$this->foreignTableId = $foreign_table->tableId;
}
/**
* Each Table object have connection points
* which is used to connect to other objects in Dia
* we detect the position of key in fields and
* then determines its left and right connection
* points.
*
* @param string table The current table name
* @param string column The relation column name
* @return array Table right,left connection points and key position
* @access private
*/
private function _getXy($table, $column)
{
$pos = array_search($column, $table->fields);
// left, right, position
$value = 12;
if($pos != 0)
{
return array($pos + $value + $pos, $pos + $value + $pos + 1, $pos);
}
return array($pos + $value , $pos + $value + 1, $pos);
}
/**
* Draws relation references
*
* connects master table's master field to foreign table's
* forein field using Dia object type Database - Reference
* Dia object is used to generate the XML of Dia Document.
* Database reference Object and their attributes are involved
* in the combination of displaing Database - reference on Dia Document.
*
* @param boolean changeColor Whether to use one color per relation or not
if changeColor is true then an array of $listOfColors
will be used to choose the random colors for references
lines. we can change/add more colors to this array
* @return void
* @global object The current Dia document
* @access public
* @see PMA_PDF
*/
public function relationDraw($changeColor)
{
global $dia;
PMA_Dia_Relation_Schema::$objectId += 1;
/*
* if source connection points and destination connection
* points are same then return it false and don't draw that
* relation
*/
if ( $this->srcConnPointsRight == $this->destConnPointsRight ){
if ( $this->srcConnPointsLeft == $this->destConnPointsLeft ){
return false;
}
}
if ($changeColor) {
$listOfColors = array(
'FF0000',
'000099',
'00FF00'
);
shuffle($listOfColors);
$this->referenceColor = '#'.$listOfColors[0].'';
} else {
$this->referenceColor = '#000000';
}
$dia->writeRaw(
'<dia:object type="Database - Reference" version="0" id="'.PMA_Dia_Relation_Schema::$objectId.'">
<dia:attribute name="obj_pos">
<dia:point val="3.27,18.9198"/>
</dia:attribute>
<dia:attribute name="obj_bb">
<dia:rectangle val="2.27,8.7175;17.7679,18.9198"/>
</dia:attribute>
<dia:attribute name="meta">
<dia:composite type="dict"/>
</dia:attribute>
<dia:attribute name="orth_points">
<dia:point val="3.27,18.9198"/>
<dia:point val="2.27,18.9198"/>
<dia:point val="2.27,14.1286"/>
<dia:point val="17.7679,14.1286"/>
<dia:point val="17.7679,9.3375"/>
<dia:point val="16.7679,9.3375"/>
</dia:attribute>
<dia:attribute name="orth_orient">
<dia:enum val="0"/>
<dia:enum val="1"/>
<dia:enum val="0"/>
<dia:enum val="1"/>
<dia:enum val="0"/>
</dia:attribute>
<dia:attribute name="orth_autoroute">
<dia:boolean val="true"/>
</dia:attribute>
<dia:attribute name="text_colour">
<dia:color val="#000000"/>
</dia:attribute>
<dia:attribute name="line_colour">
<dia:color val="'.$this->referenceColor.'"/>
</dia:attribute>
<dia:attribute name="line_width">
<dia:real val="0.10000000000000001"/>
</dia:attribute>
<dia:attribute name="line_style">
<dia:enum val="0"/>
<dia:real val="1"/>
</dia:attribute>
<dia:attribute name="corner_radius">
<dia:real val="0"/>
</dia:attribute>
<dia:attribute name="end_arrow">
<dia:enum val="22"/>
</dia:attribute>
<dia:attribute name="end_arrow_length">
<dia:real val="0.5"/>
</dia:attribute>
<dia:attribute name="end_arrow_width">
<dia:real val="0.5"/>
</dia:attribute>
<dia:attribute name="start_point_desc">
<dia:string>#1#</dia:string>
</dia:attribute>
<dia:attribute name="end_point_desc">
<dia:string>#n#</dia:string>
</dia:attribute>
<dia:attribute name="normal_font">
<dia:font family="monospace" style="0" name="Courier"/>
</dia:attribute>
<dia:attribute name="normal_font_height">
<dia:real val="0.59999999999999998"/>
</dia:attribute>
<dia:connections>
<dia:connection handle="0" to="'.$this->masterTableId.'" connection="'.$this->srcConnPointsRight.'"/>
<dia:connection handle="1" to="'.$this->foreignTableId.'" connection="'.$this->destConnPointsRight.'"/>
</dia:connections>
</dia:object>'
);
}
}
/**
* Dia Relation Schema Class
*
* Purpose of this class is to generate the Dia XML Document
* which is used for representing the database diagrams in Dia IDE
* This class uses Database Table and Reference Objects of Dia and with
* the combination of these objects actually helps in preparing Dia XML.
*
* Dia XML is generated by using XMLWriter php extension and this class
* inherits Export_Relation_Schema class has common functionality added
* to this class
*
* @name Dia_Relation_Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_Dia_Relation_Schema extends PMA_Export_Relation_Schema
{
/**
* Defines properties
*/
private $_tables = array();
private $_relations = array();
private $_topMargin = 2.8222000598907471;
private $_bottomMargin = 2.8222000598907471;
private $_leftMargin = 2.8222000598907471;
private $_rightMargin = 2.8222000598907471;
public static $objectId = 0;
/**
* The "PMA_Dia_Relation_Schema" constructor
*
* Upon instantiation This outputs the Dia XML document
* that user can download
*
* @return void
* @see PMA_DIA,Table_Stats,Relation_Stats
*/
function __construct()
{
global $dia,$db;
$this->setPageNumber($_POST['pdf_page_number']);
$this->setShowGrid(isset($_POST['show_grid']));
$this->setShowColor($_POST['show_color']);
$this->setShowKeys(isset($_POST['show_keys']));
$this->setOrientation(isset($_POST['orientation']));
$this->setPaper($_POST['paper']);
$this->setExportType($_POST['export_type']);
$dia = new PMA_DIA();
$dia->startDiaDoc($this->paper,$this->_topMargin,$this->_bottomMargin,$this->_leftMargin,$this->_rightMargin,$this->orientation);
$alltables = $this->getAllTables($db,$this->pageNumber);
foreach ($alltables as $table) {
if (!isset($this->tables[$table])) {
$this->tables[$table] = new Table_Stats($table, $this->pageNumber, $this->showKeys);
}
}
$seen_a_relation = false;
foreach ($alltables as $one_table) {
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
if ($exist_rel) {
$seen_a_relation = true;
foreach ($exist_rel as $master_field => $rel) {
/* put the foreign table on the schema only if selected
* by the user
* (do not use array_search() because we would have to
* to do a === FALSE and this is not PHP3 compatible)
*/
if (in_array($rel['foreign_table'], $alltables)) {
$this->_addRelation($one_table, $master_field, $rel['foreign_table'], $rel['foreign_field'],$this->showKeys);
}
}
}
}
$this->_drawTables($this->showColor);
if ($seen_a_relation) {
$this->_drawRelations($this->showColor);
}
$dia->endDiaDoc();
$dia->showOutput($db.'-'.$this->pageNumber);
exit();
}
/**
* Defines relation objects
*
* @param string masterTable The master table name
* @param string masterField The relation field in the master table
* @param string foreignTable The foreign table name
* @param string foreignField The relation field in the foreign table
* @return void
* @access private
* @see Table_Stats::__construct(),Relation_Stats::__construct()
*/
private function _addRelation($masterTable, $masterField, $foreignTable, $foreignField, $showKeys)
{
if (!isset($this->tables[$masterTable])) {
$this->tables[$masterTable] = new Table_Stats($masterTable, $this->pageNumber, $showKeys);
}
if (!isset($this->tables[$foreignTable])) {
$this->tables[$foreignTable] = new Table_Stats($foreignTable, $this->pageNumber, $showKeys);
}
$this->_relations[] = new Relation_Stats($this->tables[$masterTable], $masterField, $this->tables[$foreignTable], $foreignField);
}
/**
* Draws relation references
*
* connects master table's master field to
* foreign table's forein field using Dia object
* type Database - Reference
*
* @param boolean changeColor Whether to use one color per relation or not
* @return void
* @access private
* @see Relation_Stats::relationDraw()
*/
private function _drawRelations($changeColor)
{
foreach ($this->_relations as $relation) {
$relation->relationDraw($changeColor);
}
}
/**
* Draws tables
*
* Tables are generated using Dia object type Database - Table
* primary fields are underlined and bold in tables
*
* @param boolean changeColor Whether to show color for tables text or not
* @return void
* @access private
* @see Table_Stats::tableDraw()
*/
private function _drawTables($changeColor)
{
foreach ($this->tables as $table) {
$table->tableDraw($changeColor);
}
}
}
?>

View File

@@ -0,0 +1,858 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
include_once("Export_Relation_Schema.class.php");
/**
* This Class is EPS Library and
* helps in developing structure of EPS Schema Export
*
* @name PMA_EPS
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @access public
* @see http://php.net/manual/en/book.xmlwriter.php
*/
class PMA_EPS
{
public $font;
public $fontSize;
public $stringCommands;
/**
* The "PMA_EPS" constructor
*
* Upon instantiation This starts writing the EPS Document.
* %!PS-Adobe-3.0 EPSF-3.0 This is the MUST first comment to include
* it shows/tells that the Post Script document is purely under
* Document Structuring Convention [DSC] and is Compliant
* Encapsulated Post Script Document
*
* @return void
* @access public
*/
function __construct()
{
$this->stringCommands = "";
$this->stringCommands .= "%!PS-Adobe-3.0 EPSF-3.0 \n";
}
/**
* Set document title
*
* @param string value sets the title text
* @return void
* @access public
*/
function setTitle($value)
{
$this->stringCommands .= '%%Title: ' . $value . "\n";
}
/**
* Set document author
*
* @param string value sets the author
* @return void
* @access public
*/
function setAuthor($value)
{
$this->stringCommands .= '%%Creator: ' . $value . "\n";
}
/**
* Set document creation date
*
* @param string value sets the date
* @return void
* @access public
*/
function setDate($value)
{
$this->stringCommands .= '%%CreationDate: ' . $value . "\n";
}
/**
* Set document orientation
*
* @param string value sets the author
* @return void
* @access public
*/
function setOrientation($value)
{
$this->stringCommands .= "%%PageOrder: Ascend \n";
if($value == "L"){
$value = "Landscape";
$this->stringCommands .= '%%Orientation: ' . $value . "\n";
}else{
$value = "Portrait";
$this->stringCommands .= '%%Orientation: ' . $value . "\n";
}
$this->stringCommands .= "%%EndComments \n";
$this->stringCommands .= "%%Pages 1 \n";
$this->stringCommands .= "%%BoundingBox: 72 150 144 170 \n";
}
/**
* Set the font and size
*
* font can be set whenever needed in EPS
*
* @param string value sets the font name e.g Arial
* @param integer value sets the size of the font e.g 10
* @return void
* @access public
*/
function setFont($value,$size)
{
$this->font = $value;
$this->fontSize = $size;
$this->stringCommands .= "/".$value." findfont % Get the basic font\n";
$this->stringCommands .= "".$size." scalefont % Scale the font to $size points\n";
$this->stringCommands .= "setfont % Make it the current font\n";
}
/**
* Get the font
*
* @return string return the font name e.g Arial
* @access public
*/
function getFont()
{
return $this->font;
}
/**
* Get the font Size
*
* @return string return the size of the font e.g 10
* @access public
*/
function getFontSize()
{
return $this->fontSize;
}
/**
* Draw the line
*
* drawing the lines from x,y source to x,y destination and set the
* width of the line. lines helps in showing relationships of tables
*
* @param integer x_from The x_from attribute defines the start
left position of the element
* @param integer y_from The y_from attribute defines the start
right position of the element
* @param integer x_to The x_to attribute defines the end
left position of the element
* @param integer y_to The y_to attribute defines the end
right position of the element
* @param integer lineWidth sets the width of the line e.g 2
* @return void
* @access public
*/
function line($x_from=0, $y_from=0, $x_to=0, $y_to=0, $lineWidth=0)
{
$this->stringCommands .= $lineWidth . " setlinewidth \n";
$this->stringCommands .= $x_from . ' ' . $y_from . " moveto \n";
$this->stringCommands .= $x_to . ' ' . $y_to . " lineto \n";
$this->stringCommands .= "stroke \n";
}
/**
* Draw the rectangle
*
* drawing the rectangle from x,y source to x,y destination and set the
* width of the line. rectangles drawn around the text shown of fields
*
* @param integer x_from The x_from attribute defines the start
left position of the element
* @param integer y_from The y_from attribute defines the start
right position of the element
* @param integer x_to The x_to attribute defines the end
left position of the element
* @param integer y_to The y_to attribute defines the end
right position of the element
* @param integer lineWidth sets the width of the line e.g 2
* @return void
* @access public
*/
function rect($x_from, $y_from, $x_to, $y_to, $lineWidth)
{
$this->stringCommands .= $lineWidth . " setlinewidth \n";
$this->stringCommands .= "newpath \n";
$this->stringCommands .= $x_from . " " . $y_from . " moveto \n";
$this->stringCommands .= "0 " . $y_to . " rlineto \n";
$this->stringCommands .= $x_to . " 0 rlineto \n";
$this->stringCommands .= "0 -" . $y_to . " rlineto \n";
$this->stringCommands .= "closepath \n";
$this->stringCommands .= "stroke \n";
}
/**
* Set the current point
*
* The moveto operator takes two numbers off the stack and treats
* them as x and y coordinates to which to move. The coordinates
* specified become the current point.
*
* @param integer x The x attribute defines the
left position of the element
* @param integer y The y attribute defines the
right position of the element
* @return void
* @access public
*/
function moveTo($x, $y)
{
$this->stringCommands .= $x . ' ' . $y . " moveto \n";
}
/**
* Output/Display the text
*
* @param string text The string to be displayed
* @return void
* @access public
*/
function show($text)
{
$this->stringCommands .= '(' . $text . ") show \n";
}
/**
* Output the text at specified co-ordinates
*
* @param string text The string to be displayed
* @param integer x The x attribute defines the
left position of the element
* @param integer y The y attribute defines the
right position of the element
* @return void
* @access public
*/
function showXY($text, $x, $y)
{
$this->moveTo($x, $y);
$this->show($text);
}
/**
* get width of string/text
*
* EPS text width is calcualted depending on font name
* and font size. It is very important to know the width of text
* because rectangle is drawn around it.
*
* This is a bit hardcore method. I didn't found any other better than this.
* if someone found better than this. would love to hear that method
*
* @param string text string that width will be calculated
* @param integer font name of the font like Arial,sans-serif etc
* @param integer fontSize size of font
* @return integer width of the text
* @access public
*/
function getStringWidth($text,$font,$fontSize)
{
/*
* Start by counting the width, giving each character a modifying value
*/
$count = 0;
$count = $count + ((strlen($text) - strlen(str_replace(array("i","j","l"),"",$text)))*0.23);//ijl
$count = $count + ((strlen($text) - strlen(str_replace(array("f"),"",$text)))*0.27);//f
$count = $count + ((strlen($text) - strlen(str_replace(array("t","I"),"",$text)))*0.28);//tI
$count = $count + ((strlen($text) - strlen(str_replace(array("r"),"",$text)))*0.34);//r
$count = $count + ((strlen($text) - strlen(str_replace(array("1"),"",$text)))*0.49);//1
$count = $count + ((strlen($text) - strlen(str_replace(array("c","k","s","v","x","y","z","J"),"",$text)))*0.5);//cksvxyzJ
$count = $count + ((strlen($text) - strlen(str_replace(array("a","b","d","e","g","h","n","o","p","q","u","L","0","2","3","4","5","6","7","8","9"),"",$text)))*0.56);//abdeghnopquL023456789
$count = $count + ((strlen($text) - strlen(str_replace(array("F","T","Z"),"",$text)))*0.61);//FTZ
$count = $count + ((strlen($text) - strlen(str_replace(array("A","B","E","K","P","S","V","X","Y"),"",$text)))*0.67);//ABEKPSVXY
$count = $count + ((strlen($text) - strlen(str_replace(array("w","C","D","H","N","R","U"),"",$text)))*0.73);//wCDHNRU
$count = $count + ((strlen($text) - strlen(str_replace(array("G","O","Q"),"",$text)))*0.78);//GOQ
$count = $count + ((strlen($text) - strlen(str_replace(array("m","M"),"",$text)))*0.84);//mM
$count = $count + ((strlen($text) - strlen(str_replace("W","",$text)))*.95);//W
$count = $count + ((strlen($text) - strlen(str_replace(" ","",$text)))*.28);//" "
$text = str_replace(" ","",$text);//remove the " "'s
$count = $count + (strlen(preg_replace("/[a-z0-9]/i","",$text))*0.3); //all other chrs
$modifier = 1;
$font = strtolower($font);
switch($font){
/*
* no modifier for arial and sans-serif
*/
case 'arial':
case 'sans-serif':
break;
/*
* .92 modifer for time, serif, brushscriptstd, and californian fb
*/
case 'times':
case 'serif':
case 'brushscriptstd':
case 'californian fb':
$modifier = .92;
break;
/*
* 1.23 modifier for broadway
*/
case 'broadway':
$modifier = 1.23;
break;
}
$textWidth = $count*$fontSize;
return ceil($textWidth*$modifier);
}
/**
* Ends EPS Document
*
* @return void
* @access public
*/
function endEpsDoc()
{
$this->stringCommands .= "showpage \n";
}
/**
* Output EPS Document for download
*
* @param string fileName name of the eps document
* @return void
* @access public
*/
function showOutput($fileName)
{
// if(ob_get_clean()){
//ob_end_clean();
//}
header('Content-type: image/x-eps');
header('Content-Disposition: attachment; filename="'.$fileName.'.eps"');
$output = $this->stringCommands;
print $output;
}
}
/**
* Table preferences/statistics
*
* This class preserves the table co-ordinates,fields
* and helps in drawing/generating the Tables in EPS.
*
* @name Table_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_EPS
*/
class Table_Stats
{
/**
* Defines properties
*/
private $_tableName;
private $_showInfo = false;
public $width = 0;
public $height;
public $fields = array();
public $heightCell = 0;
public $currentCell = 0;
public $x, $y;
public $primary = array();
/**
* The "Table_Stats" constructor
*
* @param string tableName The table name
* @param string font The font name
* @param integer fontSize The font size
* @param integer same_wide_width The max width among tables
* @param boolean showKeys Whether to display keys or not
* @param boolean showInfo Whether to display table position or not
* @global object The current eps document
* @global integer The current page number (from the
* $cfg['Servers'][$i]['table_coords'] table)
* @global array The relations settings
* @global string The current db name
* @access private
* @see PMA_EPS, Table_Stats::Table_Stats_setWidth,
Table_Stats::Table_Stats_setHeight
*/
function __construct($tableName, $font, $fontSize, $pageNumber, &$same_wide_width, $showKeys = false, $showInfo = false)
{
global $eps, $cfgRelation, $db;
$this->_tableName = $tableName;
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$eps->dieSchema($pageNumber,"EPS",sprintf(__('The %s table doesn\'t exist!'), $tableName));
}
/*
* load fields
* check to see if it will load all fields or only the foreign keys
*/
if ($showKeys) {
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
$all_columns = array();
foreach ($indexes as $index) {
$all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns())));
}
$this->fields = array_keys($all_columns);
} else {
while ($row = PMA_DBI_fetch_row($result)) {
$this->fields[] = $row[0];
}
}
$this->_showInfo = $showInfo;
// height and width
$this->_setHeightTable($fontSize);
// setWidth must me after setHeight, because title
// can include table height which changes table width
$this->_setWidthTable($font,$fontSize);
if ($same_wide_width < $this->width) {
$same_wide_width = $this->width;
}
// x and y
$sql = 'SELECT x, y FROM '
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($tableName) . '\''
. ' AND pdf_page_number = ' . $pageNumber;
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$eps->dieSchema($pageNumber,"EPS",sprintf(__('Please configure the coordinates for table %s'), $tableName));
}
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
$this->x = (double) $this->x;
$this->y = (double) $this->y;
// displayfield
$this->displayfield = PMA_getDisplayField($db, $tableName);
// index
$result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE);
if (PMA_DBI_num_rows($result) > 0) {
while ($row = PMA_DBI_fetch_assoc($result)) {
if ($row['Key_name'] == 'PRIMARY') {
$this->primary[] = $row['Column_name'];
}
}
}
}
/**
* Returns title of the current table,
* title can have the dimensions/co-ordinates of the table
*
* @return string The relation/table name
* @access private
*/
private function _getTitle()
{
return ($this->_showInfo ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell) : '') . ' ' . $this->_tableName;
}
/**
* Sets the width of the table
*
* @param string font The font name
* @param integer fontSize The font size
* @global object The current eps document
* @return void
* @access private
* @see PMA_EPS
*/
private function _setWidthTable($font,$fontSize)
{
global $eps;
foreach ($this->fields as $field) {
$this->width = max($this->width, $eps->getStringWidth($field,$font,$fontSize));
}
$this->width += $eps->getStringWidth(' ',$font,$fontSize);
/*
* it is unknown what value must be added, because
* table title is affected by the tabe width value
*/
while ($this->width < $eps->getStringWidth($this->_getTitle(),$font,$fontSize)) {
$this->width += 7;
}
}
/**
* Sets the height of the table
*
* @param integer fontSize The font size
* @return void
* @access private
*/
private function _setHeightTable($fontSize)
{
$this->heightCell = $fontSize + 4;
$this->height = (count($this->fields) + 1) * $this->heightCell;
}
/**
* Draw the table
*
* @param boolean showColor Whether to display color
* @global object The current eps document
* @return void
* @access public
* @see PMA_EPS,PMA_EPS::line,PMA_EPS::rect
*/
public function tableDraw($showColor)
{
global $eps;
//echo $this->_tableName.'<br />';
$eps->rect($this->x,$this->y + 12,
$this->width,$this->heightCell,
1
);
$eps->showXY($this->_getTitle(),$this->x + 5,$this->y + 14);
foreach ($this->fields as $field) {
$this->currentCell += $this->heightCell;
$showColor = 'none';
if ($showColor) {
if (in_array($field, $this->primary)) {
$showColor = '#0c0';
}
if ($field == $this->displayfield) {
$showColor = 'none';
}
}
$eps->rect($this->x,$this->y + 12 + $this->currentCell,
$this->width, $this->heightCell,1);
$eps->showXY($field, $this->x + 5, $this->y + 14 + $this->currentCell);
}
}
}
/**
* Relation preferences/statistics
*
* This class fetches the table master and foreign fields positions
* and helps in generating the Table references and then connects
* master table's master field to foreign table's foreign key
* in EPS document.
*
* @name Relation_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_EPS
*/
class Relation_Stats
{
/**
* Defines properties
*/
public $xSrc, $ySrc;
public $srcDir ;
public $destDir;
public $xDest, $yDest;
public $wTick = 10;
/**
* The "Relation_Stats" constructor
*
* @param string master_table The master table name
* @param string master_field The relation field in the master table
* @param string foreign_table The foreign table name
* @param string foreigh_field The relation field in the foreign table
* @see Relation_Stats::_getXy
*/
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
{
$src_pos = $this->_getXy($master_table, $master_field);
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
/*
* [0] is x-left
* [1] is x-right
* [2] is y
*/
$src_left = $src_pos[0] - $this->wTick;
$src_right = $src_pos[1] + $this->wTick;
$dest_left = $dest_pos[0] - $this->wTick;
$dest_right = $dest_pos[1] + $this->wTick;
$d1 = abs($src_left - $dest_left);
$d2 = abs($src_right - $dest_left);
$d3 = abs($src_left - $dest_right);
$d4 = abs($src_right - $dest_right);
$d = min($d1, $d2, $d3, $d4);
if ($d == $d1) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d2) {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d3) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
} else {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
}
$this->ySrc = $src_pos[2] + 10;
$this->yDest = $dest_pos[2] + 10;
}
/**
* Gets arrows coordinates
*
* @param string table The current table name
* @param string column The relation column name
* @return array Arrows coordinates
* @access private
*/
private function _getXy($table, $column)
{
$pos = array_search($column, $table->fields);
// x_left, x_right, y
return array($table->x, $table->x + $table->width, $table->y + ($pos + 1.5) * $table->heightCell);
}
/**
* draws relation links and arrows
* shows foreign key relations
*
* @param boolean changeColor Whether to use one color per relation or not
* @global object The current EPS document
* @access public
* @see PMA_EPS
*/
public function relationDraw($changeColor)
{
global $eps;
if ($changeColor) {
$listOfColors = array(
'red',
'grey',
'black',
'yellow',
'green',
'cyan',
' orange'
);
shuffle($listOfColors);
$color = $listOfColors[0];
} else {
$color = 'black';
}
// draw a line like -- to foreign field
$eps->line($this->xSrc,$this->ySrc,
$this->xSrc + $this->srcDir * $this->wTick,$this->ySrc,
1
);
// draw a line like -- to master field
$eps->line($this->xDest + $this->destDir * $this->wTick, $this->yDest,
$this->xDest, $this->yDest,
1
);
// draw a line that connects to master field line and foreign field line
$eps->line($this->xSrc + $this->srcDir * $this->wTick,$this->ySrc,
$this->xDest + $this->destDir * $this->wTick, $this->yDest,
1
);
$root2 = 2 * sqrt(2);
$eps->line($this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick ,
$this->ySrc + $this->wTick / $root2 ,
1
);
$eps->line($this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick ,
$this->ySrc - $this->wTick / $root2 ,
1
);
$eps->line($this->xDest + $this->destDir * $this->wTick / 2 , $this->yDest ,
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
$this->yDest + $this->wTick / $root2 ,
1);
$eps->line($this->xDest + $this->destDir * $this->wTick / 2 ,
$this->yDest , $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick ,
$this->yDest - $this->wTick / $root2 ,
1
);
}
}
/*
* end of the "Relation_Stats" class
*/
/**
* EPS Relation Schema Class
*
* Purpose of this class is to generate the EPS Document
* which is used for representing the database diagrams.
* This class uses post script commands and with
* the combination of these commands actually helps in preparing EPS Document.
*
* This class inherits Export_Relation_Schema class has common functionality added
* to this class
*
* @name Eps_Relation_Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_Eps_Relation_Schema extends PMA_Export_Relation_Schema
{
private $tables = array();
private $_relations = array();
/**
* The "PMA_EPS_Relation_Schema" constructor
*
* Upon instantiation This starts writing the EPS document
* user will be prompted for download as .eps extension
*
* @return void
* @see PMA_EPS
*/
function __construct()
{
global $eps,$db;
$this->setPageNumber($_POST['pdf_page_number']);
$this->setShowColor(isset($_POST['show_color']));
$this->setShowKeys(isset($_POST['show_keys']));
$this->setTableDimension(isset($_POST['show_table_dimension']));
$this->setAllTableSameWidth(isset($_POST['all_table_same_wide']));
$this->setOrientation($_POST['orientation']);
$this->setExportType($_POST['export_type']);
$eps = new PMA_EPS();
$eps->setTitle(sprintf(__('Schema of the %s database - Page %s'), $db, $this->pageNumber));
$eps->setAuthor('phpMyAdmin ' . PMA_VERSION);
$eps->setDate(date("j F Y, g:i a"));
$eps->setOrientation($this->orientation);
$eps->setFont('Verdana','10');
$alltables = $this->getAllTables($db,$this->pageNumber);
foreach ($alltables AS $table) {
if (!isset($this->tables[$table])) {
$this->tables[$table] = new Table_Stats($table,$eps->getFont(),$eps->getFontSize(), $this->pageNumber, $this->_tablewidth, $this->showKeys, $this->tableDimension);
}
if ($this->sameWide) {
$this->tables[$table]->width = $this->_tablewidth;
}
}
$seen_a_relation = false;
foreach ($alltables as $one_table) {
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
if ($exist_rel) {
$seen_a_relation = true;
foreach ($exist_rel as $master_field => $rel) {
/* put the foreign table on the schema only if selected
* by the user
* (do not use array_search() because we would have to
* to do a === FALSE and this is not PHP3 compatible)
*/
if (in_array($rel['foreign_table'], $alltables)) {
$this->_addRelation($one_table,$eps->getFont(),$eps->getFontSize(), $master_field, $rel['foreign_table'], $rel['foreign_field'], $this->tableDimension);
}
}
}
}
if ($seen_a_relation) {
$this->_drawRelations($this->showColor);
}
$this->_drawTables($this->showColor);
$eps->endEpsDoc();
$eps->showOutput($db.'-'.$this->pageNumber);
exit();
}
/**
* Defines relation objects
*
* @param string masterTable The master table name
* @param string masterField The relation field in the master table
* @param string foreignTable The foreign table name
* @param string foreignField The relation field in the foreign table
* @param boolean showInfo Whether to display table position or not
* @return void
* @access private
* @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
*/
private function _addRelation($masterTable,$font,$fontSize, $masterField, $foreignTable, $foreignField, $showInfo)
{
if (!isset($this->tables[$masterTable])) {
$this->tables[$masterTable] = new Table_Stats($masterTable, $font, $fontSize, $this->pageNumber, $this->_tablewidth, false, $showInfo);
}
if (!isset($this->tables[$foreignTable])) {
$this->tables[$foreignTable] = new Table_Stats($foreignTable,$font,$fontSize,$this->pageNumber, $this->_tablewidth, false, $showInfo);
}
$this->_relations[] = new Relation_Stats($this->tables[$masterTable], $masterField, $this->tables[$foreignTable], $foreignField);
}
/**
* Draws relation arrows and lines
* connects master table's master field to
* foreign table's forein field
*
* @param boolean changeColor Whether to use one color per relation or not
* @return void
* @access private
* @see Relation_Stats::relationDraw()
*/
private function _drawRelations($changeColor)
{
foreach ($this->_relations as $relation) {
$relation->relationDraw($changeColor);
}
}
/**
* Draws tables
*
* @param boolean changeColor Whether to show color for primary fields or not
* @return void
* @access private
* @see Table_Stats::Table_Stats_tableDraw()
*/
private function _drawTables($changeColor)
{
foreach ($this->tables as $table) {
$table->tableDraw($changeColor);
}
}
}
?>

View File

@@ -0,0 +1,223 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
/**
* This class is inherited by all schema classes
* It contains those methods which are common in them
* it works like factory pattern
*
* @name Export Relation Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_Export_Relation_Schema
{
private $_pageTitle;
public $showGrid;
public $showColor;
public $tableDimension;
public $sameWide;
public $withDoc;
public $showKeys;
public $orientation;
public $paper;
public $pageNumber;
/**
* Set Page Number
*
* @param integer value Page Number of the document to be created
* @return void
* @access public
*/
public function setPageNumber($value)
{
$this->pageNumber = isset($value) ? $value : 1;
}
/**
* Set Show Grid
*
* @param boolean value show grid of the document or not
* @return void
* @access public
*/
public function setShowGrid($value)
{
$this->showGrid = (isset($value) && $value == 'on') ? 1 : 0;
}
public function setShowColor($value)
{
$this->showColor = (isset($value) && $value == 'on') ? 1 : 0;
}
/**
* Set Table Dimension
*
* @param boolean value show table co-ordinates or not
* @return void
* @access public
*/
public function setTableDimension($value)
{
$this->tableDimension = (isset($value) && $value == 'on') ? 1 : 0;
}
/**
* Set same width of All Tables
*
* @param boolean value set same width of all tables or not
* @return void
* @access public
*/
public function setAllTableSameWidth($value)
{
$this->sameWide = (isset($value) && $value == 'on') ? 1 : 0;
}
/**
* Set Data Dictionary
*
* @param boolean value show selected database data dictionary or not
* @return void
* @access public
*/
public function setWithDataDictionary($value)
{
$this->withDoc = (isset($value) && $value == 'on') ? 1 : 0;
}
/**
* Set Show only keys
*
* @param boolean value show only keys or not
* @return void
* @access public
*/
public function setShowKeys($value)
{
$this->showKeys = (isset($value) && $value == 'on') ? 1 : 0;
}
/**
* Set Orientation
*
* @param string value Orientation will be portrait or landscape
* @return void
* @access public
*/
public function setOrientation($value)
{
$this->orientation = (isset($value) && $value == 'P') ? 'P' : 'L';
}
/**
* Set type of paper
*
* @param string value paper type can be A4 etc
* @return void
* @access public
*/
public function setPaper($value)
{
$this->paper = isset($value) ? $value : 'A4';
}
/**
* Set title of the page
*
* @param string value title of the page displayed at top of the document
* @return void
* @access public
*/
public function setPageTitle($title)
{
$this->_pageTitle=$title;
}
/**
* Set type of export relational schema
*
* @param string value can be pdf,svg,dia,visio,eps etc
* @return void
* @access public
*/
public function setExportType($value)
{
$this->exportType=$value;
}
/**
* get all tables involved or included in page
*
* @param string db name of the database
* @param integer pageNumber page number whose tables will be fetched in an array
* @return Array an array of tables
* @access public
*/
public function getAllTables($db,$pageNumber)
{
global $cfgRelation;
// Get All tables
$tab_sql = 'SELECT table_name FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND pdf_page_number = ' . $pageNumber;
$tab_rs = PMA_query_as_controluser($tab_sql, null, PMA_DBI_QUERY_STORE);
if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) {
$this->_die('',__('No tables'));
}
while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) {
$alltables[] = PMA_sqlAddslashes($curr_table['table_name']);
}
return $alltables;
}
/**
* Displays an error message
*
* @param integer pageNumber ID of the page choosen
* @param string type Schema Type
* @param string error_message the error mesage
* @global array the PMA configuration array
* @global integer the current server id
* @global string the current language
* @global string the charset to convert to
* @global string the current database name
* @global string the current charset
* @global string the current text direction
* @global string a localized string
* @global string an other localized string
* @access public
* @return void
*/
function dieSchema($pageNumber, $type = '', $error_message = '')
{
global $cfg;
global $server, $lang, $convcharset, $db;
global $charset, $text_dir;
require_once './libraries/header.inc.php';
echo "<p><strong>" . __("SCHEMA ERROR: ") . $type ."</strong></p>" . "\n";
if (!empty($error_message)) {
$error_message = htmlspecialchars($error_message);
}
echo '<p>' . "\n";
echo ' ' . $error_message . "\n";
echo '</p>' . "\n";
echo '<a href="schema_edit.php?' . PMA_generate_common_url($db).'&do=selectpage&chpage='.$pageNumber.'&action_choose=0'
. '">' . __('Back') . '</a>';
echo "\n";
require_once './libraries/footer.inc.php';
exit();
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,854 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
include_once("Export_Relation_Schema.class.php");
/**
* This Class inherits the XMLwriter class and
* helps in developing structure of SVG Schema Export
*
* @name PMA_SVG
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @access public
* @see http://php.net/manual/en/book.xmlwriter.php
*/
class PMA_SVG extends XMLWriter
{
public $title;
public $author;
public $font;
public $fontSize;
/**
* The "PMA_SVG" constructor
*
* Upon instantiation This starts writing the Svg XML document
*
* @return void
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
*/
function __construct()
{
$this->openMemory();
/*
* Set indenting using three spaces,
* so output is formatted
*/
$this->setIndent(TRUE);
$this->setIndentString(' ');
/*
* Create the XML document
*/
$this->startDocument('1.0','UTF-8');
$this->startDtd('svg','-//W3C//DTD SVG 1.1//EN','http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd');
$this->endDtd();
}
/**
* Set document title
*
* @param string value sets the title text
* @return void
* @access public
*/
function setTitle($value)
{
$this->title = $value;
}
/**
* Set document author
*
* @param string value sets the author
* @return void
* @access public
*/
function setAuthor($value)
{
$this->author = $value;
}
/**
* Set document font
*
* @param string value sets the font e.g Arial, Sans-serif etc
* @return void
* @access public
*/
function setFont($value)
{
$this->font = $value;
}
/**
* Get document font
*
* @return string returns the font name
* @access public
*/
function getFont()
{
return $this->font;
}
/**
* Set document font size
*
* @param string value sets the font size in pixels
* @return void
* @access public
*/
function setFontSize($value)
{
$this->fontSize = $value;
}
/**
* Get document font size
*
* @return string returns the font size
* @access public
*/
function getFontSize()
{
return $this->fontSize;
}
/**
* Starts Svg Document
*
* svg document starts by first initializing svg tag
* which contains all the attributes and namespace that needed
* to define the svg document
*
* @param integer width total width of the Svg document
* @param integer height total height of the Svg document
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute()
*/
function startSvgDoc($width,$height)
{
$this->startElement('svg');
$this->writeAttribute('width', $width);
$this->writeAttribute('height', $height);
$this->writeAttribute('xmlns', 'http://www.w3.org/2000/svg');
$this->writeAttribute('version', '1.1');
}
/**
* Ends Svg Document
*
* @return void
* @access public
* @see XMLWriter::endElement(),XMLWriter::endDocument()
*/
function endSvgDoc()
{
$this->endElement();
$this->endDocument();
}
/**
* output Svg Document
*
* svg document prompted to the user for download
* Svg document saved in .svg extension and can be
* easily changeable by using any svg IDE
*
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute()
*/
function showOutput($fileName)
{
//ob_get_clean();
header('Content-type: image/svg+xml');
header('Content-Disposition: attachment; filename="'.$fileName.'.svg"');
$output = $this->flush();
print $output;
}
/**
* Draws Svg elements
*
* SVG has some predefined shape elements like rectangle & text
* and other elements who have x,y co-ordinates are drawn.
* specify their width and height and can give styles too.
*
* @param string name Svg element name
* @param integer x The x attribute defines the left position of the element
(e.g. x="0" places the element 0 pixels from the left of
the browser window)
* @param integer y The y attribute defines the top position of the element
(e.g. y="0" places the element 0 pixels from the top of
the browser window)
* @param integer width The width attribute defines the width the element
* @param integer height The height attribute defines the height the element
* @param string text The text attribute defines the text the element
* @param string styles The style attribute defines the style the element
styles can be defined like CSS styles
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute(),XMLWriter::text(),XMLWriter::endElement()
*/
function printElement($name,$x,$y,$width = '',$height = '',$text = '',$styles = '')
{
$this->startElement($name);
$this->writeAttribute('width',$width);
$this->writeAttribute('height',$height);
$this->writeAttribute('x', $x);
$this->writeAttribute('y', $y);
$this->writeAttribute('style', $styles);
if(isset($text)){
$this->writeAttribute('font-family', $this->font);
$this->writeAttribute('font-size', $this->fontSize);
$this->text($text);
}
$this->endElement();
}
/**
* Draws Svg Line element
*
* Svg line element is drawn for connecting the tables.
* arrows are also drawn by specify its start and ending
* co-ordinates
*
* @param string name Svg element name i.e line
* @param integer x1 The x1 attribute defines the start of the line on the x-axis
* @param integer y1 The y1 attribute defines the start of the line on the y-axis
* @param integer x2 The x2 attribute defines the end of the line on the x-axis
* @param integer y2 The y2 attribute defines the end of the line on the y-axis
* @param string styles The style attribute defines the style the element
styles can be defined like CSS styles
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute(),XMLWriter::endElement()
*/
function printElementLine($name,$x1,$y1,$x2,$y2,$styles)
{
$this->startElement($name);
$this->writeAttribute('x1',$x1);
$this->writeAttribute('y1',$y1);
$this->writeAttribute('x2', $x2);
$this->writeAttribute('y2', $y2);
$this->writeAttribute('style', $styles);
$this->endElement();
}
/**
* get width of string/text
*
* Svg text element width is calcualted depending on font name
* and font size. It is very important to know the width of text
* because rectangle is drawn around it.
*
* This is a bit hardcore method. I didn't found any other than this.
*
* @param string text string that width will be calculated
* @param integer font name of the font like Arial,sans-serif etc
* @param integer fontSize size of font
* @return integer width of the text
* @access public
*/
function getStringWidth($text,$font,$fontSize)
{
/*
* Start by counting the width, giving each character a modifying value
*/
$count = 0;
$count = $count + ((strlen($text) - strlen(str_replace(array("i","j","l"),"",$text)))*0.23);//ijl
$count = $count + ((strlen($text) - strlen(str_replace(array("f"),"",$text)))*0.27);//f
$count = $count + ((strlen($text) - strlen(str_replace(array("t","I"),"",$text)))*0.28);//tI
$count = $count + ((strlen($text) - strlen(str_replace(array("r"),"",$text)))*0.34);//r
$count = $count + ((strlen($text) - strlen(str_replace(array("1"),"",$text)))*0.49);//1
$count = $count + ((strlen($text) - strlen(str_replace(array("c","k","s","v","x","y","z","J"),"",$text)))*0.5);//cksvxyzJ
$count = $count + ((strlen($text) - strlen(str_replace(array("a","b","d","e","g","h","n","o","p","q","u","L","0","2","3","4","5","6","7","8","9"),"",$text)))*0.56);//abdeghnopquL023456789
$count = $count + ((strlen($text) - strlen(str_replace(array("F","T","Z"),"",$text)))*0.61);//FTZ
$count = $count + ((strlen($text) - strlen(str_replace(array("A","B","E","K","P","S","V","X","Y"),"",$text)))*0.67);//ABEKPSVXY
$count = $count + ((strlen($text) - strlen(str_replace(array("w","C","D","H","N","R","U"),"",$text)))*0.73);//wCDHNRU
$count = $count + ((strlen($text) - strlen(str_replace(array("G","O","Q"),"",$text)))*0.78);//GOQ
$count = $count + ((strlen($text) - strlen(str_replace(array("m","M"),"",$text)))*0.84);//mM
$count = $count + ((strlen($text) - strlen(str_replace("W","",$text)))*.95);//W
$count = $count + ((strlen($text) - strlen(str_replace(" ","",$text)))*.28);//" "
$text = str_replace(" ","",$text);//remove the " "'s
$count = $count + (strlen(preg_replace("/[a-z0-9]/i","",$text))*0.3); //all other chrs
$modifier = 1;
$font = strtolower($font);
switch($font){
/*
* no modifier for arial and sans-serif
*/
case 'arial':
case 'sans-serif':
break;
/*
* .92 modifer for time, serif, brushscriptstd, and californian fb
*/
case 'times':
case 'serif':
case 'brushscriptstd':
case 'californian fb':
$modifier = .92;
break;
/*
* 1.23 modifier for broadway
*/
case 'broadway':
$modifier = 1.23;
break;
}
$textWidth = $count*$fontSize;
return ceil($textWidth*$modifier);
}
}
/**
* Table preferences/statistics
*
* This class preserves the table co-ordinates,fields
* and helps in drawing/generating the Tables in SVG XML document.
*
* @name Table_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_SVG
*/
class Table_Stats
{
/**
* Defines properties
*/
private $_tableName;
private $_showInfo = false;
public $width = 0;
public $height;
public $fields = array();
public $heightCell = 0;
public $currentCell = 0;
public $x, $y;
public $primary = array();
/**
* The "Table_Stats" constructor
*
* @param string table_name The table name
* @param integer ff The font size
* @param integer samewidth The max. with among tables
* @param boolean show_keys Whether to display keys or not
* @param boolean show_info Whether to display table position or not
* @global object The current SVG image document
* @global integer The current page number (from the
* $cfg['Servers'][$i]['table_coords'] table)
* @global array The relations settings
* @global string The current db name
* @access private
* @see PMA_SVG, Table_Stats::Table_Stats_setWidth,
Table_Stats::Table_Stats_setHeight
*/
function __construct($tableName, $font, $fontSize, $pageNumber, &$same_wide_width, $showKeys = false, $showInfo = false)
{
global $svg, $cfgRelation, $db;
$this->_tableName = $tableName;
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$svg->dieSchema($pageNumber,"SVG",sprintf(__('The %s table doesn\'t exist!'), $tableName));
}
/*
* load fields
* check to see if it will load all fields or only the foreign keys
*/
if ($showKeys) {
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
$all_columns = array();
foreach ($indexes as $index) {
$all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns())));
}
$this->fields = array_keys($all_columns);
} else {
while ($row = PMA_DBI_fetch_row($result)) {
$this->fields[] = $row[0];
}
}
$this->_showInfo = $showInfo;
// height and width
$this->_setHeightTable($fontSize);
// setWidth must me after setHeight, because title
// can include table height which changes table width
$this->_setWidthTable($font,$fontSize);
if ($same_wide_width < $this->width) {
$same_wide_width = $this->width;
}
// x and y
$sql = 'SELECT x, y FROM '
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($tableName) . '\''
. ' AND pdf_page_number = ' . $pageNumber;
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$svg->dieSchema($pageNumber,"SVG",sprintf(__('Please configure the coordinates for table %s'), $tableName));
}
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
$this->x = (double) $this->x;
$this->y = (double) $this->y;
// displayfield
$this->displayfield = PMA_getDisplayField($db, $tableName);
// index
$result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE);
if (PMA_DBI_num_rows($result) > 0) {
while ($row = PMA_DBI_fetch_assoc($result)) {
if ($row['Key_name'] == 'PRIMARY') {
$this->primary[] = $row['Column_name'];
}
}
}
}
/**
* Returns title of the current table,
* title can have the dimensions/co-ordinates of the table
*
* @access private
*/
private function _getTitle()
{
return ($this->_showInfo ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell) : '') . ' ' . $this->_tableName;
}
/**
* Sets the width of the table
*
* @param string font The font size
* @param integer fontSize The font size
* @global object The current SVG image document
* @access private
* @see PMA_SVG
*/
function _setWidthTable($font,$fontSize)
{
global $svg;
foreach ($this->fields as $field) {
$this->width = max($this->width, $svg->getStringWidth($field,$font,$fontSize));
}
$this->width += $svg->getStringWidth(' ',$font,$fontSize);
/*
* it is unknown what value must be added, because
* table title is affected by the tabe width value
*/
while ($this->width < $svg->getStringWidth($this->_getTitle(),$font,$fontSize)) {
$this->width += 7;
}
}
/**
* Sets the height of the table
*
* @access private
*/
function _setHeightTable($fontSize)
{
$this->heightCell = $fontSize + 4;
$this->height = (count($this->fields) + 1) * $this->heightCell;
}
/**
* draw the table
*
* @param boolean showColor Whether to display color
* @global object The current SVG image document
* @access public
* @see PMA_SVG,PMA_SVG::printElement
*/
public function tableDraw($showColor)
{
global $svg;
//echo $this->_tableName.'<br />';
$svg->printElement('rect',$this->x,$this->y,
$this->width,$this->heightCell,
NULL,'fill:red;stroke:black;'
);
$svg->printElement('text',$this->x + 5,$this->y+ 14,
$this->width,$this->heightCell,
$this->_getTitle(),
'fill:none;stroke:black;'
);
foreach ($this->fields as $field) {
$this->currentCell += $this->heightCell;
$showColor = 'none';
if ($showColor) {
if (in_array($field, $this->primary)) {
$showColor = '#0c0';
}
if ($field == $this->displayfield) {
$showColor = 'none';
}
}
$svg->printElement('rect', $this->x,$this->y + $this->currentCell,
$this->width, $this->heightCell,
NULL,
'fill:'.$showColor.';stroke:black;'
);
$svg->printElement('text', $this->x + 5, $this->y + 14 + $this->currentCell,
$this->width, $this->heightCell,
$field,
'fill:none;stroke:black;'
);
}
}
}
/**
* Relation preferences/statistics
*
* This class fetches the table master and foreign fields positions
* and helps in generating the Table references and then connects
* master table's master field to foreign table's foreign key
* in SVG XML document.
*
* @name Relation_Stats
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @see PMA_SVG::printElementLine
*/
class Relation_Stats
{
/**
* Defines properties
*/
public $xSrc, $ySrc;
public $srcDir ;
public $destDir;
public $xDest, $yDest;
public $wTick = 10;
/**
* The "Relation_Stats" constructor
*
* @param string master_table The master table name
* @param string master_field The relation field in the master table
* @param string foreign_table The foreign table name
* @param string foreigh_field The relation field in the foreign table
* @see Relation_Stats::_getXy
*/
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
{
$src_pos = $this->_getXy($master_table, $master_field);
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
/*
* [0] is x-left
* [1] is x-right
* [2] is y
*/
$src_left = $src_pos[0] - $this->wTick;
$src_right = $src_pos[1] + $this->wTick;
$dest_left = $dest_pos[0] - $this->wTick;
$dest_right = $dest_pos[1] + $this->wTick;
$d1 = abs($src_left - $dest_left);
$d2 = abs($src_right - $dest_left);
$d3 = abs($src_left - $dest_right);
$d4 = abs($src_right - $dest_right);
$d = min($d1, $d2, $d3, $d4);
if ($d == $d1) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d2) {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d3) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
} else {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
}
$this->ySrc = $src_pos[2];
$this->yDest = $dest_pos[2];
}
/**
* Gets arrows coordinates
*
* @param string table The current table name
* @param string column The relation column name
* @return array Arrows coordinates
* @access private
*/
function _getXy($table, $column)
{
$pos = array_search($column, $table->fields);
// x_left, x_right, y
return array($table->x, $table->x + $table->width, $table->y + ($pos + 1.5) * $table->heightCell);
}
/**
* draws relation links and arrows
* shows foreign key relations
*
* @param boolean changeColor Whether to use one color per relation or not
* @global object The current SVG image document
* @access public
* @see PMA_SVG
*/
public function relationDraw($changeColor)
{
global $svg;
if ($changeColor) {
$listOfColors = array(
'red',
'grey',
'black',
'yellow',
'green',
'cyan',
' orange'
);
shuffle($listOfColors);
$color = $listOfColors[0];
} else {
$color = 'black';
}
$svg->printElementLine('line',$this->xSrc,$this->ySrc,
$this->xSrc + $this->srcDir * $this->wTick,$this->ySrc,
'fill:'.$color.';stroke:black;stroke-width:2;'
);
$svg->printElementLine('line',$this->xDest + $this->destDir * $this->wTick, $this->yDest,
$this->xDest, $this->yDest,
'fill:'.$color.';stroke:black;stroke-width:2;'
);
$svg->printElementLine('line',$this->xSrc + $this->srcDir * $this->wTick,$this->ySrc,
$this->xDest + $this->destDir * $this->wTick, $this->yDest,
'fill:'.$color.';stroke:'.$color.';stroke-width:1;'
);
$root2 = 2 * sqrt(2);
$svg->printElementLine('line',$this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick ,
$this->ySrc + $this->wTick / $root2 ,
'fill:'.$color.';stroke:black;stroke-width:2;'
);
$svg->printElementLine('line',$this->xSrc + $this->srcDir * $this->wTick * 0.75, $this->ySrc,
$this->xSrc + $this->srcDir * (0.75 - 1 / $root2) * $this->wTick ,
$this->ySrc - $this->wTick / $root2 ,
'fill:'.$color.';stroke:black;stroke-width:2;'
);
$svg->printElementLine('line',$this->xDest + $this->destDir * $this->wTick / 2 , $this->yDest ,
$this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick,
$this->yDest + $this->wTick / $root2 ,
'fill:'.$color.';stroke:black;stroke-width:2;');
$svg->printElementLine('line',$this->xDest + $this->destDir * $this->wTick / 2 ,
$this->yDest , $this->xDest + $this->destDir * (0.5 + 1 / $root2) * $this->wTick ,
$this->yDest - $this->wTick / $root2 ,
'fill:'.$color.';stroke:black;stroke-width:2;'
);
}
}
/*
* end of the "Relation_Stats" class
*/
/**
* Svg Relation Schema Class
*
* Purpose of this class is to generate the SVG XML Document because
* SVG defines the graphics in XML format which is used for representing
* the database diagrams as vector image. This class actually helps
* in preparing SVG XML format.
*
* SVG XML is generated by using XMLWriter php extension and this class
* inherits Export_Relation_Schema class has common functionality added
* to this class
*
* @name Svg_Relation_Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_Svg_Relation_Schema extends PMA_Export_Relation_Schema
{
private $tables = array();
private $_relations = array();
private $_xMax = 0;
private $_yMax = 0;
private $scale;
private $_xMin = 100000;
private $_yMin = 100000;
private $t_marg = 10;
private $b_marg = 10;
private $l_marg = 10;
private $r_marg = 10;
private $_tablewidth;
/**
* The "PMA_Svg_Relation_Schema" constructor
*
* Upon instantiation This starts writing the SVG XML document
* user will be prompted for download as .svg extension
*
* @return void
* @see PMA_SVG
*/
function __construct()
{
global $svg,$db;
$this->setPageNumber($_POST['pdf_page_number']);
$this->setShowColor(isset($_POST['show_color']));
$this->setShowKeys(isset($_POST['show_keys']));
$this->setTableDimension(isset($_POST['show_table_dimension']));
$this->setAllTableSameWidth(isset($_POST['all_table_same_wide']));
$this->setExportType($_POST['export_type']);
$svg = new PMA_SVG();
$svg->setTitle(sprintf(__('Schema of the %s database - Page %s'), $db, $this->pageNumber));
$svg->SetAuthor('phpMyAdmin ' . PMA_VERSION);
$svg->setFont('Arial');
$svg->setFontSize('16px');
$svg->startSvgDoc('1000px','1000px');
$alltables = $this->getAllTables($db,$this->pageNumber);
foreach ($alltables AS $table) {
if (!isset($this->tables[$table])) {
$this->tables[$table] = new Table_Stats($table,$svg->getFont(),$svg->getFontSize(), $this->pageNumber, $this->_tablewidth, $this->showKeys, $this->tableDimension);
}
if ($this->sameWide) {
$this->tables[$table]->width = $this->_tablewidth;
}
$this->_setMinMax($this->tables[$table]);
}
$seen_a_relation = false;
foreach ($alltables as $one_table) {
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
if ($exist_rel) {
$seen_a_relation = true;
foreach ($exist_rel as $master_field => $rel) {
/* put the foreign table on the schema only if selected
* by the user
* (do not use array_search() because we would have to
* to do a === FALSE and this is not PHP3 compatible)
*/
if (in_array($rel['foreign_table'], $alltables)) {
$this->_addRelation($one_table,$svg->getFont(),$svg->getFontSize(), $master_field, $rel['foreign_table'], $rel['foreign_field'], $this->tableDimension);
}
}
}
}
if ($seen_a_relation) {
$this->_drawRelations($this->showColor);
}
$this->_drawTables($this->showColor);
$svg->endSvgDoc();
$svg->showOutput($db.'-'.$this->pageNumber);
exit();
}
/**
* Sets X and Y minimum and maximum for a table cell
*
* @param string table The table name
* @access private
*/
private function _setMinMax($table)
{
$this->_xMax = max($this->_xMax, $table->x + $table->width);
$this->_yMax = max($this->_yMax, $table->y + $table->height);
$this->_xMin = min($this->_xMin, $table->x);
$this->_yMin = min($this->_yMin, $table->y);
}
/**
* Defines relation objects
*
* @param string masterTable The master table name
* @param string masterField The relation field in the master table
* @param string foreignTable The foreign table name
* @param string foreignField The relation field in the foreign table
* @param boolean showInfo Whether to display table position or not
* @access private
* @see _setMinMax,Table_Stats::__construct(),Relation_Stats::__construct()
*/
private function _addRelation($masterTable,$font,$fontSize, $masterField, $foreignTable, $foreignField, $showInfo)
{
if (!isset($this->tables[$masterTable])) {
$this->tables[$masterTable] = new Table_Stats($masterTable, $font, $fontSize, $this->pageNumber, $this->_tablewidth, false, $showInfo);
$this->_setMinMax($this->tables[$masterTable]);
}
if (!isset($this->tables[$foreignTable])) {
$this->tables[$foreignTable] = new Table_Stats($foreignTable,$font,$fontSize,$this->pageNumber, $this->_tablewidth, false, $showInfo);
$this->_setMinMax($this->tables[$foreignTable]);
}
$this->_relations[] = new Relation_Stats($this->tables[$masterTable], $masterField, $this->tables[$foreignTable], $foreignField);
}
/**
* Draws relation arrows and lines
* connects master table's master field to
* foreign table's forein field
*
* @param boolean changeColor Whether to use one color per relation or not
* @access private
* @see Relation_Stats::relationDraw()
*/
private function _drawRelations($changeColor)
{
foreach ($this->_relations as $relation) {
$relation->relationDraw($changeColor);
}
}
/**
* Draws tables
*
* @param boolean changeColor Whether to show color for primary fields or not
* @access private
* @see Table_Stats::Table_Stats_tableDraw()
*/
private function _drawTables($changeColor)
{
foreach ($this->tables as $table) {
$table->tableDraw($changeColor);
}
}
}
?>

View File

@@ -0,0 +1,819 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
/**
* This Class interacts with the user to gather the information
* about their tables for which they want to export the relational schema
* export options are shown to user from they can choose
*
* @name User_Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_User_Schema
{
public $choosenPage;
public $autoLayoutForeign;
public $autoLayoutInternal;
public $pageNumber;
public $c_table_rows;
public $action;
public function setAction($value)
{
$this->action = $value;
}
/**
* This function will process the user defined pages
* and tables which will be exported as Relational schema
* you can set the table positions on the paper via scratchboard
* for table positions, put the x,y co-ordinates
*
* @param string $this->action It tells what the Schema is supposed to do
* create and select a page, generate schema etc
* @access public
*/
public function processUserPreferences()
{
global $action_choose,$db,$cfgRelation,$cfg,$query_default_option;
if (isset($this->action)) {
switch ($this->action) {
case 'selectpage':
$this->choosenPage = $_REQUEST['chpage'];
if ($action_choose=="1") {
$this->deleteCoordinates($db, $cfgRelation, $this->choosenPage, $query_default_option);
$this->deletePages($db, $cfgRelation, $this->choosenPage, $query_default_option);
$this->choosenPage = 0;
}
break;
case 'createpage':
$this->pageNumber = PMA_REL_create_page($_POST['newpage'], $cfgRelation, $db, $query_default_option);
$this->autoLayoutForeign = isset($_POST['auto_layout_foreign']) ? "1":NULL;
$this->autoLayoutInternal = isset($_POST['auto_layout_internal']) ? "1":NULL;
$this->processRelations($db, $this->pageNumber,$cfgRelation,$query_default_option);
break;
case 'edcoord':
$this->choosenPage = $_POST['chpage'];
$this->c_table_rows = $_POST['c_table_rows'];
$this->_editCoordinates($db, $cfgRelation,$query_default_option);
break;
case 'deleteCrap':
$this->_deleteTableRows($delrow,$cfgRelation,$db,$this->choosenPage);
break;
case 'process_export':
$this->_processExportSchema();
break;
} // end switch
} // end if (isset($do))
}
/**
* shows/displays the HTML FORM to create the page
*
* @param string db name of the selected database
* @return void
* @access public
*/
public function createPage($db)
{
?>
<form method="post" action="schema_edit.php" name="frm_create_page">
<fieldset>
<legend>
<?php echo __('Create a page') . "\n"; ?>
</legend>
<?php echo PMA_generate_common_hidden_inputs($db); ?>
<input type="hidden" name="do" value="createpage" />
<table>
<tr>
<td><label for="id_newpage"><?php echo __('Page name'); ?></label></td>
<td><input type="text" name="newpage" id="id_newpage" size="20" maxlength="50" /></td>
</tr>
<tr>
<td><?php echo __('Automatic layout based on'); ?></td>
<td>
<input type="checkbox" name="auto_layout_internal" id="id_auto_layout_internal" /><label for="id_auto_layout_internal">
<?php echo __('Internal relations'); ?></label><br />
<?php
/*
* Check to see whether INNODB and PBXT storage engines are Available in MYSQL PACKAGE
* If available, then provide AutoLayout for Foreign Keys in Schema View
*/
if (PMA_StorageEngine::isValid('InnoDB') || PMA_StorageEngine::isValid('PBXT')) {
?>
<input type="checkbox" name="auto_layout_foreign" id="id_auto_layout_foreign" /><label for="id_auto_layout_foreign">
<?php echo __('FOREIGN KEY'); ?></label><br />
<?php
}
?>
</td></tr>
</table>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" />
</fieldset>
</form>
<?php
}
/**
* shows/displays the created page names in a drop down list
* User can select any page number and edit it using dashboard etc
*
* @return void
* @access public
*/
public function selectPage()
{
global $db,$table,$query_default_option,$cfgRelation;
$page_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'';
$page_rs = PMA_query_as_controluser($page_query, FALSE, $query_default_option);
if ($page_rs && PMA_DBI_num_rows($page_rs) > 0) {
?>
<form method="get" action="schema_edit.php" name="frm_select_page">
<fieldset>
<legend>
<?php echo __('Please choose a page to edit') . "\n"; ?>
</legend>
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="do" value="selectpage" />
<select name="chpage" id="chpage" onchange="this.form.submit()">
<option value="0"><?php echo __('Select page'); ?></option>
<?php
while ($curr_page = PMA_DBI_fetch_assoc($page_rs)) {
echo "\n" . ' '
. '<option value="' . $curr_page['page_nr'] . '"';
if (isset($this->choosenPage) && $this->choosenPage == $curr_page['page_nr']) {
echo ' selected="selected"';
}
echo '>' . $curr_page['page_nr'] . ': ' . htmlspecialchars($curr_page['page_descr']) . '</option>';
} // end while
echo "\n";
?>
</select>
<?php
$choices = array(
'0' => __('Edit'),
'1' => __('Delete')
);
PMA_display_html_radio('action_choose', $choices, '0', false);
unset($choices);
?>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" /><br />
</fieldset>
</form>
<?php
} // end IF
echo "\n";
} // end function
/**
* A dashboard is displayed to AutoLayout the position of tables
* users can drag n drop the tables and change their positions
*
* @return void
* @access public
*/
public function showTableDashBoard()
{
global $db,$cfgRelation,$table,$cfg,$with_field_names,$query_default_option;
/*
* We will need an array of all tables in this db
*/
$selectboxall = array('--');
$alltab_rs = PMA_DBI_query('SHOW TABLES FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
$selectboxall[] = $val[0];
}
/*
* Now if we already have chosen a page number then we should
* show the tables involved
*/
if (isset($this->choosenPage) && $this->choosenPage > 0) {
echo "\n";
?>
<h2><?php echo __('Select Tables') ;?></h2>
<?php
$page_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($this->choosenPage) . '\'';
$page_rs = PMA_query_as_controluser($page_query, FALSE, $query_default_option);
$array_sh_page = array();
$draginit = '';
$reset_draginit = '';
$i = 0;
while ($temp_sh_page = @PMA_DBI_fetch_assoc($page_rs)) {
$array_sh_page[] = $temp_sh_page;
}
/*
* Display WYSIWYG parts
*/
if (!isset($_POST['with_field_names']) && !isset($_POST['showwysiwyg'])) {
$with_field_names = TRUE;
}
$this->_displayScratchboardTables($array_sh_page,$draginit,$reset_draginit);
?>
<form method="post" action="schema_edit.php" name="edcoord">
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="chpage" value="<?php echo htmlspecialchars($this->choosenPage); ?>" />
<input type="hidden" name="do" value="edcoord" />
<table border="0">
<tr>
<th><?php echo __('Table'); ?></th>
<th><?php echo __('Delete'); ?></th>
<th>X</th>
<th>Y</th>
</tr>
<?php
if (isset($ctable)) {
unset($ctable);
}
$i = 0;
$odd_row = true;
foreach ($array_sh_page as $dummy_sh_page => $sh_page) {
$_mtab = $sh_page['table_name'];
$tabExist[$_mtab] = FALSE;
echo "\n" . ' <tr class="';
if ($odd_row) {
echo 'odd';
} else {
echo 'even';
}
echo '">';
$odd_row != $odd_row;
echo "\n" . ' <td>'
. "\n" . ' <select name="c_table_' . $i . '[name]">';
foreach ($selectboxall as $key => $value) {
echo "\n" . ' <option value="' . htmlspecialchars($value) . '"';
if ($value == $sh_page['table_name']) {
echo ' selected="selected"';
$tabExist[$_mtab] = TRUE;
}
echo '>' . htmlspecialchars($value) . '</option>';
}
echo "\n" . ' </select>'
. "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="checkbox" name="c_table_' . $i . '[delete]" value="y" />' . __('Delete');
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" onchange="dragPlace(' . $i . ', \'x\', this.value)" name="c_table_' . $i . '[x]" value="' . $sh_page['x'] . '" />';
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" onchange="dragPlace(' . $i . ', \'y\', this.value)" name="c_table_' . $i . '[y]" value="' . $sh_page['y'] . '" />';
echo "\n" . ' </td>';
echo "\n" . ' </tr>';
$i++;
}
/*
* Add one more empty row
*/
echo "\n" . ' <tr class="';
if ($odd_row) {
echo 'odd';
} else {
echo 'even';
}
$odd_row != $odd_row;
echo '">';
echo "\n" . ' <td>'
. "\n" . ' <select name="c_table_' . $i . '[name]">';
foreach ($selectboxall as $key => $value) {
echo "\n" . ' <option value="' . htmlspecialchars($value) . '">' . htmlspecialchars($value) . '</option>';
}
echo "\n" . ' </select>'
. "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="checkbox" name="c_table_' . $i . '[delete]" value="y" />' . __('Delete');
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" name="c_table_' . $i . '[x]" value="' . (isset($sh_page['x'])?$sh_page['x']:'') . '" />';
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" name="c_table_' . $i . '[y]" value="' . (isset($sh_page['y'])?$sh_page['y']:'') . '" />';
echo "\n" . ' </td>';
echo "\n" . ' </tr>';
echo "\n" . ' </table>' . "\n";
echo "\n" . ' <input type="hidden" name="c_table_rows" value="' . ($i + 1) . '" />';
echo "\n" . ' <input type="hidden" id="showwysiwyg" name="showwysiwyg" value="' . ((isset($showwysiwyg) && $showwysiwyg == '1') ? '1' : '0') . '" />';
echo "\n" . ' <input type="checkbox" name="with_field_names" ' . (isset($with_field_names) ? 'checked="checked"' : ''). ' />' . __('Column names') . '<br />';
echo "\n" . ' <input type="submit" value="' . __('Save') . '" />';
echo "\n" . '</form>' . "\n\n";
} // end if
$this->_deleteTables($db, $this->choosenPage, isset($tabExist));
}
/**
* show Export relational schema generation options
* user can select export type of his own choice
* and the attributes related to it
*
* @return void
* @access public
*/
public function displaySchemaGenerationOptions()
{
global $cfg,$pmaThemeImage,$db,$test_rs,$chpage;
?>
<form method="post" action="schema_export.php">
<fieldset>
<legend>
<?php
echo PMA_generate_common_hidden_inputs($db);
if ($cfg['PropertiesIconic']) {
echo '<img class="icon" src="' . $pmaThemeImage . 'b_view.png"'
.' alt="" width="16" height="16" />';
}
echo __('Display relational schema');
?>:
</legend>
<select name="export_type" id="export_type">
<option value="pdf" selected="selected"><?php echo __('PDF');?></option>
<option value="svg"><?php echo __('SVG');?></option>
<option value="dia"><?php echo __('DIA');?></option>
<option value="visio"><?php echo __('VISIO');?></option>
<option value="eps"><?php echo __('EPS');?></option>
</select>
<label><?php echo __('Select Export Relational Type');?></label><br />
<?php
if (isset($test_rs)) {
?>
<label for="pdf_page_number_opt"><?php echo __('Page number:'); ?></label>
<select name="pdf_page_number" id="pdf_page_number_opt">
<?php
while ($pages = @PMA_DBI_fetch_assoc($test_rs)) {
echo ' <option value="' . $pages['page_nr'] . '">'
. $pages['page_nr'] . ': ' . htmlspecialchars($pages['page_descr']) . '</option>' . "\n";
} // end while
PMA_DBI_free_result($test_rs);
unset($test_rs);
?>
</select><br />
<?php } else { ?>
<input type="hidden" name="pdf_page_number" value="<?php echo htmlspecialchars($this->choosenPage); ?>" />
<?php } ?>
<input type="hidden" name="do" value="process_export" />
<input type="hidden" name="chpage" value="<?php echo $chpage; ?>" />
<input type="checkbox" name="show_grid" id="show_grid_opt" />
<label for="show_grid_opt"><?php echo __('Show grid'); ?></label><br />
<input type="checkbox" name="show_color" id="show_color_opt" checked="checked" />
<label for="show_color_opt"><?php echo __('Show color'); ?></label><br />
<input type="checkbox" name="show_table_dimension" id="show_table_dim_opt" />
<label for="show_table_dim_opt"><?php echo __('Show dimension of tables'); ?>
</label><br />
<input type="checkbox" name="all_table_same_wide" id="all_table_same_wide" />
<label for="all_table_same_wide"><?php echo __('Display all tables with the same width'); ?>
</label><br />
<input type="checkbox" name="with_doc" id="with_doc" checked="checked" />
<label for="with_doc"><?php echo __('Data Dictionary'); ?></label><br />
<input type="checkbox" name="show_keys" id="show_keys" />
<label for="show_keys"><?php echo __('Only show keys'); ?></label><br />
<select name="orientation" id="orientation_opt">
<option value="L"><?php echo __('Landscape');?></option>
<option value="P"><?php echo __('Portrait');?></option>
</select>
<label for="orientation_opt"><?php echo __('Orientation'); ?></label>
<br />
<select name="paper" id="paper_opt">
<?php
foreach ($cfg['PDFPageSizes'] as $key => $val) {
echo '<option value="' . $val . '"';
if ($val == $cfg['PDFDefaultPageSize']) {
echo ' selected="selected"';
}
echo ' >' . $val . '</option>' . "\n";
}
?>
</select>
<label for="paper_opt"><?php echo __('Paper size'); ?></label>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" />
</fieldset>
</form>
<?php
}
/**
* Check if there are tables that need to be deleted in dashboard,
* if there are, ask the user for allowance
*
* @param string db name of database selected
* @param integer chpage selected page
* @param array tabExist
* @return void
* @access private
*/
private function _deleteTables($db, $chpage, $tabExist)
{
$_strtrans = '';
$_strname = '';
$shoot = FALSE;
if (!empty($tabExist) && is_array($tabExist)) {
foreach ($tabExist as $key => $value) {
if (!$value) {
$_strtrans .= '<input type="hidden" name="delrow[]" value="' . htmlspecialchars($key) . '" />' . "\n";
$_strname .= '<li>' . htmlspecialchars($key) . '</li>' . "\n";
$shoot = TRUE;
}
}
if ($shoot) {
echo '<form action="schema_edit.php" method="post">' . "\n"
. PMA_generate_common_hidden_inputs($db, $table)
. '<input type="hidden" name="do" value="deleteCrap" />' . "\n"
. '<input type="hidden" name="chpage" value="' . htmlspecialchars($chpage) . '" />' . "\n"
. __('The current page has references to tables that no longer exist. Would you like to delete those references?')
. '<ul>' . "\n"
. $_strname
. '</ul>' . "\n"
. $_strtrans
. '<input type="submit" value="' . __('Go') . '" />' . "\n"
. '</form>';
}
}
}
/**
* Check if there are tables that need to be deleted in dashboard,
* if there are, ask the user for allowance
*
* @return void
* @access private
*/
private function _displayScratchboardTables($array_sh_page,$draginit,$reset_draginit)
{
global $with_field_names,$cfg,$db;
?>
<script type="text/javascript" src="./js/dom-drag.js"></script>
<form method="post" action="schema_edit.php" name="dragdrop">
<input type="button" name="dragdrop" value="<?php echo __('Toggle scratchboard'); ?>" onclick="ToggleDragDrop('pdflayout');" />
<input type="button" name="dragdropreset" value="<?php echo __('Reset'); ?>" onclick="resetDrag();" />
</form>
<div id="pdflayout" class="pdflayout" style="visibility: hidden;">
<?php
$i = 0;
foreach ($array_sh_page as $key => $temp_sh_page) {
$drag_x = $temp_sh_page['x'];
$drag_y = $temp_sh_page['y'];
$draginit .= ' Drag.init(getElement("table_' . $i . '"), null, 0, parseInt(myid.style.width)-2, 0, parseInt(myid.style.height)-5);' . "\n";
$draginit .= ' getElement("table_' . $i . '").onDrag = function (x, y) { document.edcoord.elements["c_table_' . $i . '[x]"].value = parseInt(x); document.edcoord.elements["c_table_' . $i . '[y]"].value = parseInt(y) }' . "\n";
$draginit .= ' getElement("table_' . $i . '").style.left = "' . $drag_x . 'px";' . "\n";
$draginit .= ' getElement("table_' . $i . '").style.top = "' . $drag_y . 'px";' . "\n";
$reset_draginit .= ' getElement("table_' . $i . '").style.left = "2px";' . "\n";
$reset_draginit .= ' getElement("table_' . $i . '").style.top = "' . (15 * $i) . 'px";' . "\n";
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[x]"].value = "2"' . "\n";
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[y]"].value = "' . (15 * $i) . '"' . "\n";
$local_query = 'SHOW FIELDS FROM '
. PMA_backquote($temp_sh_page['table_name'])
. ' FROM ' . PMA_backquote($db);
$fields_rs = PMA_DBI_query($local_query);
unset($local_query);
$fields_cnt = PMA_DBI_num_rows($fields_rs);
echo '<div id="table_' . $i . '" class="pdflayout_table"><u>' . $temp_sh_page['table_name'] . '</u>';
if (isset($with_field_names)) {
while ($row = PMA_DBI_fetch_assoc($fields_rs)) {
echo '<br />' . htmlspecialchars($row['Field']) . "\n";
}
}
echo '</div>' . "\n";
PMA_DBI_free_result($fields_rs);
unset($fields_rs);
$i++;
}
?>
</div>
<script type="text/javascript">
//<![CDATA[
function PDFinit() {
refreshLayout();
myid = getElement('pdflayout');
<?php echo $draginit; ?>
}
function resetDrag() {
<?php echo $reset_draginit; ?>
}
//]]>
</script>
<?php
}
/**
* delete the table rows with table co-ordinates
*
* @param int delrow delete selected table from list of tables
* @param array cfgRelation relation settings
* @param string db database name
* @param integer chpage selected page for adding relations etc
* @return void
* @access private
*/
private function _deleteTableRows($delrow,$cfgRelation,$db,$chpage)
{
foreach ($delrow as $current_row) {
$del_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' . "\n"
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' . "\n"
. ' AND table_name = \'' . PMA_sqlAddslashes($current_row) . '\'' . "\n"
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
echo $del_query;
PMA_query_as_controluser($del_query, FALSE, $query_default_option);
}
}
/**
* get all the export options and verify
* call and include the appropriate Schema Class depending on $export_type
*
* @return void
* @access private
*/
private function _processExportSchema()
{
/**
* Settings for relation stuff
*/
require_once './libraries/transformations.lib.php';
require_once './libraries/Index.class.php';
/**
* default is PDF
*/
global $db,$export_type;
$export_type = isset($export_type) ? $export_type : 'pdf';
PMA_DBI_select_db($db);
include("./libraries/schema/".ucfirst($export_type)."_Relation_Schema.class.php");
$obj_schema = eval("new PMA_".ucfirst($export_type)."_Relation_Schema();");
}
/**
* delete X and Y coordinates
*
* @param string db The database name
* @param array cfgRelation relation settings
* @param integer choosePage selected page for adding relations etc
* @return void
* @access private
*/
public function deleteCoordinates($db, $cfgRelation, $choosePage, $query_default_option)
{
$query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($choosePage) . '\'';
PMA_query_as_controluser($query, FALSE, $query_default_option);
}
/**
* delete pages
*
* @param string db The database name
* @param array cfgRelation relation settings
* @param integer choosePage selected page for adding relations etc
* @return void
* @access private
*/
public function deletePages($db, $cfgRelation, $choosePage, $query_default_option)
{
$query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND page_nr = \'' . PMA_sqlAddslashes($choosePage) . '\'';
PMA_query_as_controluser($query, FALSE, $query_default_option);
}
/**
* process internal and foreign key relations
*
* @param string db The database name
* @param array cfgRelation relation settings
* @param integer pageNumber document number/Id
* @return void
* @access private
*/
public function processRelations($db, $pageNumber, $cfgRelation, $query_default_option)
{
/*
* A u t o m a t i c l a y o u t
*
* There are 2 kinds of relations in PMA
* 1) Internal Relations 2) Foreign Key Relations
*/
if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
$all_tables = array();
}
if (isset($this->autoLayoutForeign)) {
/*
* get the tables list
* who support FOREIGN KEY, it's not
* important that we group together InnoDB tables
* and PBXT tables, as this logic is just to put
* the tables on the layout, not to determine relations
*/
$tables = PMA_DBI_get_tables_full($db);
$foreignkey_tables = array();
foreach($tables as $table_name => $table_properties) {
if (PMA_foreignkey_supported($table_properties['ENGINE'])) {
$foreignkey_tables[] = $table_name;
}
}
$all_tables = $foreignkey_tables;
/*
* could be improved by finding the tables which have the
* most references keys and placing them at the beginning
* of the array (so that they are all center of schema)
*/
unset($tables, $foreignkey_tables);
}
if (isset($this->autoLayoutInternal)) {
/*
* get the tables list who support Internal Relations;
* This type of relations will be created when
* you setup the PMA tables correctly
*/
$master_tables = 'SELECT COUNT(master_table), master_table'
. ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation'])
. ' WHERE master_db = \'' . $db . '\''
. ' GROUP BY master_table'
. ' ORDER BY ' . PMA_backquote('COUNT(master_table)') . ' DESC ';
$master_tables_rs = PMA_query_as_controluser($master_tables, FALSE, $query_default_option);
if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) {
/* first put all the master tables at beginning
* of the list, so they are near the center of
* the schema
*/
while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) {
$all_tables[] = $master_table;
}
/* Now for each master, add its foreigns into an array
* of foreign tables, if not already there
* (a foreign might be foreign for more than
* one table, and might be a master itself)
*/
$foreign_tables = array();
foreach ($all_tables as $master_table) {
$foreigners = PMA_getForeigners($db, $master_table);
foreach ($foreigners as $foreigner) {
if (!in_array($foreigner['foreign_table'], $foreign_tables)) {
$foreign_tables[] = $foreigner['foreign_table'];
}
}
}
/*
* Now merge the master and foreign arrays/tables
*/
foreach ($foreign_tables as $foreign_table) {
if (!in_array($foreign_table, $all_tables)) {
$all_tables[] = $foreign_table;
}
}
}
}
if (isset($this->autoLayoutInternal) || isset($this->autoLayoutForeign)) {
$this->addRelationCoordinates($all_tables,$pageNumber,$db, $cfgRelation,$query_default_option);
}
$this->choosenPage = $pageNumber;
}
/**
* Add X and Y coordinates for a table
*
* @param string db The database name
* @param array cfgRelation relation settings
* @param integer pageNumber document number/Id
* @param array all_tables A list of all tables involved
* @return void
* @access private
*/
public function addRelationCoordinates($all_tables,$pageNumber,$db, $cfgRelation,$query_default_option)
{
/*
* Now generate the coordinates for the schema
* in a clockwise spiral and add to co-ordinates table
*/
$pos_x = 300;
$pos_y = 300;
$delta = 110;
$delta_mult = 1.10;
$direction = "right";
foreach ($all_tables as $current_table) {
/*
* save current table's coordinates
*/
$insert_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. '(db_name, table_name, pdf_page_number, x, y) '
. 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($current_table) . '\',' . $pageNumber . ',' . $pos_x . ',' . $pos_y . ')';
PMA_query_as_controluser($insert_query, FALSE, $query_default_option);
/*
* compute for the next table
*/
switch ($direction) {
case 'right':
$pos_x += $delta;
$direction = "down";
$delta *= $delta_mult;
break;
case 'down':
$pos_y += $delta;
$direction = "left";
$delta *= $delta_mult;
break;
case 'left':
$pos_x -= $delta;
$direction = "up";
$delta *= $delta_mult;
break;
case 'up':
$pos_y -= $delta;
$direction = "right";
$delta *= $delta_mult;
break;
}
}
}
/**
* update X and Y coordinates for a table
*
* @param string db The database name
* @param array cfgRelation relation settings
* @return void
* @access private
*/
private function _editCoordinates($db, $cfgRelation,$query_default_option)
{
for ($i = 0; $i < $this->c_table_rows; $i++) {
$arrvalue = 'c_table_' . $i;
global $$arrvalue;
$arrvalue = $$arrvalue;
if (!isset($arrvalue['x']) || $arrvalue['x'] == '') {
$arrvalue['x'] = 0;
}
if (!isset($arrvalue['y']) || $arrvalue['y'] == '') {
$arrvalue['y'] = 0;
}
if (isset($arrvalue['name']) && $arrvalue['name'] != '--') {
$test_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($this->choosenPage) . '\'';
$test_rs = PMA_query_as_controluser($test_query, FALSE, $query_default_option);
//echo $test_query;
if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') {
$ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($this->choosenPage) . '\'';
} else {
$ch_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y']
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($this->choosenPage) . '\'';
}
} else {
$ch_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. '(db_name, table_name, pdf_page_number, x, y) '
. 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($arrvalue['name']) . '\', \'' . PMA_sqlAddslashes($this->choosenPage) . '\',' . $arrvalue['x'] . ',' . $arrvalue['y'] . ')';
}
//echo $ch_query;
PMA_query_as_controluser($ch_query, FALSE, $query_default_option);
} // end if
} // end for
}
}
?>

View File

@@ -0,0 +1,599 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @version $Id$
* @package phpMyAdmin
*/
include_once("Export_Relation_Schema.class.php");
/**
* This Class inherits the XMLwriter class and
* helps in developing structure of MS Visio Schema Export
*
* @name PMA_VISIO
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
* @access public
* @see http://php.net/manual/en/book.xmlwriter.php
*/
class PMA_VISIO extends XMLWriter
{
public $title;
public $author;
public $font;
public $fontSize;
/**
* The "PMA_VISIO" constructor
*
* Upon instantiation This starts writing the Visio XML .VDX document
*
* @return void
* @see XMLWriter::openMemory(),XMLWriter::setIndent(),XMLWriter::startDocument()
*/
function __construct()
{
$this->openMemory();
/*
* Set indenting using three spaces,
* so output is formatted
*/
$this->setIndent(TRUE);
$this->setIndentString(' ');
/*
* Create the XML document
*/
$this->startDocument('1.0','UTF-8');
}
/**
* Starts Visio XML .VDX Document
*
* Visio XML document starts by first initializing VisioDocument tag
* then DocumentProperties & DocumentSettings contains all the
* attributes that needed to define the document. Order of elements
* should be maintained while generating XML of Visio.
*
* @return void
* @access public
* @see XMLWriter::startElement(),XMLWriter::writeAttribute(),_documentProperties,_documentSettings
*/
function startVisioDoc()
{
$this->startElement('VisioDocument');
$this->writeAttribute('xmlns', 'http://schemas.microsoft.com/visio/2003/core');
$this->writeAttribute('xmlns:vx', 'http://schemas.microsoft.com/visio/2006/extension');
$this->writeAttribute('xml:space', 'preserve');
$this->_documentProperties();
$this->_documentSettings();
}
/**
* Set document title
*
* @param string value sets the title text
* @return void
* @access public
*/
function setTitle($value)
{
$this->title = $value;
}
/**
* Set document author
*
* @param string value sets the author
* @return void
* @access public
*/
function setAuthor($value)
{
$this->author = $value;
}
/**
* Sets Visio XML .VDX Document Properties
*
* DocumentProperties tag contains document property elements such as
the document's Title,Subject,Creator and templates tags
*
* @return void
* @access private
* @see XMLWriter::startElement(),XMLWriter::endElement(),XMLWriter::writeRaw()
*/
private function _documentProperties()
{
$this->startElement('DocumentProperties');
$this->writeRaw('<Title>'.$this->title.'</Title>');
$this->writeRaw('<Subject>'.$this->title.'</Subject>');
$this->writeRaw('<Creator>'.$this->author.'</Creator>');
$this->writeRaw('<Company>phpMyAdmin</Company>');
$this->writeRaw('<Template>c:\program files\microsoft office\office12\1033\DBMODL_U.VST</Template>');
$this->endElement();
}
/**
* Sets Visio XML .VDX Document Settings
*
* DocumentSettings tag contains elements that specify document settings.
*
* @return void
* @access private
* @see XMLWriter::startElement(),XMLWriter::endElement()
*/
private function _documentSettings()
{
$this->startElement('DocumentSettings');
$this->endElement();
}
/**
* Ends Visio XML Document
*
* @return void
* @access public
* @see XMLWriter::endElement(),XMLWriter::endDocument()
*/
function endVisioDoc()
{
$this->endElement();
$this->endDocument();
}
/**
* Output Visio XML .VDX Document for download
*
* @param string fileName name of the Visio XML document
* @return void
* @access public
* @see XMLWriter::flush()
*/
function showOutput($fileName)
{
//if(ob_get_clean()){
//ob_end_clean();
//}
header('Content-type: application/visio');
header('Content-Disposition: attachment; filename="'.$fileName.'.vdx"');
$output = $this->flush();
print $output;
}
}
/**
* Draws tables schema
*/
class Table_Stats
{
/**
* Defines properties
*/
private $_tableName;
private $_showInfo = false;
public $width = 0;
public $height;
public $fields = array();
public $heightCell = 0;
public $currentCell = 0;
public $x, $y;
public $primary = array();
/**
* The "Table_Stats" constructor
*
* @param string tableName The table name
* @param integer same_wide_width The max. with among tables
* @param boolean showKeys Whether to display keys or not
* @param boolean showInfo Whether to display table position or not
* @global object The current Visio XML document
* @global integer The current page number (from the
* $cfg['Servers'][$i]['table_coords'] table)
* @global array The relations settings
* @global string The current db name
* @access private
* @see PMA_VISIO, Table_Stats::Table_Stats_setWidth,
Table_Stats::Table_Stats_setHeight
*/
function __construct($tableName, $pageNumber, &$same_wide_width, $showKeys = false, $showInfo = false)
{
global $visio, $cfgRelation, $db;
$this->_tableName = $tableName;
$sql = 'DESCRIBE ' . PMA_backquote($tableName);
$result = PMA_DBI_try_query($sql, null, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$visio->dieSchema($pageNumber,"VISIO",sprintf(__('The %s table doesn\'t exist!'), $tableName));
}
/*
* load fields
* check to see if it will load all fields or only the foreign keys
*/
if ($showKeys) {
$indexes = PMA_Index::getFromTable($this->_tableName, $db);
$all_columns = array();
foreach ($indexes as $index) {
$all_columns = array_merge($all_columns, array_flip(array_keys($index->getColumns())));
}
$this->fields = array_keys($all_columns);
} else {
while ($row = PMA_DBI_fetch_row($result)) {
$this->fields[] = $row[0];
}
}
$this->_showInfo = $showInfo;
// height and width
$this->_setHeightTable($fontSize);
// setWidth must me after setHeight, because title
// can include table height which changes table width
$this->_setWidthTable($font,$fontSize);
if ($same_wide_width < $this->width) {
$same_wide_width = $this->width;
}
// x and y
$sql = 'SELECT x, y FROM '
. PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($tableName) . '\''
. ' AND pdf_page_number = ' . $pageNumber;
$result = PMA_query_as_controluser($sql, false, PMA_DBI_QUERY_STORE);
if (!$result || !PMA_DBI_num_rows($result)) {
$visio->dieSchema($pageNumber,"VISIO",sprintf(__('Please configure the coordinates for table %s'), $tableName));
}
list($this->x, $this->y) = PMA_DBI_fetch_row($result);
$this->x = (double) $this->x;
$this->y = (double) $this->y;
// displayfield
$this->displayfield = PMA_getDisplayField($db, $tableName);
// index
$result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($tableName) . ';', null, PMA_DBI_QUERY_STORE);
if (PMA_DBI_num_rows($result) > 0) {
while ($row = PMA_DBI_fetch_assoc($result)) {
if ($row['Key_name'] == 'PRIMARY') {
$this->primary[] = $row['Column_name'];
}
}
}
}
/**
* Returns title of the current table,
* title can have the dimensions/co-ordinates of the table
*
* @access private
*/
private function _getTitle()
{
return ($this->_showInfo ? sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->heightCell) : '') . ' ' . $this->_tableName;
}
/**
* Sets the width of the table
*
* @param string font The font name
* @param integer fontSize The font size
* @global object The current Visio XML document
* @access private
* @see PMA_VISIO
*/
function _setWidthTable($font,$fontSize)
{
global $visio;
}
/**
* Sets the height of the table
*
* @access private
*/
function _setHeightTable($fontSize)
{
$this->heightCell = $fontSize + 4;
$this->height = (count($this->fields) + 1) * $this->heightCell;
}
/**
* draw the table
*
* @param boolean showColor Whether to display color
* @global object The current Visio XML document
* @access public
* @see PMA_VISIO
*/
public function tableDraw($showColor)
{
global $visio;
//echo $this->_tableName.'<br />';
foreach ($this->fields as $field) {
$this->currentCell += $this->heightCell;
$showColor = 'none';
if ($showColor) {
if (in_array($field, $this->primary)) {
$showColor = '#0c0';
}
if ($field == $this->displayfield) {
$showColor = 'none';
}
}
// code here for drawing table diagrams
}
}
}
/**
* Draws relation links
*
* @access public
* @see PMA_VISIO
*/
class Relation_Stats
{
/**
* Defines properties
*/
public $xSrc, $ySrc;
public $srcDir ;
public $destDir;
public $xDest, $yDest;
public $wTick = 10;
/**
* The "Relation_Stats" constructor
*
* @param string master_table The master table name
* @param string master_field The relation field in the master table
* @param string foreign_table The foreign table name
* @param string foreigh_field The relation field in the foreign table
* @see Relation_Stats::_getXy
*/
function __construct($master_table, $master_field, $foreign_table, $foreign_field)
{
$src_pos = $this->_getXy($master_table, $master_field);
$dest_pos = $this->_getXy($foreign_table, $foreign_field);
/*
* [0] is x-left
* [1] is x-right
* [2] is y
*/
$src_left = $src_pos[0] - $this->wTick;
$src_right = $src_pos[1] + $this->wTick;
$dest_left = $dest_pos[0] - $this->wTick;
$dest_right = $dest_pos[1] + $this->wTick;
$d1 = abs($src_left - $dest_left);
$d2 = abs($src_right - $dest_left);
$d3 = abs($src_left - $dest_right);
$d4 = abs($src_right - $dest_right);
$d = min($d1, $d2, $d3, $d4);
if ($d == $d1) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d2) {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[0];
$this->destDir = -1;
} elseif ($d == $d3) {
$this->xSrc = $src_pos[0];
$this->srcDir = -1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
} else {
$this->xSrc = $src_pos[1];
$this->srcDir = 1;
$this->xDest = $dest_pos[1];
$this->destDir = 1;
}
$this->ySrc = $src_pos[2];
$this->yDest = $dest_pos[2];
}
/**
* Gets arrows coordinates
*
* @param string table The current table name
* @param string column The relation column name
* @return array Arrows coordinates
* @access private
*/
function _getXy($table, $column)
{
$pos = array_search($column, $table->fields);
// x_left, x_right, y
return array($table->x, $table->x + $table->width, $table->y + ($pos + 1.5) * $table->heightCell);
}
/**
* draws relation links and arrows
* shows foreign key relations
*
* @param boolean changeColor Whether to use one color per relation or not
* @global object The current Visio XML document
* @access public
* @see PMA_VISIO
*/
public function relationDraw($changeColor)
{
global $visio;
if ($changeColor) {
$listOfColors = array(
'red',
'grey',
'black',
'yellow',
'green',
'cyan',
' orange'
);
shuffle($listOfColors);
$color = $listOfColors[0];
} else {
$color = 'black';
}
// code here for making connections b/w relation objects
}
}
/*
* end of the "Relation_Stats" class
*/
/**
* Visio Relation Schema Class
*
* Purpose of this class is to generate the Visio XML .VDX Document
* which is used for representing the database diagrams in any version of MS Visio IDE.
* This class uses Software and Database Template and Database model diagram of Visio
* and with the combination of these objects actually helps in preparing Visio XML .VDX document.
*
* Visio XML is generated by using XMLWriter php extension and this class
* inherits Export_Relation_Schema class has common functionality added
* to this class
*
* @name Visio_Relation_Schema
* @author Muhammad Adnan <hiddenpearls@gmail.com>
* @copyright
* @license
*/
class PMA_Visio_Relation_Schema extends PMA_Export_Relation_Schema
{
/**
* The "PMA_Visio_Relation_Schema" constructor
*
* Upon instantiation This outputs the Visio XML document
* that user can download
*
* @return void
* @see PMA_VISIO,Table_Stats,Relation_Stats
*/
function __construct()
{
global $visio,$db;
$this->setPageNumber($_POST['pdf_page_number']);
$this->setShowGrid(isset($_POST['show_grid']));
$this->setShowColor($_POST['show_color']);
$this->setShowKeys(isset($_POST['show_keys']));
$this->setOrientation(isset($_POST['orientation']));
$this->setPaper($_POST['paper']);
$this->setExportType($_POST['export_type']);
$visio = new PMA_VISIO();
$visio->setTitle(sprintf(__('Schema of the %s database - Page %s'), $db, $this->pageNumber));
$visio->SetAuthor('phpMyAdmin ' . PMA_VERSION);
$visio->startVisioDoc();
$alltables = $this->getAllTables($db,$this->pageNumber);
foreach ($alltables as $table) {
if (!isset($this->tables[$table])) {
$this->tables[$table] = new Table_Stats($table, $this->pageNumber, $this->showKeys);
}
}
$seen_a_relation = false;
foreach ($alltables as $one_table) {
$exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
if ($exist_rel) {
$seen_a_relation = true;
foreach ($exist_rel as $master_field => $rel) {
/* put the foreign table on the schema only if selected
* by the user
* (do not use array_search() because we would have to
* to do a === FALSE and this is not PHP3 compatible)
*/
if (in_array($rel['foreign_table'], $alltables)) {
$this->_addRelation($one_table, $master_field, $rel['foreign_table'], $rel['foreign_field'],$this->showKeys);
}
}
}
}
$this->_drawTables($this->showColor);
if ($seen_a_relation) {
$this->_drawRelations($this->showColor);
}
$visio->endVisioDoc();
$visio->showOutput($db.'-'.$this->pageNumber);
exit();
}
/**
* Defines relation objects
*
* @param string masterTable The master table name
* @param string masterField The relation field in the master table
* @param string foreignTable The foreign table name
* @param string foreignField The relation field in the foreign table
* @return void
* @access private
* @see Table_Stats::__construct(),Relation_Stats::__construct()
*/
private function _addRelation($masterTable, $masterField, $foreignTable, $foreignField, $showKeys)
{
if (!isset($this->tables[$masterTable])) {
$this->tables[$masterTable] = new Table_Stats($masterTable, $this->pageNumber, $showKeys);
}
if (!isset($this->tables[$foreignTable])) {
$this->tables[$foreignTable] = new Table_Stats($foreignTable, $this->pageNumber, $showKeys);
}
$this->_relations[] = new Relation_Stats($this->tables[$masterTable], $masterField, $this->tables[$foreignTable], $foreignField);
}
/**
* Draws relation references
*
* connects master table's master field to
* foreign table's forein field.
*
* @param boolean changeColor Whether to use one color per relation or not
* @return void
* @access private
* @see Relation_Stats::relationDraw()
*/
private function _drawRelations($changeColor)
{
foreach ($this->_relations as $relation) {
$relation->relationDraw($changeColor);
}
}
/**
* Draws tables
*
*
* @param boolean changeColor Whether to show color for tables text or not
* @return void
* @access private
* @see Table_Stats::tableDraw()
*/
private function _drawTables($changeColor)
{
foreach ($this->tables as $table) {
$table->tableDraw($changeColor);
}
}
}
?>

View File

@@ -49,6 +49,29 @@ if (!$GLOBALS['is_ajax_request']) {
$tabs['status']['link'] = 'server_status.php'; $tabs['status']['link'] = 'server_status.php';
$tabs['status']['text'] = __('Status'); $tabs['status']['text'] = __('Status');
if (! empty($binary_logs)) {
$tabs['binlog']['icon'] = 's_tbl.png';
$tabs['binlog']['link'] = 'server_binlog.php';
$tabs['binlog']['text'] = __('Binary log');
}
$tabs['process']['icon'] = 's_process.png';
$tabs['process']['link'] = 'server_processlist.php';
$tabs['process']['text'] = __('Processes');
if ($is_superuser) {
$tabs['rights']['icon'] = 's_rights.png';
$tabs['rights']['link'] = 'server_privileges.php';
$tabs['rights']['text'] = __('Privileges');
}
$tabs['export']['icon'] = 'b_export.png';
$tabs['export']['link'] = 'server_export.php';
$tabs['export']['text'] = __('Export');
$tabs['import']['icon'] = 'b_import.png';
$tabs['import']['link'] = 'server_import.php';
$tabs['import']['text'] = __('Import');
$tabs['vars']['icon'] = 's_vars.png'; $tabs['vars']['icon'] = 's_vars.png';
$tabs['vars']['link'] = 'server_variables.php'; $tabs['vars']['link'] = 'server_variables.php';
$tabs['vars']['text'] = __('Variables'); $tabs['vars']['text'] = __('Variables');
@@ -62,46 +85,32 @@ if (!$GLOBALS['is_ajax_request']) {
$tabs['engine']['text'] = __('Engines'); $tabs['engine']['text'] = __('Engines');
if ($is_superuser) { if ($is_superuser) {
$tabs['rights']['icon'] = 's_rights.png';
$tabs['rights']['link'] = 'server_privileges.php';
$tabs['rights']['text'] = __('Privileges');
$tabs['replication']['icon'] = 's_replication.png'; $tabs['replication']['icon'] = 's_replication.png';
$tabs['replication']['link'] = 'server_replication.php'; $tabs['replication']['link'] = 'server_replication.php';
$tabs['replication']['text'] = __('Replication'); $tabs['replication']['text'] = __('Replication');
} }
if (! empty($binary_logs)) {
$tabs['binlog']['icon'] = 's_tbl.png';
$tabs['binlog']['link'] = 'server_binlog.php';
$tabs['binlog']['text'] = __('Binary log');
}
$tabs['process']['icon'] = 's_process.png';
$tabs['process']['link'] = 'server_processlist.php';
$tabs['process']['text'] = __('Processes');
$tabs['export']['icon'] = 'b_export.png';
$tabs['export']['link'] = 'server_export.php';
$tabs['export']['text'] = __('Export');
$tabs['import']['icon'] = 'b_import.png';
$tabs['import']['link'] = 'server_import.php';
$tabs['import']['text'] = __('Import');
$tabs['synchronize']['icon'] = 's_sync.png'; $tabs['synchronize']['icon'] = 's_sync.png';
$tabs['synchronize']['link'] = 'server_synchronize.php'; $tabs['synchronize']['link'] = 'server_synchronize.php';
$tabs['synchronize']['text'] = __('Synchronize'); $tabs['synchronize']['text'] = __('Synchronize');
$tabs['settings']['icon'] = 'b_tblops.png';
$tabs['settings']['link'] = 'prefs_manage.php';
$tabs['settings']['text'] = __('Settings');
$tabs['settings']['active'] = in_array(basename($GLOBALS['PMA_PHP_SELF']),
array('prefs_forms.php', 'prefs_manage.php'));
echo PMA_generate_html_tabs($tabs, array()); echo PMA_generate_html_tabs($tabs, array());
unset($tabs); unset($tabs);
} //end if(!$GLOBALS['is_ajax_request'])
/**
* Displays a message
*/
if (!empty($message)) {
PMA_showMessage($message);
unset($message);
}
/**
* Displays a message
*/
if (!empty($message)) {
PMA_showMessage($message);
unset($message);
}
}// end if($GLOBALS['is_ajax_request'] == true)
?> ?>

View File

@@ -61,13 +61,6 @@ $tabs['search']['icon'] = 'b_search.png';
$tabs['search']['text'] = __('Search'); $tabs['search']['text'] = __('Search');
$tabs['search']['link'] = 'tbl_select.php'; $tabs['search']['link'] = 'tbl_select.php';
if(PMA_Tracker::isActive())
{
$tabs['tracking']['icon'] = 'eye.png';
$tabs['tracking']['text'] = __('Tracking');
$tabs['tracking']['link'] = 'tbl_tracking.php';
}
if (! (isset($db_is_information_schema) && $db_is_information_schema)) { if (! (isset($db_is_information_schema) && $db_is_information_schema)) {
$tabs['insert']['icon'] = 'b_insrow.png'; $tabs['insert']['icon'] = 'b_insrow.png';
$tabs['insert']['link'] = 'tbl_change.php'; $tabs['insert']['link'] = 'tbl_change.php';
@@ -92,6 +85,13 @@ if (! $tbl_is_view && ! (isset($db_is_information_schema) && $db_is_information_
$tabs['operation']['link'] = 'tbl_operations.php'; $tabs['operation']['link'] = 'tbl_operations.php';
$tabs['operation']['text'] = __('Operations'); $tabs['operation']['text'] = __('Operations');
} }
if(PMA_Tracker::isActive()) {
$tabs['tracking']['icon'] = 'eye.png';
$tabs['tracking']['text'] = __('Tracking');
$tabs['tracking']['link'] = 'tbl_tracking.php';
}
if (! $tbl_is_view && ! (isset($db_is_information_schema) && $db_is_information_schema)) {
}
/** /**
* Views support a limited number of operations * Views support a limited number of operations

View File

@@ -2980,6 +2980,7 @@ if(!class_exists('TCPDF', false)) {
if(ob_get_contents()) { if(ob_get_contents()) {
$this->Error('Some data has already been output, can\'t send PDF file'); $this->Error('Some data has already been output, can\'t send PDF file');
} }
if(php_sapi_name()!='cli') { if(php_sapi_name()!='cli') {
//We send to a browser //We send to a browser
header('Content-Type: application/pdf'); header('Content-Type: application/pdf');
@@ -2997,6 +2998,7 @@ if(!class_exists('TCPDF', false)) {
if(ob_get_contents()) { if(ob_get_contents()) {
$this->Error('Some data has already been output, can\'t send PDF file'); $this->Error('Some data has already been output, can\'t send PDF file');
} }
if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) { if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) {
header('Content-Type: application/force-download'); header('Content-Type: application/force-download');
} else { } else {
@@ -3005,6 +3007,7 @@ if(!class_exists('TCPDF', false)) {
if(headers_sent()) { if(headers_sent()) {
$this->Error('Some data has already been output to browser, can\'t send PDF file'); $this->Error('Some data has already been output to browser, can\'t send PDF file');
} }
header('Content-Type: application/pdf');
header('Content-Length: '.strlen($this->buffer)); header('Content-Length: '.strlen($this->buffer));
header('Content-disposition: attachment; filename="'.$name.'"'); header('Content-disposition: attachment; filename="'.$name.'"');
echo $this->buffer; echo $this->buffer;

View File

@@ -0,0 +1,72 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Common header for user preferences pages
*
* @package phpMyAdmin
*/
if (!defined('PHPMYADMIN')) {
exit;
}
// show server tabs
require './libraries/server_links.inc.php';
// build user preferences menu
$form_param = filter_input(INPUT_GET, 'form');
if (!isset($forms[$form_param])) {
$forms_keys = array_keys($forms);
$form_param = array_shift($forms_keys);
}
$tabs_icons = array(
'Features' => 'b_tblops.png',
'Sql_queries' => 'b_sql.png',
'Left_frame' => 'b_select.png',
'Main_frame' => 'b_props.png',
'Import' => 'b_import.png',
'Export' => 'b_export.png');
echo '<ul id="topmenu2">';
echo PMA_generate_html_tab(array(
'link' => 'prefs_manage.php',
'text' => __('Manage your settings'))) . "\n";
echo '<li>&nbsp; &nbsp;</li>' . "\n";
$script_name = basename($GLOBALS['PMA_PHP_SELF']);
foreach (array_keys($forms) as $formset) {
$tab = array(
'link' => 'prefs_forms.php',
'text' => PMA_lang('Form_' . $formset),
'icon' => $tabs_icons[$formset],
'active' => ($script_name == 'prefs_forms.php' && $formset == $form_param));
echo PMA_generate_html_tab($tab, array('form' => $formset)) . "\n";
}
echo '</ul><div class="clearfloat"></div>';
// show "configuration saved" message and reload navigation frame if needed
if (!empty($_GET['saved'])) {
$message = PMA_Message::rawSuccess(__('Configuration has been saved'));
$message->display();
}
// debug info
if ($cfg['DBG']['php']) {
$arr = ConfigFile::getInstance()->getConfigArray();
$arr2 = array();
foreach ($arr as $k => $v) {
$arr2[] = "<b>$k</b> " . var_export($v, true);
}
$arr2 = implode(', ', $arr2);
$arr2 .= '<br />Blacklist: ' . (empty($cfg['UserprefsDisallow'])
? '<i>empty</i>'
: implode(', ', $cfg['UserprefsDisallow']));
$msg = PMA_Message::notice('Settings: ' . $arr2);
$msg->display();
}
// warn about using session storage for settings
$cfgRelation = PMA_getRelationsParam();
if (!$cfgRelation['userconfigwork']) {
$msg = __('Your preferences will be saved for current session only. Storing them permanently requires %sphpMyAdmin configuration storage%s.');
$msg = PMA_sanitize(sprintf($msg, '[a@./Documentation.html#linked-tables@_blank]', '[/a]'));
PMA_Message::notice($msg)->display();
}

View File

@@ -0,0 +1,316 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions for displaying user preferences pages
*
* @package phpMyAdmin
*/
/**
* Common initialization for user preferences modification pages
*
* @uses ConfigFile::getInstance()
* @uses ConfigFile::resetConfigData()
* @uses ConfigFile::setAllowedKeys()
* @uses ConfigFile::setCfgUpdateReadMapping()
* @uses ConfigFile::updateWithGlobalConfig()
* @uses PMA_read_userprefs_fieldnames()
*/
function PMA_userprefs_pageinit()
{
$forms_all_keys = PMA_read_userprefs_fieldnames($GLOBALS['forms']);
$cf = ConfigFile::getInstance();
$cf->resetConfigData(); // start with a clean instance
$cf->setAllowedKeys($forms_all_keys);
$cf->setCfgUpdateReadMapping(array(
'Server/hide_db' => 'Servers/1/hide_db',
'Server/only_db' => 'Servers/1/only_db'));
$cf->updateWithGlobalConfig($GLOBALS['cfg']);
}
/**
* Loads user preferences
*
* Returns an array:
* * config_data - path => value pairs
* * mtime - last modification time
* * type - 'db' (config read from pmadb) or 'session' (read from user session)
*
* @uses $_SESSION['userconfig']
* @uses $GLOBALS['controllink']
* @uses PMA_array_merge_recursive
* @uses PMA_backquote()
* @uses PMA_DBI_fetch_single_row()
* @uses PMA_getRelationsParam()
* @uses PMA_sqlAddslashes()
* @uses $GLOBALS['controllink']
* @return array
*/
function PMA_load_userprefs()
{
$cfgRelation = PMA_getRelationsParam();
if (!$cfgRelation['userconfigwork']) {
// no pmadb table, use session storage
if (!isset($_SESSION['userconfig'])) {
$_SESSION['userconfig'] = array(
'db' => array(),
'ts' => time());
}
return array(
'config_data' => $_SESSION['userconfig']['db'],
'mtime' => $_SESSION['userconfig']['ts'],
'type' => 'session');
}
// load configuration from pmadb
$query_table = PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['userconfig']);
$query = '
SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts
FROM ' . $query_table . '
WHERE `username` = \'' . PMA_sqlAddslashes($cfgRelation['user']) . '\'';
$row = PMA_DBI_fetch_single_row($query, 'ASSOC', $GLOBALS['controllink']);
return array(
'config_data' => $row ? unserialize($row['config_data']) : array(),
'mtime' => $row ? $row['ts'] : time(),
'type' => 'db');
}
/**
* Saves user preferences
*
* @uses $_SESSION['cache'][...]['userprefs']
* @uses $_SESSION['userconfig']
* @uses $GLOBALS['cfg']['ServerDefault']
* @uses $GLOBALS['controllink']
* @uses $GLOBALS['server']
* @uses ConfigFile::getConfigArray()
* @uses ConfigFile::getInstance()
* @uses PMA_backquote()
* @uses PMA_DBI_fetch_value
* @uses PMA_DBI_getError()
* @uses PMA_DBI_try_query()
* @uses PMA_Message::addMessage()
* @uses PMA_Message::error()
* @uses PMA_Message::rawError()
* @uses PMA_sqlAddslashes()
* @uses PMA_getRelationsParam()
* @param array $config_data
* @return true|PMA_Message
*/
function PMA_save_userprefs(array $config_array)
{
$cfgRelation = PMA_getRelationsParam();
$server = isset($GLOBALS['server'])
? $GLOBALS['server']
: $GLOBALS['cfg']['ServerDefault'];
$cache_key = 'server_' . $server;
if (!$cfgRelation['userconfigwork']) {
// no pmadb table, use session storage
$_SESSION['userconfig'] = array(
'db' => $config_array,
'ts' => time());
if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
unset($_SESSION['cache'][$cache_key]['userprefs']);
}
return true;
}
// save configuration to pmadb
$query_table = PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['userconfig']);
$query = '
SELECT `username`
FROM ' . $query_table . '
WHERE `username` = \'' . PMA_sqlAddslashes($cfgRelation['user']) . '\'';
$has_config = PMA_DBI_fetch_value($query, 0, 0, $GLOBALS['controllink']);
$config_data = serialize($config_array);
if ($has_config) {
$query = '
UPDATE ' . $query_table . '
SET `config_data` = \'' . PMA_sqlAddslashes($config_data) . '\'
WHERE `username` = \'' . PMA_sqlAddslashes($cfgRelation['user']) . '\'';
} else {
$query = '
INSERT INTO ' . $query_table . ' (`username`, `config_data`)
VALUES (\'' . PMA_sqlAddslashes($cfgRelation['user']) . '\',
\'' . PMA_sqlAddslashes($config_data) . '\')';
}
if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
unset($_SESSION['cache'][$cache_key]['userprefs']);
}
if (!PMA_DBI_try_query($query, $GLOBALS['controllink'])) {
$message = PMA_Message::error(__('Could not save configuration'));
$message->addMessage('<br /><br />');
$message->addMessage(PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink'])));
return $message;
}
return true;
}
/**
* Returns a user preferences array filtered by $cfg['UserprefsDisallow']
* (blacklist) and keys from user preferences form (whitelist)
*
* @uses PMA_array_write()
* @uses PMA_read_userprefs_fieldnames()
* @param array $config_data path => value pairs
* @return array
*/
function PMA_apply_userprefs(array $config_data)
{
$cfg = array();
$blacklist = array_flip($GLOBALS['cfg']['UserprefsDisallow']);
if (!$GLOBALS['cfg']['UserprefsDeveloperTab']) {
// disallow everything in the Developers tab
$blacklist['Error_Handler/display'] = true;
$blacklist['Error_Handler/gather'] = true;
$blacklist['DBG/sql'] = true;
$blacklist['DBG/php'] = true;
}
$whitelist = array_flip(PMA_read_userprefs_fieldnames());
// whitelist some additional fields which are custom handled
$whitelist['ThemeDefault'] = true;
$whitelist['fontsize'] = true;
$whitelist['lang'] = true;
$whitelist['collation_connection'] = true;
$whitelist['Server/hide_db'] = true;
$whitelist['Server/only_db'] = true;
foreach ($config_data as $path => $value) {
if (!isset($whitelist[$path]) || isset($blacklist[$path])) {
continue;
}
PMA_array_write($path, $cfg, $value);
}
return $cfg;
}
/**
* Reads user preferences field names
*
* @param array|null $forms
* @return array
*/
function PMA_read_userprefs_fieldnames(array $forms = null)
{
static $names;
// return cached results
if ($names !== null) {
return $names;
}
if (is_null($forms)) {
$forms = array();
include 'libraries/config/user_preferences.forms.php';
}
$names = array();
foreach ($forms as $formset) {
foreach ($formset as $form) {
foreach ($form as $k => $v) {
$names[] = is_int($k) ? $v : $k;
}
}
}
return $names;
}
/**
* Updates one user preferences option (loads and saves to database).
*
* No validation is done!
*
* @uses PMA_load_userprefs()
* @uses PMA_save_userprefs()
* @param string $cfg_name
* @param mixed $value
* @return void
*/
function PMA_persist_option($path, $value, $default_value)
{
$prefs = PMA_load_userprefs();
if ($value === $default_value) {
if (isset($prefs['config_data'][$path])) {
unset($prefs['config_data'][$path]);
} else {
return;
}
} else {
$prefs['config_data'][$path] = $value;
}
PMA_save_userprefs($prefs['config_data']);
}
/**
* Redirects after saving new user preferences
*
* @uses ConfigFile::getConfigArray()
* @uses ConfigFile::getInstance()
* @uses PMA_generate_common_url()
* @uses PMA_sendHeaderLocation()
* @param array $forms
* @param array $old_settings
* @param string $file_name
* @param array $params
* @param string $hash
*/
function PMA_userprefs_redirect(array $forms, array $old_settings, $file_name, $params = null, $hash = null)
{
$reload_left_frame = isset($params['reload_left_frame']) && $params['reload_left_frame'];
if (!$reload_left_frame) {
// compute differences and check whether left frame should be refreshed
$old_settings = isset($old_settings['config_data'])
? $old_settings['config_data']
: array();
$new_settings = ConfigFile::getInstance()->getConfigArray();
$diff_keys = array_keys(array_diff_assoc($old_settings, $new_settings)
+ array_diff_assoc($new_settings, $old_settings));
$check_keys = array('NaturalOrder', 'MainPageIconic', 'DefaultTabDatabase',
'Server/hide_db', 'Server/only_db');
$check_keys = array_merge($check_keys, $forms['Left_frame']['Left_frame'],
$forms['Left_frame']['Left_databases']);
$diff = array_intersect($check_keys, $diff_keys);
$reload_left_frame = !empty($diff);
}
// redirect
$url_params = array(
'saved' => 1,
'reload_left_frame' => $reload_left_frame);
if (is_array($params)) {
$url_params = array_merge($params, $url_params);
}
if ($hash) {
$hash = '#' . urlencode($hash);
}
PMA_sendHeaderLocation($GLOBALS['cfg']['PmaAbsoluteUri'] . $file_name
. PMA_generate_common_url($url_params, '&') . $hash);
}
/**
* Shows form which allows to quickly load settings stored in browser's local storage
*
* @uses $_REQUEST['prefs_autoload']
* @uses $_SESSION['userprefs_autoload']
* @uses PMA_generate_common_hidden_inputs()
*/
function PMA_userprefs_autoload_header()
{
if (isset($_REQUEST['prefs_autoload']) && $_REQUEST['prefs_autoload'] == 'hide') {
$_SESSION['userprefs_autoload'] = true;
exit;
}
$script_name = basename(basename($GLOBALS['PMA_PHP_SELF']));
$return_url = $script_name . '?' . http_build_query($_GET, '', '&');
?>
<div id="prefs_autoload" class="notice" style="display:none">
<form action="prefs_manage.php" method="post">
<?php echo PMA_generate_common_hidden_inputs() . "\n"; ?>
<input type="hidden" name="json" value="" />
<input type="hidden" name="submit_import" value="1" />
<input type="hidden" name="return_url" value="<?php echo htmlspecialchars($return_url) ?>" />
<?php echo __('Your browser has phpMyAdmin configuration for this domain. Would you like to import it for current session?') ?>
<br />
<a href="#yes"><?php echo __('Yes') ?></a> / <a href="#no"><?php echo __('No') ?></a>
</form>
</div>
<?php
}
?>

View File

@@ -144,6 +144,14 @@ echo PMA_Config::getFontsizeForm();
echo '</li>'; echo '</li>';
echo '</ul>'; echo '</ul>';
// User preferences
echo '<ul>';
echo PMA_printListItem(__('More settings'), 'li_user_preferences',
'./prefs_manage.php?' . $common_url_query);
echo '<ul>';
echo '</div>'; echo '</div>';

View File

@@ -1,559 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package phpMyAdmin
*/
/**
* Gets some core libraries
*/
require_once './libraries/common.inc.php';
require_once './libraries/db_common.inc.php';
require './libraries/StorageEngine.class.php';
$active_page = 'db_operations.php';
require_once './libraries/db_common.inc.php';
$url_query .= '&amp;goto=pdf_pages.php';
require_once './libraries/db_info.inc.php';
/**
* Settings for relation stuff
*/
$cfgRelation = PMA_getRelationsParam();
// This is to avoid "Command out of sync" errors. Before switching this to
// a value of 0 (for MYSQLI_USE_RESULT), please check the logic
// to free results wherever needed.
$query_default_option = PMA_DBI_QUERY_STORE;
/**
* Now in ./libraries/relation.lib.php we check for all tables
* that we need, but if we don't find them we are quiet about it
* so people can work without.
* This page is absolutely useless if you didn't set up your tables
* correctly, so it is a good place to see which tables we can and
* complain ;-)
*/
if (!$cfgRelation['relwork']) {
echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'relation', 'config.inc.php') . '<br />' . "\n"
. PMA_showDocu('relation') . "\n";
require './libraries/footer.inc.php';
}
if (!$cfgRelation['displaywork']) {
echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'table_info', 'config.inc.php') . '<br />' . "\n"
. PMA_showDocu('table_info') . "\n";
require './libraries/footer.inc.php';
}
if (!isset($cfgRelation['table_coords'])){
echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'table_coords', 'config.inc.php') . '<br />' . "\n"
. PMA_showDocu('table_coords') . "\n";
require './libraries/footer.inc.php';
}
if (!isset($cfgRelation['pdf_pages'])) {
echo sprintf(__('<b>%s</b> table not found or not set in %s'), 'pdf_page', 'config.inc.php') . '<br />' . "\n"
. PMA_showDocu('pdf_pages') . "\n";
require './libraries/footer.inc.php';
}
if ($cfgRelation['pdfwork']) {
// Now is the time to work on all changes
if (isset($do)) {
switch ($do) {
case 'choosepage':
if ($action_choose=="1") {
$ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
PMA_query_as_controluser($ch_query, FALSE, $query_default_option);
$ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND page_nr = \'' . PMA_sqlAddslashes($chpage) . '\'';
PMA_query_as_controluser($ch_query, FALSE, $query_default_option);
unset($chpage);
}
break;
case 'createpage':
$pdf_page_number = PMA_REL_create_page($newpage, $cfgRelation, $db, $query_default_option);
// A u t o m a t i c l a y o u t
// ================================
if (isset($auto_layout_internal) || isset($auto_layout_foreign)) {
$all_tables = array();
}
if (isset($auto_layout_foreign)) {
// get the tables list
$tables = PMA_DBI_get_tables_full($db);
// find the ones who support FOREIGN KEY; it's not
// important that we group together InnoDB tables
// and PBXT tables, as this logic is just to put
// the tables on the layout, not to determine relations
$foreignkey_tables = array();
foreach($tables as $table_name => $table_properties) {
if (PMA_foreignkey_supported($table_properties['ENGINE'])) {
$foreignkey_tables[] = $table_name;
}
}
$all_tables = $foreignkey_tables;
// could be improved by finding the tables which have the
// most references keys and placing them at the beginning
// of the array (so that they are all center of schema)
unset($tables, $foreignkey_tables);
} // endif auto_layout_foreign
if (isset($auto_layout_internal)) {
// get the tables that have relations, by descending
// number of links
$master_tables = 'SELECT COUNT(master_table), master_table'
. ' FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['relation'])
. ' WHERE master_db = \'' . $db . '\''
. ' GROUP BY master_table'
. ' ORDER BY ' . PMA_backquote('COUNT(master_table)') . ' DESC ';
$master_tables_rs = PMA_query_as_controluser($master_tables, FALSE, $query_default_option);
if ($master_tables_rs && PMA_DBI_num_rows($master_tables_rs) > 0) {
// first put all the master tables at beginning
// of the list, so they are near the center of
// the schema
while (list(, $master_table) = PMA_DBI_fetch_row($master_tables_rs)) {
$all_tables[] = $master_table;
}
// then for each master, add its foreigns into an array
// of foreign tables, if not already there
// (a foreign might be foreign for more than
// one table, and might be a master itself)
$foreign_tables = array();
foreach ($all_tables AS $master_table) {
$foreigners = PMA_getForeigners($db, $master_table);
foreach ($foreigners AS $foreigner) {
if (!in_array($foreigner['foreign_table'], $foreign_tables)) {
$foreign_tables[] = $foreigner['foreign_table'];
}
}
}
// then merge the arrays
foreach ($foreign_tables AS $foreign_table) {
if (!in_array($foreign_table, $all_tables)) {
$all_tables[] = $foreign_table;
}
}
} // endif there are master tables
} // endif auto_layout_internal
if (isset($auto_layout_internal) || isset($auto_layout_foreign)) {
// now generate the coordinates for the schema,
// in a clockwise spiral
$pos_x = 300;
$pos_y = 300;
$delta = 110;
$delta_mult = 1.10;
$direction = "right";
foreach ($all_tables AS $current_table) {
// save current table's coordinates
$insert_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. '(db_name, table_name, pdf_page_number, x, y) '
. 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($current_table) . '\',' . $pdf_page_number . ',' . $pos_x . ',' . $pos_y . ')';
PMA_query_as_controluser($insert_query, FALSE, $query_default_option);
// compute for the next table
switch ($direction) {
case 'right':
$pos_x += $delta;
$direction = "down";
$delta *= $delta_mult;
break;
case 'down':
$pos_y += $delta;
$direction = "left";
$delta *= $delta_mult;
break;
case 'left':
$pos_x -= $delta;
$direction = "up";
$delta *= $delta_mult;
break;
case 'up':
$pos_y -= $delta;
$direction = "right";
$delta *= $delta_mult;
break;
} // end switch
} // end foreach
} // end if some auto-layout to do
$chpage = $pdf_page_number;
break;
case 'edcoord':
for ($i = 0; $i < $c_table_rows; $i++) {
$arrvalue = 'c_table_' . $i;
$arrvalue = $$arrvalue;
if (!isset($arrvalue['x']) || $arrvalue['x'] == '') {
$arrvalue['x'] = 0;
}
if (!isset($arrvalue['y']) || $arrvalue['y'] == '') {
$arrvalue['y'] = 0;
}
if (isset($arrvalue['name']) && $arrvalue['name'] != '--') {
$test_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
$test_rs = PMA_query_as_controluser($test_query, FALSE, $query_default_option);
if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
if (isset($arrvalue['delete']) && $arrvalue['delete'] == 'y') {
$ch_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
} else {
$ch_query = 'UPDATE ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. 'SET x = ' . $arrvalue['x'] . ', y= ' . $arrvalue['y']
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND table_name = \'' . PMA_sqlAddslashes($arrvalue['name']) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
}
} else {
$ch_query = 'INSERT INTO ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' '
. '(db_name, table_name, pdf_page_number, x, y) '
. 'VALUES (\'' . PMA_sqlAddslashes($db) . '\', \'' . PMA_sqlAddslashes($arrvalue['name']) . '\', \'' . PMA_sqlAddslashes($chpage) . '\',' . $arrvalue['x'] . ',' . $arrvalue['y'] . ')';
}
PMA_query_as_controluser($ch_query, FALSE, $query_default_option);
} // end if
} // end for
break;
case 'deleteCrap':
foreach ($delrow AS $current_row) {
$d_query = 'DELETE FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords']) . ' ' . "\n"
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'' . "\n"
. ' AND table_name = \'' . PMA_sqlAddslashes($current_row) . '\'' . "\n"
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
PMA_query_as_controluser($d_query, FALSE, $query_default_option);
}
break;
} // end switch
} // end if (isset($do))
// We will need an array of all tables in this db
$selectboxall = array('--');
$alltab_rs = PMA_DBI_query('SHOW TABLES FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
while ($val = @PMA_DBI_fetch_row($alltab_rs)) {
$selectboxall[] = $val[0];
}
// Now first show some possibility to choose a page for the pdf
$page_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['pdf_pages'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\'';
$page_rs = PMA_query_as_controluser($page_query, FALSE, $query_default_option);
if ($page_rs && PMA_DBI_num_rows($page_rs) > 0) {
?>
<form method="get" action="pdf_pages.php" name="selpage">
<fieldset>
<legend>
<?php echo __('Please choose a page to edit') . "\n"; ?>
</legend>
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="do" value="choosepage" />
<select name="chpage" onchange="this.form.submit()">
<?php
while ($curr_page = PMA_DBI_fetch_assoc($page_rs)) {
echo "\n" . ' '
. '<option value="' . $curr_page['page_nr'] . '"';
if (isset($chpage) && $chpage == $curr_page['page_nr']) {
echo ' selected="selected"';
}
echo '>' . $curr_page['page_nr'] . ': ' . htmlspecialchars($curr_page['page_descr']) . '</option>';
} // end while
echo "\n";
?>
</select>
<?php
$choices = array(
'0' => __('Edit'),
'1' => __('Delete'));
PMA_display_html_radio('action_choose', $choices, '0', false);
unset($choices);
?>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" /><br />
</fieldset>
</form>
<?php
}
echo "\n";
// Possibility to create a new page:
?>
<form method="post" action="pdf_pages.php" name="crpage">
<fieldset>
<legend>
<?php echo __('Create a page') . "\n"; ?>
</legend>
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="do" value="createpage" />
<table>
<tr>
<td><label for="id_newpage"><?php echo __('Page name'); ?></label></td>
<td><input type="text" name="newpage" id="id_newpage" size="20" maxlength="50" /></td>
</tr>
<tr>
<td><?php echo __('Automatic layout based on'); ?></td>
<td>
<input type="checkbox" name="auto_layout_internal" id="id_auto_layout_internal" /><label for="id_auto_layout_internal"><?php echo __('Internal relations'); ?></label><br />
<?php
if (PMA_StorageEngine::isValid('InnoDB') || PMA_StorageEngine::isValid('PBXT')) {
?>
<input type="checkbox" name="auto_layout_foreign" id="id_auto_layout_foreign" /><label for="id_auto_layout_foreign">FOREIGN KEY</label><br />
<?php
}
?>
</td></tr>
</table>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" />
</fieldset>
</form>
<?php
// Now if we already have chosen a page number then we should show the
// tables involved
if (isset($chpage) && $chpage > 0) {
echo "\n";
?>
<hr />
<h2><?php echo __('Select Tables') ;?></h2>
<?php
$page_query = 'SELECT * FROM ' . PMA_backquote($GLOBALS['cfgRelation']['db']) . '.' . PMA_backquote($cfgRelation['table_coords'])
. ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
. ' AND pdf_page_number = \'' . PMA_sqlAddslashes($chpage) . '\'';
$page_rs = PMA_query_as_controluser($page_query, FALSE, $query_default_option);
$array_sh_page = array();
$draginit = '';
$reset_draginit = '';
$i = 0;
while ($temp_sh_page = @PMA_DBI_fetch_assoc($page_rs)) {
$array_sh_page[] = $temp_sh_page;
}
// Display WYSIWYG-PDF parts?
if ($cfg['WYSIWYG-PDF']) {
if (!isset($_POST['with_field_names']) && !isset($_POST['showwysiwyg'])) {
$with_field_names = TRUE;
}
?>
<script type="text/javascript" src="./js/dom-drag.js"></script>
<form method="post" action="pdf_pages.php" name="dragdrop">
<input type="button" name="dragdrop" value="<?php echo __('Toggle scratchboard'); ?>" onclick="ToggleDragDrop('pdflayout');" />
<input type="button" name="dragdropreset" value="<?php echo __('Reset'); ?>" onclick="resetDrag();" />
</form>
<div id="pdflayout" class="pdflayout" style="visibility: hidden;">
<?php
foreach ($array_sh_page AS $key => $temp_sh_page) {
$drag_x = $temp_sh_page['x'];
$drag_y = $temp_sh_page['y'];
$draginit .= ' Drag.init(getElement("table_' . $i . '"), null, 0, parseInt(myid.style.width)-2, 0, parseInt(myid.style.height)-5);' . "\n";
$draginit .= ' getElement("table_' . $i . '").onDrag = function (x, y) { document.edcoord.elements["c_table_' . $i . '[x]"].value = parseInt(x); document.edcoord.elements["c_table_' . $i . '[y]"].value = parseInt(y) }' . "\n";
$draginit .= ' getElement("table_' . $i . '").style.left = "' . $drag_x . 'px";' . "\n";
$draginit .= ' getElement("table_' . $i . '").style.top = "' . $drag_y . 'px";' . "\n";
$reset_draginit .= ' getElement("table_' . $i . '").style.left = "2px";' . "\n";
$reset_draginit .= ' getElement("table_' . $i . '").style.top = "' . (15 * $i) . 'px";' . "\n";
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[x]"].value = "2"' . "\n";
$reset_draginit .= ' document.edcoord.elements["c_table_' . $i . '[y]"].value = "' . (15 * $i) . '"' . "\n";
$local_query = 'SHOW FIELDS FROM '
. PMA_backquote($temp_sh_page['table_name'])
. ' FROM ' . PMA_backquote($db);
$fields_rs = PMA_DBI_query($local_query);
unset($local_query);
$fields_cnt = PMA_DBI_num_rows($fields_rs);
echo '<div id="table_' . $i . '" class="pdflayout_table"><u>' . $temp_sh_page['table_name'] . '</u>';
if (isset($with_field_names)) {
while ($row = PMA_DBI_fetch_assoc($fields_rs)) {
echo '<br />' . htmlspecialchars($row['Field']) . "\n";
}
}
echo '</div>' . "\n";
PMA_DBI_free_result($fields_rs);
unset($fields_rs);
$i++;
}
?>
</div>
<script type="text/javascript">
//<![CDATA[
function PDFinit() {
refreshLayout();
myid = getElement('pdflayout');
<?php echo $draginit; ?>
}
function resetDrag() {
<?php echo $reset_draginit; ?>
}
//]]>
</script>
<?php
} // end if WYSIWYG-PDF
?>
<form method="post" action="pdf_pages.php" name="edcoord">
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="chpage" value="<?php echo htmlspecialchars($chpage); ?>" />
<input type="hidden" name="do" value="edcoord" />
<table border="0">
<tr>
<th><?php echo __('Table'); ?></th>
<th><?php echo __('Delete'); ?></th>
<th>X</th>
<th>Y</th>
</tr>
<?php
if (isset($ctable)) {
unset($ctable);
}
$i = 0;
$odd_row = true;
foreach ($array_sh_page AS $dummy_sh_page => $sh_page) {
$_mtab = $sh_page['table_name'];
$tabExist[$_mtab] = FALSE;
echo "\n" . ' <tr class="';
if ($odd_row) {
echo 'odd';
} else {
echo 'even';
}
echo '">';
$odd_row != $odd_row;
echo "\n" . ' <td>'
. "\n" . ' <select name="c_table_' . $i . '[name]">';
foreach ($selectboxall AS $key => $value) {
echo "\n" . ' <option value="' . htmlspecialchars($value) . '"';
if ($value == $sh_page['table_name']) {
echo ' selected="selected"';
$tabExist[$_mtab] = TRUE;
}
echo '>' . htmlspecialchars($value) . '</option>';
} // end while
echo "\n" . ' </select>'
. "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="checkbox" name="c_table_' . $i . '[delete]" value="y" />' . __('Delete');
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" ' . ($cfg['WYSIWYG-PDF'] ? 'onchange="dragPlace(' . $i . ', \'x\', this.value)"' : '') . ' name="c_table_' . $i . '[x]" value="' . $sh_page['x'] . '" />';
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" ' . ($cfg['WYSIWYG-PDF'] ? 'onchange="dragPlace(' . $i . ', \'y\', this.value)"' : '') . ' name="c_table_' . $i . '[y]" value="' . $sh_page['y'] . '" />';
echo "\n" . ' </td>';
echo "\n" . ' </tr>';
$i++;
} // end while
// Do one more empty row
echo "\n" . ' <tr class="';
if ($odd_row) {
echo 'odd';
} else {
echo 'even';
}
$odd_row != $odd_row;
echo '">';
echo "\n" . ' <td>'
. "\n" . ' <select name="c_table_' . $i . '[name]">';
foreach ($selectboxall AS $key => $value) {
echo "\n" . ' <option value="' . htmlspecialchars($value) . '">' . htmlspecialchars($value) . '</option>';
}
echo "\n" . ' </select>'
. "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="checkbox" name="c_table_' . $i . '[delete]" value="y" />' . __('Delete');
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" name="c_table_' . $i . '[x]" value="' . (isset($sh_page['x'])?$sh_page['x']:'') . '" />';
echo "\n" . ' </td>';
echo "\n" . ' <td>'
. "\n" . ' <input type="text" name="c_table_' . $i . '[y]" value="' . (isset($sh_page['y'])?$sh_page['y']:'') . '" />';
echo "\n" . ' </td>';
echo "\n" . ' </tr>';
echo "\n" . ' </table>' . "\n";
echo "\n" . ' <input type="hidden" name="c_table_rows" value="' . ($i + 1) . '" />';
echo ($cfg['WYSIWYG-PDF'] ? "\n" . ' <input type="hidden" id="showwysiwyg" name="showwysiwyg" value="' . ((isset($showwysiwyg) && $showwysiwyg == '1') ? '1' : '0') . '" />' : '');
echo "\n" . ' <input type="checkbox" name="with_field_names" ' . (isset($with_field_names) ? 'checked="checked"' : ''). ' />' . __('Column names') . '<br />';
echo "\n" . ' <input type="submit" value="' . __('Save') . '" />';
echo "\n" . '</form>' . "\n\n";
} // end if
// Check if there are tables that need to be deleted,
// if there are, ask the user for allowance
$_strtrans = '';
$_strname = '';
$shoot = FALSE;
if (!empty($tabExist) && is_array($tabExist)) {
foreach ($tabExist AS $key => $value) {
if (!$value) {
$_strtrans .= '<input type="hidden" name="delrow[]" value="' . htmlspecialchars($key) . '" />' . "\n";
$_strname .= '<li>' . htmlspecialchars($key) . '</li>' . "\n";
$shoot = TRUE;
}
}
if ($shoot) {
echo '<form action="pdf_pages.php" method="post">' . "\n"
. PMA_generate_common_hidden_inputs($db, $table)
. '<input type="hidden" name="do" value="deleteCrap" />' . "\n"
. '<input type="hidden" name="chpage" value="' . htmlspecialchars($chpage) . '" />' . "\n"
. __('The current page has references to tables that no longer exist. Would you like to delete those references?')
. '<ul>' . "\n"
. $_strname
. '</ul>' . "\n"
. $_strtrans
. '<input type="submit" value="' . __('Go') . '" />' . "\n"
. '</form>';
}
}
// ------------------------------------
// d i s p l a y p d f s c h e m a
// ------------------------------------
if (isset($do)
&& ($do == 'edcoord'
|| ($do == 'choosepage' && isset($chpage))
|| ($do == 'createpage' && isset($chpage)))) {
include('./libraries/display_pdf_schema.lib.php');
if ((isset($showwysiwyg) && $showwysiwyg == '1')) {
?>
<script type="text/javascript">
//<![CDATA[
ToggleDragDrop('pdflayout');
//]]>
</script>
<?php
}
} // end if
} // end if ($cfgRelation['pdfwork'])
/**
* Displays the footer
*/
echo "\n";
require './libraries/footer.inc.php';
?>

File diff suppressed because it is too large Load Diff

5634
po/af.po

File diff suppressed because it is too large Load Diff

5632
po/ar.po

File diff suppressed because it is too large Load Diff

5706
po/az.po

File diff suppressed because it is too large Load Diff

5785
po/be.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5728
po/bg.po

File diff suppressed because it is too large Load Diff

6115
po/bn.po

File diff suppressed because it is too large Load Diff

5683
po/bs.po

File diff suppressed because it is too large Load Diff

6155
po/ca.po

File diff suppressed because it is too large Load Diff

6152
po/cs.po

File diff suppressed because it is too large Load Diff

5595
po/cy.po

File diff suppressed because it is too large Load Diff

5651
po/da.po

File diff suppressed because it is too large Load Diff

6138
po/de.po

File diff suppressed because it is too large Load Diff

6154
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6067
po/es.po

File diff suppressed because it is too large Load Diff

5769
po/et.po

File diff suppressed because it is too large Load Diff

5696
po/eu.po

File diff suppressed because it is too large Load Diff

5628
po/fa.po

File diff suppressed because it is too large Load Diff

6128
po/fi.po

File diff suppressed because it is too large Load Diff

6278
po/fr.po

File diff suppressed because it is too large Load Diff

6185
po/gl.po

File diff suppressed because it is too large Load Diff

5708
po/he.po

File diff suppressed because it is too large Load Diff

5587
po/hi.po

File diff suppressed because it is too large Load Diff

5758
po/hr.po

File diff suppressed because it is too large Load Diff

6175
po/hu.po

File diff suppressed because it is too large Load Diff

5710
po/id.po

File diff suppressed because it is too large Load Diff

6044
po/it.po

File diff suppressed because it is too large Load Diff

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