From: bradymiller Date: Wed, 26 Jun 2013 07:10:15 +0000 (-0700) Subject: Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet X-Git-Tag: whats-been-changed~286 X-Git-Url: https://repo.or.cz/w/openemr.git/commitdiff_plain/bcac748a7611fcdff0be8d0c76e3249760987a0e Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet --- diff --git a/phpmyadmin/ChangeLog b/phpmyadmin/ChangeLog new file mode 100644 index 000000000..8b29aabbd --- /dev/null +++ b/phpmyadmin/ChangeLog @@ -0,0 +1,222 @@ +phpMyAdmin - ChangeLog +====================== + +4.0.4.0 (2013-06-17) +- bug #3959 Using DefaultTabDatabase in NavigationTree for Database Click +- bug #3961 Avoid Suhosin warning when in simulation mode +- bug #3897 Row Statistics and Space usage bugs +- bug #3966 Only display "table has no unique column" message when applicable +- bug #3960 NavigationBarIconic config not honored +- bug #3965 Default language wrong with zh-TW +- bug #3921 Call to undefined function PMA_isSuperuser() if default server is +not set +- bug #3971 Ctrl/shift + click opens links in same window +- bug #3964 Import using https does not work +- bug Missing removeCRLF option in ExportCsv and ExportExcel plugins +- bug #3631 Drop not working Visio schema export. +- bug #3645 Better handling of invalid ODS documents +- bug #3976 Number of pages +- bug #3922 User privileges, database name unescaped + +4.0.3.0 (2013-06-05) +- bug #3941 Recent tables list always empty +- bug #3933 Do not translate "Open Document" in export settings +- bug #3927 List of tables is missing after expanding in the navigation frame +- bug #3942 Warnings about reserved word for many non reserved words +- bug #3912 Exporting row selection, resulted by ORDER BY query +- bug #3957 Cookies must be enabled past this point +- bug #3956 "Browse foreign values" search filter / page selector not working +- bug #3579 NOW() function incorrectly selected (partial regression) +- [security] Javascript execution vulnerability in Create view, + reported by Maxim Rupp (see PMASA-2013-6) + +4.0.2.0 (2013-05-24) +- bug #3902 Cannot browse when table name contains keyword "call" ++ center loading indicator for navigation refresh, related to bug #3920 +- bug #3925 Table sorting in navigation panel is case-sensitive +- bug #3915 Import of CSV file (Replace table data with file) with duplicate values +- bug #3907 undefined variables, function parameter problems +- bug #3898 Structure not refreshed after column drop +- bug #3926 View is not updatable +- bug #3919 PropertiesIconic not honored +- bug #3930 Databases to choose for specific privileges show up escaped +- bug #3910 Export database with empty table as a php array, does not produce valid PHP +- bug #3936 Query profiler chart not loading from SQL Query page +- bug #3946 Missing CSV import option "Do not abort on INSERT error" +- bug #3943 Missing Operations>Table options>AUTO_INCREMENT +- bug Missing CREATE DATABASE statement when exporting at database level +- bug #3924 Show warning when CSV file does not contain data for all columns +- bug #3947 Missing Sql Query after modify structure +- bug #3948 Server export problems +- bug #3917 CountTables directive is deprecated + +4.0.1.0 (2013-05-14) +- bug #3879 Import broken for CSV using LOAD DATA +- bug #3889 When login fails and error display is active, login data is displayed +- bug #3890 [import] Web server upload directory import fails +- bug #3891 [import] Server upload folder import file name missing in success message ++ rfe #1421 [auth] Add retry button on connection failure with config auth +- bug #3894 [interface] Provide feedback if no columns selected for multi-submit +- bug #3799 [interface] Incorrect select field change on ctrl key navigation in Firefox +- bug #3885 [browse] display_binary_as_hex option causes unexpected behavior +- bug #3899 Git commit links to Github missing +- bug #3900 CSP WARN in Firefox console +- bug #3901 Setup script warning for config auth (stored login data) shows link BBcode +- bug #3895 [browse] Fixed getting BLOB data +- bug #3905 [export] Custom Exporting exports all databases +- bug #3909 [import] Import of CSV FIle to selected table doesn't work +- bug #3904 Browsing an empty table should not display its Structure +- bug #3908 Calendar widget improperly redirects to home +- bug #3918 Greyed out tabs when there are no rows fixed +- bug #3916 [interface] Missing scrollbar (original theme) ++ [vendor] add tcpdf path to vendor_config.php +- bug fix compat with tcpdf >= 6.0 (tested with 6.0.012) + +4.0.0.0 (2013-05-03) ++ Patch #3481047 for rfe #3480477 Insert as new row enhancement ++ Patch #3480999 Activate codemirror in the query window +- Patch #3495284 XML Import - fix message and redirect ++ rfe #3484063 Null checkbox behavior ++ Patch #3497179 Contest-5: Add user: Allow create DB w/same name + grant u_% ++ Patch #3498201 Contest-6: Export all privileges ++ Patch #3502814 for rfe #3187077 Change password buttons should match ++ rfe #3488640 Expand table-group in non-light navigation frame if only one ++ Patch #3509360 Contest-3: Option "Truncate table" before "insert" ++ Patch #3506552 Contest-2: Show index information in the data dictionary ++ Patch #3510656 Contest-1: Ignoring foreign keys while dropping tables +- Bug #3509686 Reverting sort on joined column does not work ++ New transformation: append string ++ rfe #3507804 Session upload progress (PHP 5.4) ++ rfe #3488185 draggable columns vs copy column name ++ Patch #3507001 Contest-4: Textarea for large character columns ++ Removed the PHP version of the ENUM editor ++ Patch #3507111 Display distinct results, linked to corresponding data rows +- bug #3507917 [export] JSON has unescaped values for allegedly numeric columns ++ rfe #3516187 show tables creation, last update, last check timestamps in db_structure +- bug #3059806 Supporting running from CIFS/Samba shares +- bug #3516341 [export] Open Document Text, Word and Texy! Text show table structure twice +- bug [export] Texy! Text: Columns containing Pipe Character don't export properly ++ [export] Show triggers in Open Document Text, Word and Texy! Text +- Patch #3415061 [auth] Login screen appears under the page ++ rfe #3517354 [interface] Allow disabling CodeMirror with $cfg['CodemirrorEnable'] = false ++ rfe #3475567 [interface] New directive $cfg['HideStructureActions'] +- bug #3468272 [import] Fixed import of ODS with more paragraphs in a cell +- bug #3510196 [core] Improved redirecting with ForceSSL option ++ rfe #3518852 [edit] edit blob but not other binary, new option $cfg['ProtectBinary'] = 'noblob' ++ Hide language select box if there are no locales installed ++ Removed some directives: verbose_check, SuggestDBName, LightTabs, +VerboseMultiSubmit, ReplaceHelpImg +- Patch #3500882 Fixing checkbox behaviour while editing identical rows ++ rfe #3441722 [interface] Display description of datatypes ++ rfe #3517835 [structure] Move columns easily ++ Ajaxified "Create View" functionality ++ [import] New plugin: import mediawiki ++ New navigation system ++ Discontinued the use of a frame-based layout ++ rfe #3528994 [interface] Allow wrapping possibly long values in replication-status table ++ [interface] Autoselect username input on cookie login page +- bug #3563799 [interface] Grid editing destroying huge amount of data ++ [import] Remove support for the unactive docSQL import format +- bug #3577443 [edit] "Browse foreign values" does not show on ajax edit ++ rfe #3522109 [browse] Grid editing: action to trigger it (or disable) +- bug #3526598 [interface] SQL query not shown when creating table ++ Dropped configuration directive: AllowThirdPartyFraming ++ Dropped configuration directive: LeftFrameLight ++ Dropped configuration directive: DisplayDatabasesList ++ Dropped configuration directives: ShowTooltipAliasDB and ShowTooltipAliasTB ++ Dropped configuration directive: NaviDatabaseNameColor ++ Added configuration directive: MaxNavigationItems ++ Renamed configuration directive: LeftFrameDBTree => NavigationTreeEnableGrouping ++ Renamed configuration directive: LeftFrameDBSeparator => NavigationTreeDbSeparator ++ Renamed configuration directive: LeftFrameTableSeparator => NavigationTreeTableSeparator ++ Renamed configuration directive: LeftFrameTableLevel => NavigationTreeTableLevel ++ Renamed configuration directive: LeftPointerEnable => NavigationTreePointerEnable ++ Renamed configuration directive: LeftDefaultTabTable => NavigationTreeDefaultTabTable ++ Renamed configuration directive: LeftDisplayTableFilterMinimum => NavigationTreeDisplayTableFilterMinimum ++ Renamed configuration directive: LeftDisplayLogo => NavigationDisplayLogo ++ Renamed configuration directive: LeftLogoLink => NavigationLogoLink ++ Renamed configuration directive: LeftLogoLinkWindow => NavigationLogoLinkWindow ++ Renamed configuration directive: LeftDisplayServers => NavigationDisplayServers ++ Renamed configuration directive: LeftRecentTable => NumRecentTables ++ Renamed configuration directive: LeftDisplayDatabaseFilterMinimum => NavigationTreeDisplayDbFilterMinimum ++ Removed the "Mark row on click" feature; must now click the checkbox to mark ++ Removed the "Synchronize" feature ++ Improved layout of server variables page ++ rfe #1052091 [config] Double-underscores in PMA table names ++ Improved the "More" dropdown on the table structure page ++ [interface] Added "scroll to top" link in menubar ++ [designer] Fullscreen mode for the designer ++ Upgraded jquery to v1.8.3 and jquery-ui to v1.9.2 ++ Patch #3597529 [status] Add raw value as title on server status page ++ Support MySQL 5.6 partitioning ++ Removed the AjaxEnable directive ++ rfe #3542567 Accept IPv6 ranges and IPv6 CIDR notations in $cfg['Servers'][$i]['AllowDeny']['rules'] +- Bug #3576788 Grid editing shows the value before silent truncation +- Upgraded jqPlot to 1.0.4 r1121 +- Upgraded to jquery-ui-timepicker-addon 1.1.1 ++ rfe #3599046 [interface] Added comments for indexes +- Replaced qtip with jQuery UI tooltip +- Upgraded CodeMirror to 2.37 +- bug #2951 [export] Correctly export decimal fields. +- bug #3762 [core] Make Advisor work on Windows withou COM extension. +- bug #3519 [export] Prevent infinite recursion in PDF export. +- bug #3827 Table specific privileges not displayed for db name containing +underscore +- rfe #1386 Add IF NOT EXISTS clause when copying database +- No longer package .travis.yml configuration file when creating a release. +- bug #3830 Can't export custom query because it lowercases table names +- bug #3829 Enabling query profiling crashes javascript based navigation ++ rfe #879 Reserved word warning ++ Remove the database ordering sub-feature of the only_db directive +- bug #3840 When exporting to gzip format, the data is compressed 2 times ++ rfe #1319 Permit to create index when creating foreign key +- bug #3703 Incorrect updating of the list of users +- bug #3853 Blowfish implementation might be broken (replace with phpseclib) +- bug #3865 Using like operator on each backslash needs 4 backslash protection +- bug #3860 Displayed git revision info is not set +- bug #3871 Check referential integrity broken across databases +- bug #3874 [export] No preselected option when exporting table +- bug #3873 Can't copy table to target database if table exists there +- bug #3683 Incorrect listing of records from to count +- bug #3876 [import] PHP 5.2 - unexpected T_PAAMAYIM_NEKUDOTAYIM +- [security] Local file inclusion vulnerability, reported by Janek Vind + (see PMASA-2013-4) +- [security] Global variables overwrite in export.php, reported by Janek Vind + (see PMASA-2013-5) +- bug #3892 [export] SQL Export files are empty + +3.5.8.1 (2013-04-24) +- [security] Remote code execution (preg_replace), reported by Janek Vind + (see PMASA-2013-2) +- [security] Locally Saved SQL Dump File Multiple File Extension Remote Code + Execution, reported by Janek Vind (see PMASA-2013-3) + +3.5.8.0 (2013-04-08) +- bug #3828 MariaDB reported as MySQL +- bug #3854 Incorrect header for Safari 6.0 +- bug #3705 Attempt to open trigger for edit gives NULL +- Use HTML5 DOCTYPE +- [security] Self-XSS on GIS visualisation page, reported by Janek Vind +- bug #3800 Incorrect keyhandler behaviour #2 + +3.5.7.0 (2013-02-15) +- bug #3779 [core] Problem with backslash in enum fields +- bug #3816 Missing server_processlist.php +- bug #3821 Safari: white page +- Correct detection of the Chrome browser + +3.5.6.0 (2013-01-28) +- bug #3593604 [status] Erroneous advisor rule +- bug #3596070 [status] localStorage broken in server status monitor +- bug #3598736 [routines] Editing a procedure with special characters +- bug #3600322 [core] Visualize GIS data throws Fatal Error +- bug #3599362 [core] Double-escaped error message +- bug #3776 [cookies] Login without auth on second server + + --- Older ChangeLogs can be found on our project website --- + http://www.phpmyadmin.net/old-stuff/ChangeLogs/ + +# vim: et ts=4 sw=4 sts=4 +# vim: ft=changelog fenc=utf-8 +# vim: fde=getline(v\:lnum-1)=~'^\\s*$'&&getline(v\:lnum)=~'\\S'?'>1'\:1&&v\:lnum>4&&getline(v\:lnum)!~'^#' +# vim: fdn=1 fdm=expr diff --git a/phpmyadmin/LICENSE b/phpmyadmin/LICENSE new file mode 100644 index 000000000..3912109b5 --- /dev/null +++ b/phpmyadmin/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/phpmyadmin/README b/phpmyadmin/README new file mode 100644 index 000000000..94543f288 --- /dev/null +++ b/phpmyadmin/README @@ -0,0 +1,84 @@ +phpMyAdmin - Readme +=================== + +Version 4.0.4 + +A set of PHP-scripts to manage MySQL over the web. + +http://www.phpmyadmin.net/ + +Copyright +--------- + +Copyright (C) 1998-2000 + Tobias Ratschiller + +Copyright (C) 2001-2013 + Marc Delisle + Olivier Müller + Robin Johnson + Alexander M. Turek + Michal Čihař + Garvin Hicking + Michael Keck + Sebastian Mendel + [check documentation for more details] + +License +------- + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License version 2, as published by the +Free Software Foundation. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Requirements +------------ + +* PHP 5.2 or later +* MySQL 5.0 or later +* a web-browser (doh!) + +Summary +------- + +phpMyAdmin is intended to handle the administration of MySQL over the web. +For a summary of features, please see the documentation in the doc folder. + +Download +-------- + +You can get the newest version at http://www.phpmyadmin.net/. + +More Information +---------------- + +Please see the documentation in the doc folder. + +Support +------- + +See reference about support forums under http://www.phpmyadmin.net/ + + +Enjoy! +------ + +The phpMyAdmin Devel team + + +PS: + +Please, don't send us emails with question like "How do I compile PHP with +MySQL-support". We just don't have the time to be your free help desk. + +Please send your questions to the appropriate mailing lists / forums. Before +contacting us, please read the documentation (especially the FAQ part). + diff --git a/phpmyadmin/RELEASE-DATE-4.0.4 b/phpmyadmin/RELEASE-DATE-4.0.4 new file mode 100644 index 000000000..6eb670b97 --- /dev/null +++ b/phpmyadmin/RELEASE-DATE-4.0.4 @@ -0,0 +1 @@ +Mon Jun 17 16:28:34 UTC 2013 diff --git a/phpmyadmin/browse_foreigners.php b/phpmyadmin/browse_foreigners.php new file mode 100644 index 000000000..9a9fdf904 --- /dev/null +++ b/phpmyadmin/browse_foreigners.php @@ -0,0 +1,340 @@ +getFooter()->setMinimal(); +$header = $response->getHeader(); +$header->disableMenu(); +$header->setBodyId('body_browse_foreigners'); + +/** + * Displays the frame + */ + +$cfgRelation = PMA_getRelationsParam(); +$foreigners = ($cfgRelation['relwork'] ? PMA_getForeigners($db, $table) : false); + +$override_total = true; + +if (! isset($pos)) { + $pos = 0; +} + +$foreign_limit = 'LIMIT ' . $pos . ', ' . $GLOBALS['cfg']['MaxRows'] . ' '; +if (isset($foreign_navig) && $foreign_navig == __('Show all')) { + unset($foreign_limit); +} + +$foreignData = PMA_getForeignData( + $foreigners, $field, $override_total, + isset($foreign_filter) ? $foreign_filter : '', $foreign_limit +); + +if (isset($rownumber)) { + $rownumber_param = '&rownumber=' . urlencode($rownumber); +} else { + $rownumber_param = ''; +} + +$gotopage = ''; +$showall = ''; + +if (is_array($foreignData['disp_row'])) { + + if ($cfg['ShowAll'] + && ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) + ) { + $showall = ''; + } + + $session_max_rows = $GLOBALS['cfg']['MaxRows']; + $pageNow = @floor($pos / $session_max_rows) + 1; + $nbTotalPage = @ceil($foreignData['the_total'] / $session_max_rows); + + if ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) { + $gotopage = PMA_Util::pageselector( + 'pos', + $session_max_rows, + $pageNow, + $nbTotalPage, + 200, + 5, + 5, + 20, + 10, + __('Page number:') + ); + } +} + + + +if (isset($rownumber)) { + $element_name = " var element_name = field + '[multi_edit][" + . htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n" + . " var null_name = field_null + '[multi_edit][" + . htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n"; +} else { + $element_name = "var element_name = field + '[]'"; +} +$error = PMA_jsFormat( + __( + 'The target browser window could not be updated. ' + . 'Maybe you have closed the parent window, or ' + . 'your browser\'s security settings are ' + . 'configured to block cross-window updates.' + ) +); + + +if (! isset($fieldkey) || ! is_numeric($fieldkey)) { + $fieldkey = 0; +} + +$code = <<getScripts()->addCode($code); + +// HTML output +$output = '
' + . '
' + . PMA_generate_common_hidden_inputs($db, $table) + . '' + . ''; + +if (isset($rownumber)) { + $output .= ''; +} +$output .= '' + . '' + . '' + . '' + . '' + . '' . $gotopage . '' + . '' . $showall . '' + . '
' + . '
'; + +$output .= ''; + +if (is_array($foreignData['disp_row'])) { + $header = ' + + + + + + '; + + $output .= '' . $header . '' . "\n" + . '' . $header . '' . "\n" + . '' . "\n"; + + $values = array(); + $keys = array(); + foreach ($foreignData['disp_row'] as $relrow) { + if ($foreignData['foreign_display'] != false) { + $values[] = $relrow[$foreignData['foreign_display']]; + } else { + $values[] = ''; + } + + $keys[] = $relrow[$foreignData['foreign_field']]; + } + + asort($keys); + + $hcount = 0; + $odd_row = true; + $val_ordered_current_row = 0; + $val_ordered_current_equals_data = false; + $key_ordered_current_equals_data = false; + foreach ($keys as $key_ordered_current_row => $value) { + $hcount++; + + if ($cfg['RepeatCells'] > 0 && $hcount > $cfg['RepeatCells']) { + $output .= $header; + $hcount = 0; + $odd_row = true; + } + + $key_ordered_current_key = $keys[$key_ordered_current_row]; + $key_ordered_current_val = $values[$key_ordered_current_row]; + + $val_ordered_current_key = $keys[$val_ordered_current_row]; + $val_ordered_current_val = $values[$val_ordered_current_row]; + + $val_ordered_current_row++; + + if (PMA_strlen($val_ordered_current_val) <= $cfg['LimitChars']) { + $val_ordered_current_val = htmlspecialchars( + $val_ordered_current_val + ); + $val_ordered_current_val_title = ''; + } else { + $val_ordered_current_val_title = htmlspecialchars( + $val_ordered_current_val + ); + $val_ordered_current_val = htmlspecialchars( + PMA_substr($val_ordered_current_val, 0, $cfg['LimitChars']) + . '...' + ); + } + if (PMA_strlen($key_ordered_current_val) <= $cfg['LimitChars']) { + $key_ordered_current_val = htmlspecialchars( + $key_ordered_current_val + ); + $key_ordered_current_val_title = ''; + } else { + $key_ordered_current_val_title = htmlspecialchars( + $key_ordered_current_val + ); + $key_ordered_current_val = htmlspecialchars( + PMA_substr( + $key_ordered_current_val, 0, $cfg['LimitChars'] + ) . '...' + ); + } + + if (! empty($data)) { + $val_ordered_current_equals_data = $val_ordered_current_key == $data; + $key_ordered_current_equals_data = $key_ordered_current_key == $data; + } + + $output .= ''; + $odd_row = ! $odd_row; + + $output .= ''; + + $output .= ''; + + $output .= ''; + + $output .= ''; + + $output .= ''; + $output .= ''; + } // end while +} + +$output .= '' + . '
' . __('Keyname') . '' . __('Description') . '' . __('Description') . '' . __('Keyname') . '
' + . ($key_ordered_current_equals_data ? '' : '') + . '' + . htmlspecialchars($key_ordered_current_key) + . '' . ($key_ordered_current_equals_data ? '' : '') + . '' + . ($key_ordered_current_equals_data ? '' : '') + . '' + . $key_ordered_current_val . '' + . ($key_ordered_current_equals_data ? '' : '') + . '' + . '' + . ($val_ordered_current_equals_data ? '' : '') + . '' + . $val_ordered_current_val . '' + . ($val_ordered_current_equals_data ? '' : '') + . '' + . ($val_ordered_current_equals_data ? '' : '') + . '' + . htmlspecialchars($val_ordered_current_key) + . '' . ($val_ordered_current_equals_data ? '' : '') + . '
'; + +$response->addHtml($output); +?> diff --git a/phpmyadmin/changelog.php b/phpmyadmin/changelog.php new file mode 100644 index 000000000..c216c7fe3 --- /dev/null +++ b/phpmyadmin/changelog.php @@ -0,0 +1,152 @@ +disable(); + +$filename = CHANGELOG_FILE; + +/** + * Read changelog. + */ +// Check if the file is available, some distributions remove these. +if (is_readable($filename)) { + + // Test if the if is in a compressed format + if (substr($filename, -3) == '.gz') { + ob_start(); + readgzfile($filename); + $changelog = ob_get_contents(); + ob_end_clean(); + } else { + $changelog = file_get_contents($filename); + } +} else { + printf( + __('The %s file is not available on this system, please visit www.phpmyadmin.net for more information.'), + $filename + ); + exit; +} + +/** + * Whole changelog in variable. + */ +$changelog = htmlspecialchars($changelog); + +$tracker_url = 'https://sourceforge.net/support/tracker.php?aid=\\1'; +$tracker_url_bug = 'https://sourceforge.net/p/phpmyadmin/bugs/\\1/'; +$tracker_url_rfe = 'https://sourceforge.net/p/phpmyadmin/feature-requests/\\1/'; +$tracker_url_patch = 'https://sourceforge.net/p/phpmyadmin/patches/\\1/'; +$github_url = 'https://github.com/phpmyadmin/phpmyadmin/'; + +$replaces = array( + '@(http://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@' + => '\\1', + + // sourceforge users + '/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*)@users.sourceforge.net>/i' + => '\\1 \\2', + '/thanks to ([^\(\r\n]+) \(([-\w]+)\)/i' + => 'thanks to \\1', + '/thanks to ([^\(\r\n]+) -\s+([-\w]+)/i' + => 'thanks to \\1', + + // mail address + '/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*@.*)>/i' + => '\\1 \\2', + + // linking patches + '/patch\s*#?([0-9]{6,})/i' + => 'patch #\\1', + + // linking RFE + '/(?:rfe|feature)\s*#?([0-9]{6,})/i' + => 'RFE #\\1', + + // linking files + '/(\s+)([\\/a-z_0-9\.]+\.(?:php3?|html|pl|js|sh))/i' + => '\\1\\2', + + // FAQ entries + '/FAQ ([0-9]+)\.([0-9a-z]+)/i' + => 'FAQ \\1.\\2', + + // linking bugs + '/bug\s*#?([0-9]{6,})/i' + => 'bug #\\1', + + // all other 6+ digit numbers are treated as bugs + '/(? 'bug #\\1', + + // transitioned SF.net project bug/rfe/patch links + // by the time we reach 6-digit numbers, we can probably retire the above links + '/patch\s*#?([0-9]{4,5}) /i' + => 'patch #\\1 ', + '/(?:rfe|feature)\s*#?([0-9]{4,5}) /i' + => 'RFE #\\1 ', + '/bug\s*#?([0-9]{4,5}) /i' + => 'bug #\\1 ', + '/(? 'bug #\\1 ', + + // CVE/CAN entries + '/((CAN|CVE)-[0-9]+-[0-9]+)/' + => '\\1', + + // PMASAentries + '/(PMASA-[0-9]+-[0-9]+)/' + => '\\1', + + // Highlight releases (with links) + '/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/' + => '' + . '' + . '\\1.\\2.\\3.0 \\4', + '/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/' + => '' + . '' + . '\\1.\\2.\\3.\\4 \\5', + + // Highlight releases (not linkable) + '/( ### )(.*)/' + => '\\1\\2', + +); + +header('Content-type: text/html; charset=utf-8'); +?> + + + + + + phpMyAdmin - ChangeLog + + + +

phpMyAdmin - ChangeLog

+'; +echo preg_replace(array_keys($replaces), $replaces, $changelog); +echo ''; +?> + + + diff --git a/phpmyadmin/chk_rel.php b/phpmyadmin/chk_rel.php new file mode 100644 index 000000000..915e8b24b --- /dev/null +++ b/phpmyadmin/chk_rel.php @@ -0,0 +1,15 @@ +addHTML( + PMA_getRelationsParamDiagnostic(PMA_getRelationsParam()) +); + +?> diff --git a/phpmyadmin/composer.json b/phpmyadmin/composer.json new file mode 100644 index 000000000..ba03706ef --- /dev/null +++ b/phpmyadmin/composer.json @@ -0,0 +1,24 @@ +{ + "name": "phpmyadmin/phpmyadmin", + "type": "application", + "description": "MySQL web administration tool", + "keywords": ["phpmyadmin","mysql","web"], + "homepage": "http://www.phpmyadmin.net/", + "license": "GPL-2.0+", + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "phpmyadmin-devel@lists.sourceforge.net", + "homepage": "http://www.phpmyadmin.net/home_page/team.php" + } + ], + "support": { + "forum": "https://sourceforge.net/p/phpmyadmin/discussion/Help", + "issues": "https://sourceforge.net/p/phpmyadmin/bugs/", + "wiki": "http://wiki.phpmyadmin.net/", + "source": "https://github.com/phpmyadmin/phpmyadmin" + }, + "require": { + "php": ">=5.2.0" + } +} diff --git a/phpmyadmin/config.sample.inc.php b/phpmyadmin/config.sample.inc.php new file mode 100644 index 000000000..10db2b508 --- /dev/null +++ b/phpmyadmin/config.sample.inc.php @@ -0,0 +1,141 @@ +. + * + * @package PhpMyAdmin + */ + +/* + * This is needed for cookie based authentication to encrypt password in + * cookie + */ +$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ + +/* + * Servers configuration + */ +$i = 0; + +/* + * First server + */ +$i++; +/* Authentication type */ +$cfg['Servers'][$i]['auth_type'] = 'cookie'; +/* Server parameters */ +$cfg['Servers'][$i]['host'] = 'localhost'; +$cfg['Servers'][$i]['connect_type'] = 'tcp'; +$cfg['Servers'][$i]['compress'] = false; +/* Select mysql if your server does not have mysqli */ +$cfg['Servers'][$i]['extension'] = 'mysqli'; +$cfg['Servers'][$i]['AllowNoPassword'] = false; + +/* + * phpMyAdmin configuration storage settings. + */ + +/* User used to manipulate with storage */ +// $cfg['Servers'][$i]['controlhost'] = ''; +// $cfg['Servers'][$i]['controluser'] = 'pma'; +// $cfg['Servers'][$i]['controlpass'] = 'pmapass'; + +/* Storage database and tables */ +// $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin'; +// $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark'; +// $cfg['Servers'][$i]['relation'] = 'pma__relation'; +// $cfg['Servers'][$i]['table_info'] = 'pma__table_info'; +// $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords'; +// $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages'; +// $cfg['Servers'][$i]['column_info'] = 'pma__column_info'; +// $cfg['Servers'][$i]['history'] = 'pma__history'; +// $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs'; +// $cfg['Servers'][$i]['tracking'] = 'pma__tracking'; +// $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords'; +// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig'; +// $cfg['Servers'][$i]['recent'] = 'pma__recent'; +/* Contrib / Swekey authentication */ +// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf'; + +/* + * End of servers configuration + */ + +/* + * Directories for saving/loading files from server + */ +$cfg['UploadDir'] = ''; +$cfg['SaveDir'] = ''; + +/** + * Defines whether a user should be displayed a "show all (records)" + * button in browse mode or not. + * default = false + */ +//$cfg['ShowAll'] = true; + +/** + * Number of rows displayed when browsing a result set. If the result + * set contains more rows, "Previous" and "Next". + * default = 30 + */ +//$cfg['MaxRows'] = 50; + +/** + * disallow editing of binary fields + * valid values are: + * false allow editing + * 'blob' allow editing except for BLOB fields + * 'noblob' disallow editing except for BLOB fields + * 'all' disallow editing + * default = blob + */ +//$cfg['ProtectBinary'] = 'false'; + +/** + * Default language to use, if not browser-defined or user-defined + * (you find all languages in the locale folder) + * uncomment the desired line: + * default = 'en' + */ +//$cfg['DefaultLang'] = 'en'; +//$cfg['DefaultLang'] = 'de'; + +/** + * default display direction (horizontal|vertical|horizontalflipped) + */ +//$cfg['DefaultDisplay'] = 'vertical'; + + +/** + * How many columns should be used for table display of a database? + * (a value larger than 1 results in some information being hidden) + * default = 1 + */ +//$cfg['PropertiesNumColumns'] = 2; + +/** + * Set to true if you want DB-based query history.If false, this utilizes + * JS-routines to display query history (lost by window close) + * + * This requires configuration storage enabled, see above. + * default = false + */ +//$cfg['QueryHistoryDB'] = true; + +/** + * When using DB-based query history, how many entries should be kept? + * + * default = 25 + */ +//$cfg['QueryHistoryMax'] = 100; + +/* + * You can find more configuration options in the documentation + * in the doc/ folder or at . + */ +?> diff --git a/phpmyadmin/db_create.php b/phpmyadmin/db_create.php new file mode 100644 index 000000000..48ce08468 --- /dev/null +++ b/phpmyadmin/db_create.php @@ -0,0 +1,148 @@ +isSuccess(false); + $response->addJSON('message', $message); + } else { + include_once 'index.php'; + } +} else { + $message = PMA_Message::success(__('Database %1$s has been created.')); + $message->addParam($new_db); + $GLOBALS['db'] = $new_db; + + /** + * If in an Ajax request, build the output and send it + */ + if ($GLOBALS['is_ajax_request'] == true) { + //Construct the html for the new database, so that it can be appended to + // the list of databases on server_databases.php + + /** + * Build the array to be passed to {@link PMA_generate_common_url} + * to generate the links + * + * @global array $GLOBALS['db_url_params'] + * @name $db_url_params + */ + $db_url_params['db'] = $new_db; + + $is_superuser = PMA_isSuperuser(); + $column_order = PMA_getColumnOrder(); + $url_query = PMA_generate_common_url($new_db); + + /** + * String that will contain the output HTML + * @name $new_db_string + */ + $new_db_string = ''; + + if (empty($db_collation_for_ajax)) { + $db_collation_for_ajax = PMA_getServerCollation(); + } + + // $dbstats comes from the create table dialog + if (! empty($dbstats)) { + $current = array( + 'SCHEMA_NAME' => $new_db, + 'DEFAULT_COLLATION_NAME' => $db_collation_for_ajax, + 'SCHEMA_TABLES' => '0', + 'SCHEMA_TABLE_ROWS' => '0', + 'SCHEMA_DATA_LENGTH' => '0', + 'SCHEMA_MAX_DATA_LENGTH' => '0', + 'SCHEMA_INDEX_LENGTH' => '0', + 'SCHEMA_LENGTH' => '0', + 'SCHEMA_DATA_FREE' => '0' + ); + } else { + $current = array( + 'SCHEMA_NAME' => $new_db + ); + } + + list($column_order, $generated_html) = PMA_buildHtmlForDb( + $current, $is_superuser, $url_query, + $column_order, $replication_types, $replication_info + ); + $new_db_string .= $generated_html; + + $new_db_string .= ''; + + $response = PMA_Response::getInstance(); + $response->addJSON('message', $message); + $response->addJSON('new_db_string', $new_db_string); + $response->addJSON( + 'sql_query', + PMA_Util::getMessage( + null, $sql_query, 'success' + ) + ); + } else { + include_once '' . $cfg['DefaultTabDatabase']; + } +} +?> diff --git a/phpmyadmin/db_datadict.php b/phpmyadmin/db_datadict.php new file mode 100644 index 000000000..8744aa4a0 --- /dev/null +++ b/phpmyadmin/db_datadict.php @@ -0,0 +1,291 @@ +getHeader(); +$header->enablePrintView(); + +/** + * Gets the relations settings + */ +$cfgRelation = PMA_getRelationsParam(); + +require_once 'libraries/transformations.lib.php'; +require_once 'libraries/Index.class.php'; + +/** + * Check parameters + */ +PMA_Util::checkParameters(array('db')); + +/** + * Defines the url to return to in case of error in a sql statement + */ +if (strlen($table)) { + $err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table); +} else { + $err_url = 'db_sql.php?' . PMA_generate_common_url($db); +} + +if ($cfgRelation['commwork']) { + $comment = PMA_getDbComment($db); + + /** + * Displays DB comment + */ + if ($comment) { + echo '

' . __('Database comment: ') + . '' . htmlspecialchars($comment) . '

'; + } // end if +} + +/** + * Selects the database and gets tables names + */ +PMA_DBI_select_db($db); +$tables = PMA_DBI_get_tables($db); + +$count = 0; +foreach ($tables as $table) { + $comments = PMA_getComments($db, $table); + + echo '
' . "\n"; + + echo '

' . htmlspecialchars($table) . '

' . "\n"; + + /** + * Gets table informations + */ + $show_comment = PMA_Table::sGetStatusInfo($db, $table, 'TABLE_COMMENT'); + + /** + * Gets table keys and retains them + */ + + PMA_DBI_select_db($db); + $indexes = PMA_DBI_get_table_indexes($db, $table); + $primary = ''; + $indexes = array(); + $lastIndex = ''; + $indexes_info = array(); + $indexes_data = array(); + $pk_array = array(); // will be use to emphasis prim. keys in the table + // view + foreach ($indexes as $row) { + // Backups the list of primary keys + if ($row['Key_name'] == 'PRIMARY') { + $primary .= $row['Column_name'] . ', '; + $pk_array[$row['Column_name']] = 1; + } + // Retains keys informations + if ($row['Key_name'] != $lastIndex) { + $indexes[] = $row['Key_name']; + $lastIndex = $row['Key_name']; + } + $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index']; + $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique']; + if (isset($row['Cardinality'])) { + $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality']; + } + // I don't know what does following column mean.... + // $indexes_info[$row['Key_name']]['Packed'] = $row['Packed']; + + $indexes_info[$row['Key_name']]['Comment'] = $row['Comment']; + + $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name']; + if (isset($row['Sub_part'])) { + $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part']; + } + + } // end while + + /** + * Gets columns properties + */ + $columns = PMA_DBI_get_columns($db, $table); + $fields_cnt = count($columns); + + if (PMA_MYSQL_INT_VERSION < 50025) { + // We need this to correctly learn if a TIMESTAMP is NOT NULL, since + // SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL + // and SHOW CREATE TABLE says NOT NULL + // http://bugs.mysql.com/20910. + + $show_create_table_query = 'SHOW CREATE TABLE ' + . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table); + $show_create_table = PMA_DBI_fetch_value( + $show_create_table_query, 0, 1 + ); + $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table)); + } + + // Check if we can use Relations + if (!empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if (count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + + /** + * Displays the comments of the table if MySQL >= 3.23 + */ + if (!empty($show_comment)) { + echo __('Table comments') . ': ' . htmlspecialchars($show_comment) . '

'; + } + + /** + * Displays the table structure + */ + ?> + + + + +*/ ?> + + +*/ ?> + ' . __('Links to') . '' . "\n"; + } + echo ' ' . "\n"; + if ($cfgRelation['mimework']) { + echo ' ' . "\n"; + } + ?> + + NULL'; + } + } else { + $row['Default'] = htmlspecialchars($row['Default']); + } + $field_name = $row['Field']; + + if (PMA_MYSQL_INT_VERSION < 50025 + && ! empty($analyzed_sql[0]['create_table_fields'][$field_name]['type']) + && $analyzed_sql[0]['create_table_fields'][$field_name]['type'] == 'TIMESTAMP' + && $analyzed_sql[0]['create_table_fields'][$field_name]['timestamp_not_null'] + ) { + // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the + // NULL attribute, but SHOW CREATE TABLE says the contrary. Believe + // the latter. + /** + * @todo merge this logic with the one in tbl_structure.php + * or move it in a function similar to PMA_DBI_get_columns_full() + * but based on SHOW CREATE TABLE because information_schema + * cannot be trusted in this case (MySQL bug) + */ + $row['Null'] = 'NO'; + } + ?> + + + lang="en" dir="ltr"> +>*/ ?> + + +>*/ ?> + '; + if (isset($res_rel[$field_name])) { + echo htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field']); + } + echo '' . "\n"; + } + echo ' ' . "\n"; + if ($cfgRelation['mimework']) { + $mime_map = PMA_getMIME($db, $table, true); + + echo ' ' . "\n"; + } + ?> + + +
' . __('Comments') . 'MIME
+ ' . htmlspecialchars($field_name) . ''; + } else { + echo htmlspecialchars($field_name); + } + ?> + '; + if (isset($comments[$field_name])) { + echo htmlspecialchars($comments[$field_name]); + } + echo ''; + if (isset($mime_map[$field_name])) { + echo htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])); + } + echo '
+ 0) { + echo PMA_Index::getView($table, $db, true); + } +?> +
+ diff --git a/phpmyadmin/db_events.php b/phpmyadmin/db_events.php new file mode 100644 index 000000000..917778bc3 --- /dev/null +++ b/phpmyadmin/db_events.php @@ -0,0 +1,26 @@ + diff --git a/phpmyadmin/db_export.php b/phpmyadmin/db_export.php new file mode 100644 index 000000000..2b2fde41d --- /dev/null +++ b/phpmyadmin/db_export.php @@ -0,0 +1,90 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('export.js'); + +// $sub_part is also used in db_info.inc.php to see if we are coming from +// db_export.php, in which case we don't obey $cfg['MaxTableList'] +$sub_part = '_export'; +require_once 'libraries/db_common.inc.php'; +$url_query .= '&goto=db_export.php'; +require_once 'libraries/db_info.inc.php'; + +/** + * Displays the form + */ +$export_page_title = __('View dump (schema) of database'); + +// exit if no tables in db found +if ($num_tables < 1) { + PMA_Message::error(__('No tables found in database.'))->display(); + exit; +} // end if + +$multi_values = '
'; +$multi_values .= ''; +$multi_values .= __('Select All'); +$multi_values .= ''; +$multi_values .= ' / '; +$multi_values .= ''; +$multi_values .= __('Unselect All'); +$multi_values .= '
'; + +$multi_values .= '
'; + +$export_type = 'database'; +require_once 'libraries/display_export.lib.php'; + +?> diff --git a/phpmyadmin/db_import.php b/phpmyadmin/db_import.php new file mode 100644 index 000000000..f8ea8097a --- /dev/null +++ b/phpmyadmin/db_import.php @@ -0,0 +1,28 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('import.js'); + +/** + * Gets tables informations and displays top links + */ +require 'libraries/db_common.inc.php'; +require 'libraries/db_info.inc.php'; + +$import_type = 'database'; +require 'libraries/display_import.lib.php'; + +?> + diff --git a/phpmyadmin/db_operations.php b/phpmyadmin/db_operations.php new file mode 100644 index 000000000..338d38574 --- /dev/null +++ b/phpmyadmin/db_operations.php @@ -0,0 +1,293 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('db_operations.js'); + +/** + * Rename/move or copy database + */ +if (strlen($db) + && (! empty($_REQUEST['db_rename']) || ! empty($_REQUEST['db_copy'])) +) { + if (! empty($_REQUEST['db_rename'])) { + $move = true; + } else { + $move = false; + } + + if (! isset($_REQUEST['newname']) || ! strlen($_REQUEST['newname'])) { + $message = PMA_Message::error(__('The database name is empty!')); + } else { + $sql_query = ''; // in case target db exists + $_error = false; + if ($move + || (isset($_REQUEST['create_database_before_copying']) + && $_REQUEST['create_database_before_copying']) + ) { + $sql_query = PMA_getSqlQueryAndCreateDbBeforeCopy(); + } + + // here I don't use DELIMITER because it's not part of the + // language; I have to send each statement one by one + + // to avoid selecting alternatively the current and new db + // we would need to modify the CREATE definitions to qualify + // the db name + PMA_runProcedureAndFunctionDefinitions($db); + + // go back to current db, just in case + PMA_DBI_select_db($db); + + $tables_full = PMA_DBI_get_tables_full($db); + + include_once "libraries/plugin_interface.lib.php"; + // remove all foreign key constraints, otherwise we can get errors + $export_sql_plugin = PMA_getPlugin( + "export", + "sql", + 'libraries/plugins/export/', + array( + 'single_table' => isset($single_table), + 'export_type' => 'database' + ) + ); + $GLOBALS['sql_constraints_query_full_db'] + = PMA_getSqlConstraintsQueryForFullDb( + $tables_full, $export_sql_plugin, $move, $db + ); + + $views = PMA_getViewsAndCreateSqlViewStandIn( + $tables_full, $export_sql_plugin, $db + ); + + list($sql_query, $_error) = PMA_getSqlQueryForCopyTable( + $tables_full, $sql_query, $move, $db + ); + + // handle the views + if (! $_error) { + $_error = PMA_handleTheViews($views, $move, $db); + } + unset($views); + + // now that all tables exist, create all the accumulated constraints + if (! $_error && count($GLOBALS['sql_constraints_query_full_db']) > 0) { + PMA_createAllAccumulatedConstraints(); + } + + if (! PMA_DRIZZLE && PMA_MYSQL_INT_VERSION >= 50100) { + // here DELIMITER is not used because it's not part of the + // language; each statement is sent one by one + + PMA_runEventDefinitionsForDb($db); + } + + // go back to current db, just in case + PMA_DBI_select_db($db); + + // Duplicate the bookmarks for this db (done once for each db) + PMA_duplicateBookmarks($_error, $db); + + if (! $_error && $move) { + /** + * cleanup pmadb stuff for this db + */ + include_once 'libraries/relation_cleanup.lib.php'; + PMA_relationsCleanupDatabase($db); + + // if someday the RENAME DATABASE reappears, do not DROP + $local_query = 'DROP DATABASE ' . PMA_Util::backquote($db) . ';'; + $sql_query .= "\n" . $local_query; + PMA_DBI_query($local_query); + + $message = PMA_Message::success(__('Database %1$s has been renamed to %2$s')); + $message->addParam($db); + $message->addParam($_REQUEST['newname']); + } elseif (! $_error) { + $message = PMA_Message::success(__('Database %1$s has been copied to %2$s')); + $message->addParam($db); + $message->addParam($_REQUEST['newname']); + } + $reload = true; + + /* Change database to be used */ + if (! $_error && $move) { + $db = $_REQUEST['newname']; + } elseif (! $_error) { + if (isset($_REQUEST['switch_to_new']) + && $_REQUEST['switch_to_new'] == 'true' + ) { + $GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', 'true'); + $db = $_REQUEST['newname']; + } else { + $GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', ''); + } + } + + if ($_error && ! isset($message)) { + $message = PMA_Message::error(); + } + } + + /** + * Database has been successfully renamed/moved. If in an Ajax request, + * generate the output with {@link PMA_Response} and exit + */ + if ($GLOBALS['is_ajax_request'] == true) { + $response = PMA_Response::getInstance(); + $response->isSuccess($message->isSuccess()); + $response->addJSON('message', $message); + $response->addJSON('newname', $_REQUEST['newname']); + $response->addJSON( + 'sql_query', + PMA_Util::getMessage(null, $sql_query) + ); + exit; + } +} + +/** + * Settings for relations stuff + */ + +$cfgRelation = PMA_getRelationsParam(); + +/** + * Check if comments were updated + * (must be done before displaying the menu tabs) + */ +if (isset($_REQUEST['comment'])) { + PMA_setDbComment($db, $_REQUEST['comment']); +} + +/** + * Prepares the tables list if the user where not redirected to this script + * because there is no table in the database ($is_info is true) + */ +if (empty($is_info)) { + include 'libraries/db_common.inc.php'; + $url_query .= '&goto=db_operations.php'; + + // Gets the database structure + $sub_part = '_structure'; + include 'libraries/db_info.inc.php'; + echo "\n"; + + if (isset($message)) { + echo PMA_Util::getMessage($message, $sql_query); + unset($message); + } +} + +$_REQUEST['db_collation'] = PMA_getDbCollation($db); +$is_information_schema = PMA_is_system_schema($db); + +if (!$is_information_schema) { + if ($cfgRelation['commwork']) { + /** + * database comment + */ + $response->addHTML(PMA_getHtmlForDatabaseComment($db)); + } + + $response->addHTML('
'); + ob_start(); + include 'libraries/display_create_table.lib.php'; + $content = ob_get_contents(); + ob_end_clean(); + $response->addHTML($content); + $response->addHTML('
'); + + /** + * rename database + */ + if ($db != 'mysql') { + $response->addHTML(PMA_getHtmlForRenameDatabase($db)); + } + + // Drop link if allowed + // Don't even try to drop information_schema. + // You won't be able to. Believe me. You won't. + // Don't allow to easily drop mysql database, RFE #1327514. + if (($is_superuser || $GLOBALS['cfg']['AllowUserDropDatabase']) + && ! $db_is_information_schema + && (PMA_DRIZZLE || $db != 'mysql') + ) { + $response->addHTML(PMA_getHtmlForDropDatabaseLink($db)); + } + /** + * Copy database + */ + $response->addHTML(PMA_getHtmlForCopyDatabase($db)); + + /** + * Change database charset + */ + $response->addHTML(PMA_getHtmlForChangeDatabaseCharset($db, $table)); + + if ($num_tables > 0 + && ! $cfgRelation['allworks'] + && $cfg['PmaNoRelation_DisableWarning'] == false + ) { + $message = PMA_Message::notice( + __('The phpMyAdmin configuration storage has been deactivated. To find out why click %shere%s.') + ); + $message->addParam( + '', + false + ); + $message->addParam('', false); + /* Show error if user has configured something, notice elsewhere */ + if (!empty($cfg['Servers'][$server]['pmadb'])) { + $message->isError(true); + } + $response->addHTML('
'); + $response->addHTML($message->getDisplay()); + $response->addHTML('
'); + } // end if +} // end if (!$is_information_schema) + + +// not sure about displaying the PDF dialog in case db is information_schema +if ($cfgRelation['pdfwork'] && $num_tables > 0) { + // We only show this if we find something in the new pdf_pages table + $test_query = ' + SELECT * + FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) + . '.' . PMA_Util::backquote($cfgRelation['pdf_pages']) . ' + WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''; + $test_rs = PMA_queryAsControlUser($test_query, null, PMA_DBI_QUERY_STORE); + + /* + * Export Relational Schema View + */ + $response->addHTML(PMA_getHtmlForExportRelationalSchemaView($url_query)); +} // end if + +?> diff --git a/phpmyadmin/db_printview.php b/phpmyadmin/db_printview.php new file mode 100644 index 000000000..e0c2f1423 --- /dev/null +++ b/phpmyadmin/db_printview.php @@ -0,0 +1,252 @@ +getHeader(); +$header->enablePrintView(); + +PMA_Util::checkParameters(array('db')); + +/** + * Defines the url to return to in case of error in a sql statement + */ +$err_url = 'db_sql.php?' . PMA_generate_common_url($db); + +/** + * Settings for relations stuff + */ +$cfgRelation = PMA_getRelationsParam(); + +/** + * Gets the list of the table in the current db and informations about these + * tables if possible + * + * @todo merge this speedup _optionaly_ into PMA_DBI_get_tables_full() + * +// speedup view on locked tables +// Special speedup for newer MySQL Versions (in 4.0 format changed) +if ($cfg['SkipLockedTables'] == true) { + $result = PMA_DBI_query('SHOW OPEN TABLES FROM ' . PMA_Util::backquote($db) . ';'); + // Blending out tables in use + if ($result != false && PMA_DBI_num_rows($result) > 0) { + while ($tmp = PMA_DBI_fetch_row($result)) { + // if in use memorize tablename + if (preg_match('@in_use=[1-9]+@i', $tmp[0])) { + $sot_cache[$tmp[0]] = true; + } + } + PMA_DBI_free_result($result); + + if (isset($sot_cache)) { + $result = PMA_DBI_query('SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';', null, PMA_DBI_QUERY_STORE); + if ($result != false && PMA_DBI_num_rows($result) > 0) { + while ($tmp = PMA_DBI_fetch_row($result)) { + if (! isset($sot_cache[$tmp[0]])) { + $sts_result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ' LIKE \'' . sqlAddSlashes($tmp[0], true) . '\';'); + $sts_tmp = PMA_DBI_fetch_assoc($sts_result); + $tables[] = $sts_tmp; + } else { // table in use + $tables[] = array('Name' => $tmp[0]); + } + } + PMA_DBI_free_result($result); + $sot_ready = true; + } + } + unset($tmp, $result); + } +} + +if (! isset($sot_ready)) { + $result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ';'); + if (PMA_DBI_num_rows($result) > 0) { + while ($sts_tmp = PMA_DBI_fetch_assoc($result)) { + $tables[] = $sts_tmp; + } + PMA_DBI_free_result($result); + unset($res); + } +} + */ + +/** + * If there is at least one table, displays the printer friendly view, else + * an error message + */ +$tables = PMA_DBI_get_tables_full($db); +$num_tables = count($tables); + +echo '
'; + +// 1. No table +if ($num_tables == 0) { + echo __('No tables found in database.'); +} else { +// 2. Shows table information + ?> + + + + + + + ' . __('Size') . ''; + } + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + ' . PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . '' . "\n"; + } else { + echo PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . "\n"; + } + ?> + + + + + + + + '; + } else { + $needs_break = ''; + } + + if (! empty($sts_data['Create_time']) + || ! empty($sts_data['Update_time']) + || ! empty($sts_data['Check_time']) + ) { + echo $needs_break; + ?> + + + + + + + + + + + + + + + + + +
+ +
+ + + + + -- + + +
+ \n"; +?> diff --git a/phpmyadmin/db_qbe.php b/phpmyadmin/db_qbe.php new file mode 100644 index 000000000..940758ccc --- /dev/null +++ b/phpmyadmin/db_qbe.php @@ -0,0 +1,68 @@ + (maybe) execute it + */ +$message_to_display = false; +if (isset($_REQUEST['submit_sql']) && ! empty($sql_query)) { + if (! preg_match('@^SELECT@i', $sql_query)) { + $message_to_display = true; + } else { + $goto = 'db_sql.php'; + include 'sql.php'; + exit; + } +} + +$sub_part = '_qbe'; +require 'libraries/db_common.inc.php'; +$url_query .= '&goto=db_qbe.php'; +$url_params['goto'] = 'db_qbe.php'; +require 'libraries/db_info.inc.php'; + +if ($message_to_display) { + PMA_Message::error(__('You have to choose at least one column to display'))->display(); +} +unset($message_to_display); + +// create new qbe search instance +$db_qbe = new PMA_DBQbe($GLOBALS['db']); + +/** + * Displays the Query by example form + */ +if ($cfgRelation['designerwork']) { + $url = 'pmd_general.php' . PMA_generate_common_url( + array_merge( + $url_params, + array('query' => 1) + ) + ); + $response->addHTML( + PMA_Message::notice( + sprintf( + __('Switch to %svisual builder%s'), + '', + '' + ) + ) + ); +} +$response->addHTML($db_qbe->getSelectionForm($cfgRelation)); +?> diff --git a/phpmyadmin/db_routines.php b/phpmyadmin/db_routines.php new file mode 100644 index 000000000..690da852f --- /dev/null +++ b/phpmyadmin/db_routines.php @@ -0,0 +1,27 @@ + diff --git a/phpmyadmin/db_search.php b/phpmyadmin/db_search.php new file mode 100644 index 000000000..acfec8e55 --- /dev/null +++ b/phpmyadmin/db_search.php @@ -0,0 +1,57 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('db_search.js'); +$scripts->addFile('sql.js'); +$scripts->addFile('makegrid.js'); +$scripts->addFile('jquery/jquery-ui-timepicker-addon.js'); + +require 'libraries/db_common.inc.php'; + +// If config variable $GLOBALS['cfg']['Usedbsearch'] is on false : exit. +if (! $GLOBALS['cfg']['UseDbSearch']) { + PMA_Util::mysqlDie( + __('Access denied'), '', false, $err_url + ); +} // end if +$url_query .= '&goto=db_search.php'; +$url_params['goto'] = 'db_search.php'; + +// Create a database search instance +$db_search = new PMA_DbSearch($GLOBALS['db']); + +// Display top links if we are not in an Ajax request +if ( $GLOBALS['is_ajax_request'] != true) { + include 'libraries/db_info.inc.php'; +} +$response->addHTML('
'); + +// Main search form has been submitted, get results +if (isset($_REQUEST['submit_search'])) { + $response->addHTML($db_search->getSearchResults()); +} + +// If we are in an Ajax request, we need to exit after displaying all the HTML +if ($GLOBALS['is_ajax_request'] == true && empty($_REQUEST['ajax_page_request'])) { + exit; +} + +// Display the search form +$response->addHTML($db_search->getSelectionForm($url_params)); +?> diff --git a/phpmyadmin/db_sql.php b/phpmyadmin/db_sql.php new file mode 100644 index 000000000..baced4407 --- /dev/null +++ b/phpmyadmin/db_sql.php @@ -0,0 +1,65 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('functions.js'); +$scripts->addFile('makegrid.js'); +$scripts->addFile('sql.js'); + +require 'libraries/db_common.inc.php'; +require_once 'libraries/sql_query_form.lib.php'; + +// After a syntax error, we return to this script +// with the typed query in the textarea. +$goto = 'db_sql.php'; +$back = 'db_sql.php'; + +/** + * Sets globals from $_GET + */ + +$get_params = array( + 'db_query_force' +); + +foreach ($get_params as $one_get_param) { + if (isset($_GET[$one_get_param])) { + $GLOBALS[$one_get_param] = $_GET[$one_get_param]; + } +} + +/** + * Gets informations about the database and, if it is empty, move to the + * "db_structure.php" script where table can be created + */ +require 'libraries/db_info.inc.php'; +if ($num_tables == 0 && empty($db_query_force)) { + $sub_part = ''; + $is_info = true; + include 'db_structure.php'; + exit(); +} + +/** + * Query box, bookmark, insert data from textfile + */ +PMA_sqlQueryForm( + true, false, + isset($_REQUEST['delimiter']) ? htmlspecialchars($_REQUEST['delimiter']) : ';' +); + +?> diff --git a/phpmyadmin/db_structure.php b/phpmyadmin/db_structure.php new file mode 100644 index 000000000..ed5a48151 --- /dev/null +++ b/phpmyadmin/db_structure.php @@ -0,0 +1,335 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('db_structure.js'); +$scripts->addFile('tbl_change.js'); +$scripts->addFile('jquery/jquery-ui-timepicker-addon.js'); + +$post_params = array( + 'error', + 'is_info', + 'message', + 'mult_btn', + 'selected_tbl', + 'submit_mult' +); +foreach ($post_params as $one_post_param) { + if (isset($_POST[$one_post_param])) { + $GLOBALS[$one_post_param] = $_POST[$one_post_param]; + } +} +/** + * Prepares the tables list if the user where not redirected to this script + * because there is no table in the database ($is_info is true) + */ +if (empty($_POST['is_info'])) { + // Drops/deletes/etc. multiple tables if required + if ((!empty($_POST['submit_mult']) && isset($_POST['selected_tbl'])) + || isset($_POST['mult_btn']) + ) { + $action = 'db_structure.php'; + $err_url = 'db_structure.php?'. PMA_generate_common_url($db); + + // see bug #2794840; in this case, code path is: + // db_structure.php -> libraries/mult_submits.inc.php -> sql.php + // -> db_structure.php and if we got an error on the multi submit, + // we must display it here and not call again mult_submits.inc.php + if (! isset($_POST['error']) || false === $_POST['error']) { + include 'libraries/mult_submits.inc.php'; + } + if (empty($_POST['message'])) { + $_POST['message'] = PMA_Message::success(); + } + } + include 'libraries/db_common.inc.php'; + $url_query .= '&goto=db_structure.php'; + + // Gets the database structure + $sub_part = '_structure'; + include 'libraries/db_info.inc.php'; + + if (!PMA_DRIZZLE) { + include_once 'libraries/replication.inc.php'; + } else { + $server_slave_status = false; + } +} + +require_once 'libraries/bookmark.lib.php'; + +require_once 'libraries/mysql_charsets.lib.php'; +$db_collation = PMA_getDbCollation($db); + +$titles = PMA_Util::buildActionTitles(); + +// 1. No tables + +if ($num_tables == 0) { + $response->addHTML( + '

' . __('No tables found in database') . '

' . "\n" + ); + if (empty($db_is_information_schema)) { + ob_start(); + include 'libraries/display_create_table.lib.php'; + $content = ob_get_contents(); + ob_end_clean(); + $response->addHTML($content); + unset($content); + } // end if (Create Table dialog) + exit; +} + +// else +// 2. Shows table informations + +/** + * Displays the tables list + */ +$response->addHTML('
'); +$_url_params = array( + 'pos' => $pos, + 'db' => $db); + +// Add the sort options if they exists +if (isset($_REQUEST['sort'])) { + $_url_params['sort'] = $_REQUEST['sort']; +} + +if (isset($_REQUEST['sort_order'])) { + $_url_params['sort_order'] = $_REQUEST['sort_order']; +} + +$response->addHTML( + PMA_Util::getListNavigator( + $total_num_tables, $pos, $_url_params, 'db_structure.php', + 'frame_content', $GLOBALS['cfg']['MaxTableList'] + ) +); + +// tables form +$response->addHTML( + '
' +); + +$response->addHTML(PMA_generate_common_hidden_inputs($db)); + +$response->addHTML( + PMA_TableHeader($db_is_information_schema, $server_slave_status) +); + +$i = $sum_entries = 0; +$overhead_check = ''; +$create_time_all = ''; +$update_time_all = ''; +$check_time_all = ''; +$num_columns = $cfg['PropertiesNumColumns'] > 1 + ? ceil($num_tables / $cfg['PropertiesNumColumns']) + 1 + : 0; +$row_count = 0; +$sum_size = (double) 0; +$overhead_size = (double) 0; + +$hidden_fields = array(); +$odd_row = true; +$sum_row_count_pre = ''; + +foreach ($tables as $keyname => $current_table) { + // Get valid statistics whatever is the table type + + $drop_query = ''; + $drop_message = ''; + $overhead = ''; + + $table_is_view = false; + $table_encoded = urlencode($current_table['TABLE_NAME']); + // Sets parameters for links + $tbl_url_query = $url_query . '&table=' . $table_encoded; + // do not list the previous table's size info for a view + + list($current_table, $formatted_size, $unit, $formatted_overhead, + $overhead_unit, $overhead_size, $table_is_view, $sum_size) + = PMA_getStuffForEngineTypeTable( + $current_table, $db_is_information_schema, + $is_show_stats, $table_is_view, $sum_size, $overhead_size + ); + + if (! PMA_Table::isMerge($db, $current_table['TABLE_NAME'])) { + $sum_entries += $current_table['TABLE_ROWS']; + } + + if (isset($current_table['Collation'])) { + $collation = '' + . $current_table['Collation'] . ''; + } else { + $collation = '---'; + } + + if ($is_show_stats) { + if ($formatted_overhead != '') { + $overhead = '' + . '' . $formatted_overhead . '' + . '' . $overhead_unit . '' + . '' . "\n"; + $overhead_check .= + "markAllRows('row_tbl_" . ($i + 1) . "');"; + } else { + $overhead = '-'; + } + } // end if + + unset($showtable); + + if ($GLOBALS['cfg']['ShowDbStructureCreation']) { + list($create_time, $create_time_all) = PMA_getTimeForCreateUpdateCheck( + $current_table, 'Create_time', $create_time_all + ); + } + + if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) { + // $showtable might already be set from ShowDbStructureCreation, see above + list($update_time, $update_time_all) = PMA_getTimeForCreateUpdateCheck( + $current_table, 'Update_time', $update_time_all + ); + } + + if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) { + // $showtable might already be set from ShowDbStructureCreation, see above + list($check_time, $check_time_all) = PMA_getTimeForCreateUpdateCheck( + $current_table, 'Check_time', $check_time_all + ); + } + + list($alias, $truename) = PMA_getAliasAndTrueName( + $tooltip_aliasname, $current_table, $tooltip_truename + ); + + $i++; + + $row_count++; + if ($table_is_view) { + $hidden_fields[] = ''; + } + + /* + * Always activate links for Browse, Search and Empty, even if + * the icons are greyed, because + * 1. for views, we don't know the number of rows at this point + * 2. for tables, another source could have populated them since the + * page was generated + * + * I could have used the PHP ternary conditional operator but I find + * the code easier to read without this operator. + */ + list($browse_table, $search_table, $browse_table_label, $empty_table, + $tracking_icon) = PMA_getHtmlForActionLinks( + $current_table, $table_is_view, $tbl_url_query, + $titles, $truename, $db_is_information_schema, $url_query + ); + + if (! $db_is_information_schema) { + list($drop_query, $drop_message) + = PMA_getTableDropQueryAndMessage($table_is_view, $current_table); + } + + if ($num_columns > 0 + && $num_tables > $num_columns + && ($row_count % $num_columns) == 0 + ) { + $row_count = 1; + $odd_row = true; + + $response->addHTML( + '' + ); + + $response->addHTML(PMA_TableHeader(false, $server_slave_status)); + } + + list($do, $ignored) = PMA_getServerSlaveStatus( + $server_slave_status, $truename + ); + + list($html_output, $odd_row) = PMA_getHtmlForStructureTableRow( + $i, $odd_row, $table_is_view, $current_table, + $browse_table_label, $tracking_icon, $server_slave_status, + $browse_table, $tbl_url_query, $search_table, $db_is_information_schema, + $titles, $empty_table, $drop_query, $drop_message, $collation, + $formatted_size, $unit, $overhead, + (isset ($create_time) ? $create_time : ''), + (isset ($update_time) ? $update_time : ''), + (isset ($check_time) ? $check_time : ''), + $is_show_stats, $ignored, $do, $colspan_for_structure + ); + $response->addHTML($html_output); + +} // end foreach + +// Show Summary +$response->addHTML(''); +$response->addHTML( + PMA_getHtmlBodyForTableSummary( + $num_tables, $server_slave_status, $db_is_information_schema, $sum_entries, + $db_collation, $is_show_stats, $sum_size, $overhead_size, $create_time_all, + $update_time_all, $check_time_all, $sum_row_count_pre + ) +); +$response->addHTML(''); +//check all +$response->addHTML( + PMA_getHtmlForCheckAllTables( + $pmaThemeImage, $text_dir, $overhead_check, + $db_is_information_schema, $hidden_fields + ) +); +$response->addHTML('
'); //end of form + +// display again the table list navigator +$response->addHTML( + PMA_Util::getListNavigator( + $total_num_tables, $pos, $_url_params, 'db_structure.php', + 'frame_content', $GLOBALS['cfg']['MaxTableList'] + ) +); + +$response->addHTML('

'); + +/** + * Work on the database + */ +/* DATABASE WORK */ +/* Printable view of a table */ +$response->addHTML( + PMA_getHtmlForTablePrintViewLink($url_query) + . PMA_getHtmlForDataDictionaryLink($url_query) +); + +if (empty($db_is_information_schema)) { + ob_start(); + include 'libraries/display_create_table.lib.php'; + $content = ob_get_contents(); + ob_end_clean(); + $response->addHTML($content); +} // end if (Create Table dialog) + +?> diff --git a/phpmyadmin/db_tracking.php b/phpmyadmin/db_tracking.php new file mode 100644 index 000000000..e95a7e0a5 --- /dev/null +++ b/phpmyadmin/db_tracking.php @@ -0,0 +1,243 @@ +getHeader(); +$scripts = $header->getScripts(); +$scripts->addFile('db_structure.js'); + +/** + * If we are not in an Ajax request, then do the common work and show the links etc. + */ +require 'libraries/db_common.inc.php'; +$url_query .= '&goto=tbl_tracking.php&back=db_tracking.php'; + +// Get the database structure +$sub_part = '_structure'; +require 'libraries/db_info.inc.php'; + +// Work to do? +// (here, do not use $_REQUEST['db] as it can be crafted) +if (isset($_REQUEST['delete_tracking']) && isset($_REQUEST['table'])) { + PMA_Tracker::deleteTracking($GLOBALS['db'], $_REQUEST['table']); + + /** + * If in an Ajax request, generate the success message and use + * {@link PMA_Response()} to send the output + */ + if ($GLOBALS['is_ajax_request'] == true) { + $response = PMA_Response::getInstance(); + $response->addJSON('message', PMA_Message::success()); + exit; + } +} + +// Get tracked data about the database +$data = PMA_Tracker::getTrackedData($_REQUEST['db'], '', '1'); + +// No tables present and no log exist +if ($num_tables == 0 && count($data['ddlog']) == 0) { + echo '

' . __('No tables found in database.') . '

' . "\n"; + + if (empty($db_is_information_schema)) { + include 'libraries/display_create_table.lib.php'; + } + exit; +} + +// --------------------------------------------------------------------------- + +// Prepare statement to get HEAD version +$all_tables_query = ' SELECT table_name, MAX(version) as version FROM ' . + PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . '.' . + PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) . + ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db']) . '\' ' . + ' GROUP BY table_name' . + ' ORDER BY table_name ASC'; + +$all_tables_result = PMA_queryAsControlUser($all_tables_query); + +// If a HEAD version exists +if (PMA_DBI_num_rows($all_tables_result) > 0) { +?> +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ | + |
+
+ $value) { + // If $value is a table group. + if (array_key_exists(('is' . $sep . 'group'), $value) + && $value['is' . $sep . 'group'] + ) { + foreach ($value as $temp_table) { + // If $temp_table is a table with the value for 'Name' is set, + // rather than a propery of the table group. + if (is_array($temp_table) + && array_key_exists('Name', $temp_table) + ) { + $tracking_version = PMA_Tracker::getVersion( + $GLOBALS['db'], + $temp_table['Name'] + ); + if ($tracking_version == -1) { + $my_tables[] = $temp_table['Name']; + } + } + } + } else { // If $value is a table. + if (PMA_Tracker::getVersion($GLOBALS['db'], $value['Name']) == -1) { + $my_tables[] = $value['Name']; + } + } +} + +// If untracked tables exist +if (isset($my_tables)) { +?> +

+ + + + + + + + + + $tablename) { + if (PMA_Tracker::getVersion($GLOBALS['db'], $tablename) == -1) { + $my_link = ''; + $my_link .= PMA_Util::getIcon('eye.png', __('Track table')); + $my_link .= ''; + ?> + + + + + + +
+ + 0) { + $log = ''; + foreach ($data['ddlog'] as $entry) { + $log .= '# ' . $entry['date'] . ' ' . $entry['username'] . "\n" + . $entry['statement'] . "\n"; + } + echo PMA_Util::getMessage(__('Database Log'), $log); +} + +?> diff --git a/phpmyadmin/db_triggers.php b/phpmyadmin/db_triggers.php new file mode 100644 index 000000000..d1a2a8c6b --- /dev/null +++ b/phpmyadmin/db_triggers.php @@ -0,0 +1,25 @@ + diff --git a/phpmyadmin/doc/Makefile b/phpmyadmin/doc/Makefile new file mode 100644 index 000000000..1ee62c86a --- /dev/null +++ b/phpmyadmin/doc/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = . + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/phpMyAdmin.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/phpMyAdmin.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/phpMyAdmin" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/phpMyAdmin" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/phpmyadmin/doc/_ext/configext.py b/phpmyadmin/doc/_ext/configext.py new file mode 100644 index 000000000..fdf33149c --- /dev/null +++ b/phpmyadmin/doc/_ext/configext.py @@ -0,0 +1,189 @@ +from sphinx.locale import l_, _ +from sphinx.domains import Domain, ObjType +from sphinx.roles import XRefRole +from sphinx.domains.std import GenericObject, StandardDomain +from sphinx.directives import ObjectDescription +from sphinx.util.nodes import clean_astext, make_refnode +from sphinx.util import ws_re +from sphinx import addnodes +from sphinx.util.docfields import Field +from docutils import nodes + +def get_id_from_cfg(text): + ''' + Formats anchor ID from config option. + ''' + if text[:6] == '$cfg[\'': + text = text[6:] + if text[-2:] == '\']': + text = text[:-2] + text = text.replace('[$i]', '') + parts = text.split("']['") + return parts + + +class ConfigOption(ObjectDescription): + indextemplate = l_('configuration option; %s') + parse_node = None + + has_arguments = True + + doc_field_types = [ + Field('default', label=l_('Default value'), has_arg=False, + names=('default', )), + Field('type', label=l_('Type'), has_arg=False, + names=('type',)), + ] + + + def handle_signature(self, sig, signode): + signode.clear() + signode += addnodes.desc_name(sig, sig) + # normalize whitespace like XRefRole does + name = ws_re.sub('', sig) + return name + + def add_target_and_index(self, name, sig, signode): + targetparts = get_id_from_cfg(name) + targetname = 'cfg_%s' % '_'.join(targetparts) + signode['ids'].append(targetname) + self.state.document.note_explicit_target(signode) + indextype = 'single' + + # Generic index entries + indexentry = self.indextemplate % (name,) + self.indexnode['entries'].append((indextype, indexentry, + targetname, targetname)) + self.indexnode['entries'].append((indextype, name, + targetname, targetname)) + + # Server section + if targetparts[0] == 'Servers' and len(targetparts) > 1: + indexname = ', '.join(targetparts[1:]) + self.indexnode['entries'].append((indextype, l_('server configuration; %s') % indexname, + targetname, targetname)) + self.indexnode['entries'].append((indextype, indexname, + targetname, targetname)) + else: + indexname = ', '.join(targetparts) + self.indexnode['entries'].append((indextype, indexname, + targetname, targetname)) + + self.env.domaindata['config']['objects'][self.objtype, name] = \ + self.env.docname, targetname + + +class ConfigSectionXRefRole(XRefRole): + """ + Cross-referencing role for configuration sections (adds an index entry). + """ + + def result_nodes(self, document, env, node, is_ref): + if not is_ref: + return [node], [] + varname = node['reftarget'] + tgtid = 'index-%s' % env.new_serialno('index') + indexnode = addnodes.index() + indexnode['entries'] = [ + ('single', varname, tgtid, varname), + ('single', _('configuration section; %s') % varname, tgtid, varname) + ] + targetnode = nodes.target('', '', ids=[tgtid]) + document.note_explicit_target(targetnode) + return [indexnode, targetnode, node], [] + +class ConfigSection(ObjectDescription): + indextemplate = l_('configuration section; %s') + parse_node = None + + def handle_signature(self, sig, signode): + if self.parse_node: + name = self.parse_node(self.env, sig, signode) + else: + signode.clear() + signode += addnodes.desc_name(sig, sig) + # normalize whitespace like XRefRole does + name = ws_re.sub('', sig) + return name + + def add_target_and_index(self, name, sig, signode): + targetname = '%s-%s' % (self.objtype, name) + signode['ids'].append(targetname) + self.state.document.note_explicit_target(signode) + if self.indextemplate: + colon = self.indextemplate.find(':') + if colon != -1: + indextype = self.indextemplate[:colon].strip() + indexentry = self.indextemplate[colon+1:].strip() % (name,) + else: + indextype = 'single' + indexentry = self.indextemplate % (name,) + self.indexnode['entries'].append((indextype, indexentry, + targetname, targetname)) + self.env.domaindata['config']['objects'][self.objtype, name] = \ + self.env.docname, targetname + + +class ConfigOptionXRefRole(XRefRole): + """ + Cross-referencing role for configuration options (adds an index entry). + """ + + def result_nodes(self, document, env, node, is_ref): + if not is_ref: + return [node], [] + varname = node['reftarget'] + tgtid = 'index-%s' % env.new_serialno('index') + indexnode = addnodes.index() + indexnode['entries'] = [ + ('single', varname, tgtid, varname), + ('single', _('configuration option; %s') % varname, tgtid, varname) + ] + targetnode = nodes.target('', '', ids=[tgtid]) + document.note_explicit_target(targetnode) + return [indexnode, targetnode, node], [] + + +class ConfigFileDomain(Domain): + name = 'config' + label = 'Config' + + object_types = { + 'option': ObjType(l_('config option'), 'option'), + 'section': ObjType(l_('config section'), 'section'), + } + directives = { + 'option': ConfigOption, + 'section': ConfigSection, + } + roles = { + 'option': ConfigOptionXRefRole(), + 'section': ConfigSectionXRefRole(), + } + + initial_data = { + 'objects': {}, # (type, name) -> docname, labelid + } + + def clear_doc(self, docname): + for key, (fn, _) in self.data['objects'].items(): + if fn == docname: + del self.data['objects'][key] + + def resolve_xref(self, env, fromdocname, builder, + typ, target, node, contnode): + docname, labelid = self.data['objects'].get((typ, target), ('', '')) + if not docname: + return None + else: + return make_refnode(builder, fromdocname, docname, + labelid, contnode) + + def get_objects(self): + for (type, name), info in self.data['objects'].iteritems(): + yield (name, name, type, info[0], info[1], + self.object_types[type].attrs['searchprio']) + +def setup(app): + app.add_domain(ConfigFileDomain) + diff --git a/phpmyadmin/doc/conf.py b/phpmyadmin/doc/conf.py new file mode 100644 index 000000000..372d84539 --- /dev/null +++ b/phpmyadmin/doc/conf.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +# +# phpMyAdmin documentation build configuration file, created by +# sphinx-quickstart on Wed Sep 26 14:04:48 2012. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "_ext"))) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['configext'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'phpMyAdmin' +copyright = u'2012 - 2013, The phpMyAdmin devel team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '4.0.4' +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build', 'html', 'doctrees'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'phpMyAdmindoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'phpMyAdmin.tex', u'phpMyAdmin Documentation', + u'The phpMyAdmin devel team', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'phpmyadmin', u'phpMyAdmin Documentation', + [u'The phpMyAdmin devel team'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'phpMyAdmin', u'phpMyAdmin Documentation', + u'The phpMyAdmin devel team', 'phpMyAdmin', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# -- Options for Epub output --------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'phpMyAdmin' +epub_author = u'The phpMyAdmin devel team' +epub_publisher = u'The phpMyAdmin devel team' +epub_copyright = copyright + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +#epub_exclude_files = [] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True diff --git a/phpmyadmin/doc/config.rst b/phpmyadmin/doc/config.rst new file mode 100644 index 000000000..2b9ced27b --- /dev/null +++ b/phpmyadmin/doc/config.rst @@ -0,0 +1,2776 @@ +.. index:: config.inc.php + +.. _config: + +Configuration +============= + +Almost all configurable data is placed in :file:`config.inc.php`. If this file +does not exist, please refer to the :ref:`setup` section to create one. This +file only needs to contain the parameters you want to change from their +corresponding default value in :file:`libraries/config.default.php`. + +The parameters which relate to design (like colors) are placed in +:file:`themes/themename/layout.inc.php`. You might also want to create +:file:`config.footer.inc.php` and :file:`config.header.inc.php` files to add +your site specific code to be included on start and end of each page. + +.. note:: + + Some distributions (eg. Debian or Ubuntu) store :file:`config.inc.php` in + ``/etc/phpmyadmin`` instead of within phpMyAdmin sources. + +.. warning:: + + :term:`Mac` users should note that if you are on a version before + :term:`Mac OS X`, PHP does not seem to + like :term:`Mac` end of lines character (``\r``). So + ensure you choose the option that allows to use the \*nix end of line + character (``\n``) in your text editor before saving a script you have + modified. + +Basic settings +-------------- + +.. config:option:: $cfg['PmaAbsoluteUri'] + + :type: string + :default: ``''`` + + Sets here the complete :term:`URL` (with full path) to your phpMyAdmin + installation's directory. E.g. + ``http://www.example.net/path_to_your_phpMyAdmin_directory/``. Note also + that the :term:`URL` on some web servers are case–sensitive. Don’t forget + the trailing slash at the end. + + Starting with version 2.3.0, it is advisable to try leaving this blank. In + most cases phpMyAdmin automatically detects the proper setting. Users of + port forwarding will need to set :config:option:`$cfg['PmaAbsoluteUri']` + (`more info `_). + + A good test is to browse a table, edit a row and save it. There should be + an error message if phpMyAdmin is having trouble auto–detecting the correct + value. If you get an error that this must be set or if the autodetect code + fails to detect your path, please post a bug report on our bug tracker so + we can improve the code. + + .. seealso:: :ref:`faq1_40` + +.. config:option:: $cfg['PmaNoRelation_DisableWarning'] + + :type: boolean + :default: false + + Starting with version 2.3.0 phpMyAdmin offers a lot of features to + work with master / foreign – tables (see :config:option:`$cfg['Servers'][$i]['pmadb']`). + + If you tried to set this + up and it does not work for you, have a look on the :guilabel:`Structure` page + of one database where you would like to use it. You will find a link + that will analyze why those features have been disabled. + + If you do not want to use those features set this variable to ``true`` to + stop this message from appearing. + +.. config:option:: $cfg['SuhosinDisableWarning'] + + :type: boolean + :default: false + + A warning is displayed on the main page if Suhosin is detected. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['McryptDisableWarning'] + + :type: boolean + :default: false + + Disable the default warning that is displayed if mcrypt is missing for + cookie authentication. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['ServerLibraryDifference_DisableWarning'] + + :type: boolean + :default: false + + A warning is displayed on the main page if there is a difference + between the MySQL library and server version. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['ReservedWordDisableWarning'] + + :type: boolean + :default: false + + This warning is displayed on the Structure page of a table if one or more + column names match with words which are MySQL reserved. + + If you want to turn off this warning, you can set it to ``true`` and + warning will not longer be displayed + +.. config:option:: $cfg['TranslationWarningThreshold'] + + :type: integer + :default: 80 + + Show warning about incomplete translations on certain threshold. + +Server connection settings +-------------------------- + +.. config:option:: $cfg['Servers'] + + :type: array + :default: one server array with settings listed bellow + + Since version 1.4.2, phpMyAdmin supports the administration of multiple + MySQL servers. Therefore, a :config:option:`$cfg['Servers']`-array has been + added which contains the login information for the different servers. The + first :config:option:`$cfg['Servers'][$i]['host']` contains the hostname of + the first server, the second :config:option:`$cfg['Servers'][$i]['host']` + the hostname of the second server, etc. In + :file:`libraries/config.default.php`, there is only one section for server + definition, however you can put as many as you need in + :file:`config.inc.php`, copy that block or needed parts (you don't have to + define all settings, just those you need to change). + + .. note:: + + The :config:option:`$cfg['Servers']` array starts with + $cfg['Servers'][1]. Do not use $cfg['Servers'][0]. If you want more + than one server, just copy following section (including $i + incrementation) serveral times. There is no need to define full server + array, just define values you need to change. + + +.. config:option:: $cfg['Servers'][$i]['host'] + + :type: string + :default: ``'localhost'`` + + The hostname or :term:`IP` address of your $i-th MySQL-server. E.g. + ``localhost``. + + Possible values are: + + * hostname, e.g., ``'localhost'`` or ``'mydb.example.org'`` + * IP address, e.g., ``'127.0.0.1'`` or ``'192.168.10.1'`` + * dot - ``'.'``, i.e., use named pipes on windows systems + * empty - ``''``, disables this server + +.. config:option:: $cfg['Servers'][$i]['port'] + + :type: string + :default: ``''`` + + The port-number of your $i-th MySQL-server. Default is 3306 (leave + blank). + + .. note:: + + If you use ``localhost`` as the hostname, MySQL ignores this port number + and connects with the socket, so if you want to connect to a port + different from the default port, use ``127.0.0.1`` or the real hostname + in :config:option:`$cfg['Servers'][$i]['host']`. + +.. config:option:: $cfg['Servers'][$i]['socket'] + + :type: string + :default: ``''`` + + The path to the socket to use. Leave blank for default. To determine + the correct socket, check your MySQL configuration or, using the + :command:`mysql` command–line client, issue the ``status`` command. Among the + resulting information displayed will be the socket used. + +.. config:option:: $cfg['Servers'][$i]['ssl'] + + :type: boolean + :default: false + + Whether to enable SSL for connection to MySQL server. + +.. config:option:: $cfg['Servers'][$i]['connect_type'] + + :type: string + :default: ``'tcp'`` + + What type connection to use with the MySQL server. Your options are + ``'socket'`` and ``'tcp'``. It defaults to tcp as that is nearly guaranteed + to be available on all MySQL servers, while sockets are not supported on + some platforms. To use the socket mode, your MySQL server must be on the + same machine as the Web server. + +.. config:option:: $cfg['Servers'][$i]['extension'] + + :type: string + :default: ``'mysqli'`` + + What php MySQL extension to use for the connection. Valid options are: + + ``mysql`` + The classic MySQL extension. + + ``mysqli`` + The improved MySQL extension. This extension became available with PHP + 5.0.0 and is the recommended way to connect to a server running MySQL + 4.1.x or newer. + +.. config:option:: $cfg['Servers'][$i]['compress'] + + :type: boolean + :default: false + + Whether to use a compressed protocol for the MySQL server connection + or not (experimental). + +.. _controlhost: +.. config:option:: $cfg['Servers'][$i]['controlhost'] + + :type: string + :default: ``''`` + + Permits to use an alternate host to hold the configuration storage + data. + +.. _controluser: +.. config:option:: $cfg['Servers'][$i]['controluser'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['Servers'][$i]['controlpass'] + + :type: string + :default: ``''`` + + This special account is used for 2 distinct purposes: to make possible all + relational features (see :config:option:`$cfg['Servers'][$i]['pmadb']`) and, + for a MySQL server running with ``--skip-show-database``, to enable a + multi-user installation (:term:`HTTP` or cookie + authentication mode). + + When using :term:`HTTP` or + cookie authentication modes (or 'config' authentication mode since phpMyAdmin + 2.2.1), you need to supply the details of a MySQL account that has ``SELECT`` + privilege on the *mysql.user (all columns except "Password")*, *mysql.db (all + columns)* and *mysql.tables\_priv (all columns except "Grantor" and + "Timestamp")* tables. This account is used to check what databases the user + will see at login. + + .. versionchanged:: 2.2.5 + those were called ``stduser`` and ``stdpass`` + + .. seealso:: :ref:`setup`, :ref:`authentication_modes` + +.. config:option:: $cfg['Servers'][$i]['auth_type'] + + :type: string + :default: ``'cookie'`` + + Whether config or cookie or :term:`HTTP` or signon authentication should be + used for this server. + + * 'config' authentication (``$auth_type = 'config'``) is the plain old + way: username and password are stored in :file:`config.inc.php`. + * 'cookie' authentication mode (``$auth_type = 'cookie'``) as + introduced in 2.2.3 allows you to log in as any valid MySQL user with + the help of cookies. Username and password are stored in cookies + during the session and password is deleted when it ends. This can also + allow you to log in in arbitrary server if :config:option:`$cfg['AllowArbitraryServer']` enabled. + * 'http' authentication (was + called 'advanced' in previous versions and can be written also as + 'http') (``$auth_type = 'http';'``) as introduced in 1.3.0 allows you to log in as any + valid MySQL user via HTTP-Auth. + * 'signon' authentication mode (``$auth_type = 'signon'``) as + introduced in 2.10.0 allows you to log in from prepared PHP session + data or using supplied PHP script. This is useful for implementing + single signon from another application. Sample way how to seed session + is in signon example: :file:`examples/signon.php`. There is also + alternative example using OpenID - :file:`examples/openid.php` and example + for scripts based solution - :file:`examples/signon-script.php`. You need + to configure :config:option:`$cfg['Servers'][$i]['SignonSession']` or + :config:option:`$cfg['Servers'][$i]['SignonScript']` and + :config:option:`$cfg['Servers'][$i]['SignonURL']` to use this authentication + method. + + .. seealso:: :ref:`authentication_modes` + +.. _servers_auth_http_realm: +.. config:option:: $cfg['Servers'][$i]['auth_http_realm'] + + :type: string + :default: ``''`` + + When using auth\_type = ``http``, this field allows to define a custom + :term:`HTTP` Basic Auth Realm which will be displayed to the user. If not + explicitly specified in your configuration, a string combined of + "phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or + :config:option:`$cfg['Servers'][$i]['host']` will be used. + +.. _servers_auth_swekey_config: +.. config:option:: $cfg['Servers'][$i]['auth_swekey_config'] + + :type: string + :default: ``''`` + + The name of the file containing :ref:`swekey` ids and login names for hardware + authentication. Leave empty to deactivate this feature. + +.. _servers_user: +.. config:option:: $cfg['Servers'][$i]['user'] + + :type: string + :default: ``'root'`` + +.. config:option:: $cfg['Servers'][$i]['password'] + + :type: string + :default: ``''`` + + When using :config:option:`$cfg['Servers'][$i]['auth_type']` set to + 'config', this is the user/password-pair which phpMyAdmin will use to + connect to the MySQL server. This user/password pair is not needed when + :term:`HTTP` or cookie authentication is used + and should be empty. + +.. _servers_nopassword: +.. config:option:: $cfg['Servers'][$i]['nopassword'] + + :type: boolean + :default: false + + Allow attempt to log in without password when a login with password + fails. This can be used together with http authentication, when + authentication is done some other way and phpMyAdmin gets user name + from auth and uses empty password for connecting to MySQL. Password + login is still tried first, but as fallback, no password method is + tried. + +.. _servers_only_db: +.. config:option:: $cfg['Servers'][$i]['only_db'] + + :type: string or array + :default: ``''`` + + If set to a (an array of) database name(s), only this (these) + database(s) will be shown to the user. Since phpMyAdmin 2.2.1, + this/these database(s) name(s) may contain MySQL wildcards characters + ("\_" and "%"): if you want to use literal instances of these + characters, escape them (I.E. use ``'my\_db'`` and not ``'my_db'``). + + This setting is an efficient way to lower the server load since the + latter does not need to send MySQL requests to build the available + database list. But **it does not replace the privileges rules of the + MySQL database server**. If set, it just means only these databases + will be displayed but **not that all other databases can't be used.** + + An example of using more that one database: + + .. code-block:: php + + $cfg['Servers'][$i]['only_db'] = array('db1', 'db2'); + + .. versionchanged:: 4.0.0 + Previous versions permitted to specify the display order of + the database names via this directive. + +.. config:option:: $cfg['Servers'][$i]['hide_db'] + + :type: string + :default: ``''`` + + Regular expression for hiding some databases from unprivileged users. + This only hides them from listing, but a user is still able to access + them (using, for example, the SQL query area). To limit access, use + the MySQL privilege system. For example, to hide all databases + starting with the letter "a", use + + .. code-block:: php + + $cfg['Servers'][$i]['hide_db'] = '^a'; + + and to hide both "db1" and "db2" use + + .. code-block:: php + + $cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$'; + + More information on regular expressions can be found in the `PCRE + pattern syntax + `_ portion + of the PHP reference manual. + +.. config:option:: $cfg['Servers'][$i]['verbose'] + + :type: string + :default: ``''`` + + Only useful when using phpMyAdmin with multiple server entries. If + set, this string will be displayed instead of the hostname in the + pull-down menu on the main page. This can be useful if you want to + show only certain databases on your system, for example. For HTTP + auth, all non-US-ASCII characters will be stripped. + +.. config:option:: $cfg['Servers'][$i]['pmadb'] + + :type: string + :default: ``''`` + + The name of the database containing the phpMyAdmin configuration + storage. + + See the :ref:`linked-tables` section in this document to see the benefits of + this feature, and for a quick way of creating this database and the needed + tables. + + If you are the only user of this phpMyAdmin installation, you can use your + current database to store those special tables; in this case, just put your + current database name in :config:option:`$cfg['Servers'][$i]['pmadb']`. For a + multi-user installation, set this parameter to the name of your central + database containing the phpMyAdmin configuration storage. + +.. _bookmark: +.. config:option:: $cfg['Servers'][$i]['bookmarktable'] + + :type: string + :default: ``''`` + + Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This + can be useful for queries you often run. To allow the usage of this + functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * enter the table name in :config:option:`$cfg['Servers'][$i]['bookmarktable']` + + +.. _relation: +.. config:option:: $cfg['Servers'][$i]['relation'] + + :type: string + :default: ``''`` + + Since release 2.2.4 you can describe, in a special 'relation' table, + which column is a key in another table (a foreign key). phpMyAdmin + currently uses this to + + * make clickable, when you browse the master table, the data values that + point to the foreign table; + * display in an optional tool-tip the "display column" when browsing the + master table, if you move the mouse to a column containing a foreign + key (use also the 'table\_info' table); (see :ref:`faqdisplay`) + * in edit/insert mode, display a drop-down list of possible foreign keys + (key value and "display column" are shown) (see :ref:`faq6_21`) + * display links on the table properties page, to check referential + integrity (display missing foreign keys) for each described key; + * in query-by-example, create automatic joins (see :ref:`faq6_6`) + * enable you to get a :term:`PDF` schema of + your database (also uses the table\_coords table). + + The keys can be numeric or character. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the relation table name in :config:option:`$cfg['Servers'][$i]['relation']` + * now as normal user open phpMyAdmin and for each one of your tables + where you want to use this feature, click :guilabel:`Structure/Relation view/` + and choose foreign columns. + + .. note:: + + In the current version, ``master_db`` must be the same as ``foreign_db``. + Those columns have been put in future development of the cross-db + relations. + +.. _table_info: +.. config:option:: $cfg['Servers'][$i]['table_info'] + + :type: string + :default: ``''`` + + Since release 2.3.0 you can describe, in a special 'table\_info' + table, which column is to be displayed as a tool-tip when moving the + cursor over the corresponding key. This configuration variable will + hold the name of this special table. To allow the usage of this + functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['table\_info']` (e.g. + ``pma__table_info``) + * then for each table where you want to use this feature, click + "Structure/Relation view/Choose column to display" to choose the + column. + + .. seealso:: :ref:`faqdisplay` + +.. _table_coords: +.. config:option:: $cfg['Servers'][$i]['table_coords'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['Servers'][$i]['pdf_pages'] + + :type: string + :default: ``''`` + + Since release 2.3.0 you can have phpMyAdmin create :term:`PDF` pages + showing the relations between your tables. To do this it needs two tables + "pdf\_pages" (storing information about the available :term:`PDF` pages) + and "table\_coords" (storing coordinates where each table will be placed on + a :term:`PDF` schema output). You must be using the "relation" feature. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the correct table names in + :config:option:`$cfg['Servers'][$i]['table\_coords']` and + :config:option:`$cfg['Servers'][$i]['pdf\_pages']` + + .. seealso:: :ref:`faqpdf`. + +.. _col_com: +.. config:option:: $cfg['Servers'][$i]['column_info'] + + :type: string + :default: ``''`` + + This part requires a content update! Since release 2.3.0 you can + store comments to describe each column for each table. These will then + be shown on the "printview". + + Starting with release 2.5.0, comments are consequently used on the table + property pages and table browse view, showing up as tool-tips above the + column name (properties page) or embedded within the header of table in + browse view. They can also be shown in a table dump. Please see the + relevant configuration directives later on. + + Also new in release 2.5.0 is a MIME- transformation system which is also + based on the following table structure. See :ref:`transformations` for + further information. To use the MIME- transformation system, your + column\_info table has to have the three new columns 'mimetype', + 'transformation', 'transformation\_options'. + + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['column\_info']` (e.g. + ``pma__column_info``) + * to update your PRE-2.5.0 Column\_comments Table use this: and + remember that the Variable in :file:`config.inc.php` has been renamed from + :config:option:`$cfg['Servers'][$i]['column\_comments']` to + :config:option:`$cfg['Servers'][$i]['column\_info']` + + .. code-block:: mysql + + ALTER TABLE `pma__column_comments` + ADD `mimetype` VARCHAR( 255 ) NOT NULL, + ADD `transformation` VARCHAR( 255 ) NOT NULL, + ADD `transformation_options` VARCHAR( 255 ) NOT NULL; + +.. _history: +.. config:option:: $cfg['Servers'][$i]['history'] + + :type: string + :default: ``''`` + + Since release 2.5.0 you can store your :term:`SQL` history, which means all + queries you entered manually into the phpMyAdmin interface. If you don't + want to use a table-based history, you can use the JavaScript-based + history. + + Using that, all your history items are deleted when closing the window. + Using :config:option:`$cfg['QueryHistoryMax']` you can specify an amount of + history items you want to have on hold. On every login, this list gets cut + to the maximum amount. + + The query history is only available if JavaScript is enabled in + your browser. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['history']` (e.g. + ``pma__history``) + +.. _recent: +.. config:option:: $cfg['Servers'][$i]['recent'] + + :type: string + :default: ``''`` + + Since release 3.5.0 you can show recently used tables in the + navigation panel. It helps you to jump across table directly, without + the need to select the database, and then select the table. Using + :config:option:`$cfg['NumRecentTables']` you can configure the maximum number + of recent tables shown. When you select a table from the list, it will jump to + the page specified in :config:option:`$cfg['NavigationTreeDefaultTabTable']`. + + + Without configuring the storage, you can still access the recently used tables, + but it will disappear after you logout. + + To allow the usage of this functionality persistently: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['recent']` (e.g. + ``pma__recent``) + +.. _table_uiprefs: +.. config:option:: $cfg['Servers'][$i]['table_uiprefs'] + + :type: string + :default: ``''`` + + Since release 3.5.0 phpMyAdmin can be configured to remember several + things (sorted column :config:option:`$cfg['RememberSorting']`, column order, + and column visibility from a database table) for browsing tables. Without + configuring the storage, these features still can be used, but the values will + disappear after you logout. + + To allow the usage of these functionality persistently: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['table\_uiprefs']` (e.g. + ``pma__table_uiprefs``) + + +.. _tracking: +.. config:option:: $cfg['Servers'][$i]['tracking'] + + :type: string + :default: ``''`` + + Since release 3.3.x a tracking mechanism is available. It helps you to + track every :term:`SQL` command which is + executed by phpMyAdmin. The mechanism supports logging of data + manipulation and data definition statements. After enabling it you can + create versions of tables. + + The creation of a version has two effects: + + * phpMyAdmin saves a snapshot of the table, including structure and + indexes. + * phpMyAdmin logs all commands which change the structure and/or data of + the table and links these commands with the version number. + + Of course you can view the tracked changes. On the :guilabel:`Tracking` + page a complete report is available for every version. For the report you + can use filters, for example you can get a list of statements within a date + range. When you want to filter usernames you can enter \* for all names or + you enter a list of names separated by ','. In addition you can export the + (filtered) report to a file or to a temporary database. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['tracking']` (e.g. + ``pma__tracking``) + + +.. _tracking2: +.. config:option:: $cfg['Servers'][$i]['tracking_version_auto_create'] + + :type: boolean + :default: false + + Whether the tracking mechanism creates versions for tables and views + automatically. + + If this is set to true and you create a table or view with + + * CREATE TABLE ... + * CREATE VIEW ... + + and no version exists for it, the mechanism will create a version for + you automatically. + +.. _tracking3: +.. config:option:: $cfg['Servers'][$i]['tracking_default_statements'] + + :type: string + :default: ``'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE'`` + + Defines the list of statements the auto-creation uses for new + versions. + +.. _tracking4: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_view'] + + :type: boolean + :default: true + + Whether a DROP VIEW IF EXISTS statement will be added as first line to + the log when creating a view. + +.. _tracking5: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_table'] + + :type: boolean + :default: true + + Whether a DROP TABLE IF EXISTS statement will be added as first line + to the log when creating a table. + +.. _tracking6: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_database'] + + :type: boolean + :default: true + + Whether a DROP DATABASE IF EXISTS statement will be added as first + line to the log when creating a database. + +.. _userconfig: +.. config:option:: $cfg['Servers'][$i]['userconfig'] + + :type: string + :default: ``''`` + + Since release 3.4.x phpMyAdmin allows users to set most preferences by + themselves and store them in the database. + + If you don't allow for storing preferences in + :config:option:`$cfg['Servers'][$i]['pmadb']`, 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. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['userconfig']` + + + +.. _designer_coords: +.. config:option:: $cfg['Servers'][$i]['designer_coords'] + + :type: string + :default: ``''`` + + Since release 2.10.0 a Designer interface is available; it permits to + visually manage the relations. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['designer\_coords']` + (e.g. ``pma__designer_coords``) + + + +.. config:option:: $cfg['Servers'][$i]['MaxTableUiprefs'] + + :type: integer + :default: 100 + + Maximum number of rows saved in + :config:option:`$cfg['Servers'][$i]['table_uiprefs']` table. + + When tables are dropped or renamed, + :config:option:`$cfg['Servers'][$i]['table_uiprefs']` may contain invalid data + (referring to tables which no longer exist). We only keep this number of newest + rows in :config:option:`$cfg['Servers'][$i]['table_uiprefs']` and automatically + delete older rows. + +.. config:option:: $cfg['Servers'][$i]['AllowRoot'] + + :type: boolean + :default: true + + Whether to allow root access. This is just a shortcut for the + :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` below. + +.. config:option:: $cfg['Servers'][$i]['AllowNoPassword'] + + :type: boolean + :default: false + + Whether to allow logins without a password. The default value of + ``false`` for this parameter prevents unintended access to a MySQL + server with was left with an empty password for root or on which an + anonymous (blank) user is defined. + +.. _servers_allowdeny_order: +.. config:option:: $cfg['Servers'][$i]['AllowDeny']['order'] + + :type: string + :default: ``''`` + + If your rule order is empty, then :term:`IP` + authorization is disabled. + + If your rule order is set to + ``'deny,allow'`` then the system applies all deny rules followed by + allow rules. Access is allowed by default. Any client which does not + match a Deny command or does match an Allow command will be allowed + access to the server. + + If your rule order is set to ``'allow,deny'`` + then the system applies all allow rules followed by deny rules. Access + is denied by default. Any client which does not match an Allow + directive or does match a Deny directive will be denied access to the + server. + + If your rule order is set to ``'explicit'``, authorization is + performed in a similar fashion to rule order 'deny,allow', with the + added restriction that your host/username combination **must** be + listed in the *allow* rules, and not listed in the *deny* rules. This + is the **most** secure means of using Allow/Deny rules, and was + available in Apache by specifying allow and deny rules without setting + any order. + + Please also see :config:option:`$cfg['TrustedProxies']` for + detecting IP address behind proxies. + +.. _servers_allowdeny_rules: +.. config:option:: $cfg['Servers'][$i]['AllowDeny']['rules'] + + :type: array of strings + :default: array() + + The general format for the rules is as such: + + .. code-block:: none + + <'allow' | 'deny'> [from] + + If you wish to match all users, it is possible to use a ``'%'`` as a + wildcard in the *username* field. + + There are a few shortcuts you can + use in the *ipmask* field as well (please note that those containing + SERVER\_ADDRESS might not be available on all webservers): + + .. code-block:: none + + + 'all' -> 0.0.0.0/0 + 'localhost' -> 127.0.0.1/8 + 'localnetA' -> SERVER_ADDRESS/8 + 'localnetB' -> SERVER_ADDRESS/16 + 'localnetC' -> SERVER_ADDRESS/24 + + Having an empty rule list is equivalent to either using ``'allow % + from all'`` if your rule order is set to ``'deny,allow'`` or ``'deny % + from all'`` if your rule order is set to ``'allow,deny'`` or + ``'explicit'``. + + For the :term:`IP address` matching + system, the following work: + + * ``xxx.xxx.xxx.xxx`` (an exact :term:`IP address`) + * ``xxx.xxx.xxx.[yyy-zzz]`` (an :term:`IP address` range) + * ``xxx.xxx.xxx.xxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IP` addresses) + + But the following does not work: + + * ``xxx.xxx.xxx.xx[yyy-zzz]`` (partial :term:`IP` address range) + + For :term:`IPv6` addresses, the following work: + + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx`` (an exact :term:`IPv6` address) + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]`` (an :term:`IPv6` address range) + * ``xxxx:xxxx:xxxx:xxxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IPv6` addresses) + + But the following does not work: + + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]`` (partial :term:`IPv6` address range) + +.. config:option:: $cfg['Servers'][$i]['DisableIS'] + + :type: boolean + :default: true + + Disable using ``INFORMATION_SCHEMA`` to retrieve information (use + ``SHOW`` commands instead), because of speed issues when many + databases are present. Currently used in some parts of the code, more + to come. + +.. config:option:: $cfg['Servers'][$i]['ShowDatabasesCommand'] + + :type: string + :default: ``'SHOW DATABASES'`` + + On a server with a huge number of databases, the default ``SHOW DATABASES`` + command used to fetch the name of available databases will probably be too + slow, so it can be replaced by faster commands. You can use ``#user#`` + string will be replaced by current user. + + When using ``false``, it will disable fetching databases from the server, + only databases in :config:option:`$cfg['Servers'][$i]['only_db']` will be + displayed. + + Examples: + + * ``'SHOW DATABASES'`` + * ``"SHOW DATABASES LIKE '#user#\_%'"`` + * ``'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'`` + * ``'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'`` + * ``false`` + +.. config:option:: $cfg['Servers'][$i]['SignonScript'] + + :type: string + :default: ``''`` + + Name of PHP script to be sourced and executed to obtain login + credentials. This is alternative approach to session based single + signon. The script needs to provide function + ``get_login_credentials`` which returns list of username and + password, accepting single parameter of existing username (can be + empty). See :file:`examples/signon-script.php` for an example. + +.. config:option:: $cfg['Servers'][$i]['SignonSession'] + + :type: string + :default: ``''`` + + Name of session which will be used for signon authentication method. + You should use something different than ``phpMyAdmin``, because this + is session which phpMyAdmin uses internally. Takes effect only if + :config:option:`$cfg['Servers'][$i]['SignonScript']` is not configured. + +.. config:option:: $cfg['Servers'][$i]['SignonURL'] + + :type: string + :default: ``''`` + + :term:`URL` where user will be redirected + to log in for signon authentication method. Should be absolute + including protocol. + +.. config:option:: $cfg['Servers'][$i]['LogoutURL'] + + :type: string + :default: ``''`` + + :term:`URL` where user will be redirected + after logout (doesn't affect config authentication method). Should be + absolute including protocol. + +.. config:option:: $cfg['Servers'][$i]['StatusCacheDatabases'] + + :type: array of strings + :default: array() + + Enables caching of ``TABLE STATUS`` outputs for specific databases on + this server (in some cases ``TABLE STATUS`` can be very slow, so you + may want to cache it). APC is used (if the PHP extension is available, + if not, this setting is ignored silently). You have to provide + :config:option:`$cfg['Servers'][$i]['StatusCacheLifetime']`. + + Takes effect only if :config:option:`$cfg['Servers'][$i]['DisableIS']` is + ``true``. + +.. config:option:: $cfg['Servers'][$i]['StatusCacheLifetime'] + + :type: integer + :default: 0 + + Lifetime in seconds of the ``TABLE STATUS`` cache if + :config:option:`$cfg['Servers'][$i]['StatusCacheDatabases']` is used. + +Generic settings +---------------- + +.. config:option:: $cfg['ServerDefault'] + + :type: integer + :default: 1 + + If you have more than one server configured, you can set + :config:option:`$cfg['ServerDefault']` to any one of them to autoconnect to that + server when phpMyAdmin is started, or set it to 0 to be given a list + of servers without logging in. + + If you have only one server configured, + :config:option:`$cfg['ServerDefault']` MUST be set to that server. + +.. config:option:: $cfg['VersionCheck'] + + :type: boolean + :default: true + + Enables check for latest versions using javascript on main phpMyAdmin + page. + + .. note:: + + This setting can be adjusted by your vendor. + +.. config:option:: $cfg['MaxDbList'] + + :type: integer + :default: 100 + + The maximum number of database names to be displayed in the main panel's + database list. + +.. config:option:: $cfg['MaxNavigationItems'] + + :type: integer + :default: 25 + + The number of items that can be displayed on each page of the + navigation tree. + +.. config:option:: $cfg['MaxTableList'] + + :type: integer + :default: 250 + + The maximum number of table names to be displayed in the main panel's + list (except on the Export page). This limit is also enforced in the + navigation panel when in Light mode. + +.. config:option:: $cfg['ShowHint'] + + :type: boolean + :default: true + + Whether or not to show hints (for example, hints when hovering over + table headers). + +.. config:option:: $cfg['MaxCharactersInDisplayedSQL'] + + :type: integer + :default: 1000 + + The maximum number of characters when a :term:`SQL` query is displayed. The + default limit of 1000 should be correct to avoid the display of tons of + hexadecimal codes that represent BLOBs, but some users have real + :term:`SQL` queries that are longer than 1000 characters. Also, if a + query's length exceeds this limit, this query is not saved in the history. + +.. config:option:: $cfg['PersistentConnections'] + + :type: boolean + :default: false + + Whether `persistent connections `_ should be used or not. Works with + following extensions: + + * mysql (`mysql\_pconnect `_), + * mysqli (requires PHP 5.3.0 or newer, `more information + `_). + +.. config:option:: $cfg['ForceSSL'] + + :type: boolean + :default: false + + Whether to force using https while accessing phpMyAdmin. + +.. config:option:: $cfg['ExecTimeLimit'] + + :type: integer [number of seconds] + :default: 300 + + Set the number of seconds a script is allowed to run. If seconds is + set to zero, no time limit is imposed. This setting is used while + importing/exporting dump files but has + no effect when PHP is running in safe mode. + +.. config:option:: $cfg['SessionSavePath'] + + :type: string + :default: ``''`` + + Path for storing session data (`session\_save\_path PHP parameter + `_). + +.. config:option:: $cfg['MemoryLimit'] + + :type: string [number of bytes] + :default: ``'0'`` + + Set the number of bytes a script is allowed to allocate. If set to + zero, no limit is imposed. + + This setting is used while importing/exporting dump files and at some other + places in phpMyAdmin so you definitely don't want to put here a too low + value. It has no effect when PHP is running in safe mode. + + You can also use any string as in :file:`php.ini`, eg. '16M'. Ensure you + don't omit the suffix (16 means 16 bytes!) + +.. config:option:: $cfg['SkipLockedTables'] + + :type: boolean + :default: false + + Mark used tables and make it possible to show databases with locked + tables (since MySQL 3.23.30). + +.. config:option:: $cfg['ShowSQL'] + + :type: boolean + :default: true + + Defines whether :term:`SQL` queries + generated by phpMyAdmin should be displayed or not. + +.. config:option:: $cfg['RetainQueryBox'] + + :type: boolean + :default: false + + Defines whether the :term:`SQL` query box + should be kept displayed after its submission. + +.. config:option:: $cfg['CodemirrorEnable'] + + :type: boolean + :default: true + + Defines whether to use a Javascript code editor for SQL query boxes. + CodeMirror provides syntax highlighting and line numbers. However, + middle-clicking for pasting the clipboard contents in some Linux + distributions (such as Ubuntu) is not supported by all browsers. + +.. config:option:: $cfg['AllowUserDropDatabase'] + + :type: boolean + :default: false + + Defines whether normal users (non-administrator) are allowed to delete + their own database or not. If set as false, the link :guilabel:`Drop + Database` will not be shown, and even a ``DROP DATABASE mydatabase`` will + be rejected. Quite practical for :term:`ISP` 's with many customers. + + .. note:: + + This limitation of :term:`SQL` queries is not + as strict as when using MySQL privileges. This is due to nature of + :term:`SQL` queries which might be quite + complicated. So this choice should be viewed as help to avoid accidental + dropping rather than strict privilege limitation. + +.. config:option:: $cfg['Confirm'] + + :type: boolean + :default: true + + Whether a warning ("Are your really sure...") should be displayed when + you're about to lose data. + +.. config:option:: $cfg['UseDbSearch'] + + :type: boolean + :default: true + + Define whether the "search string inside database" is enabled or not. + +.. config:option:: $cfg['IgnoreMultiSubmitErrors'] + + :type: boolean + :default: false + + Define whether phpMyAdmin will continue executing a multi-query + statement if one of the queries fails. Default is to abort execution. + +Cookie authentication options +----------------------------- + +.. config:option:: $cfg['blowfish_secret'] + + :type: string + :default: ``''`` + + The "cookie" auth\_type uses blowfish algorithm to encrypt the + password. If you are using the "cookie" auth\_type, enter here a + random passphrase of your choice. It will be used internally by the + blowfish algorithm: you won’t be prompted for this passphrase. There + is no maximum length for this secret. + + .. versionchanged:: 3.1.0 + Since version 3.1.0 phpMyAdmin can generate this on the fly, but it + makes a bit weaker security as this generated secret is stored in + session and furthermore it makes impossible to recall user name from + cookie. + +.. config:option:: $cfg['LoginCookieRecall'] + + :type: boolean + :default: true + + Define whether the previous login should be recalled or not in cookie + authentication mode. + + This is automatically disabled if you do not have + configured :config:option:`$cfg['blowfish_secret']`. + +.. config:option:: $cfg['LoginCookieValidity'] + + :type: integer [number of seconds] + :default: 1440 + + Define how long a login cookie is valid. Please note that php + configuration option `session.gc\_maxlifetime + `_ might limit session validity and if the session is lost, + the login cookie is also invalidated. So it is a good idea to set + ``session.gc_maxlifetime`` at least to the same value of + :config:option:`$cfg['LoginCookieValidity']`. + +.. config:option:: $cfg['LoginCookieStore'] + + :type: integer [number of seconds] + :default: 0 + + Define how long login cookie should be stored in browser. Default 0 + means that it will be kept for existing session. This is recommended + for not trusted environments. + +.. config:option:: $cfg['LoginCookieDeleteAll'] + + :type: boolean + :default: true + + If enabled (default), logout deletes cookies for all servers, + otherwise only for current one. Setting this to false makes it easy to + forget to log out from other server, when you are using more of them. + +.. _AllowArbitraryServer: +.. config:option:: $cfg['AllowArbitraryServer'] + + :type: boolean + :default: false + + If enabled, allows you to log in to arbitrary servers using cookie + authentication. + + .. note:: + + Please use this carefully, as this may allow users access to MySQL servers + behind the firewall where your :term:`HTTP` + server is placed. + +Navigation panel setup +---------------------- + +.. config:option:: $cfg['NavigationTreeEnableGrouping'] + + :type: boolean + :default: true + + Defines whether to group the databases based on a common prefix + in their name :config:option:`$cfg['NavigationTreeDbSeparator']`. + +.. config:option:: $cfg['NavigationTreeDbSeparator'] + + :type: string or array + :default: ``'_'`` + + The string used to separate the parts of the database name when + showing them in a tree. Alternatively you can specify more strings in + an array and all of them will be used as a separator. + +.. config:option:: $cfg['NavigationTreeTableSeparator'] + + :type: string or array + :default: ``'__'`` + + Defines a string to be used to nest table spaces. This means if you have + tables like ``first__second__third`` this will be shown as a three-level + hierarchy like: first > second > third. If set to false or empty, the + feature is disabled. NOTE: You should not use this separator at the + beginning or end of a table name or multiple times after another without + any other characters in between. + +.. config:option:: $cfg['NavigationTreeTableLevel'] + + :type: integer + :default: 1 + + Defines how many sublevels should be displayed when splitting up + tables by the above separator. + +.. config:option:: $cfg['NumRecentTables'] + + :type: integer + :default: 10 + + The maximum number of recently used tables shown in the navigation + panel. Set this to 0 (zero) to disable the listing of recent tables. + +.. config:option:: $cfg['ShowTooltip'] + + :type: boolean + :default: true + + Defines whether to display item comments as tooltips in navigation + panel or not. + +.. config:option:: $cfg['NavigationDisplayLogo'] + + :type: boolean + :default: true + + Defines whether or not to display the phpMyAdmin logo at the top of + the navigation panel. + +.. config:option:: $cfg['NavigationLogoLink'] + + :type: string + :default: ``'index.php'`` + + Enter :term:`URL` where logo in the + navigation panel will point to. For use especially with self made + theme which changes this. + +.. config:option:: $cfg['NavigationLogoLinkWindow'] + + :type: string + :default: ``'main'`` + + Whether to open the linked page in the main window (``main``) or in a + new one (``new``). Note: use ``new`` if you are linking to + ``phpmyadmin.net``. + +.. config:option:: $cfg['NavigationTreeDisplayItemFilterMinimum'] + + :type: integer + :default: 30 + + Defines the minimum number of items (tables, views, routines and + events) to display a JavaScript filter box above the list of items in + the navigation tree. + + To disable the filter completely some high number can be used (e.g. 9999) + +.. config:option:: $cfg['NavigationTreeDisplayDbFilterMinimum'] + + :type: integer + :default: 30 + + Defines the minimum number of databases to display a JavaScript filter + box above the list of databases in the navigation tree. + + To disable the filter completely some high number can be used + (e.g. 9999) + +.. config:option:: $cfg['NavigationDisplayServers'] + + :type: boolean + :default: true + + Defines whether or not to display a server choice at the top of the + navigation panel. + +.. config:option:: $cfg['DisplayServersList'] + + :type: boolean + :default: false + + Defines whether to display this server choice as links instead of in a + drop-down. + +.. config:option:: $cfg['NavigationTreeDefaultTabTable'] + + :type: string + :default: ``'tbl_structure.php'`` + + Defines the tab displayed by default when clicking the small icon next + to each table name in the navigation panel. Possible values: + + * ``tbl_structure.php`` + * ``tbl_sql.php`` + * ``tbl_select.php`` + * ``tbl_change.php`` + * ``sql.php`` + +Main panel +---------- + +.. config:option:: $cfg['ShowStats'] + + :type: boolean + :default: true + + Defines whether or not to display space usage and statistics about + databases and tables. Note that statistics requires at least MySQL + 3.23.3 and that, at this date, MySQL doesn't return such information + for Berkeley DB tables. + +.. config:option:: $cfg['ShowServerInfo'] + + :type: boolean + :default: true + + Defines whether to display detailed server information on main page. + You can additionally hide more information by using + :config:option:`$cfg['Servers'][$i]['verbose']`. + +.. config:option:: $cfg['ShowPhpInfo'] + + :type: boolean + :default: false + +.. config:option:: $cfg['ShowChgPassword'] + + :type: boolean + :default: true + +.. config:option:: $cfg['ShowCreateDb'] + + :type: boolean + :default: true + + Defines whether to display the :guilabel:`PHP information` and + :guilabel:`Change password` links and form for creating database or not at + the starting main (right) frame. This setting does not check MySQL commands + entered directly. + + Please note that to block the usage of ``phpinfo()`` in scripts, you have to + put this in your :file:`php.ini`: + + .. code-block:: ini + + disable_functions = phpinfo() + + Also note that enabling the :guilabel:`Change password` link has no effect + with config authentication mode: because of the hard coded password value + in the configuration file, end users can't be allowed to change their + passwords. + +Database structure +------------------ + +.. config:option:: $cfg['ShowDbStructureCreation'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a + "Creation" column that displays when each table was created. + +.. config:option:: $cfg['ShowDbStructureLastUpdate'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a "Last + update" column that displays when each table was last updated. + +.. config:option:: $cfg['ShowDbStructureLastCheck'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a "Last + check" column that displays when each table was last checked. + +.. config:option:: $cfg['HideStructureActions'] + + :type: boolean + :default: true + + Defines whether the table structure actions are hidden under a "More" + drop-down. + +Browse mode +----------- + +.. config:option:: $cfg['NavigationBarIconic'] + + :type: string + :default: true + + Defines whether navigation bar buttons contain text or symbols only. A + value of true displays icons, false displays text and 'both' displays + both icons and text. + +.. config:option:: $cfg['ShowAll'] + + :type: boolean + :default: false + + Defines whether a user should be displayed a "Show all" button in + browse mode or not in all cases. By default it is shown only on small + tables (less than 5 × :config:option:`$cfg['MaxRows']` rows) to avoid + performance issues while getting too many rows. + +.. config:option:: $cfg['MaxRows'] + + :type: integer + :default: 30 + + Number of rows displayed when browsing a result set and no LIMIT + clause is used. If the result set contains more rows, "Previous" and + "Next" links will be shown. + +.. config:option:: $cfg['Order'] + + :type: string + :default: ``'SMART'`` + + Defines whether columns are displayed in ascending (``ASC``) order, in + descending (``DESC``) order or in a "smart" (``SMART``) order - I.E. + descending order for columns of type TIME, DATE, DATETIME and + TIMESTAMP, ascending order else- by default. + +.. config:option:: $cfg['DisplayBinaryAsHex'] + + :type: boolean + :default: true + + Defines whether the "Show binary contents as HEX" browse option is + ticked by default. + +.. config:option:: $cfg['GridEditing'] + + :type: string + :default: ``'double-click'`` + + Defines which action (``double-click`` or ``click``) triggers grid + editing. Can be deactived with the ``disabled`` value. + +.. config:option:: $cfg['SaveCellsAtOnce'] + + :type: boolean + :default: false + + Defines whether or not to save all edited cells at once for grid + editing. + +Editing mode +------------ + +.. config:option:: $cfg['ProtectBinary'] + + :type: boolean or string + :default: ``'blob'`` + + Defines whether ``BLOB`` or ``BINARY`` columns are protected from + editing when browsing a table's content. Valid values are: + + * ``false`` to allow editing of all columns; + * ``'blob'`` to allow editing of all columns except ``BLOBS``; + * ``'noblob'`` to disallow editing of all columns except ``BLOBS`` (the + opposite of ``'blob'``); + * ``'all'`` to disallow editing of all ``BINARY`` or ``BLOB`` columns. + +.. config:option:: $cfg['ShowFunctionFields'] + + :type: boolean + :default: true + + Defines whether or not MySQL functions fields should be initially + displayed in edit/insert mode. Since version 2.10, the user can toggle + this setting from the interface. + +.. config:option:: $cfg['ShowFieldTypesInDataEditView'] + + :type: boolean + :default: true + + Defines whether or not type fields should be initially displayed in + edit/insert mode. The user can toggle this setting from the interface. + +.. config:option:: $cfg['InsertRows'] + + :type: integer + :default: 2 + + Defines the maximum number of concurrent entries for the Insert page. + +.. config:option:: $cfg['ForeignKeyMaxLimit'] + + :type: integer + :default: 100 + + If there are fewer items than this in the set of foreign keys, then a + drop-down box of foreign keys is presented, in the style described by + the :config:option:`$cfg['ForeignKeyDropdownOrder']` setting. + +.. config:option:: $cfg['ForeignKeyDropdownOrder'] + + :type: array + :default: array('content-id', 'id-content') + + For the foreign key drop-down fields, there are several methods of + display, offering both the key and value data. The contents of the + array should be one or both of the following strings: ``content-id``, + ``id-content``. + +Export and import settings +-------------------------- + +.. config:option:: $cfg['ZipDump'] + + :type: boolean + :default: true + +.. config:option:: $cfg['GZipDump'] + + :type: boolean + :default: true + +.. config:option:: $cfg['BZipDump'] + + :type: boolean + :default: true + + Defines whether to allow the use of zip/GZip/BZip2 compression when + creating a dump file + +.. config:option:: $cfg['CompressOnFly'] + + :type: boolean + :default: true + + Defines whether to allow on the fly compression for GZip/BZip2 + compressed exports. This doesn't affect smaller dumps and allows users + to create larger dumps that won't otherwise fit in memory due to php + memory limit. Produced files contain more GZip/BZip2 headers, but all + normal programs handle this correctly. + +.. config:option:: $cfg['Export'] + + :type: array + :default: array(...) + + In this array are defined default parameters for export, names of + items are similar to texts seen on export page, so you can easily + identify what they mean. + +.. config:option:: $cfg['Export']['method'] + + :type: string + :default: ``'quick'`` + + Defines how the export form is displayed when it loads. Valid values + are: + + * ``quick`` to display the minimum number of options to configure + * ``custom`` to display every available option to configure + * ``custom-no-form`` same as ``custom`` but does not display the option + of using quick export + + + +.. config:option:: $cfg['Import'] + + :type: array + :default: array(...) + + In this array are defined default parameters for import, names of + items are similar to texts seen on import page, so you can easily + identify what they mean. + + +Tabs display settings +--------------------- + +.. config:option:: $cfg['PropertiesIconic'] + + :type: string + :default: ``'both'`` + + If set to ``true``, will display icons instead of text for db and table + properties links (like :guilabel:`Browse`, :guilabel:`Select`, + :guilabel:`Insert`, ...) and for the menu tabs. Can be set to ``'both'`` + if you want icons AND text. When set to ``false``, will only show text. + +.. config:option:: $cfg['PropertiesNumColumns'] + + :type: integer + :default: 1 + + How many columns will be utilized to display the tables on the database + property view? When setting this to a value larger than 1, the type of the + database will be omitted for more display space. + +.. config:option:: $cfg['DefaultTabServer'] + + :type: string + :default: ``'index.php'`` + + Defines the tab displayed by default on server view. Possible values: + + * ``main.php`` (recommended for multi-user setups) + * ``server_databases.php``, + * ``server_status.php`` + * ``server_variables.php`` + * ``server_privileges.php`` + +.. config:option:: $cfg['DefaultTabDatabase'] + + :type: string + :default: ``'db_structure.php'`` + + Defines the tab displayed by default on database view. Possible + values: + + * ``db_structure.php`` + * ``db_sql.php`` + * ``db_search.php``. + +.. config:option:: $cfg['DefaultTabTable'] + + :type: string + :default: ``'sql.php'`` + + Defines the tab displayed by default on table view. Possible values: + + * ``tbl_structure.php`` + * ``tbl_sql.php`` + * ``tbl_select.php`` + * ``tbl_change.php`` + * ``sql.php`` + +Documentation +------------- + +.. config:option:: $cfg['MySQLManualBase'] + + :type: string + :default: ``'http://dev.mysql.com/doc/refman'`` + + If set to an :term:`URL` which points to + the MySQL documentation (type depends on + :config:option:`$cfg['MySQLManualType']`), appropriate help links are + generated. + + See `MySQL Documentation page `_ for more + information about MySQL manuals and their types. + +.. config:option:: $cfg['MySQLManualType'] + + :type: string + :default: ``'viewable'`` + + Type of MySQL documentation: + + * viewable - "viewable online", current one used on MySQL website + * searchable - "Searchable, with user comments" + * chapters - "HTML, one page per chapter" + * big - "HTML, all on one page" + * none - do not show documentation links + +Languages +--------- + +.. config:option:: $cfg['DefaultLang'] + + :type: string + :default: ``'en'`` + + Defines the default language to use, if not browser-defined or user- + defined. The corresponding language file needs to be in + locale/*code*/LC\_MESSAGES/phpmyadmin.mo. + +.. config:option:: $cfg['DefaultConnectionCollation'] + + :type: string + :default: ``'utf8_general_ci'`` + + Defines the default connection collation to use, if not user-defined. + See the `MySQL documentation `_ for list of possible values. This setting is + ignored when connected to Drizzle server. + +.. config:option:: $cfg['Lang'] + + :type: string + :default: not set + + Force language to use. The corresponding language file needs to be in + locale/*code*/LC\_MESSAGES/phpmyadmin.mo. + +.. config:option:: $cfg['FilterLanguages'] + + :type: string + :default: ``''`` + + Limit list of available languages to those matching the given regular + expression. For example if you want only Czech and English, you should + set filter to ``'^(cs|en)'``. + +.. config:option:: $cfg['RecodingEngine'] + + :type: string + :default: ``'auto'`` + + You can select here which functions will be used for character set + conversion. Possible values are: + + * auto - automatically use available one (first is tested iconv, then + recode) + * iconv - use iconv or libiconv functions + * recode - use recode\_string function + * none - disable encoding conversion + + Enabled charset conversion activates a pull-down menu in the Export + and Import pages, to choose the character set when exporting a file. + The default value in this menu comes from + :config:option:`$cfg['Export']['charset']` and :config:option:`$cfg['Import']['charset']`. + +.. config:option:: $cfg['IconvExtraParams'] + + :type: string + :default: ``'//TRANSLIT'`` + + Specify some parameters for iconv used in charset conversion. See + `iconv documentation `_ for details. By default + ``//TRANSLIT`` is used, so that invalid characters will be + transliterated. + +.. config:option:: $cfg['AvailableCharsets'] + + :type: array + :default: array(..._ + + Available character sets for MySQL conversion. You can add your own + (any of supported by recode/iconv) or remove these which you don't + use. Character sets will be shown in same order as here listed, so if + you frequently use some of these move them to the top. + +Web server settings +------------------- + +.. config:option:: $cfg['OBGzip'] + + :type: string/boolean + :default: ``'auto'`` + + Defines whether to use GZip output buffering for increased speed in + :term:`HTTP` transfers. Set to + true/false for enabling/disabling. When set to 'auto' (string), + phpMyAdmin tries to enable output buffering and will automatically + disable it if your browser has some problems with buffering. IE6 with + a certain patch is known to cause data corruption when having enabled + buffering. + +.. config:option:: $cfg['TrustedProxies'] + + :type: array + :default: array() + + Lists proxies and HTTP headers which are trusted for + :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`. This list is by + default empty, you need to fill in some trusted proxy servers if you + want to use rules for IP addresses behind proxy. + + 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: + + .. code-block:: php + + $cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR'); + + The :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` directive uses the + client's IP address as usual. + +.. config:option:: $cfg['GD2Available'] + + :type: string + :default: ``'auto'`` + + Specifies whether GD >= 2 is available. If yes it can be used for MIME + transformations. Possible values are: + + * auto - automatically detect + * yes - GD 2 functions can be used + * no - GD 2 function cannot be used + +.. config:option:: $cfg['CheckConfigurationPermissions'] + + :type: boolean + :default: true + + We normally check the permissions on the configuration file to ensure + it's not world writable. However, phpMyAdmin could be installed on a + NTFS filesystem mounted on a non-Windows server, in which case the + permissions seems wrong but in fact cannot be detected. In this case a + sysadmin would set this parameter to ``false``. + +.. config:option:: $cfg['LinkLengthLimit'] + + :type: integer + :default: 1000 + + Limit for length of :term:`URL` in links. When length would be above this + limit, it is replaced by form with button. This is required as some web + servers (:term:`IIS`) have problems with long :term:`URL` . + +.. config:option:: $cfg['CSPAllow'] + + :type: string + :default: ``''`` + + Additional string to include in allowed script sources in Content Security + Policy header. + + This can be useful when you want to include some external javascript files + in :file:`config.footer.inc.php` or :file:`config.header.inc.php`, which + would be normally not allowed by Content Security Policy. + +.. config:option:: $cfg['DisableMultiTableMaintenance'] + + :type: boolean + :default: false + + In the database Structure page, it's possible to mark some tables then + choose an operation like optimizing for many tables. This can slow + down a server; therefore, setting this to ``true`` prevents this kind + of multiple maintenance operation. + +Theme settings +-------------- + +.. config:option:: $cfg['NaviWidth'] + + :type: integer + :default: + + Navigation panel width in pixels. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['NaviBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['MainBackground'] + + :type: string [CSS color for background] + :default: + + The background styles used for both the frames. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['NaviPointerBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['NaviPointerColor'] + + :type: string [CSS color] + :default: + + The style used for the pointer in the navi frame. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['Border'] + + :type: integer + :default: + + The size of a table's border. See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['ThBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['ThColor'] + + :type: string [CSS color] + :default: + + The style used for table headers. See + :file:`themes/themename/layout.inc.php`. + +.. _cfg_BgcolorOne: +.. config:option:: $cfg['BgOne'] + + :type: string [CSS color] + :default: + + The color (HTML) #1 for table rows. See + :file:`themes/themename/layout.inc.php`. + +.. _cfg_BgcolorTwo: +.. config:option:: $cfg['BgTwo'] + + :type: string [CSS color] + :default: + + The color (HTML) #2 for table rows. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['BrowsePointerBackground'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowsePointerColor'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowseMarkerBackground'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowseMarkerColor'] + + :type: string [CSS color] + :default: + + The colors (HTML) uses for the pointer and the marker in browse mode. + The former feature highlights the row over which your mouse is passing + and the latter lets you visually mark/unmark rows by clicking on the + corresponding checkbox. Highlighting / marking a column is done by + hovering over / clicking the column's header (outside of the text). + See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['FontFamily'] + + :type: string + :default: + + You put here a valid CSS font family value, for example ``arial, sans- + serif``. See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['FontFamilyFixed'] + + :type: string + :default: + + You put here a valid CSS font family value, for example ``monospace``. + This one is used in textarea. See :file:`themes/themename/layout.inc.php`. + +Design customization +-------------------- + +.. config:option:: $cfg['NavigationTreePointerEnable'] + + :type: boolean + :default: true + + A value of ``true`` activates the navi pointer. + +.. config:option:: $cfg['BrowsePointerEnable'] + + :type: boolean + :default: true + + Whether to activate the browse pointer or not. + +.. config:option:: $cfg['BrowseMarkerEnable'] + + :type: boolean + :default: true + + Whether to activate the browse marker or not. + +.. config:option:: $cfg['LimitChars'] + + :type: integer + :default: 50 + + Maximum number of characters shown in any non-numeric field on browse + view. Can be turned off by a toggle button on the browse page. + +.. config:option:: $cfg['RowActionLinks'] + + :type: string + :default: ``'left'`` + + Defines the place where table row links (Edit, Copy, Delete) would be + put when tables contents are displayed (you may have them displayed at + the left side, right side, both sides or nowhere). "left" and "right" + are parsed as "top" and "bottom" with vertical display mode. + +.. config:option:: $cfg['DefaultDisplay'] + + :type: string + :default: ``'horizonta'`` + + There are 3 display modes: horizontal, horizontalflipped and vertical. + Define which one is displayed by default. The first mode displays each + row on a horizontal line, the second rotates the headers by 90 + degrees, so you can use descriptive headers even though columns only + contain small values and still print them out. The vertical mode sorts + each row on a vertical lineup. + +.. config:option:: $cfg['RememberSorting'] + + :type: boolean + :default: true + + If enabled, remember the sorting of each table when browsing them. + +.. config:option:: $cfg['HeaderFlipType'] + + :type: string + :default: ``'auto'`` + + The HeaderFlipType can be set to 'auto', 'css' or 'fake'. When using + 'css' the rotation of the header for horizontalflipped is done via + CSS. The CSS transformation currently works only in Internet + Explorer.If set to 'fake' PHP does the transformation for you, but of + course this does not look as good as CSS. The 'auto' option enables + CSS transformation when browser supports it and use PHP based one + otherwise. + +.. config:option:: $cfg['ShowBrowseComments'] + + :type: boolean + :default: true + +.. config:option:: $cfg['ShowPropertyComments'] + + :type: boolean + :default: true + + By setting the corresponding variable to ``true`` you can enable the + display of column comments in Browse or Property display. In browse + mode, the comments are shown inside the header. In property mode, + comments are displayed using a CSS-formatted dashed-line below the + name of the column. The comment is shown as a tool-tip for that + column. + +Text fields +----------- + +.. config:option:: $cfg['CharEditing'] + + :type: string + :default: ``'input'`` + + Defines which type of editing controls should be used for CHAR and + VARCHAR columns. Possible values are: + + * input - this allows to limit size of text to size of columns in MySQL, + but has problems with newlines in columns + * textarea - no problems with newlines in columns, but also no length + limitations + +.. config:option:: $cfg['MinSizeForInputField'] + + :type: integer + :default: 4 + + Defines the minimum size for input fields generated for CHAR and + VARCHAR columns. + +.. config:option:: $cfg['MaxSizeForInputField'] + + :type: integer + :default: 60 + + Defines the maximum size for input fields generated for CHAR and + VARCHAR columns. + +.. config:option:: $cfg['TextareaCols'] + + :type: integer + :default: 40 + +.. config:option:: $cfg['TextareaRows'] + + :type: integer + :default: 15 + +.. config:option:: $cfg['CharTextareaCols'] + + :type: integer + :default: 40 + +.. config:option:: $cfg['CharTextareaRows'] + + :type: integer + :default: 2 + + Number of columns and rows for the textareas. This value will be + emphasized (\*2) for :term:`SQL` query + textareas and (\*1.25) for :term:`SQL` + textareas inside the query window. + + The Char\* values are used for CHAR + and VARCHAR editing (if configured via :config:option:`$cfg['CharEditing']`). + +.. config:option:: $cfg['LongtextDoubleTextarea'] + + :type: boolean + :default: true + + Defines whether textarea for LONGTEXT columns should have double size. + +.. config:option:: $cfg['TextareaAutoSelect'] + + :type: boolean + :default: false + + Defines if the whole textarea of the query box will be selected on + click. + + +SQL query box settings +---------------------- + +.. config:option:: $cfg['SQLQuery']['Edit'] + + :type: boolean + :default: true + + Whether to display an edit link to change a query in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['Explain'] + + :type: boolean + :default: true + + Whether to display a link to explain a SELECT query in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['ShowAsPHP'] + + :type: boolean + :default: true + + Whether to display a link to wrap a query in PHP code in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['Validate'] + + :type: boolean + :default: false + + Whether to display a link to validate a query in any SQL Query box. + + .. seealso:: :config:option:`$cfg['SQLValidator']` + +.. config:option:: $cfg['SQLQuery']['Refresh'] + + :type: boolean + :default: true + + Whether to display a link to refresh a query in any SQL Query box. + +Web server upload/save/import directories +----------------------------------------- + +.. config:option:: $cfg['UploadDir'] + + :type: string + :default: ``''`` + + The name of the directory where :term:`SQL` files have been uploaded by + other means than phpMyAdmin (for example, ftp). Those files are available + under a drop-down box when you click the database or table name, then the + Import tab. + + If + you want different directory for each user, %u will be replaced with + username. + + Please note that the file names must have the suffix ".sql" + (or ".sql.bz2" or ".sql.gz" if support for compressed formats is + enabled). + + This feature is useful when your file is too big to be + uploaded via :term:`HTTP`, or when file + uploads are disabled in PHP. + + .. note:: + + If PHP is running in safe mode, this directory must be owned by the same + user as the owner of the phpMyAdmin scripts. See also :ref:`faq1_16` for + alternatives. + +.. config:option:: $cfg['SaveDir'] + + :type: string + :default: ``''`` + + The name of the directory where dumps can be saved. + + If you want different directory for each user, %u will be replaced with + username. + + Please note that the directory must exist and has to be writable for + the user running webserver. + + .. note:: + + If PHP is running in safe mode, this directory must be owned by the same + user as the owner of the phpMyAdmin scripts. + +.. config:option:: $cfg['TempDir'] + + :type: string + :default: ``''`` + + The name of the directory where temporary files can be stored. + + This is needed for importing ESRI Shapefiles, see :ref:`faq6_30` and to + work around limitations of ``open_basedir`` for uploaded files, see + :ref:`faq1_11`. + + If the directory where phpMyAdmin is installed is + subject to an ``open_basedir`` restriction, you need to create a + temporary directory in some directory accessible by the web server. + However for security reasons, this directory should be outside the + tree published by webserver. If you cannot avoid having this directory + published by webserver, place at least an empty :file:`index.html` file + there, so that directory listing is not possible. + + This directory should have as strict permissions as possible as the only + user required to access this directory is the one who runs the webserver. + If you have root privileges, simply make this user owner of this directory + and make it accessible only by it: + + .. code-block:: sh + + + chown www-data:www-data tmp + chmod 700 tmp + + If you cannot change owner of the directory, you can achieve a similar + setup using :term:`ACL`: + + .. code-block:: sh + + chmod 700 tmp + setfacl -m "g:www-data:rwx" tmp + setfacl -d -m "g:www-data:rwx" tmp + + If neither of above works for you, you can still make the directory + :command:`chmod 777`, but it might impose risk of other users on system + reading and writing data in this directory. + +Various display setting +----------------------- + +.. config:option:: $cfg['ShowDisplayDirection'] + + :type: boolean + :default: false + + Defines whether or not type display direction option is shown when + browsing a table. + +.. config:option:: $cfg['RepeatCells'] + + :type: integer + :default: 100 + + Repeat the headers every X cells, or 0 to deactivate. + +.. config:option:: $cfg['EditInWindow'] + + :type: boolean + :default: true + +.. config:option:: $cfg['QueryWindowWidth'] + + :type: integer + :default: 550 + +.. config:option:: $cfg['QueryWindowHeight'] + + :type: integer + :default: 310 + +.. config:option:: $cfg['QueryHistoryDB'] + + :type: boolean + :default: false + +.. config:option:: $cfg['QueryWindowDefTab'] + + :type: string + :default: ``'sql'`` + +.. config:option:: $cfg['QueryHistoryMax'] + + :type: integer + :default: 25 + + All those variables affect the query window feature. A :term:`SQL` link or + icon is always displayed in the navigation panel. If JavaScript is enabled + in your browser, a click on this opens a distinct query window, which is a + direct interface to enter :term:`SQL` queries. Otherwise, the right panel + changes to display a query box. + + The size of this query window can be customized with + :config:option:`$cfg['QueryWindowWidth']` and + :config:option:`$cfg['QueryWindowHeight']` - both integers for the size in + pixels. Note that normally, those parameters will be modified in + :file:`layout.inc.php`` for the theme you are using. + + If :config:option:`$cfg['EditInWindow']` is set to true, a click on [Edit] + from the results page (in the :guilabel:`Showing Rows` section) opens the + query window and puts the current query inside it. If set to false, + clicking on the link puts the :term:`SQL` query + in the right panel's query box. + + If :config:option:`$cfg['QueryHistoryDB']` is set to ``true``, all your + Queries are logged to a table, which has to be created by you (see + :config:option:`$cfg['Servers'][$i]['history']`). If set to false, all your + queries will be appended to the form, but only as long as your window is + opened they remain saved. + + When using the JavaScript based query window, it will always get updated + when you click on a new table/db to browse and will focus if you click on + :guilabel:`Edit SQL` after using a query. You can suppress updating the + query window by checking the box :guilabel:`Do not overwrite this query + from outside the window` below the query textarea. Then you can browse + tables/databases in the background without losing the contents of the + textarea, so this is especially useful when composing a query with tables + you first have to look in. The checkbox will get automatically checked + whenever you change the contents of the textarea. Please uncheck the button + whenever you definitely want the query window to get updated even though + you have made alterations. + + If :config:option:`$cfg['QueryHistoryDB']` is set to ``true`` you can + specify the amount of saved history items using + :config:option:`$cfg['QueryHistoryMax']`. + + The query window also has a custom tabbed look to group the features. + Using the variable :config:option:`$cfg['QueryWindowDefTab']` you can + specify the default tab to be used when opening the query window. It can be + set to either ``sql``, ``files``, ``history`` or ``full``. + +.. config:option:: $cfg['BrowseMIME'] + + :type: boolean + :default: true + + Enable :ref:`transformations`. + +.. config:option:: $cfg['MaxExactCount'] + + :type: integer + :default: 0 + + For InnoDB tables, determines for how large tables phpMyAdmin should + get the exact row count using ``SELECT COUNT``. If the approximate row + count as returned by ``SHOW TABLE STATUS`` is smaller than this value, + ``SELECT COUNT`` will be used, otherwise the approximate count will be + used. + +.. config:option:: $cfg['MaxExactCountViews'] + + :type: integer + :default: 0 + + For VIEWs, since obtaining the exact count could have an impact on + performance, this value is the maximum to be displayed, using a + ``SELECT COUNT ... LIMIT``. Setting this to 0 bypasses any row + counting. + +.. config:option:: $cfg['NaturalOrder'] + + :type: boolean + :default: true + + Sorts database and table names according to natural order (for + example, t1, t2, t10). Currently implemented in the navigation panel + and in Database view, for the table list. + +.. config:option:: $cfg['InitialSlidersState'] + + :type: string + :default: ``'closed'`` + + If set to ``'closed'``, the visual sliders are initially in a closed + state. A value of ``'open'`` does the reverse. To completely disable + all visual sliders, use ``'disabled'``. + +.. config:option:: $cfg['UserprefsDisallow'] + + :type: array + :default: array() + + Contains names of configuration options (keys in ``$cfg`` array) that + users can't set through user preferences. For possible values, refer + to :file:`libraries/config/user_preferences.forms.php`. + +.. config:option:: $cfg['UserprefsDeveloperTab'] + + :type: boolean + :default: false + + Activates in the user preferences a tab containing options for + developers of phpMyAdmin. + +Page titles +----------- + +.. config:option:: $cfg['TitleTable'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleDatabase'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleServer'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleDefault'] + + :type: string + :default: ``'@HTTP_HOST@ | @PHPMYADMIN@'`` + + Allows you to specify window's title bar. You can use :ref:`faq6_27`. + +Theme manager settings +---------------------- + +.. config:option:: $cfg['ThemePath'] + + :type: string + :default: ``'./themes'`` + + If theme manager is active, use this as the path of the subdirectory + containing all the themes. + +.. config:option:: $cfg['ThemeManager'] + + :type: boolean + :default: true + + Enables user-selectable themes. See :ref:`faqthemes`. + +.. config:option:: $cfg['ThemeDefault'] + + :type: string + :default: ``'pmahomme'`` + + The default theme (a subdirectory under :config:option:`$cfg['ThemePath']`). + +.. config:option:: $cfg['ThemePerServer'] + + :type: boolean + :default: false + + Whether to allow different theme for each server. + +Default queries +--------------- + +.. config:option:: $cfg['DefaultQueryTable'] + + :type: string + :default: ``'SELECT * FROM @TABLE@ WHERE 1'`` + +.. config:option:: $cfg['DefaultQueryDatabase'] + + :type: string + :default: ``''`` + + Default queries that will be displayed in query boxes when user didn't + specify any. You can use standard :ref:`faq6_27`. + +SQL parser settings +------------------- + +.. config:option:: $cfg['SQP']['fmtType'] + + :type: string + :default: ``'html'`` + + The main use of the new :term:`SQL` Parser + is to pretty-print :term:`SQL` queries. By + default we use HTML to format the query, but you can disable this by + setting this variable to ``'none'``. + + Available options: + + * ``'html'`` + * ``'none'`` + +.. _cfg_SQP: +.. config:option:: $cfg['SQP']['fmtInd'] + + :type: float + :default: ``'1'`` + +.. config:option:: $cfg['SQP']['fmtIndUnit'] + + :type: string + :default: ``'em'`` + + For the pretty-printing of :term:`SQL` queries, + under some cases the part of a query inside a bracket is indented. By + changing :config:option:`$cfg['SQP']['fmtInd']` you can change the amount + of this indent. + + Related in purpose is :config:option:`$cfg['SQP']['fmtIndUnit']` which + specifies the units of the indent amount that you specified. This is used + via stylesheets. + + You can use any HTML unit, for example: + + * ``'em'`` + * ``'ex'`` + * ``'pt'`` + * ``'px'`` + +.. config:option:: $cfg['SQP']['fmtColor'] + + :type: array of string tuples + :default: + + This array is used to define the colours for each type of element of + the pretty-printed :term:`SQL` queries. + The tuple format is *class* => [*HTML colour code* | *empty string*] + + + If you specify an empty string for the color of a class, it is ignored + in creating the stylesheet. You should not alter the class names, only + the colour strings. + + **Class name key:** + + comment + Applies to all comment sub-classes + comment\_mysql + Comments as ``"#...\n"`` + comment\_ansi + Comments as ``"-- ...\n"`` + comment\_c + Comments as ``"/*...*/"`` + digit + Applies to all digit sub-classes + digit\_hex + Hexadecimal numbers + digit\_integer + Integer numbers + digit\_float + Floating point numbers + punct + Applies to all punctuation sub-classes + punct\_bracket\_open\_round + Opening brackets ``"("`` + punct\_bracket\_close\_round + Closing brackets ``")"`` + punct\_listsep + List item Separator ``","`` + punct\_qualifier + Table/Column Qualifier ``"."`` + punct\_queryend + End of query marker ``";"`` + alpha + Applies to all alphabetic classes + alpha\_columnType + Identifiers matching a column type + alpha\_columnAttrib + Identifiers matching a database/table/column attribute + alpha\_functionName + Identifiers matching a MySQL function name + alpha\_reservedWord + Identifiers matching any other reserved word + alpha\_variable + Identifiers matching a :term:`SQL` variable ``"@foo"`` + alpha\_identifier + All other identifiers + quote + Applies to all quotation mark classes + quote\_double + Double quotes ``"`` + quote\_single + Single quotes ``'`` + quote\_backtick + Backtick quotes ````` + +SQL validator settings +---------------------- + +.. config:option:: $cfg['SQLValidator'] + + :type: array + :default: array(...) + + + +.. config:option:: $cfg['SQLValidator']['use'] + + :type: boolean + :default: false + + phpMyAdmin now supports use of the `Mimer SQL Validator + `_ service, as originally + published on `Slashdot + `_. For + help in setting up your system to use the service, see the + :ref:`faqsqlvalidator`. + +.. config:option:: $cfg['SQLValidator']['username'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['SQLValidator']['password'] + + :type: string + :default: ``''`` + + The SOAP service allows you to log in with ``anonymous`` and any password, + so we use those by default. Instead, if you have an account with them, you + can put your login details here, and it will be used in place of the + anonymous login. + +MySQL settings +-------------- + +.. config:option:: $cfg['DefaultFunctions'] + + :type: array + :default: array(...) + + Functions selected by default when inserting/changing row, Functions + are defined for meta types as (FUNC\_NUMBER, FUNC\_DATE, FUNC\_CHAR, + FUNC\_SPATIAL, FUNC\_UUID) and for ``first_timestamp``, which is used + for first timestamp column in table. + + +Developer +--------- + +.. warning:: + + These settings might have huge effect on performance or security. + +.. config:option:: $cfg['DBG'] + + :type: array + :default: array(...) + +.. config:option:: $cfg['DBG']['sql'] + + :type: boolean + :default: false + + Enable logging queries and execution times to be + displayed in the bottom of main page (right frame). + +.. config:option:: $cfg['Error_Handler']['display'] + + :type: boolean + :default: false + + Whether to display errors from PHP or not. + +.. config:option:: $cfg['Error_Handler']['gather'] + + :type: boolean + :default: false + + Whether to gather errors from PHP or not. + diff --git a/phpmyadmin/doc/copyright.rst b/phpmyadmin/doc/copyright.rst new file mode 100644 index 000000000..cfcb86394 --- /dev/null +++ b/phpmyadmin/doc/copyright.rst @@ -0,0 +1,30 @@ +.. _copyright: + +Copyright +========= + +.. code-block:: none + + Copyright (C) 1998-2000 Tobias Ratschiller + Copyright (C) 2001-2013 Marc Delisle + Olivier Müller + Robin Johnson + Alexander M. Turek + Michal Čihař + Garvin Hicking + Michael Keck + Sebastian Mendel + [check credits for more details] + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2, as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see `http://www.gnu.org/licenses/ +`_. diff --git a/phpmyadmin/doc/credits.rst b/phpmyadmin/doc/credits.rst new file mode 100644 index 000000000..21f5e1892 --- /dev/null +++ b/phpmyadmin/doc/credits.rst @@ -0,0 +1,597 @@ +.. _credits: + +Credits +======= + + +Credits, in chronological order ++++++++++++++++++++++++++++++++ + +* Tobias Ratschiller + + * creator of the phpmyadmin project + + * maintainer from 1998 to summer 2000 + +* Marc Delisle + + * multi-language version in December 1998 + + * various fixes and improvements + + * :term:`SQL` analyser (most of it) + + * current project maintainer + +* Olivier Müller + + * started SourceForge phpMyAdmin project in March 2001 + + * sync'ed different existing CVS trees with new features and bugfixes + + * multi-language improvements, dynamic language selection + + * many bugfixes and improvements + +* Loïc Chapeaux + + * rewrote and optimized javascript, DHTML and DOM stuff + + * rewrote the scripts so they fit the :term:`PEAR` coding standards and + generate XHTML1.0 and CSS2 compliant codes + + * improved the language detection system + + * many bugfixes and improvements + +* Robin Johnson + + * database maintenance controls + + * table type code + + * Host authentication :term:`IP` Allow/Deny + + * DB-based configuration (Not completed) + + * :term:`SQL` parser and pretty-printer + + * :term:`SQL` validator + + * many bugfixes and improvements + +* Armel Fauveau + + * bookmarks feature + + * multiple dump feature + + * gzip dump feature + + * zip dump feature + +* Geert Lund + + * various fixes + + * moderator of the phpMyAdmin former users forum at phpwizard.net + +* Korakot Chaovavanich + + * "insert as new row" feature + +* Pete Kelly + + * rewrote and fix dump code + + * bugfixes + +* Steve Alberty + + * rewrote dump code for PHP4 + + * mySQL table statistics + + * bugfixes + +* Benjamin Gandon + + * main author of the version 2.1.0.1 + + * bugfixes + +* Alexander M. Turek + + * MySQL 4.0 / 4.1 / 5.0 compatibility + + * abstract database interface (PMA\_DBI) with MySQLi support + + * privileges administration + + * :term:`XML` exports + + * various features and fixes + + * German language file updates + +* Mike Beck + + * automatic joins in QBE + + * links column in printview + + * Relation view + +* Michal Čihař + + * enhanced index creation/display feature + + * feature to use a different charset for HTML than for MySQL + + * improvements of export feature + + * various features and fixes + + * Czech language file updates + +* Christophe Gesché from the "MySQL Form Generator for PHPMyAdmin" + (http://sf.net/projects/phpmysqlformgen/) + + * suggested the patch for multiple table printviews + +* Garvin Hicking + + * built the patch for vertical display of table rows + + * built the Javascript based Query window + :term:`SQL` history + + * Improvement of column/db comments + + * (MIME)-Transformations for columns + + * Use custom alias names for Databases in left frame + + * hierarchical/nested table display + + * :term:`PDF`-scratchboard for WYSIWYG- + distribution of :term:`PDF` relations + + * new icon sets + + * vertical display of column properties page + + * some bugfixes, features, support, German language additions + +* Yukihiro Kawada + + * japanese kanji encoding conversion feature + +* Piotr Roszatycki and Dan Wilson + + * the Cookie authentication mode + +* Axel Sander + + * table relation-links feature + +* Maxime Delorme + + * :term:`PDF` schema output, thanks also to + Olivier Plathey for the "FPDF" library (see ), Steven + Wittens for the "UFPDF" library (see ) and + Nicola Asuni for the "TCPDF" library (see ). + +* Olof Edlund + + * :term:`SQL` validator server + +* Ivan R. Lanin + + * phpMyAdmin logo (until June 2004) + +* Mike Cochrane + + * blowfish library from the Horde project (withdrawn in release 4.0) + +* Marcel Tschopp + + * mysqli support + + * many bugfixes and improvements + +* Nicola Asuni (Tecnick.com) + + * TCPDF library (`http://www.tcpdf.org `_) + +* Michael Keck + + * redesign for 2.6.0 + + * phpMyAdmin sailboat logo (June 2004) + +* Mathias Landhäußer + + * Representation at conferences + +* Sebastian Mendel + + * interface improvements + + * various bugfixes + +* Ivan A Kirillov + + * new relations Designer + +* Raj Kissu Rajandran (Google Summer of Code 2008) + + * BLOBstreaming support (withdrawn in release 4.0) + +* Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011) + + * improved setup script + + * user preferences + + * Drizzle support + +* Derek Schaefer (Google Summer of Code 2009) + + * Improved the import system + +* Alexander Rutkowski (Google Summer of Code 2009) + + * Tracking mechanism + +* Zahra Naeem (Google Summer of Code 2009) + + * Synchronization feature (removed in release 4.0) + +* Tomáš Srnka (Google Summer of Code 2009) + + * Replication support + +* Muhammad Adnan (Google Summer of Code 2010) + + * Relation schema export to multiple formats + +* Lori Lee (Google Summer of Code 2010) + + * User interface improvements + + * ENUM/SET editor + + * Simplified interface for export/import + +* Ninad Pundalik (Google Summer of Code 2010) + + * AJAXifying the interface + +* Martynas Mickevičius (Google Summer of Code 2010) + + * Charts + +* Barrie Leslie + + * BLOBstreaming support with PBMS PHP extension (withdrawn in release + 4.0) + +* Ankit Gupta (Google Summer of Code 2010) + + * Visual query builder + +* Madhura Jayaratne (Google Summer of Code 2011) + + * OpenGIS support + +* Ammar Yasir (Google Summer of Code 2011) + + * Zoom search + +* Aris Feryanto (Google Summer of Code 2011) + + * Browse-mode improvements + +* Thilanka Kaushalya (Google Summer of Code 2011) + + * AJAXification + +* Tyron Madlener (Google Summer of Code 2011) + + * Query statistics and charts for the status page + +* Zarubin Stas (Google Summer of Code 2011) + + * Automated testing + +* Rouslan Placella (Google Summer of Code 2011 and 2012) + + * Improved support for Stored Routines, Triggers and Events + + * Italian translation updates + + * Removal of frames, new navigation + +* Dieter Adriaenssens + + * Various bugfixes + + * Dutch translation updates + +* Alex Marin (Google Summer of Code 2012) + + * New plugins and properties system + +* Thilina Buddika Abeyrathna (Google Summer of Code 2012) + + * Refactoring + +* Atul Pratap Singh (Google Summer of Code 2012) + + * Refactoring + +* Chanaka Indrajith (Google Summer of Code 2012) + + * Refactoring + +* Yasitha Pandithawatta (Google Summer of Code 2012) + + * Automated testing + +* Jim Wigginton (phpseclib.sourceforge.net) + + * phpseclib + +And also to the following people who have contributed minor changes, +enhancements, bugfixes or support for a new language since version +2.1.0: + +Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita, +Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats +Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger, +Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg, +Andreas Pauley, Bernard M. Piller, Laurent Haas, "Sakamoto", Yuval +Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun, +Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V., +Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay, +Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael +Winningham, Vilius Zigmantas, "Manuzhai". + + +Translators ++++++++++++ + +Following people have contributed to translation of phpMyAdmin: + +* Arabic + + * Abdullah Al-Saedi + +* Bulgarian + + * stoyanster + +* Catalan + + * Xavier Navarro + +* Czech + + * Michal Čihař + +* Danish + + * opensource + * Jørgen Thomsen + +* German + + * mrbendig + * torsten.funck + * Sven Strickroth + * typo3 + * Jo Michael + +* Greek + + * Panagiotis Papazoglou + +* English (United Kingdom) + + * Robert Readman + +* Spanish + + * Matías Bellone + +* French + + * Marc Delisle + +* Hindi + + * u4663530 + * rsedwardian + +* Hungarian + + * gergo314 + +* Italian + + * Rouslan Placella + +* Japanese + + * Yuichiro + +* Lithuanian + + * Kęstutis + +* Norwegian Bokmål + + * Sven-Erik Andersen + +* Dutch + + * Dieter Adriaenssens + * Herman van Rink + +* Polish + + * Stanisław Krukowski + * Marcin Kozioł + +* Portuguese + + * JoaoTMDias + +* Portuguese (Brazil) + + * wiltave + * emerson4br + +* Romanian + + * alexukf + +* Russian + + * Victor Volkov + +* Sinhala + + * Madhura Jayaratne + +* Slovak + + * Martin Lacina + +* Slovenian + + * Domen + +* Swedish + + * stefan + +* Tamil + + * ysajeepan + +* Telugu + + * veeven + +* Thai + + * kanitchet + +* Turkish + + * Burak Yavuz + +* Uighur + + * gheni + +* Ukrainian + + * typim + * oleg-ilnytskyi + +* Urdu + + * Mehbooob Khan + +* Simplified Chinese + + * shanyan baishui + +* Traditional Chinese + + * star + +Documentation translators ++++++++++++++++++++++++++ + +Following people have contributed to translation of phpMyAdmin documentation: + +* Czech + + * Michal Čihař + +* Greek + + * Panagiotis Papazoglou + +* English (United Kingdom) + + * Robert Readman + +* French + + * Cédric Corazza + +* Japanese + + * Yuichiro Takahashi + +* Polish + + * Stanisław Krukowski + +* Portuguese (Brazil) + + * mjaning + +* Slovenian + + * Domen + +Original Credits of Version 2.1.0 ++++++++++++++++++++++++++++++++++ + +This work is based on Peter Kuppelwieser's MySQL-Webadmin. It was his +idea to create a web-based interface to MySQL using PHP3. Although I +have not used any of his source-code, there are some concepts I've +borrowed from him. phpMyAdmin was created because Peter told me he +wasn't going to further develop his (great) tool. + +Thanks go to + +* Amalesh Kempf who contributed the + code for the check when dropping a table or database. He also + suggested that you should be able to specify the primary key on + tbl\_create.php3. To version 1.1.1 he contributed the ldi\_\*.php3-set + (Import text-files) as well as a bug-report. Plus many smaller + improvements. +* Jan Legenhausen : He made many of the changes that + were introduced in 1.3.0 (including quite significant ones like the + authentication). For 1.4.1 he enhanced the table-dump feature. Plus + bug-fixes and help. +* Marc Delisle made phpMyAdmin + language-independent by outsourcing the strings to a separate file. He + also contributed the French translation. +* Alexandr Bravo who contributed + tbl\_select.php3, a feature to display only some columns from a table. +* Chris Jackson added support for MySQL functions + in tbl\_change.php3. He also added the "Query by Example" feature in + 2.0. +* Dave Walton added support for multiple + servers and is a regular contributor for bug-fixes. +* Gabriel Ash contributed the random access + features for 2.0.6. + +The following people have contributed minor changes, enhancements, +bugfixes or support for a new language: + +Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas +Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel +Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein, +Jannis Hermanns, G. Wieggers. + +And thanks to everyone else who sent me email with suggestions, bug- +reports and or just some feedback. + diff --git a/phpmyadmin/doc/developers.rst b/phpmyadmin/doc/developers.rst new file mode 100644 index 000000000..557452769 --- /dev/null +++ b/phpmyadmin/doc/developers.rst @@ -0,0 +1,12 @@ +.. _developers: + +Developers Information +====================== + +phpMyAdmin is Open Source, so you're invited to contribute to it. Many +great features have been written by other people and you too can help +to make phpMyAdmin a useful tool. + +You can check out all the possibilities to contribute in the +`contribute section on our website +`_. \ No newline at end of file diff --git a/phpmyadmin/doc/doctrees/config.doctree b/phpmyadmin/doc/doctrees/config.doctree new file mode 100644 index 000000000..98b1ab1a6 Binary files /dev/null and b/phpmyadmin/doc/doctrees/config.doctree differ diff --git a/phpmyadmin/doc/doctrees/copyright.doctree b/phpmyadmin/doc/doctrees/copyright.doctree new file mode 100644 index 000000000..26a63963b Binary files /dev/null and b/phpmyadmin/doc/doctrees/copyright.doctree differ diff --git a/phpmyadmin/doc/doctrees/credits.doctree b/phpmyadmin/doc/doctrees/credits.doctree new file mode 100644 index 000000000..9cb3aa4e7 Binary files /dev/null and b/phpmyadmin/doc/doctrees/credits.doctree differ diff --git a/phpmyadmin/doc/doctrees/developers.doctree b/phpmyadmin/doc/doctrees/developers.doctree new file mode 100644 index 000000000..de460981f Binary files /dev/null and b/phpmyadmin/doc/doctrees/developers.doctree differ diff --git a/phpmyadmin/doc/doctrees/environment.pickle b/phpmyadmin/doc/doctrees/environment.pickle new file mode 100644 index 000000000..170f0783c Binary files /dev/null and b/phpmyadmin/doc/doctrees/environment.pickle differ diff --git a/phpmyadmin/doc/doctrees/faq.doctree b/phpmyadmin/doc/doctrees/faq.doctree new file mode 100644 index 000000000..115a6f91c Binary files /dev/null and b/phpmyadmin/doc/doctrees/faq.doctree differ diff --git a/phpmyadmin/doc/doctrees/glossary.doctree b/phpmyadmin/doc/doctrees/glossary.doctree new file mode 100644 index 000000000..55feceba1 Binary files /dev/null and b/phpmyadmin/doc/doctrees/glossary.doctree differ diff --git a/phpmyadmin/doc/doctrees/index.doctree b/phpmyadmin/doc/doctrees/index.doctree new file mode 100644 index 000000000..9ffbf04aa Binary files /dev/null and b/phpmyadmin/doc/doctrees/index.doctree differ diff --git a/phpmyadmin/doc/doctrees/intro.doctree b/phpmyadmin/doc/doctrees/intro.doctree new file mode 100644 index 000000000..43e694b1f Binary files /dev/null and b/phpmyadmin/doc/doctrees/intro.doctree differ diff --git a/phpmyadmin/doc/doctrees/other.doctree b/phpmyadmin/doc/doctrees/other.doctree new file mode 100644 index 000000000..335834ff9 Binary files /dev/null and b/phpmyadmin/doc/doctrees/other.doctree differ diff --git a/phpmyadmin/doc/doctrees/privileges.doctree b/phpmyadmin/doc/doctrees/privileges.doctree new file mode 100644 index 000000000..3fb07662e Binary files /dev/null and b/phpmyadmin/doc/doctrees/privileges.doctree differ diff --git a/phpmyadmin/doc/doctrees/require.doctree b/phpmyadmin/doc/doctrees/require.doctree new file mode 100644 index 000000000..77571f799 Binary files /dev/null and b/phpmyadmin/doc/doctrees/require.doctree differ diff --git a/phpmyadmin/doc/doctrees/setup.doctree b/phpmyadmin/doc/doctrees/setup.doctree new file mode 100644 index 000000000..4a56db92f Binary files /dev/null and b/phpmyadmin/doc/doctrees/setup.doctree differ diff --git a/phpmyadmin/doc/doctrees/transformations.doctree b/phpmyadmin/doc/doctrees/transformations.doctree new file mode 100644 index 000000000..c38243235 Binary files /dev/null and b/phpmyadmin/doc/doctrees/transformations.doctree differ diff --git a/phpmyadmin/doc/doctrees/user.doctree b/phpmyadmin/doc/doctrees/user.doctree new file mode 100644 index 000000000..d29bc1652 Binary files /dev/null and b/phpmyadmin/doc/doctrees/user.doctree differ diff --git a/phpmyadmin/doc/doctrees/vendors.doctree b/phpmyadmin/doc/doctrees/vendors.doctree new file mode 100644 index 000000000..551c30c34 Binary files /dev/null and b/phpmyadmin/doc/doctrees/vendors.doctree differ diff --git a/phpmyadmin/doc/faq.rst b/phpmyadmin/doc/faq.rst new file mode 100644 index 000000000..c77f42866 --- /dev/null +++ b/phpmyadmin/doc/faq.rst @@ -0,0 +1,2001 @@ +.. _faq: + +FAQ - Frequently Asked Questions +================================ + +Please have a look at our `Link section +`_ on the official +phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and +or interface. + +.. _faqserver: + +Server +++++++ + +.. _faq1_1: + +1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in your +:file:`config.inc.php` file and the ``zlib.output_compression`` directive to +``Off`` in your php configuration file. + +.. _faq1_2: + +1.2 My Apache server crashes when using phpMyAdmin. +--------------------------------------------------- + +You should first try the latest versions of Apache (and possibly MySQL). If +your server keeps crashing, please ask for help in the various Apache support +groups. + +.. seealso:: :ref:`faq1_1` + +.. _faq1_3: + +1.3 (withdrawn). +---------------- + +.. _faq1_4: + +1.4 Using phpMyAdmin on IIS, I'm displayed the error message: "The specified CGI application misbehaved by not returning a complete set of HTTP headers ...". +------------------------------------------------------------------------------------------------------------------------------------------------------------- + +You just forgot to read the *install.txt* file from the PHP +distribution. Have a look at the last message in this `PHP bug report #12061 +`_ from the official PHP bug +database. + +.. _faq1_5: + +1.5 Using phpMyAdmin on IIS, I'm facing crashes and/or many error messages with the HTTP. +----------------------------------------------------------------------------------------- + +This is a known problem with the PHP :term:`ISAPI` filter: it's not so stable. +Please use instead the cookie authentication mode. + +.. _faq1_6: + +1.6 I can't use phpMyAdmin on PWS: nothing is displayed! +-------------------------------------------------------- + +This seems to be a PWS bug. Filippo Simoncini found a workaround (at +this time there is no better fix): remove or comment the ``DOCTYPE`` +declarations (2 lines) from the scripts :file:`libraries/Header.class.php` +and :file:`index.php`. + +.. _faq1_7: + +1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work. +---------------------------------------------------------------------------- + +These features are based on the ``gzencode()`` and ``bzcompress()`` +PHP functions to be more independent of the platform (Unix/Windows, +Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support +(``--with-zlib`` and ``--with-bz2``). + +.. _faq1_8: + +1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect. +----------------------------------------------------------------------------------------------- + +Your uploaded file is saved by PHP in the "upload dir", as defined in +:file:`php.ini` by the variable ``upload_tmp_dir`` (usually the system +default is */tmp*). We recommend the following setup for Apache +servers running in safe mode, to enable uploads of files while being +reasonably secure: + +* create a separate directory for uploads: :command:`mkdir /tmp/php` +* give ownership to the Apache server's user.group: :command:`chown + apache.apache /tmp/php` +* give proper permission: :command:`chmod 600 /tmp/php` +* put ``upload_tmp_dir = /tmp/php`` in :file:`php.ini` +* restart Apache + +.. _faq1_9: + +1.9 (withdrawn). +---------------- + +.. _faq1_10: + +1.10 I'm having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I'm using the Apache server. +---------------------------------------------------------------------------------------------------------------------------------------------------------- + +As suggested by "Rob M" in the phpWizard forum, add this line to your +*httpd.conf*: + +.. code-block:: apache + + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + +It seems to clear up many problems between Internet Explorer and SSL. + +.. _faq1_11: + +1.11 I get an 'open\_basedir restriction' while uploading a file from the query box. +------------------------------------------------------------------------------------ + +Since version 2.2.4, phpMyAdmin supports servers with open\_basedir +restrictions. However you need to create temporary directory and configure it +as :config:option:`$cfg['TempDir']`. The uploaded files will be moved there, +and after execution of your :term:`SQL` commands, removed. + +.. _faq1_12: + +1.12 I have lost my MySQL root password, what can I do? +------------------------------------------------------- + +The MySQL manual explains how to `reset the permissions +`_. + +.. _faq1_13: + +1.13 (withdrawn). +----------------- + +.. _faq1_14: + +1.14 (withdrawn). +----------------- + +.. _faq1_15: + +1.15 I have problems with *mysql.user* column names. +---------------------------------------------------- + +In previous MySQL versions, the ``User`` and ``Password``columns were +named ``user`` and ``password``. Please modify your column names to +align with current standards. + +.. _faq1_16: + +1.16 I cannot upload big dump files (memory, HTTP or timeout problems). +----------------------------------------------------------------------- + +Starting with version 2.7.0, the import engine has been re–written and +these problems should not occur. If possible, upgrade your phpMyAdmin +to the latest version to take advantage of the new import features. + +The first things to check (or ask your host provider to check) are the +values of ``upload_max_filesize``, ``memory_limit`` and +``post_max_size`` in the :file:`php.ini` configuration file. All of these +three settings limit the maximum size of data that can be submitted +and handled by PHP. One user also said that ``post_max_size`` and +``memory_limit`` need to be larger than ``upload_max_filesize``. +There exist several workarounds if your upload is too big or your +hosting provider is unwilling to change the settings: + +* Look at the :config:option:`$cfg['UploadDir']` feature. This allows one to upload a file to the server + via scp, ftp, or your favorite file transfer method. PhpMyAdmin is + then able to import the files from the temporary directory. More + information is available in the :ref:`config` of this document. +* Using a utility (such as `BigDump + `_) to split the files before + uploading. We cannot support this or any third party applications, but + are aware of users having success with it. +* If you have shell (command line) access, use MySQL to import the files + directly. You can do this by issuing the "source" command from within + MySQL: + + .. code-block:: mysql + + source filename.sql; + +.. _faq1_17: + +1.17 Which MySQL versions does phpMyAdmin support? +-------------------------------------------------- + +Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For +older MySQL versions, you need to use the latest 2.x branch. +phpMyAdmin can connect to your MySQL server using PHP's classic `MySQL +extension `_ as well as the `improved MySQL +extension (MySQLi) `_ that is available in PHP +5.0. The latter one should be used unless you have a good reason not +to do so. When compiling PHP, we strongly recommend that you manually +link the MySQL extension of your choice to a MySQL client library of +at least the same minor version since the one that is bundled with +some PHP distributions is rather old and might cause problems see +:ref:`faq1_17a`. `MariaDB `_ is also supported +(versions 5.1 and 5.2 were tested). + +.. versionchanged:: 3.5 + Since phpMyAdmin 3.5 `Drizzle `_ is supported. + +.. _faq1_17a: + +1.17a I cannot connect to the MySQL server. It always returns the error message, "Client does not support authentication protocol requested by server; consider upgrading MySQL client" +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +You tried to access MySQL with an old MySQL client library. The +version of your MySQL client library can be checked in your phpinfo() +output. In general, it should have at least the same minor version as +your server - as mentioned in :ref:`faq1_17`. This problem is +generally caused by using MySQL version 4.1 or newer. MySQL changed +the authentication hash and your PHP is trying to use the old method. +The proper solution is to use the `mysqli extension +`_ with the proper client library to match +your MySQL installation. Your chosen extension is specified in +:config:option:`$cfg['Servers'][$i]['extension']`. More +information (and several workarounds) are located in the `MySQL +Documentation `_. + +.. _faq1_18: + +1.18 (withdrawn). +----------------- + +.. _faq1_19: + +1.19 I can't run the "display relations" feature because the script seems not to know the font face I'm using! +-------------------------------------------------------------------------------------------------------------- + +The :term:`TCPDF` library we're using for this feature requires some special +files to use font faces. Please refers to the `TCPDF manual +`_ to build these files. + +.. _faqmysql: + +1.20 I receive the error "cannot load MySQL extension, please check PHP Configuration". +--------------------------------------------------------------------------------------- + +To connect to a MySQL server, PHP needs a set of MySQL functions +called "MySQL extension". This extension may be part of the PHP +distribution (compiled-in), otherwise it needs to be loaded +dynamically. Its name is probably *mysql.so* or *php\_mysql.dll*. +phpMyAdmin tried to load the extension but failed. Usually, the +problem is solved by installing a software package called "PHP-MySQL" +or something similar. + +.. _faq1_21: + +1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth. +------------------------------------------------------------------------------------------- + +In :file:`php.ini`, set ``mysql.max_links`` higher than 1. + +.. _faq1_22: + +1.22 I don't see the "Location of text file" field, so I cannot upload. +----------------------------------------------------------------------- + +This is most likely because in :file:`php.ini`, your ``file_uploads`` +parameter is not set to "on". + +.. _faq1_23: + +1.23 I'm running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase! +------------------------------------------------------------------------------------------------------------------------------ + +This happens because the MySQL directive ``lower_case_table_names`` +defaults to 1 (``ON``) in the Win32 version of MySQL. You can change +this behavior by simply changing the directive to 0 (``OFF``): Just +edit your ``my.ini`` file that should be located in your Windows +directory and add the following line to the group [mysqld]: + +.. code-block:: ini + + set-variable = lower_case_table_names=0 + +Next, save the file and restart the MySQL service. You can always +check the value of this directive using the query + +.. code-block:: mysql + + SHOW VARIABLES LIKE 'lower_case_table_names'; + +.. _faq1_24: + +1.24 (withdrawn). +----------------- + +.. _faq1_25: + +1.25 I am running Apache with mod\_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query. +---------------------------------------------------------------------------------------------------------------------------------------- + +A tip from Jose Fandos: put a comment on the following two lines in +httpd.conf, like this: + +.. code-block:: apache + + + # mod_gzip_item_include file \.php$ + # mod_gzip_item_include mime "application/x-httpd-php.*" + +as this version of mod\_gzip on Apache (Windows) has problems handling +PHP scripts. Of course you have to restart Apache. + +.. _faq1_26: + +1.26 I just installed phpMyAdmin in my document root of IIS but I get the error "No input file specified" when trying to run phpMyAdmin. +---------------------------------------------------------------------------------------------------------------------------------------- + +This is a permission problem. Right-click on the phpmyadmin folder and +choose properties. Under the tab Security, click on "Add" and select +the user "IUSR\_machine" from the list. Now set his permissions and it +should work. + +.. _faq1_27: + +1.27 I get empty page when I want to view huge page (eg. db\_structure.php with plenty of tables). +-------------------------------------------------------------------------------------------------- + +This was caused by a `PHP bug `_ that occur when +GZIP output buffering is enabled. If you turn off it (by +:config:option:`$cfg['OBGzip']` in :file:`config.inc.php`), it should work. +This bug will has been fixed in PHP 5.0.0. + +.. _faq1_28: + +1.28 My MySQL server sometimes refuses queries and returns the message 'Errorcode: 13'. What does this mean? +------------------------------------------------------------------------------------------------------------ + +This can happen due to a MySQL bug when having database / table names +with upper case characters although ``lower_case_table_names`` is +set to 1. To fix this, turn off this directive, convert all database +and table names to lower case and turn it on again. Alternatively, +there's a bug-fix available starting with MySQL 3.23.56 / +4.0.11-gamma. + +.. _faq1_29: + +1.29 When I create a table or modify a column, I get an error and the columns are duplicated. +--------------------------------------------------------------------------------------------- + +It is possible to configure Apache in such a way that PHP has problems +interpreting .php files. + +The problems occur when two different (and conflicting) set of +directives are used: + +.. code-block:: apache + + + SetOutputFilter PHP + SetInputFilter PHP + +and + +.. code-block:: apache + + AddType application/x-httpd-php .php + +In the case we saw, one set of directives was in +``/etc/httpd/conf/httpd.conf``, while the other set was in +``/etc/httpd/conf/addon-modules/php.conf``. The recommended way is +with ``AddType``, so just comment out the first set of lines and +restart Apache: + +.. code-block:: apache + + + #SetOutputFilter PHP + #SetInputFilter PHP + +.. _faq1_30: + +1.30 I get the error "navigation.php: Missing hash". +---------------------------------------------------- + +This problem is known to happen when the server is running Turck +MMCache but upgrading MMCache to version 2.3.21 solves the problem. + +.. _faq1_31: + +1.31 Does phpMyAdmin support PHP 5? +----------------------------------- + +Yes. + +Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use +phpMyAdmin 2.11.x. + +.. _faq1_32: + +1.32 Can I use HTTP authentication with IIS? +-------------------------------------------- + +Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in +:term:`ISAPI` mode under :term:`IIS` 5.1. + +#. In your :file:`php.ini` file, set ``cgi.rfc2616_headers = 0`` +#. In ``Web Site Properties -> File/Directory Security -> Anonymous + Access`` dialog box, check the ``Anonymous access`` checkbox and + uncheck any other checkboxes (i.e. uncheck ``Basic authentication``, + ``Integrated Windows authentication``, and ``Digest`` if it's + enabled.) Click ``OK``. +#. In ``Custom Errors``, select the range of ``401;1`` through ``401;5`` + and click the ``Set to Default`` button. + +.. seealso:: :rfc:`2616` + +.. _faq1_33: + +1.33 (withdrawn). +----------------- + +.. _faq1_34: + +1.34 Can I access directly to database or table pages? +------------------------------------------------------ + +Yes. Out of the box, you can use :term:`URL` like http://server/phpMyAdmin/index.php?server=X&db=databas +e&table=table&target=script. For ``server`` you use the server number +which refers to the order of the server paragraph in +:file:`config.inc.php`. Table and script parts are optional. If you want +http://server/phpMyAdmin/database[/table][/script] :term:`URL`, you need to do some configuration. Following +lines apply only for `Apache `_ web server. +First make sure, that you have enabled some features within global +configuration. You need ``Options FollowSymLinks`` and ``AllowOverride +FileInfo`` enabled for directory where phpMyAdmin is installed and you +need mod\_rewrite to be enabled. Then you just need to create +following :term:`.htaccess` file in root folder of phpMyAdmin installation (don't +forget to change directory name inside of it): + +.. code-block:: apache + + + RewriteEngine On + RewriteBase /path_to_phpMyAdmin + RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R] + RewriteRule ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R] + RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R] + RewriteRule ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R] + +.. _faq1_35: + +1.35 Can I use HTTP authentication with Apache CGI? +--------------------------------------------------- + +Yes. However you need to pass authentication variable to :term:`CGI` using +following rewrite rule: + +.. code-block:: apache + + + RewriteEngine On + RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L] + +.. _faq1_36: + +1.36 I get an error "500 Internal Server Error". +------------------------------------------------ + +There can be many explanations to this and a look at your server's +error log file might give a clue. + +.. _faq1_37: + +1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn't work. +----------------------------------------------------------------------------------------------------------- + +If your cluster consist of different architectures, PHP code used for +encryption/decryption won't work correct. This is caused by use of +pack/unpack functions in code. Only solution is to use mcrypt +extension which works fine in this case. + +.. _faq1_38: + +1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled? +------------------------------------------------------------------ + +Yes but the default configuration values of Suhosin are known to cause +problems with some operations, for example editing a table with many +columns and no primary key or with textual primary key. + +Suhosin configuration might lead to malfunction in some cases and it +can not be fully avoided as phpMyAdmin is kind of application which +needs to transfer big amounts of columns in single HTTP request, what +is something what Suhosin tries to prevent. Generally all +``suhosin.request.*``, ``suhosin.post.*`` and ``suhosin.get.*`` +directives can have negative effect on phpMyAdmin usability. You can +always find in your error logs which limit did cause dropping of +variable, so you can diagnose the problem and adjust matching +configuration variable. + +The default values for most Suhosin configuration options will work in +most scenarios, however you might want to adjust at least following +parameters: + +* `suhosin.request.max\_vars `_ should + be increased (eg. 2048) +* `suhosin.post.max\_vars `_ should be + increased (eg. 2048) +* `suhosin.request.max\_array\_index\_length `_ + should be increased (eg. 256) +* `suhosin.post.max\_array\_index\_length `_ + should be increased (eg. 256) +* `suhosin.request.max\_totalname\_length `_ + should be increased (eg. 8192) +* `suhosin.post.max\_totalname\_length `_ should be + increased (eg. 8192) +* `suhosin.get.max\_value\_length `_ + should be increased (eg. 1024) +* `suhosin.sql.bailout\_on\_error `_ + needs to be disabled (the default) +* `suhosin.log.\* `_ should not + include :term:`SQL`, otherwise you get big + slowdown + +You can also disable the warning using the :config:option:`$cfg['SuhosinDisableWarning']`. + +.. _faq1_39: + +1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior? +------------------------------------------------------------------------------------------------------------------------------------ + +Be sure that you have enabled ``SSLOptions`` and ``StdEnvVars`` in +your Apache configuration. + +.. seealso:: + +.. _faq1_40: + +1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work. +--------------------------------------------------------------------------------------- + +To be able to use cookie auth Apache must know that it has to rewrite +the set-cookie headers. Example from the Apache 2.2 documentation: + +.. code-block:: apache + + + ProxyPass /mirror/foo/ http://backend.example.com/ + ProxyPassReverse /mirror/foo/ http://backend.example.com/ + ProxyPassReverseCookieDomain backend.example.com public.example.com + ProxyPassReverseCookiePath / /mirror/foo/ + +Note: if the backend url looks like http://host/~user/phpmyadmin, the +tilde (~) must be url encoded as %7E in the ProxyPassReverse\* lines. +This is not specific to phpmyadmin, it's just the behavior of Apache. + +.. code-block:: apache + + + ProxyPass /mirror/foo/ http://backend.example.com/~user/phpmyadmin + ProxyPassReverse /mirror/foo/ http://backend.example.com/%7Euser/phpmyadmin + ProxyPassReverseCookiePath /%7Euser/phpmyadmin /mirror/foo + +.. seealso:: + +.. _faq1_41: + +1.41 When I view a database and ask to see its privileges, I get an error about an unknown column. +-------------------------------------------------------------------------------------------------- + +The MySQL server's privilege tables are not up to date, you need to +run the :command:`mysql_upgrade` command on the server. + +.. _faq1_42: + +1.42 How can I prevent robots from accessing phpMyAdmin? +-------------------------------------------------------- + +You can add various rules to :term:`.htaccess` to filter access based on user agent +field. This is quite easy to circumvent, but could prevent at least +some robots accessing your installation. + +.. code-block:: apache + + + RewriteEngine on + + # Allow only GET and POST verbs + RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR] + + # Ban Typical Vulnerability Scanners and others + # Kick out Script Kiddies + RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR] + RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR] + RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR] + + # Ban Search Engines, Crawlers to your administrative panel + # No reasons to access from bots + # Ultimately Better than the useless robots.txt + # Did google respect robots.txt? + # Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled" + RewriteCond %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.search.Crawler|Seoma.\[SEO.Crawler\]|SEOsearch|Snappy|www.urltrends.com|www.tkl.iis.u-tokyo.ac.jp/~crawler|SynooBot|crawleradmin.t-info@telekom.de|TurnitinBot|voyager|W3.SiteSearch.Crawler|W3C-checklink|W3C_Validator|www.WISEnutbot.com|yacybot|Yahoo-MMCrawler|Yahoo\!.DE.Slurp|Yahoo\!.Slurp|YahooSeeker).* [NC] + RewriteRule .* - [F] + +.. _faq1_43: + +1.43 Why can't I display the structure of my table containing hundreds of columns? +---------------------------------------------------------------------------------- + +Because your PHP's ``memory_limit`` is too low; adjust it in :file:`php.ini`. + +.. _faqconfig: + +Configuration ++++++++++++++ + +.. _faq2_1: + +2.1 The error message "Warning: Cannot add header information - headers already sent by ..." is displayed, what's the problem? +------------------------------------------------------------------------------------------------------------------------------ + +Edit your :file:`config.inc.php` file and ensure there is nothing (I.E. no +blank lines, no spaces, no characters...) neither before the ```` tag at the end. We also got a report +from a user under :term:`IIS`, that used a zipped distribution kit: the file +:file:`libraries/Config.class.php` contained an end-of-line character (hex 0A) +at the end; removing this character cleared his errors. + +.. _faq2_2: + +2.2 phpMyAdmin can't connect to MySQL. What's wrong? +---------------------------------------------------- + +Either there is an error with your PHP setup or your username/password +is wrong. Try to make a small script which uses mysql\_connect and see +if it works. If it doesn't, it may be you haven't even compiled MySQL +support into PHP. + +.. _faq2_3: + +2.3 The error message "Warning: MySQL Connection Failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) ..." is displayed. What can I do? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +For RedHat users, Harald Legner suggests this on the mailing list: + +On my RedHat-Box the socket of MySQL is */var/lib/mysql/mysql.sock*. +In your :file:`php.ini` you will find a line + +.. code-block:: ini + + mysql.default_socket = /tmp/mysql.sock + +change it to + +.. code-block:: ini + + mysql.default_socket = /var/lib/mysql/mysql.sock + +Then restart apache and it will work. + +Here is a fix suggested by Brad Ummer: + +* First, you need to determine what socket is being used by MySQL. To do + this, telnet to your server and go to the MySQL bin directory. In this + directory there should be a file named *mysqladmin*. Type + ``./mysqladmin variables``, and this should give you a bunch of info + about your MySQL server, including the socket (*/tmp/mysql.sock*, for + example). +* Then, you need to tell PHP to use this socket. To do this in + phpMyAdmin, you need to complete the socket information in the + :file:`config.inc.php`. For example: + :config:option:`$cfg['Servers'][$i]['socket']` Please also make sure that + the permissions of this file allow to be readable by your webserver (i.e. + '0755'). + +Have also a look at the `corresponding section of the MySQL +documentation `_. + +.. _faq2_4: + +2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do? +----------------------------------------------------------------------------------- + +Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in the phpMyAdmin configuration +file. It helps sometime. Also have a look at your PHP version number: +if it contains "b" or "alpha" it means you're running a testing +version of PHP. That's not a so good idea, please upgrade to a plain +revision. + +.. _faq2_5: + +2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I'm asked to log in again. What's wrong? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Check the value you set for the :config:option:`$cfg['PmaAbsoluteUri']` directive in the phpMyAdmin +configuration file. + +.. _faq2_6: + +2.6 I get an "Access denied for user: 'root@localhost' (Using password: YES)"-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost. +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +When you are using a port on your localhost, which you redirect via +port-forwarding to another host, MySQL is not resolving the localhost +as expected. Erik Wasser explains: The solution is: if your host is +"localhost" MySQL (the command line tool :command:`mysql` as well) always +tries to use the socket connection for speeding up things. And that +doesn't work in this configuration with port forwarding. If you enter +"127.0.0.1" as hostname, everything is right and MySQL uses the +:term:`TCP` connection. + +.. _faqthemes: + +2.7 Using and creating themes +----------------------------- + +Themes are configured with :config:option:`$cfg['ThemePath']`, +:config:option:`$cfg['ThemeManager']` and :config:option:`$cfg['ThemeDefault']`. +Under :config:option:`$cfg['ThemePath']`, you should not delete the +directory ``pmahomme`` or its underlying structure, because this is the +system theme used by phpMyAdmin. ``pmahomme`` contains all images and +styles, for backwards compatibility and for all themes that would not +include images or css-files. If :config:option:`$cfg['ThemeManager']` +is enabled, you can select your favorite theme on the main page. Your selected +theme will be stored in a cookie. + +To create a theme: + +* make a new subdirectory (for example "your\_theme\_name") under :config:option:`$cfg['ThemePath']` (by + default ``themes``) +* copy the files and directories from ``pmahomme`` to "your\_theme\_name" +* edit the css-files in "your\_theme\_name/css" +* put your new images in "your\_theme\_name/img" +* edit :file:`layout.inc.php` in "your\_theme\_name" +* edit :file:`info.inc.php` in "your\_theme\_name" to contain your chosen + theme name, that will be visible in user interface +* make a new screenshot of your theme and save it under + "your\_theme\_name/screen.png" + +In theme directory there is file :file:`info.inc.php` which contains theme +verbose name, theme generation and theme version. These versions and +generations are enumerated from 1 and do not have any direct +dependence on phpMyAdmin version. Themes within same generation should +be backwards compatible - theme with version 2 should work in +phpMyAdmin requiring version 1. Themes with different generation are +incompatible. + +If you do not want to use your own symbols and buttons, remove the +directory "img" in "your\_theme\_name". phpMyAdmin will use the +default icons and buttons (from the system-theme ``pmahomme``). + +.. _faqmissingparameters: + +2.8 I get "Missing parameters" errors, what can I do? +----------------------------------------------------- + +Here are a few points to check: + +* In :file:`config.inc.php`, try to leave the :config:option:`$cfg['PmaAbsoluteUri']` directive empty. See also + :ref:`faq4_7`. +* Maybe you have a broken PHP installation or you need to upgrade your + Zend Optimizer. See . +* If you are using Hardened PHP with the ini directive + ``varfilter.max_request_variables`` set to the default (200) or + another low value, you could get this error if your table has a high + number of columns. Adjust this setting accordingly. (Thanks to Klaus + Dorninger for the hint). +* In the :file:`php.ini` directive ``arg_separator.input``, a value of ";" + will cause this error. Replace it with "&;". +* If you are using `Hardened-PHP `_, you + might want to increase `request limits `_. +* The directory specified in the :file:`php.ini` directive + ``session.save_path`` does not exist or is read-only. + +.. _faq2_9: + +2.9 Seeing an upload progress bar +--------------------------------- + +To be able to see a progress bar during your uploads, your server must +have the `APC `_ extension, the +`uploadprogress `_ one, or +you must be running PHP 5.4.0 or higher. Moreover, the JSON extension +has to be enabled in your PHP. + +If using APC, you must set ``apc.rfc1867`` to ``on`` in your :file:`php.ini`. + +If using PHP 5.4.0 or higher, you must set +``session.upload_progress.enabled`` to ``1`` in your :file:`php.ini`. However, +starting from phpMyAdmin version 4.0.4, session-based upload progress has +been temporarily deactivated due to its problematic behavior. + +.. seealso:: :rfc:`1867` + +.. _faqlimitations: + +Known limitations ++++++++++++++++++ + +.. _login_bug: + +3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick. +----------------------------------------------------------------------------------------------------- + +This is related to the authentication mechanism (protocol) used by +phpMyAdmin. To bypass this problem: just close all the opened browser +windows and then go back to phpMyAdmin. You should be able to log in +again. + +.. _faq3_2: + +3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error. +---------------------------------------------------------------------------------------------------- + +Compressed dumps are built in memory and because of this are limited +to php's memory limit. For GZip/BZip2 exports this can be overcome +since 2.5.4 using :config:option:`$cfg['CompressOnFly']` (enabled by default). +Zip exports can not be handled this way, so if you need Zip files for larger +dump, you have to use another way. + +.. _faq3_3: + +3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column. +------------------------------------------------------------------------------------------- + +This is an InnoDB bug, see . + +.. _faq3_4: + +3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution. +------------------------------------------------------------------------------------------------------------- + +The problem is that older versions of ``mysqldump`` created invalid +comments like this: + +.. code-block:: mysql + + + -- MySQL dump 8.22 + -- + -- Host: localhost Database: database + --------------------------------------------------------- + -- Server version 3.23.54 + +The invalid part of the code is the horizontal line made of dashes +that appears once in every dump created with mysqldump. If you want to +run your dump you have to turn it into valid MySQL. This means, you +have to add a whitespace after the first two dashes of the line or add +a # before it: ``-- -------------------------------------------------------`` or +``#---------------------------------------------------------`` + +.. _faq3_5: + +3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner. +------------------------------------------------------------------------------------ + +Please note that you should not use the separating string multiple +times without any characters between them, or at the beginning/end of +your table name. If you have to, think about using another +TableSeparator or disabling that feature. + +.. seealso:: :config:option:`$cfg['NavigationTreeTableSeparator']` + +.. _faq3_6: + +3.6 What is currently not supported in phpMyAdmin about InnoDB? +--------------------------------------------------------------- + +In Relation view, being able to choose a table in another database, or +having more than one index column in the foreign key. In Query-by- +example (Query), automatic generation of the query LEFT JOIN from the +foreign table. + +.. _faq3_7: + +3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like "Warning: unable to parse url". How can this be fixed? +----------------------------------------------------------------------------------------------------------------------------------------------------------- + +Your table neither have a primary key nor an unique one, so we must +use a long expression to identify this row. This causes problems to +parse\_url function. The workaround is to create a primary or unique +key. + +.. _faq3_8: + +3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto! +------------------------------------------------------------------------------------------ + +Due to a surrounding form-container (for multi-row delete checkboxes), +no nested forms can be put inside the table where phpMyAdmin displays +the results. You can, however, use any form inside of a table if keep +the parent form-container with the target to tbl\_row\_delete.php and +just put your own input-elements inside. If you use a custom submit +input field, the form will submit itself to the displaying page again, +where you can validate the $HTTP\_POST\_VARS in a transformation. For +a tutorial on how to effectively use transformations, see our `Link +section `_ on the +official phpMyAdmin-homepage. + +.. _faq3_9: + +3.9 I get error messages when using "--sql\_mode=ANSI" for the MySQL server. +---------------------------------------------------------------------------- + +When MySQL is running in ANSI-compatibility mode, there are some major +differences in how :term:`SQL` is structured (see +). Most important of all, the +quote-character (") is interpreted as an identifier quote character and not as +a string quote character, which makes many internal phpMyAdmin operations into +invalid :term:`SQL` statements. There is no +workaround to this behaviour. News to this item will be posted in `Bug report +#1013 `_. + +.. _faq3_10: + +3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example ``SELECT lastname from employees where firstname like 'A%'`` and two "Smith" values are displayed), if I click Edit I cannot be sure that I am editing the intended row. +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Please make sure that your table has a primary key, so that phpMyAdmin +can use it for the Edit and Delete links. + +.. _faq3_11: + +3.11 The number of rows for InnoDB tables is not correct. +--------------------------------------------------------- + +phpMyAdmin uses a quick method to get the row count, and this method only +returns an approximate count in the case of InnoDB tables. See +:config:option:`$cfg['MaxExactCount']` for a way to modify those results, but +this could have a serious impact on performance. + +.. _faq3_12: + +3.12 (withdrawn). +----------------- + +.. _faq3_13: + +3.13 I get an error when entering ``USE`` followed by a db name containing an hyphen. +------------------------------------------------------------------------------------- + +The tests I have made with MySQL 5.1.49 shows that the API does not +accept this syntax for the USE command. + +.. _faq3_14: + +3.14 I am not able to browse a table when I don't have the right to SELECT one of the columns. +---------------------------------------------------------------------------------------------- + +This has been a known limitation of phpMyAdmin since the beginning and +it's not likely to be solved in the future. + +.. _faq3_15: + +3.15 (withdrawn). +----------------- + +.. _faq3_16: + +3.16 (withdrawn). +----------------- + +.. _faq3_17: + +3.17 (withdrawn). +----------------- + +.. _faq3_18: + +3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table. +---------------------------------------------------------------------------------------------------------- + +There is no reliable way to differentiate tables in :term:`CSV` format. For the +time being, you will have to break apart :term:`CSV` files containing multiple +tables. + +.. _faq3_19: + +3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types. +------------------------------------------------------------------------------------------------------------------------------------ + +Currently, the import type-detection system can only assign these +MySQL types to columns. In future, more will likely be added but for +the time being you will have to edit the structure to your liking +post-import. Also, you should note the fact that phpMyAdmin will use +the size of the largest item in any given column as the column size +for the appropriate type. If you know you will be adding larger items +to that column then you should manually adjust the column sizes +accordingly. This is done for the sake of efficiency. + +.. _faqmultiuser: + +ISPs, multi-user installations +++++++++++++++++++++++++++++++ + +.. _faq4_1: + +4.1 I'm an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer? +-------------------------------------------------------------------------------------------------------- + +Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your +users. The development of this feature was kindly sponsored by NetCologne GmbH. +This requires a properly setup MySQL user management and phpMyAdmin +:term:`HTTP` or cookie authentication. + +.. seealso:: :ref:`authentication_modes` + +.. _faq4_2: + +4.2 What's the preferred way of making phpMyAdmin secure against evil access? +----------------------------------------------------------------------------- + +This depends on your system. If you're running a server which cannot be +accessed by other people, it's sufficient to use the directory protection +bundled with your webserver (with Apache you can use :term:`.htaccess` files, +for example). If other people have telnet access to your server, you should use +phpMyAdmin's :term:`HTTP` or cookie authentication features. + +Suggestions: + +* Your :file:`config.inc.php` file should be ``chmod 660``. +* All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy + is a user whose password is only known to you, and apache is the group + under which Apache runs. +* Follow security recommendations for PHP and your webserver. + +.. _faq4_3: + +4.3 I get errors about not being able to include a file in */lang* or in */libraries*. +-------------------------------------------------------------------------------------- + +Check :file:`php.ini`, or ask your sysadmin to check it. The +``include_path`` must contain "." somewhere in it, and +``open_basedir``, if used, must contain "." and "./lang" to allow +normal operation of phpMyAdmin. + +.. _faq4_4: + +4.4 phpMyAdmin always gives "Access denied" when using HTTP authentication. +--------------------------------------------------------------------------- + +This could happen for several reasons: + +* :config:option:`$cfg['Servers'][$i]['controluser']` and/or :config:option:`$cfg['Servers'][$i]['controlpass']` are wrong. +* The username/password you specify in the login dialog are invalid. +* You have already setup a security mechanism for the phpMyAdmin- + directory, eg. a :term:`.htaccess` file. This would interfere with phpMyAdmin's + authentication, so remove it. + +.. _faq4_5: + +4.5 Is it possible to let users create their own databases? +----------------------------------------------------------- + +Starting with 2.2.5, in the user management page, you can enter a +wildcard database name for a user (for example "joe%"), and put the +privileges you want. For example, adding ``SELECT, INSERT, UPDATE, +DELETE, CREATE, DROP, INDEX, ALTER`` would let a user create/manage +his/her database(s). + +.. _faq4_6: + +4.6 How can I use the Host-based authentication additions? +---------------------------------------------------------- + +If you have existing rules from an old :term:`.htaccess` file, you can take them and +add a username between the ``'deny'``/``'allow'`` and ``'from'`` +strings. Using the username wildcard of ``'%'`` would be a major +benefit here if your installation is suited to using it. Then you can +just add those updated lines into the +:config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` array. + +If you want a pre-made sample, you can try this fragment. It stops the +'root' user from logging in from any networks other than the private +network :term:`IP` blocks. + +.. code-block:: php + + + //block root from logging in except from the private networks + $cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow'; + $cfg['Servers'][$i]['AllowDeny']['rules'] = array( + 'deny root from all', + 'allow root from localhost', + 'allow root from 10.0.0.0/8', + 'allow root from 192.168.0.0/16', + 'allow root from 172.16.0.0/12', + ); + +.. _faq4_7: + +4.7 Authentication window is displayed more than once, why? +----------------------------------------------------------- + +This happens if you are using a :term:`URL` to start phpMyAdmin which is +different than the one set in your :config:option:`$cfg['PmaAbsoluteUri']`. For +example, a missing "www", or entering with an :term:`IP` address while a domain +name is defined in the config file. + +.. _faq4_8: + +4.8 Which parameters can I use in the URL that starts phpMyAdmin? +----------------------------------------------------------------- + +When starting phpMyAdmin, you can use the ``db``, ``pma_username``, +``pma_password`` and ``server`` parameters. This last one can contain +either the numeric host index (from ``$i`` of the configuration file) +or one of the host names present in the configuration file. Using +``pma_username`` and ``pma_password`` has been tested along with the +usage of 'cookie' ``auth_type``. + +.. _faqbrowsers: + +Browsers or client OS ++++++++++++++++++++++ + +.. _faq5_1: + +5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns. +------------------------------------------------------------------------------------------------------------------------------ + +We could reproduce this problem only under Win98/98SE. Testing under +WinNT4 or Win2K, we could easily create more than 60 columns. A +workaround is to create a smaller number of columns, then come back to +your table properties and add the other columns. + +.. _faq5_2: + +5.2 With Xitami 2.5b4, phpMyAdmin won't process form fields. +------------------------------------------------------------ + +This is not a phpMyAdmin problem but a Xitami known bug: you'll face +it with each script/website that use forms. Upgrade or downgrade your +Xitami server. + +.. _faq5_3: + +5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2). +--------------------------------------------------------------------- + +With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except +that the proposed file name for the dump is always 'tbl\_dump.php'. +Bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps +work; zip dumps are placed into the user's temporary directory, so +they must be moved before closing Konqueror, or else they disappear. +GZip dumps give an error message. Testing needs to be done for +Konqueror 2.2.2. + +.. _faq5_4: + +5.4 I can't use the cookie authentication mode because Internet Explorer never stores the cookies. +-------------------------------------------------------------------------------------------------- + +MS Internet Explorer seems to be really buggy about cookies, at least +till version 6. + +.. _faq5_5: + +5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows. +---------------------------------------------------------------------------- + +Upgrade to at least Internet Explorer 5.5 SP2. + +.. _faq5_6: + +5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like "Page not found") when trying to modify a row in a table with many columns, or with a text column. +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Your table neither have a primary key nor an unique one, so we must use a long +:term:`URL` to identify this row. There is a limit on the length of the +:term:`URL` in those browsers, and this not happen in Netscape, for example. +The workaround is to create a primary or unique key, or use another browser. + +.. _faq5_7: + +5.7 I refresh (reload) my browser, and come back to the welcome page. +--------------------------------------------------------------------- + +Some browsers support right-clicking into the frame you want to +refresh, just do this in the right frame. + +.. _faq5_8: + +5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box. +--------------------------------------------------------------------------------- + +Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future +Mozilla versions. + +.. _faq5_9: + +5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can't type a whitespace in the SQL-Query edit area: the page scrolls down. +------------------------------------------------------------------------------------------------------------------------------- + +This is a Mozilla bug (see bug #26882 at `BugZilla +`_). + +.. _faq5_10: + +5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file. +----------------------------------------------------------------------------------------- + +This is a known Netscape 4.75 bug: it adds some line feeds when +exporting data in octet-stream mode. Since we can't detect the +specific Netscape version, we cannot workaround this bug. + +.. _faq5_11: + +5.11 Extended-ASCII characters like German umlauts are displayed wrong. +----------------------------------------------------------------------- + +Please ensure that you have set your browser's character set to the +one of the language file you have selected on phpMyAdmin's start page. +Alternatively, you can try the auto detection mode that is supported +by the recent versions of the most browsers. + +.. _faq5_12: + +5.12 Mac OS X Safari browser changes special characters to "?". +--------------------------------------------------------------- + +This issue has been reported by a :term:`Mac OS X` user, who adds that Chimera, +Netscape and Mozilla do not have this problem. + +.. _faq5_13: + +5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation. +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +This is a bug in Internet Explorer, other browsers do not behave this +way. + +.. _faq5_14: + +5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen. +------------------------------------------------------------------------------------------------------------------ + +Please upgrade to Opera7 at least. + +.. _faq5_15: + +5.15 I have display problems with Safari. +----------------------------------------- + +Please upgrade to at least version 1.2.3. + +.. _faq5_16: + +5.16 With Internet Explorer, I get "Access is denied" Javascript errors. Or I cannot make phpMyAdmin work under Windows. +------------------------------------------------------------------------------------------------------------------------ + +Please check the following points: + +* Maybe you have defined your :config:option:`$cfg['PmaAbsoluteUri']` setting in + :file:`config.inc.php` to an :term:`IP` address and you are starting phpMyAdmin + with a :term:`URL` containing a domain name, or the reverse situation. +* Security settings in IE and/or Microsoft Security Center are too high, + thus blocking scripts execution. +* The Windows Firewall is blocking Apache and MySQL. You must allow + :term:`HTTP` ports (80 or 443) and MySQL + port (usually 3306) in the "in" and "out" directions. + +.. _faq5_17: + +5.17 With Firefox, I cannot delete rows of data or drop a database. +------------------------------------------------------------------- + +Many users have confirmed that the Tabbrowser Extensions plugin they +installed in their Firefox is causing the problem. + +.. _faq5_18: + +5.18 With Konqueror 4.2.x an invalid ``LIMIT`` clause is generated when I browse a table. +----------------------------------------------------------------------------------------- + +This happens only when both of these conditions are met: using the +``http`` authentication mode and ``register_globals`` being set to +``On`` on the server. It seems to be a browser-specific problem; +meanwhile use the ``cookie`` authentication mode. + +.. _faq5_19: + +5.19 I get JavaScript errors in my browser. +------------------------------------------- + +Issues have been reported with some combinations of browser +extensions. To troubleshoot, disable all extensions then clear your +browser cache to see if the problem goes away. + +.. _faqusing: + +Using phpMyAdmin +++++++++++++++++ + +.. _faq6_1: + +6.1 I can't insert new rows into a table / I can't create a table - MySQL brings up a SQL error. +------------------------------------------------------------------------------------------------ + +Examine the :term:`SQL` error with care. +Often the problem is caused by specifying a wrong column-type. Common +errors include: + +* Using ``VARCHAR`` without a size argument +* Using ``TEXT`` or ``BLOB`` with a size argument + +Also, look at the syntax chapter in the MySQL manual to confirm that +your syntax is correct. + +.. _faq6_2: + +6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns. +------------------------------------------------------------------------------------------------------------------------- + +This is the way to create a multi-columns index. If you want two +indexes, create the first one when creating the table, save, then +display the table properties and click the Index link to create the +other index. + +.. _faq6_3: + +6.3 How can I insert a null value into my table? +------------------------------------------------ + +Since version 2.2.3, you have a checkbox for each column that can be +null. Before 2.2.3, you had to enter "null", without the quotes, as +the column's value. Since version 2.5.5, you have to use the checkbox +to get a real NULL value, so if you enter "NULL" this means you want a +literal NULL in the column, and not a NULL value (this works in PHP4). + +.. _faq6_4: + +6.4 How can I backup my database or table? +------------------------------------------ + +Click on a database or table name in the navigation panel, the properties will +be displayed. Then on the menu, click "Export", you can dump the structure, the +data, or both. This will generate standard :term:`SQL` statements that can be +used to recreate your database/table. You will need to choose "Save as file", +so that phpMyAdmin can transmit the resulting dump to your station. Depending +on your PHP configuration, you will see options to compress the dump. See also +the :config:option:`$cfg['ExecTimeLimit']` configuration variable. For +additional help on this subject, look for the word "dump" in this document. + +.. _faq6_5: + +6.5 How can I restore (upload) my database or table using a dump? How can I run a ".sql" file? +---------------------------------------------------------------------------------------------- + +Click on a database name in the navigation panel, the properties will +be displayed. Select "Import" from the list of tabs in the right–hand +frame (or ":term:`SQL`" if your phpMyAdmin +version is previous to 2.7.0). In the "Location of the text file" +section, type in the path to your dump filename, or use the Browse +button. Then click Go. With version 2.7.0, the import engine has been +re–written, if possible it is suggested that you upgrade to take +advantage of the new features. For additional help on this subject, +look for the word "upload" in this document. + +.. _faq6_6: + +6.6 How can I use the relation table in Query-by-example? +--------------------------------------------------------- + +Here is an example with the tables persons, towns and countries, all +located in the database mydb. If you don't have a ``pma__relation`` +table, create it as explained in the configuration section. Then +create the example tables: + +.. code-block:: mysql + + + CREATE TABLE REL_countries ( + country_code char(1) NOT NULL default '', + description varchar(10) NOT NULL default '', + PRIMARY KEY (country_code) + ) TYPE=MyISAM; + + INSERT INTO REL_countries VALUES ('C', 'Canada'); + + CREATE TABLE REL_persons ( + id tinyint(4) NOT NULL auto_increment, + person_name varchar(32) NOT NULL default '', + town_code varchar(5) default '0', + country_code char(1) NOT NULL default '', + PRIMARY KEY (id) + ) TYPE=MyISAM; + + INSERT INTO REL_persons VALUES (11, 'Marc', 'S', ''); + INSERT INTO REL_persons VALUES (15, 'Paul', 'S', 'C'); + + CREATE TABLE REL_towns ( + town_code varchar(5) NOT NULL default '0', + description varchar(30) NOT NULL default '', + PRIMARY KEY (town_code) + ) TYPE=MyISAM; + + INSERT INTO REL_towns VALUES ('S', 'Sherbrooke'); + INSERT INTO REL_towns VALUES ('M', 'Montréal'); + +To setup appropriate links and display information: + +* on table "REL\_persons" click Structure, then Relation view +* in Links, for "town\_code" choose "REL\_towns->code" +* in Links, for "country\_code" choose "REL\_countries->country\_code" +* on table "REL\_towns" click Structure, then Relation view +* in "Choose column to display", choose "description" +* repeat the two previous steps for table "REL\_countries" + +Then test like this: + +* Click on your db name in the navigation panel +* Choose "Query" +* Use tables: persons, towns, countries +* Click "Update query" +* In the columns row, choose persons.person\_name and click the "Show" + tickbox +* Do the same for towns.description and countries.descriptions in the + other 2 columns +* Click "Update query" and you will see in the query box that the + correct joins have been generated +* Click "Submit query" + +.. _faqdisplay: + +6.7 How can I use the "display column" feature? +----------------------------------------------- + +Starting from the previous example, create the ``pma__table_info`` as +explained in the configuration section, then browse your persons +table, and move the mouse over a town code or country code. See also +:ref:`faq6_21` for an additional feature that "display column" +enables: drop-down list of possible values. + +.. _faqpdf: + +6.8 How can I produce a PDF schema of my database? +-------------------------------------------------- + +First the configuration variables "relation", "table\_coords" and +"pdf\_pages" have to be filled in. Then you need to think about your +schema layout. Which tables will go on which pages? + +* Select your database in the navigation panel. +* Choose "Operations" in the navigation bar at the top. +* Choose "Edit :term:`PDF` Pages" near the + bottom of the page. +* Enter a name for the first :term:`PDF` page + and click Go. If you like, you can use the "automatic layout," which + will put all your linked tables onto the new page. +* Select the name of the new page (making sure the Edit radio button is + selected) and click Go. +* Select a table from the list, enter its coordinates and click Save. + Coordinates are relative; your diagram will be automatically scaled to + fit the page. When initially placing tables on the page, just pick any + coordinates -- say, 50x50. After clicking Save, you can then use the + :ref:`wysiwyg` to position the element correctly. +* When you'd like to look at your :term:`PDF`, first be sure to click the Save + button beneath the list of tables and coordinates, to save any changes you + made there. Then scroll all the way down, select the :term:`PDF` options you + want, and click Go. +* Internet Explorer for Windows may suggest an incorrect filename when + you try to save a generated :term:`PDF`. + When saving a generated :term:`PDF`, be + sure that the filename ends in ".pdf", for example "schema.pdf". + Browsers on other operating systems, and other browsers on Windows, do + not have this problem. + +.. _faq6_9: + +6.9 phpMyAdmin is changing the type of one of my columns! +--------------------------------------------------------- + +No, it's MySQL that is doing `silent column type changing +`_. + +.. _underscore: + +6.10 When creating a privilege, what happens with underscores in the database name? +----------------------------------------------------------------------------------- + +If you do not put a backslash before the underscore, this is a +wildcard grant, and the underscore means "any character". So, if the +database name is "john\_db", the user would get rights to john1db, +john2db ... If you put a backslash before the underscore, it means +that the database name will have a real underscore. + +.. _faq6_11: + +6.11 What is the curious symbol ø in the statistics pages? +---------------------------------------------------------- + +It means "average". + +.. _faqexport: + +6.12 I want to understand some Export options. +---------------------------------------------- + +**Structure:** + +* "Add DROP TABLE" will add a line telling MySQL to `drop the table + `_, if it already + exists during the import. It does NOT drop the table after your + export, it only affects the import file. +* "If Not Exists" will only create the table if it doesn't exist. + Otherwise, you may get an error if the table name exists but has a + different structure. +* "Add AUTO\_INCREMENT value" ensures that AUTO\_INCREMENT value (if + any) will be included in backup. +* "Enclose table and column names with backquotes" ensures that column + and table names formed with special characters are protected. +* "Add into comments" includes column comments, relations, and MIME + types set in the pmadb in the dump as :term:`SQL` comments + (*/\* xxx \*/*). + +**Data:** + +* "Complete inserts" adds the column names on every INSERT command, for + better documentation (but resulting file is bigger). +* "Extended inserts" provides a shorter dump file by using only once the + INSERT verb and the table name. +* "Delayed inserts" are best explained in the `MySQL manual - INSERT DELAYED Syntax + `_. +* "Ignore inserts" treats errors as a warning instead. Again, more info + is provided in the `MySQL manual - INSERT Syntax + `_, but basically with + this selected, invalid values are adjusted and inserted rather than + causing the entire statement to fail. + +.. _faq6_13: + +6.13 I would like to create a database with a dot in its name. +-------------------------------------------------------------- + +This is a bad idea, because in MySQL the syntax "database.table" is +the normal way to reference a database and table name. Worse, MySQL +will usually let you create a database with a dot, but then you cannot +work with it, nor delete it. + +.. _faqsqlvalidator: + +6.14 How do I set up the SQL Validator? +--------------------------------------- + +To use SQL Validator, you need PHP with :term:`XML`, :term:`PCRE` and +:term:`PEAR` support. In addition you need a :term:`SOAP` support, either as a +PHP extension or as a PEAR SOAP module. + +To install :term:`PEAR` :term:`SOAP` module, run :command:`pear install +Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP` to get the necessary +:term:`PEAR` modules for usage. + +If you use the Validator, you should be aware that any :term:`SQL` statement +you submit will be stored anonymously (database/table/column names, strings, +numbers replaced with generic values). The Mimer :term:`SQL` Validator itself, +is © 2001 Upright Database Technology. We utilize it as free SOAP service. + +.. _faq6_15: + +6.15 I want to add a BLOB column and put an index on it, but MySQL says "BLOB column '...' used in key specification without a key length". +------------------------------------------------------------------------------------------------------------------------------------------- + +The right way to do this, is to create the column without any indexes, +then display the table structure and use the "Create an index" dialog. +On this page, you will be able to choose your BLOB column, and set a +size to the index, which is the condition to create an index on a BLOB +column. + +.. _faq6_16: + +6.16 How can I simply move in page with plenty editing fields? +-------------------------------------------------------------- + +You can use :kbd:`Ctrl+arrows` (:kbd:`Option+Arrows` in Safari) for moving on +most pages with many editing fields (table structure changes, row editing, +etc.). + +.. _faq6_17: + +6.17 Transformations: I can't enter my own mimetype! WTF is this feature then useful for? +----------------------------------------------------------------------------------------- + +Slow down :). Defining mimetypes is of no use, if you can't put +transformations on them. Otherwise you could just put a comment on the +column. Because entering your own mimetype will cause serious syntax +checking issues and validation, this introduces a high-risk false- +user-input situation. Instead you have to initialize mimetypes using +functions or empty mimetype definitions. + +Plus, you have a whole overview of available mimetypes. Who knows all those +mimetypes by heart so he/she can enter it at will? + +.. _faqbookmark: + +6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What is this variable for? +-------------------------------------------------------------------------------------------------------------------------- + +Any query you have executed can be stored as a bookmark on the page +where the results are displayed. You will find a button labeled +'Bookmark this query' just at the end of the page. As soon as you have +stored a bookmark, it is related to the database you run the query on. +You can now access a bookmark dropdown on each page, the query box +appears on for that database. + +You can also have, inside the query, a placeholder for a variable. +This is done by inserting into the query a SQL comment between ``/*`` and +``*/``. Inside the comment, the special string ``[VARIABLE]`` is used. +Be aware that the whole query minus the SQL comment must be +valid by itself, otherwise you won't be able to store it as a bookmark. + +When you execute the bookmark, everything typed into the *value* +input box on the query box page will replace the string ``/*[VARIABLE]*/`` in +your stored query. + +Also remember, that everything else inside the ``/*[VARIABLE]*/`` string for +your query will remain the way it is, but will be stripped of the ``/**/`` +chars. So you can use: + +.. code-block:: mysql + + /*, [VARIABLE] AS myname */ + +which will be expanded to + +.. code-block:: mysql + + , VARIABLE as myname + +in your query, where VARIABLE is the string you entered in the input box. If an +empty string is provided, no replacements are made. + +A more complex example. Say you have stored +this query: + +.. code-block:: mysql + + SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */ + +Say, you now enter "phpMyAdmin" as the variable for the stored query, the full +query will be: + +.. code-block:: mysql + + SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%' + +You can use multiple occurrences of ``/*[VARIABLE]*/`` in a single query +(that is, multiple occurrences of the *same* variable). + +**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces +inserted there will be later also inserted as spaces in your query and may lead +to unexpected results especially when using the variable expansion inside of a +"LIKE ''" expression. + +Your initial query which is going to be stored as a bookmark has to yield at +least one result row so you can store the bookmark. You may have that to work +around using well positioned ``/**/`` comments. + +.. _faq6_19: + +6.19 How can I create simple LATEX document to include exported table? +---------------------------------------------------------------------- + +You can simply include table in your LATEX documents, +minimal sample document should look like following one (assuming you +have table exported in file :file:`table.tex`): + +.. code-block:: latex + + + \documentclass{article} % or any class you want + \usepackage{longtable} % for displaying table + \begin{document} % start of document + \include{table} % including exported table + \end{document} % end of document + +.. _faq6_20: + +6.20 I see a lot of databases which are not mine, and cannot access them. +------------------------------------------------------------------------- + +You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW +DATABASES, LOCK TABLES. Those privileges also enable users to see all the +database names. So if your users do not need those privileges, you can remove +them and their databases list will shorten. + +.. seealso:: + +.. _faq6_21: + +6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table? +------------------------------------------------------------------------------------------------------------ + +You have to setup appropriate links between the tables, and also setup +the "display column" in the foreign table. See :ref:`faq6_6` for an +example. Then, if there are 100 values or less in the foreign table, a +drop-down list of values will be available. You will see two lists of +values, the first list containing the key and the display column, the +second list containing the display column and the key. The reason for +this is to be able to type the first letter of either the key or the +display column. For 100 values or more, a distinct window will appear, +to browse foreign key values and choose one. To change the default +limit of 100, see :config:option:`$cfg['ForeignKeyMaxLimit']`. + + +.. _faq6_22: + +6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table? +----------------------------------------------------------------------------------------------------- + +Yes. If a bookmark has the same label as a table name and it's not a +public bookmark, it will be executed. + +.. _faq6_23: + +6.23 Export: I heard phpMyAdmin can export Microsoft Excel files? +----------------------------------------------------------------- + +You can use :term:`CSV` for Microsoft Excel, +which works out of the box. + +.. versionchanged:: 3.4.5 + Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version + 97 and newer was dropped. + +.. _faq6_24: + +6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb? +------------------------------------------------------------------------------------------------------------------------- + +Automatic migration of a table's pmadb-style column comments to the +native ones is done whenever you enter Structure page for this table. + +.. _faq6_25: + +6.25 (withdrawn). +----------------- + +.. _faq6_26: + +6.26 How can I select a range of rows? +-------------------------------------- + +Click the first row of the range, hold the shift key and click the +last row of the range. This works everywhere you see rows, for example +in Browse mode or on the Structure page. + +.. _faq6_27: + +6.27 What format strings can I use? +----------------------------------- + +In all places where phpMyAdmin accepts format strings, you can use +``@VARIABLE@`` expansion and `strftime `_ +format strings. The expanded variables depend on a context (for +example, if you haven't chosen a table, you can not get the table +name), but the following variables can be used: + +``@HTTP_HOST@`` + HTTP host that runs phpMyAdmin +``@SERVER@`` + MySQL server name +``@VERBOSE@`` + Verbose MySQL server name as defined in :config:option:`$cfg['Servers'][$i]['verbose']` +``@VSERVER@`` + Verbose MySQL server name if set, otherwise normal +``@DATABASE@`` + Currently opened database +``@TABLE@`` + Currently opened table +``@COLUMNS@`` + Columns of the currently opened table +``@PHPMYADMIN@`` + phpMyAdmin with version + +.. _wysiwyg: + +6.28 How can I easily edit relational schema for export? +-------------------------------------------------------- + +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. + +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. + +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. + +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. + +.. _faq6_29: + +6.29 Why can't I get a chart from my query result table? +-------------------------------------------------------- + +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 `wiki `_. + +.. _faq6_30: + +6.30 Import: How can I import ESRI Shapefiles +--------------------------------------------- + +An ESRI Shapefile is actually a set of several files, where .shp file +contains geometry data and .dbf file contains data related to those +geometry data. To read data from .dbf file you need to have PHP +compiled with the dBase extension (--enable-dbase). Otherwise only +geometry data will be imported. + +To upload these set of files you can use either of the following +methods: + +Configure upload directory with :config:option:`$cfg['UploadDir']`, upload both .shp and .dbf files with +the same filename and chose the .shp file from the import page. + +Create a Zip archive with .shp and .dbf files and import it. For this +to work, you need to set :config:option:`$cfg['TempDir']` to a place where the web server user can +write (for example ``'./tmp'``). + +To create the temporary directory on a UNIX-based system, you can do: + +.. code-block:: sh + + cd phpMyAdmin + mkdir tmp + chmod o+rwx tmp + +.. _faq6_31: + +6.31 How do I create a relation in designer? +-------------------------------------------- + +To select relation, click: The display column is shown in pink. To +set/unset a column as the display column, click the "Choose column to +display" icon, then click on the appropriate column name. + +.. _faq6_32: + +6.32 How can I use the zoom search feature? +------------------------------------------- + +The Zoom search feature is an alternative to table search feature. It allows +you to explore a table by representing its data in a scatter plot. You can +locate this feature by selecting a table and clicking the :guilabel:`Search` +tab. One of the sub-tabs in the :guilabel:`Table Search` page is +:guilabel:`Zoom Search`. + +Consider the table REL\_persons in :ref:`faq6_6` for +an example. To use zoom search, two columns need to be selected, for +example, id and town\_code. The id values will be represented on one +axis and town\_code values on the other axis. Each row will be +represented as a point in a scatter plot based on its id and +town\_code. You can include two additional search criteria apart from +the two fields to display. + +You can choose which field should be +displayed as label for each point. If a display column has been set +for the table (see :ref:`faqdisplay`), it is taken as the label unless +you specify otherwise. You can also select the maximum number of rows +you want to be displayed in the plot by specifing it in the 'Max rows +to plot' field. Once you have decided over your criteria, click 'Go' +to display the plot. + +After the plot is generated, you can use the +mousewheel to zoom in and out of the plot. In addition, panning +feature is enabled to navigate through the plot. You can zoom-in to a +certail level of detail and use panning to locate your area of +interest. Clicking on a point opens a dialogue box, displaying field +values of the data row represented by the point. You can edit the +values if required and click on submit to issue an update query. Basic +instructions on how to use can be viewed by clicking the 'How to use?' +link located just above the plot. + +.. _faq6_33: + +6.33 When browsing a table, how can I copy a column name? +--------------------------------------------------------- + +Selecting the name of the column within the browse table header cell +for copying is difficult, as the columns support reordering by +dragging the header cells as well as sorting by clicking on the linked +column name. To copy a column name, double-click on the empty area +next to the column name, when the tooltip tells you to do so. This +will show you an input box with the column name. You may right-click +the column name within this input box to copy it to your clipboard. + +.. _faqproject: + +phpMyAdmin project +++++++++++++++++++ + +.. _faq7_1: + +7.1 I have found a bug. How do I inform developers? +--------------------------------------------------- + +Our Bug Tracker is located at under the +Bugs section. But please first discuss your bug with other users: +. + +.. _faq7_2: + +7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start? +--------------------------------------------------------------------------------------------------------- + +Translations are very welcome and all you need to have are the +language skills. The easiest way is to use our `online translation +service `_. You can check +out all the possibilities to translate in the `translate section on +our website `_. + +.. _faq7_3: + +7.3 I would like to help out with the development of phpMyAdmin. How should I proceed? +-------------------------------------------------------------------------------------- + +We welcome every contribution to the development of phpMyAdmin. You +can check out all the possibilities to contribute in the `contribute +section on our website +`_. + +.. seealso:: :ref:`developers` + +.. _faqsecurity: + +Security +++++++++ + +.. _faq8_1: + +8.1 Where can I get information about the security alerts issued for phpMyAdmin? +-------------------------------------------------------------------------------- + +Please refer to . + +.. _faq8_2: + +8.2 How can I protect phpMyAdmin against brute force attacks? +------------------------------------------------------------- + +If you use Apache web server, phpMyAdmin exports information about +authentication to the Apache environment and it can be used in Apache +logs. Currently there are two variables available: + + +``userID`` + User name of currently active user (he does not have to be logged in). +``userStatus`` + Status of currently active user, one of ``ok`` (user is logged in), + ``mysql-denied`` (MySQL denied user login), ``allow-denied`` (user denied + by allow/deny rules), ``root-denied`` (root is denied in configuration), + ``empty-denied`` (empty password is denied). + +``LogFormat`` directive for Apache can look like following: + +.. code-block:: apache + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n" pma_combined + +You can then use any log analyzing tools to detect possible break-in +attempts. + +.. _faqsynchronization: + +Synchronization ++++++++++++++++ + +.. _faq9_1: + +9.1 (withdrawn). +---------------- + +.. _faq9_2: + +9.2 (withdrawn). +---------------- + diff --git a/phpmyadmin/doc/glossary.rst b/phpmyadmin/doc/glossary.rst new file mode 100644 index 000000000..d558b4405 --- /dev/null +++ b/phpmyadmin/doc/glossary.rst @@ -0,0 +1,406 @@ +.. _glossary: + +Glossary +======== + +From Wikipedia, the free encyclopedia + +.. glossary:: + + .htaccess + the default name of Apache's directory-level configuration file. + + .. seealso:: + + ACL + Access Contol List + + Blowfish + a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier. + + .. seealso:: + + Browser + a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web. + + .. seealso:: + + bzip2 + a free software/open source data compression algorithm and program developed by Julian Seward. + + .. seealso:: + + CGI + Common Gateway Interface is an important World Wide Web technology that + enables a client web browser to request data from a program executed on + the Web server. + + .. seealso:: + + Changelog + a log or record of changes made to a project. + + .. seealso:: + + Client + a computer system that accesses a (remote) service on another computer by some kind of network. + + .. seealso:: + + column + a set of data values of a particular simple type, one for each row of the table. + + .. seealso:: + + Cookie + a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server. + + .. seealso:: + + CSV + Comma- separated values + + .. seealso:: + + DB + look at :term:`database` + + database + an organized collection of data. + + .. seealso:: + + Engine + look at :term:`storage engines` + + extension + a PHP module that extends PHP with additional functionality. + + .. seealso:: + + FAQ + Frequently Asked Questions is a list of commonly asked question and there + answers. + + .. seealso:: + + Field + one part of divided data/columns. + + .. seealso:: + + foreign key + a column or group of columns in a database row that point to a key column + or group of columns forming a key of another database row in some + (usually different) table. + + .. seealso:: + + FPDF + the free :term:`PDF` library + + .. seealso:: + + GD + Graphics Library by Thomas Boutell and others for dynamically manipulating images. + + .. seealso:: + + GD2 + look at :term:`gd` + + gzip + gzip is short for GNU zip, a GNU free software file compression program. + + .. seealso:: + + host + any machine connected to a computer network, a node that has a hostname. + + .. seealso:: + + hostname + the unique name by which a network attached device is known on a network. + + .. seealso:: + + HTTP + HyperText Transfer Protocol is the primary method used to transfer or + convey information on the World Wide Web. + + .. seealso:: + + https + a :term:`HTTP`-connection with additional security measures. + + .. seealso:: + + IEC + International Electrotechnical Commission + + IIS + Internet Information Services is a set of Internet-based services for + servers using Microsoft Windows. + + .. seealso:: + + Index + a feature that allows quick access to the rows in a table. + + .. seealso:: + + IP + Internet Protocol is a data-oriented protocol used by source and + destination hosts for communicating data across a packet-switched + internetwork. + + .. seealso:: + + IP Address + a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard. + + .. seealso:: + + IPv6 + IPv6 (Internet Protocol version 6) is the latest revision of the + Internet Protocol (:term:`IP`), designed to deal with the + long-anticipated problem of its precedessor IPv4 running out of addresses. + + .. seealso:: + + ISAPI + Internet Server Application Programming Interface is the API of Internet Information Services (IIS). + + .. seealso:: + + ISP + Internet service provider is a business or organization that offers users + access to the Internet and related services. + + .. seealso:: + + ISO + International Standards Organisation + + JPEG + a most commonly used standard method of lossy compression for photographic images. + + .. seealso:: + + JPG + look at :term:`jpeg` + + Key + look at :term:`index` + + LATEX + a document preparation system for the TEX typesetting program. + + .. seealso:: + + Mac + Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer. + + .. seealso:: + + Mac OS X + the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets. + + .. seealso:: + + MCrypt + a cryptographic library. + + .. seealso:: + + mcrypt + the MCrypt PHP extension. + + .. seealso:: + + MIME + Multipurpose Internet Mail Extensions is + an Internet Standard for the format of e-mail. + + .. seealso:: + + module + some sort of extension for the Apache Webserver. + + .. seealso:: + + MySQL + a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS). + + .. seealso:: + + mysqli + the improved MySQL client PHP extension. + + .. seealso:: + + mysql + the MySQL client PHP extension. + + .. seealso:: + + OpenDocument + open standard for office documents. + + .. seealso:: + + OS X + look at :term:`Mac OS X`. + + .. seealso:: + + PDF + Portable Document Format is a file format developed by Adobe Systems for + representing two dimensional documents in a device independent and + resolution independent format. + + .. seealso:: + + PEAR + the PHP Extension and Application Repository. + + .. seealso:: + + PCRE + Perl Compatible Regular Expressions is the perl-compatible regular + expression functions for PHP + + .. seealso:: + + PHP + short for "PHP: Hypertext Preprocessor", is an open-source, reflective + programming language used mainly for developing server-side applications + and dynamic web content, and more recently, a broader range of software + applications. + + .. seealso:: + + port + a connection through which data is sent and received. + + .. seealso:: + + RFC + Request for Comments (RFC) documents are a series of memoranda + encompassing new research, innovations, and methodologies applicable to + Internet technologies. + + .. seealso:: + + RFC 1952 + GZIP file format specification version 4.3 + + .. seealso:: :rfc:`1952` + + Row (record, tuple) + represents a single, implicitly structured data item in a table. + + .. seealso:: + + Server + a computer system that provides services to other computing systems over a network. + + .. seealso:: + + Storage Engines + handlers for different table types + + .. seealso:: + + SOAP + Simple Object Access Protocol is a protocol specification for exchanging + structured information in the implementation of Web Services in computer + networks. + + .. seealso:: + + socket + a form of inter-process communication. + + .. seealso:: + + SSL + Secure Sockets Layer is a cryptographic protocol which provides secure + communication on the Internet. + + .. seealso:: + + Stored procedure + a subroutine available to applications accessing a relational database system + + .. seealso:: + + SQL + Structured Query Language + + .. seealso:: + + table + a set of data elements (cells) that is organized, defined and stored as + horizontal rows and vertical columns where each item can be uniquely + identified by a label or key or by it?s position in relation to other + items. + + .. seealso:: + + tar + a type of archive file format: the Tape ARchive format. + + .. seealso:: + + TCP + Transmission Control Protocol is one of the core protocols of the + Internet protocol suite. + + .. seealso:: + + TCPDF + Rewrite of :term:`UFPDF` with various improvements. + + .. seealso:: + + trigger + a procedural code that is automatically executed in response to certain events on a particular table or view in a database + + .. seealso:: + + UFPDF + Unicode/UTF-8 extension for :term:`FPDF` + + .. seealso:: + + URL + Uniform Resource Locator is a sequence of characters, conforming to a + standardized format, that is used for referring to resources, such as + documents and images on the Internet, by their location. + + .. seealso:: + + Webserver + A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages. + + .. seealso:: + + XML + Extensible Markup Language is a W3C-recommended general- purpose markup + language for creating special-purpose markup languages, capable of + describing many different kinds of data. + + .. seealso:: + + ZIP + a popular data compression and archival format. + + .. seealso:: + + zlib + an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler. + + .. seealso:: + + diff --git a/phpmyadmin/doc/html/.buildinfo b/phpmyadmin/doc/html/.buildinfo new file mode 100644 index 000000000..65e743185 --- /dev/null +++ b/phpmyadmin/doc/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 391ce1d2159bfa0058ee08a87344a0a5 +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/phpmyadmin/doc/html/_sources/config.txt b/phpmyadmin/doc/html/_sources/config.txt new file mode 100644 index 000000000..2b9ced27b --- /dev/null +++ b/phpmyadmin/doc/html/_sources/config.txt @@ -0,0 +1,2776 @@ +.. index:: config.inc.php + +.. _config: + +Configuration +============= + +Almost all configurable data is placed in :file:`config.inc.php`. If this file +does not exist, please refer to the :ref:`setup` section to create one. This +file only needs to contain the parameters you want to change from their +corresponding default value in :file:`libraries/config.default.php`. + +The parameters which relate to design (like colors) are placed in +:file:`themes/themename/layout.inc.php`. You might also want to create +:file:`config.footer.inc.php` and :file:`config.header.inc.php` files to add +your site specific code to be included on start and end of each page. + +.. note:: + + Some distributions (eg. Debian or Ubuntu) store :file:`config.inc.php` in + ``/etc/phpmyadmin`` instead of within phpMyAdmin sources. + +.. warning:: + + :term:`Mac` users should note that if you are on a version before + :term:`Mac OS X`, PHP does not seem to + like :term:`Mac` end of lines character (``\r``). So + ensure you choose the option that allows to use the \*nix end of line + character (``\n``) in your text editor before saving a script you have + modified. + +Basic settings +-------------- + +.. config:option:: $cfg['PmaAbsoluteUri'] + + :type: string + :default: ``''`` + + Sets here the complete :term:`URL` (with full path) to your phpMyAdmin + installation's directory. E.g. + ``http://www.example.net/path_to_your_phpMyAdmin_directory/``. Note also + that the :term:`URL` on some web servers are case–sensitive. Don’t forget + the trailing slash at the end. + + Starting with version 2.3.0, it is advisable to try leaving this blank. In + most cases phpMyAdmin automatically detects the proper setting. Users of + port forwarding will need to set :config:option:`$cfg['PmaAbsoluteUri']` + (`more info `_). + + A good test is to browse a table, edit a row and save it. There should be + an error message if phpMyAdmin is having trouble auto–detecting the correct + value. If you get an error that this must be set or if the autodetect code + fails to detect your path, please post a bug report on our bug tracker so + we can improve the code. + + .. seealso:: :ref:`faq1_40` + +.. config:option:: $cfg['PmaNoRelation_DisableWarning'] + + :type: boolean + :default: false + + Starting with version 2.3.0 phpMyAdmin offers a lot of features to + work with master / foreign – tables (see :config:option:`$cfg['Servers'][$i]['pmadb']`). + + If you tried to set this + up and it does not work for you, have a look on the :guilabel:`Structure` page + of one database where you would like to use it. You will find a link + that will analyze why those features have been disabled. + + If you do not want to use those features set this variable to ``true`` to + stop this message from appearing. + +.. config:option:: $cfg['SuhosinDisableWarning'] + + :type: boolean + :default: false + + A warning is displayed on the main page if Suhosin is detected. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['McryptDisableWarning'] + + :type: boolean + :default: false + + Disable the default warning that is displayed if mcrypt is missing for + cookie authentication. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['ServerLibraryDifference_DisableWarning'] + + :type: boolean + :default: false + + A warning is displayed on the main page if there is a difference + between the MySQL library and server version. + + You can set this parameter to ``true`` to stop this message from appearing. + +.. config:option:: $cfg['ReservedWordDisableWarning'] + + :type: boolean + :default: false + + This warning is displayed on the Structure page of a table if one or more + column names match with words which are MySQL reserved. + + If you want to turn off this warning, you can set it to ``true`` and + warning will not longer be displayed + +.. config:option:: $cfg['TranslationWarningThreshold'] + + :type: integer + :default: 80 + + Show warning about incomplete translations on certain threshold. + +Server connection settings +-------------------------- + +.. config:option:: $cfg['Servers'] + + :type: array + :default: one server array with settings listed bellow + + Since version 1.4.2, phpMyAdmin supports the administration of multiple + MySQL servers. Therefore, a :config:option:`$cfg['Servers']`-array has been + added which contains the login information for the different servers. The + first :config:option:`$cfg['Servers'][$i]['host']` contains the hostname of + the first server, the second :config:option:`$cfg['Servers'][$i]['host']` + the hostname of the second server, etc. In + :file:`libraries/config.default.php`, there is only one section for server + definition, however you can put as many as you need in + :file:`config.inc.php`, copy that block or needed parts (you don't have to + define all settings, just those you need to change). + + .. note:: + + The :config:option:`$cfg['Servers']` array starts with + $cfg['Servers'][1]. Do not use $cfg['Servers'][0]. If you want more + than one server, just copy following section (including $i + incrementation) serveral times. There is no need to define full server + array, just define values you need to change. + + +.. config:option:: $cfg['Servers'][$i]['host'] + + :type: string + :default: ``'localhost'`` + + The hostname or :term:`IP` address of your $i-th MySQL-server. E.g. + ``localhost``. + + Possible values are: + + * hostname, e.g., ``'localhost'`` or ``'mydb.example.org'`` + * IP address, e.g., ``'127.0.0.1'`` or ``'192.168.10.1'`` + * dot - ``'.'``, i.e., use named pipes on windows systems + * empty - ``''``, disables this server + +.. config:option:: $cfg['Servers'][$i]['port'] + + :type: string + :default: ``''`` + + The port-number of your $i-th MySQL-server. Default is 3306 (leave + blank). + + .. note:: + + If you use ``localhost`` as the hostname, MySQL ignores this port number + and connects with the socket, so if you want to connect to a port + different from the default port, use ``127.0.0.1`` or the real hostname + in :config:option:`$cfg['Servers'][$i]['host']`. + +.. config:option:: $cfg['Servers'][$i]['socket'] + + :type: string + :default: ``''`` + + The path to the socket to use. Leave blank for default. To determine + the correct socket, check your MySQL configuration or, using the + :command:`mysql` command–line client, issue the ``status`` command. Among the + resulting information displayed will be the socket used. + +.. config:option:: $cfg['Servers'][$i]['ssl'] + + :type: boolean + :default: false + + Whether to enable SSL for connection to MySQL server. + +.. config:option:: $cfg['Servers'][$i]['connect_type'] + + :type: string + :default: ``'tcp'`` + + What type connection to use with the MySQL server. Your options are + ``'socket'`` and ``'tcp'``. It defaults to tcp as that is nearly guaranteed + to be available on all MySQL servers, while sockets are not supported on + some platforms. To use the socket mode, your MySQL server must be on the + same machine as the Web server. + +.. config:option:: $cfg['Servers'][$i]['extension'] + + :type: string + :default: ``'mysqli'`` + + What php MySQL extension to use for the connection. Valid options are: + + ``mysql`` + The classic MySQL extension. + + ``mysqli`` + The improved MySQL extension. This extension became available with PHP + 5.0.0 and is the recommended way to connect to a server running MySQL + 4.1.x or newer. + +.. config:option:: $cfg['Servers'][$i]['compress'] + + :type: boolean + :default: false + + Whether to use a compressed protocol for the MySQL server connection + or not (experimental). + +.. _controlhost: +.. config:option:: $cfg['Servers'][$i]['controlhost'] + + :type: string + :default: ``''`` + + Permits to use an alternate host to hold the configuration storage + data. + +.. _controluser: +.. config:option:: $cfg['Servers'][$i]['controluser'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['Servers'][$i]['controlpass'] + + :type: string + :default: ``''`` + + This special account is used for 2 distinct purposes: to make possible all + relational features (see :config:option:`$cfg['Servers'][$i]['pmadb']`) and, + for a MySQL server running with ``--skip-show-database``, to enable a + multi-user installation (:term:`HTTP` or cookie + authentication mode). + + When using :term:`HTTP` or + cookie authentication modes (or 'config' authentication mode since phpMyAdmin + 2.2.1), you need to supply the details of a MySQL account that has ``SELECT`` + privilege on the *mysql.user (all columns except "Password")*, *mysql.db (all + columns)* and *mysql.tables\_priv (all columns except "Grantor" and + "Timestamp")* tables. This account is used to check what databases the user + will see at login. + + .. versionchanged:: 2.2.5 + those were called ``stduser`` and ``stdpass`` + + .. seealso:: :ref:`setup`, :ref:`authentication_modes` + +.. config:option:: $cfg['Servers'][$i]['auth_type'] + + :type: string + :default: ``'cookie'`` + + Whether config or cookie or :term:`HTTP` or signon authentication should be + used for this server. + + * 'config' authentication (``$auth_type = 'config'``) is the plain old + way: username and password are stored in :file:`config.inc.php`. + * 'cookie' authentication mode (``$auth_type = 'cookie'``) as + introduced in 2.2.3 allows you to log in as any valid MySQL user with + the help of cookies. Username and password are stored in cookies + during the session and password is deleted when it ends. This can also + allow you to log in in arbitrary server if :config:option:`$cfg['AllowArbitraryServer']` enabled. + * 'http' authentication (was + called 'advanced' in previous versions and can be written also as + 'http') (``$auth_type = 'http';'``) as introduced in 1.3.0 allows you to log in as any + valid MySQL user via HTTP-Auth. + * 'signon' authentication mode (``$auth_type = 'signon'``) as + introduced in 2.10.0 allows you to log in from prepared PHP session + data or using supplied PHP script. This is useful for implementing + single signon from another application. Sample way how to seed session + is in signon example: :file:`examples/signon.php`. There is also + alternative example using OpenID - :file:`examples/openid.php` and example + for scripts based solution - :file:`examples/signon-script.php`. You need + to configure :config:option:`$cfg['Servers'][$i]['SignonSession']` or + :config:option:`$cfg['Servers'][$i]['SignonScript']` and + :config:option:`$cfg['Servers'][$i]['SignonURL']` to use this authentication + method. + + .. seealso:: :ref:`authentication_modes` + +.. _servers_auth_http_realm: +.. config:option:: $cfg['Servers'][$i]['auth_http_realm'] + + :type: string + :default: ``''`` + + When using auth\_type = ``http``, this field allows to define a custom + :term:`HTTP` Basic Auth Realm which will be displayed to the user. If not + explicitly specified in your configuration, a string combined of + "phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or + :config:option:`$cfg['Servers'][$i]['host']` will be used. + +.. _servers_auth_swekey_config: +.. config:option:: $cfg['Servers'][$i]['auth_swekey_config'] + + :type: string + :default: ``''`` + + The name of the file containing :ref:`swekey` ids and login names for hardware + authentication. Leave empty to deactivate this feature. + +.. _servers_user: +.. config:option:: $cfg['Servers'][$i]['user'] + + :type: string + :default: ``'root'`` + +.. config:option:: $cfg['Servers'][$i]['password'] + + :type: string + :default: ``''`` + + When using :config:option:`$cfg['Servers'][$i]['auth_type']` set to + 'config', this is the user/password-pair which phpMyAdmin will use to + connect to the MySQL server. This user/password pair is not needed when + :term:`HTTP` or cookie authentication is used + and should be empty. + +.. _servers_nopassword: +.. config:option:: $cfg['Servers'][$i]['nopassword'] + + :type: boolean + :default: false + + Allow attempt to log in without password when a login with password + fails. This can be used together with http authentication, when + authentication is done some other way and phpMyAdmin gets user name + from auth and uses empty password for connecting to MySQL. Password + login is still tried first, but as fallback, no password method is + tried. + +.. _servers_only_db: +.. config:option:: $cfg['Servers'][$i]['only_db'] + + :type: string or array + :default: ``''`` + + If set to a (an array of) database name(s), only this (these) + database(s) will be shown to the user. Since phpMyAdmin 2.2.1, + this/these database(s) name(s) may contain MySQL wildcards characters + ("\_" and "%"): if you want to use literal instances of these + characters, escape them (I.E. use ``'my\_db'`` and not ``'my_db'``). + + This setting is an efficient way to lower the server load since the + latter does not need to send MySQL requests to build the available + database list. But **it does not replace the privileges rules of the + MySQL database server**. If set, it just means only these databases + will be displayed but **not that all other databases can't be used.** + + An example of using more that one database: + + .. code-block:: php + + $cfg['Servers'][$i]['only_db'] = array('db1', 'db2'); + + .. versionchanged:: 4.0.0 + Previous versions permitted to specify the display order of + the database names via this directive. + +.. config:option:: $cfg['Servers'][$i]['hide_db'] + + :type: string + :default: ``''`` + + Regular expression for hiding some databases from unprivileged users. + This only hides them from listing, but a user is still able to access + them (using, for example, the SQL query area). To limit access, use + the MySQL privilege system. For example, to hide all databases + starting with the letter "a", use + + .. code-block:: php + + $cfg['Servers'][$i]['hide_db'] = '^a'; + + and to hide both "db1" and "db2" use + + .. code-block:: php + + $cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$'; + + More information on regular expressions can be found in the `PCRE + pattern syntax + `_ portion + of the PHP reference manual. + +.. config:option:: $cfg['Servers'][$i]['verbose'] + + :type: string + :default: ``''`` + + Only useful when using phpMyAdmin with multiple server entries. If + set, this string will be displayed instead of the hostname in the + pull-down menu on the main page. This can be useful if you want to + show only certain databases on your system, for example. For HTTP + auth, all non-US-ASCII characters will be stripped. + +.. config:option:: $cfg['Servers'][$i]['pmadb'] + + :type: string + :default: ``''`` + + The name of the database containing the phpMyAdmin configuration + storage. + + See the :ref:`linked-tables` section in this document to see the benefits of + this feature, and for a quick way of creating this database and the needed + tables. + + If you are the only user of this phpMyAdmin installation, you can use your + current database to store those special tables; in this case, just put your + current database name in :config:option:`$cfg['Servers'][$i]['pmadb']`. For a + multi-user installation, set this parameter to the name of your central + database containing the phpMyAdmin configuration storage. + +.. _bookmark: +.. config:option:: $cfg['Servers'][$i]['bookmarktable'] + + :type: string + :default: ``''`` + + Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This + can be useful for queries you often run. To allow the usage of this + functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * enter the table name in :config:option:`$cfg['Servers'][$i]['bookmarktable']` + + +.. _relation: +.. config:option:: $cfg['Servers'][$i]['relation'] + + :type: string + :default: ``''`` + + Since release 2.2.4 you can describe, in a special 'relation' table, + which column is a key in another table (a foreign key). phpMyAdmin + currently uses this to + + * make clickable, when you browse the master table, the data values that + point to the foreign table; + * display in an optional tool-tip the "display column" when browsing the + master table, if you move the mouse to a column containing a foreign + key (use also the 'table\_info' table); (see :ref:`faqdisplay`) + * in edit/insert mode, display a drop-down list of possible foreign keys + (key value and "display column" are shown) (see :ref:`faq6_21`) + * display links on the table properties page, to check referential + integrity (display missing foreign keys) for each described key; + * in query-by-example, create automatic joins (see :ref:`faq6_6`) + * enable you to get a :term:`PDF` schema of + your database (also uses the table\_coords table). + + The keys can be numeric or character. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the relation table name in :config:option:`$cfg['Servers'][$i]['relation']` + * now as normal user open phpMyAdmin and for each one of your tables + where you want to use this feature, click :guilabel:`Structure/Relation view/` + and choose foreign columns. + + .. note:: + + In the current version, ``master_db`` must be the same as ``foreign_db``. + Those columns have been put in future development of the cross-db + relations. + +.. _table_info: +.. config:option:: $cfg['Servers'][$i]['table_info'] + + :type: string + :default: ``''`` + + Since release 2.3.0 you can describe, in a special 'table\_info' + table, which column is to be displayed as a tool-tip when moving the + cursor over the corresponding key. This configuration variable will + hold the name of this special table. To allow the usage of this + functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['table\_info']` (e.g. + ``pma__table_info``) + * then for each table where you want to use this feature, click + "Structure/Relation view/Choose column to display" to choose the + column. + + .. seealso:: :ref:`faqdisplay` + +.. _table_coords: +.. config:option:: $cfg['Servers'][$i]['table_coords'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['Servers'][$i]['pdf_pages'] + + :type: string + :default: ``''`` + + Since release 2.3.0 you can have phpMyAdmin create :term:`PDF` pages + showing the relations between your tables. To do this it needs two tables + "pdf\_pages" (storing information about the available :term:`PDF` pages) + and "table\_coords" (storing coordinates where each table will be placed on + a :term:`PDF` schema output). You must be using the "relation" feature. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the correct table names in + :config:option:`$cfg['Servers'][$i]['table\_coords']` and + :config:option:`$cfg['Servers'][$i]['pdf\_pages']` + + .. seealso:: :ref:`faqpdf`. + +.. _col_com: +.. config:option:: $cfg['Servers'][$i]['column_info'] + + :type: string + :default: ``''`` + + This part requires a content update! Since release 2.3.0 you can + store comments to describe each column for each table. These will then + be shown on the "printview". + + Starting with release 2.5.0, comments are consequently used on the table + property pages and table browse view, showing up as tool-tips above the + column name (properties page) or embedded within the header of table in + browse view. They can also be shown in a table dump. Please see the + relevant configuration directives later on. + + Also new in release 2.5.0 is a MIME- transformation system which is also + based on the following table structure. See :ref:`transformations` for + further information. To use the MIME- transformation system, your + column\_info table has to have the three new columns 'mimetype', + 'transformation', 'transformation\_options'. + + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['column\_info']` (e.g. + ``pma__column_info``) + * to update your PRE-2.5.0 Column\_comments Table use this: and + remember that the Variable in :file:`config.inc.php` has been renamed from + :config:option:`$cfg['Servers'][$i]['column\_comments']` to + :config:option:`$cfg['Servers'][$i]['column\_info']` + + .. code-block:: mysql + + ALTER TABLE `pma__column_comments` + ADD `mimetype` VARCHAR( 255 ) NOT NULL, + ADD `transformation` VARCHAR( 255 ) NOT NULL, + ADD `transformation_options` VARCHAR( 255 ) NOT NULL; + +.. _history: +.. config:option:: $cfg['Servers'][$i]['history'] + + :type: string + :default: ``''`` + + Since release 2.5.0 you can store your :term:`SQL` history, which means all + queries you entered manually into the phpMyAdmin interface. If you don't + want to use a table-based history, you can use the JavaScript-based + history. + + Using that, all your history items are deleted when closing the window. + Using :config:option:`$cfg['QueryHistoryMax']` you can specify an amount of + history items you want to have on hold. On every login, this list gets cut + to the maximum amount. + + The query history is only available if JavaScript is enabled in + your browser. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['history']` (e.g. + ``pma__history``) + +.. _recent: +.. config:option:: $cfg['Servers'][$i]['recent'] + + :type: string + :default: ``''`` + + Since release 3.5.0 you can show recently used tables in the + navigation panel. It helps you to jump across table directly, without + the need to select the database, and then select the table. Using + :config:option:`$cfg['NumRecentTables']` you can configure the maximum number + of recent tables shown. When you select a table from the list, it will jump to + the page specified in :config:option:`$cfg['NavigationTreeDefaultTabTable']`. + + + Without configuring the storage, you can still access the recently used tables, + but it will disappear after you logout. + + To allow the usage of this functionality persistently: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['recent']` (e.g. + ``pma__recent``) + +.. _table_uiprefs: +.. config:option:: $cfg['Servers'][$i]['table_uiprefs'] + + :type: string + :default: ``''`` + + Since release 3.5.0 phpMyAdmin can be configured to remember several + things (sorted column :config:option:`$cfg['RememberSorting']`, column order, + and column visibility from a database table) for browsing tables. Without + configuring the storage, these features still can be used, but the values will + disappear after you logout. + + To allow the usage of these functionality persistently: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['table\_uiprefs']` (e.g. + ``pma__table_uiprefs``) + + +.. _tracking: +.. config:option:: $cfg['Servers'][$i]['tracking'] + + :type: string + :default: ``''`` + + Since release 3.3.x a tracking mechanism is available. It helps you to + track every :term:`SQL` command which is + executed by phpMyAdmin. The mechanism supports logging of data + manipulation and data definition statements. After enabling it you can + create versions of tables. + + The creation of a version has two effects: + + * phpMyAdmin saves a snapshot of the table, including structure and + indexes. + * phpMyAdmin logs all commands which change the structure and/or data of + the table and links these commands with the version number. + + Of course you can view the tracked changes. On the :guilabel:`Tracking` + page a complete report is available for every version. For the report you + can use filters, for example you can get a list of statements within a date + range. When you want to filter usernames you can enter \* for all names or + you enter a list of names separated by ','. In addition you can export the + (filtered) report to a file or to a temporary database. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['tracking']` (e.g. + ``pma__tracking``) + + +.. _tracking2: +.. config:option:: $cfg['Servers'][$i]['tracking_version_auto_create'] + + :type: boolean + :default: false + + Whether the tracking mechanism creates versions for tables and views + automatically. + + If this is set to true and you create a table or view with + + * CREATE TABLE ... + * CREATE VIEW ... + + and no version exists for it, the mechanism will create a version for + you automatically. + +.. _tracking3: +.. config:option:: $cfg['Servers'][$i]['tracking_default_statements'] + + :type: string + :default: ``'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE'`` + + Defines the list of statements the auto-creation uses for new + versions. + +.. _tracking4: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_view'] + + :type: boolean + :default: true + + Whether a DROP VIEW IF EXISTS statement will be added as first line to + the log when creating a view. + +.. _tracking5: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_table'] + + :type: boolean + :default: true + + Whether a DROP TABLE IF EXISTS statement will be added as first line + to the log when creating a table. + +.. _tracking6: +.. config:option:: $cfg['Servers'][$i]['tracking_add_drop_database'] + + :type: boolean + :default: true + + Whether a DROP DATABASE IF EXISTS statement will be added as first + line to the log when creating a database. + +.. _userconfig: +.. config:option:: $cfg['Servers'][$i]['userconfig'] + + :type: string + :default: ``''`` + + Since release 3.4.x phpMyAdmin allows users to set most preferences by + themselves and store them in the database. + + If you don't allow for storing preferences in + :config:option:`$cfg['Servers'][$i]['pmadb']`, 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. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['userconfig']` + + + +.. _designer_coords: +.. config:option:: $cfg['Servers'][$i]['designer_coords'] + + :type: string + :default: ``''`` + + Since release 2.10.0 a Designer interface is available; it permits to + visually manage the relations. + + To allow the usage of this functionality: + + * set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage + * put the table name in :config:option:`$cfg['Servers'][$i]['designer\_coords']` + (e.g. ``pma__designer_coords``) + + + +.. config:option:: $cfg['Servers'][$i]['MaxTableUiprefs'] + + :type: integer + :default: 100 + + Maximum number of rows saved in + :config:option:`$cfg['Servers'][$i]['table_uiprefs']` table. + + When tables are dropped or renamed, + :config:option:`$cfg['Servers'][$i]['table_uiprefs']` may contain invalid data + (referring to tables which no longer exist). We only keep this number of newest + rows in :config:option:`$cfg['Servers'][$i]['table_uiprefs']` and automatically + delete older rows. + +.. config:option:: $cfg['Servers'][$i]['AllowRoot'] + + :type: boolean + :default: true + + Whether to allow root access. This is just a shortcut for the + :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` below. + +.. config:option:: $cfg['Servers'][$i]['AllowNoPassword'] + + :type: boolean + :default: false + + Whether to allow logins without a password. The default value of + ``false`` for this parameter prevents unintended access to a MySQL + server with was left with an empty password for root or on which an + anonymous (blank) user is defined. + +.. _servers_allowdeny_order: +.. config:option:: $cfg['Servers'][$i]['AllowDeny']['order'] + + :type: string + :default: ``''`` + + If your rule order is empty, then :term:`IP` + authorization is disabled. + + If your rule order is set to + ``'deny,allow'`` then the system applies all deny rules followed by + allow rules. Access is allowed by default. Any client which does not + match a Deny command or does match an Allow command will be allowed + access to the server. + + If your rule order is set to ``'allow,deny'`` + then the system applies all allow rules followed by deny rules. Access + is denied by default. Any client which does not match an Allow + directive or does match a Deny directive will be denied access to the + server. + + If your rule order is set to ``'explicit'``, authorization is + performed in a similar fashion to rule order 'deny,allow', with the + added restriction that your host/username combination **must** be + listed in the *allow* rules, and not listed in the *deny* rules. This + is the **most** secure means of using Allow/Deny rules, and was + available in Apache by specifying allow and deny rules without setting + any order. + + Please also see :config:option:`$cfg['TrustedProxies']` for + detecting IP address behind proxies. + +.. _servers_allowdeny_rules: +.. config:option:: $cfg['Servers'][$i]['AllowDeny']['rules'] + + :type: array of strings + :default: array() + + The general format for the rules is as such: + + .. code-block:: none + + <'allow' | 'deny'> [from] + + If you wish to match all users, it is possible to use a ``'%'`` as a + wildcard in the *username* field. + + There are a few shortcuts you can + use in the *ipmask* field as well (please note that those containing + SERVER\_ADDRESS might not be available on all webservers): + + .. code-block:: none + + + 'all' -> 0.0.0.0/0 + 'localhost' -> 127.0.0.1/8 + 'localnetA' -> SERVER_ADDRESS/8 + 'localnetB' -> SERVER_ADDRESS/16 + 'localnetC' -> SERVER_ADDRESS/24 + + Having an empty rule list is equivalent to either using ``'allow % + from all'`` if your rule order is set to ``'deny,allow'`` or ``'deny % + from all'`` if your rule order is set to ``'allow,deny'`` or + ``'explicit'``. + + For the :term:`IP address` matching + system, the following work: + + * ``xxx.xxx.xxx.xxx`` (an exact :term:`IP address`) + * ``xxx.xxx.xxx.[yyy-zzz]`` (an :term:`IP address` range) + * ``xxx.xxx.xxx.xxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IP` addresses) + + But the following does not work: + + * ``xxx.xxx.xxx.xx[yyy-zzz]`` (partial :term:`IP` address range) + + For :term:`IPv6` addresses, the following work: + + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx`` (an exact :term:`IPv6` address) + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz]`` (an :term:`IPv6` address range) + * ``xxxx:xxxx:xxxx:xxxx/nn`` (CIDR, Classless Inter-Domain Routing type :term:`IPv6` addresses) + + But the following does not work: + + * ``xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz]`` (partial :term:`IPv6` address range) + +.. config:option:: $cfg['Servers'][$i]['DisableIS'] + + :type: boolean + :default: true + + Disable using ``INFORMATION_SCHEMA`` to retrieve information (use + ``SHOW`` commands instead), because of speed issues when many + databases are present. Currently used in some parts of the code, more + to come. + +.. config:option:: $cfg['Servers'][$i]['ShowDatabasesCommand'] + + :type: string + :default: ``'SHOW DATABASES'`` + + On a server with a huge number of databases, the default ``SHOW DATABASES`` + command used to fetch the name of available databases will probably be too + slow, so it can be replaced by faster commands. You can use ``#user#`` + string will be replaced by current user. + + When using ``false``, it will disable fetching databases from the server, + only databases in :config:option:`$cfg['Servers'][$i]['only_db']` will be + displayed. + + Examples: + + * ``'SHOW DATABASES'`` + * ``"SHOW DATABASES LIKE '#user#\_%'"`` + * ``'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'`` + * ``'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'`` + * ``false`` + +.. config:option:: $cfg['Servers'][$i]['SignonScript'] + + :type: string + :default: ``''`` + + Name of PHP script to be sourced and executed to obtain login + credentials. This is alternative approach to session based single + signon. The script needs to provide function + ``get_login_credentials`` which returns list of username and + password, accepting single parameter of existing username (can be + empty). See :file:`examples/signon-script.php` for an example. + +.. config:option:: $cfg['Servers'][$i]['SignonSession'] + + :type: string + :default: ``''`` + + Name of session which will be used for signon authentication method. + You should use something different than ``phpMyAdmin``, because this + is session which phpMyAdmin uses internally. Takes effect only if + :config:option:`$cfg['Servers'][$i]['SignonScript']` is not configured. + +.. config:option:: $cfg['Servers'][$i]['SignonURL'] + + :type: string + :default: ``''`` + + :term:`URL` where user will be redirected + to log in for signon authentication method. Should be absolute + including protocol. + +.. config:option:: $cfg['Servers'][$i]['LogoutURL'] + + :type: string + :default: ``''`` + + :term:`URL` where user will be redirected + after logout (doesn't affect config authentication method). Should be + absolute including protocol. + +.. config:option:: $cfg['Servers'][$i]['StatusCacheDatabases'] + + :type: array of strings + :default: array() + + Enables caching of ``TABLE STATUS`` outputs for specific databases on + this server (in some cases ``TABLE STATUS`` can be very slow, so you + may want to cache it). APC is used (if the PHP extension is available, + if not, this setting is ignored silently). You have to provide + :config:option:`$cfg['Servers'][$i]['StatusCacheLifetime']`. + + Takes effect only if :config:option:`$cfg['Servers'][$i]['DisableIS']` is + ``true``. + +.. config:option:: $cfg['Servers'][$i]['StatusCacheLifetime'] + + :type: integer + :default: 0 + + Lifetime in seconds of the ``TABLE STATUS`` cache if + :config:option:`$cfg['Servers'][$i]['StatusCacheDatabases']` is used. + +Generic settings +---------------- + +.. config:option:: $cfg['ServerDefault'] + + :type: integer + :default: 1 + + If you have more than one server configured, you can set + :config:option:`$cfg['ServerDefault']` to any one of them to autoconnect to that + server when phpMyAdmin is started, or set it to 0 to be given a list + of servers without logging in. + + If you have only one server configured, + :config:option:`$cfg['ServerDefault']` MUST be set to that server. + +.. config:option:: $cfg['VersionCheck'] + + :type: boolean + :default: true + + Enables check for latest versions using javascript on main phpMyAdmin + page. + + .. note:: + + This setting can be adjusted by your vendor. + +.. config:option:: $cfg['MaxDbList'] + + :type: integer + :default: 100 + + The maximum number of database names to be displayed in the main panel's + database list. + +.. config:option:: $cfg['MaxNavigationItems'] + + :type: integer + :default: 25 + + The number of items that can be displayed on each page of the + navigation tree. + +.. config:option:: $cfg['MaxTableList'] + + :type: integer + :default: 250 + + The maximum number of table names to be displayed in the main panel's + list (except on the Export page). This limit is also enforced in the + navigation panel when in Light mode. + +.. config:option:: $cfg['ShowHint'] + + :type: boolean + :default: true + + Whether or not to show hints (for example, hints when hovering over + table headers). + +.. config:option:: $cfg['MaxCharactersInDisplayedSQL'] + + :type: integer + :default: 1000 + + The maximum number of characters when a :term:`SQL` query is displayed. The + default limit of 1000 should be correct to avoid the display of tons of + hexadecimal codes that represent BLOBs, but some users have real + :term:`SQL` queries that are longer than 1000 characters. Also, if a + query's length exceeds this limit, this query is not saved in the history. + +.. config:option:: $cfg['PersistentConnections'] + + :type: boolean + :default: false + + Whether `persistent connections `_ should be used or not. Works with + following extensions: + + * mysql (`mysql\_pconnect `_), + * mysqli (requires PHP 5.3.0 or newer, `more information + `_). + +.. config:option:: $cfg['ForceSSL'] + + :type: boolean + :default: false + + Whether to force using https while accessing phpMyAdmin. + +.. config:option:: $cfg['ExecTimeLimit'] + + :type: integer [number of seconds] + :default: 300 + + Set the number of seconds a script is allowed to run. If seconds is + set to zero, no time limit is imposed. This setting is used while + importing/exporting dump files but has + no effect when PHP is running in safe mode. + +.. config:option:: $cfg['SessionSavePath'] + + :type: string + :default: ``''`` + + Path for storing session data (`session\_save\_path PHP parameter + `_). + +.. config:option:: $cfg['MemoryLimit'] + + :type: string [number of bytes] + :default: ``'0'`` + + Set the number of bytes a script is allowed to allocate. If set to + zero, no limit is imposed. + + This setting is used while importing/exporting dump files and at some other + places in phpMyAdmin so you definitely don't want to put here a too low + value. It has no effect when PHP is running in safe mode. + + You can also use any string as in :file:`php.ini`, eg. '16M'. Ensure you + don't omit the suffix (16 means 16 bytes!) + +.. config:option:: $cfg['SkipLockedTables'] + + :type: boolean + :default: false + + Mark used tables and make it possible to show databases with locked + tables (since MySQL 3.23.30). + +.. config:option:: $cfg['ShowSQL'] + + :type: boolean + :default: true + + Defines whether :term:`SQL` queries + generated by phpMyAdmin should be displayed or not. + +.. config:option:: $cfg['RetainQueryBox'] + + :type: boolean + :default: false + + Defines whether the :term:`SQL` query box + should be kept displayed after its submission. + +.. config:option:: $cfg['CodemirrorEnable'] + + :type: boolean + :default: true + + Defines whether to use a Javascript code editor for SQL query boxes. + CodeMirror provides syntax highlighting and line numbers. However, + middle-clicking for pasting the clipboard contents in some Linux + distributions (such as Ubuntu) is not supported by all browsers. + +.. config:option:: $cfg['AllowUserDropDatabase'] + + :type: boolean + :default: false + + Defines whether normal users (non-administrator) are allowed to delete + their own database or not. If set as false, the link :guilabel:`Drop + Database` will not be shown, and even a ``DROP DATABASE mydatabase`` will + be rejected. Quite practical for :term:`ISP` 's with many customers. + + .. note:: + + This limitation of :term:`SQL` queries is not + as strict as when using MySQL privileges. This is due to nature of + :term:`SQL` queries which might be quite + complicated. So this choice should be viewed as help to avoid accidental + dropping rather than strict privilege limitation. + +.. config:option:: $cfg['Confirm'] + + :type: boolean + :default: true + + Whether a warning ("Are your really sure...") should be displayed when + you're about to lose data. + +.. config:option:: $cfg['UseDbSearch'] + + :type: boolean + :default: true + + Define whether the "search string inside database" is enabled or not. + +.. config:option:: $cfg['IgnoreMultiSubmitErrors'] + + :type: boolean + :default: false + + Define whether phpMyAdmin will continue executing a multi-query + statement if one of the queries fails. Default is to abort execution. + +Cookie authentication options +----------------------------- + +.. config:option:: $cfg['blowfish_secret'] + + :type: string + :default: ``''`` + + The "cookie" auth\_type uses blowfish algorithm to encrypt the + password. If you are using the "cookie" auth\_type, enter here a + random passphrase of your choice. It will be used internally by the + blowfish algorithm: you won’t be prompted for this passphrase. There + is no maximum length for this secret. + + .. versionchanged:: 3.1.0 + Since version 3.1.0 phpMyAdmin can generate this on the fly, but it + makes a bit weaker security as this generated secret is stored in + session and furthermore it makes impossible to recall user name from + cookie. + +.. config:option:: $cfg['LoginCookieRecall'] + + :type: boolean + :default: true + + Define whether the previous login should be recalled or not in cookie + authentication mode. + + This is automatically disabled if you do not have + configured :config:option:`$cfg['blowfish_secret']`. + +.. config:option:: $cfg['LoginCookieValidity'] + + :type: integer [number of seconds] + :default: 1440 + + Define how long a login cookie is valid. Please note that php + configuration option `session.gc\_maxlifetime + `_ might limit session validity and if the session is lost, + the login cookie is also invalidated. So it is a good idea to set + ``session.gc_maxlifetime`` at least to the same value of + :config:option:`$cfg['LoginCookieValidity']`. + +.. config:option:: $cfg['LoginCookieStore'] + + :type: integer [number of seconds] + :default: 0 + + Define how long login cookie should be stored in browser. Default 0 + means that it will be kept for existing session. This is recommended + for not trusted environments. + +.. config:option:: $cfg['LoginCookieDeleteAll'] + + :type: boolean + :default: true + + If enabled (default), logout deletes cookies for all servers, + otherwise only for current one. Setting this to false makes it easy to + forget to log out from other server, when you are using more of them. + +.. _AllowArbitraryServer: +.. config:option:: $cfg['AllowArbitraryServer'] + + :type: boolean + :default: false + + If enabled, allows you to log in to arbitrary servers using cookie + authentication. + + .. note:: + + Please use this carefully, as this may allow users access to MySQL servers + behind the firewall where your :term:`HTTP` + server is placed. + +Navigation panel setup +---------------------- + +.. config:option:: $cfg['NavigationTreeEnableGrouping'] + + :type: boolean + :default: true + + Defines whether to group the databases based on a common prefix + in their name :config:option:`$cfg['NavigationTreeDbSeparator']`. + +.. config:option:: $cfg['NavigationTreeDbSeparator'] + + :type: string or array + :default: ``'_'`` + + The string used to separate the parts of the database name when + showing them in a tree. Alternatively you can specify more strings in + an array and all of them will be used as a separator. + +.. config:option:: $cfg['NavigationTreeTableSeparator'] + + :type: string or array + :default: ``'__'`` + + Defines a string to be used to nest table spaces. This means if you have + tables like ``first__second__third`` this will be shown as a three-level + hierarchy like: first > second > third. If set to false or empty, the + feature is disabled. NOTE: You should not use this separator at the + beginning or end of a table name or multiple times after another without + any other characters in between. + +.. config:option:: $cfg['NavigationTreeTableLevel'] + + :type: integer + :default: 1 + + Defines how many sublevels should be displayed when splitting up + tables by the above separator. + +.. config:option:: $cfg['NumRecentTables'] + + :type: integer + :default: 10 + + The maximum number of recently used tables shown in the navigation + panel. Set this to 0 (zero) to disable the listing of recent tables. + +.. config:option:: $cfg['ShowTooltip'] + + :type: boolean + :default: true + + Defines whether to display item comments as tooltips in navigation + panel or not. + +.. config:option:: $cfg['NavigationDisplayLogo'] + + :type: boolean + :default: true + + Defines whether or not to display the phpMyAdmin logo at the top of + the navigation panel. + +.. config:option:: $cfg['NavigationLogoLink'] + + :type: string + :default: ``'index.php'`` + + Enter :term:`URL` where logo in the + navigation panel will point to. For use especially with self made + theme which changes this. + +.. config:option:: $cfg['NavigationLogoLinkWindow'] + + :type: string + :default: ``'main'`` + + Whether to open the linked page in the main window (``main``) or in a + new one (``new``). Note: use ``new`` if you are linking to + ``phpmyadmin.net``. + +.. config:option:: $cfg['NavigationTreeDisplayItemFilterMinimum'] + + :type: integer + :default: 30 + + Defines the minimum number of items (tables, views, routines and + events) to display a JavaScript filter box above the list of items in + the navigation tree. + + To disable the filter completely some high number can be used (e.g. 9999) + +.. config:option:: $cfg['NavigationTreeDisplayDbFilterMinimum'] + + :type: integer + :default: 30 + + Defines the minimum number of databases to display a JavaScript filter + box above the list of databases in the navigation tree. + + To disable the filter completely some high number can be used + (e.g. 9999) + +.. config:option:: $cfg['NavigationDisplayServers'] + + :type: boolean + :default: true + + Defines whether or not to display a server choice at the top of the + navigation panel. + +.. config:option:: $cfg['DisplayServersList'] + + :type: boolean + :default: false + + Defines whether to display this server choice as links instead of in a + drop-down. + +.. config:option:: $cfg['NavigationTreeDefaultTabTable'] + + :type: string + :default: ``'tbl_structure.php'`` + + Defines the tab displayed by default when clicking the small icon next + to each table name in the navigation panel. Possible values: + + * ``tbl_structure.php`` + * ``tbl_sql.php`` + * ``tbl_select.php`` + * ``tbl_change.php`` + * ``sql.php`` + +Main panel +---------- + +.. config:option:: $cfg['ShowStats'] + + :type: boolean + :default: true + + Defines whether or not to display space usage and statistics about + databases and tables. Note that statistics requires at least MySQL + 3.23.3 and that, at this date, MySQL doesn't return such information + for Berkeley DB tables. + +.. config:option:: $cfg['ShowServerInfo'] + + :type: boolean + :default: true + + Defines whether to display detailed server information on main page. + You can additionally hide more information by using + :config:option:`$cfg['Servers'][$i]['verbose']`. + +.. config:option:: $cfg['ShowPhpInfo'] + + :type: boolean + :default: false + +.. config:option:: $cfg['ShowChgPassword'] + + :type: boolean + :default: true + +.. config:option:: $cfg['ShowCreateDb'] + + :type: boolean + :default: true + + Defines whether to display the :guilabel:`PHP information` and + :guilabel:`Change password` links and form for creating database or not at + the starting main (right) frame. This setting does not check MySQL commands + entered directly. + + Please note that to block the usage of ``phpinfo()`` in scripts, you have to + put this in your :file:`php.ini`: + + .. code-block:: ini + + disable_functions = phpinfo() + + Also note that enabling the :guilabel:`Change password` link has no effect + with config authentication mode: because of the hard coded password value + in the configuration file, end users can't be allowed to change their + passwords. + +Database structure +------------------ + +.. config:option:: $cfg['ShowDbStructureCreation'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a + "Creation" column that displays when each table was created. + +.. config:option:: $cfg['ShowDbStructureLastUpdate'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a "Last + update" column that displays when each table was last updated. + +.. config:option:: $cfg['ShowDbStructureLastCheck'] + + :type: boolean + :default: false + + Defines whether the database structure page (tables list) has a "Last + check" column that displays when each table was last checked. + +.. config:option:: $cfg['HideStructureActions'] + + :type: boolean + :default: true + + Defines whether the table structure actions are hidden under a "More" + drop-down. + +Browse mode +----------- + +.. config:option:: $cfg['NavigationBarIconic'] + + :type: string + :default: true + + Defines whether navigation bar buttons contain text or symbols only. A + value of true displays icons, false displays text and 'both' displays + both icons and text. + +.. config:option:: $cfg['ShowAll'] + + :type: boolean + :default: false + + Defines whether a user should be displayed a "Show all" button in + browse mode or not in all cases. By default it is shown only on small + tables (less than 5 × :config:option:`$cfg['MaxRows']` rows) to avoid + performance issues while getting too many rows. + +.. config:option:: $cfg['MaxRows'] + + :type: integer + :default: 30 + + Number of rows displayed when browsing a result set and no LIMIT + clause is used. If the result set contains more rows, "Previous" and + "Next" links will be shown. + +.. config:option:: $cfg['Order'] + + :type: string + :default: ``'SMART'`` + + Defines whether columns are displayed in ascending (``ASC``) order, in + descending (``DESC``) order or in a "smart" (``SMART``) order - I.E. + descending order for columns of type TIME, DATE, DATETIME and + TIMESTAMP, ascending order else- by default. + +.. config:option:: $cfg['DisplayBinaryAsHex'] + + :type: boolean + :default: true + + Defines whether the "Show binary contents as HEX" browse option is + ticked by default. + +.. config:option:: $cfg['GridEditing'] + + :type: string + :default: ``'double-click'`` + + Defines which action (``double-click`` or ``click``) triggers grid + editing. Can be deactived with the ``disabled`` value. + +.. config:option:: $cfg['SaveCellsAtOnce'] + + :type: boolean + :default: false + + Defines whether or not to save all edited cells at once for grid + editing. + +Editing mode +------------ + +.. config:option:: $cfg['ProtectBinary'] + + :type: boolean or string + :default: ``'blob'`` + + Defines whether ``BLOB`` or ``BINARY`` columns are protected from + editing when browsing a table's content. Valid values are: + + * ``false`` to allow editing of all columns; + * ``'blob'`` to allow editing of all columns except ``BLOBS``; + * ``'noblob'`` to disallow editing of all columns except ``BLOBS`` (the + opposite of ``'blob'``); + * ``'all'`` to disallow editing of all ``BINARY`` or ``BLOB`` columns. + +.. config:option:: $cfg['ShowFunctionFields'] + + :type: boolean + :default: true + + Defines whether or not MySQL functions fields should be initially + displayed in edit/insert mode. Since version 2.10, the user can toggle + this setting from the interface. + +.. config:option:: $cfg['ShowFieldTypesInDataEditView'] + + :type: boolean + :default: true + + Defines whether or not type fields should be initially displayed in + edit/insert mode. The user can toggle this setting from the interface. + +.. config:option:: $cfg['InsertRows'] + + :type: integer + :default: 2 + + Defines the maximum number of concurrent entries for the Insert page. + +.. config:option:: $cfg['ForeignKeyMaxLimit'] + + :type: integer + :default: 100 + + If there are fewer items than this in the set of foreign keys, then a + drop-down box of foreign keys is presented, in the style described by + the :config:option:`$cfg['ForeignKeyDropdownOrder']` setting. + +.. config:option:: $cfg['ForeignKeyDropdownOrder'] + + :type: array + :default: array('content-id', 'id-content') + + For the foreign key drop-down fields, there are several methods of + display, offering both the key and value data. The contents of the + array should be one or both of the following strings: ``content-id``, + ``id-content``. + +Export and import settings +-------------------------- + +.. config:option:: $cfg['ZipDump'] + + :type: boolean + :default: true + +.. config:option:: $cfg['GZipDump'] + + :type: boolean + :default: true + +.. config:option:: $cfg['BZipDump'] + + :type: boolean + :default: true + + Defines whether to allow the use of zip/GZip/BZip2 compression when + creating a dump file + +.. config:option:: $cfg['CompressOnFly'] + + :type: boolean + :default: true + + Defines whether to allow on the fly compression for GZip/BZip2 + compressed exports. This doesn't affect smaller dumps and allows users + to create larger dumps that won't otherwise fit in memory due to php + memory limit. Produced files contain more GZip/BZip2 headers, but all + normal programs handle this correctly. + +.. config:option:: $cfg['Export'] + + :type: array + :default: array(...) + + In this array are defined default parameters for export, names of + items are similar to texts seen on export page, so you can easily + identify what they mean. + +.. config:option:: $cfg['Export']['method'] + + :type: string + :default: ``'quick'`` + + Defines how the export form is displayed when it loads. Valid values + are: + + * ``quick`` to display the minimum number of options to configure + * ``custom`` to display every available option to configure + * ``custom-no-form`` same as ``custom`` but does not display the option + of using quick export + + + +.. config:option:: $cfg['Import'] + + :type: array + :default: array(...) + + In this array are defined default parameters for import, names of + items are similar to texts seen on import page, so you can easily + identify what they mean. + + +Tabs display settings +--------------------- + +.. config:option:: $cfg['PropertiesIconic'] + + :type: string + :default: ``'both'`` + + If set to ``true``, will display icons instead of text for db and table + properties links (like :guilabel:`Browse`, :guilabel:`Select`, + :guilabel:`Insert`, ...) and for the menu tabs. Can be set to ``'both'`` + if you want icons AND text. When set to ``false``, will only show text. + +.. config:option:: $cfg['PropertiesNumColumns'] + + :type: integer + :default: 1 + + How many columns will be utilized to display the tables on the database + property view? When setting this to a value larger than 1, the type of the + database will be omitted for more display space. + +.. config:option:: $cfg['DefaultTabServer'] + + :type: string + :default: ``'index.php'`` + + Defines the tab displayed by default on server view. Possible values: + + * ``main.php`` (recommended for multi-user setups) + * ``server_databases.php``, + * ``server_status.php`` + * ``server_variables.php`` + * ``server_privileges.php`` + +.. config:option:: $cfg['DefaultTabDatabase'] + + :type: string + :default: ``'db_structure.php'`` + + Defines the tab displayed by default on database view. Possible + values: + + * ``db_structure.php`` + * ``db_sql.php`` + * ``db_search.php``. + +.. config:option:: $cfg['DefaultTabTable'] + + :type: string + :default: ``'sql.php'`` + + Defines the tab displayed by default on table view. Possible values: + + * ``tbl_structure.php`` + * ``tbl_sql.php`` + * ``tbl_select.php`` + * ``tbl_change.php`` + * ``sql.php`` + +Documentation +------------- + +.. config:option:: $cfg['MySQLManualBase'] + + :type: string + :default: ``'http://dev.mysql.com/doc/refman'`` + + If set to an :term:`URL` which points to + the MySQL documentation (type depends on + :config:option:`$cfg['MySQLManualType']`), appropriate help links are + generated. + + See `MySQL Documentation page `_ for more + information about MySQL manuals and their types. + +.. config:option:: $cfg['MySQLManualType'] + + :type: string + :default: ``'viewable'`` + + Type of MySQL documentation: + + * viewable - "viewable online", current one used on MySQL website + * searchable - "Searchable, with user comments" + * chapters - "HTML, one page per chapter" + * big - "HTML, all on one page" + * none - do not show documentation links + +Languages +--------- + +.. config:option:: $cfg['DefaultLang'] + + :type: string + :default: ``'en'`` + + Defines the default language to use, if not browser-defined or user- + defined. The corresponding language file needs to be in + locale/*code*/LC\_MESSAGES/phpmyadmin.mo. + +.. config:option:: $cfg['DefaultConnectionCollation'] + + :type: string + :default: ``'utf8_general_ci'`` + + Defines the default connection collation to use, if not user-defined. + See the `MySQL documentation `_ for list of possible values. This setting is + ignored when connected to Drizzle server. + +.. config:option:: $cfg['Lang'] + + :type: string + :default: not set + + Force language to use. The corresponding language file needs to be in + locale/*code*/LC\_MESSAGES/phpmyadmin.mo. + +.. config:option:: $cfg['FilterLanguages'] + + :type: string + :default: ``''`` + + Limit list of available languages to those matching the given regular + expression. For example if you want only Czech and English, you should + set filter to ``'^(cs|en)'``. + +.. config:option:: $cfg['RecodingEngine'] + + :type: string + :default: ``'auto'`` + + You can select here which functions will be used for character set + conversion. Possible values are: + + * auto - automatically use available one (first is tested iconv, then + recode) + * iconv - use iconv or libiconv functions + * recode - use recode\_string function + * none - disable encoding conversion + + Enabled charset conversion activates a pull-down menu in the Export + and Import pages, to choose the character set when exporting a file. + The default value in this menu comes from + :config:option:`$cfg['Export']['charset']` and :config:option:`$cfg['Import']['charset']`. + +.. config:option:: $cfg['IconvExtraParams'] + + :type: string + :default: ``'//TRANSLIT'`` + + Specify some parameters for iconv used in charset conversion. See + `iconv documentation `_ for details. By default + ``//TRANSLIT`` is used, so that invalid characters will be + transliterated. + +.. config:option:: $cfg['AvailableCharsets'] + + :type: array + :default: array(..._ + + Available character sets for MySQL conversion. You can add your own + (any of supported by recode/iconv) or remove these which you don't + use. Character sets will be shown in same order as here listed, so if + you frequently use some of these move them to the top. + +Web server settings +------------------- + +.. config:option:: $cfg['OBGzip'] + + :type: string/boolean + :default: ``'auto'`` + + Defines whether to use GZip output buffering for increased speed in + :term:`HTTP` transfers. Set to + true/false for enabling/disabling. When set to 'auto' (string), + phpMyAdmin tries to enable output buffering and will automatically + disable it if your browser has some problems with buffering. IE6 with + a certain patch is known to cause data corruption when having enabled + buffering. + +.. config:option:: $cfg['TrustedProxies'] + + :type: array + :default: array() + + Lists proxies and HTTP headers which are trusted for + :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']`. This list is by + default empty, you need to fill in some trusted proxy servers if you + want to use rules for IP addresses behind proxy. + + 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: + + .. code-block:: php + + $cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR'); + + The :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` directive uses the + client's IP address as usual. + +.. config:option:: $cfg['GD2Available'] + + :type: string + :default: ``'auto'`` + + Specifies whether GD >= 2 is available. If yes it can be used for MIME + transformations. Possible values are: + + * auto - automatically detect + * yes - GD 2 functions can be used + * no - GD 2 function cannot be used + +.. config:option:: $cfg['CheckConfigurationPermissions'] + + :type: boolean + :default: true + + We normally check the permissions on the configuration file to ensure + it's not world writable. However, phpMyAdmin could be installed on a + NTFS filesystem mounted on a non-Windows server, in which case the + permissions seems wrong but in fact cannot be detected. In this case a + sysadmin would set this parameter to ``false``. + +.. config:option:: $cfg['LinkLengthLimit'] + + :type: integer + :default: 1000 + + Limit for length of :term:`URL` in links. When length would be above this + limit, it is replaced by form with button. This is required as some web + servers (:term:`IIS`) have problems with long :term:`URL` . + +.. config:option:: $cfg['CSPAllow'] + + :type: string + :default: ``''`` + + Additional string to include in allowed script sources in Content Security + Policy header. + + This can be useful when you want to include some external javascript files + in :file:`config.footer.inc.php` or :file:`config.header.inc.php`, which + would be normally not allowed by Content Security Policy. + +.. config:option:: $cfg['DisableMultiTableMaintenance'] + + :type: boolean + :default: false + + In the database Structure page, it's possible to mark some tables then + choose an operation like optimizing for many tables. This can slow + down a server; therefore, setting this to ``true`` prevents this kind + of multiple maintenance operation. + +Theme settings +-------------- + +.. config:option:: $cfg['NaviWidth'] + + :type: integer + :default: + + Navigation panel width in pixels. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['NaviBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['MainBackground'] + + :type: string [CSS color for background] + :default: + + The background styles used for both the frames. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['NaviPointerBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['NaviPointerColor'] + + :type: string [CSS color] + :default: + + The style used for the pointer in the navi frame. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['Border'] + + :type: integer + :default: + + The size of a table's border. See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['ThBackground'] + + :type: string [CSS color for background] + :default: + +.. config:option:: $cfg['ThColor'] + + :type: string [CSS color] + :default: + + The style used for table headers. See + :file:`themes/themename/layout.inc.php`. + +.. _cfg_BgcolorOne: +.. config:option:: $cfg['BgOne'] + + :type: string [CSS color] + :default: + + The color (HTML) #1 for table rows. See + :file:`themes/themename/layout.inc.php`. + +.. _cfg_BgcolorTwo: +.. config:option:: $cfg['BgTwo'] + + :type: string [CSS color] + :default: + + The color (HTML) #2 for table rows. See + :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['BrowsePointerBackground'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowsePointerColor'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowseMarkerBackground'] + + :type: string [CSS color] + :default: + +.. config:option:: $cfg['BrowseMarkerColor'] + + :type: string [CSS color] + :default: + + The colors (HTML) uses for the pointer and the marker in browse mode. + The former feature highlights the row over which your mouse is passing + and the latter lets you visually mark/unmark rows by clicking on the + corresponding checkbox. Highlighting / marking a column is done by + hovering over / clicking the column's header (outside of the text). + See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['FontFamily'] + + :type: string + :default: + + You put here a valid CSS font family value, for example ``arial, sans- + serif``. See :file:`themes/themename/layout.inc.php`. + +.. config:option:: $cfg['FontFamilyFixed'] + + :type: string + :default: + + You put here a valid CSS font family value, for example ``monospace``. + This one is used in textarea. See :file:`themes/themename/layout.inc.php`. + +Design customization +-------------------- + +.. config:option:: $cfg['NavigationTreePointerEnable'] + + :type: boolean + :default: true + + A value of ``true`` activates the navi pointer. + +.. config:option:: $cfg['BrowsePointerEnable'] + + :type: boolean + :default: true + + Whether to activate the browse pointer or not. + +.. config:option:: $cfg['BrowseMarkerEnable'] + + :type: boolean + :default: true + + Whether to activate the browse marker or not. + +.. config:option:: $cfg['LimitChars'] + + :type: integer + :default: 50 + + Maximum number of characters shown in any non-numeric field on browse + view. Can be turned off by a toggle button on the browse page. + +.. config:option:: $cfg['RowActionLinks'] + + :type: string + :default: ``'left'`` + + Defines the place where table row links (Edit, Copy, Delete) would be + put when tables contents are displayed (you may have them displayed at + the left side, right side, both sides or nowhere). "left" and "right" + are parsed as "top" and "bottom" with vertical display mode. + +.. config:option:: $cfg['DefaultDisplay'] + + :type: string + :default: ``'horizonta'`` + + There are 3 display modes: horizontal, horizontalflipped and vertical. + Define which one is displayed by default. The first mode displays each + row on a horizontal line, the second rotates the headers by 90 + degrees, so you can use descriptive headers even though columns only + contain small values and still print them out. The vertical mode sorts + each row on a vertical lineup. + +.. config:option:: $cfg['RememberSorting'] + + :type: boolean + :default: true + + If enabled, remember the sorting of each table when browsing them. + +.. config:option:: $cfg['HeaderFlipType'] + + :type: string + :default: ``'auto'`` + + The HeaderFlipType can be set to 'auto', 'css' or 'fake'. When using + 'css' the rotation of the header for horizontalflipped is done via + CSS. The CSS transformation currently works only in Internet + Explorer.If set to 'fake' PHP does the transformation for you, but of + course this does not look as good as CSS. The 'auto' option enables + CSS transformation when browser supports it and use PHP based one + otherwise. + +.. config:option:: $cfg['ShowBrowseComments'] + + :type: boolean + :default: true + +.. config:option:: $cfg['ShowPropertyComments'] + + :type: boolean + :default: true + + By setting the corresponding variable to ``true`` you can enable the + display of column comments in Browse or Property display. In browse + mode, the comments are shown inside the header. In property mode, + comments are displayed using a CSS-formatted dashed-line below the + name of the column. The comment is shown as a tool-tip for that + column. + +Text fields +----------- + +.. config:option:: $cfg['CharEditing'] + + :type: string + :default: ``'input'`` + + Defines which type of editing controls should be used for CHAR and + VARCHAR columns. Possible values are: + + * input - this allows to limit size of text to size of columns in MySQL, + but has problems with newlines in columns + * textarea - no problems with newlines in columns, but also no length + limitations + +.. config:option:: $cfg['MinSizeForInputField'] + + :type: integer + :default: 4 + + Defines the minimum size for input fields generated for CHAR and + VARCHAR columns. + +.. config:option:: $cfg['MaxSizeForInputField'] + + :type: integer + :default: 60 + + Defines the maximum size for input fields generated for CHAR and + VARCHAR columns. + +.. config:option:: $cfg['TextareaCols'] + + :type: integer + :default: 40 + +.. config:option:: $cfg['TextareaRows'] + + :type: integer + :default: 15 + +.. config:option:: $cfg['CharTextareaCols'] + + :type: integer + :default: 40 + +.. config:option:: $cfg['CharTextareaRows'] + + :type: integer + :default: 2 + + Number of columns and rows for the textareas. This value will be + emphasized (\*2) for :term:`SQL` query + textareas and (\*1.25) for :term:`SQL` + textareas inside the query window. + + The Char\* values are used for CHAR + and VARCHAR editing (if configured via :config:option:`$cfg['CharEditing']`). + +.. config:option:: $cfg['LongtextDoubleTextarea'] + + :type: boolean + :default: true + + Defines whether textarea for LONGTEXT columns should have double size. + +.. config:option:: $cfg['TextareaAutoSelect'] + + :type: boolean + :default: false + + Defines if the whole textarea of the query box will be selected on + click. + + +SQL query box settings +---------------------- + +.. config:option:: $cfg['SQLQuery']['Edit'] + + :type: boolean + :default: true + + Whether to display an edit link to change a query in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['Explain'] + + :type: boolean + :default: true + + Whether to display a link to explain a SELECT query in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['ShowAsPHP'] + + :type: boolean + :default: true + + Whether to display a link to wrap a query in PHP code in any SQL Query + box. + +.. config:option:: $cfg['SQLQuery']['Validate'] + + :type: boolean + :default: false + + Whether to display a link to validate a query in any SQL Query box. + + .. seealso:: :config:option:`$cfg['SQLValidator']` + +.. config:option:: $cfg['SQLQuery']['Refresh'] + + :type: boolean + :default: true + + Whether to display a link to refresh a query in any SQL Query box. + +Web server upload/save/import directories +----------------------------------------- + +.. config:option:: $cfg['UploadDir'] + + :type: string + :default: ``''`` + + The name of the directory where :term:`SQL` files have been uploaded by + other means than phpMyAdmin (for example, ftp). Those files are available + under a drop-down box when you click the database or table name, then the + Import tab. + + If + you want different directory for each user, %u will be replaced with + username. + + Please note that the file names must have the suffix ".sql" + (or ".sql.bz2" or ".sql.gz" if support for compressed formats is + enabled). + + This feature is useful when your file is too big to be + uploaded via :term:`HTTP`, or when file + uploads are disabled in PHP. + + .. note:: + + If PHP is running in safe mode, this directory must be owned by the same + user as the owner of the phpMyAdmin scripts. See also :ref:`faq1_16` for + alternatives. + +.. config:option:: $cfg['SaveDir'] + + :type: string + :default: ``''`` + + The name of the directory where dumps can be saved. + + If you want different directory for each user, %u will be replaced with + username. + + Please note that the directory must exist and has to be writable for + the user running webserver. + + .. note:: + + If PHP is running in safe mode, this directory must be owned by the same + user as the owner of the phpMyAdmin scripts. + +.. config:option:: $cfg['TempDir'] + + :type: string + :default: ``''`` + + The name of the directory where temporary files can be stored. + + This is needed for importing ESRI Shapefiles, see :ref:`faq6_30` and to + work around limitations of ``open_basedir`` for uploaded files, see + :ref:`faq1_11`. + + If the directory where phpMyAdmin is installed is + subject to an ``open_basedir`` restriction, you need to create a + temporary directory in some directory accessible by the web server. + However for security reasons, this directory should be outside the + tree published by webserver. If you cannot avoid having this directory + published by webserver, place at least an empty :file:`index.html` file + there, so that directory listing is not possible. + + This directory should have as strict permissions as possible as the only + user required to access this directory is the one who runs the webserver. + If you have root privileges, simply make this user owner of this directory + and make it accessible only by it: + + .. code-block:: sh + + + chown www-data:www-data tmp + chmod 700 tmp + + If you cannot change owner of the directory, you can achieve a similar + setup using :term:`ACL`: + + .. code-block:: sh + + chmod 700 tmp + setfacl -m "g:www-data:rwx" tmp + setfacl -d -m "g:www-data:rwx" tmp + + If neither of above works for you, you can still make the directory + :command:`chmod 777`, but it might impose risk of other users on system + reading and writing data in this directory. + +Various display setting +----------------------- + +.. config:option:: $cfg['ShowDisplayDirection'] + + :type: boolean + :default: false + + Defines whether or not type display direction option is shown when + browsing a table. + +.. config:option:: $cfg['RepeatCells'] + + :type: integer + :default: 100 + + Repeat the headers every X cells, or 0 to deactivate. + +.. config:option:: $cfg['EditInWindow'] + + :type: boolean + :default: true + +.. config:option:: $cfg['QueryWindowWidth'] + + :type: integer + :default: 550 + +.. config:option:: $cfg['QueryWindowHeight'] + + :type: integer + :default: 310 + +.. config:option:: $cfg['QueryHistoryDB'] + + :type: boolean + :default: false + +.. config:option:: $cfg['QueryWindowDefTab'] + + :type: string + :default: ``'sql'`` + +.. config:option:: $cfg['QueryHistoryMax'] + + :type: integer + :default: 25 + + All those variables affect the query window feature. A :term:`SQL` link or + icon is always displayed in the navigation panel. If JavaScript is enabled + in your browser, a click on this opens a distinct query window, which is a + direct interface to enter :term:`SQL` queries. Otherwise, the right panel + changes to display a query box. + + The size of this query window can be customized with + :config:option:`$cfg['QueryWindowWidth']` and + :config:option:`$cfg['QueryWindowHeight']` - both integers for the size in + pixels. Note that normally, those parameters will be modified in + :file:`layout.inc.php`` for the theme you are using. + + If :config:option:`$cfg['EditInWindow']` is set to true, a click on [Edit] + from the results page (in the :guilabel:`Showing Rows` section) opens the + query window and puts the current query inside it. If set to false, + clicking on the link puts the :term:`SQL` query + in the right panel's query box. + + If :config:option:`$cfg['QueryHistoryDB']` is set to ``true``, all your + Queries are logged to a table, which has to be created by you (see + :config:option:`$cfg['Servers'][$i]['history']`). If set to false, all your + queries will be appended to the form, but only as long as your window is + opened they remain saved. + + When using the JavaScript based query window, it will always get updated + when you click on a new table/db to browse and will focus if you click on + :guilabel:`Edit SQL` after using a query. You can suppress updating the + query window by checking the box :guilabel:`Do not overwrite this query + from outside the window` below the query textarea. Then you can browse + tables/databases in the background without losing the contents of the + textarea, so this is especially useful when composing a query with tables + you first have to look in. The checkbox will get automatically checked + whenever you change the contents of the textarea. Please uncheck the button + whenever you definitely want the query window to get updated even though + you have made alterations. + + If :config:option:`$cfg['QueryHistoryDB']` is set to ``true`` you can + specify the amount of saved history items using + :config:option:`$cfg['QueryHistoryMax']`. + + The query window also has a custom tabbed look to group the features. + Using the variable :config:option:`$cfg['QueryWindowDefTab']` you can + specify the default tab to be used when opening the query window. It can be + set to either ``sql``, ``files``, ``history`` or ``full``. + +.. config:option:: $cfg['BrowseMIME'] + + :type: boolean + :default: true + + Enable :ref:`transformations`. + +.. config:option:: $cfg['MaxExactCount'] + + :type: integer + :default: 0 + + For InnoDB tables, determines for how large tables phpMyAdmin should + get the exact row count using ``SELECT COUNT``. If the approximate row + count as returned by ``SHOW TABLE STATUS`` is smaller than this value, + ``SELECT COUNT`` will be used, otherwise the approximate count will be + used. + +.. config:option:: $cfg['MaxExactCountViews'] + + :type: integer + :default: 0 + + For VIEWs, since obtaining the exact count could have an impact on + performance, this value is the maximum to be displayed, using a + ``SELECT COUNT ... LIMIT``. Setting this to 0 bypasses any row + counting. + +.. config:option:: $cfg['NaturalOrder'] + + :type: boolean + :default: true + + Sorts database and table names according to natural order (for + example, t1, t2, t10). Currently implemented in the navigation panel + and in Database view, for the table list. + +.. config:option:: $cfg['InitialSlidersState'] + + :type: string + :default: ``'closed'`` + + If set to ``'closed'``, the visual sliders are initially in a closed + state. A value of ``'open'`` does the reverse. To completely disable + all visual sliders, use ``'disabled'``. + +.. config:option:: $cfg['UserprefsDisallow'] + + :type: array + :default: array() + + Contains names of configuration options (keys in ``$cfg`` array) that + users can't set through user preferences. For possible values, refer + to :file:`libraries/config/user_preferences.forms.php`. + +.. config:option:: $cfg['UserprefsDeveloperTab'] + + :type: boolean + :default: false + + Activates in the user preferences a tab containing options for + developers of phpMyAdmin. + +Page titles +----------- + +.. config:option:: $cfg['TitleTable'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleDatabase'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleServer'] + + :type: string + :default: ``'@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@'`` + +.. config:option:: $cfg['TitleDefault'] + + :type: string + :default: ``'@HTTP_HOST@ | @PHPMYADMIN@'`` + + Allows you to specify window's title bar. You can use :ref:`faq6_27`. + +Theme manager settings +---------------------- + +.. config:option:: $cfg['ThemePath'] + + :type: string + :default: ``'./themes'`` + + If theme manager is active, use this as the path of the subdirectory + containing all the themes. + +.. config:option:: $cfg['ThemeManager'] + + :type: boolean + :default: true + + Enables user-selectable themes. See :ref:`faqthemes`. + +.. config:option:: $cfg['ThemeDefault'] + + :type: string + :default: ``'pmahomme'`` + + The default theme (a subdirectory under :config:option:`$cfg['ThemePath']`). + +.. config:option:: $cfg['ThemePerServer'] + + :type: boolean + :default: false + + Whether to allow different theme for each server. + +Default queries +--------------- + +.. config:option:: $cfg['DefaultQueryTable'] + + :type: string + :default: ``'SELECT * FROM @TABLE@ WHERE 1'`` + +.. config:option:: $cfg['DefaultQueryDatabase'] + + :type: string + :default: ``''`` + + Default queries that will be displayed in query boxes when user didn't + specify any. You can use standard :ref:`faq6_27`. + +SQL parser settings +------------------- + +.. config:option:: $cfg['SQP']['fmtType'] + + :type: string + :default: ``'html'`` + + The main use of the new :term:`SQL` Parser + is to pretty-print :term:`SQL` queries. By + default we use HTML to format the query, but you can disable this by + setting this variable to ``'none'``. + + Available options: + + * ``'html'`` + * ``'none'`` + +.. _cfg_SQP: +.. config:option:: $cfg['SQP']['fmtInd'] + + :type: float + :default: ``'1'`` + +.. config:option:: $cfg['SQP']['fmtIndUnit'] + + :type: string + :default: ``'em'`` + + For the pretty-printing of :term:`SQL` queries, + under some cases the part of a query inside a bracket is indented. By + changing :config:option:`$cfg['SQP']['fmtInd']` you can change the amount + of this indent. + + Related in purpose is :config:option:`$cfg['SQP']['fmtIndUnit']` which + specifies the units of the indent amount that you specified. This is used + via stylesheets. + + You can use any HTML unit, for example: + + * ``'em'`` + * ``'ex'`` + * ``'pt'`` + * ``'px'`` + +.. config:option:: $cfg['SQP']['fmtColor'] + + :type: array of string tuples + :default: + + This array is used to define the colours for each type of element of + the pretty-printed :term:`SQL` queries. + The tuple format is *class* => [*HTML colour code* | *empty string*] + + + If you specify an empty string for the color of a class, it is ignored + in creating the stylesheet. You should not alter the class names, only + the colour strings. + + **Class name key:** + + comment + Applies to all comment sub-classes + comment\_mysql + Comments as ``"#...\n"`` + comment\_ansi + Comments as ``"-- ...\n"`` + comment\_c + Comments as ``"/*...*/"`` + digit + Applies to all digit sub-classes + digit\_hex + Hexadecimal numbers + digit\_integer + Integer numbers + digit\_float + Floating point numbers + punct + Applies to all punctuation sub-classes + punct\_bracket\_open\_round + Opening brackets ``"("`` + punct\_bracket\_close\_round + Closing brackets ``")"`` + punct\_listsep + List item Separator ``","`` + punct\_qualifier + Table/Column Qualifier ``"."`` + punct\_queryend + End of query marker ``";"`` + alpha + Applies to all alphabetic classes + alpha\_columnType + Identifiers matching a column type + alpha\_columnAttrib + Identifiers matching a database/table/column attribute + alpha\_functionName + Identifiers matching a MySQL function name + alpha\_reservedWord + Identifiers matching any other reserved word + alpha\_variable + Identifiers matching a :term:`SQL` variable ``"@foo"`` + alpha\_identifier + All other identifiers + quote + Applies to all quotation mark classes + quote\_double + Double quotes ``"`` + quote\_single + Single quotes ``'`` + quote\_backtick + Backtick quotes ````` + +SQL validator settings +---------------------- + +.. config:option:: $cfg['SQLValidator'] + + :type: array + :default: array(...) + + + +.. config:option:: $cfg['SQLValidator']['use'] + + :type: boolean + :default: false + + phpMyAdmin now supports use of the `Mimer SQL Validator + `_ service, as originally + published on `Slashdot + `_. For + help in setting up your system to use the service, see the + :ref:`faqsqlvalidator`. + +.. config:option:: $cfg['SQLValidator']['username'] + + :type: string + :default: ``''`` + +.. config:option:: $cfg['SQLValidator']['password'] + + :type: string + :default: ``''`` + + The SOAP service allows you to log in with ``anonymous`` and any password, + so we use those by default. Instead, if you have an account with them, you + can put your login details here, and it will be used in place of the + anonymous login. + +MySQL settings +-------------- + +.. config:option:: $cfg['DefaultFunctions'] + + :type: array + :default: array(...) + + Functions selected by default when inserting/changing row, Functions + are defined for meta types as (FUNC\_NUMBER, FUNC\_DATE, FUNC\_CHAR, + FUNC\_SPATIAL, FUNC\_UUID) and for ``first_timestamp``, which is used + for first timestamp column in table. + + +Developer +--------- + +.. warning:: + + These settings might have huge effect on performance or security. + +.. config:option:: $cfg['DBG'] + + :type: array + :default: array(...) + +.. config:option:: $cfg['DBG']['sql'] + + :type: boolean + :default: false + + Enable logging queries and execution times to be + displayed in the bottom of main page (right frame). + +.. config:option:: $cfg['Error_Handler']['display'] + + :type: boolean + :default: false + + Whether to display errors from PHP or not. + +.. config:option:: $cfg['Error_Handler']['gather'] + + :type: boolean + :default: false + + Whether to gather errors from PHP or not. + diff --git a/phpmyadmin/doc/html/_sources/copyright.txt b/phpmyadmin/doc/html/_sources/copyright.txt new file mode 100644 index 000000000..cfcb86394 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/copyright.txt @@ -0,0 +1,30 @@ +.. _copyright: + +Copyright +========= + +.. code-block:: none + + Copyright (C) 1998-2000 Tobias Ratschiller + Copyright (C) 2001-2013 Marc Delisle + Olivier Müller + Robin Johnson + Alexander M. Turek + Michal Čihař + Garvin Hicking + Michael Keck + Sebastian Mendel + [check credits for more details] + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2, as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see `http://www.gnu.org/licenses/ +`_. diff --git a/phpmyadmin/doc/html/_sources/credits.txt b/phpmyadmin/doc/html/_sources/credits.txt new file mode 100644 index 000000000..21f5e1892 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/credits.txt @@ -0,0 +1,597 @@ +.. _credits: + +Credits +======= + + +Credits, in chronological order ++++++++++++++++++++++++++++++++ + +* Tobias Ratschiller + + * creator of the phpmyadmin project + + * maintainer from 1998 to summer 2000 + +* Marc Delisle + + * multi-language version in December 1998 + + * various fixes and improvements + + * :term:`SQL` analyser (most of it) + + * current project maintainer + +* Olivier Müller + + * started SourceForge phpMyAdmin project in March 2001 + + * sync'ed different existing CVS trees with new features and bugfixes + + * multi-language improvements, dynamic language selection + + * many bugfixes and improvements + +* Loïc Chapeaux + + * rewrote and optimized javascript, DHTML and DOM stuff + + * rewrote the scripts so they fit the :term:`PEAR` coding standards and + generate XHTML1.0 and CSS2 compliant codes + + * improved the language detection system + + * many bugfixes and improvements + +* Robin Johnson + + * database maintenance controls + + * table type code + + * Host authentication :term:`IP` Allow/Deny + + * DB-based configuration (Not completed) + + * :term:`SQL` parser and pretty-printer + + * :term:`SQL` validator + + * many bugfixes and improvements + +* Armel Fauveau + + * bookmarks feature + + * multiple dump feature + + * gzip dump feature + + * zip dump feature + +* Geert Lund + + * various fixes + + * moderator of the phpMyAdmin former users forum at phpwizard.net + +* Korakot Chaovavanich + + * "insert as new row" feature + +* Pete Kelly + + * rewrote and fix dump code + + * bugfixes + +* Steve Alberty + + * rewrote dump code for PHP4 + + * mySQL table statistics + + * bugfixes + +* Benjamin Gandon + + * main author of the version 2.1.0.1 + + * bugfixes + +* Alexander M. Turek + + * MySQL 4.0 / 4.1 / 5.0 compatibility + + * abstract database interface (PMA\_DBI) with MySQLi support + + * privileges administration + + * :term:`XML` exports + + * various features and fixes + + * German language file updates + +* Mike Beck + + * automatic joins in QBE + + * links column in printview + + * Relation view + +* Michal Čihař + + * enhanced index creation/display feature + + * feature to use a different charset for HTML than for MySQL + + * improvements of export feature + + * various features and fixes + + * Czech language file updates + +* Christophe Gesché from the "MySQL Form Generator for PHPMyAdmin" + (http://sf.net/projects/phpmysqlformgen/) + + * suggested the patch for multiple table printviews + +* Garvin Hicking + + * built the patch for vertical display of table rows + + * built the Javascript based Query window + :term:`SQL` history + + * Improvement of column/db comments + + * (MIME)-Transformations for columns + + * Use custom alias names for Databases in left frame + + * hierarchical/nested table display + + * :term:`PDF`-scratchboard for WYSIWYG- + distribution of :term:`PDF` relations + + * new icon sets + + * vertical display of column properties page + + * some bugfixes, features, support, German language additions + +* Yukihiro Kawada + + * japanese kanji encoding conversion feature + +* Piotr Roszatycki and Dan Wilson + + * the Cookie authentication mode + +* Axel Sander + + * table relation-links feature + +* Maxime Delorme + + * :term:`PDF` schema output, thanks also to + Olivier Plathey for the "FPDF" library (see ), Steven + Wittens for the "UFPDF" library (see ) and + Nicola Asuni for the "TCPDF" library (see ). + +* Olof Edlund + + * :term:`SQL` validator server + +* Ivan R. Lanin + + * phpMyAdmin logo (until June 2004) + +* Mike Cochrane + + * blowfish library from the Horde project (withdrawn in release 4.0) + +* Marcel Tschopp + + * mysqli support + + * many bugfixes and improvements + +* Nicola Asuni (Tecnick.com) + + * TCPDF library (`http://www.tcpdf.org `_) + +* Michael Keck + + * redesign for 2.6.0 + + * phpMyAdmin sailboat logo (June 2004) + +* Mathias Landhäußer + + * Representation at conferences + +* Sebastian Mendel + + * interface improvements + + * various bugfixes + +* Ivan A Kirillov + + * new relations Designer + +* Raj Kissu Rajandran (Google Summer of Code 2008) + + * BLOBstreaming support (withdrawn in release 4.0) + +* Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011) + + * improved setup script + + * user preferences + + * Drizzle support + +* Derek Schaefer (Google Summer of Code 2009) + + * Improved the import system + +* Alexander Rutkowski (Google Summer of Code 2009) + + * Tracking mechanism + +* Zahra Naeem (Google Summer of Code 2009) + + * Synchronization feature (removed in release 4.0) + +* Tomáš Srnka (Google Summer of Code 2009) + + * Replication support + +* Muhammad Adnan (Google Summer of Code 2010) + + * Relation schema export to multiple formats + +* Lori Lee (Google Summer of Code 2010) + + * User interface improvements + + * ENUM/SET editor + + * Simplified interface for export/import + +* Ninad Pundalik (Google Summer of Code 2010) + + * AJAXifying the interface + +* Martynas Mickevičius (Google Summer of Code 2010) + + * Charts + +* Barrie Leslie + + * BLOBstreaming support with PBMS PHP extension (withdrawn in release + 4.0) + +* Ankit Gupta (Google Summer of Code 2010) + + * Visual query builder + +* Madhura Jayaratne (Google Summer of Code 2011) + + * OpenGIS support + +* Ammar Yasir (Google Summer of Code 2011) + + * Zoom search + +* Aris Feryanto (Google Summer of Code 2011) + + * Browse-mode improvements + +* Thilanka Kaushalya (Google Summer of Code 2011) + + * AJAXification + +* Tyron Madlener (Google Summer of Code 2011) + + * Query statistics and charts for the status page + +* Zarubin Stas (Google Summer of Code 2011) + + * Automated testing + +* Rouslan Placella (Google Summer of Code 2011 and 2012) + + * Improved support for Stored Routines, Triggers and Events + + * Italian translation updates + + * Removal of frames, new navigation + +* Dieter Adriaenssens + + * Various bugfixes + + * Dutch translation updates + +* Alex Marin (Google Summer of Code 2012) + + * New plugins and properties system + +* Thilina Buddika Abeyrathna (Google Summer of Code 2012) + + * Refactoring + +* Atul Pratap Singh (Google Summer of Code 2012) + + * Refactoring + +* Chanaka Indrajith (Google Summer of Code 2012) + + * Refactoring + +* Yasitha Pandithawatta (Google Summer of Code 2012) + + * Automated testing + +* Jim Wigginton (phpseclib.sourceforge.net) + + * phpseclib + +And also to the following people who have contributed minor changes, +enhancements, bugfixes or support for a new language since version +2.1.0: + +Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita, +Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats +Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger, +Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg, +Andreas Pauley, Bernard M. Piller, Laurent Haas, "Sakamoto", Yuval +Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun, +Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V., +Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay, +Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael +Winningham, Vilius Zigmantas, "Manuzhai". + + +Translators ++++++++++++ + +Following people have contributed to translation of phpMyAdmin: + +* Arabic + + * Abdullah Al-Saedi + +* Bulgarian + + * stoyanster + +* Catalan + + * Xavier Navarro + +* Czech + + * Michal Čihař + +* Danish + + * opensource + * Jørgen Thomsen + +* German + + * mrbendig + * torsten.funck + * Sven Strickroth + * typo3 + * Jo Michael + +* Greek + + * Panagiotis Papazoglou + +* English (United Kingdom) + + * Robert Readman + +* Spanish + + * Matías Bellone + +* French + + * Marc Delisle + +* Hindi + + * u4663530 + * rsedwardian + +* Hungarian + + * gergo314 + +* Italian + + * Rouslan Placella + +* Japanese + + * Yuichiro + +* Lithuanian + + * Kęstutis + +* Norwegian Bokmål + + * Sven-Erik Andersen + +* Dutch + + * Dieter Adriaenssens + * Herman van Rink + +* Polish + + * Stanisław Krukowski + * Marcin Kozioł + +* Portuguese + + * JoaoTMDias + +* Portuguese (Brazil) + + * wiltave + * emerson4br + +* Romanian + + * alexukf + +* Russian + + * Victor Volkov + +* Sinhala + + * Madhura Jayaratne + +* Slovak + + * Martin Lacina + +* Slovenian + + * Domen + +* Swedish + + * stefan + +* Tamil + + * ysajeepan + +* Telugu + + * veeven + +* Thai + + * kanitchet + +* Turkish + + * Burak Yavuz + +* Uighur + + * gheni + +* Ukrainian + + * typim + * oleg-ilnytskyi + +* Urdu + + * Mehbooob Khan + +* Simplified Chinese + + * shanyan baishui + +* Traditional Chinese + + * star + +Documentation translators ++++++++++++++++++++++++++ + +Following people have contributed to translation of phpMyAdmin documentation: + +* Czech + + * Michal Čihař + +* Greek + + * Panagiotis Papazoglou + +* English (United Kingdom) + + * Robert Readman + +* French + + * Cédric Corazza + +* Japanese + + * Yuichiro Takahashi + +* Polish + + * Stanisław Krukowski + +* Portuguese (Brazil) + + * mjaning + +* Slovenian + + * Domen + +Original Credits of Version 2.1.0 ++++++++++++++++++++++++++++++++++ + +This work is based on Peter Kuppelwieser's MySQL-Webadmin. It was his +idea to create a web-based interface to MySQL using PHP3. Although I +have not used any of his source-code, there are some concepts I've +borrowed from him. phpMyAdmin was created because Peter told me he +wasn't going to further develop his (great) tool. + +Thanks go to + +* Amalesh Kempf who contributed the + code for the check when dropping a table or database. He also + suggested that you should be able to specify the primary key on + tbl\_create.php3. To version 1.1.1 he contributed the ldi\_\*.php3-set + (Import text-files) as well as a bug-report. Plus many smaller + improvements. +* Jan Legenhausen : He made many of the changes that + were introduced in 1.3.0 (including quite significant ones like the + authentication). For 1.4.1 he enhanced the table-dump feature. Plus + bug-fixes and help. +* Marc Delisle made phpMyAdmin + language-independent by outsourcing the strings to a separate file. He + also contributed the French translation. +* Alexandr Bravo who contributed + tbl\_select.php3, a feature to display only some columns from a table. +* Chris Jackson added support for MySQL functions + in tbl\_change.php3. He also added the "Query by Example" feature in + 2.0. +* Dave Walton added support for multiple + servers and is a regular contributor for bug-fixes. +* Gabriel Ash contributed the random access + features for 2.0.6. + +The following people have contributed minor changes, enhancements, +bugfixes or support for a new language: + +Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas +Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel +Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein, +Jannis Hermanns, G. Wieggers. + +And thanks to everyone else who sent me email with suggestions, bug- +reports and or just some feedback. + diff --git a/phpmyadmin/doc/html/_sources/developers.txt b/phpmyadmin/doc/html/_sources/developers.txt new file mode 100644 index 000000000..557452769 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/developers.txt @@ -0,0 +1,12 @@ +.. _developers: + +Developers Information +====================== + +phpMyAdmin is Open Source, so you're invited to contribute to it. Many +great features have been written by other people and you too can help +to make phpMyAdmin a useful tool. + +You can check out all the possibilities to contribute in the +`contribute section on our website +`_. \ No newline at end of file diff --git a/phpmyadmin/doc/html/_sources/faq.txt b/phpmyadmin/doc/html/_sources/faq.txt new file mode 100644 index 000000000..c77f42866 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/faq.txt @@ -0,0 +1,2001 @@ +.. _faq: + +FAQ - Frequently Asked Questions +================================ + +Please have a look at our `Link section +`_ on the official +phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and +or interface. + +.. _faqserver: + +Server +++++++ + +.. _faq1_1: + +1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in your +:file:`config.inc.php` file and the ``zlib.output_compression`` directive to +``Off`` in your php configuration file. + +.. _faq1_2: + +1.2 My Apache server crashes when using phpMyAdmin. +--------------------------------------------------- + +You should first try the latest versions of Apache (and possibly MySQL). If +your server keeps crashing, please ask for help in the various Apache support +groups. + +.. seealso:: :ref:`faq1_1` + +.. _faq1_3: + +1.3 (withdrawn). +---------------- + +.. _faq1_4: + +1.4 Using phpMyAdmin on IIS, I'm displayed the error message: "The specified CGI application misbehaved by not returning a complete set of HTTP headers ...". +------------------------------------------------------------------------------------------------------------------------------------------------------------- + +You just forgot to read the *install.txt* file from the PHP +distribution. Have a look at the last message in this `PHP bug report #12061 +`_ from the official PHP bug +database. + +.. _faq1_5: + +1.5 Using phpMyAdmin on IIS, I'm facing crashes and/or many error messages with the HTTP. +----------------------------------------------------------------------------------------- + +This is a known problem with the PHP :term:`ISAPI` filter: it's not so stable. +Please use instead the cookie authentication mode. + +.. _faq1_6: + +1.6 I can't use phpMyAdmin on PWS: nothing is displayed! +-------------------------------------------------------- + +This seems to be a PWS bug. Filippo Simoncini found a workaround (at +this time there is no better fix): remove or comment the ``DOCTYPE`` +declarations (2 lines) from the scripts :file:`libraries/Header.class.php` +and :file:`index.php`. + +.. _faq1_7: + +1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work. +---------------------------------------------------------------------------- + +These features are based on the ``gzencode()`` and ``bzcompress()`` +PHP functions to be more independent of the platform (Unix/Windows, +Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support +(``--with-zlib`` and ``--with-bz2``). + +.. _faq1_8: + +1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect. +----------------------------------------------------------------------------------------------- + +Your uploaded file is saved by PHP in the "upload dir", as defined in +:file:`php.ini` by the variable ``upload_tmp_dir`` (usually the system +default is */tmp*). We recommend the following setup for Apache +servers running in safe mode, to enable uploads of files while being +reasonably secure: + +* create a separate directory for uploads: :command:`mkdir /tmp/php` +* give ownership to the Apache server's user.group: :command:`chown + apache.apache /tmp/php` +* give proper permission: :command:`chmod 600 /tmp/php` +* put ``upload_tmp_dir = /tmp/php`` in :file:`php.ini` +* restart Apache + +.. _faq1_9: + +1.9 (withdrawn). +---------------- + +.. _faq1_10: + +1.10 I'm having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I'm using the Apache server. +---------------------------------------------------------------------------------------------------------------------------------------------------------- + +As suggested by "Rob M" in the phpWizard forum, add this line to your +*httpd.conf*: + +.. code-block:: apache + + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + +It seems to clear up many problems between Internet Explorer and SSL. + +.. _faq1_11: + +1.11 I get an 'open\_basedir restriction' while uploading a file from the query box. +------------------------------------------------------------------------------------ + +Since version 2.2.4, phpMyAdmin supports servers with open\_basedir +restrictions. However you need to create temporary directory and configure it +as :config:option:`$cfg['TempDir']`. The uploaded files will be moved there, +and after execution of your :term:`SQL` commands, removed. + +.. _faq1_12: + +1.12 I have lost my MySQL root password, what can I do? +------------------------------------------------------- + +The MySQL manual explains how to `reset the permissions +`_. + +.. _faq1_13: + +1.13 (withdrawn). +----------------- + +.. _faq1_14: + +1.14 (withdrawn). +----------------- + +.. _faq1_15: + +1.15 I have problems with *mysql.user* column names. +---------------------------------------------------- + +In previous MySQL versions, the ``User`` and ``Password``columns were +named ``user`` and ``password``. Please modify your column names to +align with current standards. + +.. _faq1_16: + +1.16 I cannot upload big dump files (memory, HTTP or timeout problems). +----------------------------------------------------------------------- + +Starting with version 2.7.0, the import engine has been re–written and +these problems should not occur. If possible, upgrade your phpMyAdmin +to the latest version to take advantage of the new import features. + +The first things to check (or ask your host provider to check) are the +values of ``upload_max_filesize``, ``memory_limit`` and +``post_max_size`` in the :file:`php.ini` configuration file. All of these +three settings limit the maximum size of data that can be submitted +and handled by PHP. One user also said that ``post_max_size`` and +``memory_limit`` need to be larger than ``upload_max_filesize``. +There exist several workarounds if your upload is too big or your +hosting provider is unwilling to change the settings: + +* Look at the :config:option:`$cfg['UploadDir']` feature. This allows one to upload a file to the server + via scp, ftp, or your favorite file transfer method. PhpMyAdmin is + then able to import the files from the temporary directory. More + information is available in the :ref:`config` of this document. +* Using a utility (such as `BigDump + `_) to split the files before + uploading. We cannot support this or any third party applications, but + are aware of users having success with it. +* If you have shell (command line) access, use MySQL to import the files + directly. You can do this by issuing the "source" command from within + MySQL: + + .. code-block:: mysql + + source filename.sql; + +.. _faq1_17: + +1.17 Which MySQL versions does phpMyAdmin support? +-------------------------------------------------- + +Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For +older MySQL versions, you need to use the latest 2.x branch. +phpMyAdmin can connect to your MySQL server using PHP's classic `MySQL +extension `_ as well as the `improved MySQL +extension (MySQLi) `_ that is available in PHP +5.0. The latter one should be used unless you have a good reason not +to do so. When compiling PHP, we strongly recommend that you manually +link the MySQL extension of your choice to a MySQL client library of +at least the same minor version since the one that is bundled with +some PHP distributions is rather old and might cause problems see +:ref:`faq1_17a`. `MariaDB `_ is also supported +(versions 5.1 and 5.2 were tested). + +.. versionchanged:: 3.5 + Since phpMyAdmin 3.5 `Drizzle `_ is supported. + +.. _faq1_17a: + +1.17a I cannot connect to the MySQL server. It always returns the error message, "Client does not support authentication protocol requested by server; consider upgrading MySQL client" +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +You tried to access MySQL with an old MySQL client library. The +version of your MySQL client library can be checked in your phpinfo() +output. In general, it should have at least the same minor version as +your server - as mentioned in :ref:`faq1_17`. This problem is +generally caused by using MySQL version 4.1 or newer. MySQL changed +the authentication hash and your PHP is trying to use the old method. +The proper solution is to use the `mysqli extension +`_ with the proper client library to match +your MySQL installation. Your chosen extension is specified in +:config:option:`$cfg['Servers'][$i]['extension']`. More +information (and several workarounds) are located in the `MySQL +Documentation `_. + +.. _faq1_18: + +1.18 (withdrawn). +----------------- + +.. _faq1_19: + +1.19 I can't run the "display relations" feature because the script seems not to know the font face I'm using! +-------------------------------------------------------------------------------------------------------------- + +The :term:`TCPDF` library we're using for this feature requires some special +files to use font faces. Please refers to the `TCPDF manual +`_ to build these files. + +.. _faqmysql: + +1.20 I receive the error "cannot load MySQL extension, please check PHP Configuration". +--------------------------------------------------------------------------------------- + +To connect to a MySQL server, PHP needs a set of MySQL functions +called "MySQL extension". This extension may be part of the PHP +distribution (compiled-in), otherwise it needs to be loaded +dynamically. Its name is probably *mysql.so* or *php\_mysql.dll*. +phpMyAdmin tried to load the extension but failed. Usually, the +problem is solved by installing a software package called "PHP-MySQL" +or something similar. + +.. _faq1_21: + +1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth. +------------------------------------------------------------------------------------------- + +In :file:`php.ini`, set ``mysql.max_links`` higher than 1. + +.. _faq1_22: + +1.22 I don't see the "Location of text file" field, so I cannot upload. +----------------------------------------------------------------------- + +This is most likely because in :file:`php.ini`, your ``file_uploads`` +parameter is not set to "on". + +.. _faq1_23: + +1.23 I'm running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase! +------------------------------------------------------------------------------------------------------------------------------ + +This happens because the MySQL directive ``lower_case_table_names`` +defaults to 1 (``ON``) in the Win32 version of MySQL. You can change +this behavior by simply changing the directive to 0 (``OFF``): Just +edit your ``my.ini`` file that should be located in your Windows +directory and add the following line to the group [mysqld]: + +.. code-block:: ini + + set-variable = lower_case_table_names=0 + +Next, save the file and restart the MySQL service. You can always +check the value of this directive using the query + +.. code-block:: mysql + + SHOW VARIABLES LIKE 'lower_case_table_names'; + +.. _faq1_24: + +1.24 (withdrawn). +----------------- + +.. _faq1_25: + +1.25 I am running Apache with mod\_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query. +---------------------------------------------------------------------------------------------------------------------------------------- + +A tip from Jose Fandos: put a comment on the following two lines in +httpd.conf, like this: + +.. code-block:: apache + + + # mod_gzip_item_include file \.php$ + # mod_gzip_item_include mime "application/x-httpd-php.*" + +as this version of mod\_gzip on Apache (Windows) has problems handling +PHP scripts. Of course you have to restart Apache. + +.. _faq1_26: + +1.26 I just installed phpMyAdmin in my document root of IIS but I get the error "No input file specified" when trying to run phpMyAdmin. +---------------------------------------------------------------------------------------------------------------------------------------- + +This is a permission problem. Right-click on the phpmyadmin folder and +choose properties. Under the tab Security, click on "Add" and select +the user "IUSR\_machine" from the list. Now set his permissions and it +should work. + +.. _faq1_27: + +1.27 I get empty page when I want to view huge page (eg. db\_structure.php with plenty of tables). +-------------------------------------------------------------------------------------------------- + +This was caused by a `PHP bug `_ that occur when +GZIP output buffering is enabled. If you turn off it (by +:config:option:`$cfg['OBGzip']` in :file:`config.inc.php`), it should work. +This bug will has been fixed in PHP 5.0.0. + +.. _faq1_28: + +1.28 My MySQL server sometimes refuses queries and returns the message 'Errorcode: 13'. What does this mean? +------------------------------------------------------------------------------------------------------------ + +This can happen due to a MySQL bug when having database / table names +with upper case characters although ``lower_case_table_names`` is +set to 1. To fix this, turn off this directive, convert all database +and table names to lower case and turn it on again. Alternatively, +there's a bug-fix available starting with MySQL 3.23.56 / +4.0.11-gamma. + +.. _faq1_29: + +1.29 When I create a table or modify a column, I get an error and the columns are duplicated. +--------------------------------------------------------------------------------------------- + +It is possible to configure Apache in such a way that PHP has problems +interpreting .php files. + +The problems occur when two different (and conflicting) set of +directives are used: + +.. code-block:: apache + + + SetOutputFilter PHP + SetInputFilter PHP + +and + +.. code-block:: apache + + AddType application/x-httpd-php .php + +In the case we saw, one set of directives was in +``/etc/httpd/conf/httpd.conf``, while the other set was in +``/etc/httpd/conf/addon-modules/php.conf``. The recommended way is +with ``AddType``, so just comment out the first set of lines and +restart Apache: + +.. code-block:: apache + + + #SetOutputFilter PHP + #SetInputFilter PHP + +.. _faq1_30: + +1.30 I get the error "navigation.php: Missing hash". +---------------------------------------------------- + +This problem is known to happen when the server is running Turck +MMCache but upgrading MMCache to version 2.3.21 solves the problem. + +.. _faq1_31: + +1.31 Does phpMyAdmin support PHP 5? +----------------------------------- + +Yes. + +Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use +phpMyAdmin 2.11.x. + +.. _faq1_32: + +1.32 Can I use HTTP authentication with IIS? +-------------------------------------------- + +Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in +:term:`ISAPI` mode under :term:`IIS` 5.1. + +#. In your :file:`php.ini` file, set ``cgi.rfc2616_headers = 0`` +#. In ``Web Site Properties -> File/Directory Security -> Anonymous + Access`` dialog box, check the ``Anonymous access`` checkbox and + uncheck any other checkboxes (i.e. uncheck ``Basic authentication``, + ``Integrated Windows authentication``, and ``Digest`` if it's + enabled.) Click ``OK``. +#. In ``Custom Errors``, select the range of ``401;1`` through ``401;5`` + and click the ``Set to Default`` button. + +.. seealso:: :rfc:`2616` + +.. _faq1_33: + +1.33 (withdrawn). +----------------- + +.. _faq1_34: + +1.34 Can I access directly to database or table pages? +------------------------------------------------------ + +Yes. Out of the box, you can use :term:`URL` like http://server/phpMyAdmin/index.php?server=X&db=databas +e&table=table&target=script. For ``server`` you use the server number +which refers to the order of the server paragraph in +:file:`config.inc.php`. Table and script parts are optional. If you want +http://server/phpMyAdmin/database[/table][/script] :term:`URL`, you need to do some configuration. Following +lines apply only for `Apache `_ web server. +First make sure, that you have enabled some features within global +configuration. You need ``Options FollowSymLinks`` and ``AllowOverride +FileInfo`` enabled for directory where phpMyAdmin is installed and you +need mod\_rewrite to be enabled. Then you just need to create +following :term:`.htaccess` file in root folder of phpMyAdmin installation (don't +forget to change directory name inside of it): + +.. code-block:: apache + + + RewriteEngine On + RewriteBase /path_to_phpMyAdmin + RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R] + RewriteRule ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R] + RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R] + RewriteRule ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R] + +.. _faq1_35: + +1.35 Can I use HTTP authentication with Apache CGI? +--------------------------------------------------- + +Yes. However you need to pass authentication variable to :term:`CGI` using +following rewrite rule: + +.. code-block:: apache + + + RewriteEngine On + RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L] + +.. _faq1_36: + +1.36 I get an error "500 Internal Server Error". +------------------------------------------------ + +There can be many explanations to this and a look at your server's +error log file might give a clue. + +.. _faq1_37: + +1.37 I run phpMyAdmin on cluster of different machines and password encryption in cookie auth doesn't work. +----------------------------------------------------------------------------------------------------------- + +If your cluster consist of different architectures, PHP code used for +encryption/decryption won't work correct. This is caused by use of +pack/unpack functions in code. Only solution is to use mcrypt +extension which works fine in this case. + +.. _faq1_38: + +1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled? +------------------------------------------------------------------ + +Yes but the default configuration values of Suhosin are known to cause +problems with some operations, for example editing a table with many +columns and no primary key or with textual primary key. + +Suhosin configuration might lead to malfunction in some cases and it +can not be fully avoided as phpMyAdmin is kind of application which +needs to transfer big amounts of columns in single HTTP request, what +is something what Suhosin tries to prevent. Generally all +``suhosin.request.*``, ``suhosin.post.*`` and ``suhosin.get.*`` +directives can have negative effect on phpMyAdmin usability. You can +always find in your error logs which limit did cause dropping of +variable, so you can diagnose the problem and adjust matching +configuration variable. + +The default values for most Suhosin configuration options will work in +most scenarios, however you might want to adjust at least following +parameters: + +* `suhosin.request.max\_vars `_ should + be increased (eg. 2048) +* `suhosin.post.max\_vars `_ should be + increased (eg. 2048) +* `suhosin.request.max\_array\_index\_length `_ + should be increased (eg. 256) +* `suhosin.post.max\_array\_index\_length `_ + should be increased (eg. 256) +* `suhosin.request.max\_totalname\_length `_ + should be increased (eg. 8192) +* `suhosin.post.max\_totalname\_length `_ should be + increased (eg. 8192) +* `suhosin.get.max\_value\_length `_ + should be increased (eg. 1024) +* `suhosin.sql.bailout\_on\_error `_ + needs to be disabled (the default) +* `suhosin.log.\* `_ should not + include :term:`SQL`, otherwise you get big + slowdown + +You can also disable the warning using the :config:option:`$cfg['SuhosinDisableWarning']`. + +.. _faq1_39: + +1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior? +------------------------------------------------------------------------------------------------------------------------------------ + +Be sure that you have enabled ``SSLOptions`` and ``StdEnvVars`` in +your Apache configuration. + +.. seealso:: + +.. _faq1_40: + +1.40 When accessing phpMyAdmin via an Apache reverse proxy, cookie login does not work. +--------------------------------------------------------------------------------------- + +To be able to use cookie auth Apache must know that it has to rewrite +the set-cookie headers. Example from the Apache 2.2 documentation: + +.. code-block:: apache + + + ProxyPass /mirror/foo/ http://backend.example.com/ + ProxyPassReverse /mirror/foo/ http://backend.example.com/ + ProxyPassReverseCookieDomain backend.example.com public.example.com + ProxyPassReverseCookiePath / /mirror/foo/ + +Note: if the backend url looks like http://host/~user/phpmyadmin, the +tilde (~) must be url encoded as %7E in the ProxyPassReverse\* lines. +This is not specific to phpmyadmin, it's just the behavior of Apache. + +.. code-block:: apache + + + ProxyPass /mirror/foo/ http://backend.example.com/~user/phpmyadmin + ProxyPassReverse /mirror/foo/ http://backend.example.com/%7Euser/phpmyadmin + ProxyPassReverseCookiePath /%7Euser/phpmyadmin /mirror/foo + +.. seealso:: + +.. _faq1_41: + +1.41 When I view a database and ask to see its privileges, I get an error about an unknown column. +-------------------------------------------------------------------------------------------------- + +The MySQL server's privilege tables are not up to date, you need to +run the :command:`mysql_upgrade` command on the server. + +.. _faq1_42: + +1.42 How can I prevent robots from accessing phpMyAdmin? +-------------------------------------------------------- + +You can add various rules to :term:`.htaccess` to filter access based on user agent +field. This is quite easy to circumvent, but could prevent at least +some robots accessing your installation. + +.. code-block:: apache + + + RewriteEngine on + + # Allow only GET and POST verbs + RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR] + + # Ban Typical Vulnerability Scanners and others + # Kick out Script Kiddies + RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR] + RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR] + RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR] + + # Ban Search Engines, Crawlers to your administrative panel + # No reasons to access from bots + # Ultimately Better than the useless robots.txt + # Did google respect robots.txt? + # Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled" + RewriteCond %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.search.Crawler|Seoma.\[SEO.Crawler\]|SEOsearch|Snappy|www.urltrends.com|www.tkl.iis.u-tokyo.ac.jp/~crawler|SynooBot|crawleradmin.t-info@telekom.de|TurnitinBot|voyager|W3.SiteSearch.Crawler|W3C-checklink|W3C_Validator|www.WISEnutbot.com|yacybot|Yahoo-MMCrawler|Yahoo\!.DE.Slurp|Yahoo\!.Slurp|YahooSeeker).* [NC] + RewriteRule .* - [F] + +.. _faq1_43: + +1.43 Why can't I display the structure of my table containing hundreds of columns? +---------------------------------------------------------------------------------- + +Because your PHP's ``memory_limit`` is too low; adjust it in :file:`php.ini`. + +.. _faqconfig: + +Configuration ++++++++++++++ + +.. _faq2_1: + +2.1 The error message "Warning: Cannot add header information - headers already sent by ..." is displayed, what's the problem? +------------------------------------------------------------------------------------------------------------------------------ + +Edit your :file:`config.inc.php` file and ensure there is nothing (I.E. no +blank lines, no spaces, no characters...) neither before the ```` tag at the end. We also got a report +from a user under :term:`IIS`, that used a zipped distribution kit: the file +:file:`libraries/Config.class.php` contained an end-of-line character (hex 0A) +at the end; removing this character cleared his errors. + +.. _faq2_2: + +2.2 phpMyAdmin can't connect to MySQL. What's wrong? +---------------------------------------------------- + +Either there is an error with your PHP setup or your username/password +is wrong. Try to make a small script which uses mysql\_connect and see +if it works. If it doesn't, it may be you haven't even compiled MySQL +support into PHP. + +.. _faq2_3: + +2.3 The error message "Warning: MySQL Connection Failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) ..." is displayed. What can I do? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +For RedHat users, Harald Legner suggests this on the mailing list: + +On my RedHat-Box the socket of MySQL is */var/lib/mysql/mysql.sock*. +In your :file:`php.ini` you will find a line + +.. code-block:: ini + + mysql.default_socket = /tmp/mysql.sock + +change it to + +.. code-block:: ini + + mysql.default_socket = /var/lib/mysql/mysql.sock + +Then restart apache and it will work. + +Here is a fix suggested by Brad Ummer: + +* First, you need to determine what socket is being used by MySQL. To do + this, telnet to your server and go to the MySQL bin directory. In this + directory there should be a file named *mysqladmin*. Type + ``./mysqladmin variables``, and this should give you a bunch of info + about your MySQL server, including the socket (*/tmp/mysql.sock*, for + example). +* Then, you need to tell PHP to use this socket. To do this in + phpMyAdmin, you need to complete the socket information in the + :file:`config.inc.php`. For example: + :config:option:`$cfg['Servers'][$i]['socket']` Please also make sure that + the permissions of this file allow to be readable by your webserver (i.e. + '0755'). + +Have also a look at the `corresponding section of the MySQL +documentation `_. + +.. _faq2_4: + +2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do? +----------------------------------------------------------------------------------- + +Try to set the :config:option:`$cfg['OBGzip']` directive to ``false`` in the phpMyAdmin configuration +file. It helps sometime. Also have a look at your PHP version number: +if it contains "b" or "alpha" it means you're running a testing +version of PHP. That's not a so good idea, please upgrade to a plain +revision. + +.. _faq2_5: + +2.5 Each time I want to insert or change a row or drop a database or a table, an error 404 (page not found) is displayed or, with HTTP or cookie authentication, I'm asked to log in again. What's wrong? +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Check the value you set for the :config:option:`$cfg['PmaAbsoluteUri']` directive in the phpMyAdmin +configuration file. + +.. _faq2_6: + +2.6 I get an "Access denied for user: 'root@localhost' (Using password: YES)"-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost. +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +When you are using a port on your localhost, which you redirect via +port-forwarding to another host, MySQL is not resolving the localhost +as expected. Erik Wasser explains: The solution is: if your host is +"localhost" MySQL (the command line tool :command:`mysql` as well) always +tries to use the socket connection for speeding up things. And that +doesn't work in this configuration with port forwarding. If you enter +"127.0.0.1" as hostname, everything is right and MySQL uses the +:term:`TCP` connection. + +.. _faqthemes: + +2.7 Using and creating themes +----------------------------- + +Themes are configured with :config:option:`$cfg['ThemePath']`, +:config:option:`$cfg['ThemeManager']` and :config:option:`$cfg['ThemeDefault']`. +Under :config:option:`$cfg['ThemePath']`, you should not delete the +directory ``pmahomme`` or its underlying structure, because this is the +system theme used by phpMyAdmin. ``pmahomme`` contains all images and +styles, for backwards compatibility and for all themes that would not +include images or css-files. If :config:option:`$cfg['ThemeManager']` +is enabled, you can select your favorite theme on the main page. Your selected +theme will be stored in a cookie. + +To create a theme: + +* make a new subdirectory (for example "your\_theme\_name") under :config:option:`$cfg['ThemePath']` (by + default ``themes``) +* copy the files and directories from ``pmahomme`` to "your\_theme\_name" +* edit the css-files in "your\_theme\_name/css" +* put your new images in "your\_theme\_name/img" +* edit :file:`layout.inc.php` in "your\_theme\_name" +* edit :file:`info.inc.php` in "your\_theme\_name" to contain your chosen + theme name, that will be visible in user interface +* make a new screenshot of your theme and save it under + "your\_theme\_name/screen.png" + +In theme directory there is file :file:`info.inc.php` which contains theme +verbose name, theme generation and theme version. These versions and +generations are enumerated from 1 and do not have any direct +dependence on phpMyAdmin version. Themes within same generation should +be backwards compatible - theme with version 2 should work in +phpMyAdmin requiring version 1. Themes with different generation are +incompatible. + +If you do not want to use your own symbols and buttons, remove the +directory "img" in "your\_theme\_name". phpMyAdmin will use the +default icons and buttons (from the system-theme ``pmahomme``). + +.. _faqmissingparameters: + +2.8 I get "Missing parameters" errors, what can I do? +----------------------------------------------------- + +Here are a few points to check: + +* In :file:`config.inc.php`, try to leave the :config:option:`$cfg['PmaAbsoluteUri']` directive empty. See also + :ref:`faq4_7`. +* Maybe you have a broken PHP installation or you need to upgrade your + Zend Optimizer. See . +* If you are using Hardened PHP with the ini directive + ``varfilter.max_request_variables`` set to the default (200) or + another low value, you could get this error if your table has a high + number of columns. Adjust this setting accordingly. (Thanks to Klaus + Dorninger for the hint). +* In the :file:`php.ini` directive ``arg_separator.input``, a value of ";" + will cause this error. Replace it with "&;". +* If you are using `Hardened-PHP `_, you + might want to increase `request limits `_. +* The directory specified in the :file:`php.ini` directive + ``session.save_path`` does not exist or is read-only. + +.. _faq2_9: + +2.9 Seeing an upload progress bar +--------------------------------- + +To be able to see a progress bar during your uploads, your server must +have the `APC `_ extension, the +`uploadprogress `_ one, or +you must be running PHP 5.4.0 or higher. Moreover, the JSON extension +has to be enabled in your PHP. + +If using APC, you must set ``apc.rfc1867`` to ``on`` in your :file:`php.ini`. + +If using PHP 5.4.0 or higher, you must set +``session.upload_progress.enabled`` to ``1`` in your :file:`php.ini`. However, +starting from phpMyAdmin version 4.0.4, session-based upload progress has +been temporarily deactivated due to its problematic behavior. + +.. seealso:: :rfc:`1867` + +.. _faqlimitations: + +Known limitations ++++++++++++++++++ + +.. _login_bug: + +3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick. +----------------------------------------------------------------------------------------------------- + +This is related to the authentication mechanism (protocol) used by +phpMyAdmin. To bypass this problem: just close all the opened browser +windows and then go back to phpMyAdmin. You should be able to log in +again. + +.. _faq3_2: + +3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error. +---------------------------------------------------------------------------------------------------- + +Compressed dumps are built in memory and because of this are limited +to php's memory limit. For GZip/BZip2 exports this can be overcome +since 2.5.4 using :config:option:`$cfg['CompressOnFly']` (enabled by default). +Zip exports can not be handled this way, so if you need Zip files for larger +dump, you have to use another way. + +.. _faq3_3: + +3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column. +------------------------------------------------------------------------------------------- + +This is an InnoDB bug, see . + +.. _faq3_4: + +3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution. +------------------------------------------------------------------------------------------------------------- + +The problem is that older versions of ``mysqldump`` created invalid +comments like this: + +.. code-block:: mysql + + + -- MySQL dump 8.22 + -- + -- Host: localhost Database: database + --------------------------------------------------------- + -- Server version 3.23.54 + +The invalid part of the code is the horizontal line made of dashes +that appears once in every dump created with mysqldump. If you want to +run your dump you have to turn it into valid MySQL. This means, you +have to add a whitespace after the first two dashes of the line or add +a # before it: ``-- -------------------------------------------------------`` or +``#---------------------------------------------------------`` + +.. _faq3_5: + +3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner. +------------------------------------------------------------------------------------ + +Please note that you should not use the separating string multiple +times without any characters between them, or at the beginning/end of +your table name. If you have to, think about using another +TableSeparator or disabling that feature. + +.. seealso:: :config:option:`$cfg['NavigationTreeTableSeparator']` + +.. _faq3_6: + +3.6 What is currently not supported in phpMyAdmin about InnoDB? +--------------------------------------------------------------- + +In Relation view, being able to choose a table in another database, or +having more than one index column in the foreign key. In Query-by- +example (Query), automatic generation of the query LEFT JOIN from the +foreign table. + +.. _faq3_7: + +3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like "Warning: unable to parse url". How can this be fixed? +----------------------------------------------------------------------------------------------------------------------------------------------------------- + +Your table neither have a primary key nor an unique one, so we must +use a long expression to identify this row. This causes problems to +parse\_url function. The workaround is to create a primary or unique +key. + +.. _faq3_8: + +3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto! +------------------------------------------------------------------------------------------ + +Due to a surrounding form-container (for multi-row delete checkboxes), +no nested forms can be put inside the table where phpMyAdmin displays +the results. You can, however, use any form inside of a table if keep +the parent form-container with the target to tbl\_row\_delete.php and +just put your own input-elements inside. If you use a custom submit +input field, the form will submit itself to the displaying page again, +where you can validate the $HTTP\_POST\_VARS in a transformation. For +a tutorial on how to effectively use transformations, see our `Link +section `_ on the +official phpMyAdmin-homepage. + +.. _faq3_9: + +3.9 I get error messages when using "--sql\_mode=ANSI" for the MySQL server. +---------------------------------------------------------------------------- + +When MySQL is running in ANSI-compatibility mode, there are some major +differences in how :term:`SQL` is structured (see +). Most important of all, the +quote-character (") is interpreted as an identifier quote character and not as +a string quote character, which makes many internal phpMyAdmin operations into +invalid :term:`SQL` statements. There is no +workaround to this behaviour. News to this item will be posted in `Bug report +#1013 `_. + +.. _faq3_10: + +3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example ``SELECT lastname from employees where firstname like 'A%'`` and two "Smith" values are displayed), if I click Edit I cannot be sure that I am editing the intended row. +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Please make sure that your table has a primary key, so that phpMyAdmin +can use it for the Edit and Delete links. + +.. _faq3_11: + +3.11 The number of rows for InnoDB tables is not correct. +--------------------------------------------------------- + +phpMyAdmin uses a quick method to get the row count, and this method only +returns an approximate count in the case of InnoDB tables. See +:config:option:`$cfg['MaxExactCount']` for a way to modify those results, but +this could have a serious impact on performance. + +.. _faq3_12: + +3.12 (withdrawn). +----------------- + +.. _faq3_13: + +3.13 I get an error when entering ``USE`` followed by a db name containing an hyphen. +------------------------------------------------------------------------------------- + +The tests I have made with MySQL 5.1.49 shows that the API does not +accept this syntax for the USE command. + +.. _faq3_14: + +3.14 I am not able to browse a table when I don't have the right to SELECT one of the columns. +---------------------------------------------------------------------------------------------- + +This has been a known limitation of phpMyAdmin since the beginning and +it's not likely to be solved in the future. + +.. _faq3_15: + +3.15 (withdrawn). +----------------- + +.. _faq3_16: + +3.16 (withdrawn). +----------------- + +.. _faq3_17: + +3.17 (withdrawn). +----------------- + +.. _faq3_18: + +3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table. +---------------------------------------------------------------------------------------------------------- + +There is no reliable way to differentiate tables in :term:`CSV` format. For the +time being, you will have to break apart :term:`CSV` files containing multiple +tables. + +.. _faq3_19: + +3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types. +------------------------------------------------------------------------------------------------------------------------------------ + +Currently, the import type-detection system can only assign these +MySQL types to columns. In future, more will likely be added but for +the time being you will have to edit the structure to your liking +post-import. Also, you should note the fact that phpMyAdmin will use +the size of the largest item in any given column as the column size +for the appropriate type. If you know you will be adding larger items +to that column then you should manually adjust the column sizes +accordingly. This is done for the sake of efficiency. + +.. _faqmultiuser: + +ISPs, multi-user installations +++++++++++++++++++++++++++++++ + +.. _faq4_1: + +4.1 I'm an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer? +-------------------------------------------------------------------------------------------------------- + +Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your +users. The development of this feature was kindly sponsored by NetCologne GmbH. +This requires a properly setup MySQL user management and phpMyAdmin +:term:`HTTP` or cookie authentication. + +.. seealso:: :ref:`authentication_modes` + +.. _faq4_2: + +4.2 What's the preferred way of making phpMyAdmin secure against evil access? +----------------------------------------------------------------------------- + +This depends on your system. If you're running a server which cannot be +accessed by other people, it's sufficient to use the directory protection +bundled with your webserver (with Apache you can use :term:`.htaccess` files, +for example). If other people have telnet access to your server, you should use +phpMyAdmin's :term:`HTTP` or cookie authentication features. + +Suggestions: + +* Your :file:`config.inc.php` file should be ``chmod 660``. +* All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy + is a user whose password is only known to you, and apache is the group + under which Apache runs. +* Follow security recommendations for PHP and your webserver. + +.. _faq4_3: + +4.3 I get errors about not being able to include a file in */lang* or in */libraries*. +-------------------------------------------------------------------------------------- + +Check :file:`php.ini`, or ask your sysadmin to check it. The +``include_path`` must contain "." somewhere in it, and +``open_basedir``, if used, must contain "." and "./lang" to allow +normal operation of phpMyAdmin. + +.. _faq4_4: + +4.4 phpMyAdmin always gives "Access denied" when using HTTP authentication. +--------------------------------------------------------------------------- + +This could happen for several reasons: + +* :config:option:`$cfg['Servers'][$i]['controluser']` and/or :config:option:`$cfg['Servers'][$i]['controlpass']` are wrong. +* The username/password you specify in the login dialog are invalid. +* You have already setup a security mechanism for the phpMyAdmin- + directory, eg. a :term:`.htaccess` file. This would interfere with phpMyAdmin's + authentication, so remove it. + +.. _faq4_5: + +4.5 Is it possible to let users create their own databases? +----------------------------------------------------------- + +Starting with 2.2.5, in the user management page, you can enter a +wildcard database name for a user (for example "joe%"), and put the +privileges you want. For example, adding ``SELECT, INSERT, UPDATE, +DELETE, CREATE, DROP, INDEX, ALTER`` would let a user create/manage +his/her database(s). + +.. _faq4_6: + +4.6 How can I use the Host-based authentication additions? +---------------------------------------------------------- + +If you have existing rules from an old :term:`.htaccess` file, you can take them and +add a username between the ``'deny'``/``'allow'`` and ``'from'`` +strings. Using the username wildcard of ``'%'`` would be a major +benefit here if your installation is suited to using it. Then you can +just add those updated lines into the +:config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` array. + +If you want a pre-made sample, you can try this fragment. It stops the +'root' user from logging in from any networks other than the private +network :term:`IP` blocks. + +.. code-block:: php + + + //block root from logging in except from the private networks + $cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow'; + $cfg['Servers'][$i]['AllowDeny']['rules'] = array( + 'deny root from all', + 'allow root from localhost', + 'allow root from 10.0.0.0/8', + 'allow root from 192.168.0.0/16', + 'allow root from 172.16.0.0/12', + ); + +.. _faq4_7: + +4.7 Authentication window is displayed more than once, why? +----------------------------------------------------------- + +This happens if you are using a :term:`URL` to start phpMyAdmin which is +different than the one set in your :config:option:`$cfg['PmaAbsoluteUri']`. For +example, a missing "www", or entering with an :term:`IP` address while a domain +name is defined in the config file. + +.. _faq4_8: + +4.8 Which parameters can I use in the URL that starts phpMyAdmin? +----------------------------------------------------------------- + +When starting phpMyAdmin, you can use the ``db``, ``pma_username``, +``pma_password`` and ``server`` parameters. This last one can contain +either the numeric host index (from ``$i`` of the configuration file) +or one of the host names present in the configuration file. Using +``pma_username`` and ``pma_password`` has been tested along with the +usage of 'cookie' ``auth_type``. + +.. _faqbrowsers: + +Browsers or client OS ++++++++++++++++++++++ + +.. _faq5_1: + +5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns. +------------------------------------------------------------------------------------------------------------------------------ + +We could reproduce this problem only under Win98/98SE. Testing under +WinNT4 or Win2K, we could easily create more than 60 columns. A +workaround is to create a smaller number of columns, then come back to +your table properties and add the other columns. + +.. _faq5_2: + +5.2 With Xitami 2.5b4, phpMyAdmin won't process form fields. +------------------------------------------------------------ + +This is not a phpMyAdmin problem but a Xitami known bug: you'll face +it with each script/website that use forms. Upgrade or downgrade your +Xitami server. + +.. _faq5_3: + +5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2). +--------------------------------------------------------------------- + +With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except +that the proposed file name for the dump is always 'tbl\_dump.php'. +Bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps +work; zip dumps are placed into the user's temporary directory, so +they must be moved before closing Konqueror, or else they disappear. +GZip dumps give an error message. Testing needs to be done for +Konqueror 2.2.2. + +.. _faq5_4: + +5.4 I can't use the cookie authentication mode because Internet Explorer never stores the cookies. +-------------------------------------------------------------------------------------------------- + +MS Internet Explorer seems to be really buggy about cookies, at least +till version 6. + +.. _faq5_5: + +5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows. +---------------------------------------------------------------------------- + +Upgrade to at least Internet Explorer 5.5 SP2. + +.. _faq5_6: + +5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like "Page not found") when trying to modify a row in a table with many columns, or with a text column. +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Your table neither have a primary key nor an unique one, so we must use a long +:term:`URL` to identify this row. There is a limit on the length of the +:term:`URL` in those browsers, and this not happen in Netscape, for example. +The workaround is to create a primary or unique key, or use another browser. + +.. _faq5_7: + +5.7 I refresh (reload) my browser, and come back to the welcome page. +--------------------------------------------------------------------- + +Some browsers support right-clicking into the frame you want to +refresh, just do this in the right frame. + +.. _faq5_8: + +5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box. +--------------------------------------------------------------------------------- + +Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future +Mozilla versions. + +.. _faq5_9: + +5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can't type a whitespace in the SQL-Query edit area: the page scrolls down. +------------------------------------------------------------------------------------------------------------------------------- + +This is a Mozilla bug (see bug #26882 at `BugZilla +`_). + +.. _faq5_10: + +5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file. +----------------------------------------------------------------------------------------- + +This is a known Netscape 4.75 bug: it adds some line feeds when +exporting data in octet-stream mode. Since we can't detect the +specific Netscape version, we cannot workaround this bug. + +.. _faq5_11: + +5.11 Extended-ASCII characters like German umlauts are displayed wrong. +----------------------------------------------------------------------- + +Please ensure that you have set your browser's character set to the +one of the language file you have selected on phpMyAdmin's start page. +Alternatively, you can try the auto detection mode that is supported +by the recent versions of the most browsers. + +.. _faq5_12: + +5.12 Mac OS X Safari browser changes special characters to "?". +--------------------------------------------------------------- + +This issue has been reported by a :term:`Mac OS X` user, who adds that Chimera, +Netscape and Mozilla do not have this problem. + +.. _faq5_13: + +5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation. +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +This is a bug in Internet Explorer, other browsers do not behave this +way. + +.. _faq5_14: + +5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen. +------------------------------------------------------------------------------------------------------------------ + +Please upgrade to Opera7 at least. + +.. _faq5_15: + +5.15 I have display problems with Safari. +----------------------------------------- + +Please upgrade to at least version 1.2.3. + +.. _faq5_16: + +5.16 With Internet Explorer, I get "Access is denied" Javascript errors. Or I cannot make phpMyAdmin work under Windows. +------------------------------------------------------------------------------------------------------------------------ + +Please check the following points: + +* Maybe you have defined your :config:option:`$cfg['PmaAbsoluteUri']` setting in + :file:`config.inc.php` to an :term:`IP` address and you are starting phpMyAdmin + with a :term:`URL` containing a domain name, or the reverse situation. +* Security settings in IE and/or Microsoft Security Center are too high, + thus blocking scripts execution. +* The Windows Firewall is blocking Apache and MySQL. You must allow + :term:`HTTP` ports (80 or 443) and MySQL + port (usually 3306) in the "in" and "out" directions. + +.. _faq5_17: + +5.17 With Firefox, I cannot delete rows of data or drop a database. +------------------------------------------------------------------- + +Many users have confirmed that the Tabbrowser Extensions plugin they +installed in their Firefox is causing the problem. + +.. _faq5_18: + +5.18 With Konqueror 4.2.x an invalid ``LIMIT`` clause is generated when I browse a table. +----------------------------------------------------------------------------------------- + +This happens only when both of these conditions are met: using the +``http`` authentication mode and ``register_globals`` being set to +``On`` on the server. It seems to be a browser-specific problem; +meanwhile use the ``cookie`` authentication mode. + +.. _faq5_19: + +5.19 I get JavaScript errors in my browser. +------------------------------------------- + +Issues have been reported with some combinations of browser +extensions. To troubleshoot, disable all extensions then clear your +browser cache to see if the problem goes away. + +.. _faqusing: + +Using phpMyAdmin +++++++++++++++++ + +.. _faq6_1: + +6.1 I can't insert new rows into a table / I can't create a table - MySQL brings up a SQL error. +------------------------------------------------------------------------------------------------ + +Examine the :term:`SQL` error with care. +Often the problem is caused by specifying a wrong column-type. Common +errors include: + +* Using ``VARCHAR`` without a size argument +* Using ``TEXT`` or ``BLOB`` with a size argument + +Also, look at the syntax chapter in the MySQL manual to confirm that +your syntax is correct. + +.. _faq6_2: + +6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns. +------------------------------------------------------------------------------------------------------------------------- + +This is the way to create a multi-columns index. If you want two +indexes, create the first one when creating the table, save, then +display the table properties and click the Index link to create the +other index. + +.. _faq6_3: + +6.3 How can I insert a null value into my table? +------------------------------------------------ + +Since version 2.2.3, you have a checkbox for each column that can be +null. Before 2.2.3, you had to enter "null", without the quotes, as +the column's value. Since version 2.5.5, you have to use the checkbox +to get a real NULL value, so if you enter "NULL" this means you want a +literal NULL in the column, and not a NULL value (this works in PHP4). + +.. _faq6_4: + +6.4 How can I backup my database or table? +------------------------------------------ + +Click on a database or table name in the navigation panel, the properties will +be displayed. Then on the menu, click "Export", you can dump the structure, the +data, or both. This will generate standard :term:`SQL` statements that can be +used to recreate your database/table. You will need to choose "Save as file", +so that phpMyAdmin can transmit the resulting dump to your station. Depending +on your PHP configuration, you will see options to compress the dump. See also +the :config:option:`$cfg['ExecTimeLimit']` configuration variable. For +additional help on this subject, look for the word "dump" in this document. + +.. _faq6_5: + +6.5 How can I restore (upload) my database or table using a dump? How can I run a ".sql" file? +---------------------------------------------------------------------------------------------- + +Click on a database name in the navigation panel, the properties will +be displayed. Select "Import" from the list of tabs in the right–hand +frame (or ":term:`SQL`" if your phpMyAdmin +version is previous to 2.7.0). In the "Location of the text file" +section, type in the path to your dump filename, or use the Browse +button. Then click Go. With version 2.7.0, the import engine has been +re–written, if possible it is suggested that you upgrade to take +advantage of the new features. For additional help on this subject, +look for the word "upload" in this document. + +.. _faq6_6: + +6.6 How can I use the relation table in Query-by-example? +--------------------------------------------------------- + +Here is an example with the tables persons, towns and countries, all +located in the database mydb. If you don't have a ``pma__relation`` +table, create it as explained in the configuration section. Then +create the example tables: + +.. code-block:: mysql + + + CREATE TABLE REL_countries ( + country_code char(1) NOT NULL default '', + description varchar(10) NOT NULL default '', + PRIMARY KEY (country_code) + ) TYPE=MyISAM; + + INSERT INTO REL_countries VALUES ('C', 'Canada'); + + CREATE TABLE REL_persons ( + id tinyint(4) NOT NULL auto_increment, + person_name varchar(32) NOT NULL default '', + town_code varchar(5) default '0', + country_code char(1) NOT NULL default '', + PRIMARY KEY (id) + ) TYPE=MyISAM; + + INSERT INTO REL_persons VALUES (11, 'Marc', 'S', ''); + INSERT INTO REL_persons VALUES (15, 'Paul', 'S', 'C'); + + CREATE TABLE REL_towns ( + town_code varchar(5) NOT NULL default '0', + description varchar(30) NOT NULL default '', + PRIMARY KEY (town_code) + ) TYPE=MyISAM; + + INSERT INTO REL_towns VALUES ('S', 'Sherbrooke'); + INSERT INTO REL_towns VALUES ('M', 'Montréal'); + +To setup appropriate links and display information: + +* on table "REL\_persons" click Structure, then Relation view +* in Links, for "town\_code" choose "REL\_towns->code" +* in Links, for "country\_code" choose "REL\_countries->country\_code" +* on table "REL\_towns" click Structure, then Relation view +* in "Choose column to display", choose "description" +* repeat the two previous steps for table "REL\_countries" + +Then test like this: + +* Click on your db name in the navigation panel +* Choose "Query" +* Use tables: persons, towns, countries +* Click "Update query" +* In the columns row, choose persons.person\_name and click the "Show" + tickbox +* Do the same for towns.description and countries.descriptions in the + other 2 columns +* Click "Update query" and you will see in the query box that the + correct joins have been generated +* Click "Submit query" + +.. _faqdisplay: + +6.7 How can I use the "display column" feature? +----------------------------------------------- + +Starting from the previous example, create the ``pma__table_info`` as +explained in the configuration section, then browse your persons +table, and move the mouse over a town code or country code. See also +:ref:`faq6_21` for an additional feature that "display column" +enables: drop-down list of possible values. + +.. _faqpdf: + +6.8 How can I produce a PDF schema of my database? +-------------------------------------------------- + +First the configuration variables "relation", "table\_coords" and +"pdf\_pages" have to be filled in. Then you need to think about your +schema layout. Which tables will go on which pages? + +* Select your database in the navigation panel. +* Choose "Operations" in the navigation bar at the top. +* Choose "Edit :term:`PDF` Pages" near the + bottom of the page. +* Enter a name for the first :term:`PDF` page + and click Go. If you like, you can use the "automatic layout," which + will put all your linked tables onto the new page. +* Select the name of the new page (making sure the Edit radio button is + selected) and click Go. +* Select a table from the list, enter its coordinates and click Save. + Coordinates are relative; your diagram will be automatically scaled to + fit the page. When initially placing tables on the page, just pick any + coordinates -- say, 50x50. After clicking Save, you can then use the + :ref:`wysiwyg` to position the element correctly. +* When you'd like to look at your :term:`PDF`, first be sure to click the Save + button beneath the list of tables and coordinates, to save any changes you + made there. Then scroll all the way down, select the :term:`PDF` options you + want, and click Go. +* Internet Explorer for Windows may suggest an incorrect filename when + you try to save a generated :term:`PDF`. + When saving a generated :term:`PDF`, be + sure that the filename ends in ".pdf", for example "schema.pdf". + Browsers on other operating systems, and other browsers on Windows, do + not have this problem. + +.. _faq6_9: + +6.9 phpMyAdmin is changing the type of one of my columns! +--------------------------------------------------------- + +No, it's MySQL that is doing `silent column type changing +`_. + +.. _underscore: + +6.10 When creating a privilege, what happens with underscores in the database name? +----------------------------------------------------------------------------------- + +If you do not put a backslash before the underscore, this is a +wildcard grant, and the underscore means "any character". So, if the +database name is "john\_db", the user would get rights to john1db, +john2db ... If you put a backslash before the underscore, it means +that the database name will have a real underscore. + +.. _faq6_11: + +6.11 What is the curious symbol ø in the statistics pages? +---------------------------------------------------------- + +It means "average". + +.. _faqexport: + +6.12 I want to understand some Export options. +---------------------------------------------- + +**Structure:** + +* "Add DROP TABLE" will add a line telling MySQL to `drop the table + `_, if it already + exists during the import. It does NOT drop the table after your + export, it only affects the import file. +* "If Not Exists" will only create the table if it doesn't exist. + Otherwise, you may get an error if the table name exists but has a + different structure. +* "Add AUTO\_INCREMENT value" ensures that AUTO\_INCREMENT value (if + any) will be included in backup. +* "Enclose table and column names with backquotes" ensures that column + and table names formed with special characters are protected. +* "Add into comments" includes column comments, relations, and MIME + types set in the pmadb in the dump as :term:`SQL` comments + (*/\* xxx \*/*). + +**Data:** + +* "Complete inserts" adds the column names on every INSERT command, for + better documentation (but resulting file is bigger). +* "Extended inserts" provides a shorter dump file by using only once the + INSERT verb and the table name. +* "Delayed inserts" are best explained in the `MySQL manual - INSERT DELAYED Syntax + `_. +* "Ignore inserts" treats errors as a warning instead. Again, more info + is provided in the `MySQL manual - INSERT Syntax + `_, but basically with + this selected, invalid values are adjusted and inserted rather than + causing the entire statement to fail. + +.. _faq6_13: + +6.13 I would like to create a database with a dot in its name. +-------------------------------------------------------------- + +This is a bad idea, because in MySQL the syntax "database.table" is +the normal way to reference a database and table name. Worse, MySQL +will usually let you create a database with a dot, but then you cannot +work with it, nor delete it. + +.. _faqsqlvalidator: + +6.14 How do I set up the SQL Validator? +--------------------------------------- + +To use SQL Validator, you need PHP with :term:`XML`, :term:`PCRE` and +:term:`PEAR` support. In addition you need a :term:`SOAP` support, either as a +PHP extension or as a PEAR SOAP module. + +To install :term:`PEAR` :term:`SOAP` module, run :command:`pear install +Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP` to get the necessary +:term:`PEAR` modules for usage. + +If you use the Validator, you should be aware that any :term:`SQL` statement +you submit will be stored anonymously (database/table/column names, strings, +numbers replaced with generic values). The Mimer :term:`SQL` Validator itself, +is © 2001 Upright Database Technology. We utilize it as free SOAP service. + +.. _faq6_15: + +6.15 I want to add a BLOB column and put an index on it, but MySQL says "BLOB column '...' used in key specification without a key length". +------------------------------------------------------------------------------------------------------------------------------------------- + +The right way to do this, is to create the column without any indexes, +then display the table structure and use the "Create an index" dialog. +On this page, you will be able to choose your BLOB column, and set a +size to the index, which is the condition to create an index on a BLOB +column. + +.. _faq6_16: + +6.16 How can I simply move in page with plenty editing fields? +-------------------------------------------------------------- + +You can use :kbd:`Ctrl+arrows` (:kbd:`Option+Arrows` in Safari) for moving on +most pages with many editing fields (table structure changes, row editing, +etc.). + +.. _faq6_17: + +6.17 Transformations: I can't enter my own mimetype! WTF is this feature then useful for? +----------------------------------------------------------------------------------------- + +Slow down :). Defining mimetypes is of no use, if you can't put +transformations on them. Otherwise you could just put a comment on the +column. Because entering your own mimetype will cause serious syntax +checking issues and validation, this introduces a high-risk false- +user-input situation. Instead you have to initialize mimetypes using +functions or empty mimetype definitions. + +Plus, you have a whole overview of available mimetypes. Who knows all those +mimetypes by heart so he/she can enter it at will? + +.. _faqbookmark: + +6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What is this variable for? +-------------------------------------------------------------------------------------------------------------------------- + +Any query you have executed can be stored as a bookmark on the page +where the results are displayed. You will find a button labeled +'Bookmark this query' just at the end of the page. As soon as you have +stored a bookmark, it is related to the database you run the query on. +You can now access a bookmark dropdown on each page, the query box +appears on for that database. + +You can also have, inside the query, a placeholder for a variable. +This is done by inserting into the query a SQL comment between ``/*`` and +``*/``. Inside the comment, the special string ``[VARIABLE]`` is used. +Be aware that the whole query minus the SQL comment must be +valid by itself, otherwise you won't be able to store it as a bookmark. + +When you execute the bookmark, everything typed into the *value* +input box on the query box page will replace the string ``/*[VARIABLE]*/`` in +your stored query. + +Also remember, that everything else inside the ``/*[VARIABLE]*/`` string for +your query will remain the way it is, but will be stripped of the ``/**/`` +chars. So you can use: + +.. code-block:: mysql + + /*, [VARIABLE] AS myname */ + +which will be expanded to + +.. code-block:: mysql + + , VARIABLE as myname + +in your query, where VARIABLE is the string you entered in the input box. If an +empty string is provided, no replacements are made. + +A more complex example. Say you have stored +this query: + +.. code-block:: mysql + + SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */ + +Say, you now enter "phpMyAdmin" as the variable for the stored query, the full +query will be: + +.. code-block:: mysql + + SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%' + +You can use multiple occurrences of ``/*[VARIABLE]*/`` in a single query +(that is, multiple occurrences of the *same* variable). + +**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces +inserted there will be later also inserted as spaces in your query and may lead +to unexpected results especially when using the variable expansion inside of a +"LIKE ''" expression. + +Your initial query which is going to be stored as a bookmark has to yield at +least one result row so you can store the bookmark. You may have that to work +around using well positioned ``/**/`` comments. + +.. _faq6_19: + +6.19 How can I create simple LATEX document to include exported table? +---------------------------------------------------------------------- + +You can simply include table in your LATEX documents, +minimal sample document should look like following one (assuming you +have table exported in file :file:`table.tex`): + +.. code-block:: latex + + + \documentclass{article} % or any class you want + \usepackage{longtable} % for displaying table + \begin{document} % start of document + \include{table} % including exported table + \end{document} % end of document + +.. _faq6_20: + +6.20 I see a lot of databases which are not mine, and cannot access them. +------------------------------------------------------------------------- + +You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW +DATABASES, LOCK TABLES. Those privileges also enable users to see all the +database names. So if your users do not need those privileges, you can remove +them and their databases list will shorten. + +.. seealso:: + +.. _faq6_21: + +6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table? +------------------------------------------------------------------------------------------------------------ + +You have to setup appropriate links between the tables, and also setup +the "display column" in the foreign table. See :ref:`faq6_6` for an +example. Then, if there are 100 values or less in the foreign table, a +drop-down list of values will be available. You will see two lists of +values, the first list containing the key and the display column, the +second list containing the display column and the key. The reason for +this is to be able to type the first letter of either the key or the +display column. For 100 values or more, a distinct window will appear, +to browse foreign key values and choose one. To change the default +limit of 100, see :config:option:`$cfg['ForeignKeyMaxLimit']`. + + +.. _faq6_22: + +6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table? +----------------------------------------------------------------------------------------------------- + +Yes. If a bookmark has the same label as a table name and it's not a +public bookmark, it will be executed. + +.. _faq6_23: + +6.23 Export: I heard phpMyAdmin can export Microsoft Excel files? +----------------------------------------------------------------- + +You can use :term:`CSV` for Microsoft Excel, +which works out of the box. + +.. versionchanged:: 3.4.5 + Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version + 97 and newer was dropped. + +.. _faq6_24: + +6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb? +------------------------------------------------------------------------------------------------------------------------- + +Automatic migration of a table's pmadb-style column comments to the +native ones is done whenever you enter Structure page for this table. + +.. _faq6_25: + +6.25 (withdrawn). +----------------- + +.. _faq6_26: + +6.26 How can I select a range of rows? +-------------------------------------- + +Click the first row of the range, hold the shift key and click the +last row of the range. This works everywhere you see rows, for example +in Browse mode or on the Structure page. + +.. _faq6_27: + +6.27 What format strings can I use? +----------------------------------- + +In all places where phpMyAdmin accepts format strings, you can use +``@VARIABLE@`` expansion and `strftime `_ +format strings. The expanded variables depend on a context (for +example, if you haven't chosen a table, you can not get the table +name), but the following variables can be used: + +``@HTTP_HOST@`` + HTTP host that runs phpMyAdmin +``@SERVER@`` + MySQL server name +``@VERBOSE@`` + Verbose MySQL server name as defined in :config:option:`$cfg['Servers'][$i]['verbose']` +``@VSERVER@`` + Verbose MySQL server name if set, otherwise normal +``@DATABASE@`` + Currently opened database +``@TABLE@`` + Currently opened table +``@COLUMNS@`` + Columns of the currently opened table +``@PHPMYADMIN@`` + phpMyAdmin with version + +.. _wysiwyg: + +6.28 How can I easily edit relational schema for export? +-------------------------------------------------------- + +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. + +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. + +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. + +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. + +.. _faq6_29: + +6.29 Why can't I get a chart from my query result table? +-------------------------------------------------------- + +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 `wiki `_. + +.. _faq6_30: + +6.30 Import: How can I import ESRI Shapefiles +--------------------------------------------- + +An ESRI Shapefile is actually a set of several files, where .shp file +contains geometry data and .dbf file contains data related to those +geometry data. To read data from .dbf file you need to have PHP +compiled with the dBase extension (--enable-dbase). Otherwise only +geometry data will be imported. + +To upload these set of files you can use either of the following +methods: + +Configure upload directory with :config:option:`$cfg['UploadDir']`, upload both .shp and .dbf files with +the same filename and chose the .shp file from the import page. + +Create a Zip archive with .shp and .dbf files and import it. For this +to work, you need to set :config:option:`$cfg['TempDir']` to a place where the web server user can +write (for example ``'./tmp'``). + +To create the temporary directory on a UNIX-based system, you can do: + +.. code-block:: sh + + cd phpMyAdmin + mkdir tmp + chmod o+rwx tmp + +.. _faq6_31: + +6.31 How do I create a relation in designer? +-------------------------------------------- + +To select relation, click: The display column is shown in pink. To +set/unset a column as the display column, click the "Choose column to +display" icon, then click on the appropriate column name. + +.. _faq6_32: + +6.32 How can I use the zoom search feature? +------------------------------------------- + +The Zoom search feature is an alternative to table search feature. It allows +you to explore a table by representing its data in a scatter plot. You can +locate this feature by selecting a table and clicking the :guilabel:`Search` +tab. One of the sub-tabs in the :guilabel:`Table Search` page is +:guilabel:`Zoom Search`. + +Consider the table REL\_persons in :ref:`faq6_6` for +an example. To use zoom search, two columns need to be selected, for +example, id and town\_code. The id values will be represented on one +axis and town\_code values on the other axis. Each row will be +represented as a point in a scatter plot based on its id and +town\_code. You can include two additional search criteria apart from +the two fields to display. + +You can choose which field should be +displayed as label for each point. If a display column has been set +for the table (see :ref:`faqdisplay`), it is taken as the label unless +you specify otherwise. You can also select the maximum number of rows +you want to be displayed in the plot by specifing it in the 'Max rows +to plot' field. Once you have decided over your criteria, click 'Go' +to display the plot. + +After the plot is generated, you can use the +mousewheel to zoom in and out of the plot. In addition, panning +feature is enabled to navigate through the plot. You can zoom-in to a +certail level of detail and use panning to locate your area of +interest. Clicking on a point opens a dialogue box, displaying field +values of the data row represented by the point. You can edit the +values if required and click on submit to issue an update query. Basic +instructions on how to use can be viewed by clicking the 'How to use?' +link located just above the plot. + +.. _faq6_33: + +6.33 When browsing a table, how can I copy a column name? +--------------------------------------------------------- + +Selecting the name of the column within the browse table header cell +for copying is difficult, as the columns support reordering by +dragging the header cells as well as sorting by clicking on the linked +column name. To copy a column name, double-click on the empty area +next to the column name, when the tooltip tells you to do so. This +will show you an input box with the column name. You may right-click +the column name within this input box to copy it to your clipboard. + +.. _faqproject: + +phpMyAdmin project +++++++++++++++++++ + +.. _faq7_1: + +7.1 I have found a bug. How do I inform developers? +--------------------------------------------------- + +Our Bug Tracker is located at under the +Bugs section. But please first discuss your bug with other users: +. + +.. _faq7_2: + +7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start? +--------------------------------------------------------------------------------------------------------- + +Translations are very welcome and all you need to have are the +language skills. The easiest way is to use our `online translation +service `_. You can check +out all the possibilities to translate in the `translate section on +our website `_. + +.. _faq7_3: + +7.3 I would like to help out with the development of phpMyAdmin. How should I proceed? +-------------------------------------------------------------------------------------- + +We welcome every contribution to the development of phpMyAdmin. You +can check out all the possibilities to contribute in the `contribute +section on our website +`_. + +.. seealso:: :ref:`developers` + +.. _faqsecurity: + +Security +++++++++ + +.. _faq8_1: + +8.1 Where can I get information about the security alerts issued for phpMyAdmin? +-------------------------------------------------------------------------------- + +Please refer to . + +.. _faq8_2: + +8.2 How can I protect phpMyAdmin against brute force attacks? +------------------------------------------------------------- + +If you use Apache web server, phpMyAdmin exports information about +authentication to the Apache environment and it can be used in Apache +logs. Currently there are two variables available: + + +``userID`` + User name of currently active user (he does not have to be logged in). +``userStatus`` + Status of currently active user, one of ``ok`` (user is logged in), + ``mysql-denied`` (MySQL denied user login), ``allow-denied`` (user denied + by allow/deny rules), ``root-denied`` (root is denied in configuration), + ``empty-denied`` (empty password is denied). + +``LogFormat`` directive for Apache can look like following: + +.. code-block:: apache + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n" pma_combined + +You can then use any log analyzing tools to detect possible break-in +attempts. + +.. _faqsynchronization: + +Synchronization ++++++++++++++++ + +.. _faq9_1: + +9.1 (withdrawn). +---------------- + +.. _faq9_2: + +9.2 (withdrawn). +---------------- + diff --git a/phpmyadmin/doc/html/_sources/glossary.txt b/phpmyadmin/doc/html/_sources/glossary.txt new file mode 100644 index 000000000..d558b4405 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/glossary.txt @@ -0,0 +1,406 @@ +.. _glossary: + +Glossary +======== + +From Wikipedia, the free encyclopedia + +.. glossary:: + + .htaccess + the default name of Apache's directory-level configuration file. + + .. seealso:: + + ACL + Access Contol List + + Blowfish + a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier. + + .. seealso:: + + Browser + a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web. + + .. seealso:: + + bzip2 + a free software/open source data compression algorithm and program developed by Julian Seward. + + .. seealso:: + + CGI + Common Gateway Interface is an important World Wide Web technology that + enables a client web browser to request data from a program executed on + the Web server. + + .. seealso:: + + Changelog + a log or record of changes made to a project. + + .. seealso:: + + Client + a computer system that accesses a (remote) service on another computer by some kind of network. + + .. seealso:: + + column + a set of data values of a particular simple type, one for each row of the table. + + .. seealso:: + + Cookie + a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server. + + .. seealso:: + + CSV + Comma- separated values + + .. seealso:: + + DB + look at :term:`database` + + database + an organized collection of data. + + .. seealso:: + + Engine + look at :term:`storage engines` + + extension + a PHP module that extends PHP with additional functionality. + + .. seealso:: + + FAQ + Frequently Asked Questions is a list of commonly asked question and there + answers. + + .. seealso:: + + Field + one part of divided data/columns. + + .. seealso:: + + foreign key + a column or group of columns in a database row that point to a key column + or group of columns forming a key of another database row in some + (usually different) table. + + .. seealso:: + + FPDF + the free :term:`PDF` library + + .. seealso:: + + GD + Graphics Library by Thomas Boutell and others for dynamically manipulating images. + + .. seealso:: + + GD2 + look at :term:`gd` + + gzip + gzip is short for GNU zip, a GNU free software file compression program. + + .. seealso:: + + host + any machine connected to a computer network, a node that has a hostname. + + .. seealso:: + + hostname + the unique name by which a network attached device is known on a network. + + .. seealso:: + + HTTP + HyperText Transfer Protocol is the primary method used to transfer or + convey information on the World Wide Web. + + .. seealso:: + + https + a :term:`HTTP`-connection with additional security measures. + + .. seealso:: + + IEC + International Electrotechnical Commission + + IIS + Internet Information Services is a set of Internet-based services for + servers using Microsoft Windows. + + .. seealso:: + + Index + a feature that allows quick access to the rows in a table. + + .. seealso:: + + IP + Internet Protocol is a data-oriented protocol used by source and + destination hosts for communicating data across a packet-switched + internetwork. + + .. seealso:: + + IP Address + a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard. + + .. seealso:: + + IPv6 + IPv6 (Internet Protocol version 6) is the latest revision of the + Internet Protocol (:term:`IP`), designed to deal with the + long-anticipated problem of its precedessor IPv4 running out of addresses. + + .. seealso:: + + ISAPI + Internet Server Application Programming Interface is the API of Internet Information Services (IIS). + + .. seealso:: + + ISP + Internet service provider is a business or organization that offers users + access to the Internet and related services. + + .. seealso:: + + ISO + International Standards Organisation + + JPEG + a most commonly used standard method of lossy compression for photographic images. + + .. seealso:: + + JPG + look at :term:`jpeg` + + Key + look at :term:`index` + + LATEX + a document preparation system for the TEX typesetting program. + + .. seealso:: + + Mac + Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer. + + .. seealso:: + + Mac OS X + the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets. + + .. seealso:: + + MCrypt + a cryptographic library. + + .. seealso:: + + mcrypt + the MCrypt PHP extension. + + .. seealso:: + + MIME + Multipurpose Internet Mail Extensions is + an Internet Standard for the format of e-mail. + + .. seealso:: + + module + some sort of extension for the Apache Webserver. + + .. seealso:: + + MySQL + a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS). + + .. seealso:: + + mysqli + the improved MySQL client PHP extension. + + .. seealso:: + + mysql + the MySQL client PHP extension. + + .. seealso:: + + OpenDocument + open standard for office documents. + + .. seealso:: + + OS X + look at :term:`Mac OS X`. + + .. seealso:: + + PDF + Portable Document Format is a file format developed by Adobe Systems for + representing two dimensional documents in a device independent and + resolution independent format. + + .. seealso:: + + PEAR + the PHP Extension and Application Repository. + + .. seealso:: + + PCRE + Perl Compatible Regular Expressions is the perl-compatible regular + expression functions for PHP + + .. seealso:: + + PHP + short for "PHP: Hypertext Preprocessor", is an open-source, reflective + programming language used mainly for developing server-side applications + and dynamic web content, and more recently, a broader range of software + applications. + + .. seealso:: + + port + a connection through which data is sent and received. + + .. seealso:: + + RFC + Request for Comments (RFC) documents are a series of memoranda + encompassing new research, innovations, and methodologies applicable to + Internet technologies. + + .. seealso:: + + RFC 1952 + GZIP file format specification version 4.3 + + .. seealso:: :rfc:`1952` + + Row (record, tuple) + represents a single, implicitly structured data item in a table. + + .. seealso:: + + Server + a computer system that provides services to other computing systems over a network. + + .. seealso:: + + Storage Engines + handlers for different table types + + .. seealso:: + + SOAP + Simple Object Access Protocol is a protocol specification for exchanging + structured information in the implementation of Web Services in computer + networks. + + .. seealso:: + + socket + a form of inter-process communication. + + .. seealso:: + + SSL + Secure Sockets Layer is a cryptographic protocol which provides secure + communication on the Internet. + + .. seealso:: + + Stored procedure + a subroutine available to applications accessing a relational database system + + .. seealso:: + + SQL + Structured Query Language + + .. seealso:: + + table + a set of data elements (cells) that is organized, defined and stored as + horizontal rows and vertical columns where each item can be uniquely + identified by a label or key or by it?s position in relation to other + items. + + .. seealso:: + + tar + a type of archive file format: the Tape ARchive format. + + .. seealso:: + + TCP + Transmission Control Protocol is one of the core protocols of the + Internet protocol suite. + + .. seealso:: + + TCPDF + Rewrite of :term:`UFPDF` with various improvements. + + .. seealso:: + + trigger + a procedural code that is automatically executed in response to certain events on a particular table or view in a database + + .. seealso:: + + UFPDF + Unicode/UTF-8 extension for :term:`FPDF` + + .. seealso:: + + URL + Uniform Resource Locator is a sequence of characters, conforming to a + standardized format, that is used for referring to resources, such as + documents and images on the Internet, by their location. + + .. seealso:: + + Webserver + A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages. + + .. seealso:: + + XML + Extensible Markup Language is a W3C-recommended general- purpose markup + language for creating special-purpose markup languages, capable of + describing many different kinds of data. + + .. seealso:: + + ZIP + a popular data compression and archival format. + + .. seealso:: + + zlib + an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler. + + .. seealso:: + + diff --git a/phpmyadmin/doc/html/_sources/index.txt b/phpmyadmin/doc/html/_sources/index.txt new file mode 100644 index 000000000..917ddf810 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/index.txt @@ -0,0 +1,32 @@ +.. phpMyAdmin documentation master file, created by + sphinx-quickstart on Wed Sep 26 14:04:48 2012. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phpMyAdmin's documentation! +====================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + intro + require + setup + config + user + faq + developers + vendors + copyright + credits + glossary + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` +* :ref:`glossary` diff --git a/phpmyadmin/doc/html/_sources/intro.txt b/phpmyadmin/doc/html/_sources/intro.txt new file mode 100644 index 000000000..9d81e44a4 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/intro.txt @@ -0,0 +1,68 @@ +.. _intro: + +Introduction +============ + +phpMyAdmin can manage a whole MySQL server (needs a super-user) as +well as a single database. To accomplish the latter you'll need a +properly set up MySQL user who can read/write only the desired +database. It's up to you to look up the appropriate part in the MySQL +manual. + + +Supported features +------------------ + +Currently phpMyAdmin can: + +* browse and drop databases, tables, views, columns and indexes +* display multiple results sets through stored procedures or queries +* create, copy, drop, rename and alter databases, tables, columns and + indexes +* maintenance server, databases and tables, with proposals on server + configuration +* execute, edit and bookmark any :term:`SQL`-statement, even batch-queries +* load text files into tables +* create [#f1]_ and read dumps of tables +* export [#f1]_ data to various formats: :term:`CSV`, :term:`XML`, :term:`PDF`, + :term:`ISO`/:term:`IEC` 26300 - :term:`OpenDocument` Text and Spreadsheet, Microsoft + Word 2000, and LATEX formats +* import data and :term:`MySQL` structures from :term:`OpenDocument` spreadsheets, as + well as :term:`XML`, :term:`CSV`, and :term:`SQL` files +* administer multiple servers +* manage MySQL users and privileges +* check referential integrity in MyISAM tables +* using Query-by-example (QBE), create complex queries automatically + connecting required tables +* create :term:`PDF` graphics of your + database layout +* search globally in a database or a subset of it +* transform stored data into any format using a set of predefined + functions, like displaying BLOB-data as image or download-link +* track changes on databases, tables and views +* support InnoDB tables and foreign keys see :ref:`faq3_6` +* support mysqli, the improved MySQL extension see :ref:`faq1_17` +* create, edit, call, export and drop stored procedures and functions +* create, edit, export and drop events and triggers +* communicate in `62 different languages + `_ + + +A word about users +------------------ + +Many people have difficulty understanding the concept of user +management with regards to phpMyAdmin. When a user logs in to +phpMyAdmin, that username and password are passed directly to MySQL. +phpMyAdmin does no account management on its own (other than allowing +one to manipulate the MySQL user account information); all users must +be valid MySQL users. + +.. rubric:: Footnotes + +.. [#f1] + + phpMyAdmin can compress (:term:`Zip`, :term:`GZip` :term:`RFC 1952` or + :term:`Bzip2` formats) dumps and :term:`CSV` exports if you use PHP with + :term:`Zlib` support (``--with-zlib``) and/or :term:`Bzip2` support + (``--with-bz2``). Proper support may also need changes in :file:`php.ini`. diff --git a/phpmyadmin/doc/html/_sources/other.txt b/phpmyadmin/doc/html/_sources/other.txt new file mode 100644 index 000000000..aa9545121 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/other.txt @@ -0,0 +1,18 @@ +Other sources of information +============================ + +Printed Book +------------ + +The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for +Effective MySQL Management by Marc Delisle. You can get information on that +book and other officially endorsed `books at the phpMyAdmin site`_. + +.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books + +Tutorials +--------- + +Third party tutorials and articles are listed on our `wiki page`_. + +.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles diff --git a/phpmyadmin/doc/html/_sources/privileges.txt b/phpmyadmin/doc/html/_sources/privileges.txt new file mode 100644 index 000000000..0c12932d0 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/privileges.txt @@ -0,0 +1,50 @@ +User management +=============== + +User management is the process of controlling which users are allowed to +connect to the MySQL server and what permissions they have on each database. +phpMyAdmin does not handle user management, rather it passes the username and +password on to MySQL, which then determines whether a user is permitted to +perform a particular action. Within phpMyAdmin, administrators have full +control over creating users, viewing and editing privileges for existing users, +and removing users. + +Within phpMyAdmin, user management is controlled via the :guilabel:`Users` link +from the main page. Users can be created, edited, and removed. + +Creating a new user +------------------- + +To create a new user, click the :guilabel:`Add a new user` link near the bottom +of the :guilabel:`Users` page (you must be a "superuser", e.g., user "root"). +Use the textboxes and drop-downs to configure the user to your particular +needs. You can then select whether to create a database for that user and grant +specific global privileges. Once you've created the user (by clicking Go), you +can define that user's permissions on a specific database (don't grant global +privileges in that case). In general, users do not need any global privileges +(other than USAGE), only permissions for their specific database. + +Editing an existing user +------------------------ + +To edit an existing user, simply click the pencil icon to the right of that +user in the :guilabel:`Users` page. You can then edit their global- and +database-specific privileges, change their password, or even copy those +privileges to a new user. + +Deleting a user +--------------- + +From the :guilabel:`Users` page, check the checkbox for the user you wish to +remove, select whether or not to also remove any databases of the same name (if +they exist), and click Go. + +Assigning privileges to user for a specific database +---------------------------------------------------- + +Users are assigned to databases by editing the user record (from the +:guilabel:`Users` link on the home page) not from within the :guilabel:`Users` +link under the table. If you are creating a user specifically for a given table +you will have to create the user first (with no global privileges) and then go +back and edit that user to add the table and privileges for the individual +table. diff --git a/phpmyadmin/doc/html/_sources/require.txt b/phpmyadmin/doc/html/_sources/require.txt new file mode 100644 index 000000000..1452ee34f --- /dev/null +++ b/phpmyadmin/doc/html/_sources/require.txt @@ -0,0 +1,55 @@ +.. _require: + +Requirements +============ + +Web server +---------- + +Since, phpMyAdmin's interface is based entirely in your browser, you'll need a +web server (such as Apache, :term:`IIS`) to install phpMyAdmin's files into. + +PHP +--- + +* You need PHP 5.2.0 or newer, with ``session`` support, the Standard PHP Library + (SPL) extension and JSON support. + +* To support uploading of ZIP files, you need the PHP ``zip`` extension. + +* For proper support of multibyte strings (eg. UTF-8, which is currently + the default), you should install the ``mbstring`` and ``ctype`` extensions. + +* You need GD2 support in PHP to display inline thumbnails of JPEGs + ("image/jpeg: inline") with their original aspect ratio. + +* When using the cookie authentication (the default), the `mcrypt + `_ extension is strongly suggested for most + users and is **required** for 64–bit machines. Not using mcrypt will + cause phpMyAdmin to load pages significantly slower. + +* To support upload progress bars, see :ref:`faq2_9`. + +* To support XML and Open Document Spreadsheet importing, you need PHP + 5.2.17 or newer and the `libxml `_ + extension. + +.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes` + +Database +-------- + +phpMyAdmin support MySQL compatible databases. + +* MySQL 5.0 or newer +* MariaDB 5.0 or newer +* Drizzle + +.. seealso:: :ref:`faq1_17` + +Web browser +----------- + +To access phpMyAdmin you need a web browser with cookies and javascript +enabled. + diff --git a/phpmyadmin/doc/html/_sources/setup.txt b/phpmyadmin/doc/html/_sources/setup.txt new file mode 100644 index 000000000..850d67a2c --- /dev/null +++ b/phpmyadmin/doc/html/_sources/setup.txt @@ -0,0 +1,424 @@ +.. _setup: + +Installation +============ + +phpMyAdmin does not apply any special security methods to the MySQL +database server. It is still the system administrator's job to grant +permissions on the MySQL databases properly. phpMyAdmin's :guilabel:`Users` +page can be used for this. + +.. warning:: + + :term:`Mac` users should note that if you are on a version before + :term:`Mac OS X`, StuffIt unstuffs with :term:`Mac` formats. So you'll have + to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before + uploading them to your server, as PHP seems not to like :term:`Mac`-style + end of lines character ("``\r``"). + +.. _quick_install: + +Quick Install ++++++++++++++ + +#. Choose an appropriate distribution kit from the phpmyadmin.net + Downloads page. Some kits contain only the English messages, others + contain all languages. We'll assume you chose a kit whose name + looks like ``phpMyAdmin-x.x.x -all-languages.tar.gz``. +#. Untar or unzip the distribution (be sure to unzip the subdirectories): + ``tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz`` in your + webserver's document root. If you don't have direct access to your + document root, put the files in a directory on your local machine, + and, after step 4, transfer the directory on your web server using, + for example, ftp. +#. Ensure that all the scripts have the appropriate owner (if PHP is + running in safe mode, having some scripts with an owner different from + the owner of other scripts will be a problem). See :ref:`faq4_2` and + :ref:`faq1_26` for suggestions. +#. Now you must configure your installation. There are two methods that + can be used. Traditionally, users have hand-edited a copy of + :file:`config.inc.php`, but now a wizard-style setup script is provided + for those who prefer a graphical installation. Creating a + :file:`config.inc.php` is still a quick way to get started and needed for + some advanced features. + + +Manualy creating file +--------------------- + +To manually create the file, simply use your text editor to create the +file :file:`config.inc.php` (you can copy :file:`config.sample.inc.php` to get +minimal configuration file) in the main (top-level) phpMyAdmin +directory (the one that contains :file:`index.php`). phpMyAdmin first +loads :file:`libraries/config.default.php` and then overrides those values +with anything found in :file:`config.inc.php`. If the default value is +okay for a particular setting, there is no need to include it in +:file:`config.inc.php`. You'll need a few directives to get going, a +simple configuration may look like this: + +.. code-block:: php + + + + +Or, if you prefer to not be prompted every time you log in: + +.. code-block:: php + + + + +For a full explanation of possible configuration values, see the +:ref:`config` of this document. + +.. index:: Setup script + +.. _setup_script: + +Using Setup script +------------------ + +Instead of manually editing :file:`config.inc.php`, you can use the `Setup +Script `_. First you must manually create a folder ``config`` +in the phpMyAdmin directory. This is a security measure. On a +Linux/Unix system you can use the following commands: + +.. code-block:: sh + + + cd phpMyAdmin + mkdir config # create directory for saving + chmod o+rw config # give it world writable permissions + +And to edit an existing configuration, copy it over first: + +.. code-block:: sh + + + cp config.inc.php config/ # copy current configuration for editing + chmod o+w config/config.inc.php # give it world writable permissions + +On other platforms, simply create the folder and ensure that your web +server has read and write access to it. :ref:`faq1_26` can help with +this. + +Next, open ``setup/`` in your browser. Note that **changes are +not saved to disk until explicitly choose ``Save``** from the +*Configuration* area of the screen. Normally the script saves the new +:file:`config.inc.php` to the ``config/`` directory, but if the webserver does +not have the proper permissions you may see the error "Cannot load or +save configuration." Ensure that the ``config/`` directory exists and +has the proper permissions - or use the ``Download`` link to save the +config file locally and upload (via FTP or some similar means) to the +proper location. + +Once the file has been saved, it must be moved out of the ``config/`` +directory and the permissions must be reset, again as a security +measure: + +.. code-block:: sh + + + mv config/config.inc.php . # move file to current directory + chmod o-rw config.inc.php # remove world read and write permissions + rm -rf config # remove not needed directory + +Now the file is ready to be used. You can choose to review or edit the +file with your favorite editor, if you prefer to set some advanced +options which the setup script does not provide. + +#. If you are using the ``auth_type`` "config", it is suggested that you + protect the phpMyAdmin installation directory because using config + does not require a user to enter a password to access the phpMyAdmin + installation. Use of an alternate authentication method is + recommended, for example with HTTP–AUTH in a :term:`.htaccess` file or switch to using + ``auth_type`` cookie or http. See the :ref:`faqmultiuser` + for additional information, especially :ref:`faq4_4`. +#. Open the `main phpMyAdmin directory `_ in your browser. + phpMyAdmin should now display a welcome screen and your databases, or + a login dialog if using :term:`HTTP` or + cookie authentication mode. +#. You should deny access to the ``./libraries`` and ``./setup/lib`` + subfolders in your webserver configuration. For Apache you can use + supplied :term:`.htaccess` file in that folder, for other webservers, you should + configure this yourself. Such configuration prevents from possible + path exposure and cross side scripting vulnerabilities that might + happen to be found in that code. +#. It is generally good idea to protect public phpMyAdmin installation + against access by robots as they usually can not do anything good + there. You can do this using ``robots.txt`` file in root of your + webserver or limit access by web server configuration, see + :ref:`faq1_42`. + +.. index:: + single: Configuration storage + single: phpMyAdmin configuration storage + single: pmadb + +.. _linked-tables: + +phpMyAdmin configuration storage +++++++++++++++++++++++++++++++++ + +For a whole set of new features (bookmarks, comments, :term:`SQL`-history, +tracking mechanism, :term:`PDF`-generation, column contents transformation, +etc.) you need to create a set of special tables. Those tables can be located +in your own database, or in a central database for a multi-user installation +(this database would then be accessed by the controluser, so no other user +should have rights to it). + +Please look at your ``./examples/`` directory, where you should find a +file called *create\_tables.sql*. (If you are using a Windows server, +pay special attention to :ref:`faq1_23`). + +If you already had this infrastructure and upgraded to MySQL 4.1.2 or +newer, please use :file:`examples/upgrade_tables_mysql_4_1_2+.sql` +and then create new tables by importing +:file:`examples/create_tables.sql`. + +You can use your phpMyAdmin to create the tables for you. Please be +aware that you may need special (administrator) privileges to create +the database and tables, and that the script may need some tuning, +depending on the database name. + +After having imported the :file:`examples/create_tables.sql` file, you +should specify the table names in your :file:`config.inc.php` file. The +directives used for that can be found in the :ref:`config`. You will also need to +have a controluser with the proper rights to those tables (see section +:ref:`authentication_modes` below). + +.. _upgrading: + +Upgrading from an older version ++++++++++++++++++++++++++++++++ + +Simply copy :file:`config.inc.php` from your previous installation into +the newly unpacked one. Configuration files from old versions may +require some tweaking as some options have been changed or removed. +For compatibility with PHP 6, remove a +``set_magic_quotes_runtime(0);`` statement that you might find near +the end of your configuration file. + +You should **not** copy :file:`libraries/config.default.php` over +:file:`config.inc.php` because the default configuration file is version- +specific. + +If you have upgraded your MySQL server from a version previous to 4.1.2 to +version 5.x or newer and if you use the phpMyAdmin configuration storage, you +should run the :term:`SQL` script found in +:file:`examples/upgrade_tables_mysql_4_1_2+.sql`. + +.. index:: Authentication mode + +.. _authentication_modes: + +Using authentication modes +++++++++++++++++++++++++++ + +:term:`HTTP` and cookie authentication modes are recommended in a **multi-user +environment** where you want to give users access to their own database and +don't want them to play around with others. Nevertheless be aware that MS +Internet Explorer seems to be really buggy about cookies, at least till version +6. Even in a **single-user environment**, you might prefer to use :term:`HTTP` +or cookie mode so that your user/password pair are not in clear in the +configuration file. + +:term:`HTTP` and cookie authentication +modes are more secure: the MySQL login information does not need to be +set in the phpMyAdmin configuration file (except possibly for the +:config:option:`$cfg['Servers'][$i]['controluser']`). +However, keep in mind that the password travels in plain text, unless +you are using the HTTPS protocol. In cookie mode, the password is +stored, encrypted with the blowfish algorithm, in a temporary cookie. + +.. note: + + This section is only applicable if your MySQL server is running + with ``--skip-show-database``. + +For ':term:`HTTP`' and 'cookie' modes, phpMyAdmin needs a controluser that has +**only** the ``SELECT`` privilege on the *`mysql`.`user` (all columns except +`Password`)*, *`mysql`.`db` (all columns)*, *`mysql`.`host` (all columns)* and +*`mysql`.`tables\_priv` (all columns except `Grantor` and `Timestamp`)* tables. +You must specify the details for the controluser in the :file:`config.inc.php` +file under the :config:option:`$cfg['Servers'][$i]['controluser']` and +:config:option:`$cfg['Servers'][$i]['controlpass']` settings. The following +example assumes you want to use ``pma`` as the controluser and ``pmapass`` as +the controlpass, but **this is only an example: use something else in your +file!** Input these statements from the phpMyAdmin :term:`SQL` Query window or +mysql command–line client. Of course you have to replace ``localhost`` with the +webserver's host if it's not the same as the MySQL server's one. + +If you want to use the many new relation and bookmark features: (this of +course requires that your :ref:`linked-tables` be set up). + +.. code-block:: mysql + + GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass'; + GRANT SELECT ( + Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv, + Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, + File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, + Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, + Execute_priv, Repl_slave_priv, Repl_client_priv + ) ON mysql.user TO 'pma'@'localhost'; + GRANT SELECT ON mysql.db TO 'pma'@'localhost'; + GRANT SELECT ON mysql.host TO 'pma'@'localhost'; + GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv) + ON mysql.tables_priv TO 'pma'@'localhost'; + +If you want to use the many new relation and bookmark features: + +.. code-block:: mysql + + GRANT SELECT, INSERT, UPDATE, DELETE ON .* TO 'pma'@'localhost'; + +(this of course requires that your phpMyAdmin +configuration storage be set up). + +Then each of the *true* users should be granted a set of privileges +on a set of particular databases. Normally you shouldn't give global +privileges to an ordinary user, unless you understand the impact of those +privileges (for example, you are creating a superuser). +For example, to grant the user *real_user* with all privileges on +the database *user_base*: + +.. code-block:: mysql + + GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password'; + + +What the user may now do is controlled entirely by the MySQL user management +system. With HTTP or cookie authentication mode, you don't need to fill the +user/password fields inside the :config:option:`$cfg['Servers']`. + +.. index:: pair: HTTP; Authentication mode + +HTTP authentication mode +------------------------ + +* Uses :term:`HTTP` Basic authentication + method and allows you to log in as any valid MySQL user. +* Is supported with most PHP configurations. For :term:`IIS` (:term:`ISAPI`) + support using :term:`CGI` PHP see :ref:`faq1_32`, for using with Apache + :term:`CGI` see :ref:`faq1_35`. +* See also :ref:`faq4_4` about not using the :term:`.htaccess` mechanism along with + ':term:`HTTP`' authentication mode. + +.. index:: pair: Cookie; Authentication mode + +.. _cookie: + +Cookie authentication mode +-------------------------- + +* You can use this method as a replacement for the :term:`HTTP` authentication + (for example, if you're running :term:`IIS`). +* Obviously, the user must enable cookies in the browser, but this is + now a requirement for all authentication modes. +* With this mode, the user can truly log out of phpMyAdmin and log in + back with the same username. +* If you want to log in to arbitrary server see :config:option:`$cfg['AllowArbitraryServer']` directive. +* As mentioned in the :ref:`require` section, having the ``mcrypt`` extension will + speed up access considerably, but is not required. + +.. index:: pair: Signon; Authentication mode + +Signon authentication mode +-------------------------- + +* This mode is a convenient way of using credentials from another + application to authenticate to phpMyAdmin. +* The other application has to store login information into session + data. + +.. seealso:: + :config:option:`$cfg['Servers'][$i]['auth_type']`, + :config:option:`$cfg['Servers'][$i]['SignonSession']`, + :config:option:`$cfg['Servers'][$i]['SignonScript']`, + :config:option:`$cfg['Servers'][$i]['SignonURL']` + + +.. index:: pair: Config; Authentication mode + +Config authentication mode +-------------------------- + +* This mode is the less secure one because it requires you to fill the + :config:option:`$cfg['Servers'][$i]['user']` and + :config:option:`$cfg['Servers'][$i]['password']` + fields (and as a result, anyone who can read your :file:`config.inc.php` + can discover your username and password). But you don't need to setup + a "controluser" here: using the :config:option:`$cfg['Servers'][$i]['only_db']` might be enough. +* In the :ref:`faqmultiuser` section, there is an entry explaining how + to protect your configuration file. +* For additional security in this mode, you may wish to consider the + Host authentication :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']` + and :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` configuration directives. +* Unlike cookie and http, does not require a user to log in when first + loading the phpMyAdmin site. This is by design but could allow any + user to access your installation. Use of some restriction method is + suggested, perhaps a :term:`.htaccess` file with the HTTP-AUTH directive or disallowing + incoming HTTP requests at one’s router or firewall will suffice (both + of which are beyond the scope of this manual but easily searchable + with Google). + +.. index:: pair: Swekey; Authentication mode + +.. _swekey: + +Swekey authentication mode +-------------------------- + +The Swekey is a low cost authentication USB key that can be used in +web applications. When Swekey authentication is activated, phpMyAdmin +requires the users's Swekey to be plugged before entering the login +page (currently supported for cookie authentication mode only). Swekey +Authentication is disabled by default. To enable it, add the following +line to :file:`config.inc.php`: + +.. code-block:: php + + $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf'; + +You then have to create the ``swekey.conf`` file that will associate +each user with their Swekey Id. It is important to place this file +outside of your web server's document root (in the example, it is +located in ``/etc``). A self documented sample file is provided in the +``examples`` directory. Feel free to use it with your own users' +information. If you want to purchase a Swekey please visit +`http://phpmyadmin.net/auth\_key `_ +since this link provides funding for phpMyAdmin. + +.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']` + + +Securing your phpMyAdmin installation ++++++++++++++++++++++++++++++++++++++ + +The phpMyAdmin team tries hardly to make the application secure, however there +are always ways to make your installation more secure: + +* remove ``setup`` directory from phpMyAdmin, you will probably not + use it after initial setup +* prevent access to ``libraries`` directory from browser, + as it is not needed, supplied ``.htaccess`` file does this +* properly choose authentication method - :ref:`cookie` + is probably the best choice for shared hosting +* in case you don't want all MySQL users to be able to access + phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them +* consider hiding phpMyAdmin behind authentication proxy, so that + MySQL credentials are not all users need to login diff --git a/phpmyadmin/doc/html/_sources/transformations.txt b/phpmyadmin/doc/html/_sources/transformations.txt new file mode 100644 index 000000000..4c3ce46c9 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/transformations.txt @@ -0,0 +1,138 @@ +.. _transformations: + +Transformations +=============== + +.. _transformationsintro: + +Introduction +++++++++++++ + +To enable transformations, you have to setup the ``column_info`` +table and the proper directives. Please see the :ref:`config` on how to do so. + +You can apply different transformations to the contents of each +column. The transformation will take the content of each column and +transform it with certain rules defined in the selected +transformation. + +Say you have a column 'filename' which contains a filename. Normally +you would see in phpMyAdmin only this filename. Using transformations +you can transform that filename into a HTML link, so you can click +inside of the phpMyAdmin structure on the column's link and will see +the file displayed in a new browser window. Using transformation +options you can also specify strings to append/prepend to a string or +the format you want the output stored in. + +For a general overview of all available transformations and their +options, you can consult your *//transformation\_overview.php* installation. + +For a tutorial on how to effectively use transformations, see our +`Link section `_ on the +official phpMyAdmin homepage. + +.. _transformationshowto: + +Usage ++++++ + +Go to your *tbl\_structure.php* page (i.e. reached through clicking on +the 'Structure' link for a table). There click on "Change" (or change +icon) and there you will see three new fields at the end of the line. +They are called 'MIME-type', 'Browser transformation' and +'Transformation options'. + +* The field 'MIME-type' is a drop-down field. Select the MIME-type that + corresponds to the column's contents. Please note that transformations + are inactive as long as no MIME-type is selected. +* The field 'Browser transformation' is a drop-down field. You can + choose from a hopefully growing amount of pre-defined transformations. + See below for information on how to build your own transformation. + There are global transformations and mimetype-bound transformations. + Global transformations can be used for any mimetype. They will take + the mimetype, if necessary, into regard. Mimetype-bound + transformations usually only operate on a certain mimetype. There are + transformations which operate on the main mimetype (like 'image'), + which will most likely take the subtype into regard, and those who + only operate on a specific subtype (like 'image/jpeg'). You can use + transformations on mimetypes for which the function was not defined + for. There is no security check for you selected the right + transformation, so take care of what the output will be like. +* The field 'Transformation options' is a free-type textfield. You have + to enter transform-function specific options here. Usually the + transforms can operate with default options, but it is generally a + good idea to look up the overview to see which options are necessary. + Much like the ENUM/SET-Fields, you have to split up several options + using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is + because internally the options will be parsed as an array, leaving the + first value the first element in the array, and so forth. If you want + to specify a MIME character set you can define it in the + transformation\_options. You have to put that outside of the pre- + defined options of the specific mime-transform, as the last value of + the set. Use the format "'; charset=XXX'". If you use a transform, for + which you can specify 2 options and you want to append a character + set, enter "'first parameter','second parameter','charset=us-ascii'". + You can, however use the defaults for the parameters: "'','','charset + =us-ascii'". + +.. _transformationsfiles: + +File structure +++++++++++++++ + +All specific transformations for mimetypes are defined through class +files in the directory 'libraries/plugins/transformations/'. Each of +them extends a certain transformation abstract class declared in +libraries/plugins/transformations/abstract. + +They are stored in files to ease up customization and easy adding of +new transformations. + +Because the user cannot enter own mimetypes, it is kept sure that +transformations always work. It makes no sense to apply a +transformation to a mimetype the transform-function doesn't know to +handle. + +There is a file called '*transformations.lib.php*' that provides some +basic functions which can be included by any other transform function. + +The file name convention is ``[Mimetype]_[Subtype]_[Transformation +Name].class.php``, while the abtract class that it extends has the +name ``[Transformation Name]TransformationsPlugin``. All of the +methods that have to be implemented by a transformations plug-in are: + +#. getMIMEType() and getMIMESubtype() in the main class; +#. getName(), getInfo() and applyTransformation() in the abstract class + it extends. + +The getMIMEType(), getMIMESubtype() and getName() methods return the +name of the MIME type, MIME Subtype and transformation accordingly. +getInfo() returns the transformation's description and possible +options it may receive and applyTransformation() is the method that +does the actual work of the transformation plug-in. + +Please see the libraries/plugins/transformations/TEMPLATE and +libraries/plugins/transformations/TEMPLATE\_ABSTRACT files for adding +your own transformation plug-in. You can also generate a new +transformation plug-in (with or without the abstract transformation +class), by using +:file:`libraries/plugins/transformations/generator_plugin.sh` or +:file:`libraries/plugins/transformations/generator_main_class.sh`. + +The applyTransformation() method always gets passed three variables: + +#. **$buffer** - Contains the text inside of the column. This is the + text, you want to transform. +#. **$options** - Contains any user-passed options to a transform + function as an array. +#. **$meta** - Contains an object with information about your column. The + data is drawn from the output of the `mysql\_fetch\_field() + `_ function. This means, all + object properties described on the `manual page + `_ are available in this + variable and can be used to transform a column accordingly to + unsigned/zerofill/not\_null/... properties. The $meta->mimetype + variable contains the original MIME-type of the column (i.e. + 'text/plain', 'image/jpeg' etc.) + diff --git a/phpmyadmin/doc/html/_sources/user.txt b/phpmyadmin/doc/html/_sources/user.txt new file mode 100644 index 000000000..ceaf72332 --- /dev/null +++ b/phpmyadmin/doc/html/_sources/user.txt @@ -0,0 +1,9 @@ +User Guide +========== + +.. toctree:: + :maxdepth: 2 + + transformations + privileges + other diff --git a/phpmyadmin/doc/html/_sources/vendors.txt b/phpmyadmin/doc/html/_sources/vendors.txt new file mode 100644 index 000000000..13d7e550a --- /dev/null +++ b/phpmyadmin/doc/html/_sources/vendors.txt @@ -0,0 +1,34 @@ +Distributing and packaging phpMyAdmin +===================================== + +This document is intended to give advices to people who want to +redistribute phpMyAdmin inside other software package such as Linux +distribution or some all in one package including web server and MySQL +server. + +Generally you can customize some basic aspects (paths to some files and +behavior) in :file:`libraries/vendor_config.php`. + +For example if you want setup script to generate config file in var, change +``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you +will also probably want to skip directory writable check, so set +``SETUP_DIR_WRITABLE`` to false. + +External libraries +------------------ + +phpMyAdmin includes several external libraries, you might want to +replace them with system ones if they are available, but please note +that you should test whether version you provide is compatible with the +one we ship. + +Currently known list of external libraries: + +js/jquery + jQuery js framework and various jQuery based libraries. + +libraries/php-gettext + php-gettext library +libraries/tcpdf + tcpdf library, stripped down of not needed files + diff --git a/phpmyadmin/doc/html/_static/ajax-loader.gif b/phpmyadmin/doc/html/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/phpmyadmin/doc/html/_static/ajax-loader.gif differ diff --git a/phpmyadmin/doc/html/_static/basic.css b/phpmyadmin/doc/html/_static/basic.css new file mode 100644 index 000000000..43e8bafaf --- /dev/null +++ b/phpmyadmin/doc/html/_static/basic.css @@ -0,0 +1,540 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/phpmyadmin/doc/html/_static/comment-bright.png b/phpmyadmin/doc/html/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment-bright.png differ diff --git a/phpmyadmin/doc/html/_static/comment-close.png b/phpmyadmin/doc/html/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment-close.png differ diff --git a/phpmyadmin/doc/html/_static/comment.png b/phpmyadmin/doc/html/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/phpmyadmin/doc/html/_static/comment.png differ diff --git a/phpmyadmin/doc/html/_static/default.css b/phpmyadmin/doc/html/_static/default.css new file mode 100644 index 000000000..21f3f5098 --- /dev/null +++ b/phpmyadmin/doc/html/_static/default.css @@ -0,0 +1,256 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/phpmyadmin/doc/html/_static/doctools.js b/phpmyadmin/doc/html/_static/doctools.js new file mode 100644 index 000000000..d4619fdfb --- /dev/null +++ b/phpmyadmin/doc/html/_static/doctools.js @@ -0,0 +1,247 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +} + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/phpmyadmin/doc/html/_static/down-pressed.png b/phpmyadmin/doc/html/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/phpmyadmin/doc/html/_static/down-pressed.png differ diff --git a/phpmyadmin/doc/html/_static/down.png b/phpmyadmin/doc/html/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/phpmyadmin/doc/html/_static/down.png differ diff --git a/phpmyadmin/doc/html/_static/file.png b/phpmyadmin/doc/html/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/phpmyadmin/doc/html/_static/file.png differ diff --git a/phpmyadmin/doc/html/_static/jquery.js b/phpmyadmin/doc/html/_static/jquery.js new file mode 100644 index 000000000..7c2430802 --- /dev/null +++ b/phpmyadmin/doc/html/_static/jquery.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/phpmyadmin/doc/html/_static/minus.png b/phpmyadmin/doc/html/_static/minus.png new file mode 100644 index 000000000..da1c5620d Binary files /dev/null and b/phpmyadmin/doc/html/_static/minus.png differ diff --git a/phpmyadmin/doc/html/_static/plus.png b/phpmyadmin/doc/html/_static/plus.png new file mode 100644 index 000000000..b3cb37425 Binary files /dev/null and b/phpmyadmin/doc/html/_static/plus.png differ diff --git a/phpmyadmin/doc/html/_static/pygments.css b/phpmyadmin/doc/html/_static/pygments.css new file mode 100644 index 000000000..1a14f2ae1 --- /dev/null +++ b/phpmyadmin/doc/html/_static/pygments.css @@ -0,0 +1,62 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #303030 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/phpmyadmin/doc/html/_static/searchtools.js b/phpmyadmin/doc/html/_static/searchtools.js new file mode 100644 index 000000000..663be4c90 --- /dev/null +++ b/phpmyadmin/doc/html/_static/searchtools.js @@ -0,0 +1,560 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; +} + + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, success: null, + dataType: "script", cache: true}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('
'); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ +
\ +

\ + Sort by:\ + best rated\ + newest\ + oldest\ +

\ +
Comments
\ +
\ + loading comments...
\ +
    \ +
    \ +

    Add a comment\ + (markup):

    \ +
    \ + reStructured text markup: *emph*, **strong**, \ + ``code``, \ + code blocks: :: and an indented block after blank line
    \ +
    \ + \ +

    \ + \ + Propose a change ▹\ + \ + \ + Propose a change ▿\ + \ +

    \ + \ + \ + \ + \ +
    \ +
    \ +
    '; + + var commentTemplate = '\ +
    \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +
    \ +

    \ + <%username%>\ + <%pretty_rating%>\ + <%time.delta%>\ +

    \ +
    <#text#>
    \ +

    \ + \ + reply ▿\ + proposal ▹\ + proposal ▿\ + \ + \ +

    \ +
    \
    +<#proposal_diff#>\
    +        
    \ +
      \ +
      \ +
      \ +
      \ + '; + + var replyTemplate = '\ +
    • \ +
      \ +
      \ + \ + \ + \ + \ + \ +
      \ +
      \ +
    • '; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/phpmyadmin/doc/html/config.html b/phpmyadmin/doc/html/config.html new file mode 100644 index 000000000..9646bdfb8 --- /dev/null +++ b/phpmyadmin/doc/html/config.html @@ -0,0 +1,4896 @@ + + + + + + + + + + Configuration — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Configuration

      +

      Almost all configurable data is placed in config.inc.php. If this file +does not exist, please refer to the Installation section to create one. This +file only needs to contain the parameters you want to change from their +corresponding default value in libraries/config.default.php.

      +

      The parameters which relate to design (like colors) are placed in +themes/themename/layout.inc.php. You might also want to create +config.footer.inc.php and config.header.inc.php files to add +your site specific code to be included on start and end of each page.

      +
      +

      Note

      +

      Some distributions (eg. Debian or Ubuntu) store config.inc.php in +/etc/phpmyadmin instead of within phpMyAdmin sources.

      +
      +
      +

      Warning

      +

      Mac users should note that if you are on a version before +Mac OS X, PHP does not seem to +like Mac end of lines character (\r). So +ensure you choose the option that allows to use the *nix end of line +character (\n) in your text editor before saving a script you have +modified.

      +
      +
      +

      Basic settings

      +
      +
      +$cfg['PmaAbsoluteUri']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Sets here the complete URL (with full path) to your phpMyAdmin +installation’s directory. E.g. +http://www.example.net/path_to_your_phpMyAdmin_directory/. Note also +that the URL on some web servers are case–sensitive. Don’t forget +the trailing slash at the end.

      +

      Starting with version 2.3.0, it is advisable to try leaving this blank. In +most cases phpMyAdmin automatically detects the proper setting. Users of +port forwarding will need to set $cfg['PmaAbsoluteUri'] +(more info).

      +

      A good test is to browse a table, edit a row and save it. There should be +an error message if phpMyAdmin is having trouble auto–detecting the correct +value. If you get an error that this must be set or if the autodetect code +fails to detect your path, please post a bug report on our bug tracker so +we can improve the code.

      + +
      + +
      +
      +$cfg['PmaNoRelation_DisableWarning']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Starting with version 2.3.0 phpMyAdmin offers a lot of features to +work with master / foreign – tables (see $cfg['Servers'][$i]['pmadb']).

      +

      If you tried to set this +up and it does not work for you, have a look on the Structure page +of one database where you would like to use it. You will find a link +that will analyze why those features have been disabled.

      +

      If you do not want to use those features set this variable to true to +stop this message from appearing.

      +
      + +
      +
      +$cfg['SuhosinDisableWarning']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      A warning is displayed on the main page if Suhosin is detected.

      +

      You can set this parameter to true to stop this message from appearing.

      +
      + +
      +
      +$cfg['McryptDisableWarning']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Disable the default warning that is displayed if mcrypt is missing for +cookie authentication.

      +

      You can set this parameter to true to stop this message from appearing.

      +
      + +
      +
      +$cfg['ServerLibraryDifference_DisableWarning']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      A warning is displayed on the main page if there is a difference +between the MySQL library and server version.

      +

      You can set this parameter to true to stop this message from appearing.

      +
      + +
      +
      +$cfg['ReservedWordDisableWarning']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      This warning is displayed on the Structure page of a table if one or more +column names match with words which are MySQL reserved.

      +

      If you want to turn off this warning, you can set it to true and +warning will not longer be displayed

      +
      + +
      +
      +$cfg['TranslationWarningThreshold']
      +
      +++ + + + + + +
      Type:integer
      Default value:80
      +

      Show warning about incomplete translations on certain threshold.

      +
      + +
      +
      +

      Server connection settings

      +
      +
      +$cfg['Servers']
      +
      +++ + + + + + +
      Type:array
      Default value:one server array with settings listed bellow
      +

      Since version 1.4.2, phpMyAdmin supports the administration of multiple +MySQL servers. Therefore, a $cfg['Servers']-array has been +added which contains the login information for the different servers. The +first $cfg['Servers'][$i]['host'] contains the hostname of +the first server, the second $cfg['Servers'][$i]['host'] +the hostname of the second server, etc. In +libraries/config.default.php, there is only one section for server +definition, however you can put as many as you need in +config.inc.php, copy that block or needed parts (you don’t have to +define all settings, just those you need to change).

      +
      +

      Note

      +

      The $cfg['Servers'] array starts with +$cfg[‘Servers’][1]. Do not use $cfg[‘Servers’][0]. If you want more +than one server, just copy following section (including $i +incrementation) serveral times. There is no need to define full server +array, just define values you need to change.

      +
      +
      + +
      +
      +$cfg['Servers'][$i]['host']
      +
      +++ + + + + + +
      Type:string
      Default value:'localhost'
      +

      The hostname or IP address of your $i-th MySQL-server. E.g. +localhost.

      +

      Possible values are:

      +
        +
      • hostname, e.g., 'localhost' or 'mydb.example.org'
      • +
      • IP address, e.g., '127.0.0.1' or '192.168.10.1'
      • +
      • dot - '.', i.e., use named pipes on windows systems
      • +
      • empty - '', disables this server
      • +
      +
      + +
      +
      +$cfg['Servers'][$i]['port']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The port-number of your $i-th MySQL-server. Default is 3306 (leave +blank).

      +
      +

      Note

      +

      If you use localhost as the hostname, MySQL ignores this port number +and connects with the socket, so if you want to connect to a port +different from the default port, use 127.0.0.1 or the real hostname +in $cfg['Servers'][$i]['host'].

      +
      +
      + +
      +
      +$cfg['Servers'][$i]['socket']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The path to the socket to use. Leave blank for default. To determine +the correct socket, check your MySQL configuration or, using the +mysql command–line client, issue the status command. Among the +resulting information displayed will be the socket used.

      +
      + +
      +
      +$cfg['Servers'][$i]['ssl']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to enable SSL for connection to MySQL server.

      +
      + +
      +
      +$cfg['Servers'][$i]['connect_type']
      +
      +++ + + + + + +
      Type:string
      Default value:'tcp'
      +

      What type connection to use with the MySQL server. Your options are +'socket' and 'tcp'. It defaults to tcp as that is nearly guaranteed +to be available on all MySQL servers, while sockets are not supported on +some platforms. To use the socket mode, your MySQL server must be on the +same machine as the Web server.

      +
      + +
      +
      +$cfg['Servers'][$i]['extension']
      +
      +++ + + + + + +
      Type:string
      Default value:'mysqli'
      +

      What php MySQL extension to use for the connection. Valid options are:

      +
      +
      mysql
      +
      The classic MySQL extension.
      +
      mysqli
      +
      The improved MySQL extension. This extension became available with PHP +5.0.0 and is the recommended way to connect to a server running MySQL +4.1.x or newer.
      +
      +
      + +
      +
      +$cfg['Servers'][$i]['compress']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to use a compressed protocol for the MySQL server connection +or not (experimental).

      +
      + +
      +
      +$cfg['Servers'][$i]['controlhost']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Permits to use an alternate host to hold the configuration storage +data.

      +
      + +
      +
      +$cfg['Servers'][$i]['controluser']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +
      + +
      +
      +$cfg['Servers'][$i]['controlpass']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      This special account is used for 2 distinct purposes: to make possible all +relational features (see $cfg['Servers'][$i]['pmadb']) and, +for a MySQL server running with --skip-show-database, to enable a +multi-user installation (HTTP or cookie +authentication mode).

      +

      When using HTTP or +cookie authentication modes (or ‘config’ authentication mode since phpMyAdmin +2.2.1), you need to supply the details of a MySQL account that has SELECT +privilege on the mysql.user (all columns except “Password”), mysql.db (all +columns) and mysql.tables_priv (all columns except “Grantor” and +“Timestamp”) tables. This account is used to check what databases the user +will see at login.

      +

      +Changed in version 2.2.5: those were called stduser and stdpass

      + +
      + +
      +
      +$cfg['Servers'][$i]['auth_type']
      +
      +++ + + + + + +
      Type:string
      Default value:'cookie'
      +

      Whether config or cookie or HTTP or signon authentication should be +used for this server.

      +
        +
      • ‘config’ authentication ($auth_type = 'config') is the plain old +way: username and password are stored in config.inc.php.
      • +
      • ‘cookie’ authentication mode ($auth_type = 'cookie') as +introduced in 2.2.3 allows you to log in as any valid MySQL user with +the help of cookies. Username and password are stored in cookies +during the session and password is deleted when it ends. This can also +allow you to log in in arbitrary server if $cfg['AllowArbitraryServer'] enabled.
      • +
      • ‘http’ authentication (was +called ‘advanced’ in previous versions and can be written also as +‘http’) ($auth_type = 'http';') as introduced in 1.3.0 allows you to log in as any +valid MySQL user via HTTP-Auth.
      • +
      • ‘signon’ authentication mode ($auth_type = 'signon') as +introduced in 2.10.0 allows you to log in from prepared PHP session +data or using supplied PHP script. This is useful for implementing +single signon from another application. Sample way how to seed session +is in signon example: examples/signon.php. There is also +alternative example using OpenID - examples/openid.php and example +for scripts based solution - examples/signon-script.php. You need +to configure $cfg['Servers'][$i]['SignonSession'] or +$cfg['Servers'][$i]['SignonScript'] and +$cfg['Servers'][$i]['SignonURL'] to use this authentication +method.
      • +
      + +
      + +
      +
      +$cfg['Servers'][$i]['auth_http_realm']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      When using auth_type = http, this field allows to define a custom +HTTP Basic Auth Realm which will be displayed to the user. If not +explicitly specified in your configuration, a string combined of +“phpMyAdmin ” and either $cfg['Servers'][$i]['verbose'] or +$cfg['Servers'][$i]['host'] will be used.

      +
      + +
      +
      +$cfg['Servers'][$i]['auth_swekey_config']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The name of the file containing Swekey authentication mode ids and login names for hardware +authentication. Leave empty to deactivate this feature.

      +
      + +
      +
      +$cfg['Servers'][$i]['user']
      +
      +++ + + + + + +
      Type:string
      Default value:'root'
      +
      + +
      +
      +$cfg['Servers'][$i]['password']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      When using $cfg['Servers'][$i]['auth_type'] set to +‘config’, this is the user/password-pair which phpMyAdmin will use to +connect to the MySQL server. This user/password pair is not needed when +HTTP or cookie authentication is used +and should be empty.

      +
      + +
      +
      +$cfg['Servers'][$i]['nopassword']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Allow attempt to log in without password when a login with password +fails. This can be used together with http authentication, when +authentication is done some other way and phpMyAdmin gets user name +from auth and uses empty password for connecting to MySQL. Password +login is still tried first, but as fallback, no password method is +tried.

      +
      + +
      +
      +$cfg['Servers'][$i]['only_db']
      +
      +++ + + + + + +
      Type:string or array
      Default value:''
      +

      If set to a (an array of) database name(s), only this (these) +database(s) will be shown to the user. Since phpMyAdmin 2.2.1, +this/these database(s) name(s) may contain MySQL wildcards characters +(“_” and “%”): if you want to use literal instances of these +characters, escape them (I.E. use 'my\_db' and not 'my_db').

      +

      This setting is an efficient way to lower the server load since the +latter does not need to send MySQL requests to build the available +database list. But it does not replace the privileges rules of the +MySQL database server. If set, it just means only these databases +will be displayed but not that all other databases can’t be used.

      +

      An example of using more that one database:

      +
      $cfg['Servers'][$i]['only_db'] = array('db1', 'db2');
      +
      +
      +

      +Changed in version 4.0.0: Previous versions permitted to specify the display order of +the database names via this directive.

      +
      + +
      +
      +$cfg['Servers'][$i]['hide_db']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Regular expression for hiding some databases from unprivileged users. +This only hides them from listing, but a user is still able to access +them (using, for example, the SQL query area). To limit access, use +the MySQL privilege system. For example, to hide all databases +starting with the letter “a”, use

      +
      $cfg['Servers'][$i]['hide_db'] = '^a';
      +
      +
      +

      and to hide both “db1” and “db2” use

      +
      $cfg['Servers'][$i]['hide_db'] = '^(db1|db2)$';
      +
      +
      +

      More information on regular expressions can be found in the PCRE +pattern syntax portion +of the PHP reference manual.

      +
      + +
      +
      +$cfg['Servers'][$i]['verbose']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Only useful when using phpMyAdmin with multiple server entries. If +set, this string will be displayed instead of the hostname in the +pull-down menu on the main page. This can be useful if you want to +show only certain databases on your system, for example. For HTTP +auth, all non-US-ASCII characters will be stripped.

      +
      + +
      +
      +$cfg['Servers'][$i]['pmadb']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The name of the database containing the phpMyAdmin configuration +storage.

      +

      See the phpMyAdmin configuration storage section in this document to see the benefits of +this feature, and for a quick way of creating this database and the needed +tables.

      +

      If you are the only user of this phpMyAdmin installation, you can use your +current database to store those special tables; in this case, just put your +current database name in $cfg['Servers'][$i]['pmadb']. For a +multi-user installation, set this parameter to the name of your central +database containing the phpMyAdmin configuration storage.

      +
      + +
      +
      +$cfg['Servers'][$i]['bookmarktable']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.2.0 phpMyAdmin allows users to bookmark queries. This +can be useful for queries you often run. To allow the usage of this +functionality:

      + +
      + +
      +
      +$cfg['Servers'][$i]['relation']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.2.4 you can describe, in a special ‘relation’ table, +which column is a key in another table (a foreign key). phpMyAdmin +currently uses this to

      + +

      The keys can be numeric or character.

      +

      To allow the usage of this functionality:

      +
        +
      • set up $cfg['Servers'][$i]['pmadb'] and the phpMyAdmin configuration storage
      • +
      • put the relation table name in $cfg['Servers'][$i]['relation']
      • +
      • now as normal user open phpMyAdmin and for each one of your tables +where you want to use this feature, click Structure/Relation view/ +and choose foreign columns.
      • +
      +
      +

      Note

      +

      In the current version, master_db must be the same as foreign_db. +Those columns have been put in future development of the cross-db +relations.

      +
      +
      + +
      +
      +$cfg['Servers'][$i]['table_info']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.3.0 you can describe, in a special ‘table_info’ +table, which column is to be displayed as a tool-tip when moving the +cursor over the corresponding key. This configuration variable will +hold the name of this special table. To allow the usage of this +functionality:

      + + +
      + +
      +
      +$cfg['Servers'][$i]['table_coords']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +
      + +
      +
      +$cfg['Servers'][$i]['pdf_pages']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.3.0 you can have phpMyAdmin create PDF pages +showing the relations between your tables. To do this it needs two tables +“pdf_pages” (storing information about the available PDF pages) +and “table_coords” (storing coordinates where each table will be placed on +a PDF schema output). You must be using the “relation” feature.

      +

      To allow the usage of this functionality:

      + + +
      + +
      +
      +$cfg['Servers'][$i]['column_info']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      This part requires a content update! Since release 2.3.0 you can +store comments to describe each column for each table. These will then +be shown on the “printview”.

      +

      Starting with release 2.5.0, comments are consequently used on the table +property pages and table browse view, showing up as tool-tips above the +column name (properties page) or embedded within the header of table in +browse view. They can also be shown in a table dump. Please see the +relevant configuration directives later on.

      +

      Also new in release 2.5.0 is a MIME- transformation system which is also +based on the following table structure. See Transformations for +further information. To use the MIME- transformation system, your +column_info table has to have the three new columns ‘mimetype’, +‘transformation’, ‘transformation_options’.

      +

      To allow the usage of this functionality:

      +
        +
      • set up $cfg['Servers'][$i]['pmadb'] and the phpMyAdmin configuration storage

        +
      • +
      • put the table name in $cfg['Servers'][$i]['column_info'] (e.g. +pma__column_info)

        +
      • +
      • to update your PRE-2.5.0 Column_comments Table use this: and +remember that the Variable in config.inc.php has been renamed from +$cfg['Servers'][$i]['column_comments'] to +$cfg['Servers'][$i]['column_info']

        +
        ALTER TABLE `pma__column_comments`
        +ADD `mimetype` VARCHAR( 255 ) NOT NULL,
        +ADD `transformation` VARCHAR( 255 ) NOT NULL,
        +ADD `transformation_options` VARCHAR( 255 ) NOT NULL;
        +
        +
        +
      • +
      +
      + +
      +
      +$cfg['Servers'][$i]['history']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.5.0 you can store your SQL history, which means all +queries you entered manually into the phpMyAdmin interface. If you don’t +want to use a table-based history, you can use the JavaScript-based +history.

      +

      Using that, all your history items are deleted when closing the window. +Using $cfg['QueryHistoryMax'] you can specify an amount of +history items you want to have on hold. On every login, this list gets cut +to the maximum amount.

      +

      The query history is only available if JavaScript is enabled in +your browser.

      +

      To allow the usage of this functionality:

      + +
      + +
      +
      +$cfg['Servers'][$i]['recent']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 3.5.0 you can show recently used tables in the +navigation panel. It helps you to jump across table directly, without +the need to select the database, and then select the table. Using +$cfg['NumRecentTables'] you can configure the maximum number +of recent tables shown. When you select a table from the list, it will jump to +the page specified in $cfg['NavigationTreeDefaultTabTable'].

      +

      Without configuring the storage, you can still access the recently used tables, +but it will disappear after you logout.

      +

      To allow the usage of this functionality persistently:

      + +
      + +
      +
      +$cfg['Servers'][$i]['table_uiprefs']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 3.5.0 phpMyAdmin can be configured to remember several +things (sorted column $cfg['RememberSorting'], column order, +and column visibility from a database table) for browsing tables. Without +configuring the storage, these features still can be used, but the values will +disappear after you logout.

      +

      To allow the usage of these functionality persistently:

      + +
      + +
      +
      +$cfg['Servers'][$i]['tracking']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 3.3.x a tracking mechanism is available. It helps you to +track every SQL command which is +executed by phpMyAdmin. The mechanism supports logging of data +manipulation and data definition statements. After enabling it you can +create versions of tables.

      +

      The creation of a version has two effects:

      +
        +
      • phpMyAdmin saves a snapshot of the table, including structure and +indexes.
      • +
      • phpMyAdmin logs all commands which change the structure and/or data of +the table and links these commands with the version number.
      • +
      +

      Of course you can view the tracked changes. On the Tracking +page a complete report is available for every version. For the report you +can use filters, for example you can get a list of statements within a date +range. When you want to filter usernames you can enter * for all names or +you enter a list of names separated by ‘,’. In addition you can export the +(filtered) report to a file or to a temporary database.

      +

      To allow the usage of this functionality:

      + +
      + +
      +
      +$cfg['Servers'][$i]['tracking_version_auto_create']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether the tracking mechanism creates versions for tables and views +automatically.

      +

      If this is set to true and you create a table or view with

      +
        +
      • CREATE TABLE ...
      • +
      • CREATE VIEW ...
      • +
      +

      and no version exists for it, the mechanism will create a version for +you automatically.

      +
      + +
      +
      +$cfg['Servers'][$i]['tracking_default_statements']
      +
      +++ + + + + + +
      Type:string
      Default value:'CREATE TABLE,ALTER TABLE,DROP TABLE,RENAME TABLE,CREATE INDEX,DROP INDEX,INSERT,UPDATE,DELETE,TRUNCATE,REPLACE,CREATE VIEW,ALTER VIEW,DROP VIEW,CREATE DATABASE,ALTER DATABASE,DROP DATABASE'
      +

      Defines the list of statements the auto-creation uses for new +versions.

      +
      + +
      +
      +$cfg['Servers'][$i]['tracking_add_drop_view']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether a DROP VIEW IF EXISTS statement will be added as first line to +the log when creating a view.

      +
      + +
      +
      +$cfg['Servers'][$i]['tracking_add_drop_table']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether a DROP TABLE IF EXISTS statement will be added as first line +to the log when creating a table.

      +
      + +
      +
      +$cfg['Servers'][$i]['tracking_add_drop_database']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether a DROP DATABASE IF EXISTS statement will be added as first +line to the log when creating a database.

      +
      + +
      +
      +$cfg['Servers'][$i]['userconfig']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 3.4.x phpMyAdmin allows users to set most preferences by +themselves and store them in the database.

      +

      If you don’t allow for storing preferences in +$cfg['Servers'][$i]['pmadb'], 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.

      +

      To allow the usage of this functionality:

      + +
      + +
      +
      +$cfg['Servers'][$i]['designer_coords']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Since release 2.10.0 a Designer interface is available; it permits to +visually manage the relations.

      +

      To allow the usage of this functionality:

      + +
      + +
      +
      +$cfg['Servers'][$i]['MaxTableUiprefs']
      +
      +++ + + + + + +
      Type:integer
      Default value:100
      +

      Maximum number of rows saved in +$cfg['Servers'][$i]['table_uiprefs'] table.

      +

      When tables are dropped or renamed, +$cfg['Servers'][$i]['table_uiprefs'] may contain invalid data +(referring to tables which no longer exist). We only keep this number of newest +rows in $cfg['Servers'][$i]['table_uiprefs'] and automatically +delete older rows.

      +
      + +
      +
      +$cfg['Servers'][$i]['AllowRoot']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to allow root access. This is just a shortcut for the +$cfg['Servers'][$i]['AllowDeny']['rules'] below.

      +
      + +
      +
      +$cfg['Servers'][$i]['AllowNoPassword']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to allow logins without a password. The default value of +false for this parameter prevents unintended access to a MySQL +server with was left with an empty password for root or on which an +anonymous (blank) user is defined.

      +
      + +
      +
      +$cfg['Servers'][$i]['AllowDeny']['order']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      If your rule order is empty, then IP +authorization is disabled.

      +

      If your rule order is set to +'deny,allow' then the system applies all deny rules followed by +allow rules. Access is allowed by default. Any client which does not +match a Deny command or does match an Allow command will be allowed +access to the server.

      +

      If your rule order is set to 'allow,deny' +then the system applies all allow rules followed by deny rules. Access +is denied by default. Any client which does not match an Allow +directive or does match a Deny directive will be denied access to the +server.

      +

      If your rule order is set to 'explicit', authorization is +performed in a similar fashion to rule order ‘deny,allow’, with the +added restriction that your host/username combination must be +listed in the allow rules, and not listed in the deny rules. This +is the most secure means of using Allow/Deny rules, and was +available in Apache by specifying allow and deny rules without setting +any order.

      +

      Please also see $cfg['TrustedProxies'] for +detecting IP address behind proxies.

      +
      + +
      +
      +$cfg['Servers'][$i]['AllowDeny']['rules']
      +
      +++ + + + + + +
      Type:array of strings
      Default value:array()
      +

      The general format for the rules is as such:

      +
      <'allow' | 'deny'> <username> [from] <ipmask>
      +
      +
      +

      If you wish to match all users, it is possible to use a '%' as a +wildcard in the username field.

      +

      There are a few shortcuts you can +use in the ipmask field as well (please note that those containing +SERVER_ADDRESS might not be available on all webservers):

      +
      'all' -> 0.0.0.0/0
      +'localhost' -> 127.0.0.1/8
      +'localnetA' -> SERVER_ADDRESS/8
      +'localnetB' -> SERVER_ADDRESS/16
      +'localnetC' -> SERVER_ADDRESS/24
      +
      +
      +

      Having an empty rule list is equivalent to either using 'allow % +from all' if your rule order is set to 'deny,allow' or 'deny % +from all' if your rule order is set to 'allow,deny' or +'explicit'.

      +

      For the IP address matching +system, the following work:

      +
        +
      • xxx.xxx.xxx.xxx (an exact IP address)
      • +
      • xxx.xxx.xxx.[yyy-zzz] (an IP address range)
      • +
      • xxx.xxx.xxx.xxx/nn (CIDR, Classless Inter-Domain Routing type IP addresses)
      • +
      +

      But the following does not work:

      +
        +
      • xxx.xxx.xxx.xx[yyy-zzz] (partial IP address range)
      • +
      +

      For IPv6 addresses, the following work:

      +
        +
      • xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (an exact IPv6 address)
      • +
      • xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:[yyyy-zzzz] (an IPv6 address range)
      • +
      • xxxx:xxxx:xxxx:xxxx/nn (CIDR, Classless Inter-Domain Routing type IPv6 addresses)
      • +
      +

      But the following does not work:

      +
        +
      • xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx[yyy-zzz] (partial IPv6 address range)
      • +
      +
      + +
      +
      +$cfg['Servers'][$i]['DisableIS']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Disable using INFORMATION_SCHEMA to retrieve information (use +SHOW commands instead), because of speed issues when many +databases are present. Currently used in some parts of the code, more +to come.

      +
      + +
      +
      +$cfg['Servers'][$i]['ShowDatabasesCommand']
      +
      +++ + + + + + +
      Type:string
      Default value:'SHOW DATABASES'
      +

      On a server with a huge number of databases, the default SHOW DATABASES +command used to fetch the name of available databases will probably be too +slow, so it can be replaced by faster commands. You can use #user# +string will be replaced by current user.

      +

      When using false, it will disable fetching databases from the server, +only databases in $cfg['Servers'][$i]['only_db'] will be +displayed.

      +

      Examples:

      +
        +
      • 'SHOW DATABASES'
      • +
      • "SHOW DATABASES LIKE '#user#\_%'"
      • +
      • 'SELECT DISTINCT TABLE_SCHEMA FROM information_schema.SCHEMA_PRIVILEGES'
      • +
      • 'SELECT SCHEMA_NAME FROM information_schema.SCHEMATA'
      • +
      • false
      • +
      +
      + +
      +
      +$cfg['Servers'][$i]['SignonScript']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Name of PHP script to be sourced and executed to obtain login +credentials. This is alternative approach to session based single +signon. The script needs to provide function +get_login_credentials which returns list of username and +password, accepting single parameter of existing username (can be +empty). See examples/signon-script.php for an example.

      +
      + +
      +
      +$cfg['Servers'][$i]['SignonSession']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Name of session which will be used for signon authentication method. +You should use something different than phpMyAdmin, because this +is session which phpMyAdmin uses internally. Takes effect only if +$cfg['Servers'][$i]['SignonScript'] is not configured.

      +
      + +
      +
      +$cfg['Servers'][$i]['SignonURL']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      URL where user will be redirected +to log in for signon authentication method. Should be absolute +including protocol.

      +
      + +
      +
      +$cfg['Servers'][$i]['LogoutURL']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      URL where user will be redirected +after logout (doesn’t affect config authentication method). Should be +absolute including protocol.

      +
      + +
      +
      +$cfg['Servers'][$i]['StatusCacheDatabases']
      +
      +++ + + + + + +
      Type:array of strings
      Default value:array()
      +

      Enables caching of TABLE STATUS outputs for specific databases on +this server (in some cases TABLE STATUS can be very slow, so you +may want to cache it). APC is used (if the PHP extension is available, +if not, this setting is ignored silently). You have to provide +$cfg['Servers'][$i]['StatusCacheLifetime'].

      +

      Takes effect only if $cfg['Servers'][$i]['DisableIS'] is +true.

      +
      + +
      +
      +$cfg['Servers'][$i]['StatusCacheLifetime']
      +
      +++ + + + + + +
      Type:integer
      Default value:0
      +

      Lifetime in seconds of the TABLE STATUS cache if +$cfg['Servers'][$i]['StatusCacheDatabases'] is used.

      +
      + +
      +
      +

      Generic settings

      +
      +
      +$cfg['ServerDefault']
      +
      +++ + + + + + +
      Type:integer
      Default value:1
      +

      If you have more than one server configured, you can set +$cfg['ServerDefault'] to any one of them to autoconnect to that +server when phpMyAdmin is started, or set it to 0 to be given a list +of servers without logging in.

      +

      If you have only one server configured, +$cfg['ServerDefault'] MUST be set to that server.

      +
      + +
      +
      +$cfg['VersionCheck']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Enables check for latest versions using javascript on main phpMyAdmin +page.

      +
      +

      Note

      +

      This setting can be adjusted by your vendor.

      +
      +
      + +
      +
      +$cfg['MaxDbList']
      +
      +++ + + + + + +
      Type:integer
      Default value:100
      +

      The maximum number of database names to be displayed in the main panel’s +database list.

      +
      + +
      +
      +$cfg['MaxNavigationItems']
      +
      +++ + + + + + +
      Type:integer
      Default value:25
      +

      The number of items that can be displayed on each page of the +navigation tree.

      +
      + +
      +
      +$cfg['MaxTableList']
      +
      +++ + + + + + +
      Type:integer
      Default value:250
      +

      The maximum number of table names to be displayed in the main panel’s +list (except on the Export page). This limit is also enforced in the +navigation panel when in Light mode.

      +
      + +
      +
      +$cfg['ShowHint']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether or not to show hints (for example, hints when hovering over +table headers).

      +
      + +
      +
      +$cfg['MaxCharactersInDisplayedSQL']
      +
      +++ + + + + + +
      Type:integer
      Default value:1000
      +

      The maximum number of characters when a SQL query is displayed. The +default limit of 1000 should be correct to avoid the display of tons of +hexadecimal codes that represent BLOBs, but some users have real +SQL queries that are longer than 1000 characters. Also, if a +query’s length exceeds this limit, this query is not saved in the history.

      +
      + +
      +
      +$cfg['PersistentConnections']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether persistent connections should be used or not. Works with +following extensions:

      + +
      + +
      +
      +$cfg['ForceSSL']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to force using https while accessing phpMyAdmin.

      +
      + +
      +
      +$cfg['ExecTimeLimit']
      +
      +++ + + + + + +
      Type:integer [number of seconds]
      Default value:300
      +

      Set the number of seconds a script is allowed to run. If seconds is +set to zero, no time limit is imposed. This setting is used while +importing/exporting dump files but has +no effect when PHP is running in safe mode.

      +
      + +
      +
      +$cfg['SessionSavePath']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Path for storing session data (session_save_path PHP parameter).

      +
      + +
      +
      +$cfg['MemoryLimit']
      +
      +++ + + + + + +
      Type:string [number of bytes]
      Default value:'0'
      +

      Set the number of bytes a script is allowed to allocate. If set to +zero, no limit is imposed.

      +

      This setting is used while importing/exporting dump files and at some other +places in phpMyAdmin so you definitely don’t want to put here a too low +value. It has no effect when PHP is running in safe mode.

      +

      You can also use any string as in php.ini, eg. ‘16M’. Ensure you +don’t omit the suffix (16 means 16 bytes!)

      +
      + +
      +
      +$cfg['SkipLockedTables']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Mark used tables and make it possible to show databases with locked +tables (since MySQL 3.23.30).

      +
      + +
      +
      +$cfg['ShowSQL']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether SQL queries +generated by phpMyAdmin should be displayed or not.

      +
      + +
      +
      +$cfg['RetainQueryBox']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether the SQL query box +should be kept displayed after its submission.

      +
      + +
      +
      +$cfg['CodemirrorEnable']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether to use a Javascript code editor for SQL query boxes. +CodeMirror provides syntax highlighting and line numbers. However, +middle-clicking for pasting the clipboard contents in some Linux +distributions (such as Ubuntu) is not supported by all browsers.

      +
      + +
      +
      +$cfg['AllowUserDropDatabase']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether normal users (non-administrator) are allowed to delete +their own database or not. If set as false, the link Drop +Database will not be shown, and even a DROP DATABASE mydatabase will +be rejected. Quite practical for ISP ‘s with many customers.

      +
      +

      Note

      +

      This limitation of SQL queries is not +as strict as when using MySQL privileges. This is due to nature of +SQL queries which might be quite +complicated. So this choice should be viewed as help to avoid accidental +dropping rather than strict privilege limitation.

      +
      +
      + +
      +
      +$cfg['Confirm']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether a warning (“Are your really sure...”) should be displayed when +you’re about to lose data.

      +
      + +
      +
      +$cfg['UseDbSearch']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Define whether the “search string inside database” is enabled or not.

      +
      + +
      +
      +$cfg['IgnoreMultiSubmitErrors']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Define whether phpMyAdmin will continue executing a multi-query +statement if one of the queries fails. Default is to abort execution.

      +
      + +
      + + +
      +

      Main panel

      +
      +
      +$cfg['ShowStats']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether or not to display space usage and statistics about +databases and tables. Note that statistics requires at least MySQL +3.23.3 and that, at this date, MySQL doesn’t return such information +for Berkeley DB tables.

      +
      + +
      +
      +$cfg['ShowServerInfo']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether to display detailed server information on main page. +You can additionally hide more information by using +$cfg['Servers'][$i]['verbose'].

      +
      + +
      +
      +$cfg['ShowPhpInfo']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +
      + +
      +
      +$cfg['ShowChgPassword']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +
      + +
      +
      +$cfg['ShowCreateDb']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether to display the PHP information and +Change password links and form for creating database or not at +the starting main (right) frame. This setting does not check MySQL commands +entered directly.

      +

      Please note that to block the usage of phpinfo() in scripts, you have to +put this in your php.ini:

      +
      disable_functions = phpinfo()
      +
      +
      +

      Also note that enabling the Change password link has no effect +with config authentication mode: because of the hard coded password value +in the configuration file, end users can’t be allowed to change their +passwords.

      +
      + +
      +
      +

      Database structure

      +
      +
      +$cfg['ShowDbStructureCreation']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether the database structure page (tables list) has a +“Creation” column that displays when each table was created.

      +
      + +
      +
      +$cfg['ShowDbStructureLastUpdate']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether the database structure page (tables list) has a “Last +update” column that displays when each table was last updated.

      +
      + +
      +
      +$cfg['ShowDbStructureLastCheck']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether the database structure page (tables list) has a “Last +check” column that displays when each table was last checked.

      +
      + +
      +
      +$cfg['HideStructureActions']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether the table structure actions are hidden under a “More” +drop-down.

      +
      + +
      +
      +

      Browse mode

      +
      +
      +$cfg['NavigationBarIconic']
      +
      +++ + + + + + +
      Type:string
      Default value:true
      +

      Defines whether navigation bar buttons contain text or symbols only. A +value of true displays icons, false displays text and ‘both’ displays +both icons and text.

      +
      + +
      +
      +$cfg['ShowAll']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether a user should be displayed a “Show all” button in +browse mode or not in all cases. By default it is shown only on small +tables (less than 5 × $cfg['MaxRows'] rows) to avoid +performance issues while getting too many rows.

      +
      + +
      +
      +$cfg['MaxRows']
      +
      +++ + + + + + +
      Type:integer
      Default value:30
      +

      Number of rows displayed when browsing a result set and no LIMIT +clause is used. If the result set contains more rows, “Previous” and +“Next” links will be shown.

      +
      + +
      +
      +$cfg['Order']
      +
      +++ + + + + + +
      Type:string
      Default value:'SMART'
      +

      Defines whether columns are displayed in ascending (ASC) order, in +descending (DESC) order or in a “smart” (SMART) order - I.E. +descending order for columns of type TIME, DATE, DATETIME and +TIMESTAMP, ascending order else- by default.

      +
      + +
      +
      +$cfg['DisplayBinaryAsHex']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether the “Show binary contents as HEX” browse option is +ticked by default.

      +
      + +
      +
      +$cfg['GridEditing']
      +
      +++ + + + + + +
      Type:string
      Default value:'double-click'
      +

      Defines which action (double-click or click) triggers grid +editing. Can be deactived with the disabled value.

      +
      + +
      +
      +$cfg['SaveCellsAtOnce']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether or not to save all edited cells at once for grid +editing.

      +
      + +
      +
      +

      Editing mode

      +
      +
      +$cfg['ProtectBinary']
      +
      +++ + + + + + +
      Type:boolean or string
      Default value:'blob'
      +

      Defines whether BLOB or BINARY columns are protected from +editing when browsing a table’s content. Valid values are:

      +
        +
      • false to allow editing of all columns;
      • +
      • 'blob' to allow editing of all columns except BLOBS;
      • +
      • 'noblob' to disallow editing of all columns except BLOBS (the +opposite of 'blob');
      • +
      • 'all' to disallow editing of all BINARY or BLOB columns.
      • +
      +
      + +
      +
      +$cfg['ShowFunctionFields']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether or not MySQL functions fields should be initially +displayed in edit/insert mode. Since version 2.10, the user can toggle +this setting from the interface.

      +
      + +
      +
      +$cfg['ShowFieldTypesInDataEditView']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether or not type fields should be initially displayed in +edit/insert mode. The user can toggle this setting from the interface.

      +
      + +
      +
      +$cfg['InsertRows']
      +
      +++ + + + + + +
      Type:integer
      Default value:2
      +

      Defines the maximum number of concurrent entries for the Insert page.

      +
      + +
      +
      +$cfg['ForeignKeyMaxLimit']
      +
      +++ + + + + + +
      Type:integer
      Default value:100
      +

      If there are fewer items than this in the set of foreign keys, then a +drop-down box of foreign keys is presented, in the style described by +the $cfg['ForeignKeyDropdownOrder'] setting.

      +
      + +
      +
      +$cfg['ForeignKeyDropdownOrder']
      +
      +++ + + + + + +
      Type:array
      Default value:array(‘content-id’, ‘id-content’)
      +

      For the foreign key drop-down fields, there are several methods of +display, offering both the key and value data. The contents of the +array should be one or both of the following strings: content-id, +id-content.

      +
      + +
      +
      +

      Export and import settings

      +
      +
      +$cfg['ZipDump']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +
      + +
      +
      +$cfg['GZipDump']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +
      + +
      +
      +$cfg['BZipDump']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether to allow the use of zip/GZip/BZip2 compression when +creating a dump file

      +
      + +
      +
      +$cfg['CompressOnFly']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether to allow on the fly compression for GZip/BZip2 +compressed exports. This doesn’t affect smaller dumps and allows users +to create larger dumps that won’t otherwise fit in memory due to php +memory limit. Produced files contain more GZip/BZip2 headers, but all +normal programs handle this correctly.

      +
      + +
      +
      +$cfg['Export']
      +
      +++ + + + + + +
      Type:array
      Default value:array(...)
      +

      In this array are defined default parameters for export, names of +items are similar to texts seen on export page, so you can easily +identify what they mean.

      +
      + +
      +
      +$cfg['Export']['method']
      +
      +++ + + + + + +
      Type:string
      Default value:'quick'
      +

      Defines how the export form is displayed when it loads. Valid values +are:

      +
        +
      • quick to display the minimum number of options to configure
      • +
      • custom to display every available option to configure
      • +
      • custom-no-form same as custom but does not display the option +of using quick export
      • +
      +
      + +
      +
      +$cfg['Import']
      +
      +++ + + + + + +
      Type:array
      Default value:array(...)
      +

      In this array are defined default parameters for import, names of +items are similar to texts seen on import page, so you can easily +identify what they mean.

      +
      + +
      +
      +

      Tabs display settings

      +
      +
      +$cfg['PropertiesIconic']
      +
      +++ + + + + + +
      Type:string
      Default value:'both'
      +

      If set to true, will display icons instead of text for db and table +properties links (like Browse, Select, +Insert, ...) and for the menu tabs. Can be set to 'both' +if you want icons AND text. When set to false, will only show text.

      +
      + +
      +
      +$cfg['PropertiesNumColumns']
      +
      +++ + + + + + +
      Type:integer
      Default value:1
      +

      How many columns will be utilized to display the tables on the database +property view? When setting this to a value larger than 1, the type of the +database will be omitted for more display space.

      +
      + +
      +
      +$cfg['DefaultTabServer']
      +
      +++ + + + + + +
      Type:string
      Default value:'index.php'
      +

      Defines the tab displayed by default on server view. Possible values:

      +
        +
      • main.php (recommended for multi-user setups)
      • +
      • server_databases.php,
      • +
      • server_status.php
      • +
      • server_variables.php
      • +
      • server_privileges.php
      • +
      +
      + +
      +
      +$cfg['DefaultTabDatabase']
      +
      +++ + + + + + +
      Type:string
      Default value:'db_structure.php'
      +

      Defines the tab displayed by default on database view. Possible +values:

      +
        +
      • db_structure.php
      • +
      • db_sql.php
      • +
      • db_search.php.
      • +
      +
      + +
      +
      +$cfg['DefaultTabTable']
      +
      +++ + + + + + +
      Type:string
      Default value:'sql.php'
      +

      Defines the tab displayed by default on table view. Possible values:

      +
        +
      • tbl_structure.php
      • +
      • tbl_sql.php
      • +
      • tbl_select.php
      • +
      • tbl_change.php
      • +
      • sql.php
      • +
      +
      + +
      +
      +

      Documentation

      +
      +
      +$cfg['MySQLManualBase']
      +
      +++ + + + + + +
      Type:string
      Default value:'http://dev.mysql.com/doc/refman'
      +

      If set to an URL which points to +the MySQL documentation (type depends on +$cfg['MySQLManualType']), appropriate help links are +generated.

      +

      See MySQL Documentation page for more +information about MySQL manuals and their types.

      +
      + +
      +
      +$cfg['MySQLManualType']
      +
      +++ + + + + + +
      Type:string
      Default value:'viewable'
      +

      Type of MySQL documentation:

      +
        +
      • viewable - “viewable online”, current one used on MySQL website
      • +
      • searchable - “Searchable, with user comments”
      • +
      • chapters - “HTML, one page per chapter”
      • +
      • big - “HTML, all on one page”
      • +
      • none - do not show documentation links
      • +
      +
      + +
      +
      +

      Languages

      +
      +
      +$cfg['DefaultLang']
      +
      +++ + + + + + +
      Type:string
      Default value:'en'
      +

      Defines the default language to use, if not browser-defined or user- +defined. The corresponding language file needs to be in +locale/code/LC_MESSAGES/phpmyadmin.mo.

      +
      + +
      +
      +$cfg['DefaultConnectionCollation']
      +
      +++ + + + + + +
      Type:string
      Default value:'utf8_general_ci'
      +

      Defines the default connection collation to use, if not user-defined. +See the MySQL documentation for list of possible values. This setting is +ignored when connected to Drizzle server.

      +
      + +
      +
      +$cfg['Lang']
      +
      +++ + + + + + +
      Type:string
      Default value:not set
      +

      Force language to use. The corresponding language file needs to be in +locale/code/LC_MESSAGES/phpmyadmin.mo.

      +
      + +
      +
      +$cfg['FilterLanguages']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Limit list of available languages to those matching the given regular +expression. For example if you want only Czech and English, you should +set filter to '^(cs|en)'.

      +
      + +
      +
      +$cfg['RecodingEngine']
      +
      +++ + + + + + +
      Type:string
      Default value:'auto'
      +

      You can select here which functions will be used for character set +conversion. Possible values are:

      +
        +
      • auto - automatically use available one (first is tested iconv, then +recode)
      • +
      • iconv - use iconv or libiconv functions
      • +
      • recode - use recode_string function
      • +
      • none - disable encoding conversion
      • +
      +

      Enabled charset conversion activates a pull-down menu in the Export +and Import pages, to choose the character set when exporting a file. +The default value in this menu comes from +$cfg['Export']['charset'] and $cfg['Import']['charset'].

      +
      + +
      +
      +$cfg['IconvExtraParams']
      +
      +++ + + + + + +
      Type:string
      Default value:'//TRANSLIT'
      +

      Specify some parameters for iconv used in charset conversion. See +iconv documentation for details. By default +//TRANSLIT is used, so that invalid characters will be +transliterated.

      +
      + +
      +
      +$cfg['AvailableCharsets']
      +
      +++ + + + + + +
      Type:array
      Default value:array(..._
      +

      Available character sets for MySQL conversion. You can add your own +(any of supported by recode/iconv) or remove these which you don’t +use. Character sets will be shown in same order as here listed, so if +you frequently use some of these move them to the top.

      +
      + +
      +
      +

      Web server settings

      +
      +
      +$cfg['OBGzip']
      +
      +++ + + + + + +
      Type:string/boolean
      Default value:'auto'
      +

      Defines whether to use GZip output buffering for increased speed in +HTTP transfers. Set to +true/false for enabling/disabling. When set to ‘auto’ (string), +phpMyAdmin tries to enable output buffering and will automatically +disable it if your browser has some problems with buffering. IE6 with +a certain patch is known to cause data corruption when having enabled +buffering.

      +
      + +
      +
      +$cfg['TrustedProxies']
      +
      +++ + + + + + +
      Type:array
      Default value:array()
      +

      Lists proxies and HTTP headers which are trusted for +$cfg['Servers'][$i]['AllowDeny']['order']. This list is by +default empty, you need to fill in some trusted proxy servers if you +want to use rules for IP addresses behind proxy.

      +

      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:

      +
      $cfg['TrustedProxies'] = array('1.2.3.4' => 'HTTP_X_FORWARDED_FOR');
      +
      +
      +

      The $cfg['Servers'][$i]['AllowDeny']['rules'] directive uses the +client’s IP address as usual.

      +
      + +
      +
      +$cfg['GD2Available']
      +
      +++ + + + + + +
      Type:string
      Default value:'auto'
      +

      Specifies whether GD >= 2 is available. If yes it can be used for MIME +transformations. Possible values are:

      +
        +
      • auto - automatically detect
      • +
      • yes - GD 2 functions can be used
      • +
      • no - GD 2 function cannot be used
      • +
      +
      + +
      +
      +$cfg['CheckConfigurationPermissions']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      We normally check the permissions on the configuration file to ensure +it’s not world writable. However, phpMyAdmin could be installed on a +NTFS filesystem mounted on a non-Windows server, in which case the +permissions seems wrong but in fact cannot be detected. In this case a +sysadmin would set this parameter to false.

      +
      + +
      +
      +$cfg['LinkLengthLimit']
      +
      +++ + + + + + +
      Type:integer
      Default value:1000
      +

      Limit for length of URL in links. When length would be above this +limit, it is replaced by form with button. This is required as some web +servers (IIS) have problems with long URL .

      +
      + +
      +
      +$cfg['CSPAllow']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Additional string to include in allowed script sources in Content Security +Policy header.

      +

      This can be useful when you want to include some external javascript files +in config.footer.inc.php or config.header.inc.php, which +would be normally not allowed by Content Security Policy.

      +
      + +
      +
      +$cfg['DisableMultiTableMaintenance']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      In the database Structure page, it’s possible to mark some tables then +choose an operation like optimizing for many tables. This can slow +down a server; therefore, setting this to true prevents this kind +of multiple maintenance operation.

      +
      + +
      +
      +

      Theme settings

      +
      +
      +$cfg['NaviWidth']
      +
      +++ + + + + + +
      Type:integer
      Default value:
      +

      Navigation panel width in pixels. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['NaviBackground']
      +
      +++ + + + + + +
      Type:string [CSS color for background]
      Default value:
      +
      + +
      +
      +$cfg['MainBackground']
      +
      +++ + + + + + +
      Type:string [CSS color for background]
      Default value:
      +

      The background styles used for both the frames. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['NaviPointerBackground']
      +
      +++ + + + + + +
      Type:string [CSS color for background]
      Default value:
      +
      + +
      +
      +$cfg['NaviPointerColor']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +

      The style used for the pointer in the navi frame. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['Border']
      +
      +++ + + + + + +
      Type:integer
      Default value:
      +

      The size of a table’s border. See themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['ThBackground']
      +
      +++ + + + + + +
      Type:string [CSS color for background]
      Default value:
      +
      + +
      +
      +$cfg['ThColor']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +

      The style used for table headers. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['BgOne']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +

      The color (HTML) #1 for table rows. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['BgTwo']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +

      The color (HTML) #2 for table rows. See +themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['BrowsePointerBackground']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +
      + +
      +
      +$cfg['BrowsePointerColor']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +
      + +
      +
      +$cfg['BrowseMarkerBackground']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +
      + +
      +
      +$cfg['BrowseMarkerColor']
      +
      +++ + + + + + +
      Type:string [CSS color]
      Default value:
      +

      The colors (HTML) uses for the pointer and the marker in browse mode. +The former feature highlights the row over which your mouse is passing +and the latter lets you visually mark/unmark rows by clicking on the +corresponding checkbox. Highlighting / marking a column is done by +hovering over / clicking the column’s header (outside of the text). +See themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['FontFamily']
      +
      +++ + + + + + +
      Type:string
      Default value:
      +

      You put here a valid CSS font family value, for example arial, sans- +serif. See themes/themename/layout.inc.php.

      +
      + +
      +
      +$cfg['FontFamilyFixed']
      +
      +++ + + + + + +
      Type:string
      Default value:
      +

      You put here a valid CSS font family value, for example monospace. +This one is used in textarea. See themes/themename/layout.inc.php.

      +
      + +
      +
      +

      Design customization

      +
      +
      +$cfg['NavigationTreePointerEnable']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      A value of true activates the navi pointer.

      +
      + +
      +
      +$cfg['BrowsePointerEnable']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to activate the browse pointer or not.

      +
      + +
      +
      +$cfg['BrowseMarkerEnable']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to activate the browse marker or not.

      +
      + +
      +
      +$cfg['LimitChars']
      +
      +++ + + + + + +
      Type:integer
      Default value:50
      +

      Maximum number of characters shown in any non-numeric field on browse +view. Can be turned off by a toggle button on the browse page.

      +
      + +
      + +
      +++ + + + + + +
      Type:string
      Default value:'left'
      +

      Defines the place where table row links (Edit, Copy, Delete) would be +put when tables contents are displayed (you may have them displayed at +the left side, right side, both sides or nowhere). “left” and “right” +are parsed as “top” and “bottom” with vertical display mode.

      +
      + +
      +
      +$cfg['DefaultDisplay']
      +
      +++ + + + + + +
      Type:string
      Default value:'horizonta'
      +

      There are 3 display modes: horizontal, horizontalflipped and vertical. +Define which one is displayed by default. The first mode displays each +row on a horizontal line, the second rotates the headers by 90 +degrees, so you can use descriptive headers even though columns only +contain small values and still print them out. The vertical mode sorts +each row on a vertical lineup.

      +
      + +
      +
      +$cfg['RememberSorting']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      If enabled, remember the sorting of each table when browsing them.

      +
      + +
      +
      +$cfg['HeaderFlipType']
      +
      +++ + + + + + +
      Type:string
      Default value:'auto'
      +

      The HeaderFlipType can be set to ‘auto’, ‘css’ or ‘fake’. When using +‘css’ the rotation of the header for horizontalflipped is done via +CSS. The CSS transformation currently works only in Internet +Explorer.If set to ‘fake’ PHP does the transformation for you, but of +course this does not look as good as CSS. The ‘auto’ option enables +CSS transformation when browser supports it and use PHP based one +otherwise.

      +
      + +
      +
      +$cfg['ShowBrowseComments']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +
      + +
      +
      +$cfg['ShowPropertyComments']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      By setting the corresponding variable to true you can enable the +display of column comments in Browse or Property display. In browse +mode, the comments are shown inside the header. In property mode, +comments are displayed using a CSS-formatted dashed-line below the +name of the column. The comment is shown as a tool-tip for that +column.

      +
      + +
      +
      +

      Text fields

      +
      +
      +$cfg['CharEditing']
      +
      +++ + + + + + +
      Type:string
      Default value:'input'
      +

      Defines which type of editing controls should be used for CHAR and +VARCHAR columns. Possible values are:

      +
        +
      • input - this allows to limit size of text to size of columns in MySQL, +but has problems with newlines in columns
      • +
      • textarea - no problems with newlines in columns, but also no length +limitations
      • +
      +
      + +
      +
      +$cfg['MinSizeForInputField']
      +
      +++ + + + + + +
      Type:integer
      Default value:4
      +

      Defines the minimum size for input fields generated for CHAR and +VARCHAR columns.

      +
      + +
      +
      +$cfg['MaxSizeForInputField']
      +
      +++ + + + + + +
      Type:integer
      Default value:60
      +

      Defines the maximum size for input fields generated for CHAR and +VARCHAR columns.

      +
      + +
      +
      +$cfg['TextareaCols']
      +
      +++ + + + + + +
      Type:integer
      Default value:40
      +
      + +
      +
      +$cfg['TextareaRows']
      +
      +++ + + + + + +
      Type:integer
      Default value:15
      +
      + +
      +
      +$cfg['CharTextareaCols']
      +
      +++ + + + + + +
      Type:integer
      Default value:40
      +
      + +
      +
      +$cfg['CharTextareaRows']
      +
      +++ + + + + + +
      Type:integer
      Default value:2
      +

      Number of columns and rows for the textareas. This value will be +emphasized (*2) for SQL query +textareas and (*1.25) for SQL +textareas inside the query window.

      +

      The Char* values are used for CHAR +and VARCHAR editing (if configured via $cfg['CharEditing']).

      +
      + +
      +
      +$cfg['LongtextDoubleTextarea']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Defines whether textarea for LONGTEXT columns should have double size.

      +
      + +
      +
      +$cfg['TextareaAutoSelect']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines if the whole textarea of the query box will be selected on +click.

      +
      + +
      +
      +

      SQL query box settings

      +
      +
      +$cfg['SQLQuery']['Edit']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to display an edit link to change a query in any SQL Query +box.

      +
      + +
      +
      +$cfg['SQLQuery']['Explain']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to display a link to explain a SELECT query in any SQL Query +box.

      +
      + +
      +
      +$cfg['SQLQuery']['ShowAsPHP']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to display a link to wrap a query in PHP code in any SQL Query +box.

      +
      + +
      +
      +$cfg['SQLQuery']['Validate']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to display a link to validate a query in any SQL Query box.

      +
      +

      See also

      +

      $cfg['SQLValidator']

      +
      +
      + +
      +
      +$cfg['SQLQuery']['Refresh']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Whether to display a link to refresh a query in any SQL Query box.

      +
      + +
      +
      +

      Web server upload/save/import directories

      +
      +
      +$cfg['UploadDir']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The name of the directory where SQL files have been uploaded by +other means than phpMyAdmin (for example, ftp). Those files are available +under a drop-down box when you click the database or table name, then the +Import tab.

      +

      If +you want different directory for each user, %u will be replaced with +username.

      +

      Please note that the file names must have the suffix ”.sql” +(or ”.sql.bz2” or ”.sql.gz” if support for compressed formats is +enabled).

      +

      This feature is useful when your file is too big to be +uploaded via HTTP, or when file +uploads are disabled in PHP.

      +
      +

      Note

      +

      If PHP is running in safe mode, this directory must be owned by the same +user as the owner of the phpMyAdmin scripts. See also 1.16 I cannot upload big dump files (memory, HTTP or timeout problems). for +alternatives.

      +
      +
      + +
      +
      +$cfg['SaveDir']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The name of the directory where dumps can be saved.

      +

      If you want different directory for each user, %u will be replaced with +username.

      +

      Please note that the directory must exist and has to be writable for +the user running webserver.

      +
      +

      Note

      +

      If PHP is running in safe mode, this directory must be owned by the same +user as the owner of the phpMyAdmin scripts.

      +
      +
      + +
      +
      +$cfg['TempDir']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The name of the directory where temporary files can be stored.

      +

      This is needed for importing ESRI Shapefiles, see 6.30 Import: How can I import ESRI Shapefiles and to +work around limitations of open_basedir for uploaded files, see +1.11 I get an ‘open_basedir restriction’ while uploading a file from the query box..

      +

      If the directory where phpMyAdmin is installed is +subject to an open_basedir restriction, you need to create a +temporary directory in some directory accessible by the web server. +However for security reasons, this directory should be outside the +tree published by webserver. If you cannot avoid having this directory +published by webserver, place at least an empty index.html file +there, so that directory listing is not possible.

      +

      This directory should have as strict permissions as possible as the only +user required to access this directory is the one who runs the webserver. +If you have root privileges, simply make this user owner of this directory +and make it accessible only by it:

      +
      chown www-data:www-data tmp
      +chmod 700 tmp
      +
      +
      +

      If you cannot change owner of the directory, you can achieve a similar +setup using ACL:

      +
      chmod 700 tmp
      +setfacl -m "g:www-data:rwx" tmp
      +setfacl -d -m "g:www-data:rwx" tmp
      +
      +
      +

      If neither of above works for you, you can still make the directory +chmod 777, but it might impose risk of other users on system +reading and writing data in this directory.

      +
      + +
      +
      +

      Various display setting

      +
      +
      +$cfg['ShowDisplayDirection']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Defines whether or not type display direction option is shown when +browsing a table.

      +
      + +
      +
      +$cfg['RepeatCells']
      +
      +++ + + + + + +
      Type:integer
      Default value:100
      +

      Repeat the headers every X cells, or 0 to deactivate.

      +
      + +
      +
      +$cfg['EditInWindow']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +
      + +
      +
      +$cfg['QueryWindowWidth']
      +
      +++ + + + + + +
      Type:integer
      Default value:550
      +
      + +
      +
      +$cfg['QueryWindowHeight']
      +
      +++ + + + + + +
      Type:integer
      Default value:310
      +
      + +
      +
      +$cfg['QueryHistoryDB']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +
      + +
      +
      +$cfg['QueryWindowDefTab']
      +
      +++ + + + + + +
      Type:string
      Default value:'sql'
      +
      + +
      +
      +$cfg['QueryHistoryMax']
      +
      +++ + + + + + +
      Type:integer
      Default value:25
      +

      All those variables affect the query window feature. A SQL link or +icon is always displayed in the navigation panel. If JavaScript is enabled +in your browser, a click on this opens a distinct query window, which is a +direct interface to enter SQL queries. Otherwise, the right panel +changes to display a query box.

      +

      The size of this query window can be customized with +$cfg['QueryWindowWidth'] and +$cfg['QueryWindowHeight'] - both integers for the size in +pixels. Note that normally, those parameters will be modified in +layout.inc.php` for the theme you are using.

      +

      If $cfg['EditInWindow'] is set to true, a click on [Edit] +from the results page (in the Showing Rows section) opens the +query window and puts the current query inside it. If set to false, +clicking on the link puts the SQL query +in the right panel’s query box.

      +

      If $cfg['QueryHistoryDB'] is set to true, all your +Queries are logged to a table, which has to be created by you (see +$cfg['Servers'][$i]['history']). If set to false, all your +queries will be appended to the form, but only as long as your window is +opened they remain saved.

      +

      When using the JavaScript based query window, it will always get updated +when you click on a new table/db to browse and will focus if you click on +Edit SQL after using a query. You can suppress updating the +query window by checking the box Do not overwrite this query +from outside the window below the query textarea. Then you can browse +tables/databases in the background without losing the contents of the +textarea, so this is especially useful when composing a query with tables +you first have to look in. The checkbox will get automatically checked +whenever you change the contents of the textarea. Please uncheck the button +whenever you definitely want the query window to get updated even though +you have made alterations.

      +

      If $cfg['QueryHistoryDB'] is set to true you can +specify the amount of saved history items using +$cfg['QueryHistoryMax'].

      +

      The query window also has a custom tabbed look to group the features. +Using the variable $cfg['QueryWindowDefTab'] you can +specify the default tab to be used when opening the query window. It can be +set to either sql, files, history or full.

      +
      + +
      +
      +$cfg['BrowseMIME']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Enable Transformations.

      +
      + +
      +
      +$cfg['MaxExactCount']
      +
      +++ + + + + + +
      Type:integer
      Default value:0
      +

      For InnoDB tables, determines for how large tables phpMyAdmin should +get the exact row count using SELECT COUNT. If the approximate row +count as returned by SHOW TABLE STATUS is smaller than this value, +SELECT COUNT will be used, otherwise the approximate count will be +used.

      +
      + +
      +
      +$cfg['MaxExactCountViews']
      +
      +++ + + + + + +
      Type:integer
      Default value:0
      +

      For VIEWs, since obtaining the exact count could have an impact on +performance, this value is the maximum to be displayed, using a +SELECT COUNT ... LIMIT. Setting this to 0 bypasses any row +counting.

      +
      + +
      +
      +$cfg['NaturalOrder']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Sorts database and table names according to natural order (for +example, t1, t2, t10). Currently implemented in the navigation panel +and in Database view, for the table list.

      +
      + +
      +
      +$cfg['InitialSlidersState']
      +
      +++ + + + + + +
      Type:string
      Default value:'closed'
      +

      If set to 'closed', the visual sliders are initially in a closed +state. A value of 'open' does the reverse. To completely disable +all visual sliders, use 'disabled'.

      +
      + +
      +
      +$cfg['UserprefsDisallow']
      +
      +++ + + + + + +
      Type:array
      Default value:array()
      +

      Contains names of configuration options (keys in $cfg array) that +users can’t set through user preferences. For possible values, refer +to libraries/config/user_preferences.forms.php.

      +
      + +
      +
      +$cfg['UserprefsDeveloperTab']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Activates in the user preferences a tab containing options for +developers of phpMyAdmin.

      +
      + +
      +
      +

      Page titles

      +
      +
      +$cfg['TitleTable']
      +
      +++ + + + + + +
      Type:string
      Default value:'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ / @TABLE@ | @PHPMYADMIN@'
      +
      + +
      +
      +$cfg['TitleDatabase']
      +
      +++ + + + + + +
      Type:string
      Default value:'@HTTP_HOST@ / @VSERVER@ / @DATABASE@ | @PHPMYADMIN@'
      +
      + +
      +
      +$cfg['TitleServer']
      +
      +++ + + + + + +
      Type:string
      Default value:'@HTTP_HOST@ / @VSERVER@ | @PHPMYADMIN@'
      +
      + +
      +
      +$cfg['TitleDefault']
      +
      +++ + + + + + +
      Type:string
      Default value:'@HTTP_HOST@ | @PHPMYADMIN@'
      +

      Allows you to specify window’s title bar. You can use 6.27 What format strings can I use?.

      +
      + +
      +
      +

      Theme manager settings

      +
      +
      +$cfg['ThemePath']
      +
      +++ + + + + + +
      Type:string
      Default value:'./themes'
      +

      If theme manager is active, use this as the path of the subdirectory +containing all the themes.

      +
      + +
      +
      +$cfg['ThemeManager']
      +
      +++ + + + + + +
      Type:boolean
      Default value:true
      +

      Enables user-selectable themes. See 2.7 Using and creating themes.

      +
      + +
      +
      +$cfg['ThemeDefault']
      +
      +++ + + + + + +
      Type:string
      Default value:'pmahomme'
      +

      The default theme (a subdirectory under $cfg['ThemePath']).

      +
      + +
      +
      +$cfg['ThemePerServer']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to allow different theme for each server.

      +
      + +
      +
      +

      Default queries

      +
      +
      +$cfg['DefaultQueryTable']
      +
      +++ + + + + + +
      Type:string
      Default value:'SELECT * FROM @TABLE@ WHERE 1'
      +
      + +
      +
      +$cfg['DefaultQueryDatabase']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      Default queries that will be displayed in query boxes when user didn’t +specify any. You can use standard 6.27 What format strings can I use?.

      +
      + +
      +
      +

      SQL parser settings

      +
      +
      +$cfg['SQP']['fmtType']
      +
      +++ + + + + + +
      Type:string
      Default value:'html'
      +

      The main use of the new SQL Parser +is to pretty-print SQL queries. By +default we use HTML to format the query, but you can disable this by +setting this variable to 'none'.

      +

      Available options:

      +
        +
      • 'html'
      • +
      • 'none'
      • +
      +
      + +
      +
      +$cfg['SQP']['fmtInd']
      +
      +++ + + + + + +
      Type:float
      Default value:'1'
      +
      + +
      +
      +$cfg['SQP']['fmtIndUnit']
      +
      +++ + + + + + +
      Type:string
      Default value:'em'
      +

      For the pretty-printing of SQL queries, +under some cases the part of a query inside a bracket is indented. By +changing $cfg['SQP']['fmtInd'] you can change the amount +of this indent.

      +

      Related in purpose is $cfg['SQP']['fmtIndUnit'] which +specifies the units of the indent amount that you specified. This is used +via stylesheets.

      +

      You can use any HTML unit, for example:

      +
        +
      • 'em'
      • +
      • 'ex'
      • +
      • 'pt'
      • +
      • 'px'
      • +
      +
      + +
      +
      +$cfg['SQP']['fmtColor']
      +
      +++ + + + + + +
      Type:array of string tuples
      Default value:
      +

      This array is used to define the colours for each type of element of +the pretty-printed SQL queries. +The tuple format is class => [HTML colour code | empty string]

      +

      If you specify an empty string for the color of a class, it is ignored +in creating the stylesheet. You should not alter the class names, only +the colour strings.

      +

      Class name key:

      +
      +
      comment
      +
      Applies to all comment sub-classes
      +
      comment_mysql
      +
      Comments as "#...\n"
      +
      comment_ansi
      +
      Comments as "-- ...\n"
      +
      comment_c
      +
      Comments as "/*...*/"
      +
      digit
      +
      Applies to all digit sub-classes
      +
      digit_hex
      +
      Hexadecimal numbers
      +
      digit_integer
      +
      Integer numbers
      +
      digit_float
      +
      Floating point numbers
      +
      punct
      +
      Applies to all punctuation sub-classes
      +
      punct_bracket_open_round
      +
      Opening brackets "("
      +
      punct_bracket_close_round
      +
      Closing brackets ")"
      +
      punct_listsep
      +
      List item Separator ","
      +
      punct_qualifier
      +
      Table/Column Qualifier "."
      +
      punct_queryend
      +
      End of query marker ";"
      +
      alpha
      +
      Applies to all alphabetic classes
      +
      alpha_columnType
      +
      Identifiers matching a column type
      +
      alpha_columnAttrib
      +
      Identifiers matching a database/table/column attribute
      +
      alpha_functionName
      +
      Identifiers matching a MySQL function name
      +
      alpha_reservedWord
      +
      Identifiers matching any other reserved word
      +
      alpha_variable
      +
      Identifiers matching a SQL variable "@foo"
      +
      alpha_identifier
      +
      All other identifiers
      +
      quote
      +
      Applies to all quotation mark classes
      +
      quote_double
      +
      Double quotes "
      +
      quote_single
      +
      Single quotes '
      +
      quote_backtick
      +
      Backtick quotes `
      +
      +
      + +
      +
      +

      SQL validator settings

      +
      +
      +$cfg['SQLValidator']
      +
      +++ + + + + + +
      Type:array
      Default value:array(...)
      +
      + +
      +
      +$cfg['SQLValidator']['use']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      phpMyAdmin now supports use of the Mimer SQL Validator service, as originally +published on Slashdot. For +help in setting up your system to use the service, see the +6.14 How do I set up the SQL Validator?.

      +
      + +
      +
      +$cfg['SQLValidator']['username']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +
      + +
      +
      +$cfg['SQLValidator']['password']
      +
      +++ + + + + + +
      Type:string
      Default value:''
      +

      The SOAP service allows you to log in with anonymous and any password, +so we use those by default. Instead, if you have an account with them, you +can put your login details here, and it will be used in place of the +anonymous login.

      +
      + +
      +
      +

      MySQL settings

      +
      +
      +$cfg['DefaultFunctions']
      +
      +++ + + + + + +
      Type:array
      Default value:array(...)
      +

      Functions selected by default when inserting/changing row, Functions +are defined for meta types as (FUNC_NUMBER, FUNC_DATE, FUNC_CHAR, +FUNC_SPATIAL, FUNC_UUID) and for first_timestamp, which is used +for first timestamp column in table.

      +
      + +
      +
      +

      Developer

      +
      +

      Warning

      +

      These settings might have huge effect on performance or security.

      +
      +
      +
      +$cfg['DBG']
      +
      +++ + + + + + +
      Type:array
      Default value:array(...)
      +
      + +
      +
      +$cfg['DBG']['sql']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Enable logging queries and execution times to be +displayed in the bottom of main page (right frame).

      +
      + +
      +
      +$cfg['Error_Handler']['display']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to display errors from PHP or not.

      +
      + +
      +
      +$cfg['Error_Handler']['gather']
      +
      +++ + + + + + +
      Type:boolean
      Default value:false
      +

      Whether to gather errors from PHP or not.

      +
      + +
      +
      + + +
      +
      +
      + +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/copyright.html b/phpmyadmin/doc/html/copyright.html new file mode 100644 index 000000000..f6a207a3f --- /dev/null +++ b/phpmyadmin/doc/html/copyright.html @@ -0,0 +1,134 @@ + + + + + + + + + + Copyright — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + + + + +
      +
      +
      +
      +
      +

      Previous topic

      +

      Distributing and packaging phpMyAdmin

      +

      Next topic

      +

      Credits

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/credits.html b/phpmyadmin/doc/html/credits.html new file mode 100644 index 000000000..747dfd900 --- /dev/null +++ b/phpmyadmin/doc/html/credits.html @@ -0,0 +1,658 @@ + + + + + + + + + + Credits — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Credits

      +
      +

      Credits, in chronological order

      +
        +
      • Tobias Ratschiller <tobias_at_ratschiller.com>
          +
        • creator of the phpmyadmin project
        • +
        • maintainer from 1998 to summer 2000
        • +
        +
      • +
      • Marc Delisle <marc_at_infomarc.info>
          +
        • multi-language version in December 1998
        • +
        • various fixes and improvements
        • +
        • SQL analyser (most of it)
        • +
        • current project maintainer
        • +
        +
      • +
      • Olivier Müller <om_at_omnis.ch>
          +
        • started SourceForge phpMyAdmin project in March 2001
        • +
        • sync’ed different existing CVS trees with new features and bugfixes
        • +
        • multi-language improvements, dynamic language selection
        • +
        • many bugfixes and improvements
        • +
        +
      • +
      • Loïc Chapeaux <lolo_at_phpheaven.net>
          +
        • rewrote and optimized javascript, DHTML and DOM stuff
        • +
        • rewrote the scripts so they fit the PEAR coding standards and +generate XHTML1.0 and CSS2 compliant codes
        • +
        • improved the language detection system
        • +
        • many bugfixes and improvements
        • +
        +
      • +
      • Robin Johnson <robbat2_at_users.sourceforge.net>
          +
        • database maintenance controls
        • +
        • table type code
        • +
        • Host authentication IP Allow/Deny
        • +
        • DB-based configuration (Not completed)
        • +
        • SQL parser and pretty-printer
        • +
        • SQL validator
        • +
        • many bugfixes and improvements
        • +
        +
      • +
      • Armel Fauveau <armel.fauveau_at_globalis-ms.com>
          +
        • bookmarks feature
        • +
        • multiple dump feature
        • +
        • gzip dump feature
        • +
        • zip dump feature
        • +
        +
      • +
      • Geert Lund <glund_at_silversoft.dk>
          +
        • various fixes
        • +
        • moderator of the phpMyAdmin former users forum at phpwizard.net
        • +
        +
      • +
      • Korakot Chaovavanich <korakot_at_iname.com>
          +
        • “insert as new row” feature
        • +
        +
      • +
      • Pete Kelly <webmaster_at_trafficg.com>
          +
        • rewrote and fix dump code
        • +
        • bugfixes
        • +
        +
      • +
      • Steve Alberty <alberty_at_neptunlabs.de>
          +
        • rewrote dump code for PHP4
        • +
        • mySQL table statistics
        • +
        • bugfixes
        • +
        +
      • +
      • Benjamin Gandon <gandon_at_isia.cma.fr>
          +
        • main author of the version 2.1.0.1
        • +
        • bugfixes
        • +
        +
      • +
      • Alexander M. Turek <me_at_derrabus.de>
          +
        • MySQL 4.0 / 4.1 / 5.0 compatibility
        • +
        • abstract database interface (PMA_DBI) with MySQLi support
        • +
        • privileges administration
        • +
        • XML exports
        • +
        • various features and fixes
        • +
        • German language file updates
        • +
        +
      • +
      • Mike Beck <mike.beck_at_web.de>
          +
        • automatic joins in QBE
        • +
        • links column in printview
        • +
        • Relation view
        • +
        +
      • +
      • Michal Čihař <michal_at_cihar.com>
          +
        • enhanced index creation/display feature
        • +
        • feature to use a different charset for HTML than for MySQL
        • +
        • improvements of export feature
        • +
        • various features and fixes
        • +
        • Czech language file updates
        • +
        +
      • +
      • Christophe Gesché from the “MySQL Form Generator for PHPMyAdmin” +(http://sf.net/projects/phpmysqlformgen/)
          +
        • suggested the patch for multiple table printviews
        • +
        +
      • +
      • Garvin Hicking <me_at_supergarv.de>
          +
        • built the patch for vertical display of table rows
        • +
        • built the Javascript based Query window + SQL history
        • +
        • Improvement of column/db comments
        • +
        • (MIME)-Transformations for columns
        • +
        • Use custom alias names for Databases in left frame
        • +
        • hierarchical/nested table display
        • +
        • PDF-scratchboard for WYSIWYG- +distribution of PDF relations
        • +
        • new icon sets
        • +
        • vertical display of column properties page
        • +
        • some bugfixes, features, support, German language additions
        • +
        +
      • +
      • Yukihiro Kawada <kawada_at_den.fujifilm.co.jp>
          +
        • japanese kanji encoding conversion feature
        • +
        +
      • +
      • Piotr Roszatycki <d3xter_at_users.sourceforge.net> and Dan Wilson
          +
        • the Cookie authentication mode
        • +
        +
      • +
      • Axel Sander <n8falke_at_users.sourceforge.net>
          +
        • table relation-links feature
        • +
        +
      • +
      • Maxime Delorme <delorme.maxime_at_free.fr> +
      • +
      • Olof Edlund <olof.edlund_at_upright.se>
          +
        • SQL validator server
        • +
        +
      • +
      • Ivan R. Lanin <ivanlanin_at_users.sourceforge.net>
          +
        • phpMyAdmin logo (until June 2004)
        • +
        +
      • +
      • Mike Cochrane <mike_at_graftonhall.co.nz>
          +
        • blowfish library from the Horde project (withdrawn in release 4.0)
        • +
        +
      • +
      • Marcel Tschopp <ne0x_at_users.sourceforge.net>
          +
        • mysqli support
        • +
        • many bugfixes and improvements
        • +
        +
      • +
      • Nicola Asuni (Tecnick.com) +
      • +
      • Michael Keck <mkkeck_at_users.sourceforge.net>
          +
        • redesign for 2.6.0
        • +
        • phpMyAdmin sailboat logo (June 2004)
        • +
        +
      • +
      • Mathias Landhäußer
          +
        • Representation at conferences
        • +
        +
      • +
      • Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
          +
        • interface improvements
        • +
        • various bugfixes
        • +
        +
      • +
      • Ivan A Kirillov
          +
        • new relations Designer
        • +
        +
      • +
      • Raj Kissu Rajandran (Google Summer of Code 2008)
          +
        • BLOBstreaming support (withdrawn in release 4.0)
        • +
        +
      • +
      • Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011)
          +
        • improved setup script
        • +
        • user preferences
        • +
        • Drizzle support
        • +
        +
      • +
      • Derek Schaefer (Google Summer of Code 2009)
          +
        • Improved the import system
        • +
        +
      • +
      • Alexander Rutkowski (Google Summer of Code 2009)
          +
        • Tracking mechanism
        • +
        +
      • +
      • Zahra Naeem (Google Summer of Code 2009)
          +
        • Synchronization feature (removed in release 4.0)
        • +
        +
      • +
      • Tomáš Srnka (Google Summer of Code 2009)
          +
        • Replication support
        • +
        +
      • +
      • Muhammad Adnan (Google Summer of Code 2010)
          +
        • Relation schema export to multiple formats
        • +
        +
      • +
      • Lori Lee (Google Summer of Code 2010)
          +
        • User interface improvements
        • +
        • ENUM/SET editor
        • +
        • Simplified interface for export/import
        • +
        +
      • +
      • Ninad Pundalik (Google Summer of Code 2010)
          +
        • AJAXifying the interface
        • +
        +
      • +
      • Martynas Mickevičius (Google Summer of Code 2010)
          +
        • Charts
        • +
        +
      • +
      • Barrie Leslie
          +
        • BLOBstreaming support with PBMS PHP extension (withdrawn in release +4.0)
        • +
        +
      • +
      • Ankit Gupta (Google Summer of Code 2010)
          +
        • Visual query builder
        • +
        +
      • +
      • Madhura Jayaratne (Google Summer of Code 2011)
          +
        • OpenGIS support
        • +
        +
      • +
      • Ammar Yasir (Google Summer of Code 2011)
          +
        • Zoom search
        • +
        +
      • +
      • Aris Feryanto (Google Summer of Code 2011)
          +
        • Browse-mode improvements
        • +
        +
      • +
      • Thilanka Kaushalya (Google Summer of Code 2011)
          +
        • AJAXification
        • +
        +
      • +
      • Tyron Madlener (Google Summer of Code 2011)
          +
        • Query statistics and charts for the status page
        • +
        +
      • +
      • Zarubin Stas (Google Summer of Code 2011)
          +
        • Automated testing
        • +
        +
      • +
      • Rouslan Placella (Google Summer of Code 2011 and 2012)
          +
        • Improved support for Stored Routines, Triggers and Events
        • +
        • Italian translation updates
        • +
        • Removal of frames, new navigation
        • +
        +
      • +
      • Dieter Adriaenssens
          +
        • Various bugfixes
        • +
        • Dutch translation updates
        • +
        +
      • +
      • Alex Marin (Google Summer of Code 2012)
          +
        • New plugins and properties system
        • +
        +
      • +
      • Thilina Buddika Abeyrathna (Google Summer of Code 2012)
          +
        • Refactoring
        • +
        +
      • +
      • Atul Pratap Singh (Google Summer of Code 2012)
          +
        • Refactoring
        • +
        +
      • +
      • Chanaka Indrajith (Google Summer of Code 2012)
          +
        • Refactoring
        • +
        +
      • +
      • Yasitha Pandithawatta (Google Summer of Code 2012)
          +
        • Automated testing
        • +
        +
      • +
      • Jim Wigginton (phpseclib.sourceforge.net)
          +
        • phpseclib
        • +
        +
      • +
      +

      And also to the following people who have contributed minor changes, +enhancements, bugfixes or support for a new language since version +2.1.0:

      +

      Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita, +Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats +Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger, +Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg, +Andreas Pauley, Bernard M. Piller, Laurent Haas, “Sakamoto”, Yuval +Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun, +Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V., +Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay, +Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael +Winningham, Vilius Zigmantas, “Manuzhai”.

      +
      +
      +

      Translators

      +

      Following people have contributed to translation of phpMyAdmin:

      +
        +
      • Arabic
          +
        • Abdullah Al-Saedi <abdullah.10_at_windowslive.com>
        • +
        +
      • +
      • Bulgarian
          +
        • stoyanster <stoyanster_at_gmail.com>
        • +
        +
      • +
      • Catalan
          +
        • Xavier Navarro <xvnavarro_at_gmail.com>
        • +
        +
      • +
      • Czech
          +
        • Michal Čihař <michal_at_cihar.com>
        • +
        +
      • +
      • Danish
          +
        • opensource <opensource_at_jth.net>
        • +
        • Jørgen Thomsen <opensource_at_jth.net>
        • +
        +
      • +
      • German
          +
        • mrbendig <mrbendig_at_mrbendig.com>
        • +
        • torsten.funck <torsten.funck_at_googlemail.com>
        • +
        • Sven Strickroth <email_at_cs-ware.de>
        • +
        • typo3 <typo3_at_dirk-weise.de>
        • +
        • Jo Michael <me_at_mynetx.net>
        • +
        +
      • +
      • Greek
          +
        • Panagiotis Papazoglou <papaz_p_at_yahoo.com>
        • +
        +
      • +
      • English (United Kingdom)
          +
        • Robert Readman <robert_readman_at_hotmail.com>
        • +
        +
      • +
      • Spanish
          +
        • Matías Bellone <matiasbellone_at_gmail.com>
        • +
        +
      • +
      • French
          +
        • Marc Delisle <marc_at_infomarc.info>
        • +
        +
      • +
      • Hindi
          +
        • u4663530 <u4663530_at_anu.edu.au>
        • +
        • rsedwardian <rsedwardian_at_gmail.com>
        • +
        +
      • +
      • Hungarian
          +
        • gergo314 <gergo314_at_gmail.com>
        • +
        +
      • +
      • Italian
          +
        • Rouslan Placella <rouslan_at_placella.com>
        • +
        +
      • +
      • Japanese
          +
        • Yuichiro <yuichiro_at_pop07.odn.ne.jp>
        • +
        +
      • +
      • Lithuanian
          +
        • Kęstutis <forkik_at_gmail.com>
        • +
        +
      • +
      • Norwegian Bokmål
          +
        • Sven-Erik Andersen <sven.erik.andersen_at_gmail.com>
        • +
        +
      • +
      • Dutch
          +
        • Dieter Adriaenssens <ruleant_at_users.sourceforge.net>
        • +
        • Herman van Rink <rink_at_initfour.nl>
        • +
        +
      • +
      • Polish
          +
        • Stanisław Krukowski <stankruk_at_neostrada.pl>
        • +
        • Marcin Kozioł <lord_dark_at_wp.pl>
        • +
        +
      • +
      • Portuguese
          +
        • JoaoTMDias <contacto_at_joaodias.me>
        • +
        +
      • +
      • Portuguese (Brazil)
          +
        • wiltave <wiltave_at_gmail.com>
        • +
        • emerson4br <emerson4br_at_gmail.com>
        • +
        +
      • +
      • Romanian
          +
        • alexukf <alex.ukf_at_gmail.com>
        • +
        +
      • +
      • Russian
          +
        • Victor Volkov <hanut_at_php-myadmin.ru>
        • +
        +
      • +
      • Sinhala
          +
        • Madhura Jayaratne <madhura.cj_at_gmail.com>
        • +
        +
      • +
      • Slovak
          +
        • Martin Lacina <martin_at_whistler.sk>
        • +
        +
      • +
      • Slovenian
          +
        • Domen <dbc334_at_gmail.com>
        • +
        +
      • +
      • Swedish
          +
        • stefan <stefan_at_inkopsforum.se>
        • +
        +
      • +
      • Tamil
          +
        • ysajeepan <ysajeepan_at_live.com>
        • +
        +
      • +
      • Telugu
          +
        • veeven <veeven_at_gmail.com>
        • +
        +
      • +
      • Thai
          +
        • kanitchet <kanichet_at_hotmail.com>
        • +
        +
      • +
      • Turkish
          +
        • Burak Yavuz <hitowerdigit_at_hotmail.com>
        • +
        +
      • +
      • Uighur
          +
        • gheni <gheni_at_yahoo.cn>
        • +
        +
      • +
      • Ukrainian
          +
        • typim <duke3d_at_ukr.net>
        • +
        • oleg-ilnytskyi <ukraine.oleg_at_gmail.com>
        • +
        +
      • +
      • Urdu
          +
        • Mehbooob Khan <mehboobbugti_at_gmail.com>
        • +
        +
      • +
      • Simplified Chinese
          +
        • shanyan baishui <Siramizu_at_gmail.com>
        • +
        +
      • +
      • Traditional Chinese
          +
        • star <star_at_origin.club.tw>
        • +
        +
      • +
      +
      +
      +

      Documentation translators

      +

      Following people have contributed to translation of phpMyAdmin documentation:

      +
        +
      • Czech
          +
        • Michal Čihař <michal_at_cihar.com>
        • +
        +
      • +
      • Greek
          +
        • Panagiotis Papazoglou <papaz_p_at_yahoo.com>
        • +
        +
      • +
      • English (United Kingdom)
          +
        • Robert Readman <robert_readman_at_hotmail.com>
        • +
        +
      • +
      • French
          +
        • Cédric Corazza <cedric.corazza_at_wanadoo.fr>
        • +
        +
      • +
      • Japanese
          +
        • Yuichiro Takahashi <yuichiro_at_pop07.odn.ne.jp>
        • +
        +
      • +
      • Polish
          +
        • Stanisław Krukowski <stankruk_at_neostrada.pl>
        • +
        +
      • +
      • Portuguese (Brazil)
          +
        • mjaning <mjaning_at_gmail.com>
        • +
        +
      • +
      • Slovenian
          +
        • Domen <dbc334_at_gmail.com>
        • +
        +
      • +
      +
      +
      +

      Original Credits of Version 2.1.0

      +

      This work is based on Peter Kuppelwieser’s MySQL-Webadmin. It was his +idea to create a web-based interface to MySQL using PHP3. Although I +have not used any of his source-code, there are some concepts I’ve +borrowed from him. phpMyAdmin was created because Peter told me he +wasn’t going to further develop his (great) tool.

      +

      Thanks go to

      +
        +
      • Amalesh Kempf <ak-lsml_at_living-source.com> who contributed the +code for the check when dropping a table or database. He also +suggested that you should be able to specify the primary key on +tbl_create.php3. To version 1.1.1 he contributed the ldi_*.php3-set +(Import text-files) as well as a bug-report. Plus many smaller +improvements.
      • +
      • Jan Legenhausen <jan_at_nrw.net>: He made many of the changes that +were introduced in 1.3.0 (including quite significant ones like the +authentication). For 1.4.1 he enhanced the table-dump feature. Plus +bug-fixes and help.
      • +
      • Marc Delisle <DelislMa_at_CollegeSherbrooke.qc.ca> made phpMyAdmin +language-independent by outsourcing the strings to a separate file. He +also contributed the French translation.
      • +
      • Alexandr Bravo <abravo_at_hq.admiral.ru> who contributed +tbl_select.php3, a feature to display only some columns from a table.
      • +
      • Chris Jackson <chrisj_at_ctel.net> added support for MySQL functions +in tbl_change.php3. He also added the “Query by Example” feature in +2.0.
      • +
      • Dave Walton <walton_at_nordicdms.com> added support for multiple +servers and is a regular contributor for bug-fixes.
      • +
      • Gabriel Ash <ga244_at_is8.nyu.edu> contributed the random access +features for 2.0.6.
      • +
      +

      The following people have contributed minor changes, enhancements, +bugfixes or support for a new language:

      +

      Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas +Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel +Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein, +Jannis Hermanns, G. Wieggers.

      +

      And thanks to everyone else who sent me email with suggestions, bug- +reports and or just some feedback.

      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Copyright

      +

      Next topic

      +

      Glossary

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/developers.html b/phpmyadmin/doc/html/developers.html new file mode 100644 index 000000000..d1789e636 --- /dev/null +++ b/phpmyadmin/doc/html/developers.html @@ -0,0 +1,118 @@ + + + + + + + + + + Developers Information — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Developers Information

      +

      phpMyAdmin is Open Source, so you’re invited to contribute to it. Many +great features have been written by other people and you too can help +to make phpMyAdmin a useful tool.

      +

      You can check out all the possibilities to contribute in the +contribute section on our website.

      +
      + + +
      +
      +
      +
      +
      +

      Previous topic

      +

      FAQ - Frequently Asked Questions

      +

      Next topic

      +

      Distributing and packaging phpMyAdmin

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/faq.html b/phpmyadmin/doc/html/faq.html new file mode 100644 index 000000000..f3ecca503 --- /dev/null +++ b/phpmyadmin/doc/html/faq.html @@ -0,0 +1,1780 @@ + + + + + + + + + + FAQ - Frequently Asked Questions — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      FAQ - Frequently Asked Questions

      +

      Please have a look at our Link section on the official +phpMyAdmin homepage for in-depth coverage of phpMyAdmin’s features and +or interface.

      +
      +

      Server

      +
      +

      1.1 My server is crashing each time a specific action is required or phpMyAdmin sends a blank page or a page full of cryptic characters to my browser, what can I do?

      +

      Try to set the $cfg['OBGzip'] directive to false in your +config.inc.php file and the zlib.output_compression directive to +Off in your php configuration file.

      +
      +
      +

      1.2 My Apache server crashes when using phpMyAdmin.

      +

      You should first try the latest versions of Apache (and possibly MySQL). If +your server keeps crashing, please ask for help in the various Apache support +groups.

      + +
      +
      +

      1.3 (withdrawn).

      +
      +
      +

      1.4 Using phpMyAdmin on IIS, I’m displayed the error message: “The specified CGI application misbehaved by not returning a complete set of HTTP headers ...”.

      +

      You just forgot to read the install.txt file from the PHP +distribution. Have a look at the last message in this PHP bug report #12061 from the official PHP bug +database.

      +
      +
      +

      1.5 Using phpMyAdmin on IIS, I’m facing crashes and/or many error messages with the HTTP.

      +

      This is a known problem with the PHP ISAPI filter: it’s not so stable. +Please use instead the cookie authentication mode.

      +
      +
      +

      1.6 I can’t use phpMyAdmin on PWS: nothing is displayed!

      +

      This seems to be a PWS bug. Filippo Simoncini found a workaround (at +this time there is no better fix): remove or comment the DOCTYPE +declarations (2 lines) from the scripts libraries/Header.class.php +and index.php.

      +
      +
      +

      1.7 How can I GZip or Bzip a dump or a CSV export? It does not seem to work.

      +

      These features are based on the gzencode() and bzcompress() +PHP functions to be more independent of the platform (Unix/Windows, +Safe Mode or not, and so on). So, you must have Zlib/Bzip2 support +(--with-zlib and --with-bz2).

      +
      +
      +

      1.8 I cannot insert a text file in a table, and I get an error about safe mode being in effect.

      +

      Your uploaded file is saved by PHP in the “upload dir”, as defined in +php.ini by the variable upload_tmp_dir (usually the system +default is /tmp). We recommend the following setup for Apache +servers running in safe mode, to enable uploads of files while being +reasonably secure:

      +
        +
      • create a separate directory for uploads: mkdir /tmp/php
      • +
      • give ownership to the Apache server’s user.group: chown +apache.apache /tmp/php
      • +
      • give proper permission: chmod 600 /tmp/php
      • +
      • put upload_tmp_dir = /tmp/php in php.ini
      • +
      • restart Apache
      • +
      +
      +
      +

      1.9 (withdrawn).

      +
      +
      +

      1.10 I’m having troubles when uploading files with phpMyAdmin running on a secure server. My browser is Internet Explorer and I’m using the Apache server.

      +

      As suggested by “Rob M” in the phpWizard forum, add this line to your +httpd.conf:

      +
      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
      +
      +
      +

      It seems to clear up many problems between Internet Explorer and SSL.

      +
      +
      +

      1.11 I get an ‘open_basedir restriction’ while uploading a file from the query box.

      +

      Since version 2.2.4, phpMyAdmin supports servers with open_basedir +restrictions. However you need to create temporary directory and configure it +as $cfg['TempDir']. The uploaded files will be moved there, +and after execution of your SQL commands, removed.

      +
      +
      +

      1.12 I have lost my MySQL root password, what can I do?

      +

      The MySQL manual explains how to reset the permissions.

      +
      +
      +

      1.13 (withdrawn).

      +
      +
      +

      1.14 (withdrawn).

      +
      +
      +

      1.15 I have problems with mysql.user column names.

      +

      In previous MySQL versions, the User and Password``columns were +named ``user and password. Please modify your column names to +align with current standards.

      +
      +
      +

      1.16 I cannot upload big dump files (memory, HTTP or timeout problems).

      +

      Starting with version 2.7.0, the import engine has been re–written and +these problems should not occur. If possible, upgrade your phpMyAdmin +to the latest version to take advantage of the new import features.

      +

      The first things to check (or ask your host provider to check) are the +values of upload_max_filesize, memory_limit and +post_max_size in the php.ini configuration file. All of these +three settings limit the maximum size of data that can be submitted +and handled by PHP. One user also said that post_max_size and +memory_limit need to be larger than upload_max_filesize. +There exist several workarounds if your upload is too big or your +hosting provider is unwilling to change the settings:

      +
        +
      • Look at the $cfg['UploadDir'] feature. This allows one to upload a file to the server +via scp, ftp, or your favorite file transfer method. PhpMyAdmin is +then able to import the files from the temporary directory. More +information is available in the Configuration of this document.

        +
      • +
      • Using a utility (such as BigDump) to split the files before +uploading. We cannot support this or any third party applications, but +are aware of users having success with it.

        +
      • +
      • If you have shell (command line) access, use MySQL to import the files +directly. You can do this by issuing the “source” command from within +MySQL:

        +
        source filename.sql;
        +
        +
        +
      • +
      +
      +
      +

      1.17 Which MySQL versions does phpMyAdmin support?

      +

      Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For +older MySQL versions, you need to use the latest 2.x branch. +phpMyAdmin can connect to your MySQL server using PHP’s classic MySQL +extension as well as the improved MySQL +extension (MySQLi) that is available in PHP +5.0. The latter one should be used unless you have a good reason not +to do so. When compiling PHP, we strongly recommend that you manually +link the MySQL extension of your choice to a MySQL client library of +at least the same minor version since the one that is bundled with +some PHP distributions is rather old and might cause problems see +1.17a I cannot connect to the MySQL server. It always returns the error message, “Client does not support authentication protocol requested by server; consider upgrading MySQL client”. MariaDB is also supported +(versions 5.1 and 5.2 were tested).

      +

      +Changed in version 3.5: Since phpMyAdmin 3.5 Drizzle is supported.

      +
      +
      +

      1.17a I cannot connect to the MySQL server. It always returns the error message, “Client does not support authentication protocol requested by server; consider upgrading MySQL client”

      +

      You tried to access MySQL with an old MySQL client library. The +version of your MySQL client library can be checked in your phpinfo() +output. In general, it should have at least the same minor version as +your server - as mentioned in 1.17 Which MySQL versions does phpMyAdmin support?. This problem is +generally caused by using MySQL version 4.1 or newer. MySQL changed +the authentication hash and your PHP is trying to use the old method. +The proper solution is to use the mysqli extension with the proper client library to match +your MySQL installation. Your chosen extension is specified in +$cfg['Servers'][$i]['extension']. More +information (and several workarounds) are located in the MySQL +Documentation.

      +
      +
      +

      1.18 (withdrawn).

      +
      +
      +

      1.19 I can’t run the “display relations” feature because the script seems not to know the font face I’m using!

      +

      The TCPDF library we’re using for this feature requires some special +files to use font faces. Please refers to the TCPDF manual to build these files.

      +
      +
      +

      1.20 I receive the error “cannot load MySQL extension, please check PHP Configuration”.

      +

      To connect to a MySQL server, PHP needs a set of MySQL functions +called “MySQL extension”. This extension may be part of the PHP +distribution (compiled-in), otherwise it needs to be loaded +dynamically. Its name is probably mysql.so or php_mysql.dll. +phpMyAdmin tried to load the extension but failed. Usually, the +problem is solved by installing a software package called “PHP-MySQL” +or something similar.

      +
      + +
      +

      1.22 I don’t see the “Location of text file” field, so I cannot upload.

      +

      This is most likely because in php.ini, your file_uploads +parameter is not set to “on”.

      +
      +
      +

      1.23 I’m running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!

      +

      This happens because the MySQL directive lower_case_table_names +defaults to 1 (ON) in the Win32 version of MySQL. You can change +this behavior by simply changing the directive to 0 (OFF): Just +edit your my.ini file that should be located in your Windows +directory and add the following line to the group [mysqld]:

      +
      set-variable = lower_case_table_names=0
      +
      +
      +

      Next, save the file and restart the MySQL service. You can always +check the value of this directive using the query

      +
      SHOW VARIABLES LIKE 'lower_case_table_names';
      +
      +
      +
      +
      +

      1.24 (withdrawn).

      +
      +
      +

      1.25 I am running Apache with mod_gzip-1.3.26.1a on Windows XP, and I get problems, such as undefined variables when I run a SQL query.

      +

      A tip from Jose Fandos: put a comment on the following two lines in +httpd.conf, like this:

      +
      # mod_gzip_item_include file \.php$
      +# mod_gzip_item_include mime "application/x-httpd-php.*"
      +
      +
      +

      as this version of mod_gzip on Apache (Windows) has problems handling +PHP scripts. Of course you have to restart Apache.

      +
      +
      +

      1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin.

      +

      This is a permission problem. Right-click on the phpmyadmin folder and +choose properties. Under the tab Security, click on “Add” and select +the user “IUSR_machine” from the list. Now set his permissions and it +should work.

      +
      +
      +

      1.27 I get empty page when I want to view huge page (eg. db_structure.php with plenty of tables).

      +

      This was caused by a PHP bug that occur when +GZIP output buffering is enabled. If you turn off it (by +$cfg['OBGzip'] in config.inc.php), it should work. +This bug will has been fixed in PHP 5.0.0.

      +
      +
      +

      1.28 My MySQL server sometimes refuses queries and returns the message ‘Errorcode: 13’. What does this mean?

      +

      This can happen due to a MySQL bug when having database / table names +with upper case characters although lower_case_table_names is +set to 1. To fix this, turn off this directive, convert all database +and table names to lower case and turn it on again. Alternatively, +there’s a bug-fix available starting with MySQL 3.23.56 / +4.0.11-gamma.

      +
      +
      +

      1.29 When I create a table or modify a column, I get an error and the columns are duplicated.

      +

      It is possible to configure Apache in such a way that PHP has problems +interpreting .php files.

      +

      The problems occur when two different (and conflicting) set of +directives are used:

      +
      SetOutputFilter PHP
      +SetInputFilter PHP
      +
      +
      +

      and

      +
      AddType application/x-httpd-php .php
      +
      +
      +

      In the case we saw, one set of directives was in +/etc/httpd/conf/httpd.conf, while the other set was in +/etc/httpd/conf/addon-modules/php.conf. The recommended way is +with AddType, so just comment out the first set of lines and +restart Apache:

      +
      #SetOutputFilter PHP
      +#SetInputFilter PHP
      +
      +
      +
      +
      +

      1.30 I get the error “navigation.php: Missing hash”.

      +

      This problem is known to happen when the server is running Turck +MMCache but upgrading MMCache to version 2.3.21 solves the problem.

      +
      +
      +

      1.31 Does phpMyAdmin support PHP 5?

      +

      Yes.

      +

      Since release 3.0 only PHP 5.2 and newer. For older PHP versions, use +phpMyAdmin 2.11.x.

      +
      +
      +

      1.32 Can I use HTTP authentication with IIS?

      +

      Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in +ISAPI mode under IIS 5.1.

      +
        +
      1. In your php.ini file, set cgi.rfc2616_headers = 0
      2. +
      3. In Web Site Properties -> File/Directory Security -> Anonymous +Access dialog box, check the Anonymous access checkbox and +uncheck any other checkboxes (i.e. uncheck Basic authentication, +Integrated Windows authentication, and Digest if it’s +enabled.) Click OK.
      4. +
      5. In Custom Errors, select the range of 401;1 through 401;5 +and click the Set to Default button.
      6. +
      +
      +

      See also

      +

      RFC 2616

      +
      +
      +
      +

      1.33 (withdrawn).

      +
      +
      +

      1.34 Can I access directly to database or table pages?

      +

      Yes. Out of the box, you can use URL like http://server/phpMyAdmin/index.php?server=X&db=databas +e&table=table&target=script. For server you use the server number +which refers to the order of the server paragraph in +config.inc.php. Table and script parts are optional. If you want +http://server/phpMyAdmin/database[/table][/script] URL, you need to do some configuration. Following +lines apply only for Apache web server. +First make sure, that you have enabled some features within global +configuration. You need Options FollowSymLinks and AllowOverride +FileInfo enabled for directory where phpMyAdmin is installed and you +need mod_rewrite to be enabled. Then you just need to create +following .htaccess file in root folder of phpMyAdmin installation (don’t +forget to change directory name inside of it):

      +
      RewriteEngine On
      +RewriteBase /path_to_phpMyAdmin
      +RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&table=$2&target=$3 [R]
      +RewriteRule ^([a-zA-Z0-9_]+)/([a-z_]+\.php)$ index.php?db=$1&target=$2 [R]
      +RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)$ index.php?db=$1&table=$2 [R]
      +RewriteRule ^([a-zA-Z0-9_]+)$ index.php?db=$1 [R]
      +
      +
      +
      +
      +

      1.35 Can I use HTTP authentication with Apache CGI?

      +

      Yes. However you need to pass authentication variable to CGI using +following rewrite rule:

      +
      RewriteEngine On
      +RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
      +
      +
      +
      +
      +

      1.36 I get an error “500 Internal Server Error”.

      +

      There can be many explanations to this and a look at your server’s +error log file might give a clue.

      +
      + +
      +

      1.38 Can I use phpMyAdmin on a server on which Suhosin is enabled?

      +

      Yes but the default configuration values of Suhosin are known to cause +problems with some operations, for example editing a table with many +columns and no primary key or with textual primary key.

      +

      Suhosin configuration might lead to malfunction in some cases and it +can not be fully avoided as phpMyAdmin is kind of application which +needs to transfer big amounts of columns in single HTTP request, what +is something what Suhosin tries to prevent. Generally all +suhosin.request.*, suhosin.post.* and suhosin.get.* +directives can have negative effect on phpMyAdmin usability. You can +always find in your error logs which limit did cause dropping of +variable, so you can diagnose the problem and adjust matching +configuration variable.

      +

      The default values for most Suhosin configuration options will work in +most scenarios, however you might want to adjust at least following +parameters:

      + +

      You can also disable the warning using the $cfg['SuhosinDisableWarning'].

      +
      +
      +

      1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?

      +

      Be sure that you have enabled SSLOptions and StdEnvVars in +your Apache configuration.

      + +
      + +
      +

      1.41 When I view a database and ask to see its privileges, I get an error about an unknown column.

      +

      The MySQL server’s privilege tables are not up to date, you need to +run the mysql_upgrade command on the server.

      +
      +
      +

      1.42 How can I prevent robots from accessing phpMyAdmin?

      +

      You can add various rules to .htaccess to filter access based on user agent +field. This is quite easy to circumvent, but could prevent at least +some robots accessing your installation.

      +
      RewriteEngine on
      +
      +# Allow only GET and POST verbs
      +RewriteCond %{REQUEST_METHOD} !^(GET|POST)$ [NC,OR]
      +
      +# Ban Typical Vulnerability Scanners and others
      +# Kick out Script Kiddies
      +RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
      +RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|scan|acunetix).* [NC,OR]
      +RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
      +
      +# Ban Search Engines, Crawlers to your administrative panel
      +# No reasons to access from bots
      +# Ultimately Better than the useless robots.txt
      +# Did google respect robots.txt?
      +# Try google: intitle:phpMyAdmin intext:"Welcome to phpMyAdmin *.*.*" intext:"Log in" -wiki -forum -forums -questions intext:"Cookies must be enabled"
      +RewriteCond %{HTTP_USER_AGENT} ^.*(AdsBot-Google|ia_archiver|Scooter|Ask.Jeeves|Baiduspider|Exabot|FAST.Enterprise.Crawler|FAST-WebCrawler|www\.neomo\.de|Gigabot|Mediapartners-Google|Google.Desktop|Feedfetcher-Google|Googlebot|heise-IT-Markt-Crawler|heritrix|ibm.com\cs/crawler|ICCrawler|ichiro|MJ12bot|MetagerBot|msnbot-NewsBlogs|msnbot|msnbot-media|NG-Search|lucene.apache.org|NutchCVS|OmniExplorer_Bot|online.link.validator|psbot0|Seekbot|Sensis.Web.Crawler|SEO.search.Crawler|Seoma.\[SEO.Crawler\]|SEOsearch|Snappy|www.urltrends.com|www.tkl.iis.u-tokyo.ac.jp/~crawler|SynooBot|crawleradmin.t-info@telekom.de|TurnitinBot|voyager|W3.SiteSearch.Crawler|W3C-checklink|W3C_Validator|www.WISEnutbot.com|yacybot|Yahoo-MMCrawler|Yahoo\!.DE.Slurp|Yahoo\!.Slurp|YahooSeeker).* [NC]
      +RewriteRule .* - [F]
      +
      +
      +
      +
      +

      1.43 Why can’t I display the structure of my table containing hundreds of columns?

      +

      Because your PHP’s memory_limit is too low; adjust it in php.ini.

      +
      +
      +
      +

      Configuration

      +
      +

      2.1 The error message “Warning: Cannot add header information - headers already sent by ...” is displayed, what’s the problem?

      +

      Edit your config.inc.php file and ensure there is nothing (I.E. no +blank lines, no spaces, no characters...) neither before the <?php tag at +the beginning, neither after the ?> tag at the end. We also got a report +from a user under IIS, that used a zipped distribution kit: the file +libraries/Config.class.php contained an end-of-line character (hex 0A) +at the end; removing this character cleared his errors.

      +
      +
      +

      2.2 phpMyAdmin can’t connect to MySQL. What’s wrong?

      +

      Either there is an error with your PHP setup or your username/password +is wrong. Try to make a small script which uses mysql_connect and see +if it works. If it doesn’t, it may be you haven’t even compiled MySQL +support into PHP.

      +
      +
      +

      2.3 The error message “Warning: MySQL Connection Failed: Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (111) ...” is displayed. What can I do?

      +

      For RedHat users, Harald Legner suggests this on the mailing list:

      +

      On my RedHat-Box the socket of MySQL is /var/lib/mysql/mysql.sock. +In your php.ini you will find a line

      +
      mysql.default_socket = /tmp/mysql.sock
      +
      +
      +

      change it to

      +
      mysql.default_socket = /var/lib/mysql/mysql.sock
      +
      +
      +

      Then restart apache and it will work.

      +

      Here is a fix suggested by Brad Ummer:

      +
        +
      • First, you need to determine what socket is being used by MySQL. To do +this, telnet to your server and go to the MySQL bin directory. In this +directory there should be a file named mysqladmin. Type +./mysqladmin variables, and this should give you a bunch of info +about your MySQL server, including the socket (/tmp/mysql.sock, for +example).
      • +
      • Then, you need to tell PHP to use this socket. To do this in +phpMyAdmin, you need to complete the socket information in the +config.inc.php. For example: +$cfg['Servers'][$i]['socket'] Please also make sure that +the permissions of this file allow to be readable by your webserver (i.e. +‘0755’).
      • +
      +

      Have also a look at the corresponding section of the MySQL +documentation.

      +
      +
      +

      2.4 Nothing is displayed by my browser when I try to run phpMyAdmin, what can I do?

      +

      Try to set the $cfg['OBGzip'] directive to false in the phpMyAdmin configuration +file. It helps sometime. Also have a look at your PHP version number: +if it contains “b” or “alpha” it means you’re running a testing +version of PHP. That’s not a so good idea, please upgrade to a plain +revision.

      +
      + +
      +

      2.6 I get an “Access denied for user: 'root@localhost‘ (Using password: YES)”-error when trying to access a MySQL-Server on a host which is port-forwarded for my localhost.

      +

      When you are using a port on your localhost, which you redirect via +port-forwarding to another host, MySQL is not resolving the localhost +as expected. Erik Wasser explains: The solution is: if your host is +“localhost” MySQL (the command line tool mysql as well) always +tries to use the socket connection for speeding up things. And that +doesn’t work in this configuration with port forwarding. If you enter +“127.0.0.1” as hostname, everything is right and MySQL uses the +TCP connection.

      +
      +
      +

      2.7 Using and creating themes

      +

      Themes are configured with $cfg['ThemePath'], +$cfg['ThemeManager'] and $cfg['ThemeDefault']. +Under $cfg['ThemePath'], you should not delete the +directory pmahomme or its underlying structure, because this is the +system theme used by phpMyAdmin. pmahomme contains all images and +styles, for backwards compatibility and for all themes that would not +include images or css-files. If $cfg['ThemeManager'] +is enabled, you can select your favorite theme on the main page. Your selected +theme will be stored in a cookie.

      +

      To create a theme:

      +
        +
      • make a new subdirectory (for example “your_theme_name”) under $cfg['ThemePath'] (by +default themes)
      • +
      • copy the files and directories from pmahomme to “your_theme_name”
      • +
      • edit the css-files in “your_theme_name/css”
      • +
      • put your new images in “your_theme_name/img”
      • +
      • edit layout.inc.php in “your_theme_name”
      • +
      • edit info.inc.php in “your_theme_name” to contain your chosen +theme name, that will be visible in user interface
      • +
      • make a new screenshot of your theme and save it under +“your_theme_name/screen.png”
      • +
      +

      In theme directory there is file info.inc.php which contains theme +verbose name, theme generation and theme version. These versions and +generations are enumerated from 1 and do not have any direct +dependence on phpMyAdmin version. Themes within same generation should +be backwards compatible - theme with version 2 should work in +phpMyAdmin requiring version 1. Themes with different generation are +incompatible.

      +

      If you do not want to use your own symbols and buttons, remove the +directory “img” in “your_theme_name”. phpMyAdmin will use the +default icons and buttons (from the system-theme pmahomme).

      +
      +
      +

      2.8 I get “Missing parameters” errors, what can I do?

      +

      Here are a few points to check:

      +
        +
      • In config.inc.php, try to leave the $cfg['PmaAbsoluteUri'] directive empty. See also +4.7 Authentication window is displayed more than once, why?.
      • +
      • Maybe you have a broken PHP installation or you need to upgrade your +Zend Optimizer. See <http://bugs.php.net/bug.php?id=31134>.
      • +
      • If you are using Hardened PHP with the ini directive +varfilter.max_request_variables set to the default (200) or +another low value, you could get this error if your table has a high +number of columns. Adjust this setting accordingly. (Thanks to Klaus +Dorninger for the hint).
      • +
      • In the php.ini directive arg_separator.input, a value of ”;” +will cause this error. Replace it with “&;”.
      • +
      • If you are using Hardened-PHP, you +might want to increase request limits.
      • +
      • The directory specified in the php.ini directive +session.save_path does not exist or is read-only.
      • +
      +
      +
      +

      2.9 Seeing an upload progress bar

      +

      To be able to see a progress bar during your uploads, your server must +have the APC extension, the +uploadprogress one, or +you must be running PHP 5.4.0 or higher. Moreover, the JSON extension +has to be enabled in your PHP.

      +

      If using APC, you must set apc.rfc1867 to on in your php.ini.

      +

      If using PHP 5.4.0 or higher, you must set +session.upload_progress.enabled to 1 in your php.ini. However, +starting from phpMyAdmin version 4.0.4, session-based upload progress has +been temporarily deactivated due to its problematic behavior.

      +
      +

      See also

      +

      RFC 1867

      +
      +
      +
      +
      +

      Known limitations

      +
      +

      3.1 When using HTTP authentication, a user who logged out can not log in again in with the same nick.

      +

      This is related to the authentication mechanism (protocol) used by +phpMyAdmin. To bypass this problem: just close all the opened browser +windows and then go back to phpMyAdmin. You should be able to log in +again.

      +
      +
      +

      3.2 When dumping a large table in compressed mode, I get a memory limit error or a time limit error.

      +

      Compressed dumps are built in memory and because of this are limited +to php’s memory limit. For GZip/BZip2 exports this can be overcome +since 2.5.4 using $cfg['CompressOnFly'] (enabled by default). +Zip exports can not be handled this way, so if you need Zip files for larger +dump, you have to use another way.

      +
      +
      +

      3.3 With InnoDB tables, I lose foreign key relationships when I rename a table or a column.

      +

      This is an InnoDB bug, see <http://bugs.mysql.com/bug.php?id=21704>.

      +
      +
      +

      3.4 I am unable to import dumps I created with the mysqldump tool bundled with the MySQL server distribution.

      +

      The problem is that older versions of mysqldump created invalid +comments like this:

      +
      -- MySQL dump 8.22
      +--
      +-- Host: localhost Database: database
      +---------------------------------------------------------
      +-- Server version 3.23.54
      +
      +
      +

      The invalid part of the code is the horizontal line made of dashes +that appears once in every dump created with mysqldump. If you want to +run your dump you have to turn it into valid MySQL. This means, you +have to add a whitespace after the first two dashes of the line or add +a # before it: -- ------------------------------------------------------- or +#---------------------------------------------------------

      +
      +
      +

      3.5 When using nested folders, multiple hierarchies are displayed in a wrong manner.

      +

      Please note that you should not use the separating string multiple +times without any characters between them, or at the beginning/end of +your table name. If you have to, think about using another +TableSeparator or disabling that feature.

      + +
      +
      +

      3.6 What is currently not supported in phpMyAdmin about InnoDB?

      +

      In Relation view, being able to choose a table in another database, or +having more than one index column in the foreign key. In Query-by- +example (Query), automatic generation of the query LEFT JOIN from the +foreign table.

      +
      +
      +

      3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like “Warning: unable to parse url”. How can this be fixed?

      +

      Your table neither have a primary key nor an unique one, so we must +use a long expression to identify this row. This causes problems to +parse_url function. The workaround is to create a primary or unique +key.

      +
      +
      +

      3.8 I cannot use (clickable) HTML-forms in columns where I put a MIME-Transformation onto!

      +

      Due to a surrounding form-container (for multi-row delete checkboxes), +no nested forms can be put inside the table where phpMyAdmin displays +the results. You can, however, use any form inside of a table if keep +the parent form-container with the target to tbl_row_delete.php and +just put your own input-elements inside. If you use a custom submit +input field, the form will submit itself to the displaying page again, +where you can validate the $HTTP_POST_VARS in a transformation. For +a tutorial on how to effectively use transformations, see our Link +section on the +official phpMyAdmin-homepage.

      +
      +
      +

      3.9 I get error messages when using “–sql_mode=ANSI” for the MySQL server.

      +

      When MySQL is running in ANSI-compatibility mode, there are some major +differences in how SQL is structured (see +<http://dev.mysql.com/doc/mysql/en/ansi-mode.html>). Most important of all, the +quote-character (”) is interpreted as an identifier quote character and not as +a string quote character, which makes many internal phpMyAdmin operations into +invalid SQL statements. There is no +workaround to this behaviour. News to this item will be posted in Bug report +#1013.

      +
      +
      +

      3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example SELECT lastname from employees where firstname like 'A%' and two “Smith” values are displayed), if I click Edit I cannot be sure that I am editing the intended row.

      +

      Please make sure that your table has a primary key, so that phpMyAdmin +can use it for the Edit and Delete links.

      +
      +
      +

      3.11 The number of rows for InnoDB tables is not correct.

      +

      phpMyAdmin uses a quick method to get the row count, and this method only +returns an approximate count in the case of InnoDB tables. See +$cfg['MaxExactCount'] for a way to modify those results, but +this could have a serious impact on performance.

      +
      +
      +

      3.12 (withdrawn).

      +
      +
      +

      3.13 I get an error when entering USE followed by a db name containing an hyphen.

      +

      The tests I have made with MySQL 5.1.49 shows that the API does not +accept this syntax for the USE command.

      +
      +
      +

      3.14 I am not able to browse a table when I don’t have the right to SELECT one of the columns.

      +

      This has been a known limitation of phpMyAdmin since the beginning and +it’s not likely to be solved in the future.

      +
      +
      +

      3.15 (withdrawn).

      +
      +
      +

      3.16 (withdrawn).

      +
      +
      +

      3.17 (withdrawn).

      +
      +
      +

      3.18 When I import a CSV file that contains multiple tables, they are lumped together into a single table.

      +

      There is no reliable way to differentiate tables in CSV format. For the +time being, you will have to break apart CSV files containing multiple +tables.

      +
      +
      +

      3.19 When I import a file and have phpMyAdmin determine the appropriate data structure it only uses int, decimal, and varchar types.

      +

      Currently, the import type-detection system can only assign these +MySQL types to columns. In future, more will likely be added but for +the time being you will have to edit the structure to your liking +post-import. Also, you should note the fact that phpMyAdmin will use +the size of the largest item in any given column as the column size +for the appropriate type. If you know you will be adding larger items +to that column then you should manually adjust the column sizes +accordingly. This is done for the sake of efficiency.

      +
      +
      +
      +

      ISPs, multi-user installations

      +
      +

      4.1 I’m an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?

      +

      Since version 2.0.3, you can setup a central copy of phpMyAdmin for all your +users. The development of this feature was kindly sponsored by NetCologne GmbH. +This requires a properly setup MySQL user management and phpMyAdmin +HTTP or cookie authentication.

      + +
      +
      +

      4.2 What’s the preferred way of making phpMyAdmin secure against evil access?

      +

      This depends on your system. If you’re running a server which cannot be +accessed by other people, it’s sufficient to use the directory protection +bundled with your webserver (with Apache you can use .htaccess files, +for example). If other people have telnet access to your server, you should use +phpMyAdmin’s HTTP or cookie authentication features.

      +

      Suggestions:

      +
        +
      • Your config.inc.php file should be chmod 660.
      • +
      • All your phpMyAdmin files should be chown -R phpmy.apache, where phpmy +is a user whose password is only known to you, and apache is the group +under which Apache runs.
      • +
      • Follow security recommendations for PHP and your webserver.
      • +
      +
      +
      +

      4.3 I get errors about not being able to include a file in /lang or in /libraries.

      +

      Check php.ini, or ask your sysadmin to check it. The +include_path must contain ”.” somewhere in it, and +open_basedir, if used, must contain ”.” and ”./lang” to allow +normal operation of phpMyAdmin.

      +
      +
      +

      4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication.

      +

      This could happen for several reasons:

      + +
      +
      +

      4.5 Is it possible to let users create their own databases?

      +

      Starting with 2.2.5, in the user management page, you can enter a +wildcard database name for a user (for example “joe%”), and put the +privileges you want. For example, adding SELECT, INSERT, UPDATE, +DELETE, CREATE, DROP, INDEX, ALTER would let a user create/manage +his/her database(s).

      +
      +
      +

      4.6 How can I use the Host-based authentication additions?

      +

      If you have existing rules from an old .htaccess file, you can take them and +add a username between the 'deny'/'allow' and 'from' +strings. Using the username wildcard of '%' would be a major +benefit here if your installation is suited to using it. Then you can +just add those updated lines into the +$cfg['Servers'][$i]['AllowDeny']['rules'] array.

      +

      If you want a pre-made sample, you can try this fragment. It stops the +‘root’ user from logging in from any networks other than the private +network IP blocks.

      +
      //block root from logging in except from the private networks
      +$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';
      +$cfg['Servers'][$i]['AllowDeny']['rules'] = array(
      +    'deny root from all',
      +    'allow root from localhost',
      +    'allow root from 10.0.0.0/8',
      +    'allow root from 192.168.0.0/16',
      +    'allow root from 172.16.0.0/12',
      +);
      +
      +
      +
      +
      +

      4.7 Authentication window is displayed more than once, why?

      +

      This happens if you are using a URL to start phpMyAdmin which is +different than the one set in your $cfg['PmaAbsoluteUri']. For +example, a missing “www”, or entering with an IP address while a domain +name is defined in the config file.

      +
      +
      +

      4.8 Which parameters can I use in the URL that starts phpMyAdmin?

      +

      When starting phpMyAdmin, you can use the db, pma_username, +pma_password and server parameters. This last one can contain +either the numeric host index (from $i of the configuration file) +or one of the host names present in the configuration file. Using +pma_username and pma_password has been tested along with the +usage of ‘cookie’ auth_type.

      +
      +
      +
      +

      Browsers or client OS

      +
      +

      5.1 I get an out of memory error, and my controls are non-functional, when trying to create a table with more than 14 columns.

      +

      We could reproduce this problem only under Win98/98SE. Testing under +WinNT4 or Win2K, we could easily create more than 60 columns. A +workaround is to create a smaller number of columns, then come back to +your table properties and add the other columns.

      +
      +
      +

      5.2 With Xitami 2.5b4, phpMyAdmin won’t process form fields.

      +

      This is not a phpMyAdmin problem but a Xitami known bug: you’ll face +it with each script/website that use forms. Upgrade or downgrade your +Xitami server.

      +
      +
      +

      5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).

      +

      With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except +that the proposed file name for the dump is always ‘tbl_dump.php’. +Bzip2 dumps don’t seem to work. With Konqueror 2.2.1: plain dumps +work; zip dumps are placed into the user’s temporary directory, so +they must be moved before closing Konqueror, or else they disappear. +GZip dumps give an error message. Testing needs to be done for +Konqueror 2.2.2.

      +
      + +
      +

      5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.

      +

      Upgrade to at least Internet Explorer 5.5 SP2.

      +
      +
      +

      5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like “Page not found”) when trying to modify a row in a table with many columns, or with a text column.

      +

      Your table neither have a primary key nor an unique one, so we must use a long +URL to identify this row. There is a limit on the length of the +URL in those browsers, and this not happen in Netscape, for example. +The workaround is to create a primary or unique key, or use another browser.

      +
      +
      +

      5.7 I refresh (reload) my browser, and come back to the welcome page.

      +

      Some browsers support right-clicking into the frame you want to +refresh, just do this in the right frame.

      +
      +
      +

      5.8 With Mozilla 0.9.7 I have problems sending a query modified in the query box.

      +

      Looks like a Mozilla bug: 0.9.6 was OK. We will keep an eye on future +Mozilla versions.

      +
      +
      +

      5.9 With Mozilla 0.9.? to 1.0 and Netscape 7.0-PR1 I can’t type a whitespace in the SQL-Query edit area: the page scrolls down.

      +

      This is a Mozilla bug (see bug #26882 at BugZilla).

      +
      +
      +

      5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.

      +

      This is a known Netscape 4.75 bug: it adds some line feeds when +exporting data in octet-stream mode. Since we can’t detect the +specific Netscape version, we cannot workaround this bug.

      +
      +
      +

      5.11 Extended-ASCII characters like German umlauts are displayed wrong.

      +

      Please ensure that you have set your browser’s character set to the +one of the language file you have selected on phpMyAdmin’s start page. +Alternatively, you can try the auto detection mode that is supported +by the recent versions of the most browsers.

      +
      +
      +

      5.12 Mac OS X Safari browser changes special characters to ”?”.

      +

      This issue has been reported by a Mac OS X user, who adds that Chimera, +Netscape and Mozilla do not have this problem.

      +
      +
      +

      5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.

      +

      This is a bug in Internet Explorer, other browsers do not behave this +way.

      +
      +
      +

      5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.

      +

      Please upgrade to Opera7 at least.

      +
      +
      +

      5.15 I have display problems with Safari.

      +

      Please upgrade to at least version 1.2.3.

      +
      +
      +

      5.16 With Internet Explorer, I get “Access is denied” Javascript errors. Or I cannot make phpMyAdmin work under Windows.

      +

      Please check the following points:

      +
        +
      • Maybe you have defined your $cfg['PmaAbsoluteUri'] setting in +config.inc.php to an IP address and you are starting phpMyAdmin +with a URL containing a domain name, or the reverse situation.
      • +
      • Security settings in IE and/or Microsoft Security Center are too high, +thus blocking scripts execution.
      • +
      • The Windows Firewall is blocking Apache and MySQL. You must allow +HTTP ports (80 or 443) and MySQL +port (usually 3306) in the “in” and “out” directions.
      • +
      +
      +
      +

      5.17 With Firefox, I cannot delete rows of data or drop a database.

      +

      Many users have confirmed that the Tabbrowser Extensions plugin they +installed in their Firefox is causing the problem.

      +
      +
      +

      5.18 With Konqueror 4.2.x an invalid LIMIT clause is generated when I browse a table.

      +

      This happens only when both of these conditions are met: using the +http authentication mode and register_globals being set to +On on the server. It seems to be a browser-specific problem; +meanwhile use the cookie authentication mode.

      +
      +
      +

      5.19 I get JavaScript errors in my browser.

      +

      Issues have been reported with some combinations of browser +extensions. To troubleshoot, disable all extensions then clear your +browser cache to see if the problem goes away.

      +
      +
      +
      +

      Using phpMyAdmin

      +
      +

      6.1 I can’t insert new rows into a table / I can’t create a table - MySQL brings up a SQL error.

      +

      Examine the SQL error with care. +Often the problem is caused by specifying a wrong column-type. Common +errors include:

      +
        +
      • Using VARCHAR without a size argument
      • +
      • Using TEXT or BLOB with a size argument
      • +
      +

      Also, look at the syntax chapter in the MySQL manual to confirm that +your syntax is correct.

      +
      +
      +

      6.2 When I create a table, I set an index for two columns and phpMyAdmin generates only one index with those two columns.

      +

      This is the way to create a multi-columns index. If you want two +indexes, create the first one when creating the table, save, then +display the table properties and click the Index link to create the +other index.

      +
      +
      +

      6.3 How can I insert a null value into my table?

      +

      Since version 2.2.3, you have a checkbox for each column that can be +null. Before 2.2.3, you had to enter “null”, without the quotes, as +the column’s value. Since version 2.5.5, you have to use the checkbox +to get a real NULL value, so if you enter “NULL” this means you want a +literal NULL in the column, and not a NULL value (this works in PHP4).

      +
      +
      +

      6.4 How can I backup my database or table?

      +

      Click on a database or table name in the navigation panel, the properties will +be displayed. Then on the menu, click “Export”, you can dump the structure, the +data, or both. This will generate standard SQL statements that can be +used to recreate your database/table. You will need to choose “Save as file”, +so that phpMyAdmin can transmit the resulting dump to your station. Depending +on your PHP configuration, you will see options to compress the dump. See also +the $cfg['ExecTimeLimit'] configuration variable. For +additional help on this subject, look for the word “dump” in this document.

      +
      +
      +

      6.5 How can I restore (upload) my database or table using a dump? How can I run a ”.sql” file?

      +

      Click on a database name in the navigation panel, the properties will +be displayed. Select “Import” from the list of tabs in the right–hand +frame (or “SQL” if your phpMyAdmin +version is previous to 2.7.0). In the “Location of the text file” +section, type in the path to your dump filename, or use the Browse +button. Then click Go. With version 2.7.0, the import engine has been +re–written, if possible it is suggested that you upgrade to take +advantage of the new features. For additional help on this subject, +look for the word “upload” in this document.

      +
      +
      +

      6.6 How can I use the relation table in Query-by-example?

      +

      Here is an example with the tables persons, towns and countries, all +located in the database mydb. If you don’t have a pma__relation +table, create it as explained in the configuration section. Then +create the example tables:

      +
      CREATE TABLE REL_countries (
      +country_code char(1) NOT NULL default '',
      +description varchar(10) NOT NULL default '',
      +PRIMARY KEY (country_code)
      +) TYPE=MyISAM;
      +
      +INSERT INTO REL_countries VALUES ('C', 'Canada');
      +
      +CREATE TABLE REL_persons (
      +id tinyint(4) NOT NULL auto_increment,
      +person_name varchar(32) NOT NULL default '',
      +town_code varchar(5) default '0',
      +country_code char(1) NOT NULL default '',
      +PRIMARY KEY (id)
      +) TYPE=MyISAM;
      +
      +INSERT INTO REL_persons VALUES (11, 'Marc', 'S', '');
      +INSERT INTO REL_persons VALUES (15, 'Paul', 'S', 'C');
      +
      +CREATE TABLE REL_towns (
      +town_code varchar(5) NOT NULL default '0',
      +description varchar(30) NOT NULL default '',
      +PRIMARY KEY (town_code)
      +) TYPE=MyISAM;
      +
      +INSERT INTO REL_towns VALUES ('S', 'Sherbrooke');
      +INSERT INTO REL_towns VALUES ('M', 'Montréal');
      +
      +
      +

      To setup appropriate links and display information:

      +
        +
      • on table “REL_persons” click Structure, then Relation view
      • +
      • in Links, for “town_code” choose “REL_towns->code”
      • +
      • in Links, for “country_code” choose “REL_countries->country_code”
      • +
      • on table “REL_towns” click Structure, then Relation view
      • +
      • in “Choose column to display”, choose “description”
      • +
      • repeat the two previous steps for table “REL_countries”
      • +
      +

      Then test like this:

      +
        +
      • Click on your db name in the navigation panel
      • +
      • Choose “Query”
      • +
      • Use tables: persons, towns, countries
      • +
      • Click “Update query”
      • +
      • In the columns row, choose persons.person_name and click the “Show” +tickbox
      • +
      • Do the same for towns.description and countries.descriptions in the +other 2 columns
      • +
      • Click “Update query” and you will see in the query box that the +correct joins have been generated
      • +
      • Click “Submit query”
      • +
      +
      +
      +

      6.7 How can I use the “display column” feature?

      +

      Starting from the previous example, create the pma__table_info as +explained in the configuration section, then browse your persons +table, and move the mouse over a town code or country code. See also +6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table? for an additional feature that “display column” +enables: drop-down list of possible values.

      +
      +
      +

      6.8 How can I produce a PDF schema of my database?

      +

      First the configuration variables “relation”, “table_coords” and +“pdf_pages” have to be filled in. Then you need to think about your +schema layout. Which tables will go on which pages?

      +
        +
      • Select your database in the navigation panel.
      • +
      • Choose “Operations” in the navigation bar at the top.
      • +
      • Choose “Edit PDF Pages” near the +bottom of the page.
      • +
      • Enter a name for the first PDF page +and click Go. If you like, you can use the “automatic layout,” which +will put all your linked tables onto the new page.
      • +
      • Select the name of the new page (making sure the Edit radio button is +selected) and click Go.
      • +
      • Select a table from the list, enter its coordinates and click Save. +Coordinates are relative; your diagram will be automatically scaled to +fit the page. When initially placing tables on the page, just pick any +coordinates – say, 50x50. After clicking Save, you can then use the +6.28 How can I easily edit relational schema for export? to position the element correctly.
      • +
      • When you’d like to look at your PDF, first be sure to click the Save +button beneath the list of tables and coordinates, to save any changes you +made there. Then scroll all the way down, select the PDF options you +want, and click Go.
      • +
      • Internet Explorer for Windows may suggest an incorrect filename when +you try to save a generated PDF. +When saving a generated PDF, be +sure that the filename ends in ”.pdf”, for example “schema.pdf”. +Browsers on other operating systems, and other browsers on Windows, do +not have this problem.
      • +
      +
      +
      +

      6.9 phpMyAdmin is changing the type of one of my columns!

      +

      No, it’s MySQL that is doing silent column type changing.

      +
      +
      +

      6.10 When creating a privilege, what happens with underscores in the database name?

      +

      If you do not put a backslash before the underscore, this is a +wildcard grant, and the underscore means “any character”. So, if the +database name is “john_db”, the user would get rights to john1db, +john2db ... If you put a backslash before the underscore, it means +that the database name will have a real underscore.

      +
      +
      +

      6.11 What is the curious symbol ø in the statistics pages?

      +

      It means “average”.

      +
      +
      +

      6.12 I want to understand some Export options.

      +

      Structure:

      +
        +
      • “Add DROP TABLE” will add a line telling MySQL to drop the table, if it already +exists during the import. It does NOT drop the table after your +export, it only affects the import file.
      • +
      • “If Not Exists” will only create the table if it doesn’t exist. +Otherwise, you may get an error if the table name exists but has a +different structure.
      • +
      • “Add AUTO_INCREMENT value” ensures that AUTO_INCREMENT value (if +any) will be included in backup.
      • +
      • “Enclose table and column names with backquotes” ensures that column +and table names formed with special characters are protected.
      • +
      • “Add into comments” includes column comments, relations, and MIME +types set in the pmadb in the dump as SQL comments +(/* xxx */).
      • +
      +

      Data:

      +
        +
      • “Complete inserts” adds the column names on every INSERT command, for +better documentation (but resulting file is bigger).
      • +
      • “Extended inserts” provides a shorter dump file by using only once the +INSERT verb and the table name.
      • +
      • “Delayed inserts” are best explained in the MySQL manual - INSERT DELAYED Syntax.
      • +
      • “Ignore inserts” treats errors as a warning instead. Again, more info +is provided in the MySQL manual - INSERT Syntax, but basically with +this selected, invalid values are adjusted and inserted rather than +causing the entire statement to fail.
      • +
      +
      +
      +

      6.13 I would like to create a database with a dot in its name.

      +

      This is a bad idea, because in MySQL the syntax “database.table” is +the normal way to reference a database and table name. Worse, MySQL +will usually let you create a database with a dot, but then you cannot +work with it, nor delete it.

      +
      +
      +

      6.14 How do I set up the SQL Validator?

      +

      To use SQL Validator, you need PHP with XML, PCRE and +PEAR support. In addition you need a SOAP support, either as a +PHP extension or as a PEAR SOAP module.

      +

      To install PEAR SOAP module, run pear install +Net_Socket Net_URL HTTP_Request Mail_Mime Net_DIME SOAP to get the necessary +PEAR modules for usage.

      +

      If you use the Validator, you should be aware that any SQL statement +you submit will be stored anonymously (database/table/column names, strings, +numbers replaced with generic values). The Mimer SQL Validator itself, +is © 2001 Upright Database Technology. We utilize it as free SOAP service.

      +
      +
      +

      6.15 I want to add a BLOB column and put an index on it, but MySQL says “BLOB column ‘...’ used in key specification without a key length”.

      +

      The right way to do this, is to create the column without any indexes, +then display the table structure and use the “Create an index” dialog. +On this page, you will be able to choose your BLOB column, and set a +size to the index, which is the condition to create an index on a BLOB +column.

      +
      +
      +

      6.16 How can I simply move in page with plenty editing fields?

      +

      You can use Ctrl+arrows (Option+Arrows in Safari) for moving on +most pages with many editing fields (table structure changes, row editing, +etc.).

      +
      +
      +

      6.17 Transformations: I can’t enter my own mimetype! WTF is this feature then useful for?

      +

      Slow down :). Defining mimetypes is of no use, if you can’t put +transformations on them. Otherwise you could just put a comment on the +column. Because entering your own mimetype will cause serious syntax +checking issues and validation, this introduces a high-risk false- +user-input situation. Instead you have to initialize mimetypes using +functions or empty mimetype definitions.

      +

      Plus, you have a whole overview of available mimetypes. Who knows all those +mimetypes by heart so he/she can enter it at will?

      +
      +
      +

      6.18 Bookmarks: Where can I store bookmarks? Why can’t I see any bookmarks below the query box? What is this variable for?

      +

      Any query you have executed can be stored as a bookmark on the page +where the results are displayed. You will find a button labeled +‘Bookmark this query’ just at the end of the page. As soon as you have +stored a bookmark, it is related to the database you run the query on. +You can now access a bookmark dropdown on each page, the query box +appears on for that database.

      +

      You can also have, inside the query, a placeholder for a variable. +This is done by inserting into the query a SQL comment between /* and +*/. Inside the comment, the special string [VARIABLE] is used. +Be aware that the whole query minus the SQL comment must be +valid by itself, otherwise you won’t be able to store it as a bookmark.

      +

      When you execute the bookmark, everything typed into the value +input box on the query box page will replace the string /*[VARIABLE]*/ in +your stored query.

      +

      Also remember, that everything else inside the /*[VARIABLE]*/ string for +your query will remain the way it is, but will be stripped of the /**/ +chars. So you can use:

      +
      /*, [VARIABLE] AS myname */
      +
      +
      +

      which will be expanded to

      +
      , VARIABLE as myname
      +
      +
      +

      in your query, where VARIABLE is the string you entered in the input box. If an +empty string is provided, no replacements are made.

      +

      A more complex example. Say you have stored +this query:

      +
      SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE]%' */
      +
      +
      +

      Say, you now enter “phpMyAdmin” as the variable for the stored query, the full +query will be:

      +
      SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
      +
      +
      +

      You can use multiple occurrences of /*[VARIABLE]*/ in a single query +(that is, multiple occurrences of the same variable).

      +

      NOTE THE ABSENCE OF SPACES inside the /**/ construct. Any spaces +inserted there will be later also inserted as spaces in your query and may lead +to unexpected results especially when using the variable expansion inside of a +“LIKE ‘’” expression.

      +

      Your initial query which is going to be stored as a bookmark has to yield at +least one result row so you can store the bookmark. You may have that to work +around using well positioned /**/ comments.

      +
      +
      +

      6.19 How can I create simple LATEX document to include exported table?

      +

      You can simply include table in your LATEX documents, +minimal sample document should look like following one (assuming you +have table exported in file table.tex):

      +
      \documentclass{article} % or any class you want
      +\usepackage{longtable}  % for displaying table
      +\begin{document}        % start of document
      +\include{table}         % including exported table
      +\end{document}          % end of document
      +
      +
      +
      +
      +

      6.20 I see a lot of databases which are not mine, and cannot access them.

      +

      You have one of these global privileges: CREATE TEMPORARY TABLES, SHOW +DATABASES, LOCK TABLES. Those privileges also enable users to see all the +database names. So if your users do not need those privileges, you can remove +them and their databases list will shorten.

      + +
      +
      +

      6.21 In edit/insert mode, how can I see a list of possible values for a column, based on some foreign table?

      +

      You have to setup appropriate links between the tables, and also setup +the “display column” in the foreign table. See 6.6 How can I use the relation table in Query-by-example? for an +example. Then, if there are 100 values or less in the foreign table, a +drop-down list of values will be available. You will see two lists of +values, the first list containing the key and the display column, the +second list containing the display column and the key. The reason for +this is to be able to type the first letter of either the key or the +display column. For 100 values or more, a distinct window will appear, +to browse foreign key values and choose one. To change the default +limit of 100, see $cfg['ForeignKeyMaxLimit'].

      +
      +
      +

      6.22 Bookmarks: Can I execute a default bookmark automatically when entering Browse mode for a table?

      +

      Yes. If a bookmark has the same label as a table name and it’s not a +public bookmark, it will be executed.

      +
      +
      +

      6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?

      +

      You can use CSV for Microsoft Excel, +which works out of the box.

      +

      +Changed in version 3.4.5: Since phpMyAdmin 3.4.5 support for direct export to Microsoft Excel version +97 and newer was dropped.

      +
      +
      +

      6.24 Now that phpMyAdmin supports native MySQL 4.1.x column comments, what happens to my column comments stored in pmadb?

      +

      Automatic migration of a table’s pmadb-style column comments to the +native ones is done whenever you enter Structure page for this table.

      +
      +
      +

      6.25 (withdrawn).

      +
      +
      +

      6.26 How can I select a range of rows?

      +

      Click the first row of the range, hold the shift key and click the +last row of the range. This works everywhere you see rows, for example +in Browse mode or on the Structure page.

      +
      +
      +

      6.27 What format strings can I use?

      +

      In all places where phpMyAdmin accepts format strings, you can use +@VARIABLE@ expansion and strftime +format strings. The expanded variables depend on a context (for +example, if you haven’t chosen a table, you can not get the table +name), but the following variables can be used:

      +
      +
      @HTTP_HOST@
      +
      HTTP host that runs phpMyAdmin
      +
      @SERVER@
      +
      MySQL server name
      +
      @VERBOSE@
      +
      Verbose MySQL server name as defined in $cfg['Servers'][$i]['verbose']
      +
      @VSERVER@
      +
      Verbose MySQL server name if set, otherwise normal
      +
      @DATABASE@
      +
      Currently opened database
      +
      @TABLE@
      +
      Currently opened table
      +
      @COLUMNS@
      +
      Columns of the currently opened table
      +
      @PHPMYADMIN@
      +
      phpMyAdmin with version
      +
      +
      +
      +

      6.28 How can I easily edit relational schema for export?

      +

      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.

      +

      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.

      +

      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.

      +

      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.

      +
      +
      +

      6.29 Why can’t I get a chart from my query result table?

      +

      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 wiki.

      +
      +
      +

      6.30 Import: How can I import ESRI Shapefiles

      +

      An ESRI Shapefile is actually a set of several files, where .shp file +contains geometry data and .dbf file contains data related to those +geometry data. To read data from .dbf file you need to have PHP +compiled with the dBase extension (–enable-dbase). Otherwise only +geometry data will be imported.

      +

      To upload these set of files you can use either of the following +methods:

      +

      Configure upload directory with $cfg['UploadDir'], upload both .shp and .dbf files with +the same filename and chose the .shp file from the import page.

      +

      Create a Zip archive with .shp and .dbf files and import it. For this +to work, you need to set $cfg['TempDir'] to a place where the web server user can +write (for example './tmp').

      +

      To create the temporary directory on a UNIX-based system, you can do:

      +
      cd phpMyAdmin
      +mkdir tmp
      +chmod o+rwx tmp
      +
      +
      +
      +
      +

      6.31 How do I create a relation in designer?

      +

      To select relation, click: The display column is shown in pink. To +set/unset a column as the display column, click the “Choose column to +display” icon, then click on the appropriate column name.

      +
      +
      +

      6.32 How can I use the zoom search feature?

      +

      The Zoom search feature is an alternative to table search feature. It allows +you to explore a table by representing its data in a scatter plot. You can +locate this feature by selecting a table and clicking the Search +tab. One of the sub-tabs in the Table Search page is +Zoom Search.

      +

      Consider the table REL_persons in 6.6 How can I use the relation table in Query-by-example? for +an example. To use zoom search, two columns need to be selected, for +example, id and town_code. The id values will be represented on one +axis and town_code values on the other axis. Each row will be +represented as a point in a scatter plot based on its id and +town_code. You can include two additional search criteria apart from +the two fields to display.

      +

      You can choose which field should be +displayed as label for each point. If a display column has been set +for the table (see 6.7 How can I use the “display column” feature?), it is taken as the label unless +you specify otherwise. You can also select the maximum number of rows +you want to be displayed in the plot by specifing it in the ‘Max rows +to plot’ field. Once you have decided over your criteria, click ‘Go’ +to display the plot.

      +

      After the plot is generated, you can use the +mousewheel to zoom in and out of the plot. In addition, panning +feature is enabled to navigate through the plot. You can zoom-in to a +certail level of detail and use panning to locate your area of +interest. Clicking on a point opens a dialogue box, displaying field +values of the data row represented by the point. You can edit the +values if required and click on submit to issue an update query. Basic +instructions on how to use can be viewed by clicking the ‘How to use?’ +link located just above the plot.

      +
      +
      +

      6.33 When browsing a table, how can I copy a column name?

      +

      Selecting the name of the column within the browse table header cell +for copying is difficult, as the columns support reordering by +dragging the header cells as well as sorting by clicking on the linked +column name. To copy a column name, double-click on the empty area +next to the column name, when the tooltip tells you to do so. This +will show you an input box with the column name. You may right-click +the column name within this input box to copy it to your clipboard.

      +
      +
      +
      +

      phpMyAdmin project

      +
      +

      7.1 I have found a bug. How do I inform developers?

      +

      Our Bug Tracker is located at <http://sf.net/projects/phpmyadmin/> under the +Bugs section. But please first discuss your bug with other users: +<https://sourceforge.net/projects/phpmyadmin/forums>.

      +
      +
      +

      7.2 I want to translate the messages to a new language or upgrade an existing language, where do I start?

      +

      Translations are very welcome and all you need to have are the +language skills. The easiest way is to use our online translation +service. You can check +out all the possibilities to translate in the translate section on +our website.

      +
      +
      +

      7.3 I would like to help out with the development of phpMyAdmin. How should I proceed?

      +

      We welcome every contribution to the development of phpMyAdmin. You +can check out all the possibilities to contribute in the contribute +section on our website.

      + +
      +
      +
      +

      Security

      +
      +

      8.1 Where can I get information about the security alerts issued for phpMyAdmin?

      +

      Please refer to <http://www.phpmyadmin.net/home_page/security.php>.

      +
      +
      +

      8.2 How can I protect phpMyAdmin against brute force attacks?

      +

      If you use Apache web server, phpMyAdmin exports information about +authentication to the Apache environment and it can be used in Apache +logs. Currently there are two variables available:

      +
      +
      userID
      +
      User name of currently active user (he does not have to be logged in).
      +
      userStatus
      +
      Status of currently active user, one of ok (user is logged in), +mysql-denied (MySQL denied user login), allow-denied (user denied +by allow/deny rules), root-denied (root is denied in configuration), +empty-denied (empty password is denied).
      +
      +

      LogFormat directive for Apache can look like following:

      +
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{userID}n %{userStatus}n"   pma_combined
      +
      +
      +

      You can then use any log analyzing tools to detect possible break-in +attempts.

      +
      +
      +
      +

      Synchronization

      +
      +

      9.1 (withdrawn).

      +
      +
      +

      9.2 (withdrawn).

      +
      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Other sources of information

      +

      Next topic

      +

      Developers Information

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/genindex.html b/phpmyadmin/doc/html/genindex.html new file mode 100644 index 000000000..0519e3049 --- /dev/null +++ b/phpmyadmin/doc/html/genindex.html @@ -0,0 +1,3699 @@ + + + + + + + + + + + + Index — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + +
      +
      +
      +
      + + +

      Index

      + +
      + Symbols + | A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + | X + | Z + +
      +

      Symbols

      + + + +
      + +
      $cfg['AllowArbitraryServer'], [1], [2] +
      + + +
      $cfg['AllowUserDropDatabase'] +
      + + +
      $cfg['AvailableCharsets'] +
      + + +
      $cfg['BgOne'] +
      + + +
      $cfg['BgTwo'] +
      + + +
      $cfg['blowfish_secret'], [1] +
      + + +
      $cfg['Border'] +
      + + +
      $cfg['BrowseMarkerBackground'] +
      + + +
      $cfg['BrowseMarkerColor'] +
      + + +
      $cfg['BrowseMarkerEnable'] +
      + + +
      $cfg['BrowseMIME'] +
      + + +
      $cfg['BrowsePointerBackground'] +
      + + +
      $cfg['BrowsePointerColor'] +
      + + +
      $cfg['BrowsePointerEnable'] +
      + + +
      $cfg['BZipDump'] +
      + + +
      $cfg['CharEditing'], [1] +
      + + +
      $cfg['CharTextareaCols'] +
      + + +
      $cfg['CharTextareaRows'] +
      + + +
      $cfg['CheckConfigurationPermissions'] +
      + + +
      $cfg['CodemirrorEnable'] +
      + + +
      $cfg['CompressOnFly'], [1] +
      + + +
      $cfg['Confirm'] +
      + + +
      $cfg['CSPAllow'] +
      + + +
      $cfg['DBG'] +
      + + +
      $cfg['DBG']['sql'] +
      + + +
      $cfg['DefaultConnectionCollation'] +
      + + +
      $cfg['DefaultDisplay'] +
      + + +
      $cfg['DefaultFunctions'] +
      + + +
      $cfg['DefaultLang'] +
      + + +
      $cfg['DefaultQueryDatabase'] +
      + + +
      $cfg['DefaultQueryTable'] +
      + + +
      $cfg['DefaultTabDatabase'] +
      + + +
      $cfg['DefaultTabServer'] +
      + + +
      $cfg['DefaultTabTable'] +
      + + +
      $cfg['DisableMultiTableMaintenance'] +
      + + +
      $cfg['DisplayBinaryAsHex'] +
      + + +
      $cfg['DisplayServersList'] +
      + + +
      $cfg['EditInWindow'], [1] +
      + + +
      $cfg['Error_Handler']['display'] +
      + + +
      $cfg['Error_Handler']['gather'] +
      + + +
      $cfg['ExecTimeLimit'], [1] +
      + + +
      $cfg['Export'] +
      + + +
      $cfg['Export']['charset'] +
      + + +
      $cfg['Export']['method'] +
      + + +
      $cfg['FilterLanguages'] +
      + + +
      $cfg['FontFamily'] +
      + + +
      $cfg['FontFamilyFixed'] +
      + + +
      $cfg['ForceSSL'] +
      + + +
      $cfg['ForeignKeyDropdownOrder'], [1] +
      + + +
      $cfg['ForeignKeyMaxLimit'], [1] +
      + + +
      $cfg['GD2Available'] +
      + + +
      $cfg['GridEditing'] +
      + + +
      $cfg['GZipDump'] +
      + + +
      $cfg['HeaderFlipType'] +
      + + +
      $cfg['HideStructureActions'] +
      + + +
      $cfg['IconvExtraParams'] +
      + + +
      $cfg['IgnoreMultiSubmitErrors'] +
      + + +
      $cfg['Import'] +
      + + +
      $cfg['Import']['charset'] +
      + + +
      $cfg['InitialSlidersState'] +
      + + +
      $cfg['InsertRows'] +
      + + +
      $cfg['Lang'] +
      + + +
      $cfg['LimitChars'] +
      + + +
      $cfg['LinkLengthLimit'] +
      + + +
      $cfg['LoginCookieDeleteAll'] +
      + + +
      $cfg['LoginCookieRecall'] +
      + + +
      $cfg['LoginCookieStore'] +
      + + +
      $cfg['LoginCookieValidity'], [1] +
      + + +
      $cfg['LongtextDoubleTextarea'] +
      + + +
      $cfg['MainBackground'] +
      + + +
      $cfg['MaxCharactersInDisplayedSQL'] +
      + + +
      $cfg['MaxDbList'] +
      + + +
      $cfg['MaxExactCount'], [1] +
      + + +
      $cfg['MaxExactCountViews'] +
      + + +
      $cfg['MaxNavigationItems'] +
      + + +
      $cfg['MaxRows'], [1] +
      + + +
      $cfg['MaxSizeForInputField'] +
      + + +
      $cfg['MaxTableList'] +
      + + +
      $cfg['McryptDisableWarning'] +
      + + +
      $cfg['MemoryLimit'] +
      + + +
      $cfg['MinSizeForInputField'] +
      + + +
      $cfg['MySQLManualBase'] +
      + + +
      $cfg['MySQLManualType'], [1] +
      + + +
      $cfg['NaturalOrder'] +
      + + +
      $cfg['NaviBackground'] +
      + + +
      $cfg['NavigationBarIconic'] +
      + + +
      $cfg['NavigationDisplayLogo'] +
      + + +
      $cfg['NavigationDisplayServers'] +
      + + +
      $cfg['NavigationLogoLink'] +
      + + +
      $cfg['NavigationLogoLinkWindow'] +
      + + +
      $cfg['NavigationTreeDbSeparator'], [1] +
      + + +
      $cfg['NavigationTreeDefaultTabTable'], [1] +
      + + +
      $cfg['NavigationTreeDisplayDbFilterMinimum'] +
      + + +
      $cfg['NavigationTreeDisplayItemFilterMinimum'] +
      + + +
      $cfg['NavigationTreeEnableGrouping'] +
      + + +
      $cfg['NavigationTreePointerEnable'] +
      + + +
      $cfg['NavigationTreeTableLevel'] +
      + + +
      $cfg['NavigationTreeTableSeparator'], [1] +
      + + +
      $cfg['NaviPointerBackground'] +
      + + +
      $cfg['NaviPointerColor'] +
      + + +
      $cfg['NaviWidth'] +
      + + +
      $cfg['NumRecentTables'], [1] +
      + + +
      $cfg['OBGzip'], [1], [2], [3] +
      + + +
      $cfg['Order'] +
      + + +
      $cfg['PersistentConnections'] +
      + + +
      $cfg['PmaAbsoluteUri'], [1], [2], [3], [4], [5] +
      + + +
      $cfg['PmaNoRelation_DisableWarning'] +
      + + +
      $cfg['PropertiesIconic'] +
      + + +
      $cfg['PropertiesNumColumns'] +
      + + +
      $cfg['ProtectBinary'] +
      + + +
      $cfg['QueryHistoryDB'], [1], [2] +
      + + +
      $cfg['QueryHistoryMax'], [1], [2] +
      + + +
      $cfg['QueryWindowDefTab'], [1] +
      + + +
      $cfg['QueryWindowHeight'], [1] +
      + + +
      $cfg['QueryWindowWidth'], [1] +
      + + +
      $cfg['RecodingEngine'] +
      + + +
      $cfg['RememberSorting'], [1] +
      + +
      + +
      $cfg['RepeatCells'] +
      + + +
      $cfg['ReservedWordDisableWarning'] +
      + + +
      $cfg['RetainQueryBox'] +
      + + +
      $cfg['RowActionLinks'] +
      + + +
      $cfg['SaveCellsAtOnce'] +
      + + +
      $cfg['SaveDir'] +
      + + +
      $cfg['ServerDefault'], [1], [2] +
      + + +
      $cfg['ServerLibraryDifference_DisableWarning'] +
      + + +
      $cfg['Servers'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['AllowDeny']['order'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['AllowDeny']['rules'], [1], [2], [3], [4], [5] +
      + + +
      $cfg['Servers'][$i]['AllowNoPassword'] +
      + + +
      $cfg['Servers'][$i]['AllowRoot'] +
      + + +
      $cfg['Servers'][$i]['auth_http_realm'] +
      + + +
      $cfg['Servers'][$i]['auth_swekey_config'], [1] +
      + + +
      $cfg['Servers'][$i]['auth_type'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['bookmarktable'], [1] +
      + + +
      $cfg['Servers'][$i]['column_comments'] +
      + + +
      $cfg['Servers'][$i]['column_info'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['compress'] +
      + + +
      $cfg['Servers'][$i]['connect_type'] +
      + + +
      $cfg['Servers'][$i]['controlhost'] +
      + + +
      $cfg['Servers'][$i]['controlpass'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['controluser'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['designer_coords'], [1] +
      + + +
      $cfg['Servers'][$i]['DisableIS'], [1] +
      + + +
      $cfg['Servers'][$i]['extension'], [1] +
      + + +
      $cfg['Servers'][$i]['hide_db'] +
      + + +
      $cfg['Servers'][$i]['history'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['host'], [1], [2], [3], [4] +
      + + +
      $cfg['Servers'][$i]['LogoutURL'] +
      + + +
      $cfg['Servers'][$i]['MaxTableUiprefs'] +
      + + +
      $cfg['Servers'][$i]['nopassword'] +
      + + +
      $cfg['Servers'][$i]['only_db'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['password'], [1] +
      + + +
      $cfg['Servers'][$i]['pdf_pages'], [1] +
      + + +
      $cfg['Servers'][$i]['pmadb'], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15] +
      + + +
      $cfg['Servers'][$i]['port'] +
      + + +
      $cfg['Servers'][$i]['recent'], [1] +
      + + +
      $cfg['Servers'][$i]['relation'], [1] +
      + + +
      $cfg['Servers'][$i]['ShowDatabasesCommand'] +
      + + +
      $cfg['Servers'][$i]['SignonScript'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['SignonSession'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['SignonURL'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['socket'], [1] +
      + + +
      $cfg['Servers'][$i]['ssl'] +
      + + +
      $cfg['Servers'][$i]['StatusCacheDatabases'], [1] +
      + + +
      $cfg['Servers'][$i]['StatusCacheLifetime'], [1] +
      + + +
      $cfg['Servers'][$i]['table_coords'], [1] +
      + + +
      $cfg['Servers'][$i]['table_info'], [1] +
      + + +
      $cfg['Servers'][$i]['table_uiprefs'], [1], [2], [3], [4] +
      + + +
      $cfg['Servers'][$i]['tracking'], [1] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_database'] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_table'] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_view'] +
      + + +
      $cfg['Servers'][$i]['tracking_default_statements'] +
      + + +
      $cfg['Servers'][$i]['tracking_version_auto_create'] +
      + + +
      $cfg['Servers'][$i]['user'], [1] +
      + + +
      $cfg['Servers'][$i]['userconfig'], [1] +
      + + +
      $cfg['Servers'][$i]['verbose'], [1], [2], [3] +
      + + +
      $cfg['SessionSavePath'] +
      + + +
      $cfg['ShowAll'] +
      + + +
      $cfg['ShowBrowseComments'] +
      + + +
      $cfg['ShowChgPassword'] +
      + + +
      $cfg['ShowCreateDb'] +
      + + +
      $cfg['ShowDbStructureCreation'] +
      + + +
      $cfg['ShowDbStructureLastCheck'] +
      + + +
      $cfg['ShowDbStructureLastUpdate'] +
      + + +
      $cfg['ShowDisplayDirection'] +
      + + +
      $cfg['ShowFieldTypesInDataEditView'] +
      + + +
      $cfg['ShowFunctionFields'] +
      + + +
      $cfg['ShowHint'] +
      + + +
      $cfg['ShowPhpInfo'] +
      + + +
      $cfg['ShowPropertyComments'] +
      + + +
      $cfg['ShowServerInfo'] +
      + + +
      $cfg['ShowSQL'] +
      + + +
      $cfg['ShowStats'] +
      + + +
      $cfg['ShowTooltip'] +
      + + +
      $cfg['SkipLockedTables'] +
      + + +
      $cfg['SQLQuery']['Edit'] +
      + + +
      $cfg['SQLQuery']['Explain'] +
      + + +
      $cfg['SQLQuery']['Refresh'] +
      + + +
      $cfg['SQLQuery']['ShowAsPHP'] +
      + + +
      $cfg['SQLQuery']['Validate'] +
      + + +
      $cfg['SQLValidator'], [1] +
      + + +
      $cfg['SQLValidator']['password'] +
      + + +
      $cfg['SQLValidator']['use'] +
      + + +
      $cfg['SQLValidator']['username'] +
      + + +
      $cfg['SQP']['fmtColor'] +
      + + +
      $cfg['SQP']['fmtInd'], [1] +
      + + +
      $cfg['SQP']['fmtIndUnit'], [1] +
      + + +
      $cfg['SQP']['fmtType'] +
      + + +
      $cfg['SuhosinDisableWarning'], [1] +
      + + +
      $cfg['TempDir'], [1], [2] +
      + + +
      $cfg['TextareaAutoSelect'] +
      + + +
      $cfg['TextareaCols'] +
      + + +
      $cfg['TextareaRows'] +
      + + +
      $cfg['ThBackground'] +
      + + +
      $cfg['ThColor'] +
      + + +
      $cfg['ThemeDefault'], [1] +
      + + +
      $cfg['ThemeManager'], [1], [2] +
      + + +
      $cfg['ThemePath'], [1], [2], [3], [4] +
      + + +
      $cfg['ThemePerServer'] +
      + + +
      $cfg['TitleDatabase'] +
      + + +
      $cfg['TitleDefault'] +
      + + +
      $cfg['TitleServer'] +
      + + +
      $cfg['TitleTable'] +
      + + +
      $cfg['TranslationWarningThreshold'] +
      + + +
      $cfg['TrustedProxies'], [1] +
      + + +
      $cfg['UploadDir'], [1], [2] +
      + + +
      $cfg['UseDbSearch'] +
      + + +
      $cfg['UserprefsDeveloperTab'] +
      + + +
      $cfg['UserprefsDisallow'] +
      + + +
      $cfg['VersionCheck'] +
      + + +
      $cfg['ZipDump'] +
      + + +
      .htaccess +
      + +
      + +

      A

      + + + +
      + +
      ACL +
      + + +
      AllowArbitraryServer +
      + + +
      AllowDeny, order +
      + + +
      AllowDeny, rules +
      + + +
      AllowNoPassword +
      + + +
      AllowRoot +
      + +
      + +
      AllowUserDropDatabase +
      + + +
      auth_http_realm +
      + + +
      auth_swekey_config +
      + + +
      auth_type +
      + + +
      Authentication mode +
      + +
      + +
      Config +
      + + +
      Cookie +
      + + +
      HTTP +
      + + +
      Signon +
      + + +
      Swekey +
      + +
      + +
      AvailableCharsets +
      + +
      + +

      B

      + + + +
      + +
      BgOne +
      + + +
      BgTwo +
      + + +
      Blowfish +
      + + +
      blowfish_secret +
      + + +
      bookmarktable +
      + + +
      Border +
      + + +
      BrowseMarkerBackground +
      + + +
      BrowseMarkerColor +
      + +
      + +
      BrowseMarkerEnable +
      + + +
      BrowseMIME +
      + + +
      BrowsePointerBackground +
      + + +
      BrowsePointerColor +
      + + +
      BrowsePointerEnable +
      + + +
      Browser +
      + + +
      bzip2 +
      + + +
      BZipDump +
      + +
      + +

      C

      + + + +
      + +
      CGI +
      + + +
      Changelog +
      + + +
      CharEditing +
      + + +
      CharTextareaCols +
      + + +
      CharTextareaRows +
      + + +
      CheckConfigurationPermissions +
      + + +
      Client +
      + + +
      CodemirrorEnable +
      + + +
      column +
      + + +
      column_info +
      + + +
      compress +
      + + +
      CompressOnFly +
      + +
      + +
      + Config +
      + +
      + +
      Authentication mode +
      + +
      + +
      config.inc.php +
      + + +
      + configuration option +
      + +
      + +
      $cfg['AllowArbitraryServer'], [1], [2] +
      + + +
      $cfg['AllowUserDropDatabase'] +
      + + +
      $cfg['AvailableCharsets'] +
      + + +
      $cfg['BZipDump'] +
      + + +
      $cfg['BgOne'] +
      + + +
      $cfg['BgTwo'] +
      + + +
      $cfg['Border'] +
      + + +
      $cfg['BrowseMIME'] +
      + + +
      $cfg['BrowseMarkerBackground'] +
      + + +
      $cfg['BrowseMarkerColor'] +
      + + +
      $cfg['BrowseMarkerEnable'] +
      + + +
      $cfg['BrowsePointerBackground'] +
      + + +
      $cfg['BrowsePointerColor'] +
      + + +
      $cfg['BrowsePointerEnable'] +
      + + +
      $cfg['CSPAllow'] +
      + + +
      $cfg['CharEditing'], [1] +
      + + +
      $cfg['CharTextareaCols'] +
      + + +
      $cfg['CharTextareaRows'] +
      + + +
      $cfg['CheckConfigurationPermissions'] +
      + + +
      $cfg['CodemirrorEnable'] +
      + + +
      $cfg['CompressOnFly'], [1] +
      + + +
      $cfg['Confirm'] +
      + + +
      $cfg['DBG'] +
      + + +
      $cfg['DBG']['sql'] +
      + + +
      $cfg['DefaultConnectionCollation'] +
      + + +
      $cfg['DefaultDisplay'] +
      + + +
      $cfg['DefaultFunctions'] +
      + + +
      $cfg['DefaultLang'] +
      + + +
      $cfg['DefaultQueryDatabase'] +
      + + +
      $cfg['DefaultQueryTable'] +
      + + +
      $cfg['DefaultTabDatabase'] +
      + + +
      $cfg['DefaultTabServer'] +
      + + +
      $cfg['DefaultTabTable'] +
      + + +
      $cfg['DisableMultiTableMaintenance'] +
      + + +
      $cfg['DisplayBinaryAsHex'] +
      + + +
      $cfg['DisplayServersList'] +
      + + +
      $cfg['EditInWindow'], [1] +
      + + +
      $cfg['Error_Handler']['display'] +
      + + +
      $cfg['Error_Handler']['gather'] +
      + + +
      $cfg['ExecTimeLimit'], [1] +
      + + +
      $cfg['Export'] +
      + + +
      $cfg['Export']['charset'] +
      + + +
      $cfg['Export']['method'] +
      + + +
      $cfg['FilterLanguages'] +
      + + +
      $cfg['FontFamily'] +
      + + +
      $cfg['FontFamilyFixed'] +
      + + +
      $cfg['ForceSSL'] +
      + + +
      $cfg['ForeignKeyDropdownOrder'], [1] +
      + + +
      $cfg['ForeignKeyMaxLimit'], [1] +
      + + +
      $cfg['GD2Available'] +
      + + +
      $cfg['GZipDump'] +
      + + +
      $cfg['GridEditing'] +
      + + +
      $cfg['HeaderFlipType'] +
      + + +
      $cfg['HideStructureActions'] +
      + + +
      $cfg['IconvExtraParams'] +
      + + +
      $cfg['IgnoreMultiSubmitErrors'] +
      + + +
      $cfg['Import'] +
      + + +
      $cfg['Import']['charset'] +
      + + +
      $cfg['InitialSlidersState'] +
      + + +
      $cfg['InsertRows'] +
      + + +
      $cfg['Lang'] +
      + + +
      $cfg['LimitChars'] +
      + + +
      $cfg['LinkLengthLimit'] +
      + + +
      $cfg['LoginCookieDeleteAll'] +
      + + +
      $cfg['LoginCookieRecall'] +
      + + +
      $cfg['LoginCookieStore'] +
      + + +
      $cfg['LoginCookieValidity'], [1] +
      + + +
      $cfg['LongtextDoubleTextarea'] +
      + + +
      $cfg['MainBackground'] +
      + + +
      $cfg['MaxCharactersInDisplayedSQL'] +
      + + +
      $cfg['MaxDbList'] +
      + + +
      $cfg['MaxExactCount'], [1] +
      + + +
      $cfg['MaxExactCountViews'] +
      + + +
      $cfg['MaxNavigationItems'] +
      + + +
      $cfg['MaxRows'], [1] +
      + + +
      $cfg['MaxSizeForInputField'] +
      + + +
      $cfg['MaxTableList'] +
      + + +
      $cfg['McryptDisableWarning'] +
      + + +
      $cfg['MemoryLimit'] +
      + + +
      $cfg['MinSizeForInputField'] +
      + + +
      $cfg['MySQLManualBase'] +
      + + +
      $cfg['MySQLManualType'], [1] +
      + + +
      $cfg['NaturalOrder'] +
      + + +
      $cfg['NaviBackground'] +
      + + +
      $cfg['NaviPointerBackground'] +
      + + +
      $cfg['NaviPointerColor'] +
      + + +
      $cfg['NaviWidth'] +
      + + +
      $cfg['NavigationBarIconic'] +
      + + +
      $cfg['NavigationDisplayLogo'] +
      + + +
      $cfg['NavigationDisplayServers'] +
      + + +
      $cfg['NavigationLogoLink'] +
      + + +
      $cfg['NavigationLogoLinkWindow'] +
      + + +
      $cfg['NavigationTreeDbSeparator'], [1] +
      + + +
      $cfg['NavigationTreeDefaultTabTable'], [1] +
      + + +
      $cfg['NavigationTreeDisplayDbFilterMinimum'] +
      + + +
      $cfg['NavigationTreeDisplayItemFilterMinimum'] +
      + + +
      $cfg['NavigationTreeEnableGrouping'] +
      + + +
      $cfg['NavigationTreePointerEnable'] +
      + + +
      $cfg['NavigationTreeTableLevel'] +
      + + +
      $cfg['NavigationTreeTableSeparator'], [1] +
      + + +
      $cfg['NumRecentTables'], [1] +
      + + +
      $cfg['OBGzip'], [1], [2], [3] +
      + + +
      $cfg['Order'] +
      + + +
      $cfg['PersistentConnections'] +
      + + +
      $cfg['PmaAbsoluteUri'], [1], [2], [3], [4], [5] +
      + + +
      $cfg['PmaNoRelation_DisableWarning'] +
      + + +
      $cfg['PropertiesIconic'] +
      + + +
      $cfg['PropertiesNumColumns'] +
      + + +
      $cfg['ProtectBinary'] +
      + + +
      $cfg['QueryHistoryDB'], [1], [2] +
      + + +
      $cfg['QueryHistoryMax'], [1], [2] +
      + + +
      $cfg['QueryWindowDefTab'], [1] +
      + + +
      $cfg['QueryWindowHeight'], [1] +
      + + +
      $cfg['QueryWindowWidth'], [1] +
      + + +
      $cfg['RecodingEngine'] +
      + + +
      $cfg['RememberSorting'], [1] +
      + + +
      $cfg['RepeatCells'] +
      + + +
      $cfg['ReservedWordDisableWarning'] +
      + + +
      $cfg['RetainQueryBox'] +
      + + +
      $cfg['RowActionLinks'] +
      + + +
      $cfg['SQLQuery']['Edit'] +
      + + +
      $cfg['SQLQuery']['Explain'] +
      + + +
      $cfg['SQLQuery']['Refresh'] +
      + + +
      $cfg['SQLQuery']['ShowAsPHP'] +
      + + +
      $cfg['SQLQuery']['Validate'] +
      + + +
      $cfg['SQLValidator'], [1] +
      + + +
      $cfg['SQLValidator']['password'] +
      + + +
      $cfg['SQLValidator']['use'] +
      + + +
      $cfg['SQLValidator']['username'] +
      + + +
      $cfg['SQP']['fmtColor'] +
      + + +
      $cfg['SQP']['fmtInd'], [1] +
      + + +
      $cfg['SQP']['fmtIndUnit'], [1] +
      + + +
      $cfg['SQP']['fmtType'] +
      + + +
      $cfg['SaveCellsAtOnce'] +
      + + +
      $cfg['SaveDir'] +
      + + +
      $cfg['ServerDefault'], [1], [2] +
      + + +
      $cfg['ServerLibraryDifference_DisableWarning'] +
      + + +
      $cfg['Servers'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['AllowDeny']['order'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['AllowDeny']['rules'], [1], [2], [3], [4], [5] +
      + + +
      $cfg['Servers'][$i]['AllowNoPassword'] +
      + + +
      $cfg['Servers'][$i]['AllowRoot'] +
      + + +
      $cfg['Servers'][$i]['DisableIS'], [1] +
      + + +
      $cfg['Servers'][$i]['LogoutURL'] +
      + + +
      $cfg['Servers'][$i]['MaxTableUiprefs'] +
      + + +
      $cfg['Servers'][$i]['ShowDatabasesCommand'] +
      + + +
      $cfg['Servers'][$i]['SignonScript'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['SignonSession'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['SignonURL'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['StatusCacheDatabases'], [1] +
      + + +
      $cfg['Servers'][$i]['StatusCacheLifetime'], [1] +
      + + +
      $cfg['Servers'][$i]['auth_http_realm'] +
      + + +
      $cfg['Servers'][$i]['auth_swekey_config'], [1] +
      + + +
      $cfg['Servers'][$i]['auth_type'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['bookmarktable'], [1] +
      + + +
      $cfg['Servers'][$i]['column_comments'] +
      + + +
      $cfg['Servers'][$i]['column_info'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['compress'] +
      + + +
      $cfg['Servers'][$i]['connect_type'] +
      + + +
      $cfg['Servers'][$i]['controlhost'] +
      + + +
      $cfg['Servers'][$i]['controlpass'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['controluser'], [1], [2], [3] +
      + + +
      $cfg['Servers'][$i]['designer_coords'], [1] +
      + + +
      $cfg['Servers'][$i]['extension'], [1] +
      + + +
      $cfg['Servers'][$i]['hide_db'] +
      + + +
      $cfg['Servers'][$i]['history'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['host'], [1], [2], [3], [4] +
      + + +
      $cfg['Servers'][$i]['nopassword'] +
      + + +
      $cfg['Servers'][$i]['only_db'], [1], [2] +
      + + +
      $cfg['Servers'][$i]['password'], [1] +
      + + +
      $cfg['Servers'][$i]['pdf_pages'], [1] +
      + + +
      $cfg['Servers'][$i]['pmadb'], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15] +
      + + +
      $cfg['Servers'][$i]['port'] +
      + + +
      $cfg['Servers'][$i]['recent'], [1] +
      + + +
      $cfg['Servers'][$i]['relation'], [1] +
      + + +
      $cfg['Servers'][$i]['socket'], [1] +
      + + +
      $cfg['Servers'][$i]['ssl'] +
      + + +
      $cfg['Servers'][$i]['table_coords'], [1] +
      + + +
      $cfg['Servers'][$i]['table_info'], [1] +
      + + +
      $cfg['Servers'][$i]['table_uiprefs'], [1], [2], [3], [4] +
      + + +
      $cfg['Servers'][$i]['tracking'], [1] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_database'] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_table'] +
      + + +
      $cfg['Servers'][$i]['tracking_add_drop_view'] +
      + + +
      $cfg['Servers'][$i]['tracking_default_statements'] +
      + + +
      $cfg['Servers'][$i]['tracking_version_auto_create'] +
      + + +
      $cfg['Servers'][$i]['user'], [1] +
      + + +
      $cfg['Servers'][$i]['userconfig'], [1] +
      + + +
      $cfg['Servers'][$i]['verbose'], [1], [2], [3] +
      + + +
      $cfg['SessionSavePath'] +
      + + +
      $cfg['ShowAll'] +
      + + +
      $cfg['ShowBrowseComments'] +
      + + +
      $cfg['ShowChgPassword'] +
      + + +
      $cfg['ShowCreateDb'] +
      + + +
      $cfg['ShowDbStructureCreation'] +
      + + +
      $cfg['ShowDbStructureLastCheck'] +
      + + +
      $cfg['ShowDbStructureLastUpdate'] +
      + + +
      $cfg['ShowDisplayDirection'] +
      + + +
      $cfg['ShowFieldTypesInDataEditView'] +
      + + +
      $cfg['ShowFunctionFields'] +
      + + +
      $cfg['ShowHint'] +
      + + +
      $cfg['ShowPhpInfo'] +
      + + +
      $cfg['ShowPropertyComments'] +
      + + +
      $cfg['ShowSQL'] +
      + + +
      $cfg['ShowServerInfo'] +
      + + +
      $cfg['ShowStats'] +
      + + +
      $cfg['ShowTooltip'] +
      + + +
      $cfg['SkipLockedTables'] +
      + + +
      $cfg['SuhosinDisableWarning'], [1] +
      + + +
      $cfg['TempDir'], [1], [2] +
      + + +
      $cfg['TextareaAutoSelect'] +
      + + +
      $cfg['TextareaCols'] +
      + + +
      $cfg['TextareaRows'] +
      + + +
      $cfg['ThBackground'] +
      + + +
      $cfg['ThColor'] +
      + + +
      $cfg['ThemeDefault'], [1] +
      + + +
      $cfg['ThemeManager'], [1], [2] +
      + + +
      $cfg['ThemePath'], [1], [2], [3], [4] +
      + + +
      $cfg['ThemePerServer'] +
      + + +
      $cfg['TitleDatabase'] +
      + + +
      $cfg['TitleDefault'] +
      + + +
      $cfg['TitleServer'] +
      + + +
      $cfg['TitleTable'] +
      + + +
      $cfg['TranslationWarningThreshold'] +
      + + +
      $cfg['TrustedProxies'], [1] +
      + + +
      $cfg['UploadDir'], [1], [2] +
      + + +
      $cfg['UseDbSearch'] +
      + + +
      $cfg['UserprefsDeveloperTab'] +
      + + +
      $cfg['UserprefsDisallow'] +
      + + +
      $cfg['VersionCheck'] +
      + + +
      $cfg['ZipDump'] +
      + + +
      $cfg['blowfish_secret'], [1] +
      + +
      + +
      Configuration storage +
      + + +
      Confirm +
      + + +
      connect_type +
      + + +
      controlhost +
      + + +
      controlpass +
      + + +
      controluser +
      + + +
      Cookie +
      + +
      + +
      Authentication mode +
      + +
      + +
      CSPAllow +
      + + +
      CSV +
      + +
      + +

      D

      + + + +
      + +
      database +
      + + +
      DB +
      + + +
      DBG +
      + + +
      DBG, sql +
      + + +
      DefaultConnectionCollation +
      + + +
      DefaultDisplay +
      + + +
      DefaultFunctions +
      + + +
      DefaultLang +
      + + +
      DefaultQueryDatabase +
      + +
      + +
      DefaultQueryTable +
      + + +
      DefaultTabDatabase +
      + + +
      DefaultTabServer +
      + + +
      DefaultTabTable +
      + + +
      designer_coords +
      + + +
      DisableIS +
      + + +
      DisableMultiTableMaintenance +
      + + +
      DisplayBinaryAsHex +
      + + +
      DisplayServersList +
      + +
      + +

      E

      + + + +
      + +
      EditInWindow +
      + + +
      Engine +
      + + +
      Error_Handler, display +
      + + +
      Error_Handler, gather +
      + +
      + +
      ExecTimeLimit +
      + + +
      Export +
      + + +
      Export, method +
      + + +
      extension, [1] +
      + +
      + +

      F

      + + + +
      + +
      FAQ +
      + + +
      Field +
      + + +
      FilterLanguages +
      + + +
      FontFamily +
      + + +
      FontFamilyFixed +
      + +
      + +
      ForceSSL +
      + + +
      foreign key +
      + + +
      ForeignKeyDropdownOrder +
      + + +
      ForeignKeyMaxLimit +
      + + +
      FPDF +
      + +
      + +

      G

      + + + +
      + +
      GD +
      + + +
      GD2 +
      + + +
      GD2Available +
      + +
      + +
      GridEditing +
      + + +
      gzip +
      + + +
      GZipDump +
      + +
      + +

      H

      + + + +
      + +
      HeaderFlipType +
      + + +
      hide_db +
      + + +
      HideStructureActions +
      + + +
      history +
      + +
      + +
      host, [1] +
      + + +
      hostname +
      + + +
      HTTP +
      + +
      + +
      Authentication mode +
      + +
      + +
      https +
      + +
      + +

      I

      + + + +
      + +
      IconvExtraParams +
      + + +
      IEC +
      + + +
      IgnoreMultiSubmitErrors +
      + + +
      IIS +
      + + +
      Import +
      + + +
      Index +
      + + +
      InitialSlidersState +
      + +
      + +
      InsertRows +
      + + +
      IP +
      + + +
      IP Address +
      + + +
      IPv6 +
      + + +
      ISAPI +
      + + +
      ISO +
      + + +
      ISP +
      + +
      + +

      J

      + + + +
      + +
      JPEG +
      + +
      + +
      JPG +
      + +
      + +

      K

      + + +
      + +
      Key +
      + +
      + +

      L

      + + + +
      + +
      Lang +
      + + +
      LATEX +
      + + +
      LimitChars +
      + + +
      LinkLengthLimit +
      + + +
      LoginCookieDeleteAll +
      + +
      + +
      LoginCookieRecall +
      + + +
      LoginCookieStore +
      + + +
      LoginCookieValidity +
      + + +
      LogoutURL +
      + + +
      LongtextDoubleTextarea +
      + +
      + +

      M

      + + + +
      + +
      Mac +
      + + +
      Mac OS X +
      + + +
      MainBackground +
      + + +
      MaxCharactersInDisplayedSQL +
      + + +
      MaxDbList +
      + + +
      MaxExactCount +
      + + +
      MaxExactCountViews +
      + + +
      MaxNavigationItems +
      + + +
      MaxRows +
      + + +
      MaxSizeForInputField +
      + + +
      MaxTableList +
      + + +
      MaxTableUiprefs +
      + +
      + +
      MCrypt +
      + + +
      mcrypt +
      + + +
      McryptDisableWarning +
      + + +
      MemoryLimit +
      + + +
      MIME +
      + + +
      MinSizeForInputField +
      + + +
      module +
      + + +
      MySQL +
      + + +
      mysql +
      + + +
      mysqli +
      + + +
      MySQLManualBase +
      + + +
      MySQLManualType +
      + +
      + +

      N

      + + + +
      + +
      NaturalOrder +
      + + +
      NaviBackground +
      + + +
      NavigationBarIconic +
      + + +
      NavigationDisplayLogo +
      + + +
      NavigationDisplayServers +
      + + +
      NavigationLogoLink +
      + + +
      NavigationLogoLinkWindow +
      + + +
      NavigationTreeDbSeparator +
      + + +
      NavigationTreeDefaultTabTable +
      + + +
      NavigationTreeDisplayDbFilterMinimum +
      + +
      + +
      NavigationTreeDisplayItemFilterMinimum +
      + + +
      NavigationTreeEnableGrouping +
      + + +
      NavigationTreePointerEnable +
      + + +
      NavigationTreeTableLevel +
      + + +
      NavigationTreeTableSeparator +
      + + +
      NaviPointerBackground +
      + + +
      NaviPointerColor +
      + + +
      NaviWidth +
      + + +
      nopassword +
      + + +
      NumRecentTables +
      + +
      + +

      O

      + + + +
      + +
      OBGzip +
      + + +
      only_db +
      + + +
      OpenDocument +
      + +
      + +
      Order +
      + + +
      OS X +
      + +
      + +

      P

      + + + +
      + +
      password +
      + + +
      PCRE +
      + + +
      PDF +
      + + +
      pdf_pages +
      + + +
      PEAR +
      + + +
      PersistentConnections +
      + + +
      PHP +
      + + +
      phpMyAdmin configuration storage +
      + +
      + +
      PmaAbsoluteUri +
      + + +
      pmadb, [1] +
      + + +
      PmaNoRelation_DisableWarning +
      + + +
      port, [1] +
      + + +
      PropertiesIconic +
      + + +
      PropertiesNumColumns +
      + + +
      ProtectBinary +
      + +
      + +

      Q

      + + + +
      + +
      QueryHistoryDB +
      + + +
      QueryHistoryMax +
      + + +
      QueryWindowDefTab +
      + +
      + +
      QueryWindowHeight +
      + + +
      QueryWindowWidth +
      + +
      + +

      R

      + + + +
      + +
      recent +
      + + +
      RecodingEngine +
      + + +
      relation +
      + + +
      RememberSorting +
      + + +
      RepeatCells +
      + + +
      ReservedWordDisableWarning +
      + +
      + +
      RetainQueryBox +
      + + +
      RFC +
      + +
      + +
      RFC 1867 +
      + + +
      RFC 1952 +
      + + +
      RFC 2616 +
      + +
      + +
      RFC 1952 +
      + + +
      Row (record, tuple) +
      + + +
      RowActionLinks +
      + +
      + +

      S

      + + + +
      + +
      SaveCellsAtOnce +
      + + +
      SaveDir +
      + + +
      Server +
      + + +
      + server configuration +
      + +
      + +
      AllowDeny, order +
      + + +
      AllowDeny, rules +
      + + +
      AllowNoPassword +
      + + +
      AllowRoot +
      + + +
      DisableIS +
      + + +
      LogoutURL +
      + + +
      MaxTableUiprefs +
      + + +
      ShowDatabasesCommand +
      + + +
      SignonScript +
      + + +
      SignonSession +
      + + +
      SignonURL +
      + + +
      StatusCacheDatabases +
      + + +
      StatusCacheLifetime +
      + + +
      auth_http_realm +
      + + +
      auth_swekey_config +
      + + +
      auth_type +
      + + +
      bookmarktable +
      + + +
      column_info +
      + + +
      compress +
      + + +
      connect_type +
      + + +
      controlhost +
      + + +
      controlpass +
      + + +
      controluser +
      + + +
      designer_coords +
      + + +
      extension +
      + + +
      hide_db +
      + + +
      history +
      + + +
      host +
      + + +
      nopassword +
      + + +
      only_db +
      + + +
      password +
      + + +
      pdf_pages +
      + + +
      pmadb +
      + + +
      port +
      + + +
      recent +
      + + +
      relation +
      + + +
      socket +
      + + +
      ssl +
      + + +
      table_coords +
      + + +
      table_info +
      + + +
      table_uiprefs +
      + + +
      tracking +
      + + +
      tracking_add_drop_database +
      + + +
      tracking_add_drop_table +
      + + +
      tracking_add_drop_view +
      + + +
      tracking_default_statements +
      + + +
      tracking_version_auto_create +
      + + +
      user +
      + + +
      userconfig +
      + + +
      verbose +
      + +
      + +
      ServerDefault +
      + + +
      ServerLibraryDifference_DisableWarning +
      + + +
      Servers +
      + + +
      SessionSavePath +
      + + +
      Setup script +
      + + +
      ShowAll +
      + + +
      ShowBrowseComments +
      + + +
      ShowChgPassword +
      + + +
      ShowCreateDb +
      + + +
      ShowDatabasesCommand +
      + + +
      ShowDbStructureCreation +
      + + +
      ShowDbStructureLastCheck +
      + + +
      ShowDbStructureLastUpdate +
      + + +
      ShowDisplayDirection +
      + + +
      ShowFieldTypesInDataEditView +
      + + +
      ShowFunctionFields +
      + + +
      ShowHint +
      + + +
      ShowPhpInfo +
      + + +
      ShowPropertyComments +
      + + +
      ShowServerInfo +
      + + +
      ShowSQL +
      + + +
      ShowStats +
      + + +
      ShowTooltip +
      + + +
      + Signon +
      + +
      + +
      Authentication mode +
      + +
      +
      + +
      SignonScript +
      + + +
      SignonSession +
      + + +
      SignonURL +
      + + +
      SkipLockedTables +
      + + +
      SOAP +
      + + +
      socket, [1] +
      + + +
      SQL +
      + + +
      SQLQuery, Edit +
      + + +
      SQLQuery, Explain +
      + + +
      SQLQuery, Refresh +
      + + +
      SQLQuery, ShowAsPHP +
      + + +
      SQLQuery, Validate +
      + + +
      SQLValidator +
      + + +
      SQLValidator, password +
      + + +
      SQLValidator, use +
      + + +
      SQLValidator, username +
      + + +
      SQP, fmtColor +
      + + +
      SQP, fmtInd +
      + + +
      SQP, fmtIndUnit +
      + + +
      SQP, fmtType +
      + + +
      SSL +
      + + +
      ssl +
      + + +
      StatusCacheDatabases +
      + + +
      StatusCacheLifetime +
      + + +
      Storage Engines +
      + + +
      Stored procedure +
      + + +
      SuhosinDisableWarning +
      + + +
      + Swekey +
      + +
      + +
      Authentication mode +
      + +
      +
      + +

      T

      + + + +
      + +
      table +
      + + +
      table_coords +
      + + +
      table_info +
      + + +
      table_uiprefs +
      + + +
      tar +
      + + +
      TCP +
      + + +
      TCPDF +
      + + +
      TempDir +
      + + +
      TextareaAutoSelect +
      + + +
      TextareaCols +
      + + +
      TextareaRows +
      + + +
      ThBackground +
      + + +
      ThColor +
      + + +
      ThemeDefault +
      + + +
      ThemeManager +
      + +
      + +
      ThemePath +
      + + +
      ThemePerServer +
      + + +
      TitleDatabase +
      + + +
      TitleDefault +
      + + +
      TitleServer +
      + + +
      TitleTable +
      + + +
      tracking +
      + + +
      tracking_add_drop_database +
      + + +
      tracking_add_drop_table +
      + + +
      tracking_add_drop_view +
      + + +
      tracking_default_statements +
      + + +
      tracking_version_auto_create +
      + + +
      TranslationWarningThreshold +
      + + +
      trigger +
      + + +
      TrustedProxies +
      + +
      + +

      U

      + + + +
      + +
      UFPDF +
      + + +
      UploadDir +
      + + +
      URL +
      + + +
      UseDbSearch +
      + +
      + +
      user +
      + + +
      userconfig +
      + + +
      UserprefsDeveloperTab +
      + + +
      UserprefsDisallow +
      + +
      + +

      V

      + + + +
      + +
      verbose +
      + +
      + +
      VersionCheck +
      + +
      + +

      W

      + + +
      + +
      Webserver +
      + +
      + +

      X

      + + +
      + +
      XML +
      + +
      + +

      Z

      + + + +
      + +
      ZIP +
      + + +
      ZipDump +
      + +
      + +
      zlib +
      + +
      + + + +
      +
      +
      +
      +
      + + + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/glossary.html b/phpmyadmin/doc/html/glossary.html new file mode 100644 index 000000000..757eb4908 --- /dev/null +++ b/phpmyadmin/doc/html/glossary.html @@ -0,0 +1,627 @@ + + + + + + + + + + Glossary — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Glossary

      +

      From Wikipedia, the free encyclopedia

      +
      +
      .htaccess
      +

      the default name of Apache’s directory-level configuration file.

      + +
      +
      ACL
      +
      Access Contol List
      +
      Blowfish
      +

      a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.

      + +
      +
      Browser
      +

      a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.

      + +
      +
      bzip2
      +

      a free software/open source data compression algorithm and program developed by Julian Seward.

      + +
      +
      CGI
      +

      Common Gateway Interface is an important World Wide Web technology that +enables a client web browser to request data from a program executed on +the Web server.

      + +
      +
      Changelog
      +

      a log or record of changes made to a project.

      + +
      +
      Client
      +

      a computer system that accesses a (remote) service on another computer by some kind of network.

      + +
      +
      column
      +

      a set of data values of a particular simple type, one for each row of the table.

      + +
      + +

      a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.

      + +
      +
      CSV
      +

      Comma- separated values

      + +
      +
      DB
      +
      look at database
      +
      database
      +

      an organized collection of data.

      + +
      +
      Engine
      +
      look at storage engines
      +
      extension
      +

      a PHP module that extends PHP with additional functionality.

      + +
      +
      FAQ
      +

      Frequently Asked Questions is a list of commonly asked question and there +answers.

      + +
      +
      Field
      +

      one part of divided data/columns.

      + +
      +
      foreign key
      +

      a column or group of columns in a database row that point to a key column +or group of columns forming a key of another database row in some +(usually different) table.

      + +
      +
      FPDF
      +

      the free PDF library

      +
      +

      See also

      +

      <http://www.fpdf.org/>

      +
      +
      +
      GD
      +

      Graphics Library by Thomas Boutell and others for dynamically manipulating images.

      + +
      +
      GD2
      +
      look at gd
      +
      gzip
      +

      gzip is short for GNU zip, a GNU free software file compression program.

      + +
      +
      host
      +

      any machine connected to a computer network, a node that has a hostname.

      + +
      +
      hostname
      +

      the unique name by which a network attached device is known on a network.

      + +
      +
      HTTP
      +

      HyperText Transfer Protocol is the primary method used to transfer or +convey information on the World Wide Web.

      + +
      +
      https
      +

      a HTTP-connection with additional security measures.

      + +
      +
      IEC
      +
      International Electrotechnical Commission
      +
      IIS
      +

      Internet Information Services is a set of Internet-based services for +servers using Microsoft Windows.

      + +
      +
      Index
      +

      a feature that allows quick access to the rows in a table.

      + +
      +
      IP
      +

      Internet Protocol is a data-oriented protocol used by source and +destination hosts for communicating data across a packet-switched +internetwork.

      + +
      +
      IP Address
      +

      a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.

      + +
      +
      IPv6
      +

      IPv6 (Internet Protocol version 6) is the latest revision of the +Internet Protocol (IP), designed to deal with the +long-anticipated problem of its precedessor IPv4 running out of addresses.

      + +
      +
      ISAPI
      +

      Internet Server Application Programming Interface is the API of Internet Information Services (IIS).

      + +
      +
      ISP
      +

      Internet service provider is a business or organization that offers users +access to the Internet and related services.

      + +
      +
      ISO
      +
      International Standards Organisation
      +
      JPEG
      +

      a most commonly used standard method of lossy compression for photographic images.

      + +
      +
      JPG
      +
      look at jpeg
      +
      Key
      +
      look at index
      +
      LATEX
      +

      a document preparation system for the TEX typesetting program.

      + +
      +
      Mac
      +

      Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.

      +

      . seealso:: <http://www.wikipedia.org/wiki/Mac>

      +
      +
      Mac OS X
      +

      the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.

      + +
      +
      MCrypt
      +

      a cryptographic library.

      + +
      +
      mcrypt
      +

      the MCrypt PHP extension.

      +
      +

      See also

      +

      <http://php.net/mcrypt>

      +
      +
      +
      MIME
      +

      Multipurpose Internet Mail Extensions is +an Internet Standard for the format of e-mail.

      + +
      +
      module
      +

      some sort of extension for the Apache Webserver.

      + +
      +
      MySQL
      +

      a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).

      + +
      +
      mysqli
      +

      the improved MySQL client PHP extension.

      +
      +

      See also

      +

      <http://php.net/mysqli>

      +
      +
      +
      mysql
      +

      the MySQL client PHP extension.

      +
      +

      See also

      +

      <http://php.net/mysql>

      +
      +
      +
      OpenDocument
      +

      open standard for office documents.

      + +
      +
      OS X
      +

      look at Mac OS X.

      + +
      +
      PDF
      +

      Portable Document Format is a file format developed by Adobe Systems for +representing two dimensional documents in a device independent and +resolution independent format.

      + +
      +
      PEAR
      +

      the PHP Extension and Application Repository.

      +
      +

      See also

      +

      <http://pear.php.net/>

      +
      +
      +
      PCRE
      +

      Perl Compatible Regular Expressions is the perl-compatible regular +expression functions for PHP

      +
      +

      See also

      +

      <http://php.net/pcre>

      +
      +
      +
      PHP
      +

      short for “PHP: Hypertext Preprocessor”, is an open-source, reflective +programming language used mainly for developing server-side applications +and dynamic web content, and more recently, a broader range of software +applications.

      + +
      +
      port
      +

      a connection through which data is sent and received.

      + +
      +
      RFC
      +

      Request for Comments (RFC) documents are a series of memoranda +encompassing new research, innovations, and methodologies applicable to +Internet technologies.

      + +
      +
      RFC 1952
      +

      GZIP file format specification version 4.3

      +
      +

      See also

      +

      RFC 1952

      +
      +
      +
      Row (record, tuple)
      +

      represents a single, implicitly structured data item in a table.

      + +
      +
      Server
      +

      a computer system that provides services to other computing systems over a network.

      + +
      +
      Storage Engines
      +

      handlers for different table types

      + +
      +
      SOAP
      +

      Simple Object Access Protocol is a protocol specification for exchanging +structured information in the implementation of Web Services in computer +networks.

      + +
      +
      socket
      +

      a form of inter-process communication.

      + +
      +
      SSL
      +

      Secure Sockets Layer is a cryptographic protocol which provides secure +communication on the Internet.

      + +
      +
      Stored procedure
      +

      a subroutine available to applications accessing a relational database system

      + +
      +
      SQL
      +

      Structured Query Language

      + +
      +
      table
      +

      a set of data elements (cells) that is organized, defined and stored as +horizontal rows and vertical columns where each item can be uniquely +identified by a label or key or by it?s position in relation to other +items.

      + +
      +
      tar
      +

      a type of archive file format: the Tape ARchive format.

      + +
      +
      TCP
      +

      Transmission Control Protocol is one of the core protocols of the +Internet protocol suite.

      + +
      +
      TCPDF
      +

      Rewrite of UFPDF with various improvements.

      +
      +

      See also

      +

      <http://www.tcpdf.org/>

      +
      +
      +
      trigger
      +

      a procedural code that is automatically executed in response to certain events on a particular table or view in a database

      + +
      +
      UFPDF
      +

      Unicode/UTF-8 extension for FPDF

      + +
      +
      URL
      +

      Uniform Resource Locator is a sequence of characters, conforming to a +standardized format, that is used for referring to resources, such as +documents and images on the Internet, by their location.

      + +
      +
      Webserver
      +

      A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.

      + +
      +
      XML
      +

      Extensible Markup Language is a W3C-recommended general- purpose markup +language for creating special-purpose markup languages, capable of +describing many different kinds of data.

      + +
      +
      ZIP
      +

      a popular data compression and archival format.

      + +
      +
      zlib
      +

      an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.

      + +
      +
      +
      + + +
      +
      +
      +
      +
      +

      Previous topic

      +

      Credits

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/index.html b/phpmyadmin/doc/html/index.html new file mode 100644 index 000000000..bb0068868 --- /dev/null +++ b/phpmyadmin/doc/html/index.html @@ -0,0 +1,206 @@ + + + + + + + + + + Welcome to phpMyAdmin’s documentation! — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + +
      + +
      +
      +

      Table Of Contents

      + + +

      Next topic

      +

      Introduction

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/intro.html b/phpmyadmin/doc/html/intro.html new file mode 100644 index 000000000..5d3bfbefe --- /dev/null +++ b/phpmyadmin/doc/html/intro.html @@ -0,0 +1,182 @@ + + + + + + + + + + Introduction — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Introduction

      +

      phpMyAdmin can manage a whole MySQL server (needs a super-user) as +well as a single database. To accomplish the latter you’ll need a +properly set up MySQL user who can read/write only the desired +database. It’s up to you to look up the appropriate part in the MySQL +manual.

      +
      +

      Supported features

      +

      Currently phpMyAdmin can:

      +
        +
      • browse and drop databases, tables, views, columns and indexes
      • +
      • display multiple results sets through stored procedures or queries
      • +
      • create, copy, drop, rename and alter databases, tables, columns and +indexes
      • +
      • maintenance server, databases and tables, with proposals on server +configuration
      • +
      • execute, edit and bookmark any SQL-statement, even batch-queries
      • +
      • load text files into tables
      • +
      • create [1] and read dumps of tables
      • +
      • export [1] data to various formats: CSV, XML, PDF, +ISO/IEC 26300 - OpenDocument Text and Spreadsheet, Microsoft +Word 2000, and LATEX formats
      • +
      • import data and MySQL structures from OpenDocument spreadsheets, as +well as XML, CSV, and SQL files
      • +
      • administer multiple servers
      • +
      • manage MySQL users and privileges
      • +
      • check referential integrity in MyISAM tables
      • +
      • using Query-by-example (QBE), create complex queries automatically +connecting required tables
      • +
      • create PDF graphics of your +database layout
      • +
      • search globally in a database or a subset of it
      • +
      • transform stored data into any format using a set of predefined +functions, like displaying BLOB-data as image or download-link
      • +
      • track changes on databases, tables and views
      • +
      • support InnoDB tables and foreign keys see 3.6 What is currently not supported in phpMyAdmin about InnoDB?
      • +
      • support mysqli, the improved MySQL extension see 1.17 Which MySQL versions does phpMyAdmin support?
      • +
      • create, edit, call, export and drop stored procedures and functions
      • +
      • create, edit, export and drop events and triggers
      • +
      • communicate in 62 different languages
      • +
      +
      +
      +

      A word about users

      +

      Many people have difficulty understanding the concept of user +management with regards to phpMyAdmin. When a user logs in to +phpMyAdmin, that username and password are passed directly to MySQL. +phpMyAdmin does no account management on its own (other than allowing +one to manipulate the MySQL user account information); all users must +be valid MySQL users.

      +

      Footnotes

      + + + + + +
      [1](1, 2) phpMyAdmin can compress (Zip, GZip RFC 1952 or +Bzip2 formats) dumps and CSV exports if you use PHP with +Zlib support (--with-zlib) and/or Bzip2 support +(--with-bz2). Proper support may also need changes in php.ini.
      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Welcome to phpMyAdmin’s documentation!

      +

      Next topic

      +

      Requirements

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/objects.inv b/phpmyadmin/doc/html/objects.inv new file mode 100644 index 000000000..51678917a Binary files /dev/null and b/phpmyadmin/doc/html/objects.inv differ diff --git a/phpmyadmin/doc/html/other.html b/phpmyadmin/doc/html/other.html new file mode 100644 index 000000000..9185e4b9f --- /dev/null +++ b/phpmyadmin/doc/html/other.html @@ -0,0 +1,135 @@ + + + + + + + + + + Other sources of information — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Other sources of information

      +
      +

      Printed Book

      +

      The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for +Effective MySQL Management by Marc Delisle. You can get information on that +book and other officially endorsed books at the phpMyAdmin site.

      +
      +
      +

      Tutorials

      +

      Third party tutorials and articles are listed on our wiki page.

      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      User management

      +

      Next topic

      +

      FAQ - Frequently Asked Questions

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/privileges.html b/phpmyadmin/doc/html/privileges.html new file mode 100644 index 000000000..be2036750 --- /dev/null +++ b/phpmyadmin/doc/html/privileges.html @@ -0,0 +1,169 @@ + + + + + + + + + + User management — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      User management

      +

      User management is the process of controlling which users are allowed to +connect to the MySQL server and what permissions they have on each database. +phpMyAdmin does not handle user management, rather it passes the username and +password on to MySQL, which then determines whether a user is permitted to +perform a particular action. Within phpMyAdmin, administrators have full +control over creating users, viewing and editing privileges for existing users, +and removing users.

      +

      Within phpMyAdmin, user management is controlled via the Users link +from the main page. Users can be created, edited, and removed.

      +
      +

      Creating a new user

      +

      To create a new user, click the Add a new user link near the bottom +of the Users page (you must be a “superuser”, e.g., user “root”). +Use the textboxes and drop-downs to configure the user to your particular +needs. You can then select whether to create a database for that user and grant +specific global privileges. Once you’ve created the user (by clicking Go), you +can define that user’s permissions on a specific database (don’t grant global +privileges in that case). In general, users do not need any global privileges +(other than USAGE), only permissions for their specific database.

      +
      +
      +

      Editing an existing user

      +

      To edit an existing user, simply click the pencil icon to the right of that +user in the Users page. You can then edit their global- and +database-specific privileges, change their password, or even copy those +privileges to a new user.

      +
      +
      +

      Deleting a user

      +

      From the Users page, check the checkbox for the user you wish to +remove, select whether or not to also remove any databases of the same name (if +they exist), and click Go.

      +
      +
      +

      Assigning privileges to user for a specific database

      +

      Users are assigned to databases by editing the user record (from the +Users link on the home page) not from within the Users +link under the table. If you are creating a user specifically for a given table +you will have to create the user first (with no global privileges) and then go +back and edit that user to add the table and privileges for the individual +table.

      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Transformations

      +

      Next topic

      +

      Other sources of information

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/require.html b/phpmyadmin/doc/html/require.html new file mode 100644 index 000000000..b47afe5f0 --- /dev/null +++ b/phpmyadmin/doc/html/require.html @@ -0,0 +1,170 @@ + + + + + + + + + + Requirements — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Requirements

      +
      +

      Web server

      +

      Since, phpMyAdmin’s interface is based entirely in your browser, you’ll need a +web server (such as Apache, IIS) to install phpMyAdmin’s files into.

      +
      +
      +

      PHP

      +
        +
      • You need PHP 5.2.0 or newer, with session support, the Standard PHP Library +(SPL) extension and JSON support.
      • +
      • To support uploading of ZIP files, you need the PHP zip extension.
      • +
      • For proper support of multibyte strings (eg. UTF-8, which is currently +the default), you should install the mbstring and ctype extensions.
      • +
      • You need GD2 support in PHP to display inline thumbnails of JPEGs +(“image/jpeg: inline”) with their original aspect ratio.
      • +
      • When using the cookie authentication (the default), the mcrypt extension is strongly suggested for most +users and is required for 64–bit machines. Not using mcrypt will +cause phpMyAdmin to load pages significantly slower.
      • +
      • To support upload progress bars, see 2.9 Seeing an upload progress bar.
      • +
      • To support XML and Open Document Spreadsheet importing, you need PHP +5.2.17 or newer and the libxml +extension.
      • +
      + +
      +
      +

      Database

      +

      phpMyAdmin support MySQL compatible databases.

      +
        +
      • MySQL 5.0 or newer
      • +
      • MariaDB 5.0 or newer
      • +
      • Drizzle
      • +
      + +
      +
      +

      Web browser

      +

      To access phpMyAdmin you need a web browser with cookies and javascript +enabled.

      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Introduction

      +

      Next topic

      +

      Installation

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/search.html b/phpmyadmin/doc/html/search.html new file mode 100644 index 000000000..83caa39b3 --- /dev/null +++ b/phpmyadmin/doc/html/search.html @@ -0,0 +1,100 @@ + + + + + + + + + + Search — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +

      Search

      +
      + +

      + Please activate JavaScript to enable the search + functionality. +

      +
      +

      + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

      +
      + + + +
      + +
      + +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/searchindex.js b/phpmyadmin/doc/html/searchindex.js new file mode 100644 index 000000000..c4dfde218 --- /dev/null +++ b/phpmyadmin/doc/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({objects:{"":{"$cfg['ExecTimeLimit']":[13,0,1,"cfg_ExecTimeLimit"],"$cfg['Servers'][$i]['SignonURL']":[13,0,1,"cfg_Servers_SignonURL"],"$cfg['UploadDir']":[13,0,1,"cfg_UploadDir"],"$cfg['Servers'][$i]['socket']":[13,0,1,"cfg_Servers_socket"],"$cfg['SkipLockedTables']":[13,0,1,"cfg_SkipLockedTables"],"$cfg['Servers'][$i]['AllowRoot']":[13,0,1,"cfg_Servers_AllowRoot"],"$cfg['Servers'][$i]['AllowDeny']['order']":[13,0,1,"cfg_Servers_AllowDeny_order"],"$cfg['GZipDump']":[13,0,1,"cfg_GZipDump"],"$cfg['SQLValidator']":[13,0,1,"cfg_SQLValidator"],"$cfg['ShowBrowseComments']":[13,0,1,"cfg_ShowBrowseComments"],"$cfg['CompressOnFly']":[13,0,1,"cfg_CompressOnFly"],"$cfg['NavigationTreePointerEnable']":[13,0,1,"cfg_NavigationTreePointerEnable"],"$cfg['Servers'][$i]['recent']":[13,0,1,"cfg_Servers_recent"],"$cfg['OBGzip']":[13,0,1,"cfg_OBGzip"],"$cfg['MaxRows']":[13,0,1,"cfg_MaxRows"],"$cfg['SaveCellsAtOnce']":[13,0,1,"cfg_SaveCellsAtOnce"],"$cfg['NavigationTreeDisplayItemFilterMinimum']":[13,0,1,"cfg_NavigationTreeDisplayItemFilterMinimum"],"$cfg['Servers'][$i]['compress']":[13,0,1,"cfg_Servers_compress"],"$cfg['ProtectBinary']":[13,0,1,"cfg_ProtectBinary"],"$cfg['DisplayServersList']":[13,0,1,"cfg_DisplayServersList"],"$cfg['ShowPropertyComments']":[13,0,1,"cfg_ShowPropertyComments"],"$cfg['MaxDbList']":[13,0,1,"cfg_MaxDbList"],"$cfg['Servers'][$i]['SignonSession']":[13,0,1,"cfg_Servers_SignonSession"],"$cfg['SQLValidator']['username']":[13,0,1,"cfg_SQLValidator_username"],"$cfg['Servers'][$i]['password']":[13,0,1,"cfg_Servers_password"],"$cfg['Export']['method']":[13,0,1,"cfg_Export_method"],"$cfg['FontFamilyFixed']":[13,0,1,"cfg_FontFamilyFixed"],"$cfg['NavigationLogoLink']":[13,0,1,"cfg_NavigationLogoLink"],"$cfg['Servers'][$i]['port']":[13,0,1,"cfg_Servers_port"],"$cfg['Confirm']":[13,0,1,"cfg_Confirm"],"$cfg['Servers'][$i]['tracking_version_auto_create']":[13,0,1,"cfg_Servers_tracking_version_auto_create"],"$cfg['MemoryLimit']":[13,0,1,"cfg_MemoryLimit"],"$cfg['ReservedWordDisableWarning']":[13,0,1,"cfg_ReservedWordDisableWarning"],"$cfg['DefaultLang']":[13,0,1,"cfg_DefaultLang"],"$cfg['LinkLengthLimit']":[13,0,1,"cfg_LinkLengthLimit"],"$cfg['DBG']['sql']":[13,0,1,"cfg_DBG_sql"],"$cfg['NavigationTreeEnableGrouping']":[13,0,1,"cfg_NavigationTreeEnableGrouping"],"$cfg['Servers'][$i]['table_uiprefs']":[13,0,1,"cfg_Servers_table_uiprefs"],"$cfg['DefaultQueryTable']":[13,0,1,"cfg_DefaultQueryTable"],"$cfg['QueryWindowWidth']":[13,0,1,"cfg_QueryWindowWidth"],"$cfg['DefaultDisplay']":[13,0,1,"cfg_DefaultDisplay"],"$cfg['NaviPointerBackground']":[13,0,1,"cfg_NaviPointerBackground"],"$cfg['Servers'][$i]['user']":[13,0,1,"cfg_Servers_user"],"$cfg['ShowPhpInfo']":[13,0,1,"cfg_ShowPhpInfo"],"$cfg['Servers'][$i]['AllowNoPassword']":[13,0,1,"cfg_Servers_AllowNoPassword"],"$cfg['SQLQuery']['Refresh']":[13,0,1,"cfg_SQLQuery_Refresh"],"$cfg['Lang']":[13,0,1,"cfg_Lang"],"$cfg['EditInWindow']":[13,0,1,"cfg_EditInWindow"],"$cfg['SQLQuery']['Explain']":[13,0,1,"cfg_SQLQuery_Explain"],"$cfg['ShowAll']":[13,0,1,"cfg_ShowAll"],"$cfg['DefaultQueryDatabase']":[13,0,1,"cfg_DefaultQueryDatabase"],"$cfg['TextareaCols']":[13,0,1,"cfg_TextareaCols"],"$cfg['Border']":[13,0,1,"cfg_Border"],"$cfg['UserprefsDisallow']":[13,0,1,"cfg_UserprefsDisallow"],"$cfg['Servers'][$i]['pdf_pages']":[13,0,1,"cfg_Servers_pdf_pages"],"$cfg['HideStructureActions']":[13,0,1,"cfg_HideStructureActions"],"$cfg['RetainQueryBox']":[13,0,1,"cfg_RetainQueryBox"],"$cfg['SQP']['fmtInd']":[13,0,1,"cfg_SQP_fmtInd"],"$cfg['Order']":[13,0,1,"cfg_Order"],"$cfg['GD2Available']":[13,0,1,"cfg_GD2Available"],"$cfg['PmaAbsoluteUri']":[13,0,1,"cfg_PmaAbsoluteUri"],"$cfg['PropertiesIconic']":[13,0,1,"cfg_PropertiesIconic"],"$cfg['NavigationBarIconic']":[13,0,1,"cfg_NavigationBarIconic"],"$cfg['ShowFieldTypesInDataEditView']":[13,0,1,"cfg_ShowFieldTypesInDataEditView"],"$cfg['Servers'][$i]['controluser']":[13,0,1,"cfg_Servers_controluser"],"$cfg['NavigationTreeTableLevel']":[13,0,1,"cfg_NavigationTreeTableLevel"],"$cfg['Servers'][$i]['relation']":[13,0,1,"cfg_Servers_relation"],"$cfg['RepeatCells']":[13,0,1,"cfg_RepeatCells"],"$cfg['Servers'][$i]['MaxTableUiprefs']":[13,0,1,"cfg_Servers_MaxTableUiprefs"],"$cfg['RememberSorting']":[13,0,1,"cfg_RememberSorting"],"$cfg['UserprefsDeveloperTab']":[13,0,1,"cfg_UserprefsDeveloperTab"],"$cfg['ShowDbStructureLastUpdate']":[13,0,1,"cfg_ShowDbStructureLastUpdate"],"$cfg['Servers'][$i]['connect_type']":[13,0,1,"cfg_Servers_connect_type"],"$cfg['MaxNavigationItems']":[13,0,1,"cfg_MaxNavigationItems"],"$cfg['ThemeManager']":[13,0,1,"cfg_ThemeManager"],"$cfg['TextareaAutoSelect']":[13,0,1,"cfg_TextareaAutoSelect"],"$cfg['Servers'][$i]['auth_swekey_config']":[13,0,1,"cfg_Servers_auth_swekey_config"],"$cfg['BZipDump']":[13,0,1,"cfg_BZipDump"],"$cfg['LimitChars']":[13,0,1,"cfg_LimitChars"],"$cfg['ShowTooltip']":[13,0,1,"cfg_ShowTooltip"],"$cfg['ShowStats']":[13,0,1,"cfg_ShowStats"],"$cfg['ThemeDefault']":[13,0,1,"cfg_ThemeDefault"],"$cfg['NaturalOrder']":[13,0,1,"cfg_NaturalOrder"],"$cfg['TitleServer']":[13,0,1,"cfg_TitleServer"],"$cfg['ThColor']":[13,0,1,"cfg_ThColor"],"$cfg['BrowsePointerColor']":[13,0,1,"cfg_BrowsePointerColor"],"$cfg['DefaultConnectionCollation']":[13,0,1,"cfg_DefaultConnectionCollation"],"$cfg['Servers'][$i]['verbose']":[13,0,1,"cfg_Servers_verbose"],"$cfg['ZipDump']":[13,0,1,"cfg_ZipDump"],"$cfg['Servers'][$i]['bookmarktable']":[13,0,1,"cfg_Servers_bookmarktable"],"$cfg['NavigationDisplayLogo']":[13,0,1,"cfg_NavigationDisplayLogo"],"$cfg['Servers'][$i]['nopassword']":[13,0,1,"cfg_Servers_nopassword"],"$cfg['NavigationTreeDefaultTabTable']":[13,0,1,"cfg_NavigationTreeDefaultTabTable"],"$cfg['NavigationLogoLinkWindow']":[13,0,1,"cfg_NavigationLogoLinkWindow"],"$cfg['FilterLanguages']":[13,0,1,"cfg_FilterLanguages"],"$cfg['ShowSQL']":[13,0,1,"cfg_ShowSQL"],"$cfg['InitialSlidersState']":[13,0,1,"cfg_InitialSlidersState"],"$cfg['Servers'][$i]['userconfig']":[13,0,1,"cfg_Servers_userconfig"],"$cfg['blowfish_secret']":[13,0,1,"cfg_blowfish_secret"],"$cfg['DefaultTabTable']":[13,0,1,"cfg_DefaultTabTable"],"$cfg['ShowServerInfo']":[13,0,1,"cfg_ShowServerInfo"],"$cfg['SQP']['fmtIndUnit']":[13,0,1,"cfg_SQP_fmtIndUnit"],"$cfg['Servers'][$i]['ssl']":[13,0,1,"cfg_Servers_ssl"],"$cfg['Servers'][$i]['hide_db']":[13,0,1,"cfg_Servers_hide_db"],"$cfg['MaxCharactersInDisplayedSQL']":[13,0,1,"cfg_MaxCharactersInDisplayedSQL"],"$cfg['LoginCookieValidity']":[13,0,1,"cfg_LoginCookieValidity"],"$cfg['ShowDbStructureLastCheck']":[13,0,1,"cfg_ShowDbStructureLastCheck"],"$cfg['DefaultTabServer']":[13,0,1,"cfg_DefaultTabServer"],"$cfg['MySQLManualBase']":[13,0,1,"cfg_MySQLManualBase"],"$cfg['NumRecentTables']":[13,0,1,"cfg_NumRecentTables"],"$cfg['Servers'][$i]['extension']":[13,0,1,"cfg_Servers_extension"],"$cfg['CharTextareaRows']":[13,0,1,"cfg_CharTextareaRows"],"$cfg['BgOne']":[13,0,1,"cfg_BgOne"],"$cfg['Servers'][$i]['SignonScript']":[13,0,1,"cfg_Servers_SignonScript"],"$cfg['HeaderFlipType']":[13,0,1,"cfg_HeaderFlipType"],"$cfg['SuhosinDisableWarning']":[13,0,1,"cfg_SuhosinDisableWarning"],"$cfg['ShowDbStructureCreation']":[13,0,1,"cfg_ShowDbStructureCreation"],"$cfg['QueryHistoryMax']":[13,0,1,"cfg_QueryHistoryMax"],"$cfg['BrowsePointerEnable']":[13,0,1,"cfg_BrowsePointerEnable"],"$cfg['LoginCookieStore']":[13,0,1,"cfg_LoginCookieStore"],"$cfg['ShowChgPassword']":[13,0,1,"cfg_ShowChgPassword"],"$cfg['BgTwo']":[13,0,1,"cfg_BgTwo"],"$cfg['TitleDatabase']":[13,0,1,"cfg_TitleDatabase"],"$cfg['Servers'][$i]['auth_type']":[13,0,1,"cfg_Servers_auth_type"],"$cfg['RowActionLinks']":[13,0,1,"cfg_RowActionLinks"],"$cfg['Error_Handler']['gather']":[13,0,1,"cfg_Error_Handler_gather"],"$cfg['Servers'][$i]['StatusCacheDatabases']":[13,0,1,"cfg_Servers_StatusCacheDatabases"],"$cfg['BrowseMarkerBackground']":[13,0,1,"cfg_BrowseMarkerBackground"],"$cfg['Servers'][$i]['column_info']":[13,0,1,"cfg_Servers_column_info"],"$cfg['TitleDefault']":[13,0,1,"cfg_TitleDefault"],"$cfg['DefaultFunctions']":[13,0,1,"cfg_DefaultFunctions"],"$cfg['GridEditing']":[13,0,1,"cfg_GridEditing"],"$cfg['QueryHistoryDB']":[13,0,1,"cfg_QueryHistoryDB"],"$cfg['SQLQuery']['ShowAsPHP']":[13,0,1,"cfg_SQLQuery_ShowAsPHP"],"$cfg['SaveDir']":[13,0,1,"cfg_SaveDir"],"$cfg['TempDir']":[13,0,1,"cfg_TempDir"],"$cfg['NavigationTreeDisplayDbFilterMinimum']":[13,0,1,"cfg_NavigationTreeDisplayDbFilterMinimum"],"$cfg['NavigationTreeTableSeparator']":[13,0,1,"cfg_NavigationTreeTableSeparator"],"$cfg['TranslationWarningThreshold']":[13,0,1,"cfg_TranslationWarningThreshold"],"$cfg['Servers'][$i]['tracking_add_drop_database']":[13,0,1,"cfg_Servers_tracking_add_drop_database"],"$cfg['Servers'][$i]['controlpass']":[13,0,1,"cfg_Servers_controlpass"],"$cfg['Servers'][$i]['tracking']":[13,0,1,"cfg_Servers_tracking"],"$cfg['ShowHint']":[13,0,1,"cfg_ShowHint"],"$cfg['MainBackground']":[13,0,1,"cfg_MainBackground"],"$cfg['MySQLManualType']":[13,0,1,"cfg_MySQLManualType"],"$cfg['Export']":[13,0,1,"cfg_Export"],"$cfg['Servers'][$i]['auth_http_realm']":[13,0,1,"cfg_Servers_auth_http_realm"],"$cfg['DisplayBinaryAsHex']":[13,0,1,"cfg_DisplayBinaryAsHex"],"$cfg['UseDbSearch']":[13,0,1,"cfg_UseDbSearch"],"$cfg['IconvExtraParams']":[13,0,1,"cfg_IconvExtraParams"],"$cfg['DisableMultiTableMaintenance']":[13,0,1,"cfg_DisableMultiTableMaintenance"],"$cfg['LoginCookieRecall']":[13,0,1,"cfg_LoginCookieRecall"],"$cfg['ThemePath']":[13,0,1,"cfg_ThemePath"],"$cfg['BrowseMarkerEnable']":[13,0,1,"cfg_BrowseMarkerEnable"],"$cfg['Servers'][$i]['tracking_add_drop_table']":[13,0,1,"cfg_Servers_tracking_add_drop_table"],"$cfg['DefaultTabDatabase']":[13,0,1,"cfg_DefaultTabDatabase"],"$cfg['LongtextDoubleTextarea']":[13,0,1,"cfg_LongtextDoubleTextarea"],"$cfg['NaviWidth']":[13,0,1,"cfg_NaviWidth"],"$cfg['MaxTableList']":[13,0,1,"cfg_MaxTableList"],"$cfg['McryptDisableWarning']":[13,0,1,"cfg_McryptDisableWarning"],"$cfg['TitleTable']":[13,0,1,"cfg_TitleTable"],"$cfg['AllowArbitraryServer']":[13,0,1,"cfg_AllowArbitraryServer"],"$cfg['RecodingEngine']":[13,0,1,"cfg_RecodingEngine"],"$cfg['Servers']":[13,0,1,"cfg_Servers"],"$cfg['NaviBackground']":[13,0,1,"cfg_NaviBackground"],"$cfg['VersionCheck']":[13,0,1,"cfg_VersionCheck"],"$cfg['BrowsePointerBackground']":[13,0,1,"cfg_BrowsePointerBackground"],"$cfg['BrowseMIME']":[13,0,1,"cfg_BrowseMIME"],"$cfg['Servers'][$i]['designer_coords']":[13,0,1,"cfg_Servers_designer_coords"],"$cfg['Servers'][$i]['controlhost']":[13,0,1,"cfg_Servers_controlhost"],"$cfg['CodemirrorEnable']":[13,0,1,"cfg_CodemirrorEnable"],"$cfg['ForeignKeyMaxLimit']":[13,0,1,"cfg_ForeignKeyMaxLimit"],"$cfg['ForeignKeyDropdownOrder']":[13,0,1,"cfg_ForeignKeyDropdownOrder"],"$cfg['Servers'][$i]['host']":[13,0,1,"cfg_Servers_host"],"$cfg['QueryWindowDefTab']":[13,0,1,"cfg_QueryWindowDefTab"],"$cfg['Servers'][$i]['StatusCacheLifetime']":[13,0,1,"cfg_Servers_StatusCacheLifetime"],"$cfg['TextareaRows']":[13,0,1,"cfg_TextareaRows"],"$cfg['Servers'][$i]['tracking_default_statements']":[13,0,1,"cfg_Servers_tracking_default_statements"],"$cfg['ServerDefault']":[13,0,1,"cfg_ServerDefault"],"$cfg['ShowDisplayDirection']":[13,0,1,"cfg_ShowDisplayDirection"],"$cfg['IgnoreMultiSubmitErrors']":[13,0,1,"cfg_IgnoreMultiSubmitErrors"],"$cfg['SessionSavePath']":[13,0,1,"cfg_SessionSavePath"],"$cfg['ShowCreateDb']":[13,0,1,"cfg_ShowCreateDb"],"$cfg['SQP']['fmtColor']":[13,0,1,"cfg_SQP_fmtColor"],"$cfg['InsertRows']":[13,0,1,"cfg_InsertRows"],"$cfg['LoginCookieDeleteAll']":[13,0,1,"cfg_LoginCookieDeleteAll"],"$cfg['PersistentConnections']":[13,0,1,"cfg_PersistentConnections"],"$cfg['ServerLibraryDifference_DisableWarning']":[13,0,1,"cfg_ServerLibraryDifference_DisableWarning"],"$cfg['Servers'][$i]['only_db']":[13,0,1,"cfg_Servers_only_db"],"$cfg['QueryWindowHeight']":[13,0,1,"cfg_QueryWindowHeight"],"$cfg['SQLValidator']['use']":[13,0,1,"cfg_SQLValidator_use"],"$cfg['CharTextareaCols']":[13,0,1,"cfg_CharTextareaCols"],"$cfg['ForceSSL']":[13,0,1,"cfg_ForceSSL"],"$cfg['SQLQuery']['Edit']":[13,0,1,"cfg_SQLQuery_Edit"],"$cfg['CheckConfigurationPermissions']":[13,0,1,"cfg_CheckConfigurationPermissions"],"$cfg['NavigationTreeDbSeparator']":[13,0,1,"cfg_NavigationTreeDbSeparator"],"$cfg['Servers'][$i]['LogoutURL']":[13,0,1,"cfg_Servers_LogoutURL"],"$cfg['SQP']['fmtType']":[13,0,1,"cfg_SQP_fmtType"],"$cfg['ThBackground']":[13,0,1,"cfg_ThBackground"],"$cfg['CSPAllow']":[13,0,1,"cfg_CSPAllow"],"$cfg['ShowFunctionFields']":[13,0,1,"cfg_ShowFunctionFields"],"$cfg['SQLValidator']['password']":[13,0,1,"cfg_SQLValidator_password"],"$cfg['SQLQuery']['Validate']":[13,0,1,"cfg_SQLQuery_Validate"],"$cfg['AllowUserDropDatabase']":[13,0,1,"cfg_AllowUserDropDatabase"],"$cfg['MaxExactCountViews']":[13,0,1,"cfg_MaxExactCountViews"],"$cfg['Servers'][$i]['table_coords']":[13,0,1,"cfg_Servers_table_coords"],"$cfg['Servers'][$i]['history']":[13,0,1,"cfg_Servers_history"],"$cfg['Import']":[13,0,1,"cfg_Import"],"$cfg['DBG']":[13,0,1,"cfg_DBG"],"$cfg['AvailableCharsets']":[13,0,1,"cfg_AvailableCharsets"],"$cfg['Servers'][$i]['ShowDatabasesCommand']":[13,0,1,"cfg_Servers_ShowDatabasesCommand"],"$cfg['MaxSizeForInputField']":[13,0,1,"cfg_MaxSizeForInputField"],"$cfg['Servers'][$i]['DisableIS']":[13,0,1,"cfg_Servers_DisableIS"],"$cfg['NaviPointerColor']":[13,0,1,"cfg_NaviPointerColor"],"$cfg['CharEditing']":[13,0,1,"cfg_CharEditing"],"$cfg['Servers'][$i]['table_info']":[13,0,1,"cfg_Servers_table_info"],"$cfg['MaxExactCount']":[13,0,1,"cfg_MaxExactCount"],"$cfg['PmaNoRelation_DisableWarning']":[13,0,1,"cfg_PmaNoRelation_DisableWarning"],"$cfg['Servers'][$i]['tracking_add_drop_view']":[13,0,1,"cfg_Servers_tracking_add_drop_view"],"$cfg['BrowseMarkerColor']":[13,0,1,"cfg_BrowseMarkerColor"],"$cfg['NavigationDisplayServers']":[13,0,1,"cfg_NavigationDisplayServers"],"$cfg['Error_Handler']['display']":[13,0,1,"cfg_Error_Handler_display"],"$cfg['PropertiesNumColumns']":[13,0,1,"cfg_PropertiesNumColumns"],"$cfg['ThemePerServer']":[13,0,1,"cfg_ThemePerServer"],"$cfg['MinSizeForInputField']":[13,0,1,"cfg_MinSizeForInputField"],"$cfg['FontFamily']":[13,0,1,"cfg_FontFamily"],"$cfg['Servers'][$i]['AllowDeny']['rules']":[13,0,1,"cfg_Servers_AllowDeny_rules"],"$cfg['Servers'][$i]['pmadb']":[13,0,1,"cfg_Servers_pmadb"],"$cfg['TrustedProxies']":[13,0,1,"cfg_TrustedProxies"]}},terms:{represent:8,varfilt:5,uploadprogress:5,prefix:13,forget:[5,13],whose:[4,5],miner:5,tobia:[8,2],usepackag:5,lori:8,under:[4,5,13,14,2],hermann:8,textareaautoselect:13,merchant:2,versioncheck:13,digit:13,everi:[4,5,13],risk:[5,13],dutch:8,max_value_length:5,alberty_at_neptunlab:8,affect:[5,13],opendocu:[3,10],viewabl:13,look:[1,3,4,5,10,13],upload:[0,4,5,13,6],cma:8,getmimesubtyp:1,multipurpos:3,zlib:[3,5,10],hord:8,direct:[4,5,13,1],nair:8,consequ:13,second:[5,13,1],chee:8,even:[2,4,5,10,13,14],dialogu:5,hide:[4,13],followsymlink:5,veeven:8,"new":[1,3,4,5,8,11,13,14],net:[2,3,4,5,8,13],ever:5,super_priv:4,told:8,abov:[5,13],readman:8,never:5,here:[4,5,13,1],beck:8,path:[4,5,13,9],interpret:5,michal:[8,2],forum:[8,5],robin:[8,2],datetim:13,transformation_opt:[13,1],permit:[14,13],mysqld:5,portabl:3,siramizu_at_gmail:8,phpseclib:8,heritrix:5,unix:[4,5],mike_at_graftonhal:8,mysqldump:5,tbl_select:[8,13],txt:[4,5],unit:[8,13],plot:5,dhima:8,upgrade_tables_mysql_4_1_2:4,describ:[3,13,1],would:[4,5,13,1],mysqladmin:5,kettler:8,call:[13,4,5,10,1],recommend:[3,4,5,13],memoranda:3,type:[3,8,5,13,1],until:[8,4,13],rink_at_initfour:8,relat:[3,8,4,5,13],email_at_c:8,yahoo:5,u4663530_at_anu:8,warn:[4,5,13],mysql_connect:5,exce:13,hold:[5,13],unpack:[4,5],addon:5,kuppelwies:8,join:[8,5,13],restor:5,setup:[0,1,4,5,8,9,13],work:[8,5,13,1],memorylimit:13,defaultconnectioncol:13,root:[4,5,13,14],overrid:4,give:[4,5,9],autodetect:13,delislma_at_collegesherbrook:8,indic:0,pandithawatta:8,unavail:13,want:[4,5,13,1,9],web_brows:3,unsign:1,horizonta:13,end:[4,5,13,1],chanaka:8,quot:[5,13],travel:4,zzzz:13,march:8,how:[4,5,13,1],func_numb:13,disappear:[5,13],pikto:5,answer:3,config:[4,5,13,9],updat:[8,4,5,13],process_priv:4,chines:8,after:[4,5,13],lump:5,manuali:4,befor:[4,5,13],wrong:[5,13],star_at_origin:8,router:4,allowuserdropdatabas:13,averag:5,autoconnect:13,attempt:[5,13],third:[5,13,7],grant:[4,5,14],credenti:[4,13],think:5,matiasbellone_at_gmail:8,witten:8,environ:[4,5,13],enter:[4,5,13,1],nikto:5,order:[0,3,4,5,8,13],oper:[3,5,13,1],feedback:8,softwar:[3,9,5,2],diagnos:5,over:[3,4,5,13,14],becaus:[8,4,5,13,1],jpeg:[3,6,1],navigationtreedisplayitemfilterminimum:13,privileg:[4,5,8,10,11,13,14],jordi:8,digest:5,textbox:14,directli:[13,5,10],fit:[8,5,13,2],fix:[8,5],better:5,offic:3,persist:13,auth_swekey_config:[4,13],hidden:13,mydb:[5,13],rachim:8,split:[5,13,1],them:[1,3,4,5,9,13],thei:[1,4,5,8,9,13,14],fragment:5,safe:[4,5,13],"break":5,kirillov:8,choic:[4,5,13],alex:8,changelog:3,telekom:5,alpha_columntyp:13,timeout:[5,13],rowactionlink:13,complet:[8,5,13],side:[3,4,13],mean:[4,5,13,1],cybot_tm_at_us:[8,2],navi:13,allowarbitraryserv:[4,13],neomo:5,arg_separ:5,phpmy:5,forgot:5,logo:[8,13],extract:5,network:[3,5],file_format:3,goe:5,zarubin:8,newli:4,content:[3,0,4,13,1],rewrit:[3,5],daniel:8,showfunctionfield:13,got:5,ware:8,userprefsdisallow:13,forth:1,"98se":5,http_request:5,navig:[0,5,13,8],situat:5,free:[3,4,5,1,2],standard:[3,8,6,5,13],small:[5,13],kaushalya:8,hand:[4,5],func_spati:13,silent:[5,13],workaround:5,server_address:13,loup:3,isp:[3,0,4,5,13],filter:[5,13],iso:[3,10],unabl:5,martijn:8,kingdom:8,onto:5,user:[0,1,3,4,5,6,8,10,11,13,14],rang:[3,5,13],signonsess:[4,13],independ:[3,8,5],xitami:5,restrict:[4,5,13],instruct:5,alreadi:[4,5],grantor:[4,13],hanut_at_php:8,unmark:13,primari:[3,8,5],fontfamilyfix:13,top:[4,5,13],sometim:5,amalesh:8,master:[7,13],too:[5,13,12],pma__designer_coord:13,danish:8,mysqlmanualtyp:13,tool:[8,5,13,12],"17a":5,sync:8,past:13,max_link:5,provid:[1,3,4,5,9,13],tree:[8,13],project:[3,0,5,8],serverlibrarydifference_disablewarn:13,swekei:[4,13],checkconfigurationpermiss:13,fashion:13,php_mysql:5,raj:8,mine:5,seed:13,manner:5,increment:13,seen:13,seem:[4,5,13],incompat:5,minu:5,userprefsdevelopertab:13,querywindowheight:13,realm:13,recreat:5,latter:[13,5,10],sakamoto:8,derek:8,thoma:[3,8],indrajith:8,hypertext_transfer_protocol:3,davidson:8,simplifi:8,thi:[1,2,4,5,8,9,13],plenti:5,though:13,usernam:[13,4,5,10,14],w3c_valid:5,marin:8,regular:[3,8,13],defaultlang:13,letter:[5,13],jean:3,lithuanian:8,titledefault:13,tradit:8,persistentconnect:13,don:[4,5,13,14],telugu:8,dom:8,doc:[3,5,13],lose:[5,13],doe:[1,4,5,10,13,6,14],omniexplorer_bot:5,bracket:13,wildcard:[5,13],neg:5,winningham:8,mrbendig_at_mrbendig:8,dot:[5,13],ldi_:8,feedfetch:5,synoobot:5,opposit:13,random:[8,13],syntax:[5,13],radio:5,protocol:[3,4,5,13],placella:8,absolut:13,layout:[13,5,10],firstnam:5,alvar:8,menu:[5,13],explain:[4,5,13],configur:[0,1,3,4,5,8,10,13,14],apach:[3,4,5,13,6],burak:8,theme:[0,5,13],busi:3,lubo:8,folder:[4,5],schneier:3,field_:3,tbl_structur:[13,1],likewis:5,stop:[5,13],sqlvalid:13,report:[8,5,13],symmetr:3,"k\u0119stuti":8,volkov:8,bar:[6,5,13],excel:5,signonurl:[4,13],method:[3,4,5,13,1],reload:5,bad:5,ban:5,taceloski:8,mysql:[0,3,4,5,8,9,10,7,13,6,14],forcessl:13,gridedit:13,result:[13,4,5,10],auto_incr:5,corrupt:13,themselv:13,best:[4,5],subject:[5,13],pete:8,awar:[4,5],tracking_default_stat:13,hopefulli:1,databas:[0,3,4,5,8,10,11,13,6,14],wikipedia:3,tracking_version_auto_cr:13,bgone:13,wiltave_at_gmail:8,atul:8,yahooseek:5,adnan:8,approach:13,attribut:13,accord:13,extend:[3,5,1],extens:[3,4,5,8,10,13,6],cut:13,preprocessor:3,wtf:5,subfold:4,protect:[4,5,13],accident:13,shapefil:[5,13],met:5,emerson4br_at_gmail:8,howev:[4,5,13,1],kronsbein:8,against:[4,5],brad:5,ivanlanin_at_us:8,countri:5,fauveau_at_globali:8,browser:[0,1,3,4,5,13,6],com:[1,2,3,5,8,13],"16m":13,clshttp:5,queryhistorydb:13,loader:5,pdf_page:[5,13],column_com:13,trust:13,assum:[4,5],gc_maxlifetim:13,duplic:5,question:[3,0,5],saedi:8,three:[5,13,1],been:[4,5,13,12],trigger:[3,8,10,13],interest:5,basic:[0,1,4,5,9,13],rather:[14,5,13],suppress:13,xxx:[5,13,1],telnet:5,argument:5,multithread:3,dave:8,"kl\u00e4ger":8,http_post_var:5,dash:[5,13],gnu:[3,2],servic:[3,5,13],properti:[8,5,13,1],sourceforg:[8,5,2],rouslan:8,pmanorelation_disablewarn:13,need:[4,5,9,10,13,6,14],libxml:6,myadmin:8,conf:[4,5],vendor:13,sever:[9,5,13,1],piotr:8,navigationtreedefaulttabt:13,perform:[14,5,13],suggest:[8,4,5,6],make:[4,5,13,1,12],ammar:8,complex:[5,10],descend:13,roszatycki:8,schema_privileg:13,http_x_forwarded_for:13,"_uri_schem":3,evil:[4,5],kit:[4,5],norwegian:8,nix:13,ownership:5,tune:4,kept:[13,1],scenario:5,execute_priv:4,punct_queryend:13,printview:[8,13],bugzilla:5,client:[3,0,4,5,13],maxtablelist:13,gzip:[3,8,5,10,13],everyth:5,maxexactcount:[5,13],left:[8,5,13],seekbot:5,table_priv:4,bellow:13,identifi:[3,4,5,13],just:[8,4,5,13],alpha_columnattrib:13,bellon:8,textareacol:13,languag:[0,3,4,5,8,10,13],jose:5,easi:[5,13,1],interfer:5,had:[4,5],logformat:5,els:[8,4,5,13],save:[0,4,5,13],jan_at_nrw:8,applic:[3,4,5,13],mayb:5,credit:[0,2,8],editinwindow:13,file_priv:4,arab:8,rfc1867:5,corazza:8,background:13,sitesearch:5,apart:5,measur:[3,4],specif:[1,3,4,5,11,13,14],arbitrari:[4,13],sublevel:13,manual:[13,4,5,10,1],zoom:[8,5],soap:[3,5,13],create_priv:4,sebastian:[8,2],underli:5,www:[1,2,3,5,8,13],right:[4,5,13,1,14],old:[4,5,13],deal:3,czech:[8,13],"_db":13,foreignkeymaxlimit:[5,13],maxim:8,getmimetyp:1,intern:[3,5,13,1],sure:[4,5,13,1],savecellsatonc:13,borg:8,inact:1,wkito:5,bora:8,transmiss:3,thu:5,bottom:[14,5,13],net_dim:5,normal:[4,5,13,1],track:[8,4,10,13],tracker:[5,13],t10:13,setoutputfilt:5,iccrawl:5,condit:5,foo:[5,13],localhost:[4,5,13],core:3,plu:[8,5],titleserv:13,connect_typ:13,punct_bracket_close_round:13,stefan:8,confer:8,ivan:8,ankit:8,post:[5,13],"super":10,"stanis\u0142aw":8,plug:[4,1],alexand:[8,2],chronolog:[0,8],surround:5,algi:8,produc:[5,13],tbl_dump:5,kissu:8,curiou:5,"float":13,profession:3,bound:1,repl_client_priv:4,down:[14,5,13,1,9],slurp:5,xavier:8,netscap:5,wrap:13,storag:[3,0,4,13],accordingli:[5,1],suffici:5,support:[0,4,5,8,10,13,6],pma_usernam:5,transform:[0,1,4,5,8,10,11,13],"class":[5,13,1],avail:[3,9,5,13,1],width:13,request_method:5,editor:[8,4,13],legner:5,form:[3,8,5,13],offer:[3,13],forc:[5,13],tickbox:5,papazogl:8,savedir:13,renam:[13,5,10],cidr:13,"true":[4,13],limitchar:13,textarea:13,bugfix:8,maximum:[5,13],tell:5,toggl:[5,13],absenc:5,legenhausen:8,featur:[0,3,4,5,8,10,12,13],classic:[5,13],request:[3,4,5,13],filterlanguag:13,decrypt:5,zend:5,mysql_fetch_field:1,seoma:5,showdisplaydirect:13,exist:[4,5,8,11,13,14],ship:[3,9],browsepointeren:13,db_search:13,interf:5,password:[13,4,5,10,14],encrypt:[4,5,13],showdbstructurelastcheck:13,refactor:8,vserver:[5,13],test:[8,9,5,13],propertiesnumcolumn:13,intend:[9,5],why:[5,13],sqp:13,yasitha:8,walton:8,consid:[4,5],sql:[0,3,4,5,8,10,13],receiv:[3,5,1,2],longer:13,furthermor:13,tinyint:5,ignor:[5,13],time:[3,4,5,13],backward:5,concept:[8,10],table_coord:[5,13],skip:[9,13],rob:5,global:[4,5,10,1,14],ba17c1ec07d65003:4,signific:8,horizontalflip:13,delete_priv:4,pma_combin:5,row:[3,8,5,13],hierarch:8,decid:5,middl:13,depend:[4,5,13],crawleradmin:5,decim:5,readabl:5,markt:5,mehbooob:8,must:[13,4,5,10,14],keck:[8,2],sourc:[0,3,5,8,7,11,12,13],string:[8,6,5,13,1],fando:5,initialslidersst:13,maxcharactersindisplayedsql:13,insertrow:13,word:[13,0,5,10],brows:[13,0,5,10,8],seealso:3,administr:[8,4,5,13,14],level:[3,4,5,13],did:5,win2k:5,"gesch\u00e9":8,item:[3,5,13],team:4,cooki:[0,3,4,5,8,13,6],dir:[5,1],prevent:[4,5,13],slower:6,obrador:8,bravo:8,applytransform:1,cost:4,dev:[3,5,13],turnitinbot:5,port:[3,5,13],digit_integ:13,appear:[5,13],session_save_path:13,abdullah:8,uniform:3,current:[3,4,5,8,9,10,13,6],portugues:8,axel:8,navigationtreepointeren:13,chartextarearow:13,dropdown:5,gener:[0,1,2,3,4,5,8,9,13,14],french:8,slow:[5,13],address:[3,5,13],along:[4,5,2],madhura:8,box:[0,5,13],invit:12,shift:5,rsedwardian_at_gmail:8,bot:5,bbedit:4,behav:5,seward:3,commonli:3,macintosh:3,fpdf:[3,8],stduser:13,getinfo:1,circumv:5,tweak:4,modul:[3,5],prefer:[8,4,5,13],backtick:13,get_login_credenti:13,fake:13,marker:13,instal:[0,1,4,5,13,6],bookmarkt:13,market:3,httpd:5,memori:[5,13],sake:5,visit:4,perl:[3,5],stylesheet:13,handler:3,everywher:5,criteria:5,scope:4,translit:13,maxime_at_fre:8,chapter:[5,13],said:5,club:8,peopl:[8,9,5,10,12],claus:[5,13],ctype:6,enhanc:8,visual:[8,13],olivi:[8,2],accept:[3,5,13],examin:5,your_theme_nam:5,easiest:5,fly:13,graphic:[3,4,10],ibm:5,dhtml:8,tokyo:5,prepar:[3,13],focu:13,minimum:13,mjane:8,can:[1,2,3,4,5,7,9,10,12,13,14],lc_messag:13,umlaut:5,purpos:[3,13,2],"c\u00e9dric":8,problemat:5,heart:5,querywindowdeftab:13,stream:5,backslash:5,agent:5,"lo\u00efc":8,heard:5,abort:13,spl:6,mediapartn:5,articl:[5,7],occur:5,swedish:8,alwai:[4,5,13,1],differenti:5,sensi:5,multipl:[13,8,5,10],hungarian:8,sailboat:8,charset:[8,13,1],nyu:8,write:[13,4,5,10],navigationlogolink:13,navipointerbackground:13,anyon:4,tild:5,protectbinari:13,securer:8,allownopassword:13,mat:8,"m\u00fcller":[8,2],max:5,sql_mode:5,usabl:5,gailli:3,funck_at_googlemail:8,mac:[3,4,5,13],mai:[13,4,5,10,1],underscor:5,data:[1,3,4,5,10,13],grow:1,practic:13,johnson:[8,2],divid:3,explicit:13,showdatabasescommand:13,inform:[0,1,3,4,5,10,11,12,13,7],"switch":[3,4,5],combin:[5,13],block:[3,5,13],anoth:[3,4,5,13],ordinari:4,simoncini:5,navigationbaricon:13,navigationdisplayserv:13,michal_at_cihar:[8,2],db1:13,still:[4,13],pointer:13,dynam:[3,8,5],"p\u00e9ter":8,group:[3,5,13],thank:[8,5],func_uuid:13,polici:13,jim:8,create_tmp_table_priv:4,platform:[3,4,5,13],window:[1,3,4,5,8,13],mail:[3,5],main:[0,1,4,5,8,13,14],non:[5,13],recal:13,encod:[8,5,13],initi:[4,5,13],maxnavigationitem:13,first_timestamp:13,safari:5,now:[4,5,13],thilina:8,discuss:5,nor:5,introduct:[0,10,1,11],term:2,glund_at_silversoft:8,name:[1,3,4,5,8,13,14],exectimelimit:[5,13],didn:13,separ:[3,8,5,13],comment_c:13,gergo314_at_gmail:8,compressonfli:[5,13],compil:5,domain:[5,13],replac:[4,5,13,9],individu:14,continu:13,contributor:8,redistribut:[9,2],sponsor:5,happen:[4,5],bgtwo:13,foreign_kei:3,canada:5,maxrow:13,shown:[5,13],accomplish:10,jackson:8,madlen:8,space:[5,13],fmtind:13,internet:[3,4,5,13],ufpdf:[3,8],correct:[5,13],integr:[13,5,10],iusr_machin:5,dbc334_at_gmail:8,state:13,migrat:5,xhtml1:8,recodingengin:13,phpmyadmin_x:4,mime:[3,8,5,13,1],superus:[4,14],fmtcolor:13,ruleant_at_us:8,mysqli:[3,8,5,10,13],"byte":13,care:[5,1],quote_doubl:13,diagram:5,recod:13,thbackground:13,wai:[8,4,5,13],unwil:5,emerson4br:8,synchron:[0,5,8],refus:5,domen:8,thing:[5,13],place:[4,5,13],titledatabas:13,wiegger:8,view:[3,14,5,8,10,13],imposs:13,frequent:[3,0,5,13],first:[4,5,13,1,14],origin:[0,6,13,1,8],info:[8,5,13,2],redhat:5,onc:[4,5,13,14],arrai:[5,13,1],reload_priv:4,yourself:4,submit:5,rink:8,spanish:8,open:[3,4,5,12,13,6],predefin:10,country_cod:5,size:[5,13],given:[14,5,13],ian:8,navigationtreeenablegroup:13,convent:1,bookmark:[13,8,4,5,10],maxexactcountview:13,conveni:4,ysajeepan_at_l:8,especi:[4,5,13],punct_qualifi:13,copi:[2,4,5,10,13,14],specifi:[8,4,5,13,1],mod_proxi:5,thai:8,than:[13,8,14,5,10],png:5,themenam:13,serv:3,wide:3,przybylski:8,quote_backtick:13,transformationsplugin:1,tecnick:8,n8falke_at_us:8,were:[8,5,13],posit:[3,5],seri:[3,5],pre:[5,13,1],sai:[5,1],zipdump:13,san:13,bailout_on_error:5,displayserverslist:13,ani:[1,2,3,4,5,8,10,13,14],subroutin:3,userconfig:13,doctyp:5,suhosin:[5,13],saw:5,chrisj_at_ctel:8,engin:[3,5],advic:9,greek:8,tcpdf:[3,8,9,5],note:[4,5,13,1,9],maintain:8,harald:5,take:[5,13,1],advis:13,noth:5,sqlqueri:13,parti:[5,7],begin:[5,13],printer:8,ukrainian:8,buffer:[5,13,1],compress:[3,13,5,10],os_x:3,pr1:5,pair:[4,13],homepag:[5,1],icon:[8,14,5,13,1],latex:[3,5,10],path_to_your_phpmyadmin_directori:13,contacto_at_joaodia:8,later:[5,13],typeset:3,meanwhil:5,pmapass:4,pattern:13,axi:5,pma_db:4,john2db:5,event:[3,8,10,13],show:[5,13],german:[8,5],tkl:5,russian:8,concurr:13,permiss:[4,5,13,14],threshold:13,foreign_db:13,help:[8,4,5,13,12],xml:[3,8,6,5,10],onli:[1,4,5,8,10,13,14],explicitli:[4,13],ratio:6,romanian:8,activ:[4,5,13],behind:[4,13],internet_information_servic:3,analyz:[5,13],comment_mysql:13,analys:8,offici:[7,5,1],reset:[4,5],nearli:13,variou:[0,3,5,8,9,10,13],get:[7,4,5,13,1],ssl:[3,5,13],kiko:8,cannot:[4,5,13,1],martin_at_whistl:8,wasser:5,sascha:8,requir:[0,4,5,10,13,6],truli:4,home_pag:5,output_compress:5,borrow:8,yield:5,email:[8,5],controlpass:[4,5,13],where:[3,4,5,13],wiki:[3,5,7],parse_url:5,numrecentt:13,punct_listsep:13,pma__histori:13,korakot:8,hierarchi:[5,13],yacybot:5,progress:[6,5],server_vari:13,logincookievalid:13,blobstream:8,detect:[8,5,13],innov:3,review:4,chapeaux:8,enumer:5,hide_db:13,label:[3,5],enough:4,between:[5,13],"import":[0,3,4,5,8,10,13,6],across:[3,13],parent:5,lsml_at_liv:8,screen:[4,5],cedric:8,retainquerybox:13,refman:13,come:[5,13],img:5,contol:3,allowroot:13,tutori:[7,5,1,11],kanitchet:8,open_basedir:[5,13],mani:[3,4,5,8,10,12,13],fauveau:8,rel_person:5,among:13,googlebot:5,mmcrawler:5,color:13,overview:[5,1],nicola:8,ultim:5,chaovavanich:8,marc:[8,5,7,2],allowdeni:[4,5,13],hardli:4,mark:[3,8,13],barri:8,"abstract":[8,1],table_uipref:13,emphas:13,"50x50":5,phpmysqlformgen:8,andrea:8,tamil:8,marconcini:8,tabbrows:5,"case":[4,5,13,14],blowfish:[3,8,4,13],mount:13,references_priv:4,wigginton:8,advantag:5,ctrl:5,marcel:8,destin:3,cluster:5,zahra:8,setup_dir_writ:9,duke3d_at_ukr:8,ascii:[5,13,1],insert_priv:4,garvin:[8,2],develop:[0,3,5,8,12,13],author:[8,5,13],alphabet:13,statuscachelifetim:13,check:[1,2,14,5,8,9,10,12,13],binari:13,html:[3,8,5,13,1],pma__table_uipref:13,pai:4,update_priv:4,document:[0,3,4,5,8,9,13,6],pan:5,defaulttabt:13,webserv:[3,4,5,13],screenshot:5,nest:[8,5,13],capabl:3,set_magic_quotes_runtim:4,http_host:[5,13],improv:[3,8,5,10,13],extern:[0,9,13],tradition:4,om_at_omni:[8,2],appropri:[13,4,5,10],moder:8,port_:3,edlund:8,without:[5,13,1,2],dimension:3,summer:8,execut:[3,13,5,10],phpmyadmin:[0,1,4,5,7,8,9,10,12,13,6,14],tip:[5,13],aspect:[6,9],polish:8,passphras:13,speed:[4,5,13],defaulttabserv:13,gigabot:5,gather:13,hint:[5,13],except:[4,5,13],adsbot:5,typo3_at_dirk:8,blob:[13,5,10],save_path:5,vulner:[4,5],table_nam:4,gd2:[3,6],hover:13,around:[4,5,13],yuval:8,read:[13,4,5,10],grid:13,dbase:5,world:[3,4,13],mod:5,setup_config_fil:9,whitespac:5,rel_town:5,integ:13,server:[0,3,4,5,8,9,10,13,6,14],benefit:[5,13],either:[5,13],output:[8,5,13,1],inter:[3,13],grant_priv:4,manag:[0,3,4,5,7,10,11,13,14],yyyi:13,node:[3,8],maxtableuipref:13,turck:5,longtextdoubletextarea:13,availablecharset:13,ascend:13,charedit:13,showserverinfo:13,authent:[0,4,5,8,13,6],strickroth:8,column_priv:4,jakub:8,martyna:8,confirm:[5,13],gd2avail:13,piankov:8,definit:[5,13,7],rewriteengin:5,nokeepal:5,complic:13,refer:[3,5,13],column_info:[13,1],schaefer:8,arrow:5,olof:8,quit:[8,5,13],each:[1,3,4,5,13,14],xzvf:4,broken:5,stdpass:13,found:[4,5,13],navigationtreedbsepar:13,digit_float:13,xvnavarro_at_gmail:8,acl:[3,13],precedessor:3,degre:13,mjaning_at_gmail:8,lucen:5,addtyp:5,backup:5,routin:[8,13],chartextareacol:13,effici:[5,13],logouturl:13,strip:[9,5,13],yyi:13,your:[0,1,4,5,10,13,6,14],lolo_at_phpheaven:8,opengi:8,log:[3,13,4,5,10],her:5,area:[4,5,13],hex:[5,13],ysajeepan:8,overwrit:13,start:[8,4,5,13],compliant:8,interfac:[3,8,6,5,13],low:[4,5,13],lot:[5,13],ipv6:[3,13],submiss:13,machin:[3,4,5,13,6],hindi:8,hard:13,tupl:[3,13],bundl:5,regard:[10,1],upload_max_files:5,cryptograph:3,realli:[4,5,13],adler:3,faster:13,pull:13,possibl:[4,5,13,1,12],"default":[0,1,3,4,5,13,6],textarearow:13,embed:13,expect:5,scanner:5,creat:[3,4,5,8,10,11,13,14],multibyt:6,certain:[3,13,1],certail:5,mike:8,strongli:[6,5],plathei:8,localnetc:13,file:[1,3,4,5,8,9,10,11,13,6],"mickevi\u010diu":8,encompass:3,fill:[4,5,13],incorrect:5,again:[4,5],showdbstructurelastupd:13,googl:[8,4,5],commiss:3,corazza_at_wanadoo:8,tbl_row_delet:5,field:[0,1,3,4,5,13],valid:[0,4,5,8,10,13],writabl:[4,13,9],you:[1,2,4,5,7,8,9,10,12,13,6,14],architectur:5,openid:13,resolut:3,sequenc:3,symbol:[5,13],pear:[3,8,5],allowoverrid:5,ansi:5,tables_priv:[4,13],viliu:8,lineup:13,gzencod:5,directori:[0,1,3,4,5,9,13],descript:[5,13,1],papaz_p_at_yahoo:8,chown:[5,13],escap:13,unset:5,file_upload:5,all:[1,3,4,5,9,10,12,13],consider:4,gupta:8,browsemarkeren:13,code:[3,8,4,5,13],yavuz:8,follow:[8,4,5,13],disk:4,minsizeforinputfield:13,scp:5,net_url:5,iconv:13,rewrot:8,intext:5,former:[8,13],alberti:8,program:[3,13,2],those:[4,5,13,1,14],introduc:[8,5,13],liter:[5,13],fals:[9,5,13],faq:[3,0,5],suhosindisablewarn:[5,13],util:[3,5,13],leiding:8,ichiro:5,verb:5,mechan:[8,4,5,13],veri:[5,13],longtext:13,list:[3,9,5,13,7],resav:4,adjust:[5,13],"\u010diha\u0159":[8,2],pbm:8,tbl_creat:8,enterpris:5,homonym:5,internetwork:3,template_abstract:1,path_to_phpmyadmin:5,showbrowsecom:13,controlhost:13,tex:[3,5],zero:13,design:[0,3,4,5,8,13],pass:[13,14,5,10,1],further:[8,13],ajaxifi:8,hick:[8,2],cursor:[5,13],what:[1,4,5,10,13,14],sub:[5,13],request_for_com:3,me_at_derrabu:[8,2],sun:8,section:[4,5,13,1,12],abl:[8,4,5,13],u4663530:8,delet:[4,5,13,14,11],version:[0,2,3,4,5,8,9,10,13,6],"public":[4,5,2],full:[4,5,13,14],hash:5,berkelei:13,wilk:8,behaviour:5,shouldn:4,modifi:[5,13,2],valu:[3,4,5,13,1],ignoremultisubmiterror:13,d3xter_at_us:8,search:[13,0,5,10,8],fmtindunit:13,thememanag:[5,13],yukihiro:8,amount:[5,13,1],pick:5,bussier:8,showcreatedb:13,lock_tables_priv:4,via:[4,5,13,14],janni:8,put:[4,5,13,1],voyag:5,armel:8,famili:13,select:[1,4,5,8,13,14],esri:[5,13],hexadecim:13,khan:8,ga244_at_is8:8,distinct:[5,13],msnbot:5,two:[3,4,5,13],coverag:5,pmahomm:[5,13],taken:5,remembersort:13,ntf:13,minor:[8,5],more:[3,4,5,13,2],webmaster_at_trafficg:8,bulgarian:8,desir:10,showtooltip:13,kristof:8,hundr:5,mozilla:5,oleg:8,particular:[3,4,14,2],known:[3,0,9,5,13],"bokm\u00e5l":8,cach:[5,13],town:5,none:13,der:8,showfieldtypesindataeditview:13,histori:[8,4,13],remain:[5,13],paragraph:5,rel_countri:5,kosit:8,abram:8,renato:8,omit:13,prompt:[4,13],scan:5,share:4,templat:1,max_totalname_length:5,chimera:5,explor:[4,5,13],tablesepar:5,action:[14,5,13],computer_socket:3,uncheck:[5,13],huge:[5,13],cours:[4,5,13],xxxx:13,newlin:13,secur:[0,1,3,4,5,13],yuichiro_at_pop07:8,hidestructureact:13,spreadsheet:[6,10],reject:13,alpha_reservedword:13,csv:[3,5,10],simpl:[3,4,5],css:[5,13],resourc:3,unprivileg:13,quote_singl:13,reflect:3,sven:8,okai:4,mendel:[8,2],mariadb:[6,5],associ:4,pma__rec:13,svec:8,mous:[5,13],"short":3,john1db:5,footer:13,themepath:[5,13],caus:[6,5,13],media:5,checkbox:[14,5,13],rotat:13,hypertext:3,soon:5,soom:8,paper:5,through:[3,13,5,10,1],same:[4,5,13,14],urdu:8,ipmask:13,"montr\u00e9al":5,disablei:13,paramet:[5,13,1],style:[4,5,13],arial:13,db_structur:[5,13],ip_address:3,me_at_supergarv:[8,2],ricardo:8,mcryptdisablewarn:13,bypass:[5,13],alpha_vari:13,might:[4,5,13,9],alter:[13,5,10],good:[4,5,13,1],"return":[5,13,1],timestamp:[4,13],disable_funct:13,select_priv:4,libwww:5,rewriterul:5,ukrain:8,framework:9,botelho:8,rwx:[5,13],bigger:5,troubleshoot:5,userid:5,unlik:4,refresh:[5,13],easili:[4,5,13],achiev:13,tamsjadi:8,innodb:[13,5,10],fulli:5,unicod:3,truncat:13,schema_nam:13,neil:8,wasn:8,idea:[8,4,5,13,1],procedur:[3,5,10],slowdown:5,connect:[0,3,14,5,10,13],http:[2,3,4,5,8,13],beyond:4,orient:[3,5],ftp:[4,5,13],marcin:8,robert:8,publish:[13,2],research:3,footnot:10,print:[7,13,11],occurr:5,msie:5,benjamin:8,difficulti:10,qualifi:13,proxi:[4,5,13],advanc:[4,13],browsepointerbackground:13,asc:13,quick:[3,0,4,5,13],reason:[5,13],base:[3,6,5,8,9,13],ask:[3,0,5],ash:8,english:[8,4,13],repl_slave_priv:4,bakondi:8,perhap:4,schemata:13,pma__rel:5,vainauska:8,lifetim:13,assign:[14,5,11],feed:5,major:5,upper:5,feel:4,exchang:3,lastnam:5,number:[3,5,13],placehold:5,alexandr:8,done:[5,13],least:[4,5,13],blank:[5,13,1],stabl:5,miss:[5,13,1],differ:[1,3,4,5,8,10,13],collat:13,mail_mim:5,interact:3,construct:5,http_cooki:3,station:5,adriaenssen:8,statement:[13,4,5,10],cfg:[4,5,13],enclos:5,ton:13,store:[1,3,4,5,8,10,13],schema:[8,5,13],option:[0,4,5,13,1],relationship:5,girish:8,villanueva:8,feryanto:8,part:[3,13,5,10],pars:[5,13,1],naviwidth:13,webadmin:8,exposur:4,kind:[3,5,13],sta:8,whenev:[5,13],remot:3,remov:[8,4,5,13,14],rsedwardian:8,horizont:[3,5,13],jqueri:9,darlow:8,kindli:5,builder:8,pma:4,comput:3,well:[13,8,5,10],wysiwyg:8,packag:[0,9,5],translationwarningthreshold:13,mod_rewrit:5,"null":[5,13],wilson:8,unintend:13,bz2:[13,5,10],equival:13,self:[4,13],also:[1,3,4,5,8,9,10,13,6,14],build:[5,13,1],kraai:8,http_user_ag:5,upload_tmp_dir:5,distribut:[0,2,4,5,8,9,13],func_dat:13,previou:[4,5,13],reach:1,chart:[8,5],most:[1,3,4,5,8,13,6],plai:4,myisam:[5,10],alpha:[5,13],max_var:5,kempf:8,filesystem:13,clear:[4,5],qbe:[8,10],usual:[3,4,5,13,1],microsoft:[3,5,10],visibl:[5,13],paul:5,mimer:[5,13],carefulli:13,consult:1,column_:3,session:[4,5,13,6],marc_at_infomarc:[8,2],font:[5,13],fine:5,find:[4,5,13],cspallow:13,impact:[4,5,13],access:[3,4,5,8,13,6],beck_at_web:8,pretti:[8,13],scooter:5,solut:[5,13],clipboard:[5,13],iec:[3,10],first__second__third:13,monospac:13,tyron:8,max_array_index_length:5,express:[3,5,13],setenvif:5,gandon_at_isia:8,nativ:5,mainten:[8,10,13],generator_main_class:1,him:8,restart:5,target:5,browsepointercolor:13,ie6:13,rfc:[3,5,10],pundalik:8,defaulttabdatabas:13,common:[3,5,13],nowher:13,kleemann:8,set:[0,1,3,4,5,8,9,10,13],dump:[13,8,5,10],creator:8,psbot0:5,see:[1,2,3,4,5,8,10,13,6],seo:5,reserv:13,browsemarkercolor:13,alexukf:8,lee:8,someth:[4,5,13],won:[5,13],gd_graphics_librari:3,opera7:5,opera6:5,navigationtreetablesepar:[5,13],altern:[4,5,13],numer:[5,13],serverdefault:13,javascript:[8,6,5,13],disallow:[4,13],lowercas:[4,5],solv:5,wiltav:8,both:[4,5,13],cryptic:5,last:[5,13,1],mod_gzip_item_includ:5,foreign:[3,13,5,10],context:5,pdf:[3,4,5,8,10,13],whole:[13,4,5,10],load:[13,4,5,10,6],simpli:[4,5,13,14],point:[3,5,13],utf8_general_ci:13,joaotmdia:8,documentclass:5,shutdown:5,suppli:[4,13],desktop:5,shanyan:8,java:5,sessionsavepath:13,navigationlogolinkwindow:13,devic:3,due:[5,13],empti:[5,13],secret:13,memory_limit:5,bzip:5,org:[3,8,5,13,2],repeatcel:13,mind:4,imag:[3,6,5,10,1],great:[8,12],coordin:[5,13],understand:[4,5,10],paulei:8,mkkeck_at_us:[8,2],remote_us:5,setfacl:13,batch:10,"while":[5,13,1],match:[5,13],behavior:[9,5],error:[4,5,13],anonym:[5,13],everyon:8,pack:5,real:[5,13],mac_os_x:3,readi:4,table_schema:13,jpg:3,asuni:8,itself:5,alter_priv:4,ignacio:8,minim:[4,5],shorten:5,shorter:5,conflict:5,higher:5,signon:[4,13],veeven_at_gmail:8,proxypassreversecookiepath:5,optim:[8,5,13],alert:5,"tom\u00e1\u0161":8,temporari:[4,5,13],winhttp:5,maxdblist:13,winnt4:5,recent:[3,5,13],lower:[5,13],drop_priv:4,lib:[4,5,1,9],older:[0,4,5,13],kelli:8,entri:[4,13],maxsizeforinputfield:13,person:[3,5,13],userstatu:5,vazquez:8,lin:8,propos:[5,10],explan:[4,5],from:[0,1,3,4,5,8,10,13,14],table_:3,administ:10,rutkowski:8,snappi:5,shortcut:13,mydatabas:13,input:[4,5,13],useless:5,bin:5,checklink:5,thilanka:8,varchar:[5,13],format:[1,3,4,5,8,10,13],big:[5,13],catalan:8,tabl:[0,1,3,4,5,8,10,13,14],lanin:8,backquot:5,insert:[8,4,5,13],bit:[6,13],oleg_at_gmail:8,lost:[5,13],table_info:13,resolv:5,collect:3,"boolean":13,proxypassrevers:5,popular:3,engstrom:8,tbl_sql:13,vendor_config:9,punct_bracket_open_round:13,often:[5,13],creation:[8,13],some:[1,3,4,5,8,9,13],back:[3,4,5,14],scratchboard:[8,5],sampl:[4,5,13],pmadb:[5,13],mirror:5,scale:5,per:13,pratap:8,bruce:3,larg:[5,13],slash:13,reproduc:5,cgi:[3,4,5],object:[3,1],run:[3,4,5,13],zzz:13,fmttype:13,ummer:5,weis:8,cochran:8,step:[4,5],bruguera:8,impos:13,blowfish_:3,proce:5,mmcach:5,delisl:[8,7,2],dialog:[4,5],func_char:13,mcrypt:[3,4,5,13,6],italian:8,gamma:5,person_nam:5,displaybinaryashex:13,within:[14,5,13],row_:3,slovak:8,klokner:8,steven:8,ensur:[4,5,13],chang:[1,3,4,5,8,9,10,13,14],pcre:[3,5,13],server_:3,cj_at_gmail:8,sock:5,fast:5,custom:[0,1,5,8,9,13],includ:[1,3,4,5,8,9,13],suit:[3,5],forward:[5,13],stoyanst:8,properli:[4,5,10],electrotechn:3,usedbsearch:13,serif:13,link:[1,4,5,8,10,13,14],translat:[0,5,13,8],newer:[4,5,13,6],upright:5,line:[3,4,5,13,1],torsten:8,trustedproxi:13,utf:[3,6],consist:5,mrbendig:8,hamann:8,reorder:5,mj12bot:5,highlight:13,similar:[4,5,13],enlarg:5,parser:[0,13,8],chao:8,doesn:[5,13,1],repres:[3,5,13],"char":[5,13],thomsen:8,incomplet:13,tar_:3,overcom:5,guarante:13,curl:5,rewritecond:5,titl:[0,13],invalid:[5,13],town_cod:5,nick:5,declar:[5,1],urltrend:5,tempdir:[5,13],browsemarkerbackground:13,navipointercolor:13,show_db_priv:4,heis:5,drag:5,clue:5,lang:[5,13],titlet:13,algorithm:[3,4,13],mimetyp:[5,13,1],rewritebas:5,sherbrook:5,depth:5,foreignkeydropdownord:13,errorcod:5,scroll:5,albiol:8,partial:13,queri:[0,3,4,5,8,10,13],steve:8,broader:3,edu:8,funck:8,privat:5,bzipdump:13,turkish:8,sensit:13,only_db:[4,13],wizard:4,send:[5,13],headerfliptyp:13,becam:13,sens:1,sent:[3,8,5],deactiv:[5,13],unzip:4,logincookiedeleteal:13,zigmanta:8,master_db:13,implicitli:3,portable_document_format:3,relev:13,net_socket:5,tri:[4,5,13],ajaxif:8,comment_ansi:13,button:[5,13],michael:[8,2],stuffit:4,fewer:13,"try":[4,5,13],mathia:8,alia:8,queryhistorymax:13,pleas:[4,5,13,1,9],impli:2,smaller:[8,5,13],visualis:5,natur:13,wors:5,noblob:13,uniqu:[3,5],jump:13,defaultdisplai:13,gmbh:5,user_prefer:13,odn:8,tobias_at_ratschil:[8,2],download:[4,10],ratschil:[8,2],click:[14,5,13,1],append:[13,1],victor:8,compat:[3,4,5,8,9,6],index:[0,3,4,5,8,10,13],ia_archiv:5,computer_sci:3,cell:[3,5,13],experiment:13,isapi:[3,4,5],typo3:8,gheni:8,chose:[4,5],tracking_add_drop_databas:13,vinai:8,internet_protocol:3,punct:13,firewal:[4,5,13],logout:13,ubuntu:13,vertic:[3,8,13],sinc:[8,4,5,13,6],pma_dbi:8,convert:5,copyright:[0,2],themedefault:[5,13],baishui:8,larger:[5,13],technolog:[3,5],delorm:8,typim:8,auth_kei:4,typic:[3,5],forkik_at_gmail:8,control:[3,4,5,8,13,14],firefox:5,haa:8,appli:[4,5,13,1],approxim:[5,13],foundat:2,gatewai:3,api:[3,5],seosearch:5,apc:[5,13],pma__track:13,zerofil:1,usb:4,zip:[3,6,5,8,10,13],commun:[3,10],doubl:[5,13],upgrad:[0,4,5],intitl:5,next:[4,5,13],websit:[3,5,13,12],few:[4,5,13],lesli:8,webcrawl:5,ninad:8,sort:[3,5,13],pencil:14,client_:3,proxypass:5,newsblog:5,trail:13,defaultqueryt:13,central:[4,5,13],harvest:5,abtract:1,acko:[3,8],account:[10,13],john_db:5,retriev:13,gabriel:8,ne0x_at_us:8,when:[4,5,8,10,13,6],showal:13,opensource_at_jth:8,obvious:4,"j\u00f8rgen":8,fetch:13,employe:5,user_bas:4,weaker:13,tar:[3,4],process:[3,14,5],lock:[5,13],codemirroren:13,high:[5,13],auth_http_realm:13,tag:5,jeev:5,tab:[0,5,13],opensourc:8,onlin:[5,13],delai:5,andersen:8,siu:8,slovenian:8,subdirectori:[4,5,13],instead:[4,5,13],chri:8,pink:5,klau:5,mysqlmanualbas:13,attent:4,mod_ssl:5,nordenberg:8,alloc:13,walton_at_nordicdm:8,light:13,astarita:8,correspond:[5,13,1],element:[3,5,13,1],issu:[5,13],encyclopedia:3,allow:[3,4,5,8,10,13,14],subtyp:1,fallback:13,cbb74bc:4,include_path:5,me_at_mynetx:8,move:[4,5,13],iconvextraparam:13,pruett:8,comma:3,korakot_at_inam:8,themeperserv:13,bunch:5,fontfamili:13,edlund_at_upright:8,till:[4,5],chosen:5,wget:5,fujifilm:8,clickabl:[5,13],ukf_at_gmail:8,dorning:5,therefor:13,pixel:13,crash:5,handl:[14,5,13,1],auto:[5,13],dan:8,auth:[4,5,13],repositori:3,mention:[4,5],srnka:8,databa:5,krukowski:8,somewher:5,anyth:4,edit:[0,4,5,10,11,13,14],mode:[0,4,5,8,13,6],beneath:5,register_glob:5,showphpinfo:13,subset:10,consum:3,drizzl:[8,6,5,13],httrack:5,our:[7,5,13,1,12],navigationtreetablelevel:13,patch:[8,13],tracking_add_drop_view:13,special:[3,4,5,13],out:[3,4,5,13,12],variabl:[5,13,1],gandon:8,showstat:13,acunetix:5,naeem:8,index_:3,rel:5,hardwar:13,sp2:5,statist:[8,5,13],insid:[4,5,13,1,9],manipul:[3,10,13],querywindowwidth:13,transliter:13,releas:[8,5,13],mysql_pconnect:13,designer_coord:13,indent:13,could:[4,5,13],david:8,navigationdisplaylogo:13,length:[5,13],enforc:13,organis:3,db_sql:13,outsid:[4,13,1],transfer:[3,4,5,13],geometri:5,manuzhai:8,endors:7,baiduspid:5,suffix:13,christoph:8,brute:5,exact:13,date:[5,13],muhammad:8,buggi:[4,5],alpha_identifi:13,netcologn:5,owner:[4,13],showchgpassword:13,suffic:4,alioglu:8,"long":[3,5,13,1],strict:13,rouslan_at_placella:8,unknown:5,licens:2,mkdir:[4,5],system:[3,4,5,8,9,13],messag:[4,5,13],ssloption:5,attach:3,attack:5,appl:3,lower_case_table_nam:5,pavel:8,rfc2616_header:5,lacina:8,ipv4:3,shell:5,mbstring:6,methodolog:3,slider:13,obgzip:[5,13],textfield:1,haven:5,gzipdump:13,photograph:3,digit_hex:13,alpha_functionnam:13,structur:[0,1,3,5,10,11,13],charact:[3,4,5,13,1],htaccess:[3,4,5],seriou:5,stoyanster_at_gmail:8,upload_progress:5,julian:3,respons:3,robot:[4,5],sysadmin:[5,13],miquel:8,have:[1,2,4,5,8,10,12,13,14],ari:8,close:[5,13],turn:[5,13],border:13,bzcompress:5,probabl:[4,5,13,9],rout:13,propertiesicon:13,browsemim:13,which:[1,3,4,5,10,13,6,14],singh:8,exabot:5,singl:[3,13,4,5,10],"5b4":5,brazil:8,untar:4,unless:[4,5],transmit:5,who:[1,4,5,8,9,10,13],discov:4,cipher:3,buddika:8,nutchcv:5,stdenvvar:5,herman:8,placement:5,secure_sockets_lay:3,url:[3,5,13],uploaddir:[5,13],uro:8,showhint:13,face:5,pipe:13,deni:[8,4,5,13],snapshot:13,determin:[14,5,13],built:[8,5],index_priv:4,fact:[5,13],dbm:3,abeyrathna:8,text:[0,1,3,4,5,8,10,13],verbos:[5,13],dbg:13,dbf:5,bring:5,turek:[8,2],"mat\u00eda":8,controlus:[4,5,13],redirect:[5,13],textual:5,locat:[3,4,5],anticip:3,auth_typ:[4,5,13],should:[2,4,5,8,9,13,6],manufactur:3,bernard:8,tape:3,local:[4,5,13],"lu\u00ed":8,hope:2,contribut:[8,5,12],autom:8,recode_str:13,drawn:1,increas:[5,13],db2:13,awai:5,takahashi:8,shp:5,enabl:[1,3,4,5,13,6],organ:3,showasphp:13,navarro:8,stuff:8,she:5,contain:[4,5,13,1],grab:5,mynam:5,statuscachedatabas:13,kawada:8,conform:3,win98:5,frame:[8,5,13],mod_gzip:5,packet:3,malfunct:5,alessandro:8,temporarili:5,tracking_add_drop_t:13,statu:[8,5,13],convers:[8,13],correctli:[5,13],mainli:3,nopassword:13,dll:5,written:[5,13,12],default_socket:5,boutel:3,navigationtreedisplaydbfilterminimum:13,longtabl:5,neither:[5,13],thumbnail:6,classless:13,kei:[3,4,5,8,10,13],smart:13,job:4,entir:[4,5,6],joe:[8,5],server_privileg:13,addit:[3,8,4,5,13],revers:[5,13],plugin:[8,5,1],wisenutbot:5,libiconv:13,etc:[4,5,13,1],instanc:13,admir:8,tschopp:8,strftime:5,comment:[3,8,4,5,13],hyphen:5,chmod:[4,5,13],defaultquerydatabas:13,respect:5,gheni_at_yahoo:8,withdrawn:[8,5],unclean:5,searchabl:[4,13],disablemultitablemainten:13,"10_at_windowsl":8,addition:13,quotat:13,compos:13,signonscript:[4,13],json:[6,5],slashdot:13,treat:5,logincookiestor:13,infrastructur:4,filippo:5,adob:3,reservedworddisablewarn:13,moreov:5,togeth:[5,13],present:[5,13],hitowerdigit_at_hotmail:8,replic:8,multi:[0,3,4,5,8,13],tbl_chang:[8,13],showdbstructurecr:13,plain:[4,5,13,1],align:5,yuichiro:8,harden:5,defin:[3,14,5,13,1],scatter:5,glossari:[3,0],server_databas:13,ini:[13,5,10],layer:3,purchas:4,dieter:8,almost:13,site:[4,5,13,7],skiplockedt:13,archiv:[3,5],incom:4,revis:[3,5],pmaabsoluteuri:[5,13],let:[5,13],welcom:[0,4,5],japanes:8,stored_procedur:3,referenti:[10,13],cross:[3,4,13],python:5,pma_password:5,largest:5,abravo_at_hq:8,linklengthlimit:13,inc:[4,5,13,9],difficult:5,proxypassreversecookiedomain:5,stankruk_at_neostrada:8,mousewheel:5,hostnam:[3,5,13],expans:5,effect:[7,5,13,1],naturalord:13,thcolor:13,php:[0,1,3,4,5,8,9,10,13,6],codemirror:13,login:[4,5,13],expand:5,keep:[4,5,13],real_us:4,off:[5,13],center:5,nevertheless:4,colour:13,jayaratn:8,real_password:4,exampl:[4,5,8,9,10,13],command:[4,5,13],choos:[4,5,13,1],undefin:5,fail:[5,13],metagerbot:5,yasir:8,latest:[3,5,13],mehboobbugti_at_gmail:8,newest:13,geert:8,less:[4,5,13],obtain:13,tcp:[3,5,13],gettext:9,skill:5,robert_readman_at_hotmail:8,web:[0,3,4,5,8,9,13,6],mainbackground:13,smith:5,script:[8,4,5,13,9],add:[4,5,13,14],other:[0,1,3,4,5,7,9,10,11,12,13,14],uighur:8,showsql:13,pma__column_com:13,kick:5,css2:8,bigdump:5,rememb:[5,13],max_request_vari:5,setinputfilt:5,punctuat:13,pma__table_info:[5,13],know:[5,1],redesign:8,tick:13,desc:13,konqueror:5,like:[1,4,5,8,10,13],success:5,header:[5,13],pma__column_info:13,necessari:[5,1],navibackground:13,martin:8,separated_valu:3,resiz:5,page:[0,1,3,4,5,6,8,7,13,14],crawler:5,drop:[1,14,5,8,10,13],prepend:1,convei:3,jan:8,"kozio\u0142":8,linux:[4,13,9],"landh\u00e4u\u00df":8,"export":[13,0,5,10,8],unstuff:4,proper:[1,4,5,10,13,6],home:14,fileinfo:5,peter:8,laurent:8,librari:[0,1,3,4,5,8,9,13,6],tmp:[5,13],win32:[4,5],guid:[0,7,11],my_db:13,lead:5,avoid:[5,13],phpinfo:[5,13],octet:5,tooltip:[5,13],leav:[5,13,1],lord_dark_at_wp:8,backend:5,kiddi:5,getnam:1,"enum":[8,1],usag:[1,4,5,11,13,14],host:[1,3,4,5,8,13],although:[8,5],"7euser":5,panel:[0,5,13],about:[0,1,4,5,10,13],misbehav:5,actual:[5,1],socket:[3,5,13],kawada_at_den:8,column:[1,3,4,5,8,10,13],andersen_at_gmail:8,zip_:3,localnetb:13,localneta:13,disabl:[4,5,13],not_nul:1,own:[13,4,5,10,1],sarna:8,transformation_overview:1,automat:[3,8,5,10,13],create_t:4,warranti:2,lund:8,robbat2_at_us:[8,2],generator_plugin:1,sander:8,w3c:[3,5],van:8,panagioti:8,much:1,downgrad:5,"var":[9,5],information_schema:13,favorit:[4,5],"function":[1,3,5,8,10,13],unexpect:5,alexi:8,lossi:3,soulard:8,eas:1,inlin:6,bug:[8,5,13],piller:8,count:[5,13],made:[3,8,5,13],database_trigg:3,whether:[14,13,9],wish:[4,13,14],defaultfunct:13,displai:[0,1,3,4,5,8,10,13,6],troubl:[5,13],record:[3,14],below:[4,5,13,1],meta:[13,1],limit:[0,4,5,13],shutdown_priv:4,otherwis:[5,13],problem:[3,4,5,13],significantli:6,"int":5,ilnytskyi:8,dure:[5,13],filenam:[5,1],implement:[3,13,1],erik:[8,5],sinhala:8,error_handl:13,stefan_at_inkopsforum:8,bzip2:[3,13,5,10],detail:[4,5,13,2],logincookierecal:13,book:[7,11],futur:[5,13],branch:5,php4:[8,5],blowfish_secret:[4,13],php3:8,repeat:[5,13],star:8,mysql_upgrad:5,june:8,kanichet_at_hotmail:8,server_statu:13,showpropertycom:13,debian:13,gergo314:8,markup:3,outsourc:8,fund:4,reliabl:5,kanji:8,rule:[4,5,13,1],post_max_s:5,portion:13,rajandran:8,decemb:8,phpwizard:[8,5]},objtypes:{"0":"config:option"},titles:["Welcome to phpMyAdmin’s documentation!","Transformations","Copyright","Glossary","Installation","FAQ - Frequently Asked Questions","Requirements","Other sources of information","Credits","Distributing and packaging phpMyAdmin","Introduction","User Guide","Developers Information","Configuration","User management"],objnames:{"0":["config","option","Config config option"]},filenames:["index","transformations","copyright","glossary","setup","faq","require","other","credits","vendors","intro","user","developers","config","privileges"]}) \ No newline at end of file diff --git a/phpmyadmin/doc/html/setup.html b/phpmyadmin/doc/html/setup.html new file mode 100644 index 000000000..aec2ae169 --- /dev/null +++ b/phpmyadmin/doc/html/setup.html @@ -0,0 +1,481 @@ + + + + + + + + + + Installation — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Installation

      +

      phpMyAdmin does not apply any special security methods to the MySQL +database server. It is still the system administrator’s job to grant +permissions on the MySQL databases properly. phpMyAdmin’s Users +page can be used for this.

      +
      +

      Warning

      +

      Mac users should note that if you are on a version before +Mac OS X, StuffIt unstuffs with Mac formats. So you’ll have +to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before +uploading them to your server, as PHP seems not to like Mac-style +end of lines character (“\r”).

      +
      +
      +

      Quick Install

      +
        +
      1. Choose an appropriate distribution kit from the phpmyadmin.net +Downloads page. Some kits contain only the English messages, others +contain all languages. We’ll assume you chose a kit whose name +looks like phpMyAdmin-x.x.x -all-languages.tar.gz.
      2. +
      3. Untar or unzip the distribution (be sure to unzip the subdirectories): +tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz in your +webserver’s document root. If you don’t have direct access to your +document root, put the files in a directory on your local machine, +and, after step 4, transfer the directory on your web server using, +for example, ftp.
      4. +
      5. Ensure that all the scripts have the appropriate owner (if PHP is +running in safe mode, having some scripts with an owner different from +the owner of other scripts will be a problem). See 4.2 What’s the preferred way of making phpMyAdmin secure against evil access? and +1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin. for suggestions.
      6. +
      7. Now you must configure your installation. There are two methods that +can be used. Traditionally, users have hand-edited a copy of +config.inc.php, but now a wizard-style setup script is provided +for those who prefer a graphical installation. Creating a +config.inc.php is still a quick way to get started and needed for +some advanced features.
      8. +
      +
      +

      Manualy creating file

      +

      To manually create the file, simply use your text editor to create the +file config.inc.php (you can copy config.sample.inc.php to get +minimal configuration file) in the main (top-level) phpMyAdmin +directory (the one that contains index.php). phpMyAdmin first +loads libraries/config.default.php and then overrides those values +with anything found in config.inc.php. If the default value is +okay for a particular setting, there is no need to include it in +config.inc.php. You’ll need a few directives to get going, a +simple configuration may look like this:

      +
      <?php
      +$cfg['blowfish_secret'] = 'ba17c1ec07d65003';  // use here a value of your choice
      +
      +$i=0;
      +$i++;
      +$cfg['Servers'][$i]['auth_type']     = 'cookie';
      +?>
      +
      +
      +

      Or, if you prefer to not be prompted every time you log in:

      +
      <?php
      +
      +$i=0;
      +$i++;
      +$cfg['Servers'][$i]['user']          = 'root';
      +$cfg['Servers'][$i]['password']      = 'cbb74bc'; // use here your password
      +$cfg['Servers'][$i]['auth_type']     = 'config';
      +?>
      +
      +
      +

      For a full explanation of possible configuration values, see the +Configuration of this document.

      +
      +
      +

      Using Setup script

      +

      Instead of manually editing config.inc.php, you can use the Setup +Script. First you must manually create a folder config +in the phpMyAdmin directory. This is a security measure. On a +Linux/Unix system you can use the following commands:

      +
      cd phpMyAdmin
      +mkdir config                        # create directory for saving
      +chmod o+rw config                   # give it world writable permissions
      +
      +
      +

      And to edit an existing configuration, copy it over first:

      +
      cp config.inc.php config/           # copy current configuration for editing
      +chmod o+w config/config.inc.php     # give it world writable permissions
      +
      +
      +

      On other platforms, simply create the folder and ensure that your web +server has read and write access to it. 1.26 I just installed phpMyAdmin in my document root of IIS but I get the error “No input file specified” when trying to run phpMyAdmin. can help with +this.

      +

      Next, open setup/ in your browser. Note that changes are +not saved to disk until explicitly choose ``Save`` from the +Configuration area of the screen. Normally the script saves the new +config.inc.php to the config/ directory, but if the webserver does +not have the proper permissions you may see the error “Cannot load or +save configuration.” Ensure that the config/ directory exists and +has the proper permissions - or use the Download link to save the +config file locally and upload (via FTP or some similar means) to the +proper location.

      +

      Once the file has been saved, it must be moved out of the config/ +directory and the permissions must be reset, again as a security +measure:

      +
      mv config/config.inc.php .         # move file to current directory
      +chmod o-rw config.inc.php          # remove world read and write permissions
      +rm -rf config                      # remove not needed directory
      +
      +
      +

      Now the file is ready to be used. You can choose to review or edit the +file with your favorite editor, if you prefer to set some advanced +options which the setup script does not provide.

      +
        +
      1. If you are using the auth_type “config”, it is suggested that you +protect the phpMyAdmin installation directory because using config +does not require a user to enter a password to access the phpMyAdmin +installation. Use of an alternate authentication method is +recommended, for example with HTTP–AUTH in a .htaccess file or switch to using +auth_type cookie or http. See the ISPs, multi-user installations +for additional information, especially 4.4 phpMyAdmin always gives “Access denied” when using HTTP authentication..
      2. +
      3. Open the main phpMyAdmin directory in your browser. +phpMyAdmin should now display a welcome screen and your databases, or +a login dialog if using HTTP or +cookie authentication mode.
      4. +
      5. You should deny access to the ./libraries and ./setup/lib +subfolders in your webserver configuration. For Apache you can use +supplied .htaccess file in that folder, for other webservers, you should +configure this yourself. Such configuration prevents from possible +path exposure and cross side scripting vulnerabilities that might +happen to be found in that code.
      6. +
      7. It is generally good idea to protect public phpMyAdmin installation +against access by robots as they usually can not do anything good +there. You can do this using robots.txt file in root of your +webserver or limit access by web server configuration, see +1.42 How can I prevent robots from accessing phpMyAdmin?.
      8. +
      +
      +
      +
      +

      phpMyAdmin configuration storage

      +

      For a whole set of new features (bookmarks, comments, SQL-history, +tracking mechanism, PDF-generation, column contents transformation, +etc.) you need to create a set of special tables. Those tables can be located +in your own database, or in a central database for a multi-user installation +(this database would then be accessed by the controluser, so no other user +should have rights to it).

      +

      Please look at your ./examples/ directory, where you should find a +file called create_tables.sql. (If you are using a Windows server, +pay special attention to 1.23 I’m running MySQL on a Win32 machine. Each time I create a new table the table and column names are changed to lowercase!).

      +

      If you already had this infrastructure and upgraded to MySQL 4.1.2 or +newer, please use examples/upgrade_tables_mysql_4_1_2+.sql +and then create new tables by importing +examples/create_tables.sql.

      +

      You can use your phpMyAdmin to create the tables for you. Please be +aware that you may need special (administrator) privileges to create +the database and tables, and that the script may need some tuning, +depending on the database name.

      +

      After having imported the examples/create_tables.sql file, you +should specify the table names in your config.inc.php file. The +directives used for that can be found in the Configuration. You will also need to +have a controluser with the proper rights to those tables (see section +Using authentication modes below).

      +
      +
      +

      Upgrading from an older version

      +

      Simply copy config.inc.php from your previous installation into +the newly unpacked one. Configuration files from old versions may +require some tweaking as some options have been changed or removed. +For compatibility with PHP 6, remove a +set_magic_quotes_runtime(0); statement that you might find near +the end of your configuration file.

      +

      You should not copy libraries/config.default.php over +config.inc.php because the default configuration file is version- +specific.

      +

      If you have upgraded your MySQL server from a version previous to 4.1.2 to +version 5.x or newer and if you use the phpMyAdmin configuration storage, you +should run the SQL script found in +examples/upgrade_tables_mysql_4_1_2+.sql.

      +
      +
      +

      Using authentication modes

      +

      HTTP and cookie authentication modes are recommended in a multi-user +environment where you want to give users access to their own database and +don’t want them to play around with others. Nevertheless be aware that MS +Internet Explorer seems to be really buggy about cookies, at least till version +6. Even in a single-user environment, you might prefer to use HTTP +or cookie mode so that your user/password pair are not in clear in the +configuration file.

      +

      HTTP and cookie authentication +modes are more secure: the MySQL login information does not need to be +set in the phpMyAdmin configuration file (except possibly for the +$cfg['Servers'][$i]['controluser']). +However, keep in mind that the password travels in plain text, unless +you are using the HTTPS protocol. In cookie mode, the password is +stored, encrypted with the blowfish algorithm, in a temporary cookie.

      +

      For ‘HTTP‘ and ‘cookie’ modes, phpMyAdmin needs a controluser that has +only the SELECT privilege on the `mysql`.`user` (all columns except +`Password`), `mysql`.`db` (all columns), `mysql`.`host` (all columns) and +`mysql`.`tables_priv` (all columns except `Grantor` and `Timestamp`) tables. +You must specify the details for the controluser in the config.inc.php +file under the $cfg['Servers'][$i]['controluser'] and +$cfg['Servers'][$i]['controlpass'] settings. The following +example assumes you want to use pma as the controluser and pmapass as +the controlpass, but this is only an example: use something else in your +file! Input these statements from the phpMyAdmin SQL Query window or +mysql command–line client. Of course you have to replace localhost with the +webserver’s host if it’s not the same as the MySQL server’s one.

      +

      If you want to use the many new relation and bookmark features: (this of +course requires that your phpMyAdmin configuration storage be set up).

      +
      GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass';
      +GRANT SELECT (
      +Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv,
      +Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv,
      +File_priv, Grant_priv, References_priv, Index_priv, Alter_priv,
      +Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv,
      +Execute_priv, Repl_slave_priv, Repl_client_priv
      +) ON mysql.user TO 'pma'@'localhost';
      +GRANT SELECT ON mysql.db TO 'pma'@'localhost';
      +GRANT SELECT ON mysql.host TO 'pma'@'localhost';
      +GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv)
      +ON mysql.tables_priv TO 'pma'@'localhost';
      +
      +
      +

      If you want to use the many new relation and bookmark features:

      +
      GRANT SELECT, INSERT, UPDATE, DELETE ON <pma_db>.* TO 'pma'@'localhost';
      +
      +
      +

      (this of course requires that your phpMyAdmin +configuration storage be set up).

      +

      Then each of the true users should be granted a set of privileges +on a set of particular databases. Normally you shouldn’t give global +privileges to an ordinary user, unless you understand the impact of those +privileges (for example, you are creating a superuser). +For example, to grant the user real_user with all privileges on +the database user_base:

      +
      GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password';
      +
      +
      +

      What the user may now do is controlled entirely by the MySQL user management +system. With HTTP or cookie authentication mode, you don’t need to fill the +user/password fields inside the $cfg['Servers'].

      +
      +

      HTTP authentication mode

      + +
      + +
      +

      Signon authentication mode

      +
        +
      • This mode is a convenient way of using credentials from another +application to authenticate to phpMyAdmin.
      • +
      • The other application has to store login information into session +data.
      • +
      + +
      +
      +

      Config authentication mode

      +
        +
      • This mode is the less secure one because it requires you to fill the +$cfg['Servers'][$i]['user'] and +$cfg['Servers'][$i]['password'] +fields (and as a result, anyone who can read your config.inc.php +can discover your username and password). But you don’t need to setup +a “controluser” here: using the $cfg['Servers'][$i]['only_db'] might be enough.
      • +
      • In the ISPs, multi-user installations section, there is an entry explaining how +to protect your configuration file.
      • +
      • For additional security in this mode, you may wish to consider the +Host authentication $cfg['Servers'][$i]['AllowDeny']['order'] +and $cfg['Servers'][$i]['AllowDeny']['rules'] configuration directives.
      • +
      • Unlike cookie and http, does not require a user to log in when first +loading the phpMyAdmin site. This is by design but could allow any +user to access your installation. Use of some restriction method is +suggested, perhaps a .htaccess file with the HTTP-AUTH directive or disallowing +incoming HTTP requests at one’s router or firewall will suffice (both +of which are beyond the scope of this manual but easily searchable +with Google).
      • +
      +
      +
      +

      Swekey authentication mode

      +

      The Swekey is a low cost authentication USB key that can be used in +web applications. When Swekey authentication is activated, phpMyAdmin +requires the users’s Swekey to be plugged before entering the login +page (currently supported for cookie authentication mode only). Swekey +Authentication is disabled by default. To enable it, add the following +line to config.inc.php:

      +
      $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';
      +
      +
      +

      You then have to create the swekey.conf file that will associate +each user with their Swekey Id. It is important to place this file +outside of your web server’s document root (in the example, it is +located in /etc). A self documented sample file is provided in the +examples directory. Feel free to use it with your own users’ +information. If you want to purchase a Swekey please visit +http://phpmyadmin.net/auth_key +since this link provides funding for phpMyAdmin.

      + +
      +
      +
      +

      Securing your phpMyAdmin installation

      +

      The phpMyAdmin team tries hardly to make the application secure, however there +are always ways to make your installation more secure:

      +
        +
      • remove setup directory from phpMyAdmin, you will probably not +use it after initial setup
      • +
      • prevent access to libraries directory from browser, +as it is not needed, supplied .htaccess file does this
      • +
      • properly choose authentication method - Cookie authentication mode +is probably the best choice for shared hosting
      • +
      • in case you don’t want all MySQL users to be able to access +phpMyAdmin, you can use $cfg['Servers'][$i]['AllowDeny']['rules'] to limit them
      • +
      • consider hiding phpMyAdmin behind authentication proxy, so that +MySQL credentials are not all users need to login
      • +
      +
      +
      + + +
      +
      +
      + +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/transformations.html b/phpmyadmin/doc/html/transformations.html new file mode 100644 index 000000000..887884e1a --- /dev/null +++ b/phpmyadmin/doc/html/transformations.html @@ -0,0 +1,240 @@ + + + + + + + + + + Transformations — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Transformations

      +
      +

      Introduction

      +

      To enable transformations, you have to setup the column_info +table and the proper directives. Please see the Configuration on how to do so.

      +

      You can apply different transformations to the contents of each +column. The transformation will take the content of each column and +transform it with certain rules defined in the selected +transformation.

      +

      Say you have a column ‘filename’ which contains a filename. Normally +you would see in phpMyAdmin only this filename. Using transformations +you can transform that filename into a HTML link, so you can click +inside of the phpMyAdmin structure on the column’s link and will see +the file displayed in a new browser window. Using transformation +options you can also specify strings to append/prepend to a string or +the format you want the output stored in.

      +

      For a general overview of all available transformations and their +options, you can consult your <www.your-host.com>/<your-install- +dir>/transformation_overview.php installation.

      +

      For a tutorial on how to effectively use transformations, see our +Link section on the +official phpMyAdmin homepage.

      +
      +
      +

      Usage

      +

      Go to your tbl_structure.php page (i.e. reached through clicking on +the ‘Structure’ link for a table). There click on “Change” (or change +icon) and there you will see three new fields at the end of the line. +They are called ‘MIME-type’, ‘Browser transformation’ and +‘Transformation options’.

      +
        +
      • The field ‘MIME-type’ is a drop-down field. Select the MIME-type that +corresponds to the column’s contents. Please note that transformations +are inactive as long as no MIME-type is selected.
      • +
      • The field ‘Browser transformation’ is a drop-down field. You can +choose from a hopefully growing amount of pre-defined transformations. +See below for information on how to build your own transformation. +There are global transformations and mimetype-bound transformations. +Global transformations can be used for any mimetype. They will take +the mimetype, if necessary, into regard. Mimetype-bound +transformations usually only operate on a certain mimetype. There are +transformations which operate on the main mimetype (like ‘image’), +which will most likely take the subtype into regard, and those who +only operate on a specific subtype (like ‘image/jpeg’). You can use +transformations on mimetypes for which the function was not defined +for. There is no security check for you selected the right +transformation, so take care of what the output will be like.
      • +
      • The field ‘Transformation options’ is a free-type textfield. You have +to enter transform-function specific options here. Usually the +transforms can operate with default options, but it is generally a +good idea to look up the overview to see which options are necessary. +Much like the ENUM/SET-Fields, you have to split up several options +using the format ‘a’,’b’,’c’,...(NOTE THE MISSING BLANKS). This is +because internally the options will be parsed as an array, leaving the +first value the first element in the array, and so forth. If you want +to specify a MIME character set you can define it in the +transformation_options. You have to put that outside of the pre- +defined options of the specific mime-transform, as the last value of +the set. Use the format “’; charset=XXX’”. If you use a transform, for +which you can specify 2 options and you want to append a character +set, enter “‘first parameter’,’second parameter’,’charset=us-ascii’”. +You can, however use the defaults for the parameters: “’‘,’‘,’charset +=us-ascii’”.
      • +
      +
      +
      +

      File structure

      +

      All specific transformations for mimetypes are defined through class +files in the directory ‘libraries/plugins/transformations/’. Each of +them extends a certain transformation abstract class declared in +libraries/plugins/transformations/abstract.

      +

      They are stored in files to ease up customization and easy adding of +new transformations.

      +

      Because the user cannot enter own mimetypes, it is kept sure that +transformations always work. It makes no sense to apply a +transformation to a mimetype the transform-function doesn’t know to +handle.

      +

      There is a file called ‘transformations.lib.php‘ that provides some +basic functions which can be included by any other transform function.

      +

      The file name convention is [Mimetype]_[Subtype]_[Transformation +Name].class.php, while the abtract class that it extends has the +name [Transformation Name]TransformationsPlugin. All of the +methods that have to be implemented by a transformations plug-in are:

      +
        +
      1. getMIMEType() and getMIMESubtype() in the main class;
      2. +
      3. getName(), getInfo() and applyTransformation() in the abstract class +it extends.
      4. +
      +

      The getMIMEType(), getMIMESubtype() and getName() methods return the +name of the MIME type, MIME Subtype and transformation accordingly. +getInfo() returns the transformation’s description and possible +options it may receive and applyTransformation() is the method that +does the actual work of the transformation plug-in.

      +

      Please see the libraries/plugins/transformations/TEMPLATE and +libraries/plugins/transformations/TEMPLATE_ABSTRACT files for adding +your own transformation plug-in. You can also generate a new +transformation plug-in (with or without the abstract transformation +class), by using +libraries/plugins/transformations/generator_plugin.sh or +libraries/plugins/transformations/generator_main_class.sh.

      +

      The applyTransformation() method always gets passed three variables:

      +
        +
      1. $buffer - Contains the text inside of the column. This is the +text, you want to transform.
      2. +
      3. $options - Contains any user-passed options to a transform +function as an array.
      4. +
      5. $meta - Contains an object with information about your column. The +data is drawn from the output of the mysql_fetch_field() function. This means, all +object properties described on the manual page are available in this +variable and can be used to transform a column accordingly to +unsigned/zerofill/not_null/... properties. The $meta->mimetype +variable contains the original MIME-type of the column (i.e. +‘text/plain’, ‘image/jpeg’ etc.)
      6. +
      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      User Guide

      +

      Next topic

      +

      User management

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/user.html b/phpmyadmin/doc/html/user.html new file mode 100644 index 000000000..8af33c0c4 --- /dev/null +++ b/phpmyadmin/doc/html/user.html @@ -0,0 +1,135 @@ + + + + + + + + + + User Guide — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      + +
      +
      +

      Previous topic

      +

      Configuration

      +

      Next topic

      +

      Transformations

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/html/vendors.html b/phpmyadmin/doc/html/vendors.html new file mode 100644 index 000000000..a54f81d29 --- /dev/null +++ b/phpmyadmin/doc/html/vendors.html @@ -0,0 +1,147 @@ + + + + + + + + + + Distributing and packaging phpMyAdmin — phpMyAdmin 4.0.4 documentation + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Distributing and packaging phpMyAdmin

      +

      This document is intended to give advices to people who want to +redistribute phpMyAdmin inside other software package such as Linux +distribution or some all in one package including web server and MySQL +server.

      +

      Generally you can customize some basic aspects (paths to some files and +behavior) in libraries/vendor_config.php.

      +

      For example if you want setup script to generate config file in var, change +SETUP_CONFIG_FILE to /var/lib/phpmyadmin/config.inc.php and you +will also probably want to skip directory writable check, so set +SETUP_DIR_WRITABLE to false.

      +
      +

      External libraries

      +

      phpMyAdmin includes several external libraries, you might want to +replace them with system ones if they are available, but please note +that you should test whether version you provide is compatible with the +one we ship.

      +

      Currently known list of external libraries:

      +
      +
      js/jquery
      +
      jQuery js framework and various jQuery based libraries.
      +
      libraries/php-gettext
      +
      php-gettext library
      +
      libraries/tcpdf
      +
      tcpdf library, stripped down of not needed files
      +
      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Developers Information

      +

      Next topic

      +

      Copyright

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/phpmyadmin/doc/index.rst b/phpmyadmin/doc/index.rst new file mode 100644 index 000000000..917ddf810 --- /dev/null +++ b/phpmyadmin/doc/index.rst @@ -0,0 +1,32 @@ +.. phpMyAdmin documentation master file, created by + sphinx-quickstart on Wed Sep 26 14:04:48 2012. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to phpMyAdmin's documentation! +====================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + intro + require + setup + config + user + faq + developers + vendors + copyright + credits + glossary + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` +* :ref:`glossary` diff --git a/phpmyadmin/doc/intro.rst b/phpmyadmin/doc/intro.rst new file mode 100644 index 000000000..9d81e44a4 --- /dev/null +++ b/phpmyadmin/doc/intro.rst @@ -0,0 +1,68 @@ +.. _intro: + +Introduction +============ + +phpMyAdmin can manage a whole MySQL server (needs a super-user) as +well as a single database. To accomplish the latter you'll need a +properly set up MySQL user who can read/write only the desired +database. It's up to you to look up the appropriate part in the MySQL +manual. + + +Supported features +------------------ + +Currently phpMyAdmin can: + +* browse and drop databases, tables, views, columns and indexes +* display multiple results sets through stored procedures or queries +* create, copy, drop, rename and alter databases, tables, columns and + indexes +* maintenance server, databases and tables, with proposals on server + configuration +* execute, edit and bookmark any :term:`SQL`-statement, even batch-queries +* load text files into tables +* create [#f1]_ and read dumps of tables +* export [#f1]_ data to various formats: :term:`CSV`, :term:`XML`, :term:`PDF`, + :term:`ISO`/:term:`IEC` 26300 - :term:`OpenDocument` Text and Spreadsheet, Microsoft + Word 2000, and LATEX formats +* import data and :term:`MySQL` structures from :term:`OpenDocument` spreadsheets, as + well as :term:`XML`, :term:`CSV`, and :term:`SQL` files +* administer multiple servers +* manage MySQL users and privileges +* check referential integrity in MyISAM tables +* using Query-by-example (QBE), create complex queries automatically + connecting required tables +* create :term:`PDF` graphics of your + database layout +* search globally in a database or a subset of it +* transform stored data into any format using a set of predefined + functions, like displaying BLOB-data as image or download-link +* track changes on databases, tables and views +* support InnoDB tables and foreign keys see :ref:`faq3_6` +* support mysqli, the improved MySQL extension see :ref:`faq1_17` +* create, edit, call, export and drop stored procedures and functions +* create, edit, export and drop events and triggers +* communicate in `62 different languages + `_ + + +A word about users +------------------ + +Many people have difficulty understanding the concept of user +management with regards to phpMyAdmin. When a user logs in to +phpMyAdmin, that username and password are passed directly to MySQL. +phpMyAdmin does no account management on its own (other than allowing +one to manipulate the MySQL user account information); all users must +be valid MySQL users. + +.. rubric:: Footnotes + +.. [#f1] + + phpMyAdmin can compress (:term:`Zip`, :term:`GZip` :term:`RFC 1952` or + :term:`Bzip2` formats) dumps and :term:`CSV` exports if you use PHP with + :term:`Zlib` support (``--with-zlib``) and/or :term:`Bzip2` support + (``--with-bz2``). Proper support may also need changes in :file:`php.ini`. diff --git a/phpmyadmin/doc/make.bat b/phpmyadmin/doc/make.bat new file mode 100644 index 000000000..19b60901f --- /dev/null +++ b/phpmyadmin/doc/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\phpMyAdmin.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\phpMyAdmin.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/phpmyadmin/doc/other.rst b/phpmyadmin/doc/other.rst new file mode 100644 index 000000000..aa9545121 --- /dev/null +++ b/phpmyadmin/doc/other.rst @@ -0,0 +1,18 @@ +Other sources of information +============================ + +Printed Book +------------ + +The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for +Effective MySQL Management by Marc Delisle. You can get information on that +book and other officially endorsed `books at the phpMyAdmin site`_. + +.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books + +Tutorials +--------- + +Third party tutorials and articles are listed on our `wiki page`_. + +.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles diff --git a/phpmyadmin/doc/privileges.rst b/phpmyadmin/doc/privileges.rst new file mode 100644 index 000000000..0c12932d0 --- /dev/null +++ b/phpmyadmin/doc/privileges.rst @@ -0,0 +1,50 @@ +User management +=============== + +User management is the process of controlling which users are allowed to +connect to the MySQL server and what permissions they have on each database. +phpMyAdmin does not handle user management, rather it passes the username and +password on to MySQL, which then determines whether a user is permitted to +perform a particular action. Within phpMyAdmin, administrators have full +control over creating users, viewing and editing privileges for existing users, +and removing users. + +Within phpMyAdmin, user management is controlled via the :guilabel:`Users` link +from the main page. Users can be created, edited, and removed. + +Creating a new user +------------------- + +To create a new user, click the :guilabel:`Add a new user` link near the bottom +of the :guilabel:`Users` page (you must be a "superuser", e.g., user "root"). +Use the textboxes and drop-downs to configure the user to your particular +needs. You can then select whether to create a database for that user and grant +specific global privileges. Once you've created the user (by clicking Go), you +can define that user's permissions on a specific database (don't grant global +privileges in that case). In general, users do not need any global privileges +(other than USAGE), only permissions for their specific database. + +Editing an existing user +------------------------ + +To edit an existing user, simply click the pencil icon to the right of that +user in the :guilabel:`Users` page. You can then edit their global- and +database-specific privileges, change their password, or even copy those +privileges to a new user. + +Deleting a user +--------------- + +From the :guilabel:`Users` page, check the checkbox for the user you wish to +remove, select whether or not to also remove any databases of the same name (if +they exist), and click Go. + +Assigning privileges to user for a specific database +---------------------------------------------------- + +Users are assigned to databases by editing the user record (from the +:guilabel:`Users` link on the home page) not from within the :guilabel:`Users` +link under the table. If you are creating a user specifically for a given table +you will have to create the user first (with no global privileges) and then go +back and edit that user to add the table and privileges for the individual +table. diff --git a/phpmyadmin/doc/require.rst b/phpmyadmin/doc/require.rst new file mode 100644 index 000000000..1452ee34f --- /dev/null +++ b/phpmyadmin/doc/require.rst @@ -0,0 +1,55 @@ +.. _require: + +Requirements +============ + +Web server +---------- + +Since, phpMyAdmin's interface is based entirely in your browser, you'll need a +web server (such as Apache, :term:`IIS`) to install phpMyAdmin's files into. + +PHP +--- + +* You need PHP 5.2.0 or newer, with ``session`` support, the Standard PHP Library + (SPL) extension and JSON support. + +* To support uploading of ZIP files, you need the PHP ``zip`` extension. + +* For proper support of multibyte strings (eg. UTF-8, which is currently + the default), you should install the ``mbstring`` and ``ctype`` extensions. + +* You need GD2 support in PHP to display inline thumbnails of JPEGs + ("image/jpeg: inline") with their original aspect ratio. + +* When using the cookie authentication (the default), the `mcrypt + `_ extension is strongly suggested for most + users and is **required** for 64–bit machines. Not using mcrypt will + cause phpMyAdmin to load pages significantly slower. + +* To support upload progress bars, see :ref:`faq2_9`. + +* To support XML and Open Document Spreadsheet importing, you need PHP + 5.2.17 or newer and the `libxml `_ + extension. + +.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes` + +Database +-------- + +phpMyAdmin support MySQL compatible databases. + +* MySQL 5.0 or newer +* MariaDB 5.0 or newer +* Drizzle + +.. seealso:: :ref:`faq1_17` + +Web browser +----------- + +To access phpMyAdmin you need a web browser with cookies and javascript +enabled. + diff --git a/phpmyadmin/doc/setup.rst b/phpmyadmin/doc/setup.rst new file mode 100644 index 000000000..850d67a2c --- /dev/null +++ b/phpmyadmin/doc/setup.rst @@ -0,0 +1,424 @@ +.. _setup: + +Installation +============ + +phpMyAdmin does not apply any special security methods to the MySQL +database server. It is still the system administrator's job to grant +permissions on the MySQL databases properly. phpMyAdmin's :guilabel:`Users` +page can be used for this. + +.. warning:: + + :term:`Mac` users should note that if you are on a version before + :term:`Mac OS X`, StuffIt unstuffs with :term:`Mac` formats. So you'll have + to resave as in BBEdit to Unix style ALL phpMyAdmin scripts before + uploading them to your server, as PHP seems not to like :term:`Mac`-style + end of lines character ("``\r``"). + +.. _quick_install: + +Quick Install ++++++++++++++ + +#. Choose an appropriate distribution kit from the phpmyadmin.net + Downloads page. Some kits contain only the English messages, others + contain all languages. We'll assume you chose a kit whose name + looks like ``phpMyAdmin-x.x.x -all-languages.tar.gz``. +#. Untar or unzip the distribution (be sure to unzip the subdirectories): + ``tar -xzvf phpMyAdmin_x.x.x-all-languages.tar.gz`` in your + webserver's document root. If you don't have direct access to your + document root, put the files in a directory on your local machine, + and, after step 4, transfer the directory on your web server using, + for example, ftp. +#. Ensure that all the scripts have the appropriate owner (if PHP is + running in safe mode, having some scripts with an owner different from + the owner of other scripts will be a problem). See :ref:`faq4_2` and + :ref:`faq1_26` for suggestions. +#. Now you must configure your installation. There are two methods that + can be used. Traditionally, users have hand-edited a copy of + :file:`config.inc.php`, but now a wizard-style setup script is provided + for those who prefer a graphical installation. Creating a + :file:`config.inc.php` is still a quick way to get started and needed for + some advanced features. + + +Manualy creating file +--------------------- + +To manually create the file, simply use your text editor to create the +file :file:`config.inc.php` (you can copy :file:`config.sample.inc.php` to get +minimal configuration file) in the main (top-level) phpMyAdmin +directory (the one that contains :file:`index.php`). phpMyAdmin first +loads :file:`libraries/config.default.php` and then overrides those values +with anything found in :file:`config.inc.php`. If the default value is +okay for a particular setting, there is no need to include it in +:file:`config.inc.php`. You'll need a few directives to get going, a +simple configuration may look like this: + +.. code-block:: php + + + + +Or, if you prefer to not be prompted every time you log in: + +.. code-block:: php + + + + +For a full explanation of possible configuration values, see the +:ref:`config` of this document. + +.. index:: Setup script + +.. _setup_script: + +Using Setup script +------------------ + +Instead of manually editing :file:`config.inc.php`, you can use the `Setup +Script `_. First you must manually create a folder ``config`` +in the phpMyAdmin directory. This is a security measure. On a +Linux/Unix system you can use the following commands: + +.. code-block:: sh + + + cd phpMyAdmin + mkdir config # create directory for saving + chmod o+rw config # give it world writable permissions + +And to edit an existing configuration, copy it over first: + +.. code-block:: sh + + + cp config.inc.php config/ # copy current configuration for editing + chmod o+w config/config.inc.php # give it world writable permissions + +On other platforms, simply create the folder and ensure that your web +server has read and write access to it. :ref:`faq1_26` can help with +this. + +Next, open ``setup/`` in your browser. Note that **changes are +not saved to disk until explicitly choose ``Save``** from the +*Configuration* area of the screen. Normally the script saves the new +:file:`config.inc.php` to the ``config/`` directory, but if the webserver does +not have the proper permissions you may see the error "Cannot load or +save configuration." Ensure that the ``config/`` directory exists and +has the proper permissions - or use the ``Download`` link to save the +config file locally and upload (via FTP or some similar means) to the +proper location. + +Once the file has been saved, it must be moved out of the ``config/`` +directory and the permissions must be reset, again as a security +measure: + +.. code-block:: sh + + + mv config/config.inc.php . # move file to current directory + chmod o-rw config.inc.php # remove world read and write permissions + rm -rf config # remove not needed directory + +Now the file is ready to be used. You can choose to review or edit the +file with your favorite editor, if you prefer to set some advanced +options which the setup script does not provide. + +#. If you are using the ``auth_type`` "config", it is suggested that you + protect the phpMyAdmin installation directory because using config + does not require a user to enter a password to access the phpMyAdmin + installation. Use of an alternate authentication method is + recommended, for example with HTTP–AUTH in a :term:`.htaccess` file or switch to using + ``auth_type`` cookie or http. See the :ref:`faqmultiuser` + for additional information, especially :ref:`faq4_4`. +#. Open the `main phpMyAdmin directory `_ in your browser. + phpMyAdmin should now display a welcome screen and your databases, or + a login dialog if using :term:`HTTP` or + cookie authentication mode. +#. You should deny access to the ``./libraries`` and ``./setup/lib`` + subfolders in your webserver configuration. For Apache you can use + supplied :term:`.htaccess` file in that folder, for other webservers, you should + configure this yourself. Such configuration prevents from possible + path exposure and cross side scripting vulnerabilities that might + happen to be found in that code. +#. It is generally good idea to protect public phpMyAdmin installation + against access by robots as they usually can not do anything good + there. You can do this using ``robots.txt`` file in root of your + webserver or limit access by web server configuration, see + :ref:`faq1_42`. + +.. index:: + single: Configuration storage + single: phpMyAdmin configuration storage + single: pmadb + +.. _linked-tables: + +phpMyAdmin configuration storage +++++++++++++++++++++++++++++++++ + +For a whole set of new features (bookmarks, comments, :term:`SQL`-history, +tracking mechanism, :term:`PDF`-generation, column contents transformation, +etc.) you need to create a set of special tables. Those tables can be located +in your own database, or in a central database for a multi-user installation +(this database would then be accessed by the controluser, so no other user +should have rights to it). + +Please look at your ``./examples/`` directory, where you should find a +file called *create\_tables.sql*. (If you are using a Windows server, +pay special attention to :ref:`faq1_23`). + +If you already had this infrastructure and upgraded to MySQL 4.1.2 or +newer, please use :file:`examples/upgrade_tables_mysql_4_1_2+.sql` +and then create new tables by importing +:file:`examples/create_tables.sql`. + +You can use your phpMyAdmin to create the tables for you. Please be +aware that you may need special (administrator) privileges to create +the database and tables, and that the script may need some tuning, +depending on the database name. + +After having imported the :file:`examples/create_tables.sql` file, you +should specify the table names in your :file:`config.inc.php` file. The +directives used for that can be found in the :ref:`config`. You will also need to +have a controluser with the proper rights to those tables (see section +:ref:`authentication_modes` below). + +.. _upgrading: + +Upgrading from an older version ++++++++++++++++++++++++++++++++ + +Simply copy :file:`config.inc.php` from your previous installation into +the newly unpacked one. Configuration files from old versions may +require some tweaking as some options have been changed or removed. +For compatibility with PHP 6, remove a +``set_magic_quotes_runtime(0);`` statement that you might find near +the end of your configuration file. + +You should **not** copy :file:`libraries/config.default.php` over +:file:`config.inc.php` because the default configuration file is version- +specific. + +If you have upgraded your MySQL server from a version previous to 4.1.2 to +version 5.x or newer and if you use the phpMyAdmin configuration storage, you +should run the :term:`SQL` script found in +:file:`examples/upgrade_tables_mysql_4_1_2+.sql`. + +.. index:: Authentication mode + +.. _authentication_modes: + +Using authentication modes +++++++++++++++++++++++++++ + +:term:`HTTP` and cookie authentication modes are recommended in a **multi-user +environment** where you want to give users access to their own database and +don't want them to play around with others. Nevertheless be aware that MS +Internet Explorer seems to be really buggy about cookies, at least till version +6. Even in a **single-user environment**, you might prefer to use :term:`HTTP` +or cookie mode so that your user/password pair are not in clear in the +configuration file. + +:term:`HTTP` and cookie authentication +modes are more secure: the MySQL login information does not need to be +set in the phpMyAdmin configuration file (except possibly for the +:config:option:`$cfg['Servers'][$i]['controluser']`). +However, keep in mind that the password travels in plain text, unless +you are using the HTTPS protocol. In cookie mode, the password is +stored, encrypted with the blowfish algorithm, in a temporary cookie. + +.. note: + + This section is only applicable if your MySQL server is running + with ``--skip-show-database``. + +For ':term:`HTTP`' and 'cookie' modes, phpMyAdmin needs a controluser that has +**only** the ``SELECT`` privilege on the *`mysql`.`user` (all columns except +`Password`)*, *`mysql`.`db` (all columns)*, *`mysql`.`host` (all columns)* and +*`mysql`.`tables\_priv` (all columns except `Grantor` and `Timestamp`)* tables. +You must specify the details for the controluser in the :file:`config.inc.php` +file under the :config:option:`$cfg['Servers'][$i]['controluser']` and +:config:option:`$cfg['Servers'][$i]['controlpass']` settings. The following +example assumes you want to use ``pma`` as the controluser and ``pmapass`` as +the controlpass, but **this is only an example: use something else in your +file!** Input these statements from the phpMyAdmin :term:`SQL` Query window or +mysql command–line client. Of course you have to replace ``localhost`` with the +webserver's host if it's not the same as the MySQL server's one. + +If you want to use the many new relation and bookmark features: (this of +course requires that your :ref:`linked-tables` be set up). + +.. code-block:: mysql + + GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass'; + GRANT SELECT ( + Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv, + Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, + File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, + Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, + Execute_priv, Repl_slave_priv, Repl_client_priv + ) ON mysql.user TO 'pma'@'localhost'; + GRANT SELECT ON mysql.db TO 'pma'@'localhost'; + GRANT SELECT ON mysql.host TO 'pma'@'localhost'; + GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv) + ON mysql.tables_priv TO 'pma'@'localhost'; + +If you want to use the many new relation and bookmark features: + +.. code-block:: mysql + + GRANT SELECT, INSERT, UPDATE, DELETE ON .* TO 'pma'@'localhost'; + +(this of course requires that your phpMyAdmin +configuration storage be set up). + +Then each of the *true* users should be granted a set of privileges +on a set of particular databases. Normally you shouldn't give global +privileges to an ordinary user, unless you understand the impact of those +privileges (for example, you are creating a superuser). +For example, to grant the user *real_user* with all privileges on +the database *user_base*: + +.. code-block:: mysql + + GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password'; + + +What the user may now do is controlled entirely by the MySQL user management +system. With HTTP or cookie authentication mode, you don't need to fill the +user/password fields inside the :config:option:`$cfg['Servers']`. + +.. index:: pair: HTTP; Authentication mode + +HTTP authentication mode +------------------------ + +* Uses :term:`HTTP` Basic authentication + method and allows you to log in as any valid MySQL user. +* Is supported with most PHP configurations. For :term:`IIS` (:term:`ISAPI`) + support using :term:`CGI` PHP see :ref:`faq1_32`, for using with Apache + :term:`CGI` see :ref:`faq1_35`. +* See also :ref:`faq4_4` about not using the :term:`.htaccess` mechanism along with + ':term:`HTTP`' authentication mode. + +.. index:: pair: Cookie; Authentication mode + +.. _cookie: + +Cookie authentication mode +-------------------------- + +* You can use this method as a replacement for the :term:`HTTP` authentication + (for example, if you're running :term:`IIS`). +* Obviously, the user must enable cookies in the browser, but this is + now a requirement for all authentication modes. +* With this mode, the user can truly log out of phpMyAdmin and log in + back with the same username. +* If you want to log in to arbitrary server see :config:option:`$cfg['AllowArbitraryServer']` directive. +* As mentioned in the :ref:`require` section, having the ``mcrypt`` extension will + speed up access considerably, but is not required. + +.. index:: pair: Signon; Authentication mode + +Signon authentication mode +-------------------------- + +* This mode is a convenient way of using credentials from another + application to authenticate to phpMyAdmin. +* The other application has to store login information into session + data. + +.. seealso:: + :config:option:`$cfg['Servers'][$i]['auth_type']`, + :config:option:`$cfg['Servers'][$i]['SignonSession']`, + :config:option:`$cfg['Servers'][$i]['SignonScript']`, + :config:option:`$cfg['Servers'][$i]['SignonURL']` + + +.. index:: pair: Config; Authentication mode + +Config authentication mode +-------------------------- + +* This mode is the less secure one because it requires you to fill the + :config:option:`$cfg['Servers'][$i]['user']` and + :config:option:`$cfg['Servers'][$i]['password']` + fields (and as a result, anyone who can read your :file:`config.inc.php` + can discover your username and password). But you don't need to setup + a "controluser" here: using the :config:option:`$cfg['Servers'][$i]['only_db']` might be enough. +* In the :ref:`faqmultiuser` section, there is an entry explaining how + to protect your configuration file. +* For additional security in this mode, you may wish to consider the + Host authentication :config:option:`$cfg['Servers'][$i]['AllowDeny']['order']` + and :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` configuration directives. +* Unlike cookie and http, does not require a user to log in when first + loading the phpMyAdmin site. This is by design but could allow any + user to access your installation. Use of some restriction method is + suggested, perhaps a :term:`.htaccess` file with the HTTP-AUTH directive or disallowing + incoming HTTP requests at one’s router or firewall will suffice (both + of which are beyond the scope of this manual but easily searchable + with Google). + +.. index:: pair: Swekey; Authentication mode + +.. _swekey: + +Swekey authentication mode +-------------------------- + +The Swekey is a low cost authentication USB key that can be used in +web applications. When Swekey authentication is activated, phpMyAdmin +requires the users's Swekey to be plugged before entering the login +page (currently supported for cookie authentication mode only). Swekey +Authentication is disabled by default. To enable it, add the following +line to :file:`config.inc.php`: + +.. code-block:: php + + $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf'; + +You then have to create the ``swekey.conf`` file that will associate +each user with their Swekey Id. It is important to place this file +outside of your web server's document root (in the example, it is +located in ``/etc``). A self documented sample file is provided in the +``examples`` directory. Feel free to use it with your own users' +information. If you want to purchase a Swekey please visit +`http://phpmyadmin.net/auth\_key `_ +since this link provides funding for phpMyAdmin. + +.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']` + + +Securing your phpMyAdmin installation ++++++++++++++++++++++++++++++++++++++ + +The phpMyAdmin team tries hardly to make the application secure, however there +are always ways to make your installation more secure: + +* remove ``setup`` directory from phpMyAdmin, you will probably not + use it after initial setup +* prevent access to ``libraries`` directory from browser, + as it is not needed, supplied ``.htaccess`` file does this +* properly choose authentication method - :ref:`cookie` + is probably the best choice for shared hosting +* in case you don't want all MySQL users to be able to access + phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them +* consider hiding phpMyAdmin behind authentication proxy, so that + MySQL credentials are not all users need to login diff --git a/phpmyadmin/doc/transformations.rst b/phpmyadmin/doc/transformations.rst new file mode 100644 index 000000000..4c3ce46c9 --- /dev/null +++ b/phpmyadmin/doc/transformations.rst @@ -0,0 +1,138 @@ +.. _transformations: + +Transformations +=============== + +.. _transformationsintro: + +Introduction +++++++++++++ + +To enable transformations, you have to setup the ``column_info`` +table and the proper directives. Please see the :ref:`config` on how to do so. + +You can apply different transformations to the contents of each +column. The transformation will take the content of each column and +transform it with certain rules defined in the selected +transformation. + +Say you have a column 'filename' which contains a filename. Normally +you would see in phpMyAdmin only this filename. Using transformations +you can transform that filename into a HTML link, so you can click +inside of the phpMyAdmin structure on the column's link and will see +the file displayed in a new browser window. Using transformation +options you can also specify strings to append/prepend to a string or +the format you want the output stored in. + +For a general overview of all available transformations and their +options, you can consult your *//transformation\_overview.php* installation. + +For a tutorial on how to effectively use transformations, see our +`Link section `_ on the +official phpMyAdmin homepage. + +.. _transformationshowto: + +Usage ++++++ + +Go to your *tbl\_structure.php* page (i.e. reached through clicking on +the 'Structure' link for a table). There click on "Change" (or change +icon) and there you will see three new fields at the end of the line. +They are called 'MIME-type', 'Browser transformation' and +'Transformation options'. + +* The field 'MIME-type' is a drop-down field. Select the MIME-type that + corresponds to the column's contents. Please note that transformations + are inactive as long as no MIME-type is selected. +* The field 'Browser transformation' is a drop-down field. You can + choose from a hopefully growing amount of pre-defined transformations. + See below for information on how to build your own transformation. + There are global transformations and mimetype-bound transformations. + Global transformations can be used for any mimetype. They will take + the mimetype, if necessary, into regard. Mimetype-bound + transformations usually only operate on a certain mimetype. There are + transformations which operate on the main mimetype (like 'image'), + which will most likely take the subtype into regard, and those who + only operate on a specific subtype (like 'image/jpeg'). You can use + transformations on mimetypes for which the function was not defined + for. There is no security check for you selected the right + transformation, so take care of what the output will be like. +* The field 'Transformation options' is a free-type textfield. You have + to enter transform-function specific options here. Usually the + transforms can operate with default options, but it is generally a + good idea to look up the overview to see which options are necessary. + Much like the ENUM/SET-Fields, you have to split up several options + using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is + because internally the options will be parsed as an array, leaving the + first value the first element in the array, and so forth. If you want + to specify a MIME character set you can define it in the + transformation\_options. You have to put that outside of the pre- + defined options of the specific mime-transform, as the last value of + the set. Use the format "'; charset=XXX'". If you use a transform, for + which you can specify 2 options and you want to append a character + set, enter "'first parameter','second parameter','charset=us-ascii'". + You can, however use the defaults for the parameters: "'','','charset + =us-ascii'". + +.. _transformationsfiles: + +File structure +++++++++++++++ + +All specific transformations for mimetypes are defined through class +files in the directory 'libraries/plugins/transformations/'. Each of +them extends a certain transformation abstract class declared in +libraries/plugins/transformations/abstract. + +They are stored in files to ease up customization and easy adding of +new transformations. + +Because the user cannot enter own mimetypes, it is kept sure that +transformations always work. It makes no sense to apply a +transformation to a mimetype the transform-function doesn't know to +handle. + +There is a file called '*transformations.lib.php*' that provides some +basic functions which can be included by any other transform function. + +The file name convention is ``[Mimetype]_[Subtype]_[Transformation +Name].class.php``, while the abtract class that it extends has the +name ``[Transformation Name]TransformationsPlugin``. All of the +methods that have to be implemented by a transformations plug-in are: + +#. getMIMEType() and getMIMESubtype() in the main class; +#. getName(), getInfo() and applyTransformation() in the abstract class + it extends. + +The getMIMEType(), getMIMESubtype() and getName() methods return the +name of the MIME type, MIME Subtype and transformation accordingly. +getInfo() returns the transformation's description and possible +options it may receive and applyTransformation() is the method that +does the actual work of the transformation plug-in. + +Please see the libraries/plugins/transformations/TEMPLATE and +libraries/plugins/transformations/TEMPLATE\_ABSTRACT files for adding +your own transformation plug-in. You can also generate a new +transformation plug-in (with or without the abstract transformation +class), by using +:file:`libraries/plugins/transformations/generator_plugin.sh` or +:file:`libraries/plugins/transformations/generator_main_class.sh`. + +The applyTransformation() method always gets passed three variables: + +#. **$buffer** - Contains the text inside of the column. This is the + text, you want to transform. +#. **$options** - Contains any user-passed options to a transform + function as an array. +#. **$meta** - Contains an object with information about your column. The + data is drawn from the output of the `mysql\_fetch\_field() + `_ function. This means, all + object properties described on the `manual page + `_ are available in this + variable and can be used to transform a column accordingly to + unsigned/zerofill/not\_null/... properties. The $meta->mimetype + variable contains the original MIME-type of the column (i.e. + 'text/plain', 'image/jpeg' etc.) + diff --git a/phpmyadmin/doc/user.rst b/phpmyadmin/doc/user.rst new file mode 100644 index 000000000..ceaf72332 --- /dev/null +++ b/phpmyadmin/doc/user.rst @@ -0,0 +1,9 @@ +User Guide +========== + +.. toctree:: + :maxdepth: 2 + + transformations + privileges + other diff --git a/phpmyadmin/doc/vendors.rst b/phpmyadmin/doc/vendors.rst new file mode 100644 index 000000000..13d7e550a --- /dev/null +++ b/phpmyadmin/doc/vendors.rst @@ -0,0 +1,34 @@ +Distributing and packaging phpMyAdmin +===================================== + +This document is intended to give advices to people who want to +redistribute phpMyAdmin inside other software package such as Linux +distribution or some all in one package including web server and MySQL +server. + +Generally you can customize some basic aspects (paths to some files and +behavior) in :file:`libraries/vendor_config.php`. + +For example if you want setup script to generate config file in var, change +``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you +will also probably want to skip directory writable check, so set +``SETUP_DIR_WRITABLE`` to false. + +External libraries +------------------ + +phpMyAdmin includes several external libraries, you might want to +replace them with system ones if they are available, but please note +that you should test whether version you provide is compatible with the +one we ship. + +Currently known list of external libraries: + +js/jquery + jQuery js framework and various jQuery based libraries. + +libraries/php-gettext + php-gettext library +libraries/tcpdf + tcpdf library, stripped down of not needed files + diff --git a/phpmyadmin/examples/config.manyhosts.inc.php b/phpmyadmin/examples/config.manyhosts.inc.php new file mode 100644 index 000000000..ad29c3a83 --- /dev/null +++ b/phpmyadmin/examples/config.manyhosts.inc.php @@ -0,0 +1,46 @@ + array( + 'user' => 'root', + 'password' => '', + ), + ); + +/** + * Simple function to show HTML page with given content. + * + * @return void + */ +function show_page($contents) +{ + header('Content-Type: text/html; charset=utf-8'); + echo '' . "\n"; + ?> + + + + + + + phpMyAdmin OpenID signon example + + +' . $_SESSION['PMA_single_signon_message'] . '

      '; + unset($_SESSION['PMA_single_signon_message']); +} +echo $contents; +?> + + + +OpenID:
      + + + +'; + show_page($content); + exit; +} + +/* Grab identifier */ +if (isset($_POST['identifier'])) { + $identifier = $_POST['identifier']; +} else if (isset($_SESSION['identifier'])) { + $identifier = $_SESSION['identifier']; +} else { + $identifier = null; +} + +/* Create OpenID object */ +try { + $o = new OpenID_RelyingParty($returnTo, $realm, $identifier); +} catch (OpenID_Exception $e) { + $contents = "
      \n"; + $contents .= "
      " . $e->getMessage() . "
      \n"; + $contents .= "
      "; + show_page($contents); + exit; +} + +/* Redirect to OpenID provider */ +if (isset($_POST['start'])) { + try { + $authRequest = $o->prepare(); + } catch (OpenID_Exception $e) { + $contents = "
      \n"; + $contents .= "
      " . $e->getMessage() . "
      \n"; + $contents .= "
      "; + show_page($contents); + exit; + } + + $url = $authRequest->getAuthorizeURL(); + + header("Location: $url"); + exit; +} else { + /* Grab query string */ + if (!count($_POST)) { + list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']); + } else { + // I hate php sometimes + $queryString = file_get_contents('php://input'); + } + + /* Check reply */ + $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP); + + $id = $message->get('openid.claimed_id'); + + if (!empty($id) && isset($AUTH_MAP[$id])) { + $_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user']; + $_SESSION['PMA_single_signon_password'] = $AUTH_MAP[$id]['password']; + session_write_close(); + /* Redirect to phpMyAdmin (should use absolute URL here!) */ + header('Location: ../index.php'); + } else { + show_page('

      User not allowed!

      '); + exit; + } +} diff --git a/phpmyadmin/examples/signon-script.php b/phpmyadmin/examples/signon-script.php new file mode 100644 index 000000000..0ef97340d --- /dev/null +++ b/phpmyadmin/examples/signon-script.php @@ -0,0 +1,29 @@ + diff --git a/phpmyadmin/examples/signon.php b/phpmyadmin/examples/signon.php new file mode 100644 index 000000000..6ab9e240a --- /dev/null +++ b/phpmyadmin/examples/signon.php @@ -0,0 +1,65 @@ + 'Signon test'); + $id = session_id(); + /* Close that session */ + session_write_close(); + /* Redirect to phpMyAdmin (should use absolute URL here!) */ + header('Location: ../index.php'); +} else { + /* Show simple form */ + header('Content-Type: text/html; charset=utf-8'); + echo '' . "\n"; + ?> + + + + + + + phpMyAdmin single signon example + + +' . $_SESSION['PMA_single_signon_error_message'] . '

      '; +} +?> +
      +Username:
      +Password:
      +Host: (will use the one from config.inc.php by default)
      +Port: (will use the one from config.inc.php by default)
      + +
      + + + diff --git a/phpmyadmin/examples/swekey.sample.conf b/phpmyadmin/examples/swekey.sample.conf new file mode 100644 index 000000000..ebf1aedf0 --- /dev/null +++ b/phpmyadmin/examples/swekey.sample.conf @@ -0,0 +1,44 @@ +# This is a typical file used to enable Swekey hardware authentication. +# +# To activate the Swekey authentication add the following line to your config.inc.php file. +# $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf'; +# Then rename this file "swekey-pma.conf" and copy it to the /etc directory. +# Add all the Swekey ids you want to grant access to in the file. +# After each Swekey id put the corresponding user name. +# +# If you don't know the id of a Swekey just visit http://www.swekey.com?sel=support +# while your Swekey is connected. +# +# If you need to purchase a Swekey please visit http://phpmyadmin.net/auth_key +# since this link provides funding to PhpMyAdmin. +# + +0000000000000000000000000000763A:root +000000000000000000000000000089E4:steve +0000000000000000000000000000231E:scott + +# +# It is recommended to include the following lines to contact the +# authentication servers in SSL mode. +# + +SERVER_CHECK=https://auth-check-ssl.musbe.net +SERVER_RNDTOKEN=https://auth-rnd-gen-ssl.musbe.net +SERVER_STATUS=https://auth-status-ssl.musbe.net + +# +# The path of the root certificate file used to ensure a secure +# communication with the authentication servers in SSL mode. +# If not specified, will use musbe-ca.crt found in your +# phpMyAdmin/libraries/auth/swekey. +# + +#CA_FILE=/var/http-root/phpmyadmin/libraries/auth/swekey/musbe-ca.crt + +# +# If your server receives many login requests, you can enable the random +# token caching to accelerate the authentication process. +# Token caching is enabled by default. +# + +#ENABLE_TOKEN_CACHE=0 diff --git a/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql b/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql new file mode 100644 index 000000000..df4046a49 --- /dev/null +++ b/phpmyadmin/examples/upgrade_tables_mysql_4_1_2+.sql @@ -0,0 +1,144 @@ +-- ------------------------------------------------------------- +-- SQL Commands to upgrade pmadb for normal phpMyAdmin operation +-- with MySQL 4.1.2 and above. +-- +-- This file is meant for use with MySQL 4.1.2 and above! +-- For older MySQL releases, please use create_tables.sql +-- +-- If you are running one MySQL 4.1.0 or 4.1.1, please create the tables using +-- create_tables.sql, then use this script. +-- +-- Please don't forget to set up the tablenames in config.inc.php +-- + +-- -------------------------------------------------------- + +-- +-- Database : `phpmyadmin` +-- +ALTER DATABASE `phpmyadmin` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; +USE phpmyadmin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__bookmark` +-- +ALTER TABLE `pma__bookmark` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__bookmark` + CHANGE `dbase` `dbase` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__bookmark` + CHANGE `user` `user` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__bookmark` + CHANGE `label` `label` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''; +ALTER TABLE `pma__bookmark` + CHANGE `query` `query` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__column_info` +-- + +ALTER TABLE `pma__column_info` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__column_info` + CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `column_name` `column_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `comment` `comment` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `mimetype` `mimetype` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `transformation` `transformation` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__column_info` + CHANGE `transformation_options` `transformation_options` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__history` +-- +ALTER TABLE `pma__history` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__history` + CHANGE `username` `username` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__history` + CHANGE `db` `db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__history` + CHANGE `table` `table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__history` + CHANGE `sqlquery` `sqlquery` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__pdf_pages` +-- + +ALTER TABLE `pma__pdf_pages` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__pdf_pages` + CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__pdf_pages` + CHANGE `page_descr` `page_descr` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL default ''; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__relation` +-- +ALTER TABLE `pma__relation` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__relation` + CHANGE `master_db` `master_db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__relation` + CHANGE `master_table` `master_table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__relation` + CHANGE `master_field` `master_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__relation` + CHANGE `foreign_db` `foreign_db` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__relation` + CHANGE `foreign_table` `foreign_table` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__relation` + CHANGE `foreign_field` `foreign_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__table_coords` +-- + +ALTER TABLE `pma__table_coords` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__table_coords` + CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__table_coords` + CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pma__table_info` +-- + +ALTER TABLE `pma__table_info` + DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE `pma__table_info` + CHANGE `db_name` `db_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__table_info` + CHANGE `table_name` `table_name` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; +ALTER TABLE `pma__table_info` + CHANGE `display_field` `display_field` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ''; diff --git a/phpmyadmin/export.php b/phpmyadmin/export.php new file mode 100644 index 000000000..c2373e305 --- /dev/null +++ b/phpmyadmin/export.php @@ -0,0 +1,979 @@ + $export_type, + 'single_table' => isset($single_table) + ) +); + +// Backward compatbility +$type = $what; + +// Check export type +if (! isset($export_plugin)) { + PMA_fatalError(__('Bad type!')); +} + +/** + * valid compression methods + */ +$compression_methods = array( + 'zip', + 'gzip', + 'bzip2', +); + +/** + * init and variable checking + */ +$compression = false; +$onserver = false; +$save_on_server = false; +$buffer_needed = false; + +// Is it a quick or custom export? +if ($_REQUEST['quick_or_custom'] == 'quick') { + $quick_export = true; +} else { + $quick_export = false; +} + +if ($_REQUEST['output_format'] == 'astext') { + $asfile = false; +} else { + $asfile = true; + if (in_array($_REQUEST['compression'], $compression_methods)) { + $compression = $_REQUEST['compression']; + $buffer_needed = true; + } + if (($quick_export && ! empty($_REQUEST['quick_export_onserver'])) + || (! $quick_export && ! empty($_REQUEST['onserver'])) + ) { + if ($quick_export) { + $onserver = $_REQUEST['quick_export_onserver']; + } else { + $onserver = $_REQUEST['onserver']; + } + // Will we save dump on server? + $save_on_server = ! empty($cfg['SaveDir']) && $onserver; + } +} + +// Does export require to be into file? +if ($export_plugin->getProperties()->getForceFile() != null && ! $asfile) { + $message = PMA_Message::error( + __('Selected export type has to be saved in file!') + ); + if ($export_type == 'server') { + $active_page = 'server_export.php'; + include 'server_export.php'; + } elseif ($export_type == 'database') { + $active_page = 'db_export.php'; + include 'db_export.php'; + } else { + $active_page = 'tbl_export.php'; + include 'tbl_export.php'; + } + exit(); +} + +// Generate error url and check for needed variables +if ($export_type == 'server') { + $err_url = 'server_export.php?' . PMA_generate_common_url(); +} elseif ($export_type == 'database' && strlen($db)) { + $err_url = 'db_export.php?' . PMA_generate_common_url($db); + // Check if we have something to export + if (isset($table_select)) { + $tables = $table_select; + } else { + $tables = array(); + } +} elseif ($export_type == 'table' && strlen($db) && strlen($table)) { + $err_url = 'tbl_export.php?' . PMA_generate_common_url($db, $table); +} else { + PMA_fatalError(__('Bad parameters!')); +} + +/** + * Increase time limit for script execution and initializes some variables + */ +@set_time_limit($cfg['ExecTimeLimit']); +if (! empty($cfg['MemoryLimit'])) { + @ini_set('memory_limit', $cfg['MemoryLimit']); +} + +// Start with empty buffer +$dump_buffer = ''; +$dump_buffer_len = 0; + +// We send fake headers to avoid browser timeout when buffering +$time_start = time(); + + +/** + * Detect ob_gzhandler + * + * @return bool + */ +function PMA_isGzHandlerEnabled() +{ + return in_array('ob_gzhandler', ob_list_handlers()); +} + +/** + * Detect whether gzencode is needed; it might not be needed if + * the server is already compressing by itself + * + * @return bool Whether gzencode is needed + */ +function PMA_gzencodeNeeded() +{ + if (@function_exists('gzencode') + && ! @ini_get('zlib.output_compression') + // Here, we detect Apache's mod_deflate so we bet that + // this module is active for this instance of phpMyAdmin + // and therefore, will gzip encode the content + && ! (function_exists('apache_get_modules') + && in_array('mod_deflate', apache_get_modules())) + && ! PMA_isGzHandlerEnabled() + ) { + return true; + } else { + return false; + } +} + +/** + * Output handler for all exports, if needed buffering, it stores data into + * $dump_buffer, otherwise it prints thems out. + * + * @param string $line the insert statement + * + * @return bool Whether output succeeded + */ +function PMA_exportOutputHandler($line) +{ + global $time_start, $dump_buffer, $dump_buffer_len, $save_filename; + + // Kanji encoding convert feature + if ($GLOBALS['output_kanji_conversion']) { + $line = PMA_kanji_str_conv( + $line, + $GLOBALS['knjenc'], + isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : '' + ); + } + // If we have to buffer data, we will perform everything at once at the end + if ($GLOBALS['buffer_needed']) { + + $dump_buffer .= $line; + if ($GLOBALS['onfly_compression']) { + + $dump_buffer_len += strlen($line); + + if ($dump_buffer_len > $GLOBALS['memory_limit']) { + if ($GLOBALS['output_charset_conversion']) { + $dump_buffer = PMA_convert_string( + 'utf-8', + $GLOBALS['charset_of_file'], + $dump_buffer + ); + } + // as bzipped + if ($GLOBALS['compression'] == 'bzip2' + && @function_exists('bzcompress') + ) { + $dump_buffer = bzcompress($dump_buffer); + } elseif ($GLOBALS['compression'] == 'gzip' + && PMA_gzencodeNeeded() + ) { + // as a gzipped file + // without the optional parameter level because it bugs + $dump_buffer = gzencode($dump_buffer); + } + if ($GLOBALS['save_on_server']) { + $write_result = @fwrite($GLOBALS['file_handle'], $dump_buffer); + if (! $write_result || ($write_result != strlen($dump_buffer))) { + $GLOBALS['message'] = PMA_Message::error( + __('Insufficient space to save the file %s.') + ); + $GLOBALS['message']->addParam($save_filename); + return false; + } + } else { + echo $dump_buffer; + } + $dump_buffer = ''; + $dump_buffer_len = 0; + } + } else { + $time_now = time(); + if ($time_start >= $time_now + 30) { + $time_start = $time_now; + header('X-pmaPing: Pong'); + } // end if + } + } else { + if ($GLOBALS['asfile']) { + if ($GLOBALS['output_charset_conversion']) { + $line = PMA_convert_string( + 'utf-8', + $GLOBALS['charset_of_file'], + $line + ); + } + if ($GLOBALS['save_on_server'] && strlen($line) > 0) { + $write_result = @fwrite($GLOBALS['file_handle'], $line); + if (! $write_result || ($write_result != strlen($line))) { + $GLOBALS['message'] = PMA_Message::error( + __('Insufficient space to save the file %s.') + ); + $GLOBALS['message']->addParam($save_filename); + return false; + } + $time_now = time(); + if ($time_start >= $time_now + 30) { + $time_start = $time_now; + header('X-pmaPing: Pong'); + } // end if + } else { + // We export as file - output normally + echo $line; + } + } else { + // We export as html - replace special chars + echo htmlspecialchars($line); + } + } + return true; +} // end of the 'PMA_exportOutputHandler()' function + +// Defines the default format. +// For SQL always use \n as MySQL wants this on all platforms. +if ($what == 'sql') { + $crlf = "\n"; +} else { + $crlf = PMA_Util::whichCrlf(); +} + +$output_kanji_conversion = function_exists('PMA_kanji_str_conv') && $type != 'xls'; + +// Do we need to convert charset? +$output_charset_conversion = $asfile + && $GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE + && isset($charset_of_file) && $charset_of_file != 'utf-8' + && $type != 'xls'; + +// Use on the fly compression? +$onfly_compression = $GLOBALS['cfg']['CompressOnFly'] + && ($compression == 'gzip' || $compression == 'bzip2'); +if ($onfly_compression) { + $memory_limit = trim(@ini_get('memory_limit')); + // 2 MB as default + if (empty($memory_limit)) { + $memory_limit = 2 * 1024 * 1024; + } + + if (strtolower(substr($memory_limit, -1)) == 'm') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024; + } elseif (strtolower(substr($memory_limit, -1)) == 'k') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024; + } elseif (strtolower(substr($memory_limit, -1)) == 'g') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024 * 1024; + } else { + $memory_limit = (int)$memory_limit; + } + + // Some of memory is needed for other thins and as treshold. + // Nijel: During export I had allocated (see memory_get_usage function) + // approx 1.2MB so this comes from that. + if ($memory_limit > 1500000) { + $memory_limit -= 1500000; + } + + // Some memory is needed for compression, assume 1/3 + $memory_limit /= 8; +} + +// Generate filename and mime type if needed +if ($asfile) { + $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']); + if ($export_type == 'server') { + if (isset($remember_template)) { + $GLOBALS['PMA_Config']->setUserValue( + 'pma_server_filename_template', + 'Export/file_template_server', + $filename_template + ); + } + } elseif ($export_type == 'database') { + if (isset($remember_template)) { + $GLOBALS['PMA_Config']->setUserValue( + 'pma_db_filename_template', + 'Export/file_template_database', + $filename_template + ); + } + } else { + if (isset($remember_template)) { + $GLOBALS['PMA_Config']->setUserValue( + 'pma_table_filename_template', + 'Export/file_template_table', + $filename_template + ); + } + } + $filename = PMA_Util::expandUserString($filename_template); + // remove dots in filename (coming from either the template or already + // part of the filename) to avoid a remote code execution vulnerability + $filename = PMA_sanitizeFilename($filename, $replaceDots = true); + + // Grab basic dump extension and mime type + // Check if the user already added extension; + // get the substring where the extension would be if it was included + $extension_start_pos = strlen($filename) - strlen( + $export_plugin->getProperties()->getExtension() + ) - 1; + $user_extension = substr($filename, $extension_start_pos, strlen($filename)); + $required_extension = "." . $export_plugin->getProperties()->getExtension(); + if (strtolower($user_extension) != $required_extension) { + $filename .= $required_extension; + } + $mime_type = $export_plugin->getProperties()->getMimeType(); + + // If dump is going to be compressed, set correct mime_type and add + // compression to extension + if ($compression == 'bzip2') { + $filename .= '.bz2'; + $mime_type = 'application/x-bzip2'; + } elseif ($compression == 'gzip') { + $filename .= '.gz'; + $mime_type = 'application/x-gzip'; + } elseif ($compression == 'zip') { + $filename .= '.zip'; + $mime_type = 'application/zip'; + } +} + +// Open file on server if needed +if ($save_on_server) { + $save_filename = PMA_Util::userDir($cfg['SaveDir']) + . preg_replace('@[/\\\\]@', '_', $filename); + unset($message); + if (file_exists($save_filename) + && ((! $quick_export && empty($onserverover)) + || ($quick_export + && $_REQUEST['quick_export_onserverover'] != 'saveitover')) + ) { + $message = PMA_Message::error( + __('File %s already exists on server, change filename or check overwrite option.') + ); + $message->addParam($save_filename); + } else { + if (is_file($save_filename) && ! is_writable($save_filename)) { + $message = PMA_Message::error( + __('The web server does not have permission to save the file %s.') + ); + $message->addParam($save_filename); + } else { + if (! $file_handle = @fopen($save_filename, 'w')) { + $message = PMA_Message::error( + __('The web server does not have permission to save the file %s.') + ); + $message->addParam($save_filename); + } + } + } + if (isset($message)) { + if ($export_type == 'server') { + $active_page = 'server_export.php'; + include 'server_export.php'; + } elseif ($export_type == 'database') { + $active_page = 'db_export.php'; + include 'db_export.php'; + } else { + $active_page = 'tbl_export.php'; + include 'tbl_export.php'; + } + exit(); + } +} + +/** + * Send headers depending on whether the user chose to download a dump file + * or not + */ +if (! $save_on_server) { + if ($asfile) { + // Download + // (avoid rewriting data containing HTML with anchors and forms; + // this was reported to happen under Plesk) + @ini_set('url_rewriter.tags', ''); + $filename = PMA_sanitizeFilename($filename); + + PMA_downloadHeader($filename, $mime_type); + } else { + // HTML + if ($export_type == 'database') { + $num_tables = count($tables); + if ($num_tables == 0) { + $message = PMA_Message::error(__('No tables found in database.')); + $active_page = 'db_export.php'; + include 'db_export.php'; + exit(); + } + } + $backup_cfgServer = $cfg['Server']; + $cfg['Server'] = $backup_cfgServer; + unset($backup_cfgServer); + echo "\n" . '
      ' . "\n"; + //echo '
      ' . "\n";
      +
      +        /**
      +         * Displays a back button with all the $_REQUEST data in the URL
      +         * (store in a variable to also display after the textarea)
      +         */
      +        $back_button = '

      [ $value) { + $back_button .= '&' . urlencode($name) . '=' . urlencode($value); + } + $back_button .= '&repopulate=1">Back ]

      '; + + echo $back_button; + echo '
      ' . "\n" + // remove auto-select for now: there is no way to select + // only a part of the text; anyway, it should obey + // $cfg['TextareaAutoSelect'] + //. ' ' . "\n" + . '
      ' . "\n"; + echo $back_button; + + echo "\n"; + echo '
      ' . "\n"; + echo "\n"; +?> + + diff --git a/phpmyadmin/favicon.ico b/phpmyadmin/favicon.ico new file mode 100644 index 000000000..2352b5fa4 Binary files /dev/null and b/phpmyadmin/favicon.ico differ diff --git a/phpmyadmin/file_echo.php b/phpmyadmin/file_echo.php new file mode 100644 index 000000000..d910b74e2 --- /dev/null +++ b/phpmyadmin/file_echo.php @@ -0,0 +1,71 @@ + 'png', + 'image/svg+xml' => 'svg', + ); + + /* Check whether MIME type is allowed */ + if (! isset($allowed[$_REQUEST['type']])) { + PMA_fatalError(__('Invalid export type')); + } + + /* + * Check file name to match mime type and not contain new lines + * to prevent response splitting. + */ + $extension = $allowed[$_REQUEST['type']]; + $valid_match = '/^[^\n\r]*\.' . $extension . '$/'; + if (! preg_match($valid_match, $_REQUEST['filename'])) { + if (! preg_match('/^[^\n\r]*$/', $_REQUEST['filename'])) { + /* Filename is unsafe, discard it */ + $filename = 'download.' . $extension; + } else { + /* Add extension */ + $filename = $_REQUEST['filename'] . '.' . $extension; + } + } else { + /* Filename from request should be safe here */ + $filename = $_REQUEST['filename']; + } + + /* Decode data */ + if ($extension != 'svg') { + $data = substr($_REQUEST['image'], strpos($_REQUEST['image'], ',') + 1); + $data = base64_decode($data); + } else { + $data = $_REQUEST['image']; + } + + /* Send download header */ + PMA_downloadHeader($filename, $_REQUEST['type'], strlen($data)); + + /* Send data */ + echo $data; + +} else if (isset($_REQUEST['monitorconfig'])) { + /* For monitor chart config export */ + PMA_downloadHeader('monitor.cfg', 'application/force-download'); + echo urldecode($_REQUEST['monitorconfig']); + +} else if (isset($_REQUEST['import'])) { + /* For monitor chart config import */ + header('Content-type: text/plain'); + if (!file_exists($_FILES['file']['tmp_name'])) { + exit(); + } + echo file_get_contents($_FILES['file']['tmp_name']); +} +?> diff --git a/phpmyadmin/gis_data_editor.php b/phpmyadmin/gis_data_editor.php new file mode 100644 index 000000000..229e36bdb --- /dev/null +++ b/phpmyadmin/gis_data_editor.php @@ -0,0 +1,416 @@ +generateParams($_REQUEST['value']) + ); +} + +// Generate Well Known Text +$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '') + ? htmlspecialchars($gis_data['srid']) : 0; +$wkt = $gis_obj->generateWkt($gis_data, 0); +$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0'); +$result = "'" . $wkt . "'," . $srid; + +// Generate PNG or SVG based visualization +$format = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8) + ? 'png' : 'svg'; +$visualizationSettings = array( + 'width' => 450, + 'height' => 300, + 'spatialColumn' => 'wkt' +); +$data = array(array('wkt' => $wkt_with_zero, 'srid' => $srid)); +$visualization = PMA_GIS_visualizationResults( + $data, $visualizationSettings, $format +); +$open_layers = PMA_GIS_visualizationResults($data, $visualizationSettings, 'ol'); + +// If the call is to update the WKT and visualization make an AJAX response +if (isset($_REQUEST['generate']) && $_REQUEST['generate'] == true) { + $extra_data = array( + 'result' => $result, + 'visualization' => $visualization, + 'openLayers' => $open_layers, + ); + $response = PMA_Response::getInstance(); + $response->addJSON($extra_data); + exit; +} + +ob_start(); + +echo '
      '; +echo ''; +echo '
      '; + +echo '

      '; +printf( + __('Value for the column "%s"'), + htmlspecialchars($_REQUEST['field']) +); +echo '

      '; + +echo ''; +// The input field to which the final result should be added +// and corresponding null checkbox +if (isset($_REQUEST['input_name'])) { + echo ''; +} +echo PMA_generate_common_hidden_inputs(); + +echo ''; +echo '
      '; +echo $visualization; +echo '
      '; + +echo '
      '; +echo '
      '; + +echo '
      '; +echo ''; +echo ''; +echo '
      '; + +echo ''; +echo ''; + + +echo ''; +echo '
      '; +echo ''; +echo '    '; +echo ''; +echo ''; +echo '
      '; +echo ''; + +echo ''; +echo '
      '; + +$geom_count = 1; +if ($geom_type == 'GEOMETRYCOLLECTION') { + $geom_count = (isset($gis_data[$geom_type]['geom_count'])) + ? $gis_data[$geom_type]['geom_count'] : 1; + if (isset($gis_data[$geom_type]['add_geom'])) { + $geom_count++; + } + echo ''; +} + +for ($a = 0; $a < $geom_count; $a++) { + + if ($geom_type == 'GEOMETRYCOLLECTION') { + echo '

      '; + echo __("Geometry") . ' ' . ($a + 1) . ': '; + echo '
      '; + if (isset($gis_data[$a]['gis_type'])) { + $type = $gis_data[$a]['gis_type']; + } else { + $type = $gis_types[0]; + } + echo ''; + } else { + $type = $geom_type; + } + + if ($type == 'POINT') { + echo '
      '; + echo __("Point") . ': '; + echo ''; + echo ''; + echo ''; + echo ''; + + } elseif ($type == 'MULTIPOINT' || $type == 'LINESTRING') { + $no_of_points = isset($gis_data[$a][$type]['no_of_points']) + ? $gis_data[$a][$type]['no_of_points'] : 1; + if ($type == 'LINESTRING' && $no_of_points < 2) { + $no_of_points = 2; + } + if ($type == 'MULTIPOINT' && $no_of_points < 1) { + $no_of_points = 1; + } + + if (isset($gis_data[$a][$type]['add_point'])) { + $no_of_points++; + } + echo ''; + + for ($i = 0; $i < $no_of_points; $i++) { + echo '
      '; + printf(__('Point %d'), $i + 1); + echo ': '; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo ''; + + } elseif ($type == 'MULTILINESTRING' || $type == 'POLYGON') { + $no_of_lines = isset($gis_data[$a][$type]['no_of_lines']) + ? $gis_data[$a][$type]['no_of_lines'] : 1; + if ($no_of_lines < 1) { + $no_of_lines = 1; + } + if (isset($gis_data[$a][$type]['add_line'])) { + $no_of_lines++; + } + echo ''; + + for ($i = 0; $i < $no_of_lines; $i++) { + echo '
      '; + if ($type == 'MULTILINESTRING') { + echo __("Linestring") . ' ' . ($i + 1) . ':'; + } else { + if ($i == 0) { + echo __("Outer Ring") . ':'; + } else { + echo __("Inner Ring") . ' ' . $i . ':'; + } + } + + $no_of_points = isset($gis_data[$a][$type][$i]['no_of_points']) + ? $gis_data[$a][$type][$i]['no_of_points'] : 2; + if ($type == 'MULTILINESTRING' && $no_of_points < 2) { + $no_of_points = 2; + } + if ($type == 'POLYGON' && $no_of_points < 4) { + $no_of_points = 4; + } + if (isset($gis_data[$a][$type][$i]['add_point'])) { + $no_of_points++; + } + echo ''; + + for ($j = 0; $j < $no_of_points; $j++) { + echo('
      '); + printf(__('Point %d'), $j + 1); + echo ': '; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo ''; + } + $caption = ($type == 'MULTILINESTRING') + ? __('Add a linestring') + : __('Add an inner ring'); + echo '
      '; + echo ''; + + } elseif ($type == 'MULTIPOLYGON') { + $no_of_polygons = isset($gis_data[$a][$type]['no_of_polygons']) + ? $gis_data[$a][$type]['no_of_polygons'] : 1; + if ($no_of_polygons < 1) { + $no_of_polygons = 1; + } + if (isset($gis_data[$a][$type]['add_polygon'])) { + $no_of_polygons++; + } + echo ''; + + for ($k = 0; $k < $no_of_polygons; $k++) { + echo '
      '; + echo __("Polygon") . ' ' . ($k + 1) . ':'; + $no_of_lines = isset($gis_data[$a][$type][$k]['no_of_lines']) + ? $gis_data[$a][$type][$k]['no_of_lines'] : 1; + if ($no_of_lines < 1) { + $no_of_lines = 1; + } + if (isset($gis_data[$a][$type][$k]['add_line'])) { + $no_of_lines++; + } + echo ''; + + for ($i = 0; $i < $no_of_lines; $i++) { + echo '

      '; + if ($i == 0) { + echo __("Outer Ring") . ':'; + } else { + echo __("Inner Ring") . ' ' . $i . ':'; + } + + $no_of_points = isset($gis_data[$a][$type][$k][$i]['no_of_points']) + ? $gis_data[$a][$type][$k][$i]['no_of_points'] : 4; + if ($no_of_points < 4) { + $no_of_points = 4; + } + if (isset($gis_data[$a][$type][$k][$i]['add_point'])) { + $no_of_points++; + } + echo ''; + + for ($j = 0; $j < $no_of_points; $j++) { + echo '
      '; + printf(__('Point %d'), $j + 1); + echo ': '; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo ''; + } + echo '
      '; + echo ''; + echo '
      '; + } + echo '
      '; + echo ''; + } +} +if ($geom_type == 'GEOMETRYCOLLECTION') { + echo '

      '; + echo ''; +} +echo '
      '; +echo ''; + +echo '
      '; +echo ''; + +echo '
      '; +echo '

      ' . __('Output') . '

      '; +echo '

      '; +echo __( + 'Choose "GeomFromText" from the "Function" column and paste the' + . ' string below into the "Value" field' +); +echo '

      '; +echo ''; +echo '
      '; + +echo '
      '; +echo '
      '; + +PMA_Response::getInstance()->addJSON('gis_editor', ob_get_contents()); +ob_end_clean(); +?> diff --git a/phpmyadmin/import.php b/phpmyadmin/import.php new file mode 100644 index 000000000..9d193ae63 --- /dev/null +++ b/phpmyadmin/import.php @@ -0,0 +1,601 @@ +addParam('[doc@faq1-16]'); + $message->addParam('[/doc]'); + + // so we can obtain the message + $_SESSION['Import_message']['message'] = $message->getDisplay(); + $_SESSION['Import_message']['go_back_url'] = $goto; + + $message->display(); + exit; // the footer is displayed automatically +} + +/** + * Sets globals from $_POST patterns, for import plugins + * We only need to load the selected plugin + */ + +$post_patterns = array( + '/^force_file_/', + '/^'. $format . '_/' +); +foreach (array_keys($_POST) as $post_key) { + foreach ($post_patterns as $one_post_pattern) { + if (preg_match($one_post_pattern, $post_key)) { + $GLOBALS[$post_key] = $_POST[$post_key]; + } + } +} + +// Check needed parameters +PMA_Util::checkParameters(array('import_type', 'format')); + +// We don't want anything special in format +$format = PMA_securePath($format); + +// Import functions +require_once 'libraries/import.lib.php'; + +// Create error and goto url +if ($import_type == 'table') { + $err_url = 'tbl_import.php?' . PMA_generate_common_url($db, $table); + $_SESSION['Import_message']['go_back_url'] = $err_url; + $goto = 'tbl_import.php'; +} elseif ($import_type == 'database') { + $err_url = 'db_import.php?' . PMA_generate_common_url($db); + $_SESSION['Import_message']['go_back_url'] = $err_url; + $goto = 'db_import.php'; +} elseif ($import_type == 'server') { + $err_url = 'server_import.php?' . PMA_generate_common_url(); + $_SESSION['Import_message']['go_back_url'] = $err_url; + $goto = 'server_import.php'; +} else { + if (empty($goto) || !preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) { + if (strlen($table) && strlen($db)) { + $goto = 'tbl_structure.php'; + } elseif (strlen($db)) { + $goto = 'db_structure.php'; + } else { + $goto = 'server_sql.php'; + } + } + if (strlen($table) && strlen($db)) { + $common = PMA_generate_common_url($db, $table); + } elseif (strlen($db)) { + $common = PMA_generate_common_url($db); + } else { + $common = PMA_generate_common_url(); + } + $err_url = $goto . '?' . $common + . (preg_match('@^tbl_[a-z]*\.php$@', $goto) + ? '&table=' . htmlspecialchars($table) + : ''); + $_SESSION['Import_message']['go_back_url'] = $err_url; +} + + +if (strlen($db)) { + PMA_DBI_select_db($db); +} + +@set_time_limit($cfg['ExecTimeLimit']); +if (! empty($cfg['MemoryLimit'])) { + @ini_set('memory_limit', $cfg['MemoryLimit']); +} + +$timestamp = time(); +if (isset($allow_interrupt)) { + $maximum_time = ini_get('max_execution_time'); +} else { + $maximum_time = 0; +} + +// set default values +$timeout_passed = false; +$error = false; +$read_multiply = 1; +$finished = false; +$offset = 0; +$max_sql_len = 0; +$file_to_unlink = ''; +$sql_query = ''; +$sql_query_disabled = false; +$go_sql = false; +$executed_queries = 0; +$run_query = true; +$charset_conversion = false; +$reset_charset = false; +$bookmark_created = false; + +// Bookmark Support: get a query back from bookmark if required +if (! empty($id_bookmark)) { + $id_bookmark = (int)$id_bookmark; + include_once 'libraries/bookmark.lib.php'; + switch ($action_bookmark) { + case 0: // bookmarked query that have to be run + $import_text = PMA_Bookmark_get( + $db, + $id_bookmark, + 'id', + isset($action_bookmark_all) + ); + if (isset($bookmark_variable) && ! empty($bookmark_variable)) { + $import_text = preg_replace( + '|/\*(.*)\[VARIABLE\](.*)\*/|imsU', + '${1}' . PMA_Util::sqlAddSlashes($bookmark_variable) . '${2}', + $import_text + ); + } + + // refresh navigation and main panels + if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $import_text)) { + $GLOBALS['reload'] = true; + } + + // refresh navigation panel only + if (preg_match('/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $import_text)) { + $ajax_reload['reload'] = true; + } + break; + case 1: // bookmarked query that have to be displayed + $import_text = PMA_Bookmark_get($db, $id_bookmark); + if ($GLOBALS['is_ajax_request'] == true) { + $message = PMA_Message::success(__('Showing bookmark')); + $response = PMA_Response::getInstance(); + $response->isSuccess($message->isSuccess()); + $response->addJSON('message', $message); + $response->addJSON('sql_query', $import_text); + $response->addJSON('action_bookmark', $action_bookmark); + exit; + } else { + $run_query = false; + } + break; + case 2: // bookmarked query that have to be deleted + $import_text = PMA_Bookmark_get($db, $id_bookmark); + PMA_Bookmark_delete($db, $id_bookmark); + if ($GLOBALS['is_ajax_request'] == true) { + $message = PMA_Message::success(__('The bookmark has been deleted.')); + $response = PMA_Response::getInstance(); + $response->isSuccess($message->isSuccess()); + $response->addJSON('message', $message); + $response->addJSON('action_bookmark', $action_bookmark); + $response->addJSON('id_bookmark', $id_bookmark); + exit; + } else { + $run_query = false; + $error = true; // this is kind of hack to skip processing the query + } + break; + } +} // end bookmarks reading + +// Do no run query if we show PHP code +if (isset($GLOBALS['show_as_php'])) { + $run_query = false; + $go_sql = true; +} + +// We can not read all at once, otherwise we can run out of memory +$memory_limit = trim(@ini_get('memory_limit')); +// 2 MB as default +if (empty($memory_limit)) { + $memory_limit = 2 * 1024 * 1024; +} +// In case no memory limit we work on 10MB chunks +if ($memory_limit == -1) { + $memory_limit = 10 * 1024 * 1024; +} + +// Calculate value of the limit +if (strtolower(substr($memory_limit, -1)) == 'm') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024; +} elseif (strtolower(substr($memory_limit, -1)) == 'k') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024; +} elseif (strtolower(substr($memory_limit, -1)) == 'g') { + $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024 * 1024; +} else { + $memory_limit = (int)$memory_limit; +} + +// Just to be sure, there might be lot of memory needed for uncompression +$read_limit = $memory_limit / 8; + +// handle filenames +if (isset($_FILES['import_file'])) { + $import_file = $_FILES['import_file']['tmp_name']; +} +if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) { + + // sanitize $local_import_file as it comes from a POST + $local_import_file = PMA_securePath($local_import_file); + + $import_file = PMA_Util::userDir($cfg['UploadDir']) + . $local_import_file; + +} elseif (empty($import_file) || ! is_uploaded_file($import_file)) { + $import_file = 'none'; +} + +// Do we have file to import? + +if ($import_file != 'none' && ! $error) { + // work around open_basedir and other limitations + $open_basedir = @ini_get('open_basedir'); + + // If we are on a server with open_basedir, we must move the file + // before opening it. The doc explains how to create the "./tmp" + // directory + + if (! empty($open_basedir)) { + + $tmp_subdir = (PMA_IS_WINDOWS ? '.\\tmp\\' : 'tmp/'); + + if (is_writable($tmp_subdir)) { + + + $import_file_new = $tmp_subdir . basename($import_file) . uniqid(); + if (move_uploaded_file($import_file, $import_file_new)) { + $import_file = $import_file_new; + $file_to_unlink = $import_file_new; + } + + $size = filesize($import_file); + } + } + + /** + * Handle file compression + * @todo duplicate code exists in File.class.php + */ + $compression = PMA_detectCompression($import_file); + if ($compression === false) { + $message = PMA_Message::error(__('File could not be read')); + $error = true; + } else { + switch ($compression) { + case 'application/bzip2': + if ($cfg['BZipDump'] && @function_exists('bzopen')) { + $import_handle = @bzopen($import_file, 'r'); + } else { + $message = PMA_Message::error( + __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.') + ); + $message->addParam($compression); + $error = true; + } + break; + case 'application/gzip': + if ($cfg['GZipDump'] && @function_exists('gzopen')) { + $import_handle = @gzopen($import_file, 'r'); + } else { + $message = PMA_Message::error( + __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.') + ); + $message->addParam($compression); + $error = true; + } + break; + case 'application/zip': + if ($cfg['ZipDump'] && @function_exists('zip_open')) { + /** + * Load interface for zip extension. + */ + include_once 'libraries/zip_extension.lib.php'; + $result = PMA_getZipContents($import_file); + if (! empty($result['error'])) { + $message = PMA_Message::rawError($result['error']); + $error = true; + } else { + $import_text = $result['data']; + } + } else { + $message = PMA_Message::error( + __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.') + ); + $message->addParam($compression); + $error = true; + } + break; + case 'none': + $import_handle = @fopen($import_file, 'r'); + break; + default: + $message = PMA_Message::error( + __('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.') + ); + $message->addParam($compression); + $error = true; + break; + } + } + // use isset() because zip compression type does not use a handle + if (! $error && isset($import_handle) && $import_handle === false) { + $message = PMA_Message::error(__('File could not be read')); + $error = true; + } +} elseif (! $error) { + if (! isset($import_text) || empty($import_text)) { + $message = PMA_Message::error( + __('No data was received to import. Either no file name was submitted, or the file size exceeded the maximum size permitted by your PHP configuration. See [doc@faq1-16]FAQ 1.16[/doc].') + ); + $error = true; + } +} + +// so we can obtain the message +//$_SESSION['Import_message'] = $message->getDisplay(); + +// Convert the file's charset if necessary +if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_file)) { + if ($charset_of_file != 'utf-8') { + $charset_conversion = true; + } +} elseif (isset($charset_of_file) && $charset_of_file != 'utf8') { + if (PMA_DRIZZLE) { + // Drizzle doesn't support other character sets, + // so we can't fallback to SET NAMES - throw an error + $error = true; + $message = PMA_Message::error( + __('Cannot convert file\'s character set without character set conversion library') + ); + } else { + PMA_DBI_query('SET NAMES \'' . $charset_of_file . '\''); + // We can not show query in this case, it is in different charset + $sql_query_disabled = true; + $reset_charset = true; + } +} + +// Something to skip? +if (! $error && isset($skip)) { + $original_skip = $skip; + while ($skip > 0) { + PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit); + // Disable read progresivity, otherwise we eat all memory! + $read_multiply = 1; + $skip -= $read_limit; + } + unset($skip); +} + +// This array contain the data like numberof valid sql queries in the statement +// and complete valid sql statement (which affected for rows) +$sql_data = array('valid_sql' => array(), 'valid_queries' => 0); + +if (! $error) { + // Check for file existance + include_once "libraries/plugin_interface.lib.php"; + $import_plugin = PMA_getPlugin( + "import", + $format, + 'libraries/plugins/import/', + $import_type + ); + if ($import_plugin == null) { + $error = true; + $message = PMA_Message::error( + __('Could not load import plugins, please check your installation!') + ); + } else { + // Do the real import + $import_plugin->doImport($sql_data); + } +} + +if (! $error && false !== $import_handle && null !== $import_handle) { + fclose($import_handle); +} + +// Cleanup temporary file +if ($file_to_unlink != '') { + unlink($file_to_unlink); +} + +// Reset charset back, if we did some changes +if ($reset_charset) { + PMA_DBI_query('SET CHARACTER SET utf8'); + PMA_DBI_query( + 'SET SESSION collation_connection =\'' . $collation_connection . '\'' + ); +} + +// Show correct message +if (! empty($id_bookmark) && $action_bookmark == 2) { + $message = PMA_Message::success(__('The bookmark has been deleted.')); + $display_query = $import_text; + $error = false; // unset error marker, it was used just to skip processing +} elseif (! empty($id_bookmark) && $action_bookmark == 1) { + $message = PMA_Message::notice(__('Showing bookmark')); +} elseif ($bookmark_created) { + $special_message = '[br]' . sprintf( + __('Bookmark %s created'), + htmlspecialchars($bkm_label) + ); +} elseif ($finished && ! $error) { + if ($import_type == 'query') { + $message = PMA_Message::success(); + } else { + if ($import_notice) { + $message = PMA_Message::success( + '' . __('Import has been successfully finished, %d queries executed.') . '' + ); + $message->addParam($executed_queries); + + $message->addString($import_notice); + if (isset($local_import_file)) { + $message->addString('(' . $local_import_file . ')'); + } else { + $message->addString('(' . $_FILES['import_file']['name'] . ')'); + } + } else { + $message = PMA_Message::success( + __('Import has been successfully finished, %d queries executed.') + ); + $message->addParam($executed_queries); + if (isset($local_import_file)) { + $message->addString('(' . $local_import_file . ')'); + } else { + $message->addString('(' . $_FILES['import_file']['name'] . ')'); + } + } + } +} + +// Did we hit timeout? Tell it user. +if ($timeout_passed) { + $message = PMA_Message::error( + __('Script timeout passed, if you want to finish import, please resubmit same file and import will resume.') + ); + if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) { + $message->addString( + __('However on last run no data has been parsed, this usually means phpMyAdmin won\'t be able to finish this import unless you increase php time limits.') + ); + } +} + +// if there is any message, copy it into $_SESSION as well, +// so we can obtain it by AJAX call +if (isset($message)) { + $_SESSION['Import_message']['message'] = $message->getDisplay(); +} +// Parse and analyze the query, for correct db and table name +// in case of a query typed in the query window +// (but if the query is too large, in case of an imported file, the parser +// can choke on it so avoid parsing) +if (strlen($sql_query) <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { + include_once 'libraries/parse_analyze.lib.php'; +} + +// There was an error? +if (isset($my_die)) { + foreach ($my_die AS $key => $die) { + PMA_Util::mysqlDie( + $die['error'], $die['sql'], '', $err_url, $error + ); + } +} + +// we want to see the results of the last query that returned at least a row +if (! empty($last_query_with_results)) { + // but we want to show intermediate results too + $disp_query = $sql_query; + $disp_message = __('Your SQL query has been executed successfully'); + $sql_query = $last_query_with_results; + $go_sql = true; +} + +if ($go_sql) { + include 'sql.php'; +} else { + $active_page = $goto; + include '' . $goto; +} +?> diff --git a/phpmyadmin/import_status.php b/phpmyadmin/import_status.php new file mode 100644 index 000000000..9b79f3fff --- /dev/null +++ b/phpmyadmin/import_status.php @@ -0,0 +1,105 @@ +=') + && ini_get('session.upload_progress.enabled') +) { + + $sessionupload = array(); + define('UPLOAD_PREFIX', ini_get('session.upload_progress.prefix')); + + session_start(); + foreach ($_SESSION as $key => $value) { + // only copy session-prefixed data + if (substr($key, 0, strlen(UPLOAD_PREFIX)) == UPLOAD_PREFIX) { + $sessionupload[$key] = $value; + } + } + // PMA will kill all variables, so let's use a constant + define('SESSIONUPLOAD', serialize($sessionupload)); + session_write_close(); + + session_name('phpMyAdmin'); + session_id($_COOKIE['phpMyAdmin']); +} + +define('PMA_MINIMUM_COMMON', 1); + +require_once 'libraries/common.inc.php'; +require_once 'libraries/display_import_ajax.lib.php'; + +if (defined('SESSIONUPLOAD')) { + // write sessionupload back into the loaded PMA session + + $sessionupload = unserialize(SESSIONUPLOAD); + foreach ($sessionupload as $key => $value) { + $_SESSION[$key] = $value; + } + + // remove session upload data that are not set anymore + foreach ($_SESSION as $key => $value) { + if (substr($key, 0, strlen(UPLOAD_PREFIX)) == UPLOAD_PREFIX + && ! isset($sessionupload[$key]) + ) { + unset($_SESSION[$key]); + } + } +} + +/** + * Sets globals from $_GET + */ +$get_params = array( + 'message', + 'id' +); +foreach ($get_params as $one_get_param) { + if (isset($_GET[$one_get_param])) { + $GLOBALS[$one_get_param] = $_GET[$one_get_param]; + } +} + +// AJAX requests can't be cached! +PMA_noCacheHeader(); + +// $GLOBALS["message"] is used for asking for an import message +if (isset($GLOBALS["message"]) && $GLOBALS["message"]) { + + header('Content-type: text/html'); + + // wait 0.3 sec before we check for $_SESSION variable, + // which is set inside import.php + usleep(300000); + + // wait until message is available + while ($_SESSION['Import_message']['message'] == null) { + usleep(250000); // 0.25 sec + } + + echo $_SESSION['Import_message']['message']; + echo '
      ' . "\n"; + echo ' [ ' . __('Back') . ' ]' . "\n"; + echo '
      '."\n"; + +} else { + PMA_importAjaxStatus($GLOBALS["id"]); +} +?> diff --git a/phpmyadmin/index.php b/phpmyadmin/index.php new file mode 100644 index 000000000..0e87ccdaf --- /dev/null +++ b/phpmyadmin/index.php @@ -0,0 +1,616 @@ +addJSON( + 'options', + PMA_RecentTable::getInstance()->getHtmlSelectOption() + ); + exit; +} + +if ($GLOBALS['PMA_Config']->isGitRevision()) { + if (isset($_REQUEST['git_revision']) && $GLOBALS['is_ajax_request'] == true) { + PMA_printGitRevision(); + exit; + } + echo '
      '; +} + +// Handles some variables that may have been sent by the calling script +$GLOBALS['db'] = ''; +$GLOBALS['table'] = ''; +$show_query = '1'; + +// Any message to display? +if (! empty($message)) { + echo PMA_Util::getMessage($message); + unset($message); +} + +$common_url_query = PMA_generate_common_url('', ''); + +// when $server > 0, a server has been chosen so we can display +// all MySQL-related information +if ($server > 0) { + include 'libraries/server_common.inc.php'; + include 'libraries/StorageEngine.class.php'; + + // Use the verbose name of the server instead of the hostname + // if a value is set + $server_info = ''; + if (! empty($cfg['Server']['verbose'])) { + $server_info .= htmlspecialchars($cfg['Server']['verbose']); + if ($GLOBALS['cfg']['ShowServerInfo']) { + $server_info .= ' ('; + } + } + if ($GLOBALS['cfg']['ShowServerInfo'] || empty($cfg['Server']['verbose'])) { + $server_info .= PMA_DBI_get_host_info(); + } + if (! empty($cfg['Server']['verbose']) && $GLOBALS['cfg']['ShowServerInfo']) { + $server_info .= ')'; + } + $mysql_cur_user_and_host = PMA_DBI_fetch_value('SELECT USER();'); + + // should we add the port info here? + $short_server_info = (!empty($GLOBALS['cfg']['Server']['verbose']) + ? $GLOBALS['cfg']['Server']['verbose'] + : $GLOBALS['cfg']['Server']['host']); +} + +echo '
      ' . "\n"; +echo '
      '; +if ($server > 0 || count($cfg['Servers']) > 1 +) { + echo '
      '; + echo '

      ' . __('General Settings') . '

      '; + echo '
        '; + + /** + * Displays the MySQL servers choice form + */ + if ($cfg['ServerDefault'] == 0 + || (! $cfg['NavigationDisplayServers'] + && (count($cfg['Servers']) > 1 + || ($server == 0 && count($cfg['Servers']) == 1) + ) + ) + ) { + echo '
      • '; + include_once 'libraries/select_server.lib.php'; + echo PMA_Util::getImage('s_host.png') . " " . PMA_selectServer(true, true); + echo '
      • '; + } + + /** + * Displays the mysql server related links + */ + if ($server > 0 && ! PMA_DRIZZLE) { + include_once 'libraries/check_user_privileges.lib.php'; + + // Logout for advanced authentication + if ($cfg['Server']['auth_type'] != 'config') { + if ($cfg['ShowChgPassword']) { + $conditional_class = 'ajax'; + PMA_printListItem( + PMA_Util::getImage('s_passwd.png') . " " . __('Change password'), + 'li_change_password', + 'user_password.php?' . $common_url_query, + null, + null, + 'change_password_anchor', + "no_bullets", + $conditional_class + ); + } + } // end if + echo '
      • '; + echo '
        ' . "\n" + . PMA_generate_common_hidden_inputs(null, null, 4, 'collation_connection') + . ' ' . "\n" + + . PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_COLLATION, + 'collation_connection', + 'select_collation_connection', + $collation_connection, + true, + 4, + true + ) + . '
        ' . "\n" + . '
      • ' . "\n"; + } // end of if ($server > 0 && !PMA_DRIZZLE) + echo '
      '; + echo '
      '; +} + +echo '
      '; +echo '

      ' . __('Appearance Settings') . '

      '; +echo '
        '; + +// Displays language selection combo +if (empty($cfg['Lang']) && count($GLOBALS['available_languages']) > 1) { + echo '
      • '; + include_once 'libraries/display_select_lang.lib.php'; + echo PMA_Util::getImage('s_lang.png') . " " . PMA_getLanguageSelectorHtml(); + echo '
      • '; +} + +// ThemeManager if available + +if ($GLOBALS['cfg']['ThemeManager']) { + echo '
      • '; + echo PMA_Util::getImage('s_theme.png') . " " + . $_SESSION['PMA_Theme_Manager']->getHtmlSelectBox(); + echo '
      • '; +} +echo '
      • '; +echo PMA_Config::getFontsizeForm(); +echo '
      • '; + +echo '
      '; + +// User preferences + +if ($server > 0) { + echo '
        '; + PMA_printListItem( + PMA_Util::getImage('b_tblops.png')." " .__('More settings'), + 'li_user_preferences', + 'prefs_manage.php?' . $common_url_query, + null, + null, + null, + "no_bullets" + ); + echo '
      '; +} + +echo '
      '; + + +echo '
      '; +echo '
      '; + + +if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) { + + echo '
      '; + echo '

      ' . __('Database server') . '

      '; + echo '
        ' . "\n"; + PMA_printListItem( + __('Server') . ': ' . $server_info, + 'li_server_info' + ); + PMA_printListItem( + __('Server type') . ': ' . PMA_Util::getServerType(), + 'li_server_type' + ); + PMA_printListItem( + __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . ' - ' . PMA_MYSQL_VERSION_COMMENT, + 'li_server_version' + ); + PMA_printListItem( + __('Protocol version') . ': ' . PMA_DBI_get_proto_info(), + 'li_mysql_proto' + ); + PMA_printListItem( + __('User') . ': ' . htmlspecialchars($mysql_cur_user_and_host), + 'li_user_info' + ); + + echo '
      • '; + echo ' ' . __('Server charset') . ': ' + . ' ' + . ' ' . $mysql_charsets_descriptions[$mysql_charset_map['utf-8']] . "\n" + . ' (' . $mysql_charset_map['utf-8'] . ')' . "\n" + . ' ' . "\n" + . '
      • ' . "\n"; + echo '
      '; + echo '
      '; +} + +if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) { + echo '
      '; + echo '

      ' . __('Web server') . '

      '; + echo '
        '; + if ($GLOBALS['cfg']['ShowServerInfo']) { + PMA_printListItem($_SERVER['SERVER_SOFTWARE'], 'li_web_server_software'); + + if ($server > 0) { + $client_version_str = PMA_DBI_get_client_info(); + if (preg_match('#\d+\.\d+\.\d+#', $client_version_str) + && in_array($GLOBALS['cfg']['Server']['extension'], array('mysql', 'mysqli')) + ) { + $client_version_str = 'libmysql - ' . $client_version_str; + } + PMA_printListItem( + __('Database client version') . ': ' . $client_version_str, + 'li_mysql_client_version' + ); + + $php_ext_string = __('PHP extension') . ': ' + . $GLOBALS['cfg']['Server']['extension'] . ' ' + . PMA_Util::showPHPDocu( + 'book.' . $GLOBALS['cfg']['Server']['extension'] . '.php' + ); + PMA_printListItem( + $php_ext_string, + 'li_used_php_extension' + ); + } + } + + if ($cfg['ShowPhpInfo']) { + PMA_printListItem( + __('Show PHP information'), + 'li_phpinfo', + 'phpinfo.php?' . $common_url_query, + null, + '_blank' + ); + } + echo '
      '; + echo '
      '; +} + +echo '
      '; +echo '

      phpMyAdmin

      '; +echo '
        '; +$class = null; +// We rely on CSP to allow access to http://www.phpmyadmin.net, but IE lacks +// support here and does not allow request to http once using https. +if ($GLOBALS['cfg']['VersionCheck'] + && (! $GLOBALS['PMA_Config']->get('is_https') || PMA_USR_BROWSER_AGENT != 'IE') +) { + $class = 'jsversioncheck'; +} +PMA_printListItem( + __('Version information') . ': ' . PMA_VERSION, + 'li_pma_version', + null, + null, + null, + null, + $class +); +PMA_printListItem( + __('Documentation'), + 'li_pma_docs', + PMA_Util::getDocuLink('index'), + null, + '_blank' +); +PMA_printListItem( + __('Wiki'), + 'li_pma_wiki', + PMA_linkURL('http://wiki.phpmyadmin.net/'), + null, + '_blank' +); + +// does not work if no target specified, don't know why +PMA_printListItem( + __('Official Homepage'), + 'li_pma_homepage', + PMA_linkURL('http://www.phpMyAdmin.net/'), + null, + '_blank' +); +PMA_printListItem( + __('Contribute'), + 'li_pma_contribute', + PMA_linkURL('http://www.phpmyadmin.net/home_page/improve.php'), + null, + '_blank' +); +PMA_printListItem( + __('Get support'), + 'li_pma_support', + PMA_linkURL('http://www.phpmyadmin.net/home_page/support.php'), + null, + '_blank' +); +PMA_printListItem( + __('List of changes'), + 'li_pma_changes', + PMA_linkURL('changelog.php'), + null, + '_blank' +); +?> +
      +
      + +
      + +
      + + 1) { + trigger_error( + __('You have enabled mbstring.func_overload in your PHP configuration. This option is incompatible with phpMyAdmin and might cause some data to be corrupted!'), + E_USER_WARNING + ); +} + +/** + * Nijel: mbstring is used for handling multibyte inside parser, so it is good + * to tell user something might be broken without it, see bug #1063149. + */ +if (! @extension_loaded('mbstring')) { + trigger_error( + __('The mbstring PHP extension was not found and you seem to be using a multibyte charset. Without the mbstring extension phpMyAdmin is unable to split strings correctly and it may result in unexpected results.'), + E_USER_WARNING + ); +} + +/** + * Check whether session.gc_maxlifetime limits session validity. + */ +$gc_time = (int)@ini_get('session.gc_maxlifetime'); +if ($gc_time < $GLOBALS['cfg']['LoginCookieValidity'] ) { + trigger_error( + __('Your PHP parameter [a@http://php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime@_blank]session.gc_maxlifetime[/a] is lower than cookie validity configured in phpMyAdmin, because of this, your login will expire sooner than configured in phpMyAdmin.'), + E_USER_WARNING + ); +} + +/** + * Check whether LoginCookieValidity is limited by LoginCookieStore. + */ +if ($GLOBALS['cfg']['LoginCookieStore'] != 0 + && $GLOBALS['cfg']['LoginCookieStore'] < $GLOBALS['cfg']['LoginCookieValidity'] +) { + trigger_error( + __('Login cookie store is lower than cookie validity configured in phpMyAdmin, because of this, your login will expire sooner than configured in phpMyAdmin.'), + E_USER_WARNING + ); +} + +/** + * Check if user does not have defined blowfish secret and it is being used. + */ +if (! empty($_SESSION['auto_blowfish_secret']) + && empty($GLOBALS['cfg']['blowfish_secret']) +) { + trigger_error( + __('The configuration file now needs a secret passphrase (blowfish_secret).'), + E_USER_WARNING + ); +} + +/** + * Check for existence of config directory which should not exist in + * production environment. + */ +if (file_exists('config')) { + trigger_error( + __('Directory [code]config[/code], which is used by the setup script, still exists in your phpMyAdmin directory. You should remove it once phpMyAdmin has been configured.'), + E_USER_WARNING + ); +} + +if ($server > 0) { + $cfgRelation = PMA_getRelationsParam(); + if (! $cfgRelation['allworks'] + && $cfg['PmaNoRelation_DisableWarning'] == false + ) { + $msg = PMA_Message::notice(__('The phpMyAdmin configuration storage is not completely configured, some extended features have been deactivated. To find out why click %shere%s.')); + $msg->addParam( + '', + false + ); + $msg->addParam('', false); + /* Show error if user has configured something, notice elsewhere */ + if (!empty($cfg['Servers'][$server]['pmadb'])) { + $msg->isError(true); + } + $msg->display(); + } // end if +} + +/** + * Warning about different MySQL library and server version + * (a difference on the third digit does not count). + * If someday there is a constant that we can check about mysqlnd, + * we can use it instead of strpos(). + * If no default server is set, PMA_DBI_get_client_info() is not defined yet. + * Drizzle can speak MySQL protocol, so don't warn about version mismatch for + * Drizzle servers. + */ +if (function_exists('PMA_DBI_get_client_info') && !PMA_DRIZZLE) { + $_client_info = PMA_DBI_get_client_info(); + if ($server > 0 + && strpos($_client_info, 'mysqlnd') === false + && substr(PMA_MYSQL_CLIENT_API, 0, 3) != substr(PMA_MYSQL_INT_VERSION, 0, 3) + ) { + trigger_error( + PMA_sanitize( + sprintf( + __('Your PHP MySQL library version %s differs from your MySQL server version %s. This may cause unpredictable behavior.'), + $_client_info, + substr( + PMA_MYSQL_STR_VERSION, + 0, + strpos(PMA_MYSQL_STR_VERSION . '-', '-') + ) + ) + ), + E_USER_NOTICE + ); + } + unset($_client_info); +} + +/** + * Warning about Suhosin + */ +if ($cfg['SuhosinDisableWarning'] == false + && @ini_get('suhosin.request.max_value_length') + // warn about Suhosin only if its simulation mode is not enabled + && @ini_get('suhosin.simulation') == '0' +) { + trigger_error( + sprintf( + __('Server running with Suhosin. Please refer to %sdocumentation%s for possible issues.'), + '[doc@faq1-38]', + '[/doc]' + ), + E_USER_WARNING + ); +} + +/** + * Warning about mcrypt. + */ +if (! function_exists('mcrypt_encrypt') + && ! $GLOBALS['cfg']['McryptDisableWarning'] +) { + PMA_warnMissingExtension('mcrypt'); +} + +/** + * Warning about incomplete translations. + * + * The data file is created while creating release by ./scripts/remove-incomplete-mo + */ +if (file_exists('libraries/language_stats.inc.php')) { + include 'libraries/language_stats.inc.php'; + /* + * This message is intentionally not translated, because we're + * handling incomplete translations here and focus on english + * speaking users. + */ + if (isset($GLOBALS['language_stats'][$lang]) + && $GLOBALS['language_stats'][$lang] < $cfg['TranslationWarningThreshold'] + ) { + trigger_error( + 'You are using an incomplete translation, please help to make it better by contributing.', + E_USER_NOTICE + ); + } +} + +/** + * prints list item for main page + * + * @param string $name displayed text + * @param string $id id, used for css styles + * @param string $url make item as link with $url as target + * @param string $mysql_help_page display a link to MySQL's manual + * @param string $target special target for $url + * @param string $a_id id for the anchor, + * used for jQuery to hook in functions + * @param string $class class for the li element + * @param string $a_class class for the anchor element + * + * @return void + */ +function PMA_printListItem($name, $id = null, $url = null, $mysql_help_page = null, + $target = null, $a_id = null, $class = null, $a_class = null +) { + echo '
    • '; + if (null !== $url) { + echo ''; + } + + echo $name; + + if (null !== $url) { + echo '' . "\n"; + } + if (null !== $mysql_help_page) { + echo PMA_Util::showMySQLDocu('', $mysql_help_page); + } + echo '
    • '; +} +?> diff --git a/phpmyadmin/js/OpenStreetMap.js b/phpmyadmin/js/OpenStreetMap.js new file mode 100644 index 000000000..dbef7b02e --- /dev/null +++ b/phpmyadmin/js/OpenStreetMap.js @@ -0,0 +1 @@ +OpenLayers.Util.OSM={};OpenLayers.Util.OSM.MISSING_TILE_URL="http://www.openstreetmap.org/openlayers/img/404.png";OpenLayers.Util.OSM.originalOnImageLoadError=OpenLayers.Util.onImageLoadError;OpenLayers.Util.onImageLoadError=function(){if(this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)){this.src=OpenLayers.Util.OSM.MISSING_TILE_URL}else{if(this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)){}else{OpenLayers.Util.OSM.originalOnImageLoadError}}};OpenLayers.Layer.OSM.Mapnik=OpenLayers.Class(OpenLayers.Layer.OSM,{initialize:function(d,c){var b=["http://a.tile.openstreetmap.org/${z}/${x}/${y}.png","http://b.tile.openstreetmap.org/${z}/${x}/${y}.png","http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"];c=OpenLayers.Util.extend({numZoomLevels:19,buffer:0,transitionEffect:"resize"},c);var a=[d,b,c];OpenLayers.Layer.OSM.prototype.initialize.apply(this,a)},CLASS_NAME:"OpenLayers.Layer.OSM.Mapnik"});OpenLayers.Layer.OSM.Osmarender=OpenLayers.Class(OpenLayers.Layer.OSM,{initialize:function(d,c){var b=["http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png","http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png","http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"];c=OpenLayers.Util.extend({numZoomLevels:18,buffer:0,transitionEffect:"resize"},c);var a=[d,b,c];OpenLayers.Layer.OSM.prototype.initialize.apply(this,a)},CLASS_NAME:"OpenLayers.Layer.OSM.Osmarender"});OpenLayers.Layer.OSM.CycleMap=OpenLayers.Class(OpenLayers.Layer.OSM,{initialize:function(d,c){var b=["http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png","http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png","http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"];c=OpenLayers.Util.extend({numZoomLevels:19,buffer:0,transitionEffect:"resize"},c);var a=[d,b,c];OpenLayers.Layer.OSM.prototype.initialize.apply(this,a)},CLASS_NAME:"OpenLayers.Layer.OSM.CycleMap"}); \ No newline at end of file diff --git a/phpmyadmin/js/ajax.js b/phpmyadmin/js/ajax.js new file mode 100644 index 000000000..a4d659f14 --- /dev/null +++ b/phpmyadmin/js/ajax.js @@ -0,0 +1 @@ +var AJAX={active:false,source:null,_callback:function(){},_debug:false,$msgbox:null,hash:function(c){c+="";var a=c.length,d=0,b=0;for(;b>6)}d+=(d<<3);d^=(d>>11);d+=(d<<15);return Math.abs(d)},registerOnload:function(b,c){var a="onload_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&console.log("Registered event "+a+" for file "+b);return this},registerTeardown:function(b,c){var a="teardown_"+AJAX.hash(b);$(document).bind(a,c);this._debug&&console.log("Registered event "+a+" for file "+b);return this},fireOnload:function(b){var a="onload_"+AJAX.hash(b);$(document).trigger(a);this._debug&&console.log("Fired event "+a+" for file "+b)},fireTeardown:function(b){var a="teardown_"+AJAX.hash(b);$(document).triggerHandler(a);this._debug&&console.log("Fired event "+a+" for file "+b)},requestHandler:function(d){var b=$(this).attr("href");if(d.shiftKey||d.ctrlKey){return true}else{if($(this).attr("target")){return true}else{if($(this).hasClass("ajax")||$(this).hasClass("disableAjax")){return true}else{if(b&&b.match(/^#/)){return true}else{if(b&&b.match(/^mailto/)){return true}else{if($(this).hasClass("ui-datepicker-next")||$(this).hasClass("ui-datepicker-prev")){return true}}}}}}if(typeof d!="undefined"){d.preventDefault();d.stopImmediatePropagation()}if(AJAX.active==true){return false}AJAX.source=$(this);$("html, body").animate({scrollTop:0},"fast");var e=!!b||false;var c=e?b:$(this).attr("action");var f="ajax_request=true&ajax_page_request=true";if(!e){f+="&"+$(this).serialize()}f+=AJAX.cache.menus.getRequestParam();AJAX._debug&&console.log("Loading: "+c);if(e){AJAX.active=true;AJAX.$msgbox=PMA_ajaxShowMessage();$.get(c,f,AJAX.responseHandler)}else{var a=$(this).data("onsubmit");if(typeof a!=="function"||a.apply(this,[d])){AJAX.active=true;AJAX.$msgbox=PMA_ajaxShowMessage();$.post(c,f,AJAX.responseHandler)}}},responseHandler:function(a){if(a.success){$table_clone=false;PMA_ajaxRemoveMessage(AJAX.$msgbox);if(a._redirect){PMA_ajaxShowMessage(a._redirect,false);AJAX.active=false;return}AJAX.scriptHandler.reset(function(){if(a._reloadNavigation){PMA_reloadNavigation()}if(a._reloadQuerywindow){var b=a._reloadQuerywindow;PMA_querywindow.reload(b.db,b.table,b.sql_query)}if(a._focusQuerywindow){PMA_querywindow.focus(a._focusQuerywindow)}if(a._title){$("title").replaceWith(a._title)}if(a._menu){AJAX.cache.menus.replace(a._menu);AJAX.cache.menus.add(a._menuHash,a._menu)}else{if(a._menuHash){AJAX.cache.menus.replace(AJAX.cache.menus.get(a._menuHash))}}$("body").children().not("#pma_navigation").not("#floating_menubar").not("#goto_pagetop").not("#page_content").not("#selflink").not("#session_debug").remove();if(a.message&&a.message.length>0){$("#page_content").replaceWith("
      "+a.message+"
      ")}if(a._selflink){$("#selflink > a").attr("href",a._selflink)}if(a._scripts){AJAX.scriptHandler.load(a._scripts)}if(a._selflink&&a._scripts&&a._menuHash&&a._params){AJAX.cache.add(a._selflink,a._scripts,a._menuHash,a._params,AJAX.source.attr("rel"))}if(a._params){PMA_commonParams.setAll(a._params)}if(a._displayMessage){$("#page_content").prepend(a._displayMessage)}$("#pma_errors").remove();if(a._errors){$("
      ",{id:"pma_errors"}).insertAfter("#selflink").append(a._errors)}if(typeof AJAX._callback==="function"){AJAX._callback.call()}AJAX._callback=function(){}})}else{PMA_ajaxShowMessage(a.error,false);AJAX.active=false}},scriptHandler:{_scripts:[],_scriptsToBeLoaded:[],_scriptsToBeFired:[],add:function(a,b){this._scripts.push(a);if(b){this._scriptsToBeFired.push(a)}return this},load:function(g){var b=this;b._scriptsToBeLoaded=[];b._scriptsToBeFired=[];for(var d in g){b._scriptsToBeLoaded.push(g[d].name);if(g[d].fire){b._scriptsToBeFired.push(g[d].name)}}var f=[];var e=false;for(var c in b._scriptsToBeLoaded){var a=b._scriptsToBeLoaded[c];if($.inArray(a,b._scripts)==-1){e=true;this.add(a);f.push("scripts[]="+a)}}if(e){$.ajax({url:"js/get_scripts.js.php?"+f.join("&"),cache:true,success:function(){b.done()},dataType:"script"})}else{b.done()}},done:function(){for(var a in this._scriptsToBeFired){AJAX.fireOnload(this._scriptsToBeFired[a])}AJAX.active=false},reset:function(b){for(var a in this._scriptsToBeFired){AJAX.fireTeardown(this._scriptsToBeFired[a])}this._scriptsToBeFired=[];$("a").die("click").live("click",AJAX.requestHandler);$("form").die("submit").live("submit",AJAX.requestHandler);AJAX.cache.update();b()}}};AJAX.registerOnload("functions.js",function(){$("form").not(".ajax").not(".disableAjax").each(function(){if($(this).attr("onsubmit")){$(this).data("onsubmit",this.onsubmit).attr("onsubmit","")}})});AJAX.cache={MAX:6,primer:{},pages:[],current:0,add:function(d,b,f,e,a){if(this.pages.length>AJAX.cache.MAX){for(var c=0;c'+PMA_messages.strInvalidPage+"
      ",false)}else{AJAX.active=true;var a=this.pages[b];AJAX.scriptHandler.reset(function(){$("#page_content").html(a.content);$("#selflink").html(a.selflink);AJAX.cache.menus.replace(AJAX.cache.menus.get(a.menu));PMA_commonParams.setAll(a.params);AJAX.scriptHandler.load(a.scripts);AJAX.cache.current=++b})}},update:function(){var a=this.pages[this.current-1];if(a){a.content=$("#page_content").html()}},menus:{size:function(c){var b=0,a;for(a in c){if(c.hasOwnProperty(a)){b++}}return b},data:{},add:function(e,d){if(this.size(this.data)>AJAX.cache.MAX){var a,c,f=0;for(var b in this.data){if(this.data[b]){if(!f||this.data[b].timestamp.getTime() link[href=favicon\\.ico]").appendTo("head")}}function b(h,i){a=false;if(c){d.location.hash="PMAURL-"+h+":"+i;e()}else{g="PMAURL-"+h+":"+i}}if(d.location.hash.substring(0,8)=="#PMAURL-"){d.location=d.location.hash.substring(d.location.hash.indexOf(":")+1)}else{f(function(){if(g!=""){d.location.hash=g;g="";e()}c=true})}f(function(){f(d).hashchange(function(){if(a===false){a=true}else{if(/^#PMAURL-\d+:/.test(d.location.hash)){var h=d.location.hash.substring(8,d.location.hash.indexOf(":"));AJAX.cache.navigate(h)}}})});return b})(jQuery,window);$(function(){if(AJAX.cache.primer.url){AJAX.cache.menus.add(AJAX.cache.primer.menuHash,$("
      ").append("
      ").append($("#serverinfo").clone()).append($("#topmenucontainer").clone()).html())}$(function(){if(AJAX.cache.primer.url){AJAX.cache.add(AJAX.cache.primer.url,AJAX.cache.primer.scripts,AJAX.cache.primer.menuHash)}})});$("a").live("click",AJAX.requestHandler);$("form").live("submit",AJAX.requestHandler);$(document).ajaxError(function(d,c,b){if(c.status!==0){var e=$.sprintf(PMA_messages.strErrorCode,c.status);var a=$.sprintf(PMA_messages.strErrorText,c.statusText);PMA_ajaxShowMessage('
      '+PMA_messages.strErrorProcessingRequest+"
      "+e+"
      "+a+"
      ",false);AJAX.active=false}}); \ No newline at end of file diff --git a/phpmyadmin/js/canvg/MIT-LICENSE.txt b/phpmyadmin/js/canvg/MIT-LICENSE.txt new file mode 100644 index 000000000..40f19bd70 --- /dev/null +++ b/phpmyadmin/js/canvg/MIT-LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2010-2011 Gabe Lerner (gabelerner@gmail.com) - http://code.google.com/p/canvg/ + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/phpmyadmin/js/canvg/canvg.js b/phpmyadmin/js/canvg/canvg.js new file mode 100644 index 000000000..fcea2ecda --- /dev/null +++ b/phpmyadmin/js/canvg/canvg.js @@ -0,0 +1 @@ +if(!window.console){window.console={};window.console.log=function(a){};window.console.dir=function(a){}}if(!Array.indexOf){Array.prototype.indexOf=function(b){for(var a=0;a]*>/,"");var d=new ActiveXObject("Microsoft.XMLDOM");d.async="false";d.loadXML(c);return d}};b.Property=function(c,e){this.name=c;this.value=e;this.hasValue=function(){return(this.value!=null&&this.value!="")};this.numValue=function(){if(!this.hasValue()){return 0}var f=parseFloat(this.value);if((this.value+"").match(/%$/)){f=f/100}return f};this.valueOrDefault=function(f){if(this.hasValue()){return this.value}return f};this.numValueOrDefault=function(f){if(this.hasValue()){return this.numValue()}return f};var d=this;this.Color={addOpacity:function(g){var h=d.value;if(g!=null&&g!=""){var f=new RGBColor(d.value);if(f.ok){h="rgba("+f.r+", "+f.g+", "+f.b+", "+g+")"}}return new b.Property(d.name,h)}};this.Definition={getDefinition:function(){var f=d.value.replace(/^(url\()?#([^\)]+)\)?$/,"$2");return b.Definitions[f]},isUrl:function(){return d.value.indexOf("url(")==0},getFillStyle:function(g){var f=this.getDefinition();if(f!=null&&f.createGradient){return f.createGradient(b.ctx,g)}if(f!=null&&f.createPattern){return f.createPattern(b.ctx,g)}return null}};this.Length={DPI:function(f){return 96},EM:function(h){var f=12;var g=new b.Property("fontSize",b.Font.Parse(b.ctx.font).fontSize);if(g.hasValue()){f=g.Length.toPixels(h)}return f},toPixels:function(g){if(!d.hasValue()){return 0}var f=d.value+"";if(f.match(/em$/)){return d.numValue()*this.EM(g)}if(f.match(/ex$/)){return d.numValue()*this.EM(g)/2}if(f.match(/px$/)){return d.numValue()}if(f.match(/pt$/)){return d.numValue()*1.25}if(f.match(/pc$/)){return d.numValue()*15}if(f.match(/cm$/)){return d.numValue()*this.DPI(g)/2.54}if(f.match(/mm$/)){return d.numValue()*this.DPI(g)/25.4}if(f.match(/in$/)){return d.numValue()*this.DPI(g)}if(f.match(/%$/)){return d.numValue()*b.ViewPort.ComputeSize(g)}return d.numValue()}};this.Time={toMilliseconds:function(){if(!d.hasValue()){return 0}var f=d.value+"";if(f.match(/s$/)){return d.numValue()*1000}if(f.match(/ms$/)){return d.numValue()}return d.numValue()}};this.Angle={toRadians:function(){if(!d.hasValue()){return 0}var f=d.value+"";if(f.match(/deg$/)){return d.numValue()*(Math.PI/180)}if(f.match(/grad$/)){return d.numValue()*(Math.PI/200)}if(f.match(/rad$/)){return d.numValue()}return d.numValue()*(Math.PI/180)}}};b.Font=new (function(){this.Styles=["normal","italic","oblique","inherit"];this.Variants=["normal","small-caps","inherit"];this.Weights=["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900","inherit"];this.CreateFont=function(l,h,e,k,d,g){var j=g!=null?this.Parse(g):this.CreateFont("","","","","",b.ctx.font);return{fontFamily:d||j.fontFamily,fontSize:k||j.fontSize,fontStyle:l||j.fontStyle,fontWeight:e||j.fontWeight,fontVariant:h||j.fontVariant,toString:function(){return[this.fontStyle,this.fontVariant,this.fontWeight,this.fontSize,this.fontFamily].join(" ")}}};var c=this;this.Parse=function(h){var j={};var k=b.trim(b.compressSpaces(h||"")).split(" ");var l={fontSize:false,fontStyle:false,fontWeight:false,fontVariant:false};var e="";for(var g=0;gthis.x2){this.x2=g}}if(h!=null){if(isNaN(this.y1)||isNaN(this.y2)){this.y1=h;this.y2=h}if(hthis.y2){this.y2=h}}};this.addX=function(g){this.addPoint(g,null)};this.addY=function(g){this.addPoint(null,g)};this.addBoundingBox=function(g){this.addPoint(g.x1,g.y1);this.addPoint(g.x2,g.y2)};this.addQuadraticCurve=function(m,l,h,g,o,n){var k=m+2/3*(h-m);var j=l+2/3*(g-l);var q=k+1/3*(o-m);var p=j+1/3*(n-l);this.addBezierCurve(m,l,k,q,j,p,o,n)};this.addBezierCurve=function(v,u,l,j,q,o,x,w){var m=[v,u],k=[l,j],h=[q,o],g=[x,w];this.addPoint(m[0],m[1]);this.addPoint(g[0],g[1]);for(i=0;i<=1;i++){var y=function(C){return Math.pow(1-C,3)*m[i]+3*Math.pow(1-C,2)*C*k[i]+3*(1-C)*Math.pow(C,2)*h[i]+Math.pow(C,3)*g[i]};var A=6*m[i]-12*k[i]+6*h[i];var B=-3*m[i]+9*k[i]-9*h[i]+3*g[i];var z=3*k[i]-3*m[i];if(B==0){if(A==0){continue}var s=-z/A;if(0=this.tokens.length-1};this.isCommandOrEnd=function(){if(this.isEnd()){return true}return this.tokens[this.i+1].match(/[A-Za-z]/)!=null};this.isRelativeCommand=function(){return this.command==this.command.toLowerCase()};this.getToken=function(){this.i=this.i+1;return this.tokens[this.i]};this.getScalar=function(){return parseFloat(this.getToken())};this.nextCommand=function(){this.previousCommand=this.command;this.command=this.getToken()};this.getPoint=function(){var d=new b.Point(this.getScalar(),this.getScalar());return this.makeAbsolute(d)};this.getAsControlPoint=function(){var d=this.getPoint();this.control=d;return d};this.getAsCurrentPoint=function(){var d=this.getPoint();this.current=d;return d};this.getReflectedControlPoint=function(){if(this.previousCommand.toLowerCase()!="c"&&this.previousCommand.toLowerCase()!="s"){return this.current}var d=new b.Point(2*this.current.x-this.control.x,2*this.current.y-this.control.y);return d};this.makeAbsolute=function(d){if(this.isRelativeCommand()){d.x=this.current.x+d.x;d.y=this.current.y+d.y}return d};this.addMarker=function(d,g){this.addMarkerAngle(d,g==null?null:g.angleTo(d))};this.addMarkerAngle=function(g,d){this.points.push(g);this.angles.push(d)};this.getMarkerPoints=function(){return this.points};this.getMarkerAngles=function(){for(var g=0;g1){q*=Math.sqrt(I);o*=Math.sqrt(I)}var B=(w==n?-1:1)*Math.sqrt(((Math.pow(q,2)*Math.pow(o,2))-(Math.pow(q,2)*Math.pow(P.y,2))-(Math.pow(o,2)*Math.pow(P.x,2)))/(Math.pow(q,2)*Math.pow(P.y,2)+Math.pow(o,2)*Math.pow(P.x,2)));if(isNaN(B)){B=0}var A=new b.Point(B*q*P.y/o,B*-o*P.x/q);var h=new b.Point((K.x+x.x)/2+Math.cos(f)*A.x-Math.sin(f)*A.y,(K.y+x.y)/2+Math.sin(f)*A.x+Math.cos(f)*A.y);var G=function(l){return Math.sqrt(Math.pow(l[0],2)+Math.pow(l[1],2))};var D=function(m,l){return(m[0]*l[0]+m[1]*l[1])/(G(m)*G(l))};var N=function(m,l){return(m[0]*l[1]=1){L=0}if(n==0&&L>0){L=L-2*Math.PI}if(n==1&&L<0){L=L+2*Math.PI}var d=new b.Point(h.x-q*Math.cos((O+L)/2),h.y-o*Math.sin((O+L)/2));J.addMarkerAngle(d,(O+L)/2+(n==0?1:-1)*Math.PI/2);J.addMarkerAngle(x,L+(n==0?1:-1)*Math.PI/2);t.addPoint(x.x,x.y);if(H!=null){var D=q>o?q:o;var E=q>o?1:q/o;var C=q>o?o/q:1;H.translate(h.x,h.y);H.rotate(f);H.scale(E,C);H.arc(0,0,D,O,O+L,1-n);H.scale(1/E,1/C);H.rotate(-f);H.translate(-h.x,-h.y)}}break;case"Z":if(H!=null){H.closePath()}J.current=J.start}}return t};this.getMarkers=function(){var f=this.PathParser.getMarkerPoints();var h=this.PathParser.getMarkerAngles();var g=[];for(var d=0;dthis.maxDuration){if(this.attribute("repeatCount").value=="indefinite"){this.duration=0}else{if(this.attribute("fill").valueOrDefault("remove")=="remove"&&!this.removed){this.removed=true;this.getProperty().value=this.initialValue;return true}else{return false}}}this.duration=this.duration+g;var d=false;if(this.begin255)?255:this.r);this.g=(this.g<0||isNaN(this.g))?0:((this.g>255)?255:this.g);this.b=(this.b<0||isNaN(this.b))?0:((this.b>255)?255:this.b);this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var l=this.r.toString(16);var k=this.g.toString(16);var j=this.b.toString(16);if(l.length==1){l="0"+l}if(k.length==1){k="0"+k}if(j.length==1){j="0"+j}return"#"+l+k+j};this.getHelpXML=function(){var m=new Array();for(var o=0;o "+s.toRGB()+" -> "+s.toHex());q.appendChild(u);q.appendChild(k);p.appendChild(q)}catch(r){}}return p}}; \ No newline at end of file diff --git a/phpmyadmin/js/canvg/flashcanvas.js b/phpmyadmin/js/canvg/flashcanvas.js new file mode 100644 index 000000000..4ae4f5bcb --- /dev/null +++ b/phpmyadmin/js/canvg/flashcanvas.js @@ -0,0 +1 @@ +if(window.ActiveXObject&&!window.CanvasRenderingContext2D){(function(window,document,undefined){var NULL=null;var CANVAS="canvas";var CANVAS_RENDERING_CONTEXT_2D="CanvasRenderingContext2D";var CANVAS_GRADIENT="CanvasGradient";var CANVAS_PATTERN="CanvasPattern";var FLASH_CANVAS="FlashCanvas";var G_VML_CANVAS_MANAGER="G_vmlCanvasManager";var OBJECT_ID_PREFIX="external";var ON_FOCUS="onfocus";var ON_PROPERTY_CHANGE="onpropertychange";var ON_READY_STATE_CHANGE="onreadystatechange";var ON_UNLOAD="onunload";var config=window[FLASH_CANVAS+"Options"]||{};var BASE_URL=config.swfPath||getScriptUrl().replace(/[^\/]+$/,"");var SWF_URL=BASE_URL+"flashcanvas.swf";var INDEX_SIZE_ERR=1;var NOT_SUPPORTED_ERR=9;var INVALID_STATE_ERR=11;var SYNTAX_ERR=12;var TYPE_MISMATCH_ERR=17;var SECURITY_ERR=18;function Lookup(array){for(var i=0,n=array.length;i0){return eval(this._swf.CallFunction(''+commands.join("�")+""))}},_resize:function(width,height){this._executeCommand();this._initialize();if(width>0){this._swf.width=width}if(height>0){this._swf.height=height}this._queue.push(properties.resize,width,height)}};var CanvasGradient=function(ctx){this._ctx=ctx;this.id=ctx._gradientPatternId++};CanvasGradient.prototype={addColorStop:function(offset,color){if(isNaN(offset)||offset<0||offset>1){throwException(INDEX_SIZE_ERR)}this._ctx._queue.push(properties.addColorStop,this.id,offset,color)}};var CanvasPattern=function(ctx){this.id=ctx._gradientPatternId++};var TextMetrics=function(width){this.width=width};var DOMException=function(code){this.code=code;this.message=DOMExceptionNames[code]};DOMException.prototype=new Error;var DOMExceptionNames={1:"INDEX_SIZE_ERR",9:"NOT_SUPPORTED_ERR",11:"INVALID_STATE_ERR",12:"SYNTAX_ERR",17:"TYPE_MISMATCH_ERR",18:"SECURITY_ERR"};function onReadyStateChange(){if(document.readyState==="complete"){document.detachEvent(ON_READY_STATE_CHANGE,onReadyStateChange);var canvases=document.getElementsByTagName(CANVAS);for(var i=0,n=canvases.length;i';canvases[canvasId]=canvas;var swf=canvas.firstChild;spans[canvasId]=canvas.lastChild;var documentContains=document.body.contains;if(documentContains(canvas)){swf.movie=SWF_URL}else{var intervalId=setInterval(function(){if(documentContains(canvas)){clearInterval(intervalId);swf.movie=SWF_URL}},0)}if(document.compatMode==="BackCompat"||!window.XMLHttpRequest){spans[canvasId].style.overflow="hidden"}var ctx=new CanvasRenderingContext2D(canvas,swf);canvas.getContext=function(contextId){return contextId==="2d"?ctx:NULL};canvas.toDataURL=function(type,quality){if((""+type).replace(/[A-Z]+/g,toLowerCase)==="image/jpeg"){ctx._queue.push(properties.toDataURL,type,typeof quality==="number"?quality:"")}else{ctx._queue.push(properties.toDataURL,type)}return ctx._executeCommand()};swf.attachEvent(ON_FOCUS,onFocus);return canvas},saveImage:function(canvas){var swf=canvas.firstChild;swf.saveImage()},setOptions:function(options){},trigger:function(canvasId,type){var canvas=canvases[canvasId];canvas.fireEvent("on"+type)},unlock:function(canvasId,ready){if(lock[canvasId]){--lock[canvasId]}if(ready){var canvas=canvases[canvasId];var swf=canvas.firstChild;var width;var height;setCanvasSize(canvas);width=canvas.width;height=canvas.height;canvas.style.width=width+"px";canvas.style.height=height+"px";if(width>0){swf.width=width}if(height>0){swf.height=height}swf.resize(width,height);canvas.attachEvent(ON_PROPERTY_CHANGE,onPropertyChange);isReady[canvasId]=true}}};function getScriptUrl(){var scripts=document.getElementsByTagName("script");var script=scripts[scripts.length-1];if(document.documentMode>=8){return script.src}else{return script.getAttribute("src",4)}}function getUniqueId(){return Math.random().toString(36).slice(2)||"0"}function encodeXML(str){return(""+str).replace(/&/g,"&").replace(/2){throw new Error("Pie charts can draw only one series")}return BaseChart.prototype.validateColumns.call(this,b)};var TimelineChart=function(a){BaseChart.call(this,a)};TimelineChart.prototype=new BaseChart();TimelineChart.prototype.constructor=TimelineChart;TimelineChart.prototype.validateColumns=function(c){var a=BaseChart.prototype.validateColumns.call(this,c);if(a){var b=c.getColumns();if(b[0].type!=ColumnType.DATE){throw new Error("First column of timeline chart need to be a date column")}}return a};var DataTable=function(){var a=[];var b;this.addColumn=function(e,d){a.push({type:e,name:d})};this.getColumns=function(){return a};this.setData=function(d){b=d;c()};this.getData=function(){return b};var c=function(){if(a.length==0){throw new Error("Set columns first")}var g,f;for(var e=0;ea.length){g.splice(a.length-1,g.length-a.length)}else{if(g.length + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/phpmyadmin/js/codemirror/lib/codemirror.js b/phpmyadmin/js/codemirror/lib/codemirror.js new file mode 100644 index 000000000..5188f162a --- /dev/null +++ b/phpmyadmin/js/codemirror/lib/codemirror.js @@ -0,0 +1 @@ +window.CodeMirror=(function(){function r(a9,a5){var ct={},bG=r.defaults;for(var aX in bG){if(bG.hasOwnProperty(aX)){ct[aX]=(a5&&a5.hasOwnProperty(aX)?a5:bG)[aX]}}var bJ=ak("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em");bJ.setAttribute("wrap","off");bJ.setAttribute("autocorrect","off");bJ.setAttribute("autocapitalize","off");var cp=ak("div",[bJ],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");var cR=ak("div",null,"CodeMirror-scrollbar-inner");var a8=ak("div",[cR],"CodeMirror-scrollbar");var aO=ak("div"),bD=ak("div",null,null,"position: relative; z-index: -1");var bA=ak("pre","\u00a0","CodeMirror-cursor"),bu=ak("pre","\u00a0","CodeMirror-cursor","visibility: hidden");var aT=ak("div",null,null,"position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;");var bU=ak("div",[aT,bA,bu,bD,aO],null,"position: relative; z-index: 0");var bl=ak("div",null,"CodeMirror-gutter-text"),a3=ak("div",[bl],"CodeMirror-gutter");var cM=ak("div",[a3,ak("div",[bU],"CodeMirror-lines")],null,"position: relative");var cC=ak("div",[cM],null,"position: relative");var bH=ak("div",[cC],"CodeMirror-scroll");bH.setAttribute("tabIndex","-1");var a1=ak("div",[cp,a8,bH],"CodeMirror"+(ct.lineWrapping?" CodeMirror-wrap":""));if(a9.appendChild){a9.appendChild(a1)}else{a9(a1)}c8();c1();if(i){bJ.style.width="0px"}if(!m){bH.draggable=true}bU.style.outline="none";if(ct.tabindex!=null){bJ.tabIndex=ct.tabindex}if(ct.autofocus){b1()}if(!ct.gutter&&!ct.lineNumbers){a3.style.display="none"}if(ah){cp.style.height="1px",cp.style.position="absolute"}if(W){a8.style.zIndex=-2;a8.style.visibility="hidden"}else{if(L){a8.style.minWidth="18px"}}var cA=new j(),aU=new j(),dl;var cH,c4=new al([new Q([new J("")])]),df=0,cO;cm();var dt={from:{line:0,ch:0},to:{line:0,ch:0},inverted:false};var cN,bO,bn,bW=0,bz,cT=false,cY=false,cf=false;var cV,cz,aZ,dj,bc,bf,c5;var bB=0,dm=0,cc=0,cd=0;var cw;var b6=db(0),c9=false,bN=true;var bS=false;var c0=null;aP(function(){bj(ct.value||"");cV=false})();var bx=new F();aE(bH,"mousedown",aP(cP));aE(bH,"dblclick",aP(co));aE(bU,"selectstart",f);if(!x){aE(bH,"contextmenu",bp)}aE(bH,"scroll",cE);aE(a8,"scroll",b2);aE(a8,"mousedown",function(){if(cO){setTimeout(b1,0)}});var cD=aE(window,"resize",function(){if(a1.parentNode){cJ(true)}else{cD()}},true);aE(bJ,"keyup",aP(cQ));aE(bJ,"input",bd);aE(bJ,"keydown",aP(cI));aE(bJ,"keypress",aP(bK));aE(bJ,"focus",dr);aE(bJ,"blur",a2);function b5(dv){if(ct.onDragEvent&&ct.onDragEvent(cF,R(dv))){return}ae(dv)}if(ct.dragDrop){aE(bH,"dragstart",a4);aE(bH,"dragenter",b5);aE(bH,"dragover",b5);aE(bH,"drop",aP(aK))}aE(bH,"paste",function(){b1();bd()});aE(bJ,"paste",function(){cf=true;bd()});aE(bJ,"cut",aP(function(){if(!ct.readOnly){bR("")}}));if(ah){aE(cC,"mouseup",function(){if(document.activeElement==bJ){bJ.blur()}b1()})}var c2;try{c2=(document.activeElement==bJ)}catch(cB){}if(c2||ct.autofocus){setTimeout(dr,20)}else{a2()}function bQ(dv){return dv>=0&&dvdv&&dz.y>dx.offsetHeight){dA=dz.y-dx.offsetHeight}if(dw+dx.offsetWidth>dC){dw=dC-dx.offsetWidth}}}dx.style.top=(dA+cX())+"px";dx.style.left=dx.style.right="";if(dD=="right"){dw=cC.clientWidth-dx.offsetWidth;dx.style.right="0px"}else{if(dD=="left"){dw=0}else{if(dD=="middle"){dw=(cC.clientWidth-dx.offsetWidth)/2}}dx.style.left=(dw+bt())+"px"}if(dB){aY(dw,dA,dw+dx.offsetWidth,dA+dx.offsetHeight)}},lineCount:function(){return c4.size},clipPos:bg,getCursor:function(dv){if(dv==null||dv=="head"){dv=dt.inverted}if(dv=="anchor"){dv=!dt.inverted}if(dv=="end"){dv=false}return aa(dv?dt.from:dt.to)},somethingSelected:function(){return !T(dt.from,dt.to)},setCursor:aP(function(dv,dx,dw){if(dx==null&&typeof dv.line=="number"){bv(dv.line,dv.ch,dw)}else{bv(dv,dx,dw)}}),setSelection:aP(function(dx,dw,dv){(dv?bZ:bX)(bg(dx),bg(dw||dx))}),getLine:function(dv){if(bQ(dv)){return db(dv).text}},getLineHandle:function(dv){if(bQ(dv)){return db(dv)}},setLine:aP(function(dv,dw){if(bQ(dv)){ci(dw,{line:dv,ch:0},{line:dv,ch:db(dv).text.length})}}),removeLine:aP(function(dv){if(bQ(dv)){ci("",{line:dv,ch:0},bg({line:dv+1,ch:0}))}}),replaceRange:aP(ci),getRange:function(dx,dw,dv){return dk(bg(dx),bg(dw),dv)},triggerOnKeyDown:aP(cI),execCommand:function(dv){return t[dv](cF)},moveH:aP(da),deleteH:aP(cS),moveV:aP(c3),toggleOverwrite:function(){if(cT){cT=false;bA.className=bA.className.replace(" CodeMirror-overwrite","")}else{cT=true;bA.className+=" CodeMirror-overwrite"}},posFromIndex:function(dw){var dx=0,dv;c4.iter(0,c4.size,function(dy){var dz=dy.text.length+1;if(dz>dw){dv=dw;return true}dw-=dz;++dx});return bg({line:dx,ch:dv})},indexFromPos:function(dw){if(dw.line<0||dw.ch<0){return 0}var dv=dw.ch;c4.iter(0,dw.line,function(dx){dv+=dx.text.length+1});return dv},scrollTo:function(dv,dw){if(dv!=null){bH.scrollLeft=dv}if(dw!=null){a8.scrollTop=bH.scrollTop=dw}cJ([])},getScrollInfo:function(){return{x:bH.scrollLeft,y:a8.scrollTop,height:a8.scrollHeight,width:bH.scrollWidth}},scrollIntoView:function(dw){var dv=dn(dw?bg(dw):dt.inverted?dt.from:dt.to);aY(dv.x,dv.y,dv.x,dv.yBot)},setSize:function(dx,dv){function dw(dy){dy=String(dy);return/^\d+$/.test(dy)?dy+"px":dy}if(dx!=null){a1.style.width=dw(dx)}if(dv!=null){bH.style.height=dw(dv)}cF.refresh()},operation:function(dv){return aP(dv)()},compoundChange:function(dv){return cg(dv)},refresh:function(){cJ(true,null,bW);if(a8.scrollHeight>bW){a8.scrollTop=bW}},getInputField:function(){return bJ},getWrapperElement:function(){return a1},getScrollerElement:function(){return bH},getGutterElement:function(){return a3}};function db(dv){return M(c4,dv)}function br(dw,dv){bf=true;var dx=dv-dw.height;for(var dy=dw;dy;dy=dy.parent){dy.height+=dx}}function ce(dv,dw){if(!dv.styles){dv.highlight(cH,dv.stateAfter=cZ(X(dv)),ct.tabSize)}return dv.getContent(ct.tabSize,dw,ct.lineWrapping)}function bj(dv){var dw={line:0,ch:0};bb(dw,{line:c4.size-1,ch:db(c4.size-1).text.length},h(dv),dw,dw);cV=true}function cu(dw){var dv=[];c4.iter(0,c4.size,function(dx){dv.push(dx.text)});return dv.join(dw||"\n")}function b2(dv){if(Math.abs(a8.scrollTop-bW)>1){bW=bH.scrollTop=a8.scrollTop;cJ([])}}function cE(dv){if(ct.fixedGutter&&a3.style.left!=bH.scrollLeft+"px"){a3.style.left=bH.scrollLeft+"px"}if(Math.abs(bH.scrollTop-bW)>1){bW=bH.scrollTop;if(a8.scrollTop!=bW){a8.scrollTop=bW}cJ([])}if(ct.onScroll){ct.onScroll(cF)}}function cP(dH){bs(ad(dH,"shiftKey"));for(var dB=ar(dH);dB!=a1;dB=dB.parentNode){if(dB.parentNode==cC&&dB!=cM){return}}for(var dB=ar(dH);dB!=a1;dB=dB.parentNode){if(dB.parentNode==bl){if(ct.onGutterClick){ct.onGutterClick(cF,u(bl.childNodes,dB)+dm,dH)}return f(dH)}}var dw=bq(dH);switch(E(dH)){case 3:if(x){bp(dH)}return;case 2:if(dw){bv(dw.line,dw.ch,true)}setTimeout(b1,20);f(dH);return}if(!dw){if(ar(dH)==bH){f(dH)}return}if(!cO){dr()}var dx=+new Date,dK="single";if(bn&&bn.time>dx-400&&T(bn.pos,dw)){dK="triple";f(dH);setTimeout(b1,20);a6(dw.line)}else{if(bO&&bO.time>dx-400&&T(bO.pos,dw)){dK="double";bn={time:dx,pos:dw};f(dH);var dv=bT(dw);bZ(dv.from,dv.to)}else{bO={time:dx,pos:dw}}}function dC(dM){if(m){bH.draggable=false}bz=false;dG();dA();if(Math.abs(dH.clientX-dM.clientX)+Math.abs(dH.clientY-dM.clientY)<10){f(dM);bv(dw.line,dw.ch,true);b1()}}var dL=dw,dz;if(ct.dragDrop&&ac&&!ct.readOnly&&!T(dt.from,dt.to)&&!D(dw,dt.from)&&!D(dt.to,dw)&&dK=="single"){if(m){bH.draggable=true}var dG=aE(document,"mouseup",aP(dC),true);var dA=aE(bH,"drop",aP(dC),true);bz=true;if(bH.dragDrop){bH.dragDrop()}return}f(dH);if(dK=="single"){bv(dw.line,dw.ch,true)}var dJ=dt.from,dy=dt.to;function dE(dN){if(dK=="single"){bZ(bg(dw),dN);return}dJ=bg(dJ);dy=bg(dy);if(dK=="double"){var dM=bT(dN);if(D(dN,dJ)){bZ(dM.from,dy)}else{bZ(dJ,dM.to)}}else{if(dK=="triple"){if(D(dN,dJ)){bZ(dy,bg({line:dN.line,ch:0}))}else{bZ(dJ,bg({line:dN.line+1,ch:0}))}}}}function dI(dM){var dO=bq(dM,true);if(dO&&!T(dO,dL)){if(!cO){dr()}dL=dO;dE(dO);cV=false;var dN=b3();if(dO.line>=dN.to||dO.line-1){setTimeout(aP(function(){b0(dt.to.line,"smart")}),75)}}if(cq(dy,dw)){return}bd()}function cQ(dv){if(ct.onKeyEvent&&ct.onKeyEvent(cF,R(dv))){return}if(ad(dv,"keyCode")==16){cN=null}}function dr(){if(ct.readOnly=="nocursor"){return}if(!cO){if(ct.onFocus){ct.onFocus(cF)}cO=true;if(bH.className.search(/\bCodeMirror-focused\b/)==-1){bH.className+=" CodeMirror-focused"}}aJ();di()}function a2(){if(cO){if(ct.onBlur){ct.onBlur(cF)}cO=false;if(cw){aP(function(){if(cw){cw();cw=null}})()}bH.className=bH.className.replace(" CodeMirror-focused","")}clearInterval(dl);setTimeout(function(){if(!cO){cN=null}},150)}function bb(dB,dA,dz,dw,dv){if(cY){return}var dy=[];c4.iter(dB.line,dA.line+1,function(dC){dy.push(k(dC.text,dC.markedSpans))});if(bx){bx.addChange(dB.line,dz.length,dy);while(bx.done.length>ct.undoDepth){bx.done.shift()}}var dx=Y(e(dy[0]),e(P(dy)),dB.ch,dA.ch,dz);aQ(dB,dA,dx,dw,dv)}function cG(dA,dB){if(!dA.length){return}var dC=dA.pop(),dw=[];for(var dx=dC.length-1;dx>=0;dx-=1){var dz=dC[dx];var dD=[],dv=dz.start+dz.added;c4.iter(dz.start,dv,function(dE){dD.push(k(dE.text,dE.markedSpans))});dw.push({start:dz.start,added:dz.old.length,old:dD});var dy={line:dz.start+dz.old.length-1,ch:C(au(P(dD)),au(P(dz.old)))};aQ({line:dz.start,ch:0},{line:dv-1,ch:db(dv-1).text.length},dz.old,dy,dy)}cV=true;dB.push(dw)}function dq(){cG(bx.done,bx.undone)}function de(){cG(bx.undone,bx.done)}function aQ(dK,dz,dw,dv,dO){if(cY){return}var dN=false,dy=b6.text.length;if(!ct.lineWrapping){c4.iter(dK.line,dz.line+1,function(dP){if(!dP.hidden&&dP.text.length==dy){dN=true;return true}})}if(dK.line!=dz.line||dw.length>1){bf=true}var dI=dz.line-dK.line,dH=db(dK.line),dx=db(dz.line);var dE=P(dw);if(dK.ch==0&&dz.ch==0&&au(dE)==""){var dF=[],dG=null;for(var dL=0,dM=dw.length-1;dL1){c4.remove(dK.line+1,dI-1,c5)}c4.insert(dK.line+1,dF)}}}if(ct.lineWrapping){var dB=Math.max(5,bH.clientWidth/bE()-3);c4.iter(dK.line,dK.line+dw.length,function(dP){if(dP.hidden){return}var dQ=Math.ceil(dP.text.length/dB)||1;if(dQ!=dP.height){br(dP,dQ)}})}else{c4.iter(dK.line,dK.line+dw.length,function(dQ){var dP=dQ.text;if(!dQ.hidden&&dP.length>dy){b6=dQ;dy=dP.length;bN=true;dN=false}});if(dN){c9=true}}df=Math.min(df,dK.line);b8(400);var dD=dw.length-dI-1;aZ.push({from:dK.line,to:dz.line+1,diff:dD});if(ct.onChange){for(var dL=0;dLbH.offsetHeight?dv:false}function aR(dw){var dv=aN();a8.style.display=dv?"block":"none";if(dv){cR.style.height=cC.style.minHeight=dv+"px";a8.style.height=bH.clientHeight+"px";if(dw!=null){a8.scrollTop=bH.scrollTop=dw;if(m){setTimeout(function(){if(a8.scrollTop!=dw){return}a8.scrollTop=dw+(dw?-1:1);a8.scrollTop=dw},0)}}}else{cC.style.minHeight=""}cM.style.top=bB*ch()+"px"}function bY(){b6=db(0);bN=true;var dv=b6.text.length;c4.iter(1,c4.size,function(dx){var dw=dx.text;if(!dx.hidden&&dw.length>dv){dv=dw.length;b6=dx}});c9=false}function ci(dw,dz,dy){dz=bg(dz);if(!dy){dy=dz}else{dy=bg(dy)}dw=h(dw);function dx(dC){if(D(dC,dz)){return dC}if(!D(dy,dC)){return dv}var dA=dC.line+dw.length-(dy.line-dz.line)-1;var dB=dC.ch;if(dC.line==dy.line){dB+=P(dw).length-(dy.ch-(dy.line==dz.line?dz.ch:0))}return{line:dA,ch:dB}}var dv;a0(dw,dz,dy,function(dA){dv=dA;return{from:dx(dt.from),to:dx(dt.to)}});return dv}function bR(dv,dw){a0(h(dv),dt.from,dt.to,function(dx){if(dw=="end"){return{from:dx,to:dx}}else{if(dw=="start"){return{from:dt.from,to:dt.from}}else{return{from:dt.from,to:dx}}}})}function a0(dy,dA,dz,dv){var dx=dy.length==1?dy[0].length+dA.ch:P(dy).length;var dw=dv({line:dA.line+dy.length-1,ch:dx});bb(dA,dz,dy,dw.from,dw.to)}function dk(dA,dz,dy){var dw=dA.line,dv=dz.line;if(dw==dv){return db(dw).text.slice(dA.ch,dz.ch)}var dx=[db(dw).text.slice(dA.ch)];c4.iter(dw+1,dv,function(dB){dx.push(dB.text)});dx.push(db(dv).text.slice(0,dz.ch));return dx.join(dy||"\n")}function cv(dv){return dk(dt.from,dt.to,dv)}function aJ(){if(bS){return}cA.set(ct.pollInterval,function(){cb();if(cO){aJ()}})}function bd(){var dv=false;bS=true;function dw(){var dx=cb();if(!dx&&!dv){dv=true;cA.set(60,dw)}else{bS=false;aJ()}}cA.set(20,dw)}var by="";function cb(){if(!cO||b(bJ)||ct.readOnly){return false}var dw=bJ.value;if(dw==by){return false}if(!cW){ba()}cN=null;var dx=0,dv=Math.min(by.length,dw.length);while(dx1000){bJ.value=by=""}else{by=dw}if(!cW){aW()}cf=false;return true}function c7(dv){if(!T(dt.from,dt.to)){by="";bJ.value=cv();if(cO){aF(bJ)}}else{if(dv){by=bJ.value=""}}}function b1(){if(ct.readOnly!="nocursor"&&(I||document.activeElement!=bJ)){bJ.focus()}}function cL(){var dy=cj();aY(dy.x,dy.y,dy.x,dy.yBot);if(!cO){return}var dw=cC.getBoundingClientRect(),dv=null;if(dy.y+dw.top<0){dv=true}else{if(dy.y+dw.top+ch()>(window.innerHeight||document.documentElement.clientHeight)){dv=false}}if(dv!=null){var dx=bA.style.display=="none";if(dx){bA.style.display="";bA.style.left=dy.x+"px";bA.style.top=(dy.y-bB)+"px"}bA.scrollIntoView(dv);if(dx){bA.style.display="none"}}}function cj(){var dw=dn(dt.inverted?dt.from:dt.to);var dv=ct.lineWrapping?Math.min(dw.x,bU.offsetWidth):dw.x;return{x:dv,y:dw.y,yBot:dw.yBot}}function aY(dw,dy,dv,dx){var dz=bm(dw,dy,dv,dx);if(dz.scrollLeft!=null){bH.scrollLeft=dz.scrollLeft}if(dz.scrollTop!=null){a8.scrollTop=bH.scrollTop=dz.scrollTop}}function bm(dy,dF,dw,dE){var dB=bt(),dK=cX();dF+=dK;dE+=dK;dy+=dB;dw+=dB;var dH=bH.clientHeight,dz=a8.scrollTop,dJ={};var dx=aN()||Infinity;var dv=dFdx-10;if(dFdz+dH){dJ.scrollTop=(dD?dx:dE)-dH}}var dG=bH.clientWidth,dI=bH.scrollLeft;var dC=ct.fixedGutter?a3.clientWidth:0;var dA=dydG+dI-3){dJ.scrollLeft=dw+10-dG}}return dJ}function b3(dz){var dv=ch(),dy=(dz!=null?dz:a8.scrollTop)-cX();var dx=Math.max(0,Math.floor(dy/dv));var dw=Math.ceil((dy+bH.clientHeight)/dv);return{from:af(c4,dx),to:af(c4,dw)}}function cJ(dE,dA,dy){if(!bH.clientWidth){dm=cc=bB=0;return}var dz=b3(dy);if(dE!==true&&dE.length==0&&dz.from>dm&&dz.todG&&cc-dG<20){dG=Math.min(c4.size,cc)}var dI=dE===true?[]:cs([{from:dm,to:cc,domStart:0}],dE);var dD=0;for(var dB=0;dBdG){dC.to=dG}if(dC.from>=dC.to){dI.splice(dB--,1)}else{dD+=dC.to-dC.from}}if(dD==dG-dF&&dF==dm&&dG==cc){aR(dy);return}dI.sort(function(dK,dJ){return dK.domStart-dJ.domStart});var dx=ch(),dv=a3.style.display;aO.style.display="none";be(dF,dG,dI);aO.style.display=a3.style.display="";var dw=dF!=dm||dG!=cc||cd!=bH.clientHeight+dx;if(dw){cd=bH.clientHeight+dx}if(dF!=dm||dG!=cc&&ct.onViewportChange){setTimeout(function(){if(ct.onViewportChange){ct.onViewportChange(cF,dF,dG)}})}dm=dF;cc=dG;bB=a(c4,dF);b8(100);if(aO.childNodes.length!=cc-dm){throw new Error("BAD PATCH! "+JSON.stringify(dI)+" size="+(cc-dm)+" nodes="+aO.childNodes.length)}function dH(){var dK=aO.firstChild,dJ=false;c4.iter(dm,cc,function(dM){if(!dK){return}if(!dM.hidden){var dL=Math.round(dK.offsetHeight/dx)||1;if(dM.height!=dL){br(dM,dL);bf=dJ=true}}dK=dK.nextSibling});return dJ}if(ct.lineWrapping){dH()}a3.style.display=dv;if(dw||bf){a7()&&ct.lineWrapping&&dH()&&a7()}aR(dy);ds();if(!dA&&ct.onUpdate){ct.onUpdate(cF)}return true}function cs(dE,dC){for(var dz=0,dx=dC.length||0;dz=dA.to){dv.push(dA)}else{if(dB.from>dA.from){dv.push({from:dA.from,to:dB.from,domStart:dA.domStart})}if(dB.todz){dx=dv(dx);dz++}for(var dy=0,dC=dF.to-dF.from;dydy){if(dH.hidden){var dI=ak("pre")}else{var dI=ce(dH);if(dH.className){dI.className=dH.className}if(dH.bgClassName){var dJ=ak("pre","\u00a0",dH.bgClassName,"position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");dI=ak("div",[dJ,dI],null,"position: relative")}}aO.insertBefore(dI,dx)}else{dx=dx.nextSibling}++dy})}function a7(){if(!ct.gutter&&!ct.lineNumbers){return}var dw=cM.offsetHeight,dE=bH.clientHeight;a3.style.height=(dw-dE<2?dE:dw)+"px";var dC=document.createDocumentFragment(),dA=dm,dD;c4.iter(dm,Math.max(cc,dm+1),function(dG){if(dG.hidden){dC.appendChild(ak("pre"))}else{var dF=dG.gutterMarker;var dJ=ct.lineNumbers?ct.lineNumberFormatter(dA+ct.firstLineNumber):null;if(dF&&dF.text){dJ=dF.text.replace("%N%",dJ!=null?dJ:"")}else{if(dJ==null){dJ="\u00a0"}}var dI=dC.appendChild(ak("pre",null,dF&&dF.style));dI.innerHTML=dJ;for(var dH=1;dH2;bU.style.marginLeft=a3.offsetWidth+"px";bf=false;return dB}function ds(){var dy=T(dt.from,dt.to);var dJ=dn(dt.from,true);var dE=dy?dJ:dn(dt.to,true);var dC=dt.inverted?dJ:dE,dw=ch();var dv=B(a1),dx=B(aO);cp.style.top=Math.max(0,Math.min(bH.offsetHeight,dC.y+dx.top-dv.top))+"px";cp.style.left=Math.max(0,Math.min(bH.offsetWidth,dC.x+dx.left-dv.left))+"px";if(dy||ct.showCursorWhenSelecting){bA.style.top=dC.y+"px";bA.style.left=(ct.lineWrapping?Math.min(dC.x,bU.offsetWidth):dC.x)+"px";bA.style.display=""}else{bA.style.display="none"}if(!dy){var dH=dJ.y==dE.y,dB=document.createDocumentFragment();var dF=bU.clientWidth||bU.offsetWidth;var dA=bU.clientHeight||bU.offsetHeight;var dI=function(dO,dN,dM,dK){var dL=n?"width: "+(!dM?dF:dF-dM-dO)+"px":"right: "+(dM-1)+"px";dB.appendChild(ak("div",null,"CodeMirror-selected","position: absolute; left: "+dO+"px; top: "+dN+"px; "+dL+"; height: "+dK+"px"))};if(dt.from.ch&&dJ.y>=0){var dG=dH?dF-dE.x:0;dI(dJ.x,dJ.y,dG,dw)}var dz=Math.max(0,dJ.y+(dt.from.ch?dw:0));var dD=Math.min(dE.y,dA)-dz;if(dD>0.2*dw){dI(0,dz,0,dD)}if((!dH||!dt.from.ch)&&dE.ydx||dE>dB.text.length){dE=dB.text.length}return{line:dF,ch:dE}}dF+=dD}}var dv=db(dA.line);var dy=dA.ch==dv.text.length&&dA.ch!=dx;if(!dv.hidden){return dA}if(dA.line>=dw){return dz(1)||dz(-1)}else{return dz(-1)||dz(1)}}function bv(dv,dx,dw){var dy=bg({line:dv,ch:dx||0});(dw?bZ:bX)(dy,dy)}function cr(dv){return Math.max(0,Math.min(dv,c4.size-1))}function bg(dx){if(dx.line<0){return{line:0,ch:0}}if(dx.line>=c4.size){return{line:c4.size-1,ch:db(c4.size-1).text.length}}var dv=dx.ch,dw=db(dx.line).text.length;if(dv==null||dv>dw){return{line:dx.line,ch:dw}}else{if(dv<0){return{line:dx.line,ch:0}}else{return dx}}}function cU(dy,dC){var dz=dt.inverted?dt.from:dt.to,dD=dz.line,dv=dz.ch;var dB=db(dD);function dw(){for(var dE=dD+dy,dG=dy<0?-1:c4.size;dE!=dG;dE+=dy){var dF=db(dE);if(!dF.hidden){dD=dE;dB=dF;return true}}}function dA(dE){if(dv==(dy<0?0:dB.text.length)){if(!dE&&dw()){dv=dy<0?dB.text.length:0}else{return false}}else{dv+=dy}return true}if(dC=="char"){dA()}else{if(dC=="column"){dA(true)}else{if(dC=="word"){var dx=false;for(;;){if(dy<0){if(!dA()){break}}if(N(dB.text.charAt(dv))){dx=true}else{if(dx){if(dy<0){dy=1;dA()}break}}if(dy>0){if(!dA()){break}}}}}}return{line:dD,ch:dv}}function da(dv,dw){var dx=dv<0?dt.from:dt.to;if(cN||T(dt.from,dt.to)){dx=cU(dv,dw)}bv(dx.line,dx.ch,true)}function cS(dv,dw){if(!T(dt.from,dt.to)){ci("",dt.from,dt.to)}else{if(dv<0){ci("",cU(dv,dw),dt.to)}else{ci("",dt.from,cU(dv,dw))}}cz=true}function c3(dw,dy){var dA=0,dB=dn(dt.inverted?dt.from:dt.to,true);if(c0!=null){dB.x=c0}if(dy=="page"){var dv=Math.min(bH.clientHeight,window.innerHeight||document.documentElement.clientHeight);var dz=b9(dB.x,dB.y+dv*dw)}else{if(dy=="line"){var dx=ch();var dz=b9(dB.x,dB.y+0.5*dx+dw*dx)}}if(dy=="page"){a8.scrollTop+=dn(dz,true).y-dB.y}bv(dz.line,dz.ch,true);c0=dB.x}function bT(dA){var dy=db(dA.line).text;var dz=dA.ch,dx=dA.ch;if(dy){if(dA.after===false||dx==dy.length){--dz}else{++dx}var dw=dy.charAt(dz);var dv=N(dw)?N:/\s/.test(dw)?function(dB){return/\s/.test(dB)}:function(dB){return !/\s/.test(dB)&&N(dB)};while(dz>0&&dv(dy.charAt(dz-1))){--dz}while(dx=dz.ch)){dy.push(dx.marker)}}}return dy}function cn(dv,dx,dw){if(typeof dv=="number"){dv=db(cr(dv))}dv.gutterMarker={text:dx,style:dw};bf=true;return dv}function aS(dv){if(typeof dv=="number"){dv=db(cr(dv))}dv.gutterMarker=null;bf=true}function bk(dw,dy){var dx=dw,dv=dw;if(typeof dw=="number"){dv=db(cr(dw))}else{dx=X(dw)}if(dx==null){return null}if(dy(dv,dx)){aZ.push({from:dx,to:dx+1})}else{return null}return dv}function bI(dw,dv,dx){return bk(dw,function(dy){if(dy.className!=dv||dy.bgClassName!=dx){dy.className=dv;dy.bgClassName=dx;return true}})}function dg(dw,dv){return bk(dw,function(dx,dA){if(dx.hidden!=dv){dx.hidden=dv;if(!ct.lineWrapping){if(dv&&dx.text.length==b6.text.length){c9=true}else{if(!dv&&dx.text.length>b6.text.length){b6=dx;c9=false}}}br(dx,dv?0:1);var dz=dt.from.line,dy=dt.to.line;if(dv&&(dz==dA||dy==dA)){var dC=dz==dA?ck({line:dz,ch:0},dz,0):dt.from;var dB=dy==dA?ck({line:dy,ch:0},dy,0):dt.to;if(!dB){return}bX(dC,dB)}return(bf=true)}})}function bi(dw){if(typeof dw=="number"){if(!bQ(dw)){return null}var dx=dw;dw=db(dw);if(!dw){return null}}else{var dx=X(dw);if(dx==null){return null}}var dv=dw.gutterMarker;return{line:dx,handle:dw,text:dw.text,markerText:dv&&dv.text,markerClass:dv&&dv.style,lineClass:dw.className,bgClass:dw.bgClassName}}function cx(dv,dy){if(dy==0){return{top:0,left:0}}var dB=ce(dv,dy);s(aT,dB);var dx=dB.anchor;var dA=dx.offsetTop,dz=dx.offsetLeft;if(U&&dA==0&&dz==0){var dw=ak("span","x");dx.parentNode.insertBefore(dw,dx.nextSibling);dA=dw.offsetTop}return{top:dA,left:dz}}function dn(dA,dy){var dv,dw=ch(),dz=dw*(a(c4,dA.line)-(dy?bB:0));if(dA.ch==0){dv=0}else{var dx=cx(db(dA.line),dA.ch);dv=dx.left;if(ct.lineWrapping){dz+=Math.max(0,dx.top)}}return{x:dv,y:dz,yBot:dz+dw}}function b9(dG,dF){var dD=ch(),dA=bE(),dM=bB+Math.floor(dF/dD);if(dM<0){return{line:0,ch:0}}var dH=af(c4,dM);if(dH>=c4.size){return{line:c4.size-1,ch:db(c4.size-1).text.length}}var dw=db(dH),dJ=dw.text;var dO=ct.lineWrapping,dE=dO?dM-a(c4,dH):0;if(dG<=0&&dE==0){return{line:dH,ch:0}}var dB=false;function dN(dQ){var dR=cx(dw,dQ);if(dO){var dS=Math.round(dR.top/dD);dB=dS!=dE;return Math.max(0,dR.left+(dS-dE)*bH.clientWidth)}return dR.left}var dL=0,dK=0,dx=dJ.length,dv;var dI=Math.min(dx,Math.ceil((dG+dE*bH.clientWidth*0.9)/dA));for(;;){var dC=dN(dI);if(dC<=dG&&dIdv){return{line:dH,ch:dx}}dI=Math.floor(dx*0.8);dC=dN(dI);if(dCdG){dx=dP;dv=dy;if(dB){dv+=1000}}else{dL=dP;dK=dy}}}function aM(dx){var dv=dn(dx,true),dw=B(bU);return{x:dw.left+dv.x,y:dw.top+dv.y,yBot:dw.top+dv.yBot}}var bo,aV,aL;function ch(){if(aL==null){aL=ak("pre");for(var dw=0;dw<49;++dw){aL.appendChild(document.createTextNode("x"));aL.appendChild(ak("br"))}aL.appendChild(document.createTextNode("x"))}var dv=aO.clientHeight;if(dv==aV){return bo}aV=dv;s(aT,aL.cloneNode(true));bo=aT.firstChild.offsetHeight/50||1;aH(aT);return bo}var dp,bV=0;function bE(){if(bH.clientWidth==bV){return dp}bV=bH.clientWidth;var dv=ak("span","x");var dw=ak("pre",[dv]);s(aT,dw);return(dp=dv.offsetWidth||10)}function cX(){return bU.offsetTop}function bt(){return bU.offsetLeft}function bq(dz,dy){var dx=B(bH,true),dv,dA;try{dv=dz.clientX;dA=dz.clientY}catch(dz){return null}if(!dy&&(dv-dx.left>bH.clientWidth||dA-dx.top>bH.clientHeight)){return null}var dw=B(bU,true);return b9(dv-dw.left,dA-dw.top)}var bP;function bp(dw){var dA=bq(dw),dz=a8.scrollTop;if(!dA||ax){return}if(T(dt.from,dt.to)||D(dA,dt.from)||!D(dA,dt.to)){aP(bv)(dA.line,dA.ch)}var dy=bJ.style.cssText;cp.style.position="absolute";bJ.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(dw.clientY-5)+"px; left: "+(dw.clientX-5)+"px; z-index: 1000; background: white; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";b1();c7(true);if(T(dt.from,dt.to)){bJ.value=by=" "}function dv(){cp.style.position="relative";bJ.style.cssText=dy;if(I){a8.scrollTop=dz}aJ();if(bJ.selectionStart!=null){clearTimeout(bP);var dC=bJ.value=" "+(T(dt.from,dt.to)?"":bJ.value),dB=0;by=" ";bJ.selectionStart=1;bJ.selectionEnd=dC.length;bP=setTimeout(function dD(){if(by==" "&&bJ.selectionStart==0){aP(t.selectAll)(cF)}else{if(dB++<10){bP=setTimeout(dD,500)}else{c7()}}},200)}}if(x){ae(dw);var dx=aE(window,"mouseup",function(){dx();setTimeout(dv,20)},true)}else{setTimeout(dv,50)}}function di(){clearInterval(dl);var dv=true;bA.style.visibility="";dl=setInterval(function(){bA.style.visibility=(dv=!dv)?"":"hidden"},ct.cursorBlinkRate)}var bM={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function cK(dB){var dv=dt.inverted?dt.from:dt.to,dD=db(dv.line),dw=dv.ch-1;var dA=(dw>=0&&bM[dD.text.charAt(dw)])||bM[dD.text.charAt(++dw)];if(!dA){return}var dE=dA.charAt(0),dC=dA.charAt(1)==">",dO=dC?1:-1,dJ=dD.styles;for(var dP=dw+1,dL=0,dN=dJ.length;dL=dW&&dV"==dC){dy.push(dY)}else{if(dy.pop()!=dT.charAt(0)){return{pos:dV,match:false}}else{if(!dy.length){return{pos:dV,match:true}}}}}}}}for(var dL=dv.line,dN=dC?Math.min(dL+100,c4.size):Math.max(-1,dL-100);dL!=dN;dL+=dO){var dD=db(dL),dz=dL==dv.line;var dF=dG(dD,dz&&dC?dw+1:0,dz&&!dC?dw:dD.text.length);if(dF){break}}if(!dF){dF={pos:null,match:false}}var dM=dF.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket";var dK=b7({line:dv.line,ch:dw},{line:dv.line,ch:dw+1},dM),dx=dF.pos!=null&&b7({line:dL,ch:dF.pos},{line:dL,ch:dF.pos+1},dM);var dH=aP(function(){dK.clear();dx&&dx.clear()});if(dB){setTimeout(dH,800)}else{cw=dH}}function bw(dB){var dA,dx;for(var dw=dB,dy=dB-40;dw>dy;--dw){if(dw==0){return 0}var dv=db(dw-1);if(dv.stateAfter){return dw}var dz=dv.indentation(ct.tabSize);if(dx==null||dA>dz){dx=dw-1;dA=dz}}return dx}function cZ(dx){var dw=bw(dx),dv=dw&&db(dw-1).stateAfter;if(!dv){dv=v(cH)}else{dv=o(cH,dv)}c4.iter(dw,dx,function(dy){dy.process(cH,dv,ct.tabSize);dy.stateAfter=(dw==dx-1||dw%5==0)?o(cH,dv):null});return dv}function cl(){if(df>=cc){return}var dv=+new Date+ct.workTime,dx=o(cH,cZ(df));var dw=df;c4.iter(df,cc,function(dy){if(df>=dm){dy.highlight(cH,dx,ct.tabSize);dy.stateAfter=o(cH,dx)}else{dy.process(cH,dx,ct.tabSize);dy.stateAfter=df%5==0?o(cH,dx):null}++df;if(+new Date>dv){b8(ct.workDelay);return true}});if(cc>dw&&df>=dm){aP(function(){aZ.push({from:dw,to:df})})()}}function b8(dv){if(df2){aL.dependencies=[];for(var aK=2;aK0&&aL.ch=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)||undefined},next:function(){if(this.posaK},eatSpace:function(){var aJ=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos))){++this.pos}return this.pos>aJ},skipToEnd:function(){this.pos=this.string.length},skipTo:function(aJ){var aK=this.string.indexOf(aJ,this.pos);if(aK>-1){this.pos=aK;return true}},backUp:function(aJ){this.pos-=aJ},column:function(){return ap(this.string,this.start,this.tabSize)},indentation:function(){return ap(this.string,null,this.tabSize)},match:function(aM,aK,aJ){if(typeof aM=="string"){var aN=function(aO){return aJ?aO.toLowerCase():aO};if(aN(this.string).indexOf(aN(aM),this.pos)==this.pos){if(aK!==false){this.pos+=aM.length}return true}}else{var aL=this.string.slice(this.pos).match(aM);if(aL&&aL.index>0){return null}if(aL&&aK!==false){this.pos+=aL[0].length}return aL}},current:function(){return this.string.slice(this.start,this.pos)}};r.StringStream=ai;function Z(aL,aK,aJ){this.from=aL;this.to=aK;this.marker=aJ}function aI(aL,aJ){if(aL){for(var aK=0;aK=aL:aR.to>aL);(aQ||(aQ=[])).push({from:aR.from,to:aM?null:aR.to,marker:aP})}}}return aQ}function aw(aL,aO){if(aL){for(var aN=0,aK;aN=aO:aP.to>aO);if(aQ||aJ.type=="bookmark"&&aP.from==aO){var aM=aP.from==null||(aJ.inclusiveLeft?aP.from<=aO:aP.from0&&aP){for(var aM=0;aM5000){aJ[aQ++]=this.text.slice(aO.pos);aJ[aQ++]=null;break}}},process:function(aM,aJ,aK){var aL=new ai(this.text,aK);if(this.text==""&&aM.blankLine){aM.blankLine(aJ)}while(!aL.eol()&&aL.pos<=5000){aM.token(aL,aJ);aL.start=aL.pos}},getTokenAt:function(aP,aM,aN,aL){var aJ=this.text,aO=new ai(aJ,aN);while(aO.pos=a3&&aJaJ+10&&/\s/.test(bm)){a9=function(){}}}}}}var a2=this.styles,aR=this.text,aZ=this.markedSpans;var bd=aR.length;function aM(bh){if(!bh){return null}return"cm-"+bh.replace(/ +/g," cm-")}if(!aR&&aJ==null){a9(aX," ")}else{if(!aZ||!aZ.length){for(var ba=0,aT=0;aTbd){a1=a1.slice(0,bd-aT)}aT+=a4;a9(aX,a1,aM(bc))}}else{aZ.sort(function(bi,bh){return bi.from-bh.from});var aO=0,ba=0,aW="",bc,bg=0;var bf=aZ[0].from||0,a8=[],be=0;var bb=function(){var bh;while(beaV?aW.slice(0,aV-aO):aW,aK);if(aL>=aV){aW=aW.slice(aV-aO);aO=aV;break}aO=aL}aW=a2[ba++];bc=aM(a2[ba++])}}}}return aX},cleanUp:function(){this.parent=null;aA(this)}};function Q(aK){this.lines=aK;this.parent=null;for(var aL=0,aM=aK.length,aJ=0;aL50){while(aJ.lines.length>50){var aM=aJ.lines.splice(aJ.lines.length-25,25);var aP=new Q(aM);aJ.height-=aP.height;this.children.splice(aL+1,0,aP);aP.parent=this}this.maybeSpill()}break}aK-=aO}},maybeSpill:function(){if(this.children.length<=10){return}var aM=this;do{var aK=aM.children.splice(aM.children.length-5,5);var aL=new al(aK);if(!aM.parent){var aN=new al(aM.children);aN.parent=aM;aM.children=[aN,aL];aM=aN}else{aM.size-=aL.size;aM.height-=aL.height;var aJ=u(aM.parent.children,aM);aM.parent.children.splice(aJ+1,0,aL)}aL.parent=aM.parent}while(aM.children.length>10);aM.parent.maybeSpill()},iter:function(aL,aK,aJ){this.iterN(aL,aK-aL,aJ)},iterN:function(aJ,aQ,aP){for(var aK=0,aN=this.children.length;aK400||!aR||this.closed||aR.start>aJ+aK.length||aR.start+aR.added0;--aM){aR.old.unshift(aK[aM-1])}for(var aM=aS;aM>0;--aM){aR.old.push(aK[aK.length-aM])}if(aP){aR.start=aJ}aR.added+=aO-(aK.length-aP-aS)}}this.time=aL},startCompound:function(){if(!this.compound++){this.closed=true}},endCompound:function(){if(!--this.compound){this.closed=true}}};function z(){ae(this)}function R(aJ){if(!aJ.stop){aJ.stop=z}return aJ}function f(aJ){if(aJ.preventDefault){aJ.preventDefault()}else{aJ.returnValue=false}}function q(aJ){if(aJ.stopPropagation){aJ.stopPropagation()}else{aJ.cancelBubble=true}}function ae(aJ){f(aJ);q(aJ)}r.e_stop=ae;r.e_preventDefault=f;r.e_stopPropagation=q;function ar(aJ){return aJ.target||aJ.srcElement}function E(aK){var aJ=aK.which;if(aJ==null){if(aK.button&1){aJ=1}else{if(aK.button&2){aJ=3}else{if(aK.button&4){aJ=2}}}}if(K&&aK.ctrlKey&&aJ==1){aJ=3}return aJ}function ad(aK,aL){var aJ=aK.override&&aK.override.hasOwnProperty(aL);return aJ?aK.override[aL]:aK[aL]}function aE(aM,aL,aK,aJ){if(typeof aM.addEventListener=="function"){aM.addEventListener(aL,aK,false);if(aJ){return function(){aM.removeEventListener(aL,aK,false)}}}else{var aN=function(aO){aK(aO||window.event)};aM.attachEvent("on"+aL,aN);if(aJ){return function(){aM.detachEvent("on"+aL,aN)}}}}r.connect=aE;function j(){this.id=null}j.prototype={set:function(aJ,aK){clearTimeout(this.id);this.id=setTimeout(aK,aJ)}};var aq=r.Pass={toString:function(){return"CodeMirror.Pass"}};var ac=function(){if(I){return false}var aJ=ak("div");return"draggable" in aJ||"dragDrop" in aJ}();var S=function(){var aJ=ak("textarea");aJ.value="foo\nbar";if(aJ.value.indexOf("\r")>-1){return"\r\n"}return"\n"}();var H=/^$/;if(x){H=/$'/}else{if(G){H=/\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/}else{if(p){H=/\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/}}}function ap(aK,aJ,aM){if(aJ==null){aJ=aK.search(/[^\s\u00a0]/);if(aJ==-1){aJ=aK.length}}for(var aL=0,aN=0;aL=0&&aJ>=0;--aK,--aJ){if(aM.charAt(aK)!=aL.charAt(aJ)){break}}return aJ+1}function u(aM,aJ){if(aM.indexOf){return aM.indexOf(aJ)}for(var aK=0,aL=aM.length;aK"\x80"&&(aJ.toUpperCase()!=aJ.toLowerCase()||O.test(aJ))}var h="\n\nb".split(/\n/).length!=3?function(aO){var aP=0,aJ=[],aN=aO.length;while(aP<=aN){var aM=aO.indexOf("\n",aP);if(aM==-1){aM=aO.length}var aL=aO.slice(aP,aO.charAt(aM-1)=="\r"?aM-1:aM);var aK=aL.indexOf("\r");if(aK!=-1){aJ.push(aL.slice(0,aK));aP+=aK+1}else{aJ.push(aL);aP=aM+1}}return aJ}:function(aJ){return aJ.split(/\r\n?|\n/)};r.splitLines=h;var b=window.getSelection?function(aK){try{return aK.selectionStart!=aK.selectionEnd}catch(aJ){return false}}:function(aL){try{var aJ=aL.ownerDocument.selection.createRange()}catch(aK){}if(!aJ||aJ.parentElement()!=aL){return false}return aJ.compareEndPoints("StartToEnd",aJ)!=0};r.defineMode("null",function(){return{token:function(aJ){aJ.skipToEnd()}}});r.defineMIME("text/plain","null");var w={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",109:"-",107:"=",127:"Delete",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};r.keyNames=w;(function(){for(var aJ=0;aJ<10;aJ++){w[aJ+48]=String(aJ)}for(var aJ=65;aJ<=90;aJ++){w[aJ]=String.fromCharCode(aJ)}for(var aJ=1;aJ<=12;aJ++){w[aJ+111]=w[aJ+63235]="F"+aJ}})();r.version="2.38";return r})(); \ No newline at end of file diff --git a/phpmyadmin/js/codemirror/mode/mysql/mysql.js b/phpmyadmin/js/codemirror/mode/mysql/mysql.js new file mode 100644 index 000000000..029094cef --- /dev/null +++ b/phpmyadmin/js/codemirror/mode/mysql/mysql.js @@ -0,0 +1 @@ +CodeMirror.defineMode("mysql",function(b){var e=b.indentUnit;var l;function g(n){return new RegExp("^(?:"+n.join("|")+")$","i")}var a=g(["str","lang","langmatches","datatype","bound","sameterm","isiri","isuri","isblank","isliteral","union","a"]);var d=g([("ACCESSIBLE"),("ALTER"),("AS"),("BEFORE"),("BINARY"),("BY"),("CASE"),("CHARACTER"),("COLUMN"),("CONTINUE"),("CROSS"),("CURRENT_TIMESTAMP"),("DATABASE"),("DAY_MICROSECOND"),("DEC"),("DEFAULT"),("DESC"),("DISTINCT"),("DOUBLE"),("EACH"),("ENCLOSED"),("EXIT"),("FETCH"),("FLOAT8"),("FOREIGN"),("GRANT"),("HIGH_PRIORITY"),("HOUR_SECOND"),("IN"),("INNER"),("INSERT"),("INT2"),("INT8"),("INTO"),("JOIN"),("KILL"),("LEFT"),("LINEAR"),("LOCALTIME"),("LONG"),("LOOP"),("MATCH"),("MEDIUMTEXT"),("MINUTE_SECOND"),("NATURAL"),("NULL"),("OPTIMIZE"),("OR"),("OUTER"),("PRIMARY"),("RANGE"),("READ_WRITE"),("REGEXP"),("REPEAT"),("RESTRICT"),("RIGHT"),("SCHEMAS"),("SENSITIVE"),("SHOW"),("SPECIFIC"),("SQLSTATE"),("SQL_CALC_FOUND_ROWS"),("STARTING"),("TERMINATED"),("TINYINT"),("TRAILING"),("UNDO"),("UNLOCK"),("USAGE"),("UTC_DATE"),("VALUES"),("VARCHARACTER"),("WHERE"),("WRITE"),("ZEROFILL"),("ALL"),("AND"),("ASENSITIVE"),("BIGINT"),("BOTH"),("CASCADE"),("CHAR"),("COLLATE"),("CONSTRAINT"),("CREATE"),("CURRENT_TIME"),("CURSOR"),("DAY_HOUR"),("DAY_SECOND"),("DECLARE"),("DELETE"),("DETERMINISTIC"),("DIV"),("DUAL"),("ELSEIF"),("EXISTS"),("FALSE"),("FLOAT4"),("FORCE"),("FULLTEXT"),("HAVING"),("HOUR_MINUTE"),("IGNORE"),("INFILE"),("INSENSITIVE"),("INT1"),("INT4"),("INTERVAL"),("ITERATE"),("KEYS"),("LEAVE"),("LIMIT"),("LOAD"),("LOCK"),("LONGTEXT"),("MASTER_SSL_VERIFY_SERVER_CERT"),("MEDIUMINT"),("MINUTE_MICROSECOND"),("MODIFIES"),("NO_WRITE_TO_BINLOG"),("ON"),("OPTIONALLY"),("OUT"),("PRECISION"),("PURGE"),("READS"),("REFERENCES"),("RENAME"),("REQUIRE"),("REVOKE"),("SCHEMA"),("SELECT"),("SET"),("SPATIAL"),("SQLEXCEPTION"),("SQL_BIG_RESULT"),("SSL"),("TABLE"),("TINYBLOB"),("TO"),("TRUE"),("UNIQUE"),("UPDATE"),("USING"),("UTC_TIMESTAMP"),("VARCHAR"),("WHEN"),("WITH"),("YEAR_MONTH"),("ADD"),("ANALYZE"),("ASC"),("BETWEEN"),("BLOB"),("CALL"),("CHANGE"),("CHECK"),("CONDITION"),("CONVERT"),("CURRENT_DATE"),("CURRENT_USER"),("DATABASES"),("DAY_MINUTE"),("DECIMAL"),("DELAYED"),("DESCRIBE"),("DISTINCTROW"),("DROP"),("ELSE"),("ESCAPED"),("EXPLAIN"),("FLOAT"),("FOR"),("FROM"),("GROUP"),("HOUR_MICROSECOND"),("IF"),("INDEX"),("INOUT"),("INT"),("INT3"),("INTEGER"),("IS"),("KEY"),("LEADING"),("LIKE"),("LINES"),("LOCALTIMESTAMP"),("LONGBLOB"),("LOW_PRIORITY"),("MEDIUMBLOB"),("MIDDLEINT"),("MOD"),("NOT"),("NUMERIC"),("OPTION"),("ORDER"),("OUTFILE"),("PROCEDURE"),("READ"),("REAL"),("RELEASE"),("REPLACE"),("RETURN"),("RLIKE"),("SECOND_MICROSECOND"),("SEPARATOR"),("SMALLINT"),("SQL"),("SQLWARNING"),("SQL_SMALL_RESULT"),("STRAIGHT_JOIN"),("THEN"),("TINYTEXT"),("TRIGGER"),("UNION"),("UNSIGNED"),("USE"),("UTC_TIME"),("VARBINARY"),("VARYING"),("WHILE"),("XOR"),("FULL"),("COLUMNS"),("MIN"),("MAX"),("STDEV"),("COUNT")]);var f=/[*+\-<>=&|]/;function c(r,p){var o=r.next();l=null;if(o=="$"||o=="?"){r.match(/^[\w\d]*/);return"variable-2"}else{if(o=="<"&&!r.match(/^[\s\u00a0=]/,false)){r.match(/^[^\s\u00a0>]*>?/);return"atom"}else{if(o=='"'||o=="'"){p.tokenize=m(o);return p.tokenize(r,p)}else{if(o=="`"){p.tokenize=j(o);return p.tokenize(r,p)}else{if(/[{}\(\),\.;\[\]]/.test(o)){l=o;return null}else{if(o=="-"&&r.eat("-")){r.skipToEnd();return"comment"}else{if(o=="/"&&r.eat("*")){p.tokenize=i;return p.tokenize(r,p)}else{if(f.test(o)){r.eatWhile(f);return null}else{if(o==":"){r.eatWhile(/[\w\d\._\-]/);return"atom"}else{r.eatWhile(/[_\w\d]/);if(r.eat(":")){r.eatWhile(/[\w\d_\-]/);return"atom"}var q=r.current(),n;if(a.test(q)){return null}else{if(d.test(q)){return"keyword"}else{return"variable"}}}}}}}}}}}}function m(n){return function(r,p){var q=false,o;while((o=r.next())!=null){if(o==n&&!q){p.tokenize=c;break}q=!q&&o=="\\"}return"string"}}function j(n){return function(r,p){var q=false,o;while((o=r.next())!=null){if(o==n&&!q){p.tokenize=c;break}q=!q&&o=="\\"}return"variable-2"}}function i(o,n){for(;;){if(o.skipTo("*")){o.next();if(o.eat("/")){n.tokenize=c;break}}else{o.skipToEnd();break}}return"comment"}function h(p,o,n){p.context={prev:p.context,indent:p.indent,col:n,type:o}}function k(n){n.indent=n.context.indent;n.context=n.context.prev}return{startState:function(n){return{tokenize:c,context:null,indent:0,col:0}},token:function(p,o){if(p.sol()){if(o.context&&o.context.align==null){o.context.align=false}o.indent=p.indentation()}if(p.eatSpace()){return null}var n=o.tokenize(p,o);if(n!="comment"&&o.context&&o.context.align==null&&o.context.type!="pattern"){o.context.align=true}if(l=="("){h(o,")",p.column())}else{if(l=="["){h(o,"]",p.column())}else{if(l=="{"){h(o,"}",p.column())}else{if(/[\]\}\)]/.test(l)){while(o.context&&o.context.type=="pattern"){k(o)}if(o.context&&l==o.context.type){k(o)}}else{if(l=="."&&o.context&&o.context.type=="pattern"){k(o)}else{if(/atom|string|variable/.test(n)&&o.context){if(/[\}\]]/.test(o.context.type)){h(o,"pattern",p.column())}else{if(o.context.type=="pattern"&&!o.context.align){o.context.align=true;o.context.col=p.column()}}}}}}}}return n},indent:function(r,n){var q=n&&n.charAt(0);var p=r.context;if(/[\]\}]/.test(q)){while(p&&p.type=="pattern"){p=p.prev}}var o=p&&q==p.type;if(!p){return 0}else{if(p.type=="pattern"){return p.col}else{if(p.align){return p.col+(o?0:1)}else{return p.indent+(o?0:e)}}}}}});CodeMirror.defineMIME("text/x-mysql","mysql"); \ No newline at end of file diff --git a/phpmyadmin/js/common.js b/phpmyadmin/js/common.js new file mode 100644 index 000000000..ca3343eef --- /dev/null +++ b/phpmyadmin/js/common.js @@ -0,0 +1 @@ +$(function(){$("#pma_open_querywindow").click(function(a){a.preventDefault();PMA_querywindow.focus()})});var PMA_commonParams=(function(){var a={};return{setAll:function(d){var c=false;for(var b in d){if(a[b]!==undefined&&a[b]!==d[b]){c=true}a[b]=d[b]}if(c){PMA_querywindow.refresh()}},get:function(b){return a[b]||""},set:function(b,c){if(a[b]!==undefined&&a[b]!==c){PMA_querywindow.refresh();PMA_reloadNavigation()}a[b]=c;return this},getUrlQuery:function(){return $.sprintf("?%s&server=%s&db=%s&table=%s",this.get("common_query"),encodeURIComponent(this.get("server")),encodeURIComponent(this.get("db")),encodeURIComponent(this.get("table")))}}})();var PMA_commonActions={setDb:function(a){if(a!=PMA_commonParams.get("db")){PMA_commonParams.set("db",a);PMA_querywindow.refresh()}},openDb:function(a){PMA_commonParams.set("db",a).set("table","");PMA_querywindow.refresh();this.refreshMain(PMA_commonParams.get("opendb_url"))},refreshMain:function(a,b){if(!a){a=$("#selflink a").attr("href");a=a.substring(0,a.indexOf("?"))}a+=PMA_commonParams.getUrlQuery();$("",{href:a}).appendTo("body").click().remove();AJAX._callback=b}};var PMA_querywindow=(function(d,c){var b={};var a="";return{open:function(f,g){if(!f){f="querywindow.php"+PMA_commonParams.getUrlQuery()}if(g){f+="&sql_query="+encodeURIComponent(g)}if(!b.closed&&b.location){var e=b.location.href;if(e!=f&&e!=PMA_commonParams.get("pma_absolute_uri")+f){if(PMA_commonParams.get("safari_browser")){b.location.href=targeturl}else{b.location.replace(targeturl)}b.focus()}}else{b=c.open(f+"&init=1","","toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=yes,resizable=yes,width="+PMA_commonParams.get("querywindow_width")+",height="+PMA_commonParams.get("querywindow_height"))}if(!b.opener){b.opener=c.window}if(c.focus){b.focus()}},focus:function(f){if(!b||b.closed||!b.location){a=f;this.open(false,f)}else{var e=b.document.getElementById("hiddenqueryform");if(e.querydisplay_tab!="sql"){e.querydisplay_tab.value="sql";e.sql_query.value=f;d(e).addClass("disableAjax");e.submit();b.focus()}else{b.focus()}}},refresh:function(f){if(!b.closed&&b.location){var e=d(b.document).find("#sqlqueryform");if(e.find("#checkbox_lock:checked").length==0){PMA_querywindow.open(f)}}},reload:function(f,g,i){if(!b.closed&&b.location){var e=d(b.document).find("#sqlqueryform");if(e.find("#checkbox_lock:checked").length==0){var h=d(b.document).find("#hiddenqueryform");h.find("input[name=db]").val(f);h.find("input[name=table]").val(g);if(i){h.find("input[name=sql_query]").val(i)}h.addClass("disableAjax").submit()}}}}})(jQuery,window); \ No newline at end of file diff --git a/phpmyadmin/js/config.js b/phpmyadmin/js/config.js new file mode 100644 index 000000000..fafd12168 --- /dev/null +++ b/phpmyadmin/js/config.js @@ -0,0 +1 @@ +AJAX.registerTeardown("config.js",function(){$("input[id], select[id], textarea[id]").unbind("change").unbind("keyup");$("input[type=button][name=submit_reset]").unbind("click");$("div.tabs_contents").undelegate();$("#import_local_storage, #export_local_storage").unbind("click");$("form.prefs-form").unbind("change").unbind("submit");$("div.click-hide-message").die("click");$("#prefs_autoload").find("a").unbind("click")});AJAX.registerOnload("config.js",function(){$("#topmenu2").find("li.active a").attr("rel","samepage");$("#topmenu2").find("li:not(.active) a").attr("rel","newpage")});var defaultValues={};function getFieldType(b){b=$(b);var a=b.prop("tagName");if(a=="INPUT"){return b.attr("type")}else{if(a=="SELECT"){return"select"}else{if(a=="TEXTAREA"){return"text"}}}return""}function setFieldValue(f,e,d){f=$(f);switch(e){case"text":f.attr("value",(d!=undefined?d:f.attr("defaultValue")));break;case"checkbox":f.attr("checked",(d!=undefined?d:f.attr("defaultChecked")));break;case"select":var a=f.prop("options");var c,b=a.length;if(d==undefined){for(c=0;c');g.find("table").before(d)}else{d=$('
      ');g.closest("td").append(d)}}var c="";for(var b=0,a=h.length;b"+h[b]+""}d.html(c)}else{if(d!==null){d.remove()}}}}function validate_fieldset(a,b,e){a=$(a);if(a.length&&typeof validators._fieldset[a.attr("id")]!="undefined"){var c=validators._fieldset[a.attr("id")].apply(a[0],[b]);for(var d in c){if(typeof e[d]=="undefined"){e[d]=[]}if(typeof c[d]=="string"){c[d]=[c[d]]}$.merge(e[d],c[d])}}}function validate_field(g,b,h){g=$(g);var e=g.attr("id");h[e]=[];var f=getFieldValidators(e,b);for(var d=0;d9?"":"0")+a}function isDate(c,b){var a=getDateFromFormat(c,b);if(a==0){return false}return true}function compareDates(e,f,c,d){var b=getDateFromFormat(e,f);var a=getDateFromFormat(c,d);if(b==0||a==0){return -1}else{if(b>a){return 1}}return 0}function formatDate(I,D){D=D+"";var l="";var v=0;var G="";var f="";var j=I.getYear()+"";var g=I.getMonth()+1;var F=I.getDate();var o=I.getDay();var n=I.getHours();var x=I.getMinutes();var q=I.getSeconds();var t,u,b,r,J,e,C,B,z,p,N,n,L,i,a,A;var w=new Object();if(j.length<4){j=""+(j-0+1900)}w.y=""+j;w.yyyy=j;w.yy=j.substring(2,4);w.M=g;w.MM=LZ(g);w.MMM=MONTH_NAMES[g-1];w.NNN=MONTH_NAMES[g+11];w.d=F;w.dd=LZ(F);w.E=DAY_NAMES[o+7];w.EE=DAY_NAMES[o];w.H=n;w.HH=LZ(n);if(n==0){w.h=12}else{if(n>12){w.h=n-12}else{w.h=n}}w.hh=LZ(w.h);if(n>11){w.K=n-12}else{w.K=n}w.k=n+1;w.KK=LZ(w.K);w.kk=LZ(w.k);if(n>11){w.a="PM"}else{w.a="AM"}w.m=x;w.mm=LZ(x);w.s=q;w.ss=LZ(q);while(v=e;a--){var b=f.substring(d,d+a);if(b.length70){j=1900+(j-0)}else{j=2000+(j-0)}}}else{if(f=="MMM"||f=="NNN"){t=0;for(var o=0;o11)){t=o+1;if(t>12){t-=12}v+=e.length;break}}}if((t<1)||(t>12)){return 0}}else{if(f=="EE"||f=="E"){for(var o=0;o12)){return 0}v+=t.length}else{if(f=="dd"||f=="d"){s=_getInt(w,v,f.length,2);if(s==null||(s<1)||(s>31)){return 0}v+=s.length}else{if(f=="hh"||f=="h"){d=_getInt(w,v,f.length,2);if(d==null||(d<1)||(d>12)){return 0}v+=d.length}else{if(f=="HH"||f=="H"){d=_getInt(w,v,f.length,2);if(d==null||(d<0)||(d>23)){return 0}v+=d.length}else{if(f=="KK"||f=="K"){d=_getInt(w,v,f.length,2);if(d==null||(d<0)||(d>11)){return 0}v+=d.length}else{if(f=="kk"||f=="k"){d=_getInt(w,v,f.length,2);if(d==null||(d<1)||(d>24)){return 0}v+=d.length;d--}else{if(f=="mm"||f=="m"){q=_getInt(w,v,f.length,2);if(q==null||(q<0)||(q>59)){return 0}v+=q.length}else{if(f=="ss"||f=="s"){n=_getInt(w,v,f.length,2);if(n==null||(n<0)||(n>59)){return 0}v+=n.length}else{if(f=="a"){if(w.substring(v,v+2).toLowerCase()=="am"){k="AM"}else{if(w.substring(v,v+2).toLowerCase()=="pm"){k="PM"}else{return 0}}v+=2}else{if(w.substring(v,v+f.length)!=f){return 0}else{v+=f.length}}}}}}}}}}}}}}if(v!=w.length){return 0}if(t==2){if(((j%4==0)&&(j%100!=0))||(j%400==0)){if(s>29){return 0}}else{if(s>28){return 0}}}if((t==4)||(t==6)||(t==9)||(t==11)){if(s>30){return 0}}if(d<12&&k=="PM"){d=d-0+12}else{if(d>11&&k=="AM"){d-=12}}var a=new Date(j,t-1,s,d,q,n);return a.getTime()}function parseDate(h){var f=(arguments.length==2)?arguments[1]:false;generalFormats=new Array("y-M-d","MMM d, y","MMM d,y","y-MMM-d","d-MMM-y","MMM d");monthFirst=new Array("M/d/y","M-d-y","M.d.y","MMM-d","M/d","M-d");dateFirst=new Array("d/M/y","d-M-y","d.M.y","d-MMM","d/M","d-M");var b=new Array("generalFormats",f?"dateFirst":"monthFirst",f?"monthFirst":"dateFirst");var g=null;for(var e=0;e').insertAfter("#searchresults").hide();$('
      ').insertAfter("#togglesearchresultsdiv").show();$("#togglesearchresultlink").html(PMA_messages.strHideSearchResults).bind("click",function(){var b=$(this);$("#searchresults").slideToggle();if(b.text()==PMA_messages.strHideSearchResults){b.text(PMA_messages.strShowSearchResults)}else{b.text(PMA_messages.strHideSearchResults)}return false});$('
      ').insertAfter("#db_search_form").hide();$("#togglequerybox").hide().bind("click",function(){var b=$(this);$("#sqlqueryform").slideToggle("medium");if(b.text()==PMA_messages.strHideQueryBox){b.text(PMA_messages.strShowQueryBox)}else{b.text(PMA_messages.strHideQueryBox)}return false});$("#togglesearchformlink").html(PMA_messages.strShowSearchCriteria).bind("click",function(){var b=$(this);$("#db_search_form").slideToggle();if(b.text()==PMA_messages.strHideSearchCriteria){b.text(PMA_messages.strShowSearchCriteria)}else{b.text(PMA_messages.strHideSearchCriteria)}return false});$("#db_search_form.ajax").live("submit",function(d){d.preventDefault();var e=PMA_ajaxShowMessage(PMA_messages.strSearching,false);var b=$(this);PMA_prepareForAjaxRequest(b);var c=b.serialize()+"&submit_search="+$("#buttonGo").val();$.post(b.attr("action"),c,function(f){if(f.success==true){$("#searchresults").html(f.message);$("#togglesearchresultlink").text(PMA_messages.strHideSearchResults);$("#togglesearchresultsdiv").show();$("#searchresults").show();$("#db_search_form").slideToggle().hide();$("#togglesearchformlink").text(PMA_messages.strShowSearchCriteria);$("#togglesearchformdiv").show()}else{$("#sqlqueryresults").html(f.error)}PMA_ajaxRemoveMessage(e)})})}); \ No newline at end of file diff --git a/phpmyadmin/js/db_structure.js b/phpmyadmin/js/db_structure.js new file mode 100644 index 000000000..7fd952be5 --- /dev/null +++ b/phpmyadmin/js/db_structure.js @@ -0,0 +1 @@ +AJAX.registerTeardown("db_structure.js",function(){$("span.fkc_switch").unbind("click");$("#fkc_checkbox").unbind("change");$("a.truncate_table_anchor.ajax").die("click");$("a.drop_table_anchor.ajax").die("click");$("a.drop_tracking_anchor.ajax").die("click");$("#real_end_input").die("click")});function PMA_adjustTotals(){var a=new Array(PMA_messages.strB,PMA_messages.strKiB,PMA_messages.strMiB,PMA_messages.strGiB,PMA_messages.strTiB,PMA_messages.strPiB,PMA_messages.strEiB);var g=$("#tablesForm table.data tbody:first tr");var h=g.size();var d=0;var c=0;var f=0;var l=false;g.each(function(){var u=$(this);var r=u.find(".tbl_rows").text();if(r.indexOf("~")==0){l=true;r=r.substring(1,r.length-1)}r=r.replace(/[,.]/g,"");var p=parseInt(r,10);if(!isNaN(p)){d+=p}var w=0;var n=0;var s=$.trim(u.find(".tbl_size span:not(.unit)").text());var v=$.trim(u.find(".tbl_size span.unit").text());var t=$.trim(u.find(".tbl_overhead span:not(.unit)").text());var q=$.trim(u.find(".tbl_overhead span.unit").text());for(var o=0;o=1024){c/=1024;e++}while(f>=1024){f/=1024;i++}c=Math.round(c*10)/10;f=Math.round(f*10)/10;var b=$("#tbl_summary_row");b.find(".tbl_num").text($.sprintf(PMA_messages.strTables,h));b.find(".tbl_rows").text(k);b.find(".tbl_size").text(c+" "+a[e]);b.find(".tbl_overhead").text(f+" "+a[i])}AJAX.registerOnload("db_structure.js",function(){$("#tablesForm").submit(function(b){var a=$(this);if(a.find("select[name=submit_mult]").val()==="print"){b.preventDefault();b.stopPropagation();$("form#clone").remove();var c=a.clone().hide().appendTo("body");c.find("select[name=submit_mult]").val("print");c.attr("target","printview").attr("id","clone").submit()}});$("span.fkc_switch").click(function(a){if($("#fkc_checkbox").prop("checked")){$("#fkc_checkbox").prop("checked",false);$("#fkc_status").html(PMA_messages.strForeignKeyCheckDisabled);return}$("#fkc_checkbox").prop("checked",true);$("#fkc_status").html(PMA_messages.strForeignKeyCheckEnabled)});$("#fkc_checkbox").change(function(){if($(this).prop("checked")){$("#fkc_status").html(PMA_messages.strForeignKeyCheckEnabled);return}$("#fkc_status").html(PMA_messages.strForeignKeyCheckDisabled)});$("a.truncate_table_anchor.ajax").live("click",function(c){c.preventDefault();var b=$(this);var d=b.parents("tr").children("th").children("a").text();var a=PMA_messages.strTruncateTableStrongWarning+" "+$.sprintf(PMA_messages.strDoYouReally,"TRUNCATE "+escapeHtml(d));b.PMA_confirm(a,b.attr("href"),function(e){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(e,{is_js_confirmed:1,ajax_request:true},function(h){if(h.success==true){PMA_ajaxShowMessage(h.message);var g=b.closest("tr");g.find(".tbl_rows").text("0");g.find(".tbl_size, .tbl_overhead").text("-");var f=b.html().replace(/b_empty/,"bd_empty");b.replaceWith(f).removeClass("truncate_table_anchor");PMA_adjustTotals()}else{PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest+" : "+h.error,false)}})})});$("a.drop_table_anchor.ajax").live("click",function(e){e.preventDefault();var d=$(this);var b=d.parents("tr");var f=b.children("th").children("a").text();var c=b.hasClass("is_view")||d.hasClass("view");var a;if(!c){a=PMA_messages.strDropTableStrongWarning+" "+$.sprintf(PMA_messages.strDoYouReally,"DROP TABLE "+escapeHtml(f))}else{a=$.sprintf(PMA_messages.strDoYouReally,"DROP VIEW "+escapeHtml(f))}d.PMA_confirm(a,d.attr("href"),function(h){var g=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(h,{is_js_confirmed:1,ajax_request:true},function(i){if(i.success==true){PMA_ajaxShowMessage(i.message);toggleRowColors(b.next());b.hide("medium").remove();PMA_adjustTotals();PMA_reloadNavigation();PMA_ajaxRemoveMessage(g)}else{PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest+" : "+i.error,false)}})})});$("a.drop_tracking_anchor.ajax").live("click",function(c){c.preventDefault();var b=$(this);var d=b.parents("tr");var a=PMA_messages.strDeleteTrackingData;b.PMA_confirm(a,b.attr("href"),function(e){PMA_ajaxShowMessage(PMA_messages.strDeletingTrackingData);$.get(e,{is_js_confirmed:1,ajax_request:true},function(j){if(j.success==true){var i=d.parents("table");var f=d.find("td:nth-child(2)").text();if(i.find("tbody tr").length===1){$("#tracked_tables").hide("slow").remove()}else{toggleRowColors(d.next());d.hide("slow",function(){$(this).remove()})}var h=$("table#noversions");if(h.length>0){var g=h.find("tbody tr");g.each(function(m){var k=$(this);var p=k.find("td:first-child").text();var n=(m==(g.length-1));if(p>f||n){var l=k.clone();l.find("td:first-child").text(f);var o=l.find("td:nth-child(2) a").attr("href").replace("table="+p,"table="+encodeURIComponent(f));l.find("td:nth-child(2) a").attr("href",o);if(p>f){l.insertBefore(k);toggleRowColors(k);return false}else{l.insertAfter(k);toggleRowColors(l)}}})}PMA_ajaxShowMessage(j.message)}else{PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest+" : "+j.error,false)}})})});$("#real_end_input").live("click",function(b){b.preventDefault();var a=PMA_messages.strOperationTakesLongTime;$(this).PMA_confirm(a,"",function(){return true});return false})}); \ No newline at end of file diff --git a/phpmyadmin/js/export.js b/phpmyadmin/js/export.js new file mode 100644 index 000000000..d2bece333 --- /dev/null +++ b/phpmyadmin/js/export.js @@ -0,0 +1 @@ +AJAX.registerTeardown("export.js",function(){$("#plugins").unbind("change");$("input[type='radio'][name='sql_structure_or_data']").unbind("change");$("input[type='radio'][name='latex_structure_or_data']").unbind("change");$("input[type='radio'][name='odt_structure_or_data']").unbind("change");$("input[type='radio'][name='texytext_structure_or_data']").unbind("change");$("input[type='radio'][name='htmlword_structure_or_data']").unbind("change");$("input[type='radio'][name='sql_structure_or_data']").unbind("change");$("input[type='radio'][name='output_format']").unbind("change");$("#checkbox_sql_include_comments").unbind("change");$("#plugins").unbind("change");$("input[type='radio'][name='quick_or_custom']").unbind("change");$("input[type='radio'][name='allrows']").unbind("change")});AJAX.registerOnload("export.js",function(){$("#plugins").change(function(){$("#format_specific_opts div.format_specific_options").hide();var a=$("#plugins option:selected").val();$("#"+a+"_options").show()});$("input[type='radio'][name='sql_structure_or_data']").change(function(){var b=$("#checkbox_sql_include_comments").prop("checked");var a=$("input[type='radio'][name='sql_structure_or_data']:checked").val();if(a=="data"){if(b){$("#checkbox_sql_dates").prop("disabled",true).parent().fadeTo("fast",0.4)}$("#checkbox_sql_relation").prop("disabled",true).parent().fadeTo("fast",0.4);$("#checkbox_sql_mime").prop("disabled",true).parent().fadeTo("fast",0.4)}else{if(b){$("#checkbox_sql_dates").removeProp("disabled").parent().fadeTo("fast",1)}$("#checkbox_sql_relation").removeProp("disabled").parent().fadeTo("fast",1);$("#checkbox_sql_mime").removeProp("disabled").parent().fadeTo("fast",1)}})});function toggle_structure_data_opts(e){var d=e+"_structure_or_data";var b="#"+e+"_data";var c="#"+e+"_structure";var a=$("input[type='radio'][name='"+d+"']:checked").val();if(a=="data"){$(b).slideDown("slow");$(c).slideUp("slow")}else{$(c).slideDown("slow");if(a=="structure"){$(b).slideUp("slow")}else{$(b).slideDown("slow")}}}AJAX.registerOnload("export.js",function(){$("input[type='radio'][name='latex_structure_or_data']").change(function(){toggle_structure_data_opts("latex")});$("input[type='radio'][name='odt_structure_or_data']").change(function(){toggle_structure_data_opts("odt")});$("input[type='radio'][name='texytext_structure_or_data']").change(function(){toggle_structure_data_opts("texytext")});$("input[type='radio'][name='htmlword_structure_or_data']").change(function(){toggle_structure_data_opts("htmlword")});$("input[type='radio'][name='sql_structure_or_data']").change(function(){toggle_structure_data_opts("sql")})});function toggle_save_to_file(){if(!$("#radio_dump_asfile").prop("checked")){$("#ul_save_asfile > li").fadeTo("fast",0.4);$("#ul_save_asfile > li > input").prop("disabled",true);$("#ul_save_asfile > li> select").prop("disabled",true)}else{$("#ul_save_asfile > li").fadeTo("fast",1);$("#ul_save_asfile > li > input").removeProp("disabled");$("#ul_save_asfile > li> select").removeProp("disabled")}}AJAX.registerOnload("export.js",function(){toggle_save_to_file();$("input[type='radio'][name='output_format']").change(toggle_save_to_file)});function toggle_sql_include_comments(){$("#checkbox_sql_include_comments").change(function(){if(!$("#checkbox_sql_include_comments").prop("checked")){$("#ul_include_comments > li").fadeTo("fast",0.4);$("#ul_include_comments > li > input").prop("disabled",true)}else{if($("#radio_sql_structure_or_data_data").prop("checked")){$("#text_sql_header_comment").removeProp("disabled").parent("li").fadeTo("fast",1)}else{$("#ul_include_comments > li").fadeTo("fast",1);$("#ul_include_comments > li > input").removeProp("disabled")}}})}AJAX.registerOnload("export.js",function(){var b=$("#checkbox_sql_create_table_statements");var a=$("#ul_create_table_statements input");b.change(function(){a.prop("checked",$(this).prop("checked"))});a.change(function(){if(a.is(":checked")){b.prop("checked",true)}});$("#plugins").change(function(){var d=$("#plugins option:selected").val();var c=$("#force_file_"+d).val();if(c=="true"){$("#radio_view_as_text").prop("disabled",true).parent().fadeTo("fast",0.4)}else{$("#radio_view_as_text").removeProp("disabled").parent().fadeTo("fast",1)}})});function toggle_quick_or_custom(){if($("#radio_custom_export").prop("checked")){$("#databases_and_tables").show();$("#rows").show();$("#output").show();$("#format_specific_opts").show();$("#output_quick_export").hide();var a=$("#plugins option:selected").val();$("#"+a+"_options").show()}else{$("#databases_and_tables").hide();$("#rows").hide();$("#output").hide();$("#format_specific_opts").hide();$("#output_quick_export").show()}}AJAX.registerOnload("export.js",function(){$("input[type='radio'][name='quick_or_custom']").change(toggle_quick_or_custom);if($("input[type='hidden'][name='export_method']").val()!="custom-no-form"){$("#quick_or_custom").show()}$("#scroll_to_options_msg").hide();$("#format_specific_opts div.format_specific_options").hide().css({border:0,margin:0,padding:0}).find("h3").remove();toggle_quick_or_custom();toggle_structure_data_opts($("select#plugins").val());toggle_sql_include_comments();disable_dump_some_rows_sub_options();$("input[type='radio'][name='allrows']").change(function(){if($("input[type='radio'][name='allrows']").prop("checked")){enable_dump_some_rows_sub_options()}else{disable_dump_some_rows_sub_options()}})});function disable_dump_some_rows_sub_options(){$("label[for='limit_to']").fadeTo("fast",0.4);$("label[for='limit_from']").fadeTo("fast",0.4);$("input[type='text'][name='limit_to']").prop("disabled","disabled");$("input[type='text'][name='limit_from']").prop("disabled","disabled")}function enable_dump_some_rows_sub_options(){$("label[for='limit_to']").fadeTo("fast",1);$("label[for='limit_from']").fadeTo("fast",1);$("input[type='text'][name='limit_to']").prop("disabled","");$("input[type='text'][name='limit_from']").prop("disabled","")}; \ No newline at end of file diff --git a/phpmyadmin/js/functions.js b/phpmyadmin/js/functions.js new file mode 100644 index 000000000..aa663d471 --- /dev/null +++ b/phpmyadmin/js/functions.js @@ -0,0 +1 @@ +var $table_clone=false;var sql_box_locked=false;var only_once_elements=[];var ajax_message_count=0;var codemirror_editor=false;var codemirror_inline_editor=false;var chart_activeTimeouts={};$.ajaxPrefilter(function(a,d,c){var b=new Date().getTime()+""+Math.floor(Math.random()*1000000);if(typeof a.data=="string"){a.data+="&_nocache="+b}else{if(typeof a.data=="object"){a.data=$.extend(d.data,{_nocache:b})}}});function PMA_prepareForAjaxRequest(a){if(!a.find("input:hidden").is("#ajax_request_hidden")){a.append('')}}function suggestPassword(a){var d="abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";var e=16;var b=a.generated_pw;b.value="";for(var c=0;c=2){if(f[1].substr(0,2)=="rc"){g=-20-parseInt(f[1].substr(2))}else{if(f[1].substr(0,4)=="beta"){g=-40-parseInt(f[1].substr(4))}else{if(f[1].substr(0,5)=="alpha"){g=-60-parseInt(f[1].substr(5))}else{if(f[1].substr(0,3)=="dev"){g=0}}}}}var a=h.split(".");var c=parseInt(a[0])||0;var d=parseInt(a[1])||0;var b=parseInt(a[2])||0;var e=parseInt(a[3])||0;return c*100000000+d*1000000+b*10000+e*100+g}function PMA_current_version(d){if(d&&d.version&&d.date){var e=parseVersionString(pmaversion);var b=parseVersionString(d.version);var f=PMA_messages.strLatestAvailable+" "+escapeHtml(d.version);if(b>e){var c=$.sprintf(PMA_messages.strNewerVersion,escapeHtml(d.version),escapeHtml(d.date));if(Math.floor(b/10000)===Math.floor(e/10000)){var a="error"}else{var a="notice"}$("#maincontainer").after('
      '+c+"
      ")}if(b===e){f=" ("+PMA_messages.strUpToDate+")"}$("#li_pma_version").append(f)}}function PMA_display_git_revision(){$("#is_git_revision").remove();$.get("index.php",{server:PMA_commonParams.get("server"),token:PMA_commonParams.get("token"),git_revision:true,ajax_request:true},function(a){if(a.success==true){$(a.message).insertAfter("#li_pma_version")}})}function displayPasswordGenerateButton(){$("#tr_element_before_generate_password").parent().append(''+PMA_messages.strGeneratePassword+'');$("#div_element_before_generate_password").parent().append('
      ')}function PMA_addDatepicker(d,b){var c=false;if(d.is(".datetimefield")){c=true}var a={showOn:"button",buttonImage:themeCalendarImage,buttonImageOnly:true,stepMinutes:1,stepHours:1,showSecond:true,showTimepicker:c,showButtonPanel:false,dateFormat:"yy-mm-dd",timeFormat:"HH:mm:ss",altFieldTimeOnly:false,showAnim:"",beforeShow:function(e,f){d.data("comes_from","datepicker");setTimeout(function(){$("#ui-timepicker-div").css("z-index",$("#ui-datepicker-div").css("z-index"))},0)},onClose:function(f,e){d.data("comes_from","")}};if(c||(typeof(b)!="undefined"&&b.showTimepicker)){d.datetimepicker($.extend(a,b))}else{d.datepicker($.extend(a,b))}}function selectContent(b,a,c){if(c&&only_once_elements[b.name]){return}only_once_elements[b.name]=true;if(a){return}b.select()}function confirmLink(d,b){if(PMA_messages.strDoYouReally==""||typeof(window.opera)!="undefined"){return true}var a=confirm($.sprintf(PMA_messages.strDoYouReally,b));if(a){if($(d).hasClass("formLinkSubmit")){var c="is_js_confirmed";if($(d).attr("href").indexOf("usesubform")!=-1){c="subform["+$(d).attr("href").substr("#").match(/usesubform\[(\d+)\]/i)[1]+"][is_js_confirmed]"}$(d).parents("form").append('')}else{if(typeof(d.href)!="undefined"){d.href+="&is_js_confirmed=1"}else{if(typeof(d.form)!="undefined"){d.form.action+="?is_js_confirmed=1"}}}}return a}function confirmQuery(d,e){if(PMA_messages.strDoYouReally==""){return true}if(PMA_messages.strNoDropDatabases!=""){var f=new RegExp("(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s","i");if(f.test(e.value)){alert(PMA_messages.strNoDropDatabases);d.reset();e.focus();return false}}var b=new RegExp("^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s","i");var a=new RegExp("^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s","i");var h=new RegExp("^\\s*DELETE\\s+FROM\\s","i");var g=new RegExp("^\\s*TRUNCATE\\s","i");if(b.test(e.value)||a.test(e.value)||h.test(e.value)||g.test(e.value)){var i=(e.value.length>100)?e.value.substr(0,100)+"\n ...":e.value;var c=confirm($.sprintf(PMA_messages.strDoYouReally,i));if(c){d.elements.is_js_confirmed.value=1;return true}else{window.focus();e.focus();return false}}return true}function checkSqlQuery(d){if(codemirror_editor){d.elements.sql_query.value=codemirror_editor.getValue()}var b=d.elements.sql_query;var c=1;var a=new RegExp("\\s+");if(typeof(d.elements.sql_file)!="undefined"&&d.elements.sql_file.value.replace(a,"")!=""){return true}if(typeof(d.elements.sql_localfile)!="undefined"&&d.elements.sql_localfile.value.replace(a,"")!=""){return true}if(c&&typeof(d.elements.id_bookmark)!="undefined"&&(d.elements.id_bookmark.value!=null||d.elements.id_bookmark.value!="")&&d.elements.id_bookmark.selectedIndex!=0){return true}if(b.value.replace(a,"")!=""){if(confirmQuery(d,b)){return true}else{return false}}d.reset();c=1;if(c){b.select();alert(PMA_messages.strFormEmpty);b.focus();return false}return true}function emptyCheckTheField(d,b){var a=d.elements[b];var c=new RegExp("\\s+");return(a.value.replace(c,"")=="")?1:0}function emptyFormElements(d,b){var a=d.elements[b];var c=emptyCheckTheField(d,b);return c}function checkFormElementInRange(g,d,e,c,b){var a=g.elements[d];var f=parseInt(a.value);if(typeof(c)=="undefined"){c=0}if(typeof(b)=="undefined"){b=Number.MAX_VALUE}if(isNaN(f)){a.select();alert(PMA_messages.strNotNumber);a.focus();return false}else{if(fb){a.select();alert($.sprintf(e,f));a.focus();return false}else{a.value=f}}return true}function checkTableEditForm(g,j){var f=0;var e,h,a,k,d,c;for(e=0;e=0){if(last_shift_clicked_row>=last_clicked_row){h=last_clicked_row;a=last_shift_clicked_row}else{h=last_shift_clicked_row;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).removeClass("marked").find(":checkbox").prop("checked",false).trigger("change")}var f=$("tr.odd:not(.noclick), tr.even:not(.noclick)").index(d);if(f>=last_clicked_row){h=last_clicked_row;a=f}else{h=f;a=last_clicked_row}d.parent().find("tr.odd:not(.noclick), tr.even:not(.noclick)").slice(h,a+1).addClass("marked").find(":checkbox").prop("checked",true).trigger("change");last_shift_clicked_row=f}});addDateTimePicker();if(navigator.userAgent.match(/(iphone|ipod|ipad)/i)){$("input[type=text]").attr("autocapitalize","off").attr("autocorrect","off")}});var last_click_checked=false;var last_clicked_row=-1;var last_shift_clicked_row=-1;var marked_row=[];function markAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",true).trigger("change").parents("tr").addClass("marked");return true}function unMarkAllRows(a){$("#"+a).find("input:checkbox:enabled").prop("checked",false).trigger("change").parents("tr").removeClass("marked");return true}function setCheckboxes(b,a){$("#"+b).find("input:checkbox").prop("checked",a);return true}function setSelectOptions(b,a,c){$("form[name='"+b+"'] select[name='"+a+"']").find("option").prop("selected",c);return true}function setQuery(a){if(codemirror_editor){codemirror_editor.setValue(a);codemirror_editor.focus()}else{document.sqlform.sql_query.value=a;document.sqlform.sql_query.focus()}}function insertQuery(c){if(c=="clear"){setQuery("");return}var f="";var a=document.sqlform.dummy;var h=document.sqlform.table.value;if(a.options.length>0){sql_box_locked=true;var b="";var g="";var e="";var j=0;for(var d=0;d1){b+=", ";g+=",";e+=","}b+=a.options[d].value;g+="[value-"+j+"]";e+=a.options[d].value+"=[value-"+j+"]"}if(c=="selectall"){f="SELECT * FROM `"+h+"` WHERE 1"}else{if(c=="select"){f="SELECT "+b+" FROM `"+h+"` WHERE 1"}else{if(c=="insert"){f="INSERT INTO `"+h+"`("+b+") VALUES ("+g+")"}else{if(c=="update"){f="UPDATE `"+h+"` SET "+e+" WHERE 1"}else{if(c=="delete"){f="DELETE FROM `"+h+"` WHERE 1"}}}}}setQuery(f);sql_box_locked=false}}function insertValueQuery(){var h=document.sqlform.sql_query;var d=document.sqlform.dummy;if(d.options.length>0){sql_box_locked=true;var e="";var j=0;for(var f=0;f1){e+=", "}e+=d.options[f].value}}if(codemirror_editor){codemirror_editor.replaceSelection(e)}else{if(document.selection){h.focus();var c=document.selection.createRange();c.text=e;document.sqlform.insert.focus()}else{if(document.sqlform.sql_query.selectionStart||document.sqlform.sql_query.selectionStart=="0"){var g=document.sqlform.sql_query.selectionStart;var b=document.sqlform.sql_query.selectionEnd;var a=document.sqlform.sql_query.value;h.value=a.substring(0,g)+e+a.substring(b,a.length)}else{h.value+=e}}}sql_box_locked=false}}function addDateTimePicker(){if($.timepicker!=undefined){$("input.datefield, input.datetimefield").each(function(){PMA_addDatepicker($(this))})}}function refreshLayout(){var c=$("#pdflayout");var d=$("#orientation_opt").val();if($("#paper_opt").length==1){var e=$("#paper_opt").val()}else{var e="A4"}if(d=="P"){var b="x";var a="y"}else{var b="y";var a="x"}c.css("width",pdfPaperSize(e,b)+"px");c.css("height",pdfPaperSize(e,a)+"px")}function TableDragInit(){$(".pdflayout_table").each(function(){var c=$(this);var b=c.data("number");var a=$("#c_table_"+b+"_x").val();var d=$("#c_table_"+b+"_y").val();c.css("left",a+"px");c.css("top",d+"px");c.draggable({containment:"parent",drag:function(e,g){var f=c.data("number");$("#c_table_"+f+"_x").val(parseInt(g.position.left));$("#c_table_"+f+"_y").val(parseInt(g.position.top))}})})}function resetDrag(){$(".pdflayout_table").each(function(){var b=$(this);var a=b.data("x");var c=b.data("y");b.css("left",a+"px");b.css("top",c+"px")})}$(function(){$(".position-change").live("change",function(){var b=$(this);var a=$("#table_"+b.data("number"));a.css(b.data("axis"),b.val()+"px")});$(".paper-change").live("change",function(){var a=$("#pdflayout");if(a.css("visibility")=="visible"){refreshLayout();TableDragInit()}});$("#toggle-dragdrop").live("click",function(){var a=$("#pdflayout");if(a.css("visibility")=="hidden"){refreshLayout();TableDragInit();a.css("visibility","visible");a.css("display","block");$("#showwysiwyg").val("1")}else{a.css("visibility","hidden");a.css("display","none");$("#showwysiwyg").val("0")}});$("#reset-dragdrop").live("click",function(){resetDrag()})});function pdfPaperSize(b,a){switch(b.toUpperCase()){case"4A0":if(a=="x"){return 4767.87}else{return 6740.79}break;case"2A0":if(a=="x"){return 3370.39}else{return 4767.87}break;case"A0":if(a=="x"){return 2383.94}else{return 3370.39}break;case"A1":if(a=="x"){return 1683.78}else{return 2383.94}break;case"A2":if(a=="x"){return 1190.55}else{return 1683.78}break;case"A3":if(a=="x"){return 841.89}else{return 1190.55}break;case"A4":if(a=="x"){return 595.28}else{return 841.89}break;case"A5":if(a=="x"){return 419.53}else{return 595.28}break;case"A6":if(a=="x"){return 297.64}else{return 419.53}break;case"A7":if(a=="x"){return 209.76}else{return 297.64}break;case"A8":if(a=="x"){return 147.4}else{return 209.76}break;case"A9":if(a=="x"){return 104.88}else{return 147.4}break;case"A10":if(a=="x"){return 73.7}else{return 104.88}break;case"B0":if(a=="x"){return 2834.65}else{return 4008.19}break;case"B1":if(a=="x"){return 2004.09}else{return 2834.65}break;case"B2":if(a=="x"){return 1417.32}else{return 2004.09}break;case"B3":if(a=="x"){return 1000.63}else{return 1417.32}break;case"B4":if(a=="x"){return 708.66}else{return 1000.63}break;case"B5":if(a=="x"){return 498.9}else{return 708.66}break;case"B6":if(a=="x"){return 354.33}else{return 498.9}break;case"B7":if(a=="x"){return 249.45}else{return 354.33}break;case"B8":if(a=="x"){return 175.75}else{return 249.45}break;case"B9":if(a=="x"){return 124.72}else{return 175.75}break;case"B10":if(a=="x"){return 87.87}else{return 124.72}break;case"C0":if(a=="x"){return 2599.37}else{return 3676.54}break;case"C1":if(a=="x"){return 1836.85}else{return 2599.37}break;case"C2":if(a=="x"){return 1298.27}else{return 1836.85}break;case"C3":if(a=="x"){return 918.43}else{return 1298.27}break;case"C4":if(a=="x"){return 649.13}else{return 918.43}break;case"C5":if(a=="x"){return 459.21}else{return 649.13}break;case"C6":if(a=="x"){return 323.15}else{return 459.21}break;case"C7":if(a=="x"){return 229.61}else{return 323.15}break;case"C8":if(a=="x"){return 161.57}else{return 229.61}break;case"C9":if(a=="x"){return 113.39}else{return 161.57}break;case"C10":if(a=="x"){return 79.37}else{return 113.39}break;case"RA0":if(a=="x"){return 2437.8}else{return 3458.27}break;case"RA1":if(a=="x"){return 1729.13}else{return 2437.8}break;case"RA2":if(a=="x"){return 1218.9}else{return 1729.13}break;case"RA3":if(a=="x"){return 864.57}else{return 1218.9}break;case"RA4":if(a=="x"){return 609.45}else{return 864.57}break;case"SRA0":if(a=="x"){return 2551.18}else{return 3628.35}break;case"SRA1":if(a=="x"){return 1814.17}else{return 2551.18}break;case"SRA2":if(a=="x"){return 1275.59}else{return 1814.17}break;case"SRA3":if(a=="x"){return 907.09}else{return 1275.59}break;case"SRA4":if(a=="x"){return 637.8}else{return 907.09}break;case"LETTER":if(a=="x"){return 612}else{return 792}break;case"LEGAL":if(a=="x"){return 612}else{return 1008}break;case"EXECUTIVE":if(a=="x"){return 521.86}else{return 756}break;case"FOLIO":if(a=="x"){return 612}else{return 936}break}return 0}AJAX.registerTeardown("functions.js",function(){$("a.inline_edit_sql").die("click");$("input#sql_query_edit_save").die("click");$("input#sql_query_edit_discard").die("click");$("input.sqlbutton").unbind("click");$("#export_type").unbind("change");$("#sqlquery").unbind("keydown");$("#sql_query_edit").unbind("keydown");if(codemirror_inline_editor){$("#sql_query_edit").text(codemirror_inline_editor.getValue());$(codemirror_inline_editor.getWrapperElement()).unbind("keydown");codemirror_inline_editor.toTextArea();codemirror_inline_editor=false}if(codemirror_editor){$(codemirror_editor.getWrapperElement()).unbind("keydown")}});AJAX.registerOnload("functions.js",function(){bindCodeMirrorToInlineEditor();$("a.inline_edit_sql").live("click",function(){if($("#sql_query_edit").length){return false}var a=$(this).prev("form");var f=a.find("input[name='sql_query']").val();var e=$(this).parent().prev().find(".inner_sql");var d=e.html();var c='\n";c+='\n';c+='\n';var b=$("div#inline_editor");if(b.length==0){b=$('
      ');b.insertBefore(e)}b.html(c);e.hide();bindCodeMirrorToInlineEditor();return false});$("input#sql_query_edit_save").live("click",function(){if(codemirror_inline_editor){var b=codemirror_inline_editor.getValue()}else{var b=$(this).prev().val()}var a=$("a.inline_edit_sql").prev("form");var c=$("
      ",{action:"import.php",method:"post"}).append(a.find("input[name=server], input[name=db], input[name=table], input[name=token]").clone()).append($("",{type:"hidden",name:"show_query",value:1})).append($("",{type:"hidden",name:"sql_query",value:b}));c.appendTo($("body")).submit()});$("input#sql_query_edit_discard").live("click",function(){$("div#inline_editor_outer").empty().siblings(".inner_sql").show()});$("input.sqlbutton").click(function(a){insertQuery(a.target.id);return false});$("#export_type").change(function(){if($("#export_type").val()=="svg"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{if($("#export_type").val()=="dia"){$("#show_grid_opt").prop("disabled",true);$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled")}else{if($("#export_type").val()=="eps"){$("#show_grid_opt").prop("disabled",true);$("#orientation_opt").removeProp("disabled");$("#with_doc").prop("disabled",true);$("#show_table_dim_opt").prop("disabled",true);$("#all_tables_same_width").prop("disabled",true);$("#paper_opt").prop("disabled",true);$("#show_color_opt").prop("disabled",true)}else{if($("#export_type").val()=="pdf"){$("#show_grid_opt").removeProp("disabled");$("#orientation_opt").removeProp("disabled");$("#with_doc").removeProp("disabled");$("#show_table_dim_opt").removeProp("disabled");$("#all_tables_same_width").removeProp("disabled");$("#paper_opt").removeProp("disabled");$("#show_color_opt").removeProp("disabled")}else{}}}}});if($("#input_username")){if($("#input_username").val()==""){$("#input_username").focus()}else{$("#input_password").focus()}}});function bindCodeMirrorToInlineEditor(){var b=$("#sql_query_edit");if(b.length>0){if(typeof CodeMirror!=="undefined"){var a=$("#sql_query_edit").css("height");codemirror_inline_editor=CodeMirror.fromTextArea(b[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_inline_editor.getScrollerElement().style.height=a;codemirror_inline_editor.refresh();codemirror_inline_editor.focus();$(codemirror_inline_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{b.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}}function catchKeypressesFromSqlTextboxes(a){if(a.ctrlKey&&(a.keyCode==13||a.keyCode==10)){if($("#sql_query_edit").length>0){$("#sql_query_edit_save").trigger("click")}else{if($("#sqlquery").length>0){$("#button_submit_query").trigger("click")}}}}function PMA_ajaxShowMessage(c,d){var b=true;var e=true;if(c==""){return true}else{if(!c){c=PMA_messages.strLoading;e=false;b=false}else{if(c==PMA_messages.strProcessingRequest){e=false;b=false}}}if(d==undefined){d=5000}else{if(d===false){b=false}}if($("#loading_parent").length==0){$('
      ').prependTo("body")}ajax_message_count++;$("span.ajax_notification[id^=ajax_message_num]").remove();var a=$('').hide().appendTo("#loading_parent").html(c).show();if(b){a.delay(d).fadeOut("medium",function(){if($(this).is(".dismissable")){$(this).tooltip("destroy")}$(this).remove()})}if(e){a.addClass("dismissable").css("cursor","pointer");PMA_tooltip(a,"span",PMA_messages.strDismiss)}return a}function PMA_ajaxRemoveMessage(a){if(a!=undefined&&a instanceof jQuery){a.stop(true,true).fadeOut("medium");if(a.is(".dismissable")){if($.isFunction(a.tooltip)){a.tooltip("destroy")}}else{a.remove()}}}$(function(){$("span.ajax_notification.dismissable").live("click",function(){PMA_ajaxRemoveMessage($(this))});$("span.ajax_notification a, span.ajax_notification button, span.ajax_notification input").live("mouseover",function(){$(this).parents("span.ajax_notification").tooltip("disable")}).live("mouseout",function(){$(this).parents("span.ajax_notification").tooltip("enable")})});function PMA_showNoticeForEnum(a){var b=a.attr("id").split("_")[1];b+="_"+(parseInt(a.attr("id").split("_")[2])+1);var c=a.val();if(c=="ENUM"||c=="SET"){$("p#enum_notice_"+b).show()}else{$("p#enum_notice_"+b).hide()}}function PMA_createProfilingChartJqplot(b,a){return $.jqplot(b,[a],{seriesDefaults:{renderer:$.jqplot.PieRenderer,rendererOptions:{showDataLabels:true}},legend:{show:true,location:"e"},seriesColors:["#fce94f","#fcaf3e","#e9b96e","#8ae234","#729fcf","#ad7fa8","#ef2929","#eeeeec","#888a85","#c4a000","#ce5c00","#8f5902","#4e9a06","#204a87","#5c3566","#a40000","#babdb6","#2e3436"]})}function PMA_prettyProfilingNum(a,b){if(!b){b=2}b=Math.pow(10,b);if(a*1000<0.1){a=Math.round(b*(a*1000*1000))/b+"µ"}else{if(a<0.1){a=Math.round(b*(a*1000))/b+"m"}else{a=Math.round(b*a)/b}}return a+"s"}function PMA_SQLPrettyPrint(a){if(typeof CodeMirror=="undefined"){return a}var l=CodeMirror.getMode({},"text/x-mysql");var e=new CodeMirror.StringStream(a);var d=l.startState();var g,m=[];var h="";var t=function(y){var w="";for(var x=0;x<4*y;x++){w+=" "}return w};var u={select:["select","from","on","where","having","limit","order by","group by"],update:["update","set","where"],"insert into":["insert into","values"]};var k={";":true,",":true,".":true,"(":true};var n={".":true};var o="";while(!e.eol()){e.start=e.pos;g=l.token(e,d);if(g!=null){m.push([g,e.current().toLowerCase()])}}var q=m[0][1];if(!u[q]){return a}var s=[];var f;var b,c;var p=0;var j,v=u[q][0];s.unshift("statement");for(var r=0;r0&&m[r-1][0]=="builtin"){s.unshift(b="function")}else{s.unshift(b="generic")}}}else{b=null}if(m[r][1]==")"){c=s[0];s.shift()}else{c=null}if(r>0&&b=="statement"){p++;h+="\n"+t(p)+m[r][1]+" "+m[r+1][1].toUpperCase()+"\n"+t(p+1);q=m[r+1][1];r++;continue}if(c=="statement"&&p>0){h+="\n"+t(p);p--}j=u[q].indexOf(m[r][1]);if(j!=-1){if(r>0){h+="\n"}h+=t(p)+m[r][1].toUpperCase();h+="\n"+t(p+1);v=m[r][1]}else{if(!k[m[r][1]]&&!(r>0&&n[m[r-1][1]])&&h.charAt(h.length-1)!=" "){h+=" "}if(m[r][0]=="keyword"){h+=m[r][1].toUpperCase()}else{h+=m[r][1]}}if((v=="select"||v=="where"||v=="set")&&m[r][1]==","&&s[0]=="statement"){h+="\n"+t(p+1)}if(v=="where"&&(m[r][1]=="and"||m[r][1]=="or"||m[r][1]=="xor")){if(s[0]=="statement"){h+="\n"+t(p+1)}}}return h}jQuery.fn.PMA_confirm=function(b,d,a){var e=PMA_commonParams.get("confirm");if(e===""||e==="1"){if($.isFunction(a)){a.call(this,d);return true}}if(PMA_messages.strDoYouReally==""){return true}var c={};c[PMA_messages.strOK]=function(){$(this).dialog("close");if($.isFunction(a)){a.call(this,d)}};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};$("
      ",{id:"confirm_dialog"}).prepend(b).dialog({buttons:c,close:function(){$(this).remove()},modal:true})};jQuery.fn.PMA_sort_table=function(a){return this.each(function(){var c=$(this);var b=$(this).find("tr").get();$.each(b,function(d,e){e.sortKey=$.trim($(e).find(a).text().toLowerCase())});b.sort(function(e,d){if(e.sortKeyd.sortKey){return 1}return 0});$.each(b,function(d,e){$(c).append(e);e.sortKey=null});$(this).find("tr:odd").removeClass("even").addClass("odd").end().find("tr:even").removeClass("odd").addClass("even")})};AJAX.registerTeardown("functions.js",function(){$("#create_table_form_minimal.ajax").die("submit");$("form.create_table_form.ajax").die("submit");$("form.create_table_form.ajax input[name=submit_num_fields]").die("click");$("form.create_table_form.ajax input").die("keyup")});AJAX.registerOnload("functions.js",function(){$("form.create_table_form.ajax").live("submit",function(b){b.preventDefault();var a=$(this);if(checkTableEditForm(a[0],a.find("input[name=orig_num_fields]").val())){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&do_save_data=1",function(i){if(i.success==true){$("#properties_message").removeClass("error").html("");PMA_ajaxShowMessage(i.message);if($("#create_table_dialog").length>0){$("#create_table_dialog").dialog("close").remove()}$("#tableslistcontainer").before(i.formatted_sql);var f=$("#tablesForm").find("tbody").not("#tbl_summary_row");if(f.length==0){PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"))}else{var h=$(f).find("tr:last");var g=$(h).find("input:checkbox").attr("id").match(/\d+/)[0];var d=parseFloat(g);var c=d+1;var e="checkbox_tbl_"+c;i.new_table_string=i.new_table_string.replace(/checkbox_tbl_/,e);$(i.new_table_string).appendTo(f);$(f).PMA_sort_table("th");PMA_adjustTotals()}PMA_reloadNavigation()}else{PMA_ajaxShowMessage('
      '+i.error+"
      ",false)}})}});$("form.create_table_form.ajax input[name=submit_num_fields]").live("click",function(b){b.preventDefault();var a=$(this).closest("form");var c=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_num_fields=1",function(d){if(d.success){$("#page_content").html(d.message);PMA_verifyColumnsProperties();PMA_ajaxRemoveMessage(c)}else{PMA_ajaxShowMessage(d.error)}})});$("form.create_table_form.ajax input").live("keydown",function(a){if(a.keyCode==13){a.preventDefault();a.stopImmediatePropagation();$(this).closest("form").append('').submit()}})});AJAX.registerTeardown("functions.js",function(){$("#copyTable.ajax").die("submit");$("#moveTableForm").die("submit");$("#tableOptionsForm").die("submit");$("#tbl_maintenance li a.maintain_action.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#copyTable.ajax").live("submit",function(b){b.preventDefault();var a=$(this);PMA_prepareForAjaxRequest(a);$.post(a.attr("action"),a.serialize()+"&submit_copy=Go",function(c){if(c.success==true){if(a.find("input[name='switch_to_new']").prop("checked")){PMA_commonParams.set("db",c.db);PMA_commonParams.set("table",a.find("input[name='new_name']").val());PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(c.message)})}else{PMA_ajaxShowMessage(c.message)}PMA_reloadNavigation()}else{PMA_ajaxShowMessage(c.error,false)}})});$("#moveTableForm").live("submit",function(c){c.preventDefault();var b=$(this);var a=b.find("select[name=target_db]").val();var d=b.find("input[name=new_name]").val();PMA_prepareForAjaxRequest(b);$.post(b.attr("action"),b.serialize()+"&submit_move=1",function(e){if(e.success==true){PMA_commonParams.set("db",a);PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){PMA_ajaxShowMessage(e.message)});PMA_reloadNavigation()}else{PMA_ajaxShowMessage(e.error,false)}})});$("#tableOptionsForm").live("submit",function(c){c.preventDefault();c.stopPropagation();var b=$(this);var a=b.find("input[name=new_name]");if(a.val()!==a[0].defaultValue){PMA_prepareForAjaxRequest(b);var d=a.val();$.post(b.attr("action"),b.serialize(),function(e){if(e.success==true){PMA_commonParams.set("table",d);PMA_commonActions.refreshMain(false,function(){$("#page_content").html(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})}else{b.removeClass("ajax").submit().addClass("ajax")}});$("#tbl_maintenance li a.maintain_action.ajax").live("click",function(a){a.preventDefault();if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}$.post($(this).attr("href"),{ajax_request:1},function(f){function d(){$("html, body").animate({scrollTop:0})}if(f.success==true&&f.sql_query!=undefined){PMA_ajaxShowMessage(f.message);$("
      ").prependTo("#page_content");$("#sqlqueryresults").html(f.sql_query);d()}else{if(f.success==true){var c=$("
      ");c.html(f.message);var e=c.find("#result_query .success");PMA_ajaxShowMessage(e);$("
      ").prependTo("#page_content");$("#sqlqueryresults").html(f.message);PMA_init_slider();$("#sqlqueryresults").children("fieldset,br").remove();d()}else{var c=$("
      ");c.html(f.error);var b=c.find("code").addClass("error");PMA_ajaxShowMessage(b,false)}}})})});AJAX.registerTeardown("functions.js",function(){$("#drop_db_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_db_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropDatabaseStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP DATABASE "+escapeHtml(PMA_commonParams.get("db")));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if(d.success){PMA_reloadNavigation();PMA_commonParams.set("db","");PMA_commonActions.refreshMain("server_databases.php",function(){PMA_ajaxShowMessage(d.message)})}else{PMA_ajaxShowMessage(d.error,false)}})})})});function PMA_checkPassword(e){if(e.find("#nopass_1").is(":checked")){return true}else{var d=e.find("#select_pred_password");if(d.length&&(d.val()=="none"||d.val()=="keep")){return true}}var a=e.find("input[name=pma_pw]");var c=e.find("input[name=pma_pw2]");var b=false;if(a.val()==""){b=PMA_messages.strPasswordEmpty}else{if(a.val()!=c.val()){b=PMA_messages.strPasswordNotSame}}if(b){alert(b);a.val("");c.val("");a.focus();return false}return true}AJAX.registerTeardown("functions.js",function(){$("#change_password_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#change_password_anchor.ajax").live("click",function(b){b.preventDefault();var c=PMA_ajaxShowMessage();var a={};a[PMA_messages.strGo]=function(){b.preventDefault();var f=$("#change_password_form");if(!PMA_checkPassword(f)){return false}var d=$(this).val();var e=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);f.append('');$.post(f.attr("action"),f.serialize()+"&change_pw="+d,function(g){if(g.success==true){$("#page_content").prepend(g.message);$("#change_password_dialog").hide().remove();$("#edit_user_dialog").dialog("close").remove();PMA_ajaxRemoveMessage(e)}else{PMA_ajaxShowMessage(g.error,false)}})};a[PMA_messages.strCancel]=function(){$(this).dialog("close")};$.get($(this).attr("href"),{ajax_request:true},function(d){if(d.success){$('
      ').dialog({title:PMA_messages.strChangePassword,width:600,close:function(e,f){$(this).remove()},buttons:a,modal:true}).append(d.message);$("fieldset#fieldset_change_password").find("legend").remove().end().find("table.noclick").unwrap().addClass("some-margin").find("input#text_pma_pw").focus();displayPasswordGenerateButton();$("#fieldset_change_password_footer").hide();PMA_ajaxRemoveMessage(c);$("#change_password_form").bind("submit",function(f){f.preventDefault();$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane .ui-button").first().click()})}else{PMA_ajaxShowMessage(d.error,false)}})})});AJAX.registerTeardown("functions.js",function(){$("select.column_type").die("change");$("select.default_type").die("change");$("input.allow_null").die("change")});AJAX.registerOnload("functions.js",function(){PMA_verifyColumnsProperties();$("select.column_type").live("change",function(){PMA_showNoticeForEnum($(this))});$("select.default_type").live("change",function(){PMA_hideShowDefaultValue($(this))});$("input.allow_null").live("change",function(){PMA_validateDefaultValue($(this))})});function PMA_verifyColumnsProperties(){$("select.column_type").each(function(){PMA_showNoticeForEnum($(this))});$("select.default_type").each(function(){PMA_hideShowDefaultValue($(this))})}function PMA_hideShowDefaultValue(b){if(b.val()=="USER_DEFINED"){b.siblings(".default_value").show().focus()}else{b.siblings(".default_value").hide();if(b.val()=="NULL"){var a=b.closest("tr").find(".allow_null");a.prop("checked",true)}}}function PMA_validateDefaultValue(b){if(!b.prop("checked")){var a=b.closest("tr").find(".default_type");if(a.val()=="NULL"){a.val("NONE")}}}AJAX.registerTeardown("functions.js",function(){$("a.open_enum_editor").die("click");$("input.add_value").die("click");$("#enum_editor td.drop").die("click")});var $enum_editor_dialog=null;AJAX.registerOnload("functions.js",function(){$("a.open_enum_editor").live("click",function(){var e=$(this).closest("tr").find("input:first").val();if(e.length<1){var m=PMA_messages.enum_newColumnVals}else{var m=PMA_messages.enum_columnVals.replace(/%s/,'"'+decodeURIComponent(e)+'"')}var k=$(this).closest("td").find("input").val();k=$("
      ").text(k).html();var n=[];var j=false;var o,f,c="";for(var d=0;d0){n.push(c)}var g="";if(n.length==0){n.push("","","","")}var l=PMA_getImage("b_drop.png");for(var d=0;d"+l+""}var h="
      "+m+"

      "+PMA_getImage("s_notice.png")+PMA_messages.enum_hint+"

      "+g+"
      ";var b={};b[PMA_messages.strGo]=function(){var i=[];$(this).find(".values input").each(function(q,s){var r=s.value.replace(/\\/g,"\\\\").replace(/'/g,"''");i.push("'"+r+"'")});var p=$(this).find("input[type='hidden']").val();$("input#"+p).val(i.join(","));$(this).dialog("close")};b[PMA_messages.strClose]=function(){$(this).dialog("close")};var a=parseInt((parseInt($("html").css("font-size"),10)/13)*340,10);if(!a){a=340}$enum_editor_dialog=$(h).dialog({minWidth:a,modal:true,title:PMA_messages.enum_editor,buttons:b,open:function(){$(this).closest(".ui-dialog").find(".ui-dialog-buttonpane button:first").focus()},close:function(){$(this).remove()}});$enum_editor_dialog.find(".slider").slider({animate:true,range:"min",value:1,min:1,max:9,slide:function(i,p){$(this).closest("table").find("input[type=submit]").val($.sprintf(PMA_messages.enum_addValue,p.value))}});$("a.ui-slider-handle").addClass("ui-state-focus");return false});$("input.add_value").live("click",function(a){a.preventDefault();var b=$enum_editor_dialog.find("div.slider").slider("value");while(b--){$enum_editor_dialog.find(".values").append(""+PMA_getImage("b_drop.png")+"").find("tr:last").show("fast")}});$("#enum_editor td.drop").live("click",function(){$(this).closest("tr").hide("fast",function(){$(this).remove()})})});function checkIndexName(b){if($("#"+b).length==0){return false}var a=$("#input_index_name");var c=$("#select_index_type");if(c.find("option:selected").val()=="PRIMARY"){a.val("PRIMARY");a.prop("disabled",true)}else{if(a.val()=="PRIMARY"){a.val("")}a.prop("disabled",false)}return true}AJAX.registerTeardown("functions.js",function(){$("#index_frm input[type=submit]").die("click")});AJAX.registerOnload("functions.js",function(){$("#index_frm input[type=submit]").live("click",function(a){a.preventDefault();var b=$(this).closest("fieldset").find(".slider").slider("value");while(b--){var c=$("#index_columns").find("tbody > tr:first").clone().appendTo($("#index_columns").find("tbody"));c.find(":input").each(function(){$(this).val("")});c.find("select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()})}})});function indexEditorDialog(d,g,f,b){if($("#edit_index_dialog").length!=0){$("#edit_index_dialog").remove()}var a=$('
      ');var c={};c[PMA_messages.strGo]=function(){var h=$("#index_frm");PMA_prepareForAjaxRequest(h);$.post(h.attr("action"),h.serialize()+"&do_save_data=1",function(k){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if(k.success==true){PMA_ajaxShowMessage(k.message);if($("#result_query").length){$("#result_query").remove()}if(k.sql_query){$('
      ').html(k.sql_query).prependTo("#page_content")}$("#result_query .notice").remove();$("#result_query").prepend(k.message);$("#table_index").remove();var j=$("
      ").append(k.index_table);j.find("#table_index").insertAfter("#index_header");if($("#edit_index_dialog").length>0){$("#edit_index_dialog").dialog("close")}$("div.no_indexes_defined").hide();if(f){f()}PMA_reloadNavigation()}else{var j=$("
      ").append(k.error);if(j.find(".error code").length!=0){var i=j.find(".error code").addClass("error")}else{var i=j}if(b){b()}PMA_ajaxShowMessage(i,false)}})};c[PMA_messages.strCancel]=function(){$(this).dialog("close")};var e=PMA_ajaxShowMessage();$.get("tbl_indexes.php",d,function(i){if(i.success==false){PMA_ajaxShowMessage(i.error,false)}else{PMA_ajaxRemoveMessage(e);a.append(i.message).dialog({title:g,width:450,open:PMA_verifyColumnsProperties,modal:true,buttons:c,close:function(){$(this).remove()}});checkIndexType();checkIndexName("index_frm");PMA_showHints(a);a.find(".slider").slider({animate:true,value:1,min:1,max:16,slide:function(j,k){$(this).closest("fieldset").find("input[type=submit]").val($.sprintf(PMA_messages.strAddToIndex,k.value))}});a.find("table#index_columns select").change(function(){if($(this).find("option:selected").val()==""){return true}$(this).closest("tr").find("input").focus()});$("a.ui-slider-handle").addClass("ui-state-focus");var h=a.find("input#input_index_name");h.val()||h.focus()}})}function PMA_showHints(a){if(a==undefined||!a instanceof jQuery||a.length==0){a=$("body")}a.find(".pma_hint").each(function(){PMA_tooltip($(this).children("img"),"img",$(this).children("span").html())})}AJAX.registerOnload("functions.js",function(){PMA_showHints()});function PMA_mainMenuResizerCallback(){return $(document.body).width()-5}$(function(){$("#topmenu").menuResizer(PMA_mainMenuResizerCallback);$(window).resize(function(){$("#topmenu").menuResizer("resize")})});function PMA_getRowNumber(a){return parseInt(a.split(/\s+row_/)[1])}function PMA_set_status_label(a){var b=a.css("display")=="none"?"+ ":"- ";a.closest(".slide-wrapper").prev().find("span").text(b)}var toggleButton=function($obj){if($("span.text_direction",$obj).text()=="ltr"){var right="right"}else{var right="left"}var h=$obj.height();$("img",$obj).height(h);$("table",$obj).css("bottom",h-1);var on=$("td.toggleOn",$obj).width();var off=$("td.toggleOff",$obj).width();$("td.toggleOn > div",$obj).width(Math.max(on,off)+2);$("td.toggleOff > div",$obj).width(Math.max(on,off)+2);var w=parseInt(($("img",$obj).height()/16)*22,10);$("table td:nth-child(2) > div",$obj).width(w);var imgw=$("img",$obj).width();var tblw=$("table",$obj).width();var offset=parseInt(((imgw-tblw)/2),10);$obj.find("img").css(right,offset);var offw=$("td.toggleOff",$obj).outerWidth();var btnw=$("table td:nth-child(2)",$obj).outerWidth();$obj.width(offw+btnw+2);var move=$("td.toggleOff",$obj).outerWidth();if($("div.container",$obj).hasClass("off")){if(right=="right"){$("div.container",$obj).animate({left:"-="+move+"px"},0)}else{$("div.container",$obj).animate({left:"+="+move+"px"},0)}}$("div.container",$obj).click(function(){if($(this).hasClass("isActive")){return false}else{$(this).addClass("isActive")}var $msg=PMA_ajaxShowMessage();var $container=$(this);var callback=$("span.callback",this).text();if($(this).hasClass("on")){if(right=="right"){var operator="-="}else{var operator="+="}var url=$(this).find("td.toggleOff > span").text();var removeClass="on";var addClass="off"}else{if(right=="right"){var operator="+="}else{var operator="-="}var url=$(this).find("td.toggleOn > span").text();var removeClass="off";var addClass="on"}$.post(url,{ajax_request:true},function(data){if(data.success==true){PMA_ajaxRemoveMessage($msg);$container.removeClass(removeClass).addClass(addClass).animate({left:operator+move+"px"},function(){$container.removeClass("isActive")});eval(callback)}else{PMA_ajaxShowMessage(data.error,false);$container.removeClass("isActive")}})})};AJAX.registerTeardown("functions.js",function(){$("div.container").unbind("click")});AJAX.registerOnload("functions.js",function(){$("div.toggleAjax").each(function(){var a=$(this).show();a.find("img").each(function(){if(this.complete){toggleButton(a)}else{$(this).load(function(){toggleButton(a)})}})})});AJAX.registerTeardown("functions.js",function(){$(".vpointer").die("hover");$(".vmarker").die("click");$("#pageselector").die("change");$("a.formLinkSubmit").die("click");$("#update_recent_tables").unbind("ready")});AJAX.registerOnload("functions.js",function(){$(".vpointer").live("hover",function(c){var a=$(this);var b=PMA_getRowNumber(a.attr("class"));$(".vpointer").filter(".row_"+b).toggleClass("hover")});$(".vmarker").live("click",function(f){if($(f.target).is("a, img, a *")){return}var c=$(this);var d=PMA_getRowNumber(c.attr("class"));var a=$(".vmarker").filter(".row_"+d+":first").find(":checkbox");if(a.length){var b=a.prop("checked");if(!$(f.target).is(":checkbox, label")){b=!b;a.prop("checked",b)}if(b){$(".vmarker").filter(".row_"+d).addClass("marked")}else{$(".vmarker").filter(".row_"+d).removeClass("marked")}}else{$(".vmarker").filter(".row_"+d).toggleClass("marked")}});$("select.pageselector").live("change",function(a){a.stopPropagation();if($(this).closest("#pma_navigation").length==0){$(this).closest("form").submit()}else{PMA_navigationTreePagination($(this))}});if($("li.jsversioncheck").length>0){$.getJSON("version_check.php",{},PMA_current_version)}if($("#is_git_revision").length>0){setTimeout(PMA_display_git_revision,10)}PMA_init_slider();$("a.formLinkSubmit").live("click",function(b){if($(this).attr("href").indexOf("=")!=-1){var a=$(this).attr("href").substr($(this).attr("href").indexOf("#")+1).split("=",2);$(this).parents("form").append('')}$(this).parents("form").submit();return false});if($("#update_recent_tables").length){$.get($("#update_recent_tables").attr("href"),function(a){if(a.success==true){$("#recentTable").html(a.options)}})}});function PMA_init_slider(){$("div.pma_auto_slider").each(function(){var b=$(this);if(b.data("slider_init_done")){return}var a=$("
      ",{"class":"slide-wrapper"});a.toggle(b.is(":visible"));$("",{href:"#"+this.id,"class":"ajax"}).text(this.title).prepend($("")).insertBefore(b).click(function(){var c=b.closest(".slide-wrapper");var d=b.is(":visible");if(!d){c.show()}b[d?"hide":"show"]("blind",function(){c.toggle(!d);PMA_set_status_label(b)});return false});b.wrap(a);PMA_set_status_label(b);b.data("slider_init_done",1)})}AJAX.registerOnload("functions.js",function(){PMA_init_slider()});AJAX.registerTeardown("functions.js",function(){$("div.pma_auto_slider").each(function(){var a=$(this);a.removeData();a.parent().replaceWith(a);a.parent().children("a").remove()})});function PMA_slidingMessage(b,c){if(b==undefined||b.length==0){return false}if(c==undefined||!c instanceof jQuery||c.length==0){if($("#PMA_slidingMessage").length==0){$("#page_content").prepend('')}c=$("#PMA_slidingMessage")}if(c.has("div").length>0){c.find("div").first().fadeOut(function(){c.children().remove();c.append('
      '+b+"
      ").animate({height:c.find("div").first().height()}).find("div").first().fadeIn()})}else{var a=c.width("100%").html('
      '+b+"
      ").find("div").first().height();c.find("div").first().css("height",0).show().animate({height:a},function(){c.height(c.find("div").first().height())})}return true}AJAX.registerTeardown("functions.js",function(){$("#drop_tbl_anchor.ajax").die("click");$("#truncate_tbl_anchor.ajax").die("click")});AJAX.registerOnload("functions.js",function(){$("#drop_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strDropTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"DROP TABLE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){var d=PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(e){if(e.success==true){PMA_ajaxRemoveMessage(d);PMA_reloadNavigation();PMA_commonParams.set("table","");PMA_commonActions.refreshMain(PMA_commonParams.get("opendb_url"),function(){PMA_ajaxShowMessage(e.message)})}else{PMA_ajaxShowMessage(e.error,false)}})})});$("#truncate_tbl_anchor.ajax").live("click",function(b){b.preventDefault();var a=PMA_messages.strTruncateTableStrongWarning+" ";a+=$.sprintf(PMA_messages.strDoYouReally,"TRUNCATE "+PMA_commonParams.get("table"));$(this).PMA_confirm(a,$(this).attr("href"),function(c){PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);$.get(c,{is_js_confirmed:"1",ajax_request:true},function(d){if($("#sqlqueryresults").length!=0){$("#sqlqueryresults").remove()}if($("#result_query").length!=0){$("#result_query").remove()}if(d.success==true){PMA_ajaxShowMessage(d.message);$("
      ").prependTo("#page_content");$("#sqlqueryresults").html(d.sql_query)}else{PMA_ajaxShowMessage(d.error,false)}})})})});AJAX.registerOnload("functions.js",function(){var a=$("#sqlquery");if(a.length>0){if(typeof CodeMirror!="undefined"){codemirror_editor=CodeMirror.fromTextArea(a[0],{lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql",lineWrapping:true});codemirror_editor.focus();$(codemirror_editor.getWrapperElement()).bind("keydown",catchKeypressesFromSqlTextboxes)}else{a.focus().bind("keydown",catchKeypressesFromSqlTextboxes)}}});AJAX.registerTeardown("functions.js",function(){if(codemirror_editor){$("#sqlquery").text(codemirror_editor.getValue());codemirror_editor.toTextArea();codemirror_editor=false}});(function(a){a.fn.noSelect=function(c){var b=(c==null)?true:c;if(b){return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).bind("selectstart",function(){return false})}else{if(a.browser.mozilla){a(this).css("MozUserSelect","none");a("body").trigger("focus")}else{if(a.browser.opera){a(this).bind("mousedown",function(){return false})}else{a(this).attr("unselectable","on")}}}})}else{return this.each(function(){if(a.browser.msie||a.browser.safari){a(this).unbind("selectstart")}else{if(a.browser.mozilla){a(this).css("MozUserSelect","inherit")}else{if(a.browser.opera){a(this).unbind("mousedown")}else{a(this).removeAttr("unselectable")}}}})}}})(jQuery);(function(a){a.fn.filterByValue=function(b){return this.filter(function(){return a(this).val()===b})}})(jQuery);function PMA_tooltip(d,e,c,b){if($("#no_hint").length>0){return}var a={content:c,items:e,tooltipClass:"tooltip",track:true,show:false,hide:false};d.tooltip($.extend(true,a,b))}function PMA_getCellValue(b){var a=$(b);if(a.is(".null")){return""}else{if(!a.is(".to_be_saved")&&a.data("original_data")){return a.data("original_data")}else{return a.text()}}}AJAX.registerTeardown("functions.js",function(){$("a.themeselect").die("click");$(".autosubmit").die("change");$("a.take_theme").unbind("click")});AJAX.registerOnload("functions.js",function(){$("a.themeselect").live("click",function(a){window.open(a.target,"themes","left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes");return false});$(".autosubmit").live("change",function(a){$(this).closest("form").submit()});$("a.take_theme").click(function(b){var a=this.name;if(window.opener&&window.opener.document.forms.setTheme.elements.set_theme){window.opener.document.forms.setTheme.elements.set_theme.value=a;window.opener.document.forms.setTheme.submit();window.close();return false}return true})});function PMA_clearSelection(){if(document.selection&&document.selection.empty){document.selection.empty()}else{if(window.getSelection){var a=window.getSelection();if(a.empty){a.empty()}if(a.removeAllRanges){a.removeAllRanges()}}}}function escapeHtml(a){return a.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function printPage(){if(typeof(window.print)!="undefined"){window.print()}}AJAX.registerTeardown("functions.js",function(){$("input#print").unbind("click");$("span a.create_view.ajax").die("click");$("#createViewDialog").find("input, select").die("keydown")});AJAX.registerOnload("functions.js",function(){$("input#print").click(printPage);$("span a.create_view.ajax").live("click",function(a){a.preventDefault();PMA_createViewDialog($(this))});$("#createViewDialog").find("input, select").live("keydown",function(a){if(a.which===13){a.preventDefault();$(this).closest(".ui-dialog").find(".ui-button:first").click()}})});function PMA_createViewDialog(c){var a=PMA_ajaxShowMessage();var b=null;$.get(c.attr("href")+"&ajax_request=1",function(g){if(g.success==true){PMA_ajaxRemoveMessage(a);var h={};h[PMA_messages.strGo]=function(){if(typeof CodeMirror!=="undefined"){b.save()}a=PMA_ajaxShowMessage();$.get("view_create.php",$("#createViewDialog").find("form").serialize(),function(i){PMA_ajaxRemoveMessage(a);if(i.success===true){$("#createViewDialog").dialog("close");$("#result_query").html(i.message);PMA_reloadNavigation()}else{PMA_ajaxShowMessage(i.error,false)}})};h[PMA_messages.strClose]=function(){$(this).dialog("close")};var f=$("
      ").attr("id","createViewDialog").append(g.message).dialog({width:500,minWidth:300,maxWidth:620,modal:true,buttons:h,title:$("legend",$(g.message)).html(),close:function(){$(this).remove()}});f.find("legend").remove();if(typeof CodeMirror!=="undefined"){var d=f.find("textarea");var e={lineNumbers:true,matchBrackets:true,indentUnit:4,mode:"text/x-mysql"};b=CodeMirror.fromTextArea(d[0],e)}$("input:visible[type=text]",f).first().focus()}else{PMA_ajaxShowMessage(g.error)}})}$(function(){if($("#floating_menubar").length&&$("#PMA_disable_floating_menubar").length==0){var a=$("html").attr("dir")=="ltr"?"left":"right";$("#floating_menubar").css("margin-"+a,$("#pma_navigation").width()+$("#pma_navigation_resizer").width()).css(a,0).css({position:"fixed",top:0,width:"100%","z-index":500}).append($("#serverinfo")).append($("#topmenucontainer"));setTimeout(function(){$("body").css("padding-top",$("#floating_menubar").outerHeight(true));$("#topmenu").menuResizer("resize")},4)}});$(function(){$(document).delegate("#serverinfo, #goto_pagetop","click",function(a){a.preventDefault();$("html, body").animate({scrollTop:0},"fast")})});var checkboxes_sel="input.checkall:checkbox:enabled";$(checkboxes_sel).live("change",function(){var a=$(this.form);var c=a.find(checkboxes_sel).length;var d=a.find(checkboxes_sel+":checked").length;var b=a.find("input#checkall");if(c==d){b.prop({checked:true,indeterminate:false})}else{if(d>0){b.prop({checked:true,indeterminate:true})}else{b.prop({checked:false,indeterminate:false})}}});$("input#checkall").live("change",function(){var a=$(this).is(":checked");$(this.form).find(checkboxes_sel).prop("checked",a).parents("tr").toggleClass("marked",a)});function toggleRowColors(b){for(var a=b;a.length>0;a=a.next()){if(a.hasClass("odd")){a.removeClass("odd").addClass("even")}else{if(a.hasClass("even")){a.removeClass("even").addClass("odd")}}}}function formatBytes(b,f,a){if(!f){var f=0}if(!a){var a="."}var c=["B","KiB","MiB","GiB"];for(var e=0;b>1024&&egetPath() . '/sprites.lib.php')) { + include $_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php'; +} +$sprites = array(); +if (function_exists('PMA_sprites')) { + $sprites = PMA_sprites(); +} +// We only need the keys from the array of sprites data, +// since they contain the (partial) class names +$keys = array(); +foreach ($sprites as $key => $value) { + $keys[] = "'$key'"; +} + +?> +/** + * Returns an HTML IMG tag for a particular image from a theme, + * which may be an actual file or an icon from a sprite + * + * @param string image The name of the file to get + * @param string alternate Used to set 'alt' and 'title' attributes of the image + * @param object attributes An associative array of other attributes + * + * @return Object The requested image, this object has two methods: + * .toString() - Returns the IMG tag for the requested image + * .attr(name) - Returns a particular attribute of the IMG + * tag given it's name + * .attr(name, value) - Sets a particular attribute of the IMG + * tag to the given value + * And one property: + * .isSprite - Whether the image is a sprite or not + */ +function PMA_getImage(image, alternate, attributes) { + var in_array = function (needle, haystack) { + for (var i in haystack) { + if (haystack[i] == needle) { + return true; + } + } + return false; + }; + var sprites = [ + + ]; + // custom image object, it will eventually be returned by this functions + var retval = { + data: { + // this is private + alt: '', + title: '', + src: (typeof PMA_TEST_THEME == 'undefined' ? '' : '../') + + 'themes/dot.gif' + }, + isSprite: true, + attr: function (name, value) { + if (value == undefined) { + if (this.data[name] == undefined) { + return ''; + } else { + return this.data[name]; + } + } else { + this.data[name] = value; + } + }, + toString: function () { + var retval = '<' + 'img'; + for (var i in this.data) { + retval += ' ' + i + '="' + this.data[i] + '"'; + } + retval += ' /' + '>'; + return retval; + } + }; + // initialise missing parameters + if (attributes == undefined) { + attributes = {}; + } + if (alternate == undefined) { + alternate = ''; + } + // set alt + if (attributes.alt != undefined) { + retval.attr('alt', attributes.alt); + } else { + retval.attr('alt', alternate); + } + // set title + if (attributes.title != undefined) { + retval.attr('title', attributes.title); + } else { + retval.attr('title', alternate); + } + // set src + var klass = image.replace('.gif', '').replace('.png', ''); + if (in_array(klass, sprites)) { + // it's an icon from a sprite + retval.attr('class', 'icon ic_' + klass); + } else { + // it's an image file + retval.isSprite = false; + retval.attr('src', "getImgPath(); ?>" + image); + } + // set all other attrubutes + for (var i in attributes) { + if (i == 'src') { + // do not allow to override the 'src' attribute + continue; + } else if (i == 'class') { + retval.attr(i, retval.attr('class') + ' ' + attributes[i]); + } else { + retval.attr(i, attributes[i]); + } + } + + return retval; +} +// \ No newline at end of file diff --git a/phpmyadmin/js/get_scripts.js.php b/phpmyadmin/js/get_scripts.js.php new file mode 100644 index 000000000..564fda7dd --- /dev/null +++ b/phpmyadmin/js/get_scripts.js.php @@ -0,0 +1,38 @@ + $filename) { + if (! preg_match("@^\.+$@", $filename) + && preg_match("@^[\w\.-]+$@", $filename) + ) { + // Disallow "." and ".." alone + // Allow alphanumeric, "." and "-" chars only + $script_name .= DIRECTORY_SEPARATOR . $filename; + } + } + // Output file contents + if (preg_match("@\.js$@", $script_name) && is_readable($script_name)) { + readfile($script_name); + echo ";\n\n"; + } + } +} + +?> diff --git a/phpmyadmin/js/gis_data_editor.js b/phpmyadmin/js/gis_data_editor.js new file mode 100644 index 000000000..233df5ed7 --- /dev/null +++ b/phpmyadmin/js/gis_data_editor.js @@ -0,0 +1 @@ +var gisEditorLoaded=false;function closeGISEditor(){$("#popup_background").fadeOut("fast");$("#gis_editor").fadeOut("fast",function(){$(this).empty()})}function prepareJSVersion(){$("#gis_editor input[name='gis_data[save]']").val(PMA_messages.strCopy).insertAfter($("#gis_data_textarea")).before("

      ");$("#gis_data_editor").prepend('
      '+PMA_messages.strClose+"");$(' '+PMA_messages.strCancel+"").insertAfter($("input[name='gis_data[save]']"));$("div#gis_data_output p").remove();$("#gis_editor input.add").each(function(c){var b=$(this);b.addClass("addJs").removeClass("add");var a=b.attr("class");b.replaceWith('+ '+b.val()+"")})}function addDataPoint(a,b){return"
      "+$.sprintf(PMA_messages.strPointN,(a+1))+': '}function initGISEditorVisualization(){selectVisualization();styleOSM();loadSVG();addZoomPanControllers();zoomAndPan()}function loadJSAndGISEditor(j,h,e,c,a){var f=document.getElementsByTagName("head")[0];var g;var d=["js/jquery/jquery.svg.js","js/jquery/jquery.mousewheel.js","js/jquery/jquery.event.drag-2.0.js","js/tbl_gis_visualization.js"];for(var b=0;b
      ');f.fadeIn("fast");a.fadeIn("fast")}function insertDataAndClose(){var a=$("form#gis_data_editor_form");var b=a.find("input[name='input_name']").val();$.post("gis_data_editor.php",a.serialize()+"&generate=true&ajax_request=true",function(c){if(c.success==true){$("input[name='"+b+"']").val(c.result)}else{PMA_ajaxShowMessage(c.error,false)}},"json");closeGISEditor()}AJAX.registerTeardown("gis_data_editor.js",function(){$("#gis_editor input[name='gis_data[save]']").die("click");$("#gis_editor").die("submit");$("#gis_editor").find("input[type='text']").die("change");$("#gis_editor select.gis_type").die("change");$("#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor").die("click");$("#gis_editor a.addJs.addPoint").die("click");$("#gis_editor a.addLine.addJs").die("click");$("#gis_editor a.addJs.addPolygon").die("click");$("#gis_editor a.addJs.addGeom").die("click")});AJAX.registerOnload("gis_data_editor.js",function(){$("span.open_gis_editor a").removeClass("formLinkSubmit");$("#gis_editor input[name='gis_data[save]']").live("click",function(event){event.preventDefault();insertDataAndClose()});$("#gis_editor").live("submit",function(event){event.preventDefault();insertDataAndClose()});$("#gis_editor").find("input[type='text']").live("change",function(){var $form=$("form#gis_data_editor_form");$.post("gis_data_editor.php",$form.serialize()+"&generate=true&ajax_request=true",function(data){if(data.success==true){$("#gis_data_textarea").val(data.result);$("#placeholder").empty().removeClass("hasSVG").html(data.visualization);$("#openlayersmap").empty();eval(data.openLayers);initGISEditorVisualization()}else{PMA_ajaxShowMessage(data.error,false)}},"json")});$("#gis_editor select.gis_type").live("change",function(event){var $gis_editor=$("#gis_editor");var $form=$("form#gis_data_editor_form");$.post("gis_data_editor.php",$form.serialize()+"&get_gis_editor=true&ajax_request=true",function(data){if(data.success==true){$gis_editor.html(data.gis_editor);initGISEditorVisualization();prepareJSVersion()}else{PMA_ajaxShowMessage(data.error,false)}},"json")});$("#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor").live("click",function(){closeGISEditor()});$("#gis_editor a.addJs.addPoint").live("click",function(){var $a=$(this);var name=$a.attr("name");var prefix=name.substr(0,name.length-11);var $noOfPointsInput=$("input[name='"+prefix+"[no_of_points]']");var noOfPoints=parseInt($noOfPointsInput.val());var html=addDataPoint(noOfPoints,prefix);$a.before(html);$noOfPointsInput.val(noOfPoints+1)});$("#gis_editor a.addLine.addJs").live("click",function(){var $a=$(this);var name=$a.attr("name");var prefix=name.substr(0,name.length-10);var type=prefix.slice(prefix.lastIndexOf("[")+1,prefix.lastIndexOf("]"));var $noOfLinesInput=$("input[name='"+prefix+"[no_of_lines]']");var noOfLines=parseInt($noOfLinesInput.val());var html="
      ";if(type=="MULTILINESTRING"){html+=PMA_messages.strLineString+" "+(noOfLines+1)+":";var noOfPoints=2}else{html+=PMA_messages.strInnerRing+" "+noOfLines+":";var noOfPoints=4}html+='';for(var i=0;i+ '+PMA_messages.strAddPoint+"
      ";$a.before(html);$noOfLinesInput.val(noOfLines+1)});$("#gis_editor a.addJs.addPolygon").live("click",function(){var $a=$(this);var name=$a.attr("name");var prefix=name.substr(0,name.length-13);var $noOfPolygonsInput=$("input[name='"+prefix+"[no_of_polygons]']");var noOfPolygons=parseInt($noOfPolygonsInput.val());var html=PMA_messages.strPolygon+" "+(noOfPolygons+1)+":
      ";html+='
      '+PMA_messages.strOuterRing+':';for(var i=0;i<4;i++){html+=addDataPoint(i,(prefix+"["+noOfPolygons+"][0]"))}html+='+ '+PMA_messages.strAddPoint+'
      + '+PMA_messages.strAddInnerRing+"

      ";$a.before(html);$noOfPolygonsInput.val(noOfPolygons+1)});$("#gis_editor a.addJs.addGeom").live("click",function(){var $a=$(this);var prefix="gis_data[GEOMETRYCOLLECTION]";var $noOfGeomsInput=$("input[name='"+prefix+"[geom_count]']");var noOfGeoms=parseInt($noOfGeomsInput.val());var html1=PMA_messages.strGeometry+" "+(noOfGeoms+1)+":
      ";var $geomType=$("select[name='gis_data["+(noOfGeoms-1)+"][gis_type]']").clone();$geomType.attr("name","gis_data["+noOfGeoms+"][gis_type]").val("POINT");var html2="
      "+PMA_messages.strPoint+' :

      ';$a.before(html1);$geomType.insertBefore($a);$a.before(html2);$noOfGeomsInput.val(noOfGeoms+1)})}); \ No newline at end of file diff --git a/phpmyadmin/js/import.js b/phpmyadmin/js/import.js new file mode 100644 index 000000000..c250baedc --- /dev/null +++ b/phpmyadmin/js/import.js @@ -0,0 +1 @@ +function changePluginOpts(){$("#format_specific_opts div.format_specific_options").each(function(){$(this).hide()});var a=$("#plugins option:selected").val();$("#"+a+"_options").fadeIn("slow");if(a=="csv"){$("#import_notification").text(PMA_messages.strImportCSV)}else{$("#import_notification").text("")}}function matchFile(d){var b=d.toLowerCase().split(".");var a=b.length;if(a!=0){var c=b[a-1];if(c=="gz"||c=="bz2"||c=="zip"){a--}if($("select[name='format'] option").filterByValue(b[a-1]).length==1){$("select[name='format'] option").filterByValue(b[a-1]).prop("selected",true);changePluginOpts()}}}AJAX.registerTeardown("import.js",function(){$("#plugins").unbind("change");$("#input_import_file").unbind("change");$("#select_local_import_file").unbind("change");$("#input_import_file").unbind("change").unbind("focus");$("#select_local_import_file").unbind("focus")});AJAX.registerOnload("import.js",function(){changePluginOpts();$("#plugins").change(function(){changePluginOpts()});$("#input_import_file").change(function(){matchFile($(this).val())});$("#select_local_import_file").change(function(){matchFile($(this).val())});$("#input_import_file").bind("focus change",function(){$("#radio_import_file").prop("checked",true);$("#radio_local_import_file").prop("checked",false)});$("#select_local_import_file").focus(function(){$("#radio_local_import_file").prop("checked",true);$("#radio_import_file").prop("checked",false)});$("#scroll_to_options_msg").hide();$("#format_specific_opts div.format_specific_options").css({border:0,margin:0,padding:0}).find("h3").remove()}); \ No newline at end of file diff --git a/phpmyadmin/js/indexes.js b/phpmyadmin/js/indexes.js new file mode 100644 index 000000000..ec86dc574 --- /dev/null +++ b/phpmyadmin/js/indexes.js @@ -0,0 +1 @@ +function checkIndexType(){$select_index_type=$("#select_index_type");$size_header=$("#index_columns thead tr th:nth-child(2)");$column_inputs=$('select[name="index[columns][names][]"]');$size_inputs=$('input[name="index[columns][sub_parts][]"]');$add_more=$("#index_frm .tblFooters");if($select_index_type.val()=="SPATIAL"){$size_header.hide();$size_inputs.each(function(){$(this).prop("disabled",true).parent("td").hide()});var a=true;$column_inputs.each(function(){$column_input=$(this);if(!a){$column_input.prop("disabled",true).parent("td").hide()}else{a=false}});$add_more.hide()}else{$size_header.show();$size_inputs.each(function(){$(this).prop("disabled",false).parent("td").show()});$column_inputs.each(function(){$(this).prop("disabled",false).parent("td").show()});$add_more.show()}}AJAX.registerTeardown("indexes.js",function(){$("#select_index_type").die("change");$("a.drop_primary_key_index_anchor.ajax").die("click");$("#table_index tbody tr td.edit_index.ajax, #indexes .add_index.ajax").die("click");$("#index_frm input[type=submit]").die("click")});AJAX.registerOnload("indexes.js",function(){checkIndexType();checkIndexName("index_frm");$("#select_index_type").live("change",function(a){a.preventDefault();checkIndexType();checkIndexName("index_frm")});$("a.drop_primary_key_index_anchor.ajax").live("click",function(f){f.preventDefault();var e=$(this);var c=e.parents("tr");var g=e.parents("td").attr("rowspan")||1;var h=c;for(var d=1,a=c.next();d tr").length){k.hide("medium",function(){$("div.no_indexes_defined").show("medium");h.remove()});k.siblings("div.notice").hide("medium")}else{toggleRowColors(h.last().next());h.hide("medium",function(){$(this).remove()})}if($("#result_query").length){$("#result_query").remove()}if(l.sql_query){$('
      ').html(l.sql_query).prependTo("#page_content")}PMA_commonActions.refreshMain(false,function(){$("a.ajax[href^=#indexes]").click()});PMA_reloadNavigation()}else{PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest+" : "+l.error,false)}})})});$("#table_index tbody tr td.edit_index.ajax, #indexes .add_index.ajax").live("click",function(c){c.preventDefault();if($(this).find("a").length==0){var b=checkFormElementInRange($(this).closest("form")[0],"added_fields","Column count has to be larger than zero.");if(!b){return}var a=$(this).closest("form").serialize();var d=PMA_messages.strAddIndex}else{var a=$(this).find("a").attr("href");if(a.substring(0,16)=="tbl_indexes.php?"){a=a.substring(16,a.length)}var d=PMA_messages.strEditIndex}a+="&ajax_request=true";indexEditorDialog(a,d,function(){PMA_commonActions.refreshMain(false,function(){$("a.ajax[href^=#indexes]").click()})})})}); \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/excanvas.js b/phpmyadmin/js/jqplot/excanvas.js new file mode 100644 index 000000000..f583bbb81 --- /dev/null +++ b/phpmyadmin/js/jqplot/excanvas.js @@ -0,0 +1 @@ +if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;i.family="'"+i.family.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'";return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(al){var aj=[];var Z=false;var m=10;var am=10;aj.push("ak.x){ak.x=j.x}if(ag.y==null||j.yak.y){ak.y=j.y}}}aj.push(' ">');if(!al){w(this,aj)}else{G(this,aj,ag,ak)}aj.push("");this.element_.insertAdjacentHTML("beforeEnd",aj.join(""))};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d+1-ao[0][0])+","+n(aq.y/d-2*ao[1][0]);ag.push('','','');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P;G_vmlCanvasManager._version=888})()}; \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/jquery.jqplot.js b/phpmyadmin/js/jqplot/jquery.jqplot.js new file mode 100644 index 000000000..b7aee6538 --- /dev/null +++ b/phpmyadmin/js/jqplot/jquery.jqplot.js @@ -0,0 +1 @@ +(function(H){var r;H.fn.emptyForce=function(){for(var ab=0,ac;(ac=H(this)[ab])!=null;ab++){if(ac.nodeType===1){H.cleanData(ac.getElementsByTagName("*"))}if(H.jqplot.use_excanvas){ac.outerHTML=""}else{while(ac.firstChild){ac.removeChild(ac.firstChild)}}ac=null}return H(this)};H.fn.removeChildForce=function(ab){while(ab.firstChild){this.removeChildForce(ab.firstChild);ab.removeChild(ab.firstChild)}};H.fn.jqplot=function(){var ab=[];var ad=[];for(var ae=0,ac=arguments.length;ae'+ai+"
      ");H("#"+ah).addClass("jqplot-error");document.getElementById(ah).style.background=H.jqplot.config.errorBackground;document.getElementById(ah).style.border=H.jqplot.config.errorBorder;document.getElementById(ah).style.fontFamily=H.jqplot.config.errorFontFamily;document.getElementById(ah).style.fontSize=H.jqplot.config.errorFontSize;document.getElementById(ah).style.fontStyle=H.jqplot.config.errorFontStyle;document.getElementById(ah).style.fontWeight=H.jqplot.config.errorFontWeight}}else{ag.init(ah,ad,ab);ag.draw();ag.themeEngine.init.call(ag);return ag}};H.jqplot.version="1.0.4";H.jqplot.revision="1121";H.jqplot.targetCounter=1;H.jqplot.CanvasManager=function(){if(typeof H.jqplot.CanvasManager.canvases=="undefined"){H.jqplot.CanvasManager.canvases=[];H.jqplot.CanvasManager.free=[]}var ab=[];this.getCanvas=function(){var ae;var ad=true;if(!H.jqplot.use_excanvas){for(var af=0,ac=H.jqplot.CanvasManager.canvases.length;af887){H.jqplot.support_canvas_text.result=true}else{H.jqplot.support_canvas_text.result=!!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}}return H.jqplot.support_canvas_text.result};H.jqplot.use_excanvas=(H.browser.msie&&!H.jqplot.support_canvas())?true:false;H.jqplot.preInitHooks=[];H.jqplot.postInitHooks=[];H.jqplot.preParseOptionsHooks=[];H.jqplot.postParseOptionsHooks=[];H.jqplot.preDrawHooks=[];H.jqplot.postDrawHooks=[];H.jqplot.preDrawSeriesHooks=[];H.jqplot.postDrawSeriesHooks=[];H.jqplot.preDrawLegendHooks=[];H.jqplot.addLegendRowHooks=[];H.jqplot.preSeriesInitHooks=[];H.jqplot.postSeriesInitHooks=[];H.jqplot.preParseSeriesOptionsHooks=[];H.jqplot.postParseSeriesOptionsHooks=[];H.jqplot.eventListenerHooks=[];H.jqplot.preDrawSeriesShadowHooks=[];H.jqplot.postDrawSeriesShadowHooks=[];H.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};H.jqplot.ElemContainer.prototype.createElement=function(ae,ag,ac,ad,ah){this._offsets=ag;var ab=ac||"jqplot";var af=document.createElement(ae);this._elem=H(af);this._elem.addClass(ab);this._elem.css(ad);this._elem.attr(ah);af=null;return this._elem};H.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};H.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};H.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};H.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};H.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};H.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};H.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function s(ab){H.jqplot.ElemContainer.call(this);this.name=ab;this._series=[];this.show=false;this.tickRenderer=H.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=H.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=H.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.drawMajorGridlines=true;this.drawMinorGridlines=false;this.drawMajorTickMarks=true;this.drawMinorTickMarks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this.scaleToHiddenSeries=false;this._dataBounds={min:null,max:null};this._intervalStats=[];this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null;this._options={}}s.prototype=new H.jqplot.ElemContainer();s.prototype.constructor=s;s.prototype.init=function(){if(H.isFunction(this.renderer)){this.renderer=new this.renderer()}this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};s.prototype.draw=function(ab,ac){if(this.__ticks){this.__ticks=null}return this.renderer.draw.call(this,ab,ac)};s.prototype.set=function(){this.renderer.set.call(this)};s.prototype.pack=function(ac,ab){if(this.show){this.renderer.pack.call(this,ac,ab)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};s.prototype.reset=function(){this.renderer.reset.call(this)};s.prototype.resetScale=function(ab){H.extend(true,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},ab);this.resetDataBounds()};s.prototype.resetDataBounds=function(){var ai=this._dataBounds;ai.min=null;ai.max=null;var ac,aj,ag;var ad=(this.show)?true:false;for(var af=0;afai.max)||ai.max==null){ai.max=ag[ae][0]}}else{if((ag[ae][ab]!=null&&ag[ae][ab]ai.max)||ai.max==null){ai.max=ag[ae][ah]}}}if(ad&&aj.renderer.constructor!==H.jqplot.BarRenderer){ad=false}else{if(ad&&this._options.hasOwnProperty("forceTickAt0")&&this._options.forceTickAt0==false){ad=false}else{if(ad&&aj.renderer.constructor===H.jqplot.BarRenderer){if(aj.barDirection=="vertical"&&this.name!="xaxis"&&this.name!="x2axis"){if(this._options.pad!=null||this._options.padMin!=null){ad=false}}else{if(aj.barDirection=="horizontal"&&(this.name=="xaxis"||this.name=="x2axis")){if(this._options.pad!=null||this._options.padMin!=null){ad=false}}}}}}}}if(ad&&this.renderer.constructor===H.jqplot.LinearAxisRenderer&&ai.min>=0){this.padMin=1;this.forceTickAt0=true}};function n(ab){H.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=H.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];H.extend(true,this,ab)}n.prototype=new H.jqplot.ElemContainer();n.prototype.constructor=n;n.prototype.setOptions=function(ab){H.extend(true,this,ab);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};n.prototype.init=function(){if(H.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};n.prototype.draw=function(ac,ad){for(var ab=0;ab
      ');this.target.append(at);at.height(ax);at.width(au);at.css("top",this.eventCanvas._offsets.top);at.css("left",this.eventCanvas._offsets.left);var aw=H('
      ');at.append(aw);aw.html(this.noDataIndicator.indicator);var av=aw.height();var ar=aw.width();aw.height(av);aw.width(ar);aw.css("top",(ax-av)/2+"px")})}}this.data=H.extend(true,[],al);this.parseOptions(aq);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.computePlotData();for(var am=0;am0){for(var ak=an;ak--;){var ah=this._plotData[ak][aj][ao];if(ap*ah>=0){this._plotData[an][aj][ao]+=ah;this._stackData[an][aj][ao]+=ah;break}}}}}else{for(var al=0;al0){am._prevPlotData=this.series[an-1]._plotData}am._sumy=0;am._sumx=0;for(al=am.data.length-1;al>-1;al--){am._sumy+=am.data[al][1];am._sumx+=am.data[al][0]}}};this.populatePlotData=function(an,ao){this._plotData=[];this._stackData=[];an._stackData=[];an._plotData=[];var ar={x:[],y:[]};if(this.stackSeries&&!an.disableStack){an._stack=true;var aq=(an._stackAxis==="x")?0:1;var at=H.extend(true,[],an.data);var au=H.extend(true,[],an.data);var ah,ag,ai,ap,af;for(var al=0;al=0){au[ak][aq]+=ap}}}for(var am=0;am0){an._prevPlotData=this.series[ao-1]._plotData}an._sumy=0;an._sumx=0;for(am=an.data.length-1;am>-1;am--){an._sumy+=an.data[am][1];an._sumx+=an.data[am][0]}};this.getNextSeriesColor=(function(ag){var af=0;var ah=ag.seriesColors;return function(){if(af=0&&ah>=0){af.top+=aE;af.bottom+=aE;af.left+=ah;af.right+=ah}}var ag=["top","bottom","left","right"];for(var au in ag){if(this._gridPadding[ag[au]]==null&&af[ag[au]]>0){this._gridPadding[ag[au]]=af[ag[au]]}else{if(this._gridPadding[ag[au]]==null){this._gridPadding[ag[au]]=this._defaultGridPadding[ag[au]]}}}var at=this._gridPadding;if(this.legend.placement==="outsideGrid"){at={top:this.title.getHeight(),left:0,right:0,bottom:0};if(this.legend.location==="s"){at.left=this._gridPadding.left;at.right=this._gridPadding.right}}al.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-al.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});al.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-al.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});al.x2axis.pack({position:"absolute",top:this._gridPadding.top-al.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aB=8;aB>0;aB--){al[aA[aB-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-ar[aB-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var an=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-al.yMidAxis.getWidth()/2;al.yMidAxis.pack({position:"absolute",top:0,left:an,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});this.target.append(this.grid.createElement(this._gridPadding,this));this.grid.draw();var ak=this.series;var aD=ak.length;for(aB=0,ay=aD;aBaq)?ao:aq;var al=this.series[ap];var ak=this.series[an];if(ak.renderer.smooth){var aj=ak.renderer._smoothedData.slice(0).reverse()}else{var aj=ak.gridData.slice(0).reverse()}if(al.renderer.smooth){var am=al.renderer._smoothedData.concat(aj)}else{var am=al.gridData.concat(aj)}var ai=(ah.color!==null)?ah.color:this.series[aq].fillColor;var ar=(ah.baseSeries!==null)?ah.baseSeries:ap;var ag=this.series[ar].renderer.shapeRenderer;var af={fillStyle:ai,fill:true,closePath:true};ag.draw(al.shadowCanvas._ctx,am,af)};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function ac(ao){var am=ao.data.plot;var ai=am.eventCanvas._elem.offset();var al={x:ao.pageX-ai.left,y:ao.pageY-ai.top};var aj={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var ak=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var af=am.axes;var ag,ah;for(ag=11;ag>0;ag--){ah=ak[ag-1];if(af[ah].show){aj[ah]=af[ah].series_p2u(al[ah.charAt(0)])}}return{offsets:ai,gridPos:al,dataPos:aj}}function ae(af,ag){var ak=ag.series;var aQ,aO,aN,aI,aJ,aD,aC,ap,an,at,au,aE;var aM,aR,aK,al,aB,aG,aP;var ah,aH;for(aN=ag.seriesStack.length-1;aN>=0;aN--){aQ=ag.seriesStack[aN];aI=ak[aQ];aP=aI._highlightThreshold;switch(aI.renderer.constructor){case H.jqplot.BarRenderer:aD=af.x;aC=af.y;for(aO=0;aOaB[0][0]&&aDaB[2][1]&&aCaB[0][0]+aP[0][0]&&aDaB[2][1]&&aC0&&-aC>=0){ap=2*Math.PI-Math.atan(-aC/aD)}else{if(aD>0&&-aC<0){ap=-Math.atan(-aC/aD)}else{if(aD<0){ap=Math.PI-Math.atan(-aC/aD)}else{if(aD==0&&-aC>0){ap=3*Math.PI/2}else{if(aD==0&&-aC<0){ap=Math.PI/2}else{if(aD==0&&aC==0){ap=0}}}}}}if(at){ap-=at;if(ap<0){ap+=2*Math.PI}else{if(ap>2*Math.PI){ap-=2*Math.PI}}}an=aI.sliceMargin/180*Math.PI;if(aJaI._innerRadius){for(aO=0;aO0)?aI.gridData[aO-1][1]+an:an;aE=aI.gridData[aO][1];if(ap>au&&ap0&&-aC>=0){ap=2*Math.PI-Math.atan(-aC/aD)}else{if(aD>0&&-aC<0){ap=-Math.atan(-aC/aD)}else{if(aD<0){ap=Math.PI-Math.atan(-aC/aD)}else{if(aD==0&&-aC>0){ap=3*Math.PI/2}else{if(aD==0&&-aC<0){ap=Math.PI/2}else{if(aD==0&&aC==0){ap=0}}}}}}if(at){ap-=at;if(ap<0){ap+=2*Math.PI}else{if(ap>2*Math.PI){ap-=2*Math.PI}}}an=aI.sliceMargin/180*Math.PI;if(aJ0)?aI.gridData[aO-1][1]+an:an;aE=aI.gridData[aO][1];if(ap>au&&ap=ar[0][1]&&aC<=ar[3][1]&&aD>=am[0]&&aD<=ay[0]){return{seriesIndex:aI.index,pointIndex:aO,gridData:null,data:aI.data[aO]}}}break;case H.jqplot.LineRenderer:aD=af.x;aC=af.y;aJ=aI.renderer;if(aI.show){if((aI.fill||(aI.renderer.bands.show&&aI.renderer.bands.fill))&&(!ag.plugins.highlighter||!ag.plugins.highlighter.show)){var aq=false;if(aD>aI._boundingBox[0][0]&&aDaI._boundingBox[1][1]&&aC=aC||av[1]=aC){if(aw[0]+(aC-aw[1])/(av[1]-aw[1])*(av[0]-aw[0])0)?aH:0;for(var aO=0;aO=aK[0]-aJ._bodyWidth/2&&aD<=aK[0]+aJ._bodyWidth/2&&aC>=ao(aI.data[aO][2])&&aC<=ao(aI.data[aO][3])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}else{if(!aJ.hlc){var ao=aI._yaxis.series_u2p;if(aD>=aK[0]-aJ._tickLength&&aD<=aK[0]+aJ._tickLength&&aC>=ao(aI.data[aO][2])&&aC<=ao(aI.data[aO][3])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}else{var ao=aI._yaxis.series_u2p;if(aD>=aK[0]-aJ._tickLength&&aD<=aK[0]+aJ._tickLength&&aC>=ao(aI.data[aO][1])&&aC<=ao(aI.data[aO][2])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}}}else{if(aK[0]!=null&&aK[1]!=null){aR=Math.sqrt((aD-aK[0])*(aD-aK[0])+(aC-aK[1])*(aC-aK[1]));if(aR<=ah&&(aR<=aM||aM==null)){aM=aR;return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}}}}}break;default:aD=af.x;aC=af.y;aJ=aI.renderer;if(aI.show){aH=aI.markerRenderer.size/2+aI.neighborThreshold;ah=(aH>0)?aH:0;for(var aO=0;aO=aK[0]-aJ._bodyWidth/2&&aD<=aK[0]+aJ._bodyWidth/2&&aC>=ao(aI.data[aO][2])&&aC<=ao(aI.data[aO][3])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}else{if(!aJ.hlc){var ao=aI._yaxis.series_u2p;if(aD>=aK[0]-aJ._tickLength&&aD<=aK[0]+aJ._tickLength&&aC>=ao(aI.data[aO][2])&&aC<=ao(aI.data[aO][3])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}else{var ao=aI._yaxis.series_u2p;if(aD>=aK[0]-aJ._tickLength&&aD<=aK[0]+aJ._tickLength&&aC>=ao(aI.data[aO][1])&&aC<=ao(aI.data[aO][2])){return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}}}else{aR=Math.sqrt((aD-aK[0])*(aD-aK[0])+(aC-aK[1])*(aC-aK[1]));if(aR<=ah&&(aR<=aM||aM==null)){aM=aR;return{seriesIndex:aQ,pointIndex:aO,gridData:aK,data:aI.data[aO]}}}}}break}}return null}this.onClick=function(ah){var ag=ac(ah);var aj=ah.data.plot;var ai=ae(ag.gridPos,aj);var af=H.Event("jqplotClick");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])};this.onDblClick=function(ah){var ag=ac(ah);var aj=ah.data.plot;var ai=ae(ag.gridPos,aj);var af=H.Event("jqplotDblClick");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])};this.onMouseDown=function(ah){var ag=ac(ah);var aj=ah.data.plot;var ai=ae(ag.gridPos,aj);var af=H.Event("jqplotMouseDown");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])};this.onMouseUp=function(ah){var ag=ac(ah);var af=H.Event("jqplotMouseUp");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,null,ah.data.plot])};this.onRightClick=function(ah){var ag=ac(ah);var aj=ah.data.plot;var ai=ae(ag.gridPos,aj);if(aj.captureRightClick){if(ah.which==3){var af=H.Event("jqplotRightClick");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])}else{var af=H.Event("jqplotMouseUp");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])}}};this.onMouseMove=function(ah){var ag=ac(ah);var aj=ah.data.plot;var ai=ae(ag.gridPos,aj);var af=H.Event("jqplotMouseMove");af.pageX=ah.pageX;af.pageY=ah.pageY;H(this).trigger(af,[ag.gridPos,ag.dataPos,ai,aj])};this.onMouseEnter=function(ah){var ag=ac(ah);var ai=ah.data.plot;var af=H.Event("jqplotMouseEnter");af.pageX=ah.pageX;af.pageY=ah.pageY;af.relatedTarget=ah.relatedTarget;H(this).trigger(af,[ag.gridPos,ag.dataPos,null,ai])};this.onMouseLeave=function(ah){var ag=ac(ah);var ai=ah.data.plot;var af=H.Event("jqplotMouseLeave");af.pageX=ah.pageX;af.pageY=ah.pageY;af.relatedTarget=ah.relatedTarget;H(this).trigger(af,[ag.gridPos,ag.dataPos,null,ai])};this.drawSeries=function(ah,af){var aj,ai,ag;af=(typeof(ah)==="number"&&af==null)?ah:af;ah=(typeof(ah)==="object")?ah:{};if(af!=r){ai=this.series[af];ag=ai.shadowCanvas._ctx;ag.clearRect(0,0,ag.canvas.width,ag.canvas.height);ai.drawShadow(ag,ah,this);ag=ai.canvas._ctx;ag.clearRect(0,0,ag.canvas.width,ag.canvas.height);ai.draw(ag,ah,this);if(ai.renderer.constructor==H.jqplot.BezierCurveRenderer){if(af660)?ab[ad]*0.85:0.73*ab[ad]+90;ab[ad]=parseInt(ab[ad],10);(ab[ad]>255)?255:ab[ad]}ab[3]=0.3+0.35*af[3];ae.push("rgba("+ab[0]+","+ab[1]+","+ab[2]+","+ab[3]+")")}}else{var af=H.jqplot.getColorComponents(ac);var ab=[af[0],af[1],af[2]];var ah=ab[0]+ab[1]+ab[2];for(var ad=0;ad<3;ad++){ab[ad]=(ah>660)?ab[ad]*0.85:0.73*ab[ad]+90;ab[ad]=parseInt(ab[ad],10);(ab[ad]>255)?255:ab[ad]}ab[3]=0.3+0.35*af[3];ae="rgba("+ab[0]+","+ab[1]+","+ab[2]+","+ab[3]+")"}return ae};H.jqplot.ColorGenerator=function(ac){ac=ac||H.jqplot.config.defaultColors;var ab=0;this.next=function(){if(ab0){return ac[ab--]}else{ab=ac.length-1;return ac[ab]}};this.get=function(ae){var ad=ae-ac.length*Math.floor(ae/ac.length);return ac[ad]};this.setColors=function(ad){ac=ad};this.reset=function(){ab=0};this.getIndex=function(){return ab};this.setIndex=function(ad){ab=ad}};H.jqplot.hex2rgb=function(ad,ab){ad=ad.replace("#","");if(ad.length==3){ad=ad.charAt(0)+ad.charAt(0)+ad.charAt(1)+ad.charAt(1)+ad.charAt(2)+ad.charAt(2)}var ac;ac="rgba("+parseInt(ad.slice(0,2),16)+", "+parseInt(ad.slice(2,4),16)+", "+parseInt(ad.slice(4,6),16);if(ab){ac+=", "+ab}ac+=")";return ac};H.jqplot.rgb2hex=function(ag){var ad=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var ab=ag.match(ad);var af="#";for(var ae=1;ae<4;ae++){var ac;if(ab[ae].search(/%/)!=-1){ac=parseInt(255*ab[ae]/100,10).toString(16);if(ac.length==1){ac="0"+ac}}else{ac=parseInt(ab[ae],10).toString(16);if(ac.length==1){ac="0"+ac}}af+=ac}return af};H.jqplot.normalize2rgb=function(ac,ab){if(ac.search(/^ *rgba?\(/)!=-1){return ac}else{if(ac.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return H.jqplot.hex2rgb(ac,ab)}else{throw"invalid color spec"}}};H.jqplot.getColorComponents=function(ag){ag=H.jqplot.colorKeywordMap[ag]||ag;var ae=H.jqplot.normalize2rgb(ag);var ad=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var ab=ae.match(ad);var ac=[];for(var af=1;af<4;af++){if(ab[af].search(/%/)!=-1){ac[af-1]=parseInt(255*ab[af]/100,10)}else{ac[af-1]=parseInt(ab[af],10)}}ac[3]=parseFloat(ab[4])?parseFloat(ab[4]):1;return ac};H.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};H.jqplot.AxisLabelRenderer=function(ab){H.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;H.extend(true,this,ab)};H.jqplot.AxisLabelRenderer.prototype=new H.jqplot.ElemContainer();H.jqplot.AxisLabelRenderer.prototype.constructor=H.jqplot.AxisLabelRenderer;H.jqplot.AxisLabelRenderer.prototype.init=function(ab){H.extend(true,this,ab)};H.jqplot.AxisLabelRenderer.prototype.draw=function(ab,ac){if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=H('
      ');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};H.jqplot.AxisLabelRenderer.prototype.pack=function(){};H.jqplot.AxisTickRenderer=function(ab){H.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label=null;this.value=null;this._styles={};this.formatter=H.jqplot.DefaultTickFormatter;this.prefix="";this.suffix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this.escapeHTML=false;this._elem;this._breakTick=false;H.extend(true,this,ab)};H.jqplot.AxisTickRenderer.prototype.init=function(ab){H.extend(true,this,ab)};H.jqplot.AxisTickRenderer.prototype=new H.jqplot.ElemContainer();H.jqplot.AxisTickRenderer.prototype.constructor=H.jqplot.AxisTickRenderer;H.jqplot.AxisTickRenderer.prototype.setTick=function(ab,ad,ac){this.value=ab;this.axis=ad;if(ac){this.isMinorTick=true}return this};H.jqplot.AxisTickRenderer.prototype.draw=function(){if(this.label===null){this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix}var ac={position:"absolute"};if(Number(this.label)){ac.whitSpace="nowrap"}if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=H(document.createElement("div"));this._elem.addClass("jqplot-"+this.axis+"-tick");if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}this._elem.css(ac);for(var ab in this._styles){this._elem.css(ab,this._styles[ab])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}if(this._breakTick){this._elem.addClass("jqplot-breakTick")}return this._elem};H.jqplot.DefaultTickFormatter=function(ab,ac){if(typeof ac=="number"){if(!ab){ab=H.jqplot.config.defaultTickFormatString}return H.jqplot.sprintf(ab,ac)}else{return String(ac)}};H.jqplot.PercentTickFormatter=function(ab,ac){if(typeof ac=="number"){ac=100*ac;if(!ab){ab=H.jqplot.config.defaultTickFormatString}return H.jqplot.sprintf(ab,ac)}else{return String(ac)}};H.jqplot.AxisTickRenderer.prototype.pack=function(){};H.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new H.jqplot.ShadowRenderer()};H.jqplot.CanvasGridRenderer.prototype.init=function(ac){this._ctx;H.extend(true,this,ac);var ab={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(ab)};H.jqplot.CanvasGridRenderer.prototype.createElement=function(ae){var ad;if(this._elem){if(H.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==r){ad=this._elem.get(0);window.G_vmlCanvasManager.uninitElement(ad);ad=null}this._elem.emptyForce();this._elem=null}ad=ae.canvasManager.getCanvas();var ab=this._plotDimensions.width;var ac=this._plotDimensions.height;ad.width=ab;ad.height=ac;this._elem=H(ad);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});ad=ae.canvasManager.initCanvas(ad);this._top=this._offsets.top;this._bottom=ac-this._offsets.bottom;this._left=this._offsets.left;this._right=ab-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;ad=null;return this._elem};H.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var am=this._ctx;var ap=this._axes;am.save();am.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);am.fillStyle=this.backgroundColor||this.background;am.fillRect(this._left,this._top,this._width,this._height);am.save();am.lineJoin="miter";am.lineCap="butt";am.lineWidth=this.gridLineWidth;am.strokeStyle=this.gridLineColor;var at,ar,aj,ak;var ag=["xaxis","yaxis","x2axis","y2axis"];for(var aq=4;aq>0;aq--){var aw=ag[aq-1];var ab=ap[aw];var au=ab._ticks;var al=au.length;if(ab.show){if(ab.drawBaseline){var av={};if(ab.baselineWidth!==null){av.lineWidth=ab.baselineWidth}if(ab.baselineColor!==null){av.strokeStyle=ab.baselineColor}switch(aw){case"xaxis":ai(this._left,this._bottom,this._right,this._bottom,av);break;case"yaxis":ai(this._left,this._bottom,this._left,this._top,av);break;case"x2axis":ai(this._left,this._bottom,this._right,this._bottom,av);break;case"y2axis":ai(this._right,this._bottom,this._right,this._top,av);break}}for(var an=al;an>0;an--){var ah=au[an-1];if(ah.show){var ae=Math.round(ab.u2p(ah.value))+0.5;switch(aw){case"xaxis":if(ah.showGridline&&this.drawGridlines&&((!ah.isMinorTick&&ab.drawMajorGridlines)||(ah.isMinorTick&&ab.drawMinorGridlines))){ai(ae,this._top,ae,this._bottom)}if(ah.showMark&&ah.mark&&((!ah.isMinorTick&&ab.drawMajorTickMarks)||(ah.isMinorTick&&ab.drawMinorTickMarks))){aj=ah.markSize;ak=ah.mark;var ae=Math.round(ab.u2p(ah.value))+0.5;switch(ak){case"outside":at=this._bottom;ar=this._bottom+aj;break;case"inside":at=this._bottom-aj;ar=this._bottom;break;case"cross":at=this._bottom-aj;ar=this._bottom+aj;break;default:at=this._bottom;ar=this._bottom+aj;break}if(this.shadow){this.renderer.shadowRenderer.draw(am,[[ae,at],[ae,ar]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ai(ae,at,ae,ar)}break;case"yaxis":if(ah.showGridline&&this.drawGridlines&&((!ah.isMinorTick&&ab.drawMajorGridlines)||(ah.isMinorTick&&ab.drawMinorGridlines))){ai(this._right,ae,this._left,ae)}if(ah.showMark&&ah.mark&&((!ah.isMinorTick&&ab.drawMajorTickMarks)||(ah.isMinorTick&&ab.drawMinorTickMarks))){aj=ah.markSize;ak=ah.mark;var ae=Math.round(ab.u2p(ah.value))+0.5;switch(ak){case"outside":at=this._left-aj;ar=this._left;break;case"inside":at=this._left;ar=this._left+aj;break;case"cross":at=this._left-aj;ar=this._left+aj;break;default:at=this._left-aj;ar=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(am,[[at,ae],[ar,ae]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ai(at,ae,ar,ae,{strokeStyle:ab.borderColor})}break;case"x2axis":if(ah.showGridline&&this.drawGridlines&&((!ah.isMinorTick&&ab.drawMajorGridlines)||(ah.isMinorTick&&ab.drawMinorGridlines))){ai(ae,this._bottom,ae,this._top)}if(ah.showMark&&ah.mark&&((!ah.isMinorTick&&ab.drawMajorTickMarks)||(ah.isMinorTick&&ab.drawMinorTickMarks))){aj=ah.markSize;ak=ah.mark;var ae=Math.round(ab.u2p(ah.value))+0.5;switch(ak){case"outside":at=this._top-aj;ar=this._top;break;case"inside":at=this._top;ar=this._top+aj;break;case"cross":at=this._top-aj;ar=this._top+aj;break;default:at=this._top-aj;ar=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(am,[[ae,at],[ae,ar]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ai(ae,at,ae,ar)}break;case"y2axis":if(ah.showGridline&&this.drawGridlines&&((!ah.isMinorTick&&ab.drawMajorGridlines)||(ah.isMinorTick&&ab.drawMinorGridlines))){ai(this._left,ae,this._right,ae)}if(ah.showMark&&ah.mark&&((!ah.isMinorTick&&ab.drawMajorTickMarks)||(ah.isMinorTick&&ab.drawMinorTickMarks))){aj=ah.markSize;ak=ah.mark;var ae=Math.round(ab.u2p(ah.value))+0.5;switch(ak){case"outside":at=this._right;ar=this._right+aj;break;case"inside":at=this._right-aj;ar=this._right;break;case"cross":at=this._right-aj;ar=this._right+aj;break;default:at=this._right;ar=this._right+aj;break}if(this.shadow){this.renderer.shadowRenderer.draw(am,[[at,ae],[ar,ae]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ai(at,ae,ar,ae,{strokeStyle:ab.borderColor})}break;default:break}}}ah=null}ab=null;au=null}ag=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var aq=7;aq>0;aq--){var ab=ap[ag[aq-1]];var au=ab._ticks;if(ab.show){var ac=au[ab.numberTicks-1];var af=au[0];var ad=ab.getLeft();var ao=[[ad,ac.getTop()+ac.getHeight()/2],[ad,af.getTop()+af.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(am,ao,{lineCap:"butt",fill:false,closePath:false})}ai(ao[0][0],ao[0][1],ao[1][0],ao[1][1],{lineCap:"butt",strokeStyle:ab.borderColor,lineWidth:ab.borderWidth});for(var an=au.length;an>0;an--){var ah=au[an-1];aj=ah.markSize;ak=ah.mark;var ae=Math.round(ab.u2p(ah.value))+0.5;if(ah.showMark&&ah.mark){switch(ak){case"outside":at=ad;ar=ad+aj;break;case"inside":at=ad-aj;ar=ad;break;case"cross":at=ad-aj;ar=ad+aj;break;default:at=ad;ar=ad+aj;break}ao=[[at,ae],[ar,ae]];if(this.shadow){this.renderer.shadowRenderer.draw(am,ao,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ai(at,ae,ar,ae,{strokeStyle:ab.borderColor})}ah=null}af=null}ab=null;au=null}am.restore();function ai(aB,aA,ay,ax,az){am.save();az=az||{};if(az.lineWidth==null||az.lineWidth!=0){H.extend(true,am,az);am.beginPath();am.moveTo(aB,aA);am.lineTo(ay,ax);am.stroke();am.restore()}}if(this.shadow){var ao=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(am,ao)}if(this.borderWidth!=0&&this.drawBorder){ai(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:ap.x2axis.borderColor,lineWidth:ap.x2axis.borderWidth});ai(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:ap.y2axis.borderColor,lineWidth:ap.y2axis.borderWidth});ai(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:ap.xaxis.borderColor,lineWidth:ap.xaxis.borderWidth});ai(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:ap.yaxis.borderColor,lineWidth:ap.yaxis.borderWidth})}am.restore();am=null;ap=null};H.jqplot.DivTitleRenderer=function(){};H.jqplot.DivTitleRenderer.prototype.init=function(ab){H.extend(true,this,ab)};H.jqplot.DivTitleRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}var ae=this.renderer;var ad=document.createElement("div");this._elem=H(ad);this._elem.addClass("jqplot-title");if(!this.text){this.show=false;this._elem.height(0);this._elem.width(0)}else{if(this.text){var ab;if(this.color){ab=this.color}else{if(this.textColor){ab=this.textColor}}var ac={position:"absolute",top:"0px",left:"0px"};if(this._plotWidth){ac.width=this._plotWidth+"px"}if(this.fontSize){ac.fontSize=this.fontSize}if(typeof this.textAlign==="string"){ac.textAlign=this.textAlign}else{ac.textAlign="center"}if(ab){ac.color=ab}if(this.paddingBottom){ac.paddingBottom=this.paddingBottom}if(this.fontFamily){ac.fontFamily=this.fontFamily}this._elem.css(ac);if(this.escapeHtml){this._elem.text(this.text)}else{this._elem.html(this.text)}}}ad=null;return this._elem};H.jqplot.DivTitleRenderer.prototype.pack=function(){};var o=0.1;H.jqplot.LinePattern=function(ap,ak){var aj={dotted:[o,H.jqplot.config.dotGapLength],dashed:[H.jqplot.config.dashLength,H.jqplot.config.gapLength],solid:null};if(typeof ak==="string"){if(ak[0]==="."||ak[0]==="-"){var aq=ak;ak=[];for(var ai=0,af=aq.length;ai0)&&(aw>0)){au/=av;at/=av;while(true){var ax=aw*al;if(ax=ak.length){ae=0}al=ak[ae]}else{an=ar;am=ay;if((ae&1)==0){ap.lineTo(an,am)}else{ap.moveTo(an,am)}al-=av/aw;break}}}};var ac=function(){ap.beginPath()};var ag=function(){ad(ah,ab)};return{moveTo:ao,lineTo:ad,beginPath:ac,closePath:ag}};H.jqplot.LineRenderer=function(){this.shapeRenderer=new H.jqplot.ShapeRenderer();this.shadowRenderer=new H.jqplot.ShadowRenderer()};H.jqplot.LineRenderer.prototype.init=function(ac,ah){ac=ac||{};this._type="line";this.renderer.animation={show:false,direction:"left",speed:2500,_supported:true};this.renderer.smooth=false;this.renderer.tension=null;this.renderer.constrainSmoothing=true;this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];this.renderer.bandData=[];this.renderer.bands={show:false,hiData:[],lowData:[],color:this.color,showLines:false,fill:true,fillColor:null,_min:null,_max:null,interval:"3%"};var af={highlightMouseOver:ac.highlightMouseOver,highlightMouseDown:ac.highlightMouseDown,highlightColor:ac.highlightColor};delete (ac.highlightMouseOver);delete (ac.highlightMouseDown);delete (ac.highlightColor);H.extend(true,this.renderer,ac);this.renderer.options=ac;if(this.renderer.bandData.length>1&&(!ac.bands||ac.bands.show==null)){this.renderer.bands.show=true}else{if(ac.bands&&ac.bands.show==null&&ac.bands.interval!=null){this.renderer.bands.show=true}}if(this.fill){this.renderer.bands.show=false}if(this.renderer.bands.show){this.renderer.initBands.call(this,this.renderer.options,ah)}if(this._stack){this.renderer.smooth=false}var ag={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(ag);var ad=ac.shadowOffset;if(ad==null){if(this.lineWidth>2.5){ad=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{ad=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var ab={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,angle:this.shadowAngle,offset:ad,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shadowRenderer.init(ab);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill||this.renderer.bands.show){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(af.highlightMouseDown&&af.highlightMouseOver==null){af.highlightMouseOver=false}H.extend(true,this,{highlightMouseOver:af.highlightMouseOver,highlightMouseDown:af.highlightMouseDown,highlightColor:af.highlightColor});if(!this.highlightColor){var ae=(this.renderer.bands.show)?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=H.jqplot.computeHighlightColors(ae)}if(this.highlighter){this.highlighter.show=false}}if(!this.isTrendline&&ah){ah.plugins.lineRenderer={};ah.postInitHooks.addOnce(v);ah.postDrawHooks.addOnce(Z);ah.eventListenerHooks.addOnce("jqplotMouseMove",g);ah.eventListenerHooks.addOnce("jqplotMouseDown",d);ah.eventListenerHooks.addOnce("jqplotMouseUp",Y);ah.eventListenerHooks.addOnce("jqplotClick",f);ah.eventListenerHooks.addOnce("jqplotRightClick",p)}};H.jqplot.LineRenderer.prototype.initBands=function(ae,ao){var af=ae.bandData||[];var ah=this.renderer.bands;ah.hiData=[];ah.lowData=[];var av=this.data;ah._max=null;ah._min=null;if(af.length==2){if(H.isArray(af[0][0])){var ai;var ab=0,al=0;for(var ap=0,am=af[0].length;apah._max)||ah._max==null){ah._max=ai[1]}if((ai[1]!=null&&ai[1]ah._max)||ah._max==null){ah._max=ai[1];al=1}if((ai[1]!=null&&ai[1]af[1][0])?0:1;var aw=(ad)?0:1;for(var ap=0,am=av.length;ap2&&!H.isArray(af[0][0])){var ad=(af[0][0]>af[0][1])?0:1;var aw=(ad)?0:1;for(var ap=0,am=af.length;apah._max)||ah._max==null){ah._max=ag[ap][1]}}for(var ap=0,am=aj.length;ap0){aL=Math.abs((aj[aK][1]-aj[aK-1][1])/(aj[aK][0]-aj[aK-1][0]))}ag=aL/aA+ay;aG=az*w(ag)-az*w(ay)+aM;aN=(aI+aG)/2}else{aN=aO}for(aE=0;aE2){var ai;if(this.renderer.constrainSmoothing){ai=F.call(this,this.gridData);this.renderer._smoothedData=ai[0];this.renderer._smoothedPlotData=ai[1];if(ae.show){ai=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ai[0];ai=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ai[0]}ai=null}else{ai=B.call(this,this.gridData);this.renderer._smoothedData=ai[0];this.renderer._smoothedPlotData=ai[1];if(ae.show){ai=B.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ai[0];ai=B.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ai[0]}ai=null}}};H.jqplot.LineRenderer.prototype.makeGridData=function(ai,ak){var ag=this._xaxis.series_u2p;var ab=this._yaxis.series_u2p;var al=[];var ad=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var af=this.renderer.bands;var ac=false;for(var ah=0;ah2){var aj;if(this.renderer.constrainSmoothing){aj=F.call(this,al);this.renderer._smoothedData=aj[0];this.renderer._smoothedPlotData=aj[1];if(af.show){aj=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=aj[0];aj=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=aj[0]}aj=null}else{aj=B.call(this,al);this.renderer._smoothedData=aj[0];this.renderer._smoothedPlotData=aj[1];if(af.show){aj=B.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=aj[0];aj=B.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=aj[0]}aj=null}}return al};H.jqplot.LineRenderer.prototype.draw=function(aq,aC,ac,av){var aw;var ak=H.extend(true,{},ac);var ae=(ak.shadow!=r)?ak.shadow:this.shadow;var aD=(ak.showLine!=r)?ak.showLine:this.showLine;var au=(ak.fill!=r)?ak.fill:this.fill;var ab=(ak.fillAndStroke!=r)?ak.fillAndStroke:this.fillAndStroke;var al,ar,ao,ay;aq.save();if(aC.length){if(aD){if(au){if(this.fillToZero){var az=this.negativeColor;if(!this.useNegativeColors){az=ak.fillStyle}var ai=false;var aj=ak.fillStyle;if(ab){var aB=aC.slice(0)}if(this.index==0||!this._stack){var ap=[];var aF=(this.renderer.smooth)?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var aA=this._yaxis.series_u2p(this.fillToValue);var ad=this._xaxis.series_u2p(this.fillToValue);ak.closePath=true;if(this.fillAxis=="y"){ap.push([aC[0][0],aA]);this._areaPoints.push([aC[0][0],aA]);for(var aw=0;aw0;aw--){aC.push(an[aw-1])}if(ae){this.renderer.shadowRenderer.draw(aq,aC,ak)}this._areaPoints=aC;this.renderer.shapeRenderer.draw(aq,aC,ak)}}else{if(ab){var aB=aC.slice(0)}if(this.index==0||!this._stack){var af=aq.canvas.height;aC.unshift([aC[0][0],af]);var ax=aC.length;aC.push([aC[ax-1][0],af])}else{var an=this._prevGridData;for(var aw=an.length;aw>0;aw--){aC.push(an[aw-1])}}this._areaPoints=aC;if(ae){this.renderer.shadowRenderer.draw(aq,aC,ak)}this.renderer.shapeRenderer.draw(aq,aC,ak)}if(ab){var at=H.extend(true,{},ak,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(aq,aB,at);if(this.markerRenderer.show){if(this.renderer.smooth){aB=this.gridData}for(aw=0;awam[0]||al==null){al=am[0]}if(ayam[1]||ar==null){ar=am[1]}}if(this.type==="line"&&this.renderer.bands.show){ay=this._yaxis.series_u2p(this.renderer.bands._min);ar=this._yaxis.series_u2p(this.renderer.bands._max)}this._boundingBox=[[al,ay],[ao,ar]];if(this.markerRenderer.show&&!au){if(this.renderer.smooth){aC=this.gridData}for(aw=0;awai){ai=ad}}}af=null;ag=null;if(ab){ac=this._label._elem.outerWidth(true);ah=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){ai=ai+ah;this._elem.css({height:ai+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){ai=ai+ah;this._elem.css({height:ai+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){ai=ai+ac;this._elem.css({width:ai+"px",left:"0px",top:"0px"});if(ab&&this._label.constructor==H.jqplot.AxisLabelRenderer){this._label._elem.css("width",ac+"px")}}else{ai=ai+ac;this._elem.css({width:ai+"px",right:"0px",top:"0px"});if(ab&&this._label.constructor==H.jqplot.AxisLabelRenderer){this._label._elem.css("width",ac+"px")}}}}}};H.jqplot.LinearAxisRenderer.prototype.createTicks=function(ad){var aN=this._ticks;var aE=this.ticks;var at=this.name;var av=this._dataBounds;var ab=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var ah;var a0,aC;var aj,ai;var aY,aU;var aB=this.min;var aZ=this.max;var aQ=this.numberTicks;var a4=this.tickInterval;var ag=30;this._scalefact=(Math.max(ab,ag+1)-ag)/300;if(aE.length){for(aU=0;aUthis.breakPoints[0]&&aI[0]<=this.breakPoints[1]){aO.show=false;aO.showGridline=false;aO.label=aI[1]}else{aO.label=aI[1]}}}else{aO.label=aI[1]}aO.setTick(aI[0],this.name);this._ticks.push(aO)}else{if(H.isPlainObject(aI)){H.extend(true,aO,aI);aO.axis=this.name;this._ticks.push(aO)}else{aO.value=aI;if(this.breakPoints){if(aI==this.breakPoints[0]){aO.label=this.breakTickLabel;aO._breakTick=true;aO.showGridline=false;aO.showMark=false}else{if(aI>this.breakPoints[0]&&aI<=this.breakPoints[1]){aO.show=false;aO.showGridline=false}}}aO.setTick(aI,this.name);this._ticks.push(aO)}}}this.numberTicks=aE.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(at=="xaxis"||at=="x2axis"){ab=this._plotDimensions.width}else{ab=this._plotDimensions.height}var aq=this.numberTicks;if(this.alignTicks){if(this.name==="x2axis"&&ad.axes.xaxis.show){aq=ad.axes.xaxis.numberTicks}else{if(this.name.charAt(0)==="y"&&this.name!=="yaxis"&&this.name!=="yMidAxis"&&ad.axes.yaxis.show){aq=ad.axes.yaxis.numberTicks}}}a0=((this.min!=null)?this.min:av.min);aC=((this.max!=null)?this.max:av.max);var ao=aC-a0;var aM,ar;var am;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(this.min==null||this.max==null&&this.tickInterval==null&&!this.autoscale){if(this.forceTickAt0){if(a0>0){a0=0}if(aC<0){aC=0}}if(this.forceTickAt100){if(a0>100){a0=100}if(aC<100){aC=100}}var ay=false,aV=false;if(this.min!=null){ay=true}else{if(this.max!=null){aV=true}}var aJ=H.jqplot.LinearTickGenerator(a0,aC,this._scalefact,aq,ay,aV);var ap=(this.min!=null)?a0:a0+ao*(this.padMin-1);var aK=(this.max!=null)?aC:aC-ao*(this.padMax-1);if(a0aK){ap=(this.min!=null)?a0:a0-ao*(this.padMin-1);aK=(this.max!=null)?aC:aC+ao*(this.padMax-1);aJ=H.jqplot.LinearTickGenerator(ap,aK,this._scalefact,aq,ay,aV)}this.min=aJ[0];this.max=aJ[1];this.numberTicks=aJ[2];this._autoFormatString=aJ[3];this.tickInterval=aJ[4]}else{if(a0==aC){var ac=0.05;if(a0>0){ac=Math.max(Math.log(a0)/Math.LN10,0.05)}a0-=ac;aC+=ac}if(this.autoscale&&this.min==null&&this.max==null){var ae,af,al;var aw=false;var aH=false;var au={min:null,max:null,average:null,stddev:null};for(var aU=0;aUaW){aW=aL[aT]}}}var an=(aW-aA)/aW;if(aP.renderer.constructor==H.jqplot.BarRenderer){if(aA>=0&&(aP.fillToZero||an>0.1)){aw=true}else{aw=false;if(aP.fill&&aP.fillToZero&&aA<0&&aW>0){aH=true}else{aH=false}}}else{if(aP.fill){if(aA>=0&&(aP.fillToZero||an>0.1)){aw=true}else{if(aA<0&&aW>0&&aP.fillToZero){aw=false;aH=true}else{aw=false;aH=false}}}else{if(aA<0){aw=false}}}}}if(aw){this.numberTicks=2+Math.ceil((ab-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aB=0;af=aC/(this.numberTicks-1);am=Math.pow(10,Math.abs(Math.floor(Math.log(af)/Math.LN10)));if(af/am==parseInt(af/am,10)){af+=am}this.tickInterval=Math.ceil(af/am)*am;this.max=this.tickInterval*(this.numberTicks-1)}else{if(aH){this.numberTicks=2+Math.ceil((ab-(this.tickSpacing-1))/this.tickSpacing);var aD=Math.ceil(Math.abs(a0)/ao*(this.numberTicks-1));var a3=this.numberTicks-1-aD;af=Math.max(Math.abs(a0/aD),Math.abs(aC/a3));am=Math.pow(10,Math.abs(Math.floor(Math.log(af)/Math.LN10)));this.tickInterval=Math.ceil(af/am)*am;this.max=this.tickInterval*a3;this.min=-this.tickInterval*aD}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(ao/this.tickInterval)}else{this.numberTicks=2+Math.ceil((ab-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){af=ao/(this.numberTicks-1);if(af<1){am=Math.pow(10,Math.abs(Math.floor(Math.log(af)/Math.LN10)))}else{am=1}this.tickInterval=Math.ceil(af*am*this.pad)/am}else{am=1/this.tickInterval}ae=this.tickInterval*(this.numberTicks-1);al=(ae-ao)/2;if(this.min==null){this.min=Math.floor(am*(a0-al))/am}if(this.max==null){this.max=this.min+ae}}}var az=H.jqplot.getSignificantFigures(this.tickInterval);var aG;if(az.digitsLeft>=az.significantDigits){aG="%d"}else{var am=Math.max(0,5-az.digitsLeft);am=Math.min(am,az.digitsRight);aG="%."+am+"f"}this._autoFormatString=aG}else{aM=(this.min!=null)?this.min:a0-ao*(this.padMin-1);ar=(this.max!=null)?this.max:aC+ao*(this.padMax-1);ao=ar-aM;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((ar-aM)/this.tickInterval)+1}else{if(ab>100){this.numberTicks=parseInt(3+(ab-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=ao/(this.numberTicks-1)}if(this.max==null){ar=aM+this.tickInterval*(this.numberTicks-1)}if(this.min==null){aM=ar-this.tickInterval*(this.numberTicks-1)}var az=H.jqplot.getSignificantFigures(this.tickInterval);var aG;if(az.digitsLeft>=az.significantDigits){aG="%d"}else{var am=Math.max(0,5-az.digitsLeft);am=Math.min(am,az.digitsRight);aG="%."+am+"f"}this._autoFormatString=aG;this.min=aM;this.max=ar}if(this.renderer.constructor==H.jqplot.LinearAxisRenderer&&this._autoFormatString==""){ao=this.max-this.min;var a1=new this.tickRenderer(this.tickOptions);var aF=a1.formatString||H.jqplot.config.defaultTickFormatString;var aF=aF.match(H.jqplot.sprintf.regex)[0];var aX=0;if(aF){if(aF.search(/[fFeEgGpP]/)>-1){var aS=aF.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(aS){aX=parseInt(aS[1],10)}else{aX=6}}else{if(aF.search(/[di]/)>-1){aX=0}}var ak=Math.pow(10,-aX);if(this.tickIntervalthis.breakPoints[0]&&authis.breakPoints[0]&&authis.breakPoints[0]&&au=this.breakPoints[1]){return(au-an)*ae/af}else{return(au+this.breakPoints[1]-this.breakPoints[0]-an)*ae/af}};this.series_p2u=function(au){return au*af/ae+an}}}else{this.p2u=function(au){return(au-ag)*af/ae+am};this.u2p=function(au){return(au-am)*ae/af+ag};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(au){return(au-am)*ae/af};this.series_p2u=function(au){return au*af/ae+am}}else{this.series_u2p=function(au){return(au-an)*ae/af};this.series_p2u=function(au){return au*af/ae+an}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var ao=0;ao0){ab=-aj._textRenderer.height*Math.cos(-aj._textRenderer.angle)/2}else{ab=-aj.getHeight()+aj._textRenderer.height*Math.cos(aj._textRenderer.angle)/2}break;case"middle":ab=-aj.getHeight()/2;break;default:ab=-aj.getHeight()/2;break}}else{ab=-aj.getHeight()/2}var at=this.u2p(aj.value)+ab+"px";aj._elem.css("top",at);aj.pack()}}if(ak){var ap=this._label._elem.outerHeight(true);this._label._elem.css("top",ai-ae/2-ap/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}ar=null};function h(ac){var ab;ac=Math.abs(ac);if(ac>=10){ab="%d"}else{if(ac>1){if(ac===parseInt(ac,10)){ab="%d"}else{ab="%.1f"}}else{var ad=-Math.floor(Math.log(ac)/Math.LN10);ab="%."+ad+"f"}}return ab}var a=[0.1,0.2,0.3,0.4,0.5,0.8,1,2,3,4,5];var b=function(ac){var ab=a.indexOf(ac);if(ab>0){return a[ab-1]}else{return a[a.length-1]/100}};var i=function(ac){var ab=a.indexOf(ac);if(ab5){ab=10*ad}else{if(ag>2){ab=5*ad}else{if(ag>1){ab=2*ad}else{ab=ad}}}}else{if(ag>5){ab=10*ad}else{if(ag>4){ab=5*ad}else{if(ag>3){ab=4*ad}else{if(ag>2){ab=3*ad}else{if(ag>1){ab=2*ad}else{ab=ad}}}}}}return ab}function M(ac,ab){ab=ab||1;var ae=Math.floor(Math.log(ac)/Math.LN10);var ag=Math.pow(10,ae);var af=ac/ag;var ad;af=af/ab;if(af<=0.38){ad=0.1}else{if(af<=1.6){ad=0.2}else{if(af<=4){ad=0.5}else{if(af<=8){ad=1}else{if(af<=16){ad=2}else{ad=5}}}}}return ad*ag}function t(ad,ac){var af=Math.floor(Math.log(ad)/Math.LN10);var ah=Math.pow(10,af);var ag=ad/ah;var ab;var ae;ag=ag/ac;if(ag<=0.38){ae=0.1}else{if(ag<=1.6){ae=0.2}else{if(ag<=4){ae=0.5}else{if(ag<=8){ae=1}else{if(ag<=16){ae=2}else{ae=5}}}}}ab=ae*ah;return[ab,ae,ah]}H.jqplot.LinearTickGenerator=function(ah,ak,ad,ae,ai,al){ai=(ai===null)?false:ai;al=(al===null||ai)?false:al;if(ah===ak){ak=(ak)?0:1}ad=ad||1;if(akam){am=av}if(ac>au){au=ac}})}ah.width=am+Number(ao);ah.height=au+Number(aq);var ae=ah.getContext("2d");ae.save();ae.fillStyle=af;ae.fillRect(0,0,ah.width,ah.height);ae.restore();ae.translate(an,al);ae.textAlign="left";ae.textBaseline="top";function aw(ay){var az=parseInt(H(ay).css("line-height"),10);if(isNaN(az)){az=parseInt(H(ay).css("font-size"),10)*1.2}return az}function ax(az,ay,aM,aA,aI,aB){var aK=aw(az);var aE=H(az).innerWidth();var aF=H(az).innerHeight();var aH=aM.split(/\s+/);var aL=aH.length;var aJ="";var aG=[];var aO=aI;var aN=aA;for(var aD=0;aDaE){aG.push(aD);aJ="";aD--}}if(aG.length===0){if(H(az).css("textAlign")==="center"){aN=aA+(aB-ay.measureText(aJ).width)/2-an}ay.fillText(aM,aN,aI)}else{aJ=aH.slice(0,aG[0]).join(" ");if(H(az).css("textAlign")==="center"){aN=aA+(aB-ay.measureText(aJ).width)/2-an}ay.fillText(aJ,aN,aO);aO+=aK;for(var aD=1,aC=aG.length;aD0){ae.strokeRect(aC,aF,H(aA).innerWidth(),H(aA).innerHeight())}H(aA).find("div.jqplot-table-legend-swatch-outline").each(function(){var aO=H(this);ae.strokeStyle=aO.css("border-top-color");var aK=aC+aO.position().left;var aL=aF+aO.position().top;ae.strokeRect(aK,aL,aO.innerWidth(),aO.innerHeight());aK+=parseInt(aO.css("padding-left"),10);aL+=parseInt(aO.css("padding-top"),10);var aN=aO.innerHeight()-2*parseInt(aO.css("padding-top"),10);var aJ=aO.innerWidth()-2*parseInt(aO.css("padding-left"),10);var aM=aO.children("div.jqplot-table-legend-swatch");ae.fillStyle=aM.css("background-color");ae.fillRect(aK,aL,aJ,aN)});H(aA).find("td.jqplot-table-legend-label").each(function(){var aL=H(this);var aJ=aC+aL.position().left;var aK=aF+aL.position().top+parseInt(aL.css("padding-top"),10);ae.font=aL.jqplotGetComputedFontStyle();ae.fillStyle=aL.css("color");ax(aL,ae,aL.text(),aJ,aK,aG)});var aB=null}else{if(aH=="canvas"){ae.drawImage(aA,aC,aF)}}}}H(this).children().each(function(){ap(this,ao,aq)});return ah};H.fn.jqplotToImageStr=function(ac){var ab=H(this).jqplotToImageCanvas(ac);if(ab){return ab.toDataURL("image/png")}else{return null}};H.fn.jqplotToImageElem=function(ab){var ac=document.createElement("img");var ad=H(this).jqplotToImageStr(ab);ac.src=ad;return ac};H.fn.jqplotToImageElemStr=function(ab){var ac="";return ac};H.fn.jqplotSaveImage=function(){var ab=H(this).jqplotToImageStr({});if(ab){window.location.href=ab.replace("image/png","image/octet-stream")}};H.fn.jqplotViewImage=function(){var ac=H(this).jqplotToImageElemStr({});var ad=H(this).jqplotToImageStr({});if(ac){var ab=window.open("");ab.document.open("image/png");ab.document.write(ac);ab.document.close();ab=null}};var aa=function(){this.syntax=aa.config.syntax;this._type="jsDate";this.proxy=new Date();this.options={};this.locale=aa.regional.getLocale();this.formatString="";this.defaultCentury=aa.config.defaultCentury;switch(arguments.length){case 0:break;case 1:if(j(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var ad=this.options=arguments[0];this.syntax=ad.syntax||this.syntax;this.defaultCentury=ad.defaultCentury||this.defaultCentury;this.proxy=aa.createDate(ad.date)}else{this.proxy=aa.createDate(arguments[0])}break;default:var ab=[];for(var ac=0;ac0?"floor":"ceil"](ae))};aa.prototype.getAbbrDayName=function(){return aa.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]};aa.prototype.getAbbrMonthName=function(){return aa.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]};aa.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"};aa.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"};aa.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)};aa.prototype.getDate=function(){return this.proxy.getDate()};aa.prototype.getDay=function(){return this.proxy.getDay()};aa.prototype.getDayOfWeek=function(){var ab=this.proxy.getDay();return ab===0?7:ab};aa.prototype.getDayOfYear=function(){var ac=this.proxy;var ab=ac-new Date(""+ac.getFullYear()+"/1/1 GMT");ab+=ac.getTimezoneOffset()*60000;ac=null;return parseInt(ab/60000/60/24,10)+1};aa.prototype.getDayName=function(){return aa.regional[this.locale]["dayNames"][this.proxy.getDay()]};aa.prototype.getFullWeekOfYear=function(){var ae=this.proxy;var ab=this.getDayOfYear();var ad=6-ae.getDay();var ac=parseInt((ab+ad)/7,10);return ac};aa.prototype.getFullYear=function(){return this.proxy.getFullYear()};aa.prototype.getGmtOffset=function(){var ab=this.proxy.getTimezoneOffset()/60;var ac=ab<0?"+":"-";ab=Math.abs(ab);return ac+J(Math.floor(ab),2)+":"+J((ab%1)*60,2)};aa.prototype.getHours=function(){return this.proxy.getHours()};aa.prototype.getHours12=function(){var ab=this.proxy.getHours();return ab>12?ab-12:(ab==0?12:ab)};aa.prototype.getIsoWeek=function(){var ae=this.proxy;var ad=ae.getWeekOfYear();var ab=(new Date(""+ae.getFullYear()+"/1/1")).getDay();var ac=ad+(ab>4||ab<=1?0:1);if(ac==53&&(new Date(""+ae.getFullYear()+"/12/31")).getDay()<4){ac=1}else{if(ac===0){ae=new aa(new Date(""+(ae.getFullYear()-1)+"/12/31"));ac=ae.getIsoWeek()}}ae=null;return ac};aa.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()};aa.prototype.getMinutes=function(){return this.proxy.getMinutes()};aa.prototype.getMonth=function(){return this.proxy.getMonth()};aa.prototype.getMonthName=function(){return aa.regional[this.locale]["monthNames"][this.proxy.getMonth()]};aa.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1};aa.prototype.getSeconds=function(){return this.proxy.getSeconds()};aa.prototype.getShortYear=function(){return this.proxy.getYear()%100};aa.prototype.getTime=function(){return this.proxy.getTime()};aa.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")};aa.prototype.getTimezoneName=function(){var ab=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return ab[1]||ab[2]||"GMT"+this.getGmtOffset()};aa.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()};aa.prototype.getWeekOfYear=function(){var ab=this.getDayOfYear();var ad=7-this.getDayOfWeek();var ac=parseInt((ab+ad)/7,10);return ac};aa.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1000,0)};aa.prototype.getYear=function(){return this.proxy.getYear()};aa.prototype.next=function(ab){ab=ab||"day";return this.clone().add(1,ab)};aa.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date();break;case 1:if(j(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var ad=this.options=arguments[0];this.syntax=ad.syntax||this.syntax;this.defaultCentury=ad.defaultCentury||this.defaultCentury;this.proxy=aa.createDate(ad.date)}else{this.proxy=aa.createDate(arguments[0])}break;default:var ab=[];for(var ac=0;ac0?"floor":"ceil"](ab/12));var ac=ad.getMonth()+(ab%12);if(ac==12){ac=0;ad.setYear(ad.getFullYear()+1)}else{if(ac==-1){ac=11;ad.setYear(ad.getFullYear()-1)}}ad.setMonth(ac)},diff:function(af,ad){var ab=af.getFullYear()-ad.getFullYear();var ac=af.getMonth()-ad.getMonth()+(ab*12);var ae=af.getDate()-ad.getDate();return ac+(ae/30)}},year:{add:function(ac,ab){ac.setYear(ac.getFullYear()+Math[ab>0?"floor":"ceil"](ab))},diff:function(ac,ab){return A.month.diff(ac,ab)/12}}};for(var T in A){if(T.substring(T.length-1)!="s"){A[T+"s"]=A[T]}}var D=function(af,ae,ac){if(aa.formats[ac]["shortcuts"][ae]){return aa.strftime(af,aa.formats[ac]["shortcuts"][ae],ac)}else{var ab=(aa.formats[ac]["codes"][ae]||"").split(".");var ad=af["get"+ab[0]]?af["get"+ab[0]]():"";if(ab[1]){ad=J(ad,ab[1])}return ad}};aa.strftime=function(ah,ae,ad,ai){var ac="perl";var ag=aa.regional.getLocale();if(ad&&aa.formats.hasOwnProperty(ad)){ac=ad}else{if(ad&&aa.regional.hasOwnProperty(ad)){ag=ad}}if(ai&&aa.formats.hasOwnProperty(ai)){ac=ai}else{if(ai&&aa.regional.hasOwnProperty(ai)){ag=ai}}if(j(ah)!="[object Object]"||ah._type!="jsDate"){ah=new aa(ah);ah.locale=ag}if(!ae){ae=ah.formatString||aa.regional[ag]["formatString"]}var ab=ae||"%Y-%m-%d",aj="",af;while(ab.length>0){if(af=ab.match(aa.formats[ac].codes.matcher)){aj+=ab.slice(0,af.index);aj+=(af[1]||"")+D(ah,af[2],ac);ab=ab.slice(af.index+af[0].length)}else{aj+=ab;ab=""}}return aj};aa.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"};aa.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};aa.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};aa.createDate=function(ad){if(ad==null){return new Date()}if(ad instanceof Date){return ad}if(typeof ad=="number"){return new Date(ad)}var ai=String(ad).replace(/^\s*(.+)\s*$/g,"$1");ai=ai.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3");ai=ai.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var ah=ai.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(ah&&ah.length>3){var am=parseFloat(ah[3]);var ag=aa.config.defaultCentury+am;ag=String(ag);ai=ai.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,ah[1]+" "+ah[2]+" "+ag)}ah=ai.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);function al(aq,ap){var aw=parseFloat(ap[1]);var av=parseFloat(ap[2]);var au=parseFloat(ap[3]);var at=aa.config.defaultCentury;var ao,an,ax,ar;if(aw>31){an=au;ax=av;ao=at+aw}else{an=av;ax=aw;ao=at+au}ar=ax+"/"+an+"/"+ao;return aq.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,ar)}if(ah&&ah.length>3){ai=al(ai,ah)}var ah=ai.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);if(ah&&ah.length>3){ai=al(ai,ah)}var af=0;var ac=aa.matchers.length;var ak,ab,aj=ai,ae;while(af31){ab=ah;ac=ag+ai}else{ab=ai;ac=ag+ah}var aj=W(ad[2],aa.regional[aa.regional.getLocale()]["monthNamesShort"]);if(aj==-1){aj=W(ad[2],aa.regional[aa.regional.getLocale()]["monthNames"])}ae.setFullYear(ac,aj,ab);ae.setHours(0,0,0,0);return ae}else{return af}}];function W(ad,ae){if(ae.indexOf){return ae.indexOf(ad)}for(var ab=0,ac=ae.length;ab=aj)?"":Array(1+aj-an.length>>>0).join(ak);return am?an+al:al+an}function ae(al){var ak=new String(al);for(var aj=10;aj>0;aj--){if(ak==(ak=ak.replace(/^(\d+)(\d{3})/,"$1"+H.jqplot.sprintf.thousandsSeparator+"$2"))){break}}return ak}function ad(ao,an,aq,al,am,ak){var ap=al-ao.length;if(ap>0){var aj=" ";if(ak){aj=" "}if(aq||!am){ao=ah(ao,al,aj,aq)}else{ao=ao.slice(0,an.length)+ah("",ap,"0",true)+ao.slice(an.length)}}return ao}function ai(ar,ak,ap,al,aj,ao,aq,an){var am=ar>>>0;ap=ap&&am&&{"2":"0b","8":"0","16":"0x"}[ak]||"";ar=ap+ah(am.toString(ak),ao||0,"0",false);return ad(ar,ap,al,aj,aq,an)}function ab(an,ao,al,aj,am,ak){if(aj!=null){an=an.slice(0,aj)}return ad(an,"",ao,al,am,ak)}var ac=arguments,af=0,ag=ac[af++];return ag.replace(H.jqplot.sprintf.regex,function(aG,aq,ar,av,aI,aD,ao){if(aG=="%%"){return"%"}var ax=false,at="",au=false,aF=false,ap=false,an=false;for(var aC=0;ar&&aC-1?6:(ao=="d")?0:void (0)}else{if(aD=="*"){aD=+ac[af++]}else{if(aD.charAt(0)=="*"){aD=+ac[aD.slice(1,-1)]}else{aD=+aD}}}var az=aq?ac[aq.slice(0,-1)]:ac[af++];switch(ao){case"s":if(az==null){return""}return ab(String(az),ax,av,aD,au,ap);case"c":return ab(String.fromCharCode(+az),ax,av,aD,au,ap);case"b":return ai(az,2,aF,ax,av,aD,au,ap);case"o":return ai(az,8,aF,ax,av,aD,au,ap);case"x":return ai(az,16,aF,ax,av,aD,au,ap);case"X":return ai(az,16,aF,ax,av,aD,au,ap).toUpperCase();case"u":return ai(az,10,aF,ax,av,aD,au,ap);case"i":var al=parseInt(+az,10);if(isNaN(al)){return""}var aB=al<0?"-":at;var aE=an?ae(String(Math.abs(al))):String(Math.abs(al));az=aB+ah(aE,aD,"0",false);return ad(az,aB,ax,av,au,ap);case"d":var al=Math.round(+az);if(isNaN(al)){return""}var aB=al<0?"-":at;var aE=an?ae(String(Math.abs(al))):String(Math.abs(al));az=aB+ah(aE,aD,"0",false);return ad(az,aB,ax,av,au,ap);case"e":case"E":case"f":case"F":case"g":case"G":var al=+az;if(isNaN(al)){return""}var aB=al<0?"-":at;var am=["toExponential","toFixed","toPrecision"]["efg".indexOf(ao.toLowerCase())];var aH=["toString","toUpperCase"]["eEfFgG".indexOf(ao)%2];var aE=Math.abs(al)[am](aD);aE=an?ae(aE):aE;az=aB+aE;var aw=ad(az,aB,ax,av,au,ap)[aH]();if(H.jqplot.sprintf.decimalMark!=="."&&H.jqplot.sprintf.decimalMark!==H.jqplot.sprintf.thousandsSeparator){return aw.replace(/\./,H.jqplot.sprintf.decimalMark)}else{return aw}case"p":case"P":var al=+az;if(isNaN(al)){return""}var aB=al<0?"-":at;var ay=String(Number(Math.abs(al)).toExponential()).split(/e|E/);var ak=(ay[0].indexOf(".")!=-1)?ay[0].length-1:ay[0].length;var aA=(ay[1]<0)?-ay[1]-1:0;if(Math.abs(al)<1){if(ak+aA<=aD){az=aB+Math.abs(al).toPrecision(ak)}else{if(ak<=aD-1){az=aB+Math.abs(al).toExponential(ak-1)}else{az=aB+Math.abs(al).toExponential(aD-1)}}}else{var aj=(ak<=aD)?ak:aD;az=aB+Math.abs(al).toPrecision(aj)}var aH=["toString","toUpperCase"]["pP".indexOf(ao)%2];return ad(az,aB,ax,av,au,ap)[aH]();case"n":return"";default:return aG}})};H.jqplot.sprintf.thousandsSeparator=",";H.jqplot.sprintf.decimalMark=".";H.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;H.jqplot.getSignificantFigures=function(af){var ah=String(Number(Math.abs(af)).toExponential()).split(/e|E/);var ag=(ah[0].indexOf(".")!=-1)?ah[0].length-1:ah[0].length;var ac=(ah[1]<0)?-ah[1]-1:0;var ab=parseInt(ah[1],10);var ad=(ab+1>0)?ab+1:0;var ae=(ag<=ad)?0:ag-ab-1;return{significantDigits:ag,digitsLeft:ad,digitsRight:ae,zeros:ac,exponent:ab}};H.jqplot.getPrecision=function(ab){return H.jqplot.getSignificantFigures(ab).digitsRight}})(jQuery);var backCompat=$.uiBackCompat!==false;$.jqplot.effects={effect:{}};var dataSpace="jqplot.storage.";$.extend($.jqplot.effects,{version:"1.9pre",save:function(b,c){for(var a=0;a
      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),a={width:b.width(),height:b.height()},d=document.activeElement;b.wrap(e);if(b[0]===d||$.contains(b[0],d)){$(d).focus()}e=b.parent();if(b.css("position")==="static"){e.css({position:"relative"});b.css({position:"relative"})}else{$.extend(c,{position:b.css("position"),zIndex:b.css("z-index")});$.each(["top","left","bottom","right"],function(f,g){c[g]=b.css(g);if(isNaN(parseInt(c[g],10))){c[g]="auto"}});b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}b.css(a);return e.css(c).show()},removeWrapper:function(a){var b=document.activeElement;if(a.parent().is(".ui-effects-wrapper")){a.parent().replaceWith(a);if(a[0]===b||$.contains(a[0],b)){$(b).focus()}}return a}});function _normalizeArguments(b,a,c,d){if($.isPlainObject(b)){return b}b={effect:b};if(a===undefined){a={}}if($.isFunction(a)){d=a;c=null;a={}}if($.type(a)==="number"||$.fx.speeds[a]){d=c;c=a;a={}}if($.isFunction(c)){d=c;c=null}if(a){$.extend(b,a)}c=c||a.duration;b.duration=$.fx.off?0:typeof c==="number"?c:c in $.fx.speeds?$.fx.speeds[c]:$.fx.speeds._default;b.complete=d||a.complete;return b}function standardSpeed(a){if(!a||typeof a==="number"||$.fx.speeds[a]){return true}if(typeof a==="string"&&!$.jqplot.effects.effect[a]){if(backCompat&&$.jqplot.effects[a]){return false}return true}return false}$.fn.extend({jqplotEffect:function(i,j,b,h){var g=_normalizeArguments.apply(this,arguments),d=g.mode,e=g.queue,f=$.jqplot.effects.effect[g.effect],a=!f&&backCompat&&$.jqplot.effects[g.effect];if($.fx.off||!(f||a)){if(d){return this[d](g.duration,g.complete)}else{return this.each(function(){if(g.complete){g.complete.call(this)}})}}function c(m){var n=$(this),l=g.complete,o=g.mode;function k(){if($.isFunction(l)){l.call(n[0])}if($.isFunction(m)){m()}}if(n.is(":hidden")?o==="hide":o==="show"){k()}else{f.call(n[0],g,k)}}if(f){return e===false?this.each(c):this.queue(e||"fx",c)}else{return a.call(this,{options:g,duration:g.duration,callback:g.complete,mode:g.mode})}}});var rvertical=/up|down|vertical/,rpositivemotion=/up|left|vertical|horizontal/;$.jqplot.effects.effect.blind=function(c,h){var d=$(this),k=["position","top","bottom","left","right","height","width"],i=$.jqplot.effects.setMode(d,c.mode||"hide"),m=c.direction||"up",f=rvertical.test(m),e=f?"height":"width",j=f?"top":"left",p=rpositivemotion.test(m),g={},n=i==="show",b,a,l;if(d.parent().is(".ui-effects-wrapper")){$.jqplot.effects.save(d.parent(),k)}else{$.jqplot.effects.save(d,k)}d.show();l=parseInt(d.css("top"),10);b=$.jqplot.effects.createWrapper(d).css({overflow:"hidden"});a=f?b[e]()+l:b[e]();g[e]=n?String(a):"0";if(!p){d.css(f?"bottom":"right",0).css(f?"top":"left","").css({position:"absolute"});g[j]=n?"0":String(a)}if(n){b.css(e,0);if(!p){b.css(j,a)}}b.animate(g,{duration:c.duration,easing:c.easing,queue:false,complete:function(){if(i==="hide"){d.hide()}$.jqplot.effects.restore(d,k);$.jqplot.effects.removeWrapper(d);h()}})}; \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js new file mode 100644 index 000000000..f97ca6169 --- /dev/null +++ b/phpmyadmin/js/jqplot/plugins/jqplot.barRenderer.js @@ -0,0 +1 @@ +(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horizontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I0&&I=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I0&&I=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;I=1024&&d<=6){f/=1024;d++}var e="%.1f";if(Math.floor(f)===f){e="%.0f"}return b.jqplot.sprintf(e+" "+c[d],f)};b.jqplot.byteFormatter=function(c){c=c||0;return function(d,e){if(typeof e==="number"){e=parseFloat(e)||0;return a(e,c)}else{return String(e)}}}})(jQuery); \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js new file mode 100644 index 000000000..5c72b7e2f --- /dev/null +++ b/phpmyadmin/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js @@ -0,0 +1 @@ +(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c,f){if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css({position:"absolute"});this._elem.addClass("jqplot-"+this.axis+"-label");e=null;return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery); \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js new file mode 100644 index 000000000..0bbe5c07c --- /dev/null +++ b/phpmyadmin/js/jqplot/plugins/jqplot.canvasTextRenderer.js @@ -0,0 +1 @@ +(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);var c=parseFloat(b);if(b.indexOf("px")>-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0b.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x0&&o
      ');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e
      ');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;ce){e=m}}}var j=0;for(var c=0;cj){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10);for(x=0;x6&&Math.abs(G.y-I._zoom.start[1])>6)||(I.constrainZoomTo=="x"&&Math.abs(G.x-I._zoom.start[0])>6)||(I.constrainZoomTo=="y"&&Math.abs(G.y-I._zoom.start[1])>6)){if(!C.plugins.cursor.zoomProxy){for(var y in t){if(I._zoom.axes[y]==undefined){I._zoom.axes[y]={};I._zoom.axes[y].numberTicks=F[y].numberTicks;I._zoom.axes[y].tickInterval=F[y].tickInterval;I._zoom.axes[y].daTickInterval=F[y].daTickInterval;I._zoom.axes[y].min=F[y].min;I._zoom.axes[y].max=F[y].max;I._zoom.axes[y].tickFormatString=(F[y].tickOptions!=null)?F[y].tickOptions.formatString:""}if((I.constrainZoomTo=="none")||(I.constrainZoomTo=="x"&&y.charAt(0)=="x")||(I.constrainZoomTo=="y"&&y.charAt(0)=="y")){z=t[y];if(z!=null){if(z>w[y]){v=w[y];x=z}else{D=w[y]-z;v=z;x=w[y]}q=F[y];H=null;if(q.alignTicks){if(q.name==="x2axis"&&C.axes.xaxis.show){H=C.axes.xaxis.numberTicks}else{if(q.name.charAt(0)==="y"&&q.name!=="yaxis"&&q.name!=="yMidAxis"&&C.axes.yaxis.show){H=C.axes.yaxis.numberTicks}}}if(this.looseZoom&&(F[y].renderer.constructor===j.jqplot.LinearAxisRenderer||F[y].renderer.constructor===j.jqplot.LogAxisRenderer)){J=j.jqplot.LinearTickGenerator(v,x,q._scalefact,H);if(F[y].tickInset&&J[0]F[y].max-F[y].tickInset*F[y].tickInterval){J[1]-=J[4];J[2]-=1}if(F[y].renderer.constructor===j.jqplot.LogAxisRenderer&&J[0]"}if(J.useAxesFormatters){for(var D=0;D"}w+=j.jqplot.sprintf(J.tooltipFormatString,t,z,x);N=true}}}}J._tooltipElem.html(w)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var r=j(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;B0;r--){s=v[r-1];if(q[s].show){u[s]=q[s].series_p2u(w[s.charAt(0)])}}return{offsets:t,gridPos:w,dataPos:u}}function h(z){var x=z.data.plot;var y=x.plugins.cursor;if(y.show&&y.zoom&&y._zoom.started&&!y.zoomTarget){z.preventDefault();var B=y.zoomCanvas._ctx;var v=o(z);var w=v.gridPos;var t=v.dataPos;y._zoom.gridpos=w;y._zoom.datapos=t;y._zoom.zooming=true;var u=w.x;var s=w.y;var A=B.canvas.height;var q=B.canvas.width;if(y.showTooltip&&!y.onGrid&&y.showTooltipOutsideZoom){e(w,t,x);if(y.followMouse){n(w,x)}}if(y.constrainZoomTo=="x"){y._zoom.end=[u,A]}else{if(y.constrainZoomTo=="y"){y._zoom.end=[q,s]}else{y._zoom.end=[u,s]}}var r=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(r&&!r().isCollapsed){r().collapse()}}l.call(y);B=null}}function a(w,s,r,x,t){var v=t.plugins.cursor;if(t.plugins.mobile){j(document).one("vmouseup.jqplot_cursor",{plot:t},p)}else{j(document).one("mouseup.jqplot_cursor",{plot:t},p)}var u=t.axes;if(document.onselectstart!=undefined){v._oldHandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!=undefined){v._oldHandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}if(document.onmousedown!=undefined){v._oldHandlers.onmousedown=document.onmousedown;document.onmousedown=function(){return false}}if(v.zoom){if(!v.zoomProxy){var y=v.zoomCanvas._ctx;y.clearRect(0,0,y.canvas.width,y.canvas.height);y=null}if(v.constrainZoomTo=="x"){v._zoom.start=[s.x,0]}else{if(v.constrainZoomTo=="y"){v._zoom.start=[0,s.y]}else{v._zoom.start=[s.x,s.y]}}v._zoom.started=true;for(var q in r){v._zoom.axes.start[q]=r[q]}if(t.plugins.mobile){j(document).bind("vmousemove.jqplotCursor",{plot:t},h)}else{j(document).bind("mousemove.jqplotCursor",{plot:t},h)}}}function p(y){var v=y.data.plot;var x=v.plugins.cursor;if(x.zoom&&x._zoom.zooming&&!x.zoomTarget){var u=x._zoom.gridpos.x;var r=x._zoom.gridpos.y;var t=x._zoom.datapos;var z=x.zoomCanvas._ctx.canvas.height;var q=x.zoomCanvas._ctx.canvas.width;var w=v.axes;if(x.constrainOutsideZoom&&!x.onGrid){if(u<0){u=0}else{if(u>q){u=q}}if(r<0){r=0}else{if(r>z){r=z}}for(var s in t){if(t[s]){if(s.charAt(0)=="x"){t[s]=w[s].series_p2u(u)}else{t[s]=w[s].series_p2u(r)}}}}if(x.constrainZoomTo=="x"){r=z}else{if(x.constrainZoomTo=="y"){u=q}}x._zoom.end=[u,r];x._zoom.gridpos={x:u,y:r};x.doZoom(x._zoom.gridpos,t,v,x)}x._zoom.started=false;x._zoom.zooming=false;j(document).unbind("mousemove.jqplotCursor",h);if(document.onselectstart!=undefined&&x._oldHandlers.onselectstart!=null){document.onselectstart=x._oldHandlers.onselectstart;x._oldHandlers.onselectstart=null}if(document.ondrag!=undefined&&x._oldHandlers.ondrag!=null){document.ondrag=x._oldHandlers.ondrag;x._oldHandlers.ondrag=null}if(document.onmousedown!=undefined&&x._oldHandlers.onmousedown!=null){document.onmousedown=x._oldHandlers.onmousedown;x._oldHandlers.onmousedown=null}}function l(){var y=this._zoom.start;var u=this._zoom.end;var s=this.zoomCanvas._ctx;var r,v,x,q;if(u[0]>y[0]){r=y[0];q=u[0]-y[0]}else{r=u[0];q=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}s.fillStyle="rgba(0,0,0,0.2)";s.strokeStyle="#999999";s.lineWidth=1;s.clearRect(0,0,s.canvas.width,s.canvas.height);s.fillRect(0,0,s.canvas.width,s.canvas.height);s.clearRect(r,v,q,x);s.strokeRect(r,v,q,x);s=null}j.jqplot.CursorLegendRenderer=function(q){j.jqplot.TableLegendRenderer.call(this,q);this.formatString="%s"};j.jqplot.CursorLegendRenderer.prototype=new j.jqplot.TableLegendRenderer();j.jqplot.CursorLegendRenderer.prototype.constructor=j.jqplot.CursorLegendRenderer;j.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var w=this._series,A;var r=document.createElement("div");this._elem=j(r);r=null;this._elem.addClass("jqplot-legend jqplot-cursor-legend");this._elem.css("position","absolute");var q=false;for(var x=0;x').appendTo(this._elem);E.data("seriesIndex",s);j('
      ').appendTo(E);var G=j('');G.appendTo(E);G.data("seriesIndex",s);if(this.escapeHtml){G.text(D)}else{G.html(D)}E=null;G=null}return this._elem}})(jQuery); \ No newline at end of file diff --git a/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js b/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js new file mode 100644 index 000000000..86d52c5b0 --- /dev/null +++ b/phpmyadmin/js/jqplot/plugins/jqplot.dateAxisRenderer.js @@ -0,0 +1 @@ +(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;qC.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;rC.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r6){D=6}}var U=new h.jsDate(ad).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var T=z.diff(U,"month");ab=Math.ceil(T/D)+1;this.min=U.getTime();this.max=U.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var Z=0;Z200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var Z=0;Z=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;WMath.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('
      '+T+"
      ").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;qB||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery); \ No newline at end of file diff --git a/phpmyadmin/js/jquery/jquery-1.8.3.js b/phpmyadmin/js/jquery/jquery-1.8.3.js new file mode 100644 index 000000000..3f4b546f9 --- /dev/null +++ b/phpmyadmin/js/jquery/jquery-1.8.3.js @@ -0,0 +1,21 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function(a2,aB){var w,af,o=a2.document,aI=a2.location,d=a2.navigator,bg=a2.jQuery,I=a2.$,am=Array.prototype.push,a4=Array.prototype.slice,aK=Array.prototype.indexOf,z=Object.prototype.toString,V=Object.prototype.hasOwnProperty,aO=String.prototype.trim,bG=function(e,bZ){return new bG.fn.init(e,bZ,w)},bx=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,aa=/\S/,aV=/\s+/,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,bo=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,a=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,bf=/^[\],:{}\s]*$/,bi=/(?:^|:|,)(?:\s*\[)+/g,bD=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,a0=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,bP=/^-ms-/,aU=/-([\da-z])/gi,N=function(e,bZ){return(bZ+"").toUpperCase()},aF=function(){if(o.addEventListener){o.removeEventListener("DOMContentLoaded",aF,false);bG.ready()}else{if(o.readyState==="complete"){o.detachEvent("onreadystatechange",aF);bG.ready()}}},Z={};bG.fn=bG.prototype={constructor:bG,init:function(e,b2,b1){var b0,b3,bZ,b4;if(!e){return this}if(e.nodeType){this.context=this[0]=e;this.length=1;return this}if(typeof e==="string"){if(e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3){b0=[null,e,null]}else{b0=bo.exec(e)}if(b0&&(b0[1]||!b2)){if(b0[1]){b2=b2 instanceof bG?b2[0]:b2;b4=(b2&&b2.nodeType?b2.ownerDocument||b2:o);e=bG.parseHTML(b0[1],b4,true);if(a.test(b0[1])&&bG.isPlainObject(b2)){this.attr.call(e,b2,true)}return bG.merge(this,e)}else{b3=o.getElementById(b0[2]);if(b3&&b3.parentNode){if(b3.id!==b0[2]){return b1.find(e)}this.length=1;this[0]=b3}this.context=o;this.selector=e;return this}}else{if(!b2||b2.jquery){return(b2||b1).find(e)}else{return this.constructor(b2).find(e)}}}else{if(bG.isFunction(e)){return b1.ready(e)}}if(e.selector!==aB){this.selector=e.selector;this.context=e.context}return bG.makeArray(e,this)},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return a4.call(this)},get:function(e){return e==null?this.toArray():(e<0?this[this.length+e]:this[e])},pushStack:function(bZ,b1,e){var b0=bG.merge(this.constructor(),bZ);b0.prevObject=this;b0.context=this.context;if(b1==="find"){b0.selector=this.selector+(this.selector?" ":"")+e}else{if(b1){b0.selector=this.selector+"."+b1+"("+e+")"}}return b0},each:function(bZ,e){return bG.each(this,bZ,e)},ready:function(e){bG.ready.promise().done(e);return this},eq:function(e){e=+e;return e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(a4.apply(this,arguments),"slice",a4.call(arguments).join(","))},map:function(e){return this.pushStack(bG.map(this,function(b0,bZ){return e.call(b0,bZ,b0)}))},end:function(){return this.prevObject||this.constructor(null)},push:am,sort:[].sort,splice:[].splice};bG.fn.init.prototype=bG.fn;bG.extend=bG.fn.extend=function(){var b7,b0,e,bZ,b4,b5,b3=arguments[0]||{},b2=1,b1=arguments.length,b6=false;if(typeof b3==="boolean"){b6=b3;b3=arguments[1]||{};b2=2}if(typeof b3!=="object"&&!bG.isFunction(b3)){b3={}}if(b1===b2){b3=this;--b2}for(;b20){return}af.resolveWith(o,[bG]);if(bG.fn.trigger){bG(o).trigger("ready").off("ready")}},isFunction:function(e){return bG.type(e)==="function"},isArray:Array.isArray||function(e){return bG.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):Z[z.call(e)]||"object"},isPlainObject:function(b1){if(!b1||bG.type(b1)!=="object"||b1.nodeType||bG.isWindow(b1)){return false}try{if(b1.constructor&&!V.call(b1,"constructor")&&!V.call(b1.constructor.prototype,"isPrototypeOf")){return false}}catch(b0){return false}var bZ;for(bZ in b1){}return bZ===aB||V.call(b1,bZ)},isEmptyObject:function(bZ){var e;for(e in bZ){return false}return true},error:function(e){throw new Error(e)},parseHTML:function(b1,b0,e){var bZ;if(!b1||typeof b1!=="string"){return null}if(typeof b0==="boolean"){e=b0;b0=0}b0=b0||o;if((bZ=a.exec(b1))){return[b0.createElement(bZ[1])]}bZ=bG.buildFragment([b1],b0,e?null:[]);return bG.merge([],(bZ.cacheable?bG.clone(bZ.fragment):bZ.fragment).childNodes)},parseJSON:function(e){if(!e||typeof e!=="string"){return null}e=bG.trim(e);if(a2.JSON&&a2.JSON.parse){return a2.JSON.parse(e)}if(bf.test(e.replace(bD,"@").replace(a0,"]").replace(bi,""))){return(new Function("return "+e))()}bG.error("Invalid JSON: "+e)},parseXML:function(b1){var bZ,b0;if(!b1||typeof b1!=="string"){return null}try{if(a2.DOMParser){b0=new DOMParser();bZ=b0.parseFromString(b1,"text/xml")}else{bZ=new ActiveXObject("Microsoft.XMLDOM");bZ.async="false";bZ.loadXML(b1)}}catch(b2){bZ=aB}if(!bZ||!bZ.documentElement||bZ.getElementsByTagName("parsererror").length){bG.error("Invalid XML: "+b1)}return bZ},noop:function(){},globalEval:function(e){if(e&&aa.test(e)){(a2.execScript||function(bZ){a2["eval"].call(a2,bZ)})(e)}},camelCase:function(e){return e.replace(bP,"ms-").replace(aU,N)},nodeName:function(bZ,e){return bZ.nodeName&&bZ.nodeName.toLowerCase()===e.toLowerCase()},each:function(b3,b4,b0){var bZ,b1=0,b2=b3.length,e=b2===aB||bG.isFunction(b3);if(b0){if(e){for(bZ in b3){if(b4.apply(b3[bZ],b0)===false){break}}}else{for(;b10&&e[0]&&e[bZ-1])||bZ===0||bG.isArray(e));if(b1){for(;b0-1){b5.splice(ca,1);if(b2){if(ca<=b3){b3--}if(ca<=b4){b4--}}}})}return this},has:function(b9){return bG.inArray(b9,b5)>-1},empty:function(){b5=[];return this},disable:function(){b5=b6=b1=aB;return this},disabled:function(){return !b5},lock:function(){b6=aB;if(!b1){b7.disable()}return this},locked:function(){return !b6},fireWith:function(ca,b9){b9=b9||[];b9=[ca,b9.slice?b9.slice():b9];if(b5&&(!e||b6)){if(b2){b6.push(b9)}else{bZ(b9)}}return this},fire:function(){b7.fireWith(this,arguments);return this},fired:function(){return !!e}};return b7};bG.extend({Deferred:function(b0){var bZ=[["resolve","done",bG.Callbacks("once memory"),"resolved"],["reject","fail",bG.Callbacks("once memory"),"rejected"],["notify","progress",bG.Callbacks("memory")]],b1="pending",b2={state:function(){return b1},always:function(){e.done(arguments).fail(arguments);return this},then:function(){var b3=arguments;return bG.Deferred(function(b4){bG.each(bZ,function(b6,b5){var b8=b5[0],b7=b3[b6];e[b5[1]](bG.isFunction(b7)?function(){var b9=b7.apply(this,arguments);if(b9&&bG.isFunction(b9.promise)){b9.promise().done(b4.resolve).fail(b4.reject).progress(b4.notify)}else{b4[b8+"With"](this===e?b4:this,[b9])}}:b4[b8])});b3=null}).promise()},promise:function(b3){return b3!=null?bG.extend(b3,b2):b2}},e={};b2.pipe=b2.then;bG.each(bZ,function(b4,b3){var b6=b3[2],b5=b3[3];b2[b3[1]]=b6.add;if(b5){b6.add(function(){b1=b5},bZ[b4^1][2].disable,bZ[2][2].lock)}e[b3[0]]=b6.fire;e[b3[0]+"With"]=b6.fireWith});b2.promise(e);if(b0){b0.call(e,e)}return e},when:function(b2){var b0=0,b4=a4.call(arguments),e=b4.length,bZ=e!==1||(b2&&bG.isFunction(b2.promise))?e:0,b7=bZ===1?b2:bG.Deferred(),b1=function(b9,ca,b8){return function(cb){ca[b9]=this;b8[b9]=arguments.length>1?a4.call(arguments):cb;if(b8===b6){b7.notifyWith(ca,b8)}else{if(!(--bZ)){b7.resolveWith(ca,b8)}}}},b6,b3,b5;if(e>1){b6=new Array(e);b3=new Array(e);b5=new Array(e);for(;b0
      a";ca=b0.getElementsByTagName("*");b8=b0.getElementsByTagName("a")[0];if(!ca||!b8||!ca.length){return{}}b9=o.createElement("select");b2=b9.appendChild(o.createElement("option"));b7=b0.getElementsByTagName("input")[0];b8.style.cssText="top:1px;float:left;opacity:.5";cb={leadingWhitespace:(b0.firstChild.nodeType===3),tbody:!b0.getElementsByTagName("tbody").length,htmlSerialize:!!b0.getElementsByTagName("link").length,style:/top/.test(b8.getAttribute("style")),hrefNormalized:(b8.getAttribute("href")==="/a"),opacity:/^0.5/.test(b8.style.opacity),cssFloat:!!b8.style.cssFloat,checkOn:(b7.value==="on"),optSelected:b2.selected,getSetAttribute:b0.className!=="t",enctype:!!o.createElement("form").enctype,html5Clone:o.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",boxModel:(o.compatMode==="CSS1Compat"),submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,boxSizingReliable:true,pixelPosition:false};b7.checked=true;cb.noCloneChecked=b7.cloneNode(true).checked;b9.disabled=true;cb.optDisabled=!b2.disabled;try{delete b0.test}catch(b5){cb.deleteExpando=false}if(!b0.addEventListener&&b0.attachEvent&&b0.fireEvent){b0.attachEvent("onclick",bZ=function(){cb.noCloneEvent=false});b0.cloneNode(true).fireEvent("onclick");b0.detachEvent("onclick",bZ)}b7=o.createElement("input");b7.value="t";b7.setAttribute("type","radio");cb.radioValue=b7.value==="t";b7.setAttribute("checked","checked");b7.setAttribute("name","t");b0.appendChild(b7);b6=o.createDocumentFragment();b6.appendChild(b0.lastChild);cb.checkClone=b6.cloneNode(true).cloneNode(true).lastChild.checked;cb.appendChecked=b7.checked;b6.removeChild(b7);b6.appendChild(b0);if(b0.attachEvent){for(b3 in {submit:true,change:true,focusin:true}){b4="on"+b3;b1=(b4 in b0);if(!b1){b0.setAttribute(b4,"return;");b1=(typeof b0[b4]==="function")}cb[b3+"Bubbles"]=b1}}bG(function(){var cc,cg,ce,cf,cd="padding:0;margin:0;border:0;display:block;overflow:hidden;",e=o.getElementsByTagName("body")[0];if(!e){return}cc=o.createElement("div");cc.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";e.insertBefore(cc,e.firstChild);cg=o.createElement("div");cc.appendChild(cg);cg.innerHTML="
      t
      ";ce=cg.getElementsByTagName("td");ce[0].style.cssText="padding:0;margin:0;border:0;display:none";b1=(ce[0].offsetHeight===0);ce[0].style.display="";ce[1].style.display="none";cb.reliableHiddenOffsets=b1&&(ce[0].offsetHeight===0);cg.innerHTML="";cg.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";cb.boxSizing=(cg.offsetWidth===4);cb.doesNotIncludeMarginInBodyOffset=(e.offsetTop!==1);if(a2.getComputedStyle){cb.pixelPosition=(a2.getComputedStyle(cg,null)||{}).top!=="1%";cb.boxSizingReliable=(a2.getComputedStyle(cg,null)||{width:"4px"}).width==="4px";cf=o.createElement("div");cf.style.cssText=cg.style.cssText=cd;cf.style.marginRight=cf.style.width="0";cg.style.width="1px";cg.appendChild(cf);cb.reliableMarginRight=!parseFloat((a2.getComputedStyle(cf,null)||{}).marginRight)}if(typeof cg.style.zoom!=="undefined"){cg.innerHTML="";cg.style.cssText=cd+"width:1px;padding:1px;display:inline;zoom:1";cb.inlineBlockNeedsLayout=(cg.offsetWidth===3);cg.style.display="block";cg.style.overflow="visible";cg.innerHTML="
      ";cg.firstChild.style.width="5px";cb.shrinkWrapBlocks=(cg.offsetWidth!==3);cc.style.zoom=1}e.removeChild(cc);cc=cg=ce=cf=null});b6.removeChild(b0);ca=b8=b9=b2=b7=b6=b0=null;return cb})();var bt=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,aL=/([A-Z])/g;bG.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(bG.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?bG.cache[e[bG.expando]]:e[bG.expando];return !!e&&!O(e)},data:function(b1,bZ,b3,b2){if(!bG.acceptData(b1)){return}var b4,b6,b7=bG.expando,b5=typeof bZ==="string",b8=b1.nodeType,e=b8?bG.cache:b1,b0=b8?b1[b7]:b1[b7]&&b7;if((!b0||!e[b0]||(!b2&&!e[b0].data))&&b5&&b3===aB){return}if(!b0){if(b8){b1[b7]=b0=bG.deletedIds.pop()||bG.guid++}else{b0=b7}}if(!e[b0]){e[b0]={};if(!b8){e[b0].toJSON=bG.noop}}if(typeof bZ==="object"||typeof bZ==="function"){if(b2){e[b0]=bG.extend(e[b0],bZ)}else{e[b0].data=bG.extend(e[b0].data,bZ)}}b4=e[b0];if(!b2){if(!b4.data){b4.data={}}b4=b4.data}if(b3!==aB){b4[bG.camelCase(bZ)]=b3}if(b5){b6=b4[bZ];if(b6==null){b6=b4[bG.camelCase(bZ)]}}else{b6=b4}return b6},removeData:function(b1,bZ,b2){if(!bG.acceptData(b1)){return}var b5,b4,b3,b6=b1.nodeType,e=b6?bG.cache:b1,b0=b6?b1[bG.expando]:bG.expando;if(!e[b0]){return}if(bZ){b5=b2?e[b0]:e[b0].data;if(b5){if(!bG.isArray(bZ)){if(bZ in b5){bZ=[bZ]}else{bZ=bG.camelCase(bZ);if(bZ in b5){bZ=[bZ]}else{bZ=bZ.split(" ")}}}for(b4=0,b3=bZ.length;b41,null,false)},removeData:function(e){return this.each(function(){bG.removeData(this,e)})}});function bv(b1,b0,b2){if(b2===aB&&b1.nodeType===1){var bZ="data-"+b0.replace(aL,"-$1").toLowerCase();b2=b1.getAttribute(bZ);if(typeof b2==="string"){try{b2=b2==="true"?true:b2==="false"?false:b2==="null"?null:+b2+""===b2?+b2:bt.test(b2)?bG.parseJSON(b2):b2}catch(b3){}bG.data(b1,b0,b2)}else{b2=aB}}return b2}function O(bZ){var e;for(e in bZ){if(e==="data"&&bG.isEmptyObject(bZ[e])){continue}if(e!=="toJSON"){return false}}return true}bG.extend({queue:function(b0,bZ,b1){var e;if(b0){bZ=(bZ||"fx")+"queue";e=bG._data(b0,bZ);if(b1){if(!e||bG.isArray(b1)){e=bG._data(b0,bZ,bG.makeArray(b1))}else{e.push(b1)}}return e||[]}},dequeue:function(b3,b2){b2=b2||"fx";var bZ=bG.queue(b3,b2),b4=bZ.length,b1=bZ.shift(),e=bG._queueHooks(b3,b2),b0=function(){bG.dequeue(b3,b2)};if(b1==="inprogress"){b1=bZ.shift();b4--}if(b1){if(b2==="fx"){bZ.unshift("inprogress")}delete e.stop;b1.call(b3,b0,e)}if(!b4&&e){e.empty.fire()}},_queueHooks:function(b0,bZ){var e=bZ+"queueHooks";return bG._data(b0,e)||bG._data(b0,e,{empty:bG.Callbacks("once memory").add(function(){bG.removeData(b0,bZ+"queue",true);bG.removeData(b0,e,true)})})}});bG.fn.extend({queue:function(e,bZ){var b0=2;if(typeof e!=="string"){bZ=e;e="fx";b0--}if(arguments.length1)},removeAttr:function(e){return this.each(function(){bG.removeAttr(this,e)})},prop:function(e,bZ){return bG.access(this,bG.prop,e,bZ,arguments.length>1)},removeProp:function(e){e=bG.propFix[e]||e;return this.each(function(){try{this[e]=aB;delete this[e]}catch(bZ){}})},addClass:function(b2){var b4,b0,bZ,b1,b3,b5,e;if(bG.isFunction(b2)){return this.each(function(b6){bG(this).addClass(b2.call(this,b6,this.className))})}if(b2&&typeof b2==="string"){b4=b2.split(aV);for(b0=0,bZ=this.length;b0=0){b2=b2.replace(" "+b1[b5]+" "," ")}}b3.className=b4?bG.trim(b2):""}}}return this},toggleClass:function(b1,bZ){var b0=typeof b1,e=typeof bZ==="boolean";if(bG.isFunction(b1)){return this.each(function(b2){bG(this).toggleClass(b1.call(this,b2,this.className,bZ),bZ)})}return this.each(function(){if(b0==="string"){var b4,b3=0,b2=bG(this),b5=bZ,b6=b1.split(aV);while((b4=b6[b3++])){b5=e?b5:!b2.hasClass(b4);b2[b5?"addClass":"removeClass"](b4)}}else{if(b0==="undefined"||b0==="boolean"){if(this.className){bG._data(this,"__className__",this.className)}this.className=this.className||b1===false?"":bG._data(this,"__className__")||""}}})},hasClass:function(e){var b1=" "+e+" ",b0=0,bZ=this.length;for(;b0=0){return true}}return false},val:function(b1){var e,bZ,b2,b0=this[0];if(!arguments.length){if(b0){e=bG.valHooks[b0.type]||bG.valHooks[b0.nodeName.toLowerCase()];if(e&&"get" in e&&(bZ=e.get(b0,"value"))!==aB){return bZ}bZ=b0.value;return typeof bZ==="string"?bZ.replace(ai,""):bZ==null?"":bZ}return}b2=bG.isFunction(b1);return this.each(function(b4){var b5,b3=bG(this);if(this.nodeType!==1){return}if(b2){b5=b1.call(this,b4,b3.val())}else{b5=b1}if(b5==null){b5=""}else{if(typeof b5==="number"){b5+=""}else{if(bG.isArray(b5)){b5=bG.map(b5,function(b6){return b6==null?"":b6+""})}}}e=bG.valHooks[this.type]||bG.valHooks[this.nodeName.toLowerCase()];if(!e||!("set" in e)||e.set(this,b5,"value")===aB){this.value=b5}})}});bG.extend({valHooks:{option:{get:function(e){var bZ=e.attributes.value;return !bZ||bZ.specified?e.value:e.text}},select:{get:function(e){var b4,b0,b6=e.options,b2=e.selectedIndex,b1=e.type==="select-one"||b2<0,b5=b1?null:[],b3=b1?b2+1:b6.length,bZ=b2<0?b3:b1?b2:0;for(;bZ=0});if(!e.length){bZ.selectedIndex=-1}return e}}},attrFn:{},attr:function(b4,b1,b5,b3){var b0,e,b2,bZ=b4.nodeType;if(!b4||bZ===3||bZ===8||bZ===2){return}if(b3&&bG.isFunction(bG.fn[b1])){return bG(b4)[b1](b5)}if(typeof b4.getAttribute==="undefined"){return bG.prop(b4,b1,b5)}b2=bZ!==1||!bG.isXMLDoc(b4);if(b2){b1=b1.toLowerCase();e=bG.attrHooks[b1]||(M.test(b1)?bV:a7)}if(b5!==aB){if(b5===null){bG.removeAttr(b4,b1);return}else{if(e&&"set" in e&&b2&&(b0=e.set(b4,b5,b1))!==aB){return b0}else{b4.setAttribute(b1,b5+"");return b5}}}else{if(e&&"get" in e&&b2&&(b0=e.get(b4,b1))!==null){return b0}else{b0=b4.getAttribute(b1);return b0===null?aB:b0}}},removeAttr:function(b1,b3){var b2,b4,bZ,e,b0=0;if(b3&&b1.nodeType===1){b4=b3.split(aV);for(;b0=0)}}})});var bE=/^(?:textarea|input|select)$/i,br=/^([^\.]*|)(?:\.(.+)|)$/,ba=/(?:^|\s)hover(\.\S+|)\b/,a3=/^key/,bK=/^(?:mouse|contextmenu)|click/,by=/^(?:focusinfocus|focusoutblur)$/,aq=function(e){return bG.event.special.hover?e:e.replace(ba,"mouseenter$1 mouseleave$1")};bG.event={add:function(b1,b5,cc,b3,b2){var b6,b4,cd,cb,ca,b8,e,b9,bZ,b0,b7;if(b1.nodeType===3||b1.nodeType===8||!b5||!cc||!(b6=bG._data(b1))){return}if(cc.handler){bZ=cc;cc=bZ.handler;b2=bZ.selector}if(!cc.guid){cc.guid=bG.guid++}cd=b6.events;if(!cd){b6.events=cd={}}b4=b6.handle;if(!b4){b6.handle=b4=function(ce){return typeof bG!=="undefined"&&(!ce||bG.event.triggered!==ce.type)?bG.event.dispatch.apply(b4.elem,arguments):aB};b4.elem=b1}b5=bG.trim(aq(b5)).split(" ");for(cb=0;cb=0){ca=ca.slice(0,-1);b1=true}if(ca.indexOf(".")>=0){b0=ca.split(".");ca=b0.shift();b0.sort()}if((!b4||bG.event.customEvent[ca])&&!bG.event.global[ca]){return}bZ=typeof bZ==="object"?bZ[bG.expando]?bZ:new bG.Event(ca,bZ):new bG.Event(ca);bZ.type=ca;bZ.isTrigger=true;bZ.exclusive=b1;bZ.namespace=b0.join(".");bZ.namespace_re=bZ.namespace?new RegExp("(^|\\.)"+b0.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;b2=ca.indexOf(":")<0?"on"+ca:"";if(!b4){e=bG.cache;for(b7 in e){if(e[b7].events&&e[b7].events[ca]){bG.event.trigger(bZ,b6,e[b7].handle.elem,true)}}return}bZ.result=aB;if(!bZ.target){bZ.target=b4}b6=b6!=null?bG.makeArray(b6):[];b6.unshift(bZ);b9=bG.event.special[ca]||{};if(b9.trigger&&b9.trigger.apply(b4,b6)===false){return}b5=[[b4,b9.bindType||ca]];if(!cd&&!b9.noBubble&&!bG.isWindow(b4)){cc=b9.delegateType||ca;cb=by.test(cc+ca)?b4:b4.parentNode;for(b3=b4;cb;cb=cb.parentNode){b5.push([cb,cc]);b3=cb}if(b3===(b4.ownerDocument||o)){b5.push([b3.defaultView||b3.parentWindow||a2,cc])}}for(b7=0;b7=0:bG.find(b1,this,null,[ce]).length}if(b7[b1]){b6.push(cc)}}if(b6.length){cb.push({elem:ce,matches:b6})}}}}if(b2.length>b3){cb.push({elem:this,matches:b2.slice(b3)})}for(b5=0;b50?this.on(e,null,b1,b0):this.trigger(e)};if(a3.test(e)){bG.event.fixHooks[e]=bG.event.keyHooks}if(bK.test(e)){bG.event.fixHooks[e]=bG.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function(cS,ch){var cX,ca,cL,b0,cm,cA,cd,cg,cc,cJ,b9=true,cu="undefined",cZ=("sizcache"+Math.random()).replace(".",""),b4=String,b8=cS.document,cb=b8.documentElement,cr=0,cf=0,cE=[].pop,cW=[].push,cl=[].slice,co=[].indexOf||function(c8){var c7=0,e=this.length;for(;c7cL.cacheLength){delete e[c7.shift()]}return(e[c8+" "]=c9)},e)},cU=c5(),cV=c5(),cn=c5(),cy="[\\x20\\t\\r\\n\\f]",ck="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",ci=ck.replace("w","w#"),c4="([*^$|!~]?=)",cP="\\["+cy+"*("+ck+")"+cy+"*(?:"+c4+cy+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+ci+")|)|)"+cy+"*\\]",c6=":("+ck+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+cP+")|[^:]|\\\\.)*|.*))\\)|)",cz=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+cy+"*((?:-\\d)?\\d*)"+cy+"*\\)|)(?=[^-]|$)",cT=new RegExp("^"+cy+"+|((?:^|[^\\\\])(?:\\\\.)*)"+cy+"+$","g"),b5=new RegExp("^"+cy+"*,"+cy+"*"),cH=new RegExp("^"+cy+"*([\\x20\\t\\r\\n\\f>+~])"+cy+"*"),cM=new RegExp(c6),cO=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,cD=/^:not/,cR=/[\x20\t\r\n\f]*[+~]/,c0=/:not\($/,cs=/h\d/i,cN=/input|select|textarea|button/i,ct=/\\(?!\\)/g,cG={ID:new RegExp("^#("+ck+")"),CLASS:new RegExp("^\\.("+ck+")"),NAME:new RegExp("^\\[name=['\"]?("+ck+")['\"]?\\]"),TAG:new RegExp("^("+ck.replace("w","w*")+")"),ATTR:new RegExp("^"+cP),PSEUDO:new RegExp("^"+c6),POS:new RegExp(cz,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+cy+"*(even|odd|(([+-]|)(\\d*)n|)"+cy+"*(?:([+-]|)"+cy+"*(\\d+)|))"+cy+"*\\)|)","i"),needsContext:new RegExp("^"+cy+"*[>+~]|"+cz,"i")},cK=function(c7){var c9=b8.createElement("div");try{return c7(c9)}catch(c8){return false}finally{c9=null}},b7=cK(function(e){e.appendChild(b8.createComment(""));return !e.getElementsByTagName("*").length}),cC=cK(function(e){e.innerHTML="";return e.firstChild&&typeof e.firstChild.getAttribute!==cu&&e.firstChild.getAttribute("href")==="#"}),cq=cK(function(c7){c7.innerHTML="";var e=typeof c7.lastChild.getAttribute("multiple");return e!=="boolean"&&e!=="string"}),cB=cK(function(e){e.innerHTML="";if(!e.getElementsByClassName||!e.getElementsByClassName("e").length){return false}e.lastChild.className="e";return e.getElementsByClassName("e").length===2}),bZ=cK(function(c7){c7.id=cZ+0;c7.innerHTML="
      ";cb.insertBefore(c7,cb.firstChild);var e=b8.getElementsByName&&b8.getElementsByName(cZ).length===2+b8.getElementsByName(cZ+0).length;ca=!b8.getElementById(cZ);cb.removeChild(c7);return e});try{cl.call(cb.childNodes,0)[0].nodeType}catch(c3){cl=function(c7){var c8,e=[];for(;(c8=this[c7]);c7++){e.push(c8)}return e}}function cQ(c9,e,db,de){db=db||[];e=e||b8;var dc,c7,dd,c8,da=e.nodeType;if(!c9||typeof c9!=="string"){return db}if(da!==1&&da!==9){return[]}dd=cm(e);if(!dd&&!de){if((dc=cO.exec(c9))){if((c8=dc[1])){if(da===9){c7=e.getElementById(c8);if(c7&&c7.parentNode){if(c7.id===c8){db.push(c7);return db}}else{return db}}else{if(e.ownerDocument&&(c7=e.ownerDocument.getElementById(c8))&&cA(e,c7)&&c7.id===c8){db.push(c7);return db}}}else{if(dc[2]){cW.apply(db,cl.call(e.getElementsByTagName(c9),0));return db}else{if((c8=dc[3])&&cB&&e.getElementsByClassName){cW.apply(db,cl.call(e.getElementsByClassName(c8),0));return db}}}}}return cY(c9.replace(cT,"$1"),e,db,de,dd)}cQ.matches=function(c7,e){return cQ(c7,null,null,e)};cQ.matchesSelector=function(e,c7){return cQ(c7,null,null,[e]).length>0};function cI(e){return function(c8){var c7=c8.nodeName.toLowerCase();return c7==="input"&&c8.type===e}}function b3(e){return function(c8){var c7=c8.nodeName.toLowerCase();return(c7==="input"||c7==="button")&&c8.type===e}}function cF(e){return c1(function(c7){c7=+c7;return c1(function(c8,dc){var da,c9=e([],c8.length,c7),db=c9.length;while(db--){if(c8[(da=c9[db])]){c8[da]=!(dc[da]=c8[da])}}})})}b0=cQ.getText=function(da){var c9,c7="",c8=0,e=da.nodeType;if(e){if(e===1||e===9||e===11){if(typeof da.textContent==="string"){return da.textContent}else{for(da=da.firstChild;da;da=da.nextSibling){c7+=b0(da)}}}else{if(e===3||e===4){return da.nodeValue}}}else{for(;(c9=da[c8]);c8++){c7+=b0(c9)}}return c7};cm=cQ.isXML=function(e){var c7=e&&(e.ownerDocument||e).documentElement;return c7?c7.nodeName!=="HTML":false};cA=cQ.contains=cb.contains?function(c7,e){var c9=c7.nodeType===9?c7.documentElement:c7,c8=e&&e.parentNode;return c7===c8||!!(c8&&c8.nodeType===1&&c9.contains&&c9.contains(c8))}:cb.compareDocumentPosition?function(c7,e){return e&&!!(c7.compareDocumentPosition(e)&16)}:function(c7,e){while((e=e.parentNode)){if(e===c7){return true}}return false};cQ.attr=function(c8,c7){var c9,e=cm(c8);if(!e){c7=c7.toLowerCase()}if((c9=cL.attrHandle[c7])){return c9(c8)}if(e||cq){return c8.getAttribute(c7)}c9=c8.getAttributeNode(c7);return c9?typeof c8[c7]==="boolean"?c8[c7]?c7:null:c9.specified?c9.value:null:null};cL=cQ.selectors={cacheLength:50,createPseudo:c1,match:cG,attrHandle:cC?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:ca?function(c9,c8,c7){if(typeof c8.getElementById!==cu&&!c7){var e=c8.getElementById(c9);return e&&e.parentNode?[e]:[]}}:function(c9,c8,c7){if(typeof c8.getElementById!==cu&&!c7){var e=c8.getElementById(c9);return e?e.id===c9||typeof e.getAttributeNode!==cu&&e.getAttributeNode("id").value===c9?[e]:ch:[]}},TAG:b7?function(e,c7){if(typeof c7.getElementsByTagName!==cu){return c7.getElementsByTagName(e)}}:function(e,da){var c9=da.getElementsByTagName(e);if(e==="*"){var db,c8=[],c7=0;for(;(db=c9[c7]);c7++){if(db.nodeType===1){c8.push(db)}}return c8}return c9},NAME:bZ&&function(e,c7){if(typeof c7.getElementsByName!==cu){return c7.getElementsByName(name)}},CLASS:cB&&function(c8,c7,e){if(typeof c7.getElementsByClassName!==cu&&!e){return c7.getElementsByClassName(c8)}}},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){e[1]=e[1].replace(ct,"");e[3]=(e[4]||e[5]||"").replace(ct,"");if(e[2]==="~="){e[3]=" "+e[3]+" "}return e.slice(0,4)},CHILD:function(e){e[1]=e[1].toLowerCase();if(e[1]==="nth"){if(!e[2]){cQ.error(e[0])}e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd"));e[4]=+((e[6]+e[7])||e[2]==="odd")}else{if(e[2]){cQ.error(e[0])}}return e},PSEUDO:function(c7){var c8,e;if(cG.CHILD.test(c7[0])){return null}if(c7[3]){c7[2]=c7[3]}else{if((c8=c7[4])){if(cM.test(c8)&&(e=b1(c8,true))&&(e=c8.indexOf(")",c8.length-e)-c8.length)){c8=c8.slice(0,e);c7[0]=c7[0].slice(0,e)}c7[2]=c8}}return c7.slice(0,3)}},filter:{ID:ca?function(e){e=e.replace(ct,"");return function(c7){return c7.getAttribute("id")===e}}:function(e){e=e.replace(ct,"");return function(c8){var c7=typeof c8.getAttributeNode!==cu&&c8.getAttributeNode("id");return c7&&c7.value===e}},TAG:function(e){if(e==="*"){return function(){return true}}e=e.replace(ct,"").toLowerCase();return function(c7){return c7.nodeName&&c7.nodeName.toLowerCase()===e}},CLASS:function(e){var c7=cU[cZ][e+" "];return c7||(c7=new RegExp("(^|"+cy+")"+e+"("+cy+"|$)"))&&cU(e,function(c8){return c7.test(c8.className||(typeof c8.getAttribute!==cu&&c8.getAttribute("class"))||"")})},ATTR:function(c8,c7,e){return function(db,da){var c9=cQ.attr(db,c8);if(c9==null){return c7==="!="}if(!c7){return true}c9+="";return c7==="="?c9===e:c7==="!="?c9!==e:c7==="^="?e&&c9.indexOf(e)===0:c7==="*="?e&&c9.indexOf(e)>-1:c7==="$="?e&&c9.substr(c9.length-e.length)===e:c7==="~="?(" "+c9+" ").indexOf(e)>-1:c7==="|="?c9===e||c9.substr(0,e.length+1)===e+"-":false}},CHILD:function(e,c8,c9,c7){if(e==="nth"){return function(dc){var db,dd,da=dc.parentNode;if(c9===1&&c7===0){return true}if(da){dd=0;for(db=da.firstChild;db;db=db.nextSibling){if(db.nodeType===1){dd++;if(dc===db){break}}}}dd-=c7;return dd===c9||(dd%c9===0&&dd/c9>=0)}}return function(db){var da=db;switch(e){case"only":case"first":while((da=da.previousSibling)){if(da.nodeType===1){return false}}if(e==="first"){return true}da=db;case"last":while((da=da.nextSibling)){if(da.nodeType===1){return false}}return true}}},PSEUDO:function(c9,c8){var e,c7=cL.pseudos[c9]||cL.setFilters[c9.toLowerCase()]||cQ.error("unsupported pseudo: "+c9);if(c7[cZ]){return c7(c8)}if(c7.length>1){e=[c9,c9,"",c8];return cL.setFilters.hasOwnProperty(c9.toLowerCase())?c1(function(dc,de){var db,da=c7(dc,c8),dd=da.length;while(dd--){db=co.call(dc,da[dd]);dc[db]=!(de[db]=da[dd])}}):function(da){return c7(da,0,e)}}return c7}},pseudos:{not:c1(function(e){var c7=[],c8=[],c9=cd(e.replace(cT,"$1"));return c9[cZ]?c1(function(db,dg,de,dc){var df,da=c9(db,null,dc,[]),dd=db.length;while(dd--){if((df=da[dd])){db[dd]=!(dg[dd]=df)}}}):function(dc,db,da){c7[0]=dc;c9(c7,null,da,c8);return !c8.pop()}}),has:c1(function(e){return function(c7){return cQ(e,c7).length>0}}),contains:c1(function(e){return function(c7){return(c7.textContent||c7.innerText||b0(c7)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===false},disabled:function(e){return e.disabled===true},checked:function(e){var c7=e.nodeName.toLowerCase();return(c7==="input"&&!!e.checked)||(c7==="option"&&!!e.selected)},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !cL.pseudos.empty(e)},empty:function(c7){var e;c7=c7.firstChild;while(c7){if(c7.nodeName>"@"||(e=c7.nodeType)===3||e===4){return false}c7=c7.nextSibling}return true},header:function(e){return cs.test(e.nodeName)},text:function(c8){var c7,e;return c8.nodeName.toLowerCase()==="input"&&(c7=c8.type)==="text"&&((e=c8.getAttribute("type"))==null||e.toLowerCase()===c7)},radio:cI("radio"),checkbox:cI("checkbox"),file:cI("file"),password:cI("password"),image:cI("image"),submit:b3("submit"),reset:b3("reset"),button:function(c7){var e=c7.nodeName.toLowerCase();return e==="input"&&c7.type==="button"||e==="button"},input:function(e){return cN.test(e.nodeName)},focus:function(e){var c7=e.ownerDocument;return e===c7.activeElement&&(!c7.hasFocus||c7.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:cF(function(){return[0]}),last:cF(function(e,c7){return[c7-1]}),eq:cF(function(e,c8,c7){return[c7<0?c7+c8:c7]}),even:cF(function(e,c8){for(var c7=0;c7=0;){e.push(c7)}return e}),gt:cF(function(e,c9,c8){for(var c7=c8<0?c8+c9:c8;++c71?function(da,c9,c7){var c8=e.length;while(c8--){if(!e[c8](da,c9,c7)){return false}}return true}:e[0]}function cv(e,c7,c8,c9,dc){var da,df=[],db=0,dd=e.length,de=c7!=null;for(;db-1){dm[dp]=!(dj[dp]=dg)}}}}else{di=cv(di===dj?di.splice(dd,di.length):di);if(db){db(null,dj,di,dl)}else{cW.apply(dj,di)}}})}function cx(dc){var c7,da,c8,db=dc.length,df=cL.relative[dc[0].type],dg=df||cL.relative[" "],c9=df?1:0,dd=cw(function(dh){return dh===c7},dg,true),de=cw(function(dh){return co.call(c7,dh)>-1},dg,true),e=[function(dj,di,dh){return(!df&&(dh||di!==cJ))||((c7=di).nodeType?dd(dj,di,dh):de(dj,di,dh))}];for(;c91&&ce(e),c9>1&&dc.slice(0,c9-1).join("").replace(cT,"$1"),da,c90,da=c9.length>0,c7=function(dk,de,dj,di,dr){var df,dg,dl,dq=[],dp=0,dh="0",db=dk&&[],dm=dr!=null,dn=cJ,dd=dk||da&&cL.find.TAG("*",dr&&de.parentNode||de),dc=(cr+=dn==null?1:Math.E);if(dm){cJ=de!==b8&&de;cX=c7.el}for(;(df=dd[dh])!=null;dh++){if(da&&df){for(dg=0;(dl=c9[dg]);dg++){if(dl(df,de,dj)){di.push(df);break}}if(dm){cr=dc;cX=++c7.el}}if(e){if((df=!dl&&df)){dp--}if(dk){db.push(df)}}}dp+=dh;if(e&&dh!==dp){for(dg=0;(dl=c8[dg]);dg++){dl(db,dq,de,dj)}if(dk){if(dp>0){while(dh--){if(!(db[dh]||dq[dh])){dq[dh]=cE.call(di)}}}dq=cv(dq)}cW.apply(di,dq);if(dm&&!dk&&dq.length>0&&(dp+c8.length)>1){cQ.uniqueSort(di)}}if(dm){cr=dc;cJ=dn}return db};c7.el=0;return e?c1(c7):c7}cd=cQ.compile=function(e,db){var c8,c7=[],da=[],c9=cn[cZ][e+" "];if(!c9){if(!db){db=b1(e)}c8=db.length;while(c8--){c9=cx(db[c8]);if(c9[cZ]){c7.push(c9)}else{da.push(c9)}}c9=cn(e,b6(da,c7))}return c9};function cp(c7,da,c9){var c8=0,e=da.length;for(;c82&&(c7=dh[0]).type==="ID"&&e.nodeType===9&&!dd&&cL.relative[dh[1].type]){e=cL.find.ID(c7.matches[0].replace(ct,""),e,dd)[0];if(!e){return da}c8=c8.slice(dh.shift().length)}for(db=cG.POS.test(c8)?-1:dh.length-1;db>=0;db--){c7=dh[db];if(cL.relative[(dg=c7.type)]){break}if((df=cL.find[dg])){if((de=df(c7.matches[0].replace(ct,""),cR.test(dh[0].type)&&e.parentNode||e,dd))){dh.splice(db,1);c8=de.length&&dh.join("");if(!c8){cW.apply(da,cl.call(de,0));return da}break}}}}}cd(c8,dc)(de,e,dd,da,cR.test(c8));return da}if(b8.querySelectorAll){(function(){var db,dc=cY,da=/'|\\/g,c8=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,c7=[":focus"],e=[":active"],c9=cb.matchesSelector||cb.mozMatchesSelector||cb.webkitMatchesSelector||cb.oMatchesSelector||cb.msMatchesSelector;cK(function(dd){dd.innerHTML="";if(!dd.querySelectorAll("[selected]").length){c7.push("\\["+cy+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)")}if(!dd.querySelectorAll(":checked").length){c7.push(":checked")}});cK(function(dd){dd.innerHTML="

      ";if(dd.querySelectorAll("[test^='']").length){c7.push("[*^$]="+cy+"*(?:\"\"|'')")}dd.innerHTML="";if(!dd.querySelectorAll(":enabled").length){c7.push(":enabled",":disabled")}});c7=new RegExp(c7.join("|"));cY=function(dj,de,dl,dp,dn){if(!dp&&!dn&&!c7.test(dj)){var dh,dm,dg=true,dd=cZ,df=de,dk=de.nodeType===9&&dj;if(de.nodeType===1&&de.nodeName.toLowerCase()!=="object"){dh=b1(dj);if((dg=de.getAttribute("id"))){dd=dg.replace(da,"\\$&")}else{de.setAttribute("id",dd)}dd="[id='"+dd+"'] ";dm=dh.length;while(dm--){dh[dm]=dd+dh[dm].join("")}df=cR.test(dj)&&de.parentNode||de;dk=dh.join(",")}if(dk){try{cW.apply(dl,cl.call(df.querySelectorAll(dk),0));return dl}catch(di){}finally{if(!dg){de.removeAttribute("id")}}}}return dc(dj,de,dl,dp,dn)};if(c9){cK(function(de){db=c9.call(de,"div");try{c9.call(de,"[test!='']:sizzle");e.push("!=",c6)}catch(dd){}});e=new RegExp(e.join("|"));cQ.matchesSelector=function(de,dg){dg=dg.replace(c8,"='$1']");if(!cm(de)&&!e.test(dg)&&!c7.test(dg)){try{var dd=c9.call(de,dg);if(dd||db||de.document&&de.document.nodeType!==11){return dd}}catch(df){}}return cQ(dg,null,null,[de]).length>0}}})()}cL.pseudos.nth=cL.pseudos.eq;function cj(){}cL.filters=cj.prototype=cL.pseudos;cL.setFilters=new cj();cQ.attr=bG.attr;bG.find=cQ;bG.expr=cQ.selectors;bG.expr[":"]=bG.expr.pseudos;bG.unique=cQ.uniqueSort;bG.text=cQ.getText;bG.isXMLDoc=cQ.isXML;bG.contains=cQ.contains})(a2);var ag=/Until$/,bq=/^(?:parents|prev(?:Until|All))/,al=/^.[^:#\[\.,]*$/,y=bG.expr.match.needsContext,bu={children:true,contents:true,next:true,prev:true};bG.fn.extend({find:function(e){var b2,bZ,b4,b5,b3,b1,b0=this;if(typeof e!=="string"){return bG(e).filter(function(){for(b2=0,bZ=b0.length;b20){for(b5=b4;b5=0:bG.filter(e,this).length>0:this.filter(e).length>0)},closest:function(b2,b1){var b3,b0=0,e=this.length,bZ=[],b4=y.test(b2)||typeof b2!=="string"?bG(b2,b1||this.context):0;for(;b0-1:bG.find.matchesSelector(b3,b2)){bZ.push(b3);break}b3=b3.parentNode}}bZ=bZ.length>1?bG.unique(bZ):bZ;return this.pushStack(bZ,"closest",b2)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return bG.inArray(this[0],bG(e))}return bG.inArray(e.jquery?e[0]:e,this)},add:function(e,bZ){var b1=typeof e==="string"?bG(e,bZ):bG.makeArray(e&&e.nodeType?[e]:e),b0=bG.merge(this.get(),b1);return this.pushStack(aR(b1[0])||aR(b0[0])?b0:bG.unique(b0))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}});bG.fn.andSelf=bG.fn.addBack;function aR(e){return !e||!e.parentNode||e.parentNode.nodeType===11}function aY(bZ,e){do{bZ=bZ[e]}while(bZ&&bZ.nodeType!==1);return bZ}bG.each({parent:function(bZ){var e=bZ.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return bG.dir(e,"parentNode")},parentsUntil:function(bZ,e,b0){return bG.dir(bZ,"parentNode",b0)},next:function(e){return aY(e,"nextSibling")},prev:function(e){return aY(e,"previousSibling")},nextAll:function(e){return bG.dir(e,"nextSibling")},prevAll:function(e){return bG.dir(e,"previousSibling")},nextUntil:function(bZ,e,b0){return bG.dir(bZ,"nextSibling",b0)},prevUntil:function(bZ,e,b0){return bG.dir(bZ,"previousSibling",b0)},siblings:function(e){return bG.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return bG.sibling(e.firstChild)},contents:function(e){return bG.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:bG.merge([],e.childNodes)}},function(e,bZ){bG.fn[e]=function(b2,b0){var b1=bG.map(this,bZ,b2);if(!ag.test(e)){b0=b2}if(b0&&typeof b0==="string"){b1=bG.filter(b0,b1)}b1=this.length>1&&!bu[e]?bG.unique(b1):b1;if(this.length>1&&bq.test(e)){b1=b1.reverse()}return this.pushStack(b1,e,a4.call(arguments).join(","))}});bG.extend({filter:function(b0,e,bZ){if(bZ){b0=":not("+b0+")"}return e.length===1?bG.find.matchesSelector(e[0],b0)?[e[0]]:[]:bG.find.matches(b0,e)},dir:function(b0,bZ,b2){var e=[],b1=b0[bZ];while(b1&&b1.nodeType!==9&&(b2===aB||b1.nodeType!==1||!bG(b1).is(b2))){if(b1.nodeType===1){e.push(b1)}b1=b1[bZ]}return e},sibling:function(b0,bZ){var e=[];for(;b0;b0=b0.nextSibling){if(b0.nodeType===1&&b0!==bZ){e.push(b0)}}return e}});function aM(b1,b0,e){b0=b0||0;if(bG.isFunction(b0)){return bG.grep(b1,function(b3,b2){var b4=!!b0.call(b3,b2,b3);return b4===e})}else{if(b0.nodeType){return bG.grep(b1,function(b3,b2){return(b3===b0)===e})}else{if(typeof b0==="string"){var bZ=bG.grep(b1,function(b2){return b2.nodeType===1});if(al.test(b0)){return bG.filter(b0,bZ,!e)}else{b0=bG.filter(b0,bZ)}}}}return bG.grep(b1,function(b3,b2){return(bG.inArray(b3,b0)>=0)===e})}function A(e){var b0=c.split("|"),bZ=e.createDocumentFragment();if(bZ.createElement){while(b0.length){bZ.createElement(b0.pop())}}return bZ}var c="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",av=/ jQuery\d+="(?:null|\d+)"/g,bY=/^\s+/,ay=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,p=/<([\w:]+)/,bT=/]","i"),aE=/^(?:checkbox|radio)$/,bR=/checked\s*(?:[^=]|=\s*.checked.)/i,bw=/\/(java|ecma)script/i,aH=/^\s*\s*$/g,T={option:[1,""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]},aQ=A(o),l=aQ.appendChild(o.createElement("div"));T.optgroup=T.option;T.tbody=T.tfoot=T.colgroup=T.caption=T.thead;T.th=T.td;if(!bG.support.htmlSerialize){T._default=[1,"X
      ","
      "]}bG.fn.extend({text:function(e){return bG.access(this,function(bZ){return bZ===aB?bG.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(bZ))},null,e,arguments.length)},wrapAll:function(e){if(bG.isFunction(e)){return this.each(function(b0){bG(this).wrapAll(e.call(this,b0))})}if(this[0]){var bZ=bG(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bZ.insertBefore(this[0])}bZ.map(function(){var b0=this;while(b0.firstChild&&b0.firstChild.nodeType===1){b0=b0.firstChild}return b0}).append(this)}return this},wrapInner:function(e){if(bG.isFunction(e)){return this.each(function(bZ){bG(this).wrapInner(e.call(this,bZ))})}return this.each(function(){var bZ=bG(this),b0=bZ.contents();if(b0.length){b0.wrapAll(e)}else{bZ.append(e)}})},wrap:function(e){var bZ=bG.isFunction(e);return this.each(function(b0){bG(this).wrapAll(bZ?e.call(this,b0):e)})},unwrap:function(){return this.parent().each(function(){if(!bG.nodeName(this,"body")){bG(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11){this.insertBefore(e,this.firstChild)}})},before:function(){if(!aR(this[0])){return this.domManip(arguments,false,function(bZ){this.parentNode.insertBefore(bZ,this)})}if(arguments.length){var e=bG.clean(arguments);return this.pushStack(bG.merge(e,this),"before",this.selector)}},after:function(){if(!aR(this[0])){return this.domManip(arguments,false,function(bZ){this.parentNode.insertBefore(bZ,this.nextSibling)})}if(arguments.length){var e=bG.clean(arguments);return this.pushStack(bG.merge(this,e),"after",this.selector)}},remove:function(e,b1){var b0,bZ=0;for(;(b0=this[bZ])!=null;bZ++){if(!e||bG.filter(e,[b0]).length){if(!b1&&b0.nodeType===1){bG.cleanData(b0.getElementsByTagName("*"));bG.cleanData([b0])}if(b0.parentNode){b0.parentNode.removeChild(b0)}}}return this},empty:function(){var bZ,e=0;for(;(bZ=this[e])!=null;e++){if(bZ.nodeType===1){bG.cleanData(bZ.getElementsByTagName("*"))}while(bZ.firstChild){bZ.removeChild(bZ.firstChild)}}return this},clone:function(bZ,e){bZ=bZ==null?false:bZ;e=e==null?bZ:e;return this.map(function(){return bG.clone(this,bZ,e)})},html:function(e){return bG.access(this,function(b2){var b1=this[0]||{},b0=0,bZ=this.length;if(b2===aB){return b1.nodeType===1?b1.innerHTML.replace(av,""):aB}if(typeof b2==="string"&&!aj.test(b2)&&(bG.support.htmlSerialize||!K.test(b2))&&(bG.support.leadingWhitespace||!bY.test(b2))&&!T[(p.exec(b2)||["",""])[1].toLowerCase()]){b2=b2.replace(ay,"<$1>");try{for(;b01&&typeof b5==="string"&&bR.test(b5)){return this.each(function(){bG(this).domManip(b4,b8,b7)})}if(bG.isFunction(b5)){return this.each(function(ca){var b9=bG(this);b4[0]=b5.call(this,ca,b8?b9.html():aB);b9.domManip(b4,b8,b7)})}if(this[0]){b0=bG.buildFragment(b4,this,bZ);b3=b0.fragment;b2=b3.firstChild;if(b3.childNodes.length===1){b3=b2}if(b2){b8=b8&&bG.nodeName(b2,"tr");for(b6=b0.cacheable||e-1;b10?this.clone(true):this).get();bG(b6[b4])[bZ](b2);b3=b3.concat(b2)}return this.pushStack(b3,e,b6.selector)}}});function m(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function bS(e){if(aE.test(e.type)){e.defaultChecked=e.checked}}bG.extend({clone:function(b2,b4,b0){var e,bZ,b1,b3;if(bG.support.html5Clone||bG.isXMLDoc(b2)||!K.test("<"+b2.nodeName+">")){b3=b2.cloneNode(true)}else{l.innerHTML=b2.outerHTML;l.removeChild(b3=l.firstChild)}if((!bG.support.noCloneEvent||!bG.support.noCloneChecked)&&(b2.nodeType===1||b2.nodeType===11)&&!bG.isXMLDoc(b2)){F(b2,b3);e=m(b2);bZ=m(b3);for(b1=0;e[b1];++b1){if(bZ[b1]){F(e[b1],bZ[b1])}}}if(b4){ao(b2,b3);if(b0){e=m(b2);bZ=m(b3);for(b1=0;e[b1];++b1){ao(e[b1],bZ[b1])}}}e=bZ=null;return b3},clean:function(cb,b0,e,b1){var b8,b7,ca,cf,b4,ce,b5,b2,bZ,b9,cd,b6,b3=b0===o&&aQ,cc=[];if(!b0||typeof b0.createDocumentFragment==="undefined"){b0=o}for(b8=0;(ca=cb[b8])!=null;b8++){if(typeof ca==="number"){ca+=""}if(!ca){continue}if(typeof ca==="string"){if(!J.test(ca)){ca=b0.createTextNode(ca)}else{b3=b3||A(b0);b5=b0.createElement("div");b3.appendChild(b5);ca=ca.replace(ay,"<$1>");cf=(p.exec(ca)||["",""])[1].toLowerCase();b4=T[cf]||T._default;ce=b4[0];b5.innerHTML=b4[1]+ca+b4[2];while(ce--){b5=b5.lastChild}if(!bG.support.tbody){b2=bT.test(ca);bZ=cf==="table"&&!b2?b5.firstChild&&b5.firstChild.childNodes:b4[1]===""&&!b2?b5.childNodes:[];for(b7=bZ.length-1;b7>=0;--b7){if(bG.nodeName(bZ[b7],"tbody")&&!bZ[b7].childNodes.length){bZ[b7].parentNode.removeChild(bZ[b7])}}}if(!bG.support.leadingWhitespace&&bY.test(ca)){b5.insertBefore(b0.createTextNode(bY.exec(ca)[0]),b5.firstChild)}ca=b5.childNodes;b5.parentNode.removeChild(b5)}}if(ca.nodeType){cc.push(ca)}else{bG.merge(cc,ca)}}if(b5){ca=b5=b3=null}if(!bG.support.appendChecked){for(b8=0;(ca=cc[b8])!=null;b8++){if(bG.nodeName(ca,"input")){bS(ca)}else{if(typeof ca.getElementsByTagName!=="undefined"){bG.grep(ca.getElementsByTagName("input"),bS)}}}}if(e){cd=function(cg){if(!cg.type||bw.test(cg.type)){return b1?b1.push(cg.parentNode?cg.parentNode.removeChild(cg):cg):e.appendChild(cg)}};for(b8=0;(ca=cc[b8])!=null;b8++){if(!(bG.nodeName(ca,"script")&&cd(ca))){e.appendChild(ca);if(typeof ca.getElementsByTagName!=="undefined"){b6=bG.grep(bG.merge([],ca.getElementsByTagName("script")),cd);cc.splice.apply(cc,[b8+1,0].concat(b6));b8+=b6.length}}}}return cc},cleanData:function(bZ,b7){var b2,b0,b1,b6,b3=0,b8=bG.expando,e=bG.cache,b4=bG.support.deleteExpando,b5=bG.event.special;for(;(b1=bZ[b3])!=null;b3++){if(b7||bG.acceptData(b1)){b0=b1[b8];b2=b0&&e[b0];if(b2){if(b2.events){for(b6 in b2.events){if(b5[b6]){bG.event.remove(b1,b6)}else{bG.removeEvent(b1,b6,b2.handle)}}}if(e[b0]){delete e[b0];if(b4){delete b1[b8]}else{if(b1.removeAttribute){b1.removeAttribute(b8)}else{b1[b8]=null}}bG.deletedIds.push(b0)}}}}}});(function(){var e,bZ;bG.uaMatch=function(b1){b1=b1.toLowerCase();var b0=/(chrome)[ \/]([\w.]+)/.exec(b1)||/(webkit)[ \/]([\w.]+)/.exec(b1)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(b1)||/(msie) ([\w.]+)/.exec(b1)||b1.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(b1)||[];return{browser:b0[1]||"",version:b0[2]||"0"}};e=bG.uaMatch(d.userAgent);bZ={};if(e.browser){bZ[e.browser]=true;bZ.version=e.version}if(bZ.chrome){bZ.webkit=true}else{if(bZ.webkit){bZ.safari=true}}bG.browser=bZ;bG.sub=function(){function b0(b3,b4){return new b0.fn.init(b3,b4)}bG.extend(true,b0,this);b0.superclass=this;b0.fn=b0.prototype=this();b0.fn.constructor=b0;b0.sub=this.sub;b0.fn.init=function b2(b3,b4){if(b4&&b4 instanceof bG&&!(b4 instanceof b0)){b4=b0(b4)}return bG.fn.init.call(this,b3,b4,b1)};b0.fn.init.prototype=b0.fn;var b1=b0(o);return b0}})();var E,az,aW,be=/alpha\([^)]*\)/i,aS=/opacity=([^)]*)/,bk=/^(top|right|bottom|left)$/,G=/^(none|table(?!-c[ea]).+)/,aZ=/^margin/,a8=new RegExp("^("+bx+")(.*)$","i"),W=new RegExp("^("+bx+")(?!px)[a-z%]+$","i"),S=new RegExp("^([-+])=("+bx+")","i"),bh={BODY:"block"},a9={position:"absolute",visibility:"hidden",display:"block"},bA={letterSpacing:0,fontWeight:400},bQ=["Top","Right","Bottom","Left"],ar=["Webkit","O","Moz","ms"],aJ=bG.fn.toggle;function b(b1,bZ){if(bZ in b1){return bZ}var b2=bZ.charAt(0).toUpperCase()+bZ.slice(1),e=bZ,b0=ar.length;while(b0--){bZ=ar[b0]+b2;if(bZ in b1){return bZ}}return e}function Q(bZ,e){bZ=e||bZ;return bG.css(bZ,"display")==="none"||!bG.contains(bZ.ownerDocument,bZ)}function s(b3,e){var b2,b4,bZ=[],b0=0,b1=b3.length;for(;b01)},show:function(){return s(this,true)},hide:function(){return s(this)},toggle:function(b0,bZ){var e=typeof b0==="boolean";if(bG.isFunction(b0)&&bG.isFunction(bZ)){return aJ.apply(this,arguments)}return this.each(function(){if(e?b0:Q(this)){bG(this).show()}else{bG(this).hide()}})}});bG.extend({cssHooks:{opacity:{get:function(b0,bZ){if(bZ){var e=E(b0,"opacity");return e===""?"1":e}}}},cssNumber:{fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":bG.support.cssFloat?"cssFloat":"styleFloat"},style:function(b1,b0,b7,b2){if(!b1||b1.nodeType===3||b1.nodeType===8||!b1.style){return}var b5,b6,b8,b3=bG.camelCase(b0),bZ=b1.style;b0=bG.cssProps[b3]||(bG.cssProps[b3]=b(bZ,b3));b8=bG.cssHooks[b0]||bG.cssHooks[b3];if(b7!==aB){b6=typeof b7;if(b6==="string"&&(b5=S.exec(b7))){b7=(b5[1]+1)*b5[2]+parseFloat(bG.css(b1,b0));b6="number"}if(b7==null||b6==="number"&&isNaN(b7)){return}if(b6==="number"&&!bG.cssNumber[b3]){b7+="px"}if(!b8||!("set" in b8)||(b7=b8.set(b1,b7,b2))!==aB){try{bZ[b0]=b7}catch(b4){}}}else{if(b8&&"get" in b8&&(b5=b8.get(b1,false,b2))!==aB){return b5}return bZ[b0]}},css:function(b4,b2,b3,bZ){var b5,b1,e,b0=bG.camelCase(b2);b2=bG.cssProps[b0]||(bG.cssProps[b0]=b(b4.style,b0));e=bG.cssHooks[b2]||bG.cssHooks[b0];if(e&&"get" in e){b5=e.get(b4,true,bZ)}if(b5===aB){b5=E(b4,b2)}if(b5==="normal"&&b2 in bA){b5=bA[b2]}if(b3||bZ!==aB){b1=parseFloat(b5);return b3||bG.isNumeric(b1)?b1||0:b5}return b5},swap:function(b2,b1,b3){var b0,bZ,e={};for(bZ in b1){e[bZ]=b2.style[bZ];b2.style[bZ]=b1[bZ]}b0=b3.call(b2);for(bZ in b1){b2.style[bZ]=e[bZ]}return b0}});if(a2.getComputedStyle){E=function(b5,bZ){var e,b2,b1,b4,b3=a2.getComputedStyle(b5,null),b0=b5.style;if(b3){e=b3.getPropertyValue(bZ)||b3[bZ];if(e===""&&!bG.contains(b5.ownerDocument,b5)){e=bG.style(b5,bZ)}if(W.test(e)&&aZ.test(bZ)){b2=b0.width;b1=b0.minWidth;b4=b0.maxWidth;b0.minWidth=b0.maxWidth=b0.width=e;e=b3.width;b0.width=b2;b0.minWidth=b1;b0.maxWidth=b4}}return e}}else{if(o.documentElement.currentStyle){E=function(b2,b0){var b3,e,bZ=b2.currentStyle&&b2.currentStyle[b0],b1=b2.style;if(bZ==null&&b1&&b1[b0]){bZ=b1[b0]}if(W.test(bZ)&&!bk.test(b0)){b3=b1.left;e=b2.runtimeStyle&&b2.runtimeStyle.left;if(e){b2.runtimeStyle.left=b2.currentStyle.left}b1.left=b0==="fontSize"?"1em":bZ;bZ=b1.pixelLeft+"px";b1.left=b3;if(e){b2.runtimeStyle.left=e}}return bZ===""?"auto":bZ}}}function aG(e,b0,b1){var bZ=a8.exec(b0);return bZ?Math.max(0,bZ[1]-(b1||0))+(bZ[2]||"px"):b0}function at(b1,bZ,e,b3){var b0=e===(b3?"border":"content")?4:bZ==="width"?1:0,b2=0;for(;b0<4;b0+=2){if(e==="margin"){b2+=bG.css(b1,e+bQ[b0],true)}if(b3){if(e==="content"){b2-=parseFloat(E(b1,"padding"+bQ[b0]))||0}if(e!=="margin"){b2-=parseFloat(E(b1,"border"+bQ[b0]+"Width"))||0}}else{b2+=parseFloat(E(b1,"padding"+bQ[b0]))||0;if(e!=="padding"){b2+=parseFloat(E(b1,"border"+bQ[b0]+"Width"))||0}}}return b2}function u(b1,bZ,e){var b2=bZ==="width"?b1.offsetWidth:b1.offsetHeight,b0=true,b3=bG.support.boxSizing&&bG.css(b1,"boxSizing")==="border-box";if(b2<=0||b2==null){b2=E(b1,bZ);if(b2<0||b2==null){b2=b1.style[bZ]}if(W.test(b2)){return b2}b0=b3&&(bG.support.boxSizingReliable||b2===b1.style[bZ]);b2=parseFloat(b2)||0}return(b2+at(b1,bZ,e||(b3?"border":"content"),b0))+"px"}function bC(b0){if(bh[b0]){return bh[b0]}var e=bG("<"+b0+">").appendTo(o.body),bZ=e.css("display");e.remove();if(bZ==="none"||bZ===""){az=o.body.appendChild(az||bG.extend(o.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!aW||!az.createElement){aW=(az.contentWindow||az.contentDocument).document;aW.write("");aW.close()}e=aW.body.appendChild(aW.createElement(b0));bZ=E(e,"display");o.body.removeChild(az)}bh[b0]=bZ;return bZ}bG.each(["height","width"],function(bZ,e){bG.cssHooks[e]={get:function(b2,b1,b0){if(b1){if(b2.offsetWidth===0&&G.test(E(b2,"display"))){return bG.swap(b2,a9,function(){return u(b2,e,b0)})}else{return u(b2,e,b0)}}},set:function(b1,b2,b0){return aG(b1,b2,b0?at(b1,e,b0,bG.support.boxSizing&&bG.css(b1,"boxSizing")==="border-box"):0)}}});if(!bG.support.opacity){bG.cssHooks.opacity={get:function(bZ,e){return aS.test((e&&bZ.currentStyle?bZ.currentStyle.filter:bZ.style.filter)||"")?(0.01*parseFloat(RegExp.$1))+"":e?"1":""},set:function(b2,b3){var b1=b2.style,bZ=b2.currentStyle,e=bG.isNumeric(b3)?"alpha(opacity="+b3*100+")":"",b0=bZ&&bZ.filter||b1.filter||"";b1.zoom=1;if(b3>=1&&bG.trim(b0.replace(be,""))===""&&b1.removeAttribute){b1.removeAttribute("filter");if(bZ&&!bZ.filter){return}}b1.filter=be.test(b0)?b0.replace(be,e):b0+" "+e}}}bG(function(){if(!bG.support.reliableMarginRight){bG.cssHooks.marginRight={get:function(bZ,e){return bG.swap(bZ,{display:"inline-block"},function(){if(e){return E(bZ,"marginRight")}})}}}if(!bG.support.pixelPosition&&bG.fn.position){bG.each(["top","left"],function(e,bZ){bG.cssHooks[bZ]={get:function(b2,b1){if(b1){var b0=E(b2,bZ);return W.test(b0)?bG(b2).position()[bZ]+"px":b0}}}})}});if(bG.expr&&bG.expr.filters){bG.expr.filters.hidden=function(e){return(e.offsetWidth===0&&e.offsetHeight===0)||(!bG.support.reliableHiddenOffsets&&((e.style&&e.style.display)||E(e,"display"))==="none")};bG.expr.filters.visible=function(e){return !bG.expr.filters.hidden(e)}}bG.each({margin:"",padding:"",border:"Width"},function(e,bZ){bG.cssHooks[e+bZ]={expand:function(b2){var b1,b3=typeof b2==="string"?b2.split(" "):[b2],b0={};for(b1=0;b1<4;b1++){b0[e+bQ[b1]+bZ]=b3[b1]||b3[b1-2]||b3[0]}return b0}};if(!aZ.test(e)){bG.cssHooks[e+bZ].set=aG}});var bs=/%20/g,aP=/\[\]$/,U=/\r?\n/g,bz=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,aD=/^(?:select|textarea)/i;bG.fn.extend({serialize:function(){return bG.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?bG.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||aD.test(this.nodeName)||bz.test(this.type))}).map(function(e,bZ){var b0=bG(this).val();return b0==null?null:bG.isArray(b0)?bG.map(b0,function(b2,b1){return{name:bZ.name,value:b2.replace(U,"\r\n")}}):{name:bZ.name,value:b0.replace(U,"\r\n")}}).get()}});bG.param=function(e,b0){var b1,bZ=[],b2=function(b3,b4){b4=bG.isFunction(b4)?b4():(b4==null?"":b4);bZ[bZ.length]=encodeURIComponent(b3)+"="+encodeURIComponent(b4)};if(b0===aB){b0=bG.ajaxSettings&&bG.ajaxSettings.traditional}if(bG.isArray(e)||(e.jquery&&!bG.isPlainObject(e))){bG.each(e,function(){b2(this.name,this.value)})}else{for(b1 in e){k(b1,e[b1],b0,b2)}}return bZ.join("&").replace(bs,"+")};function k(b0,b2,bZ,b1){var e;if(bG.isArray(b2)){bG.each(b2,function(b4,b3){if(bZ||aP.test(b0)){b1(b0,b3)}else{k(b0+"["+(typeof b3==="object"?b4:"")+"]",b3,bZ,b1)}})}else{if(!bZ&&bG.type(b2)==="object"){for(e in b2){k(b0+"["+e+"]",b2[e],bZ,b1)}}else{b1(b0,b2)}}}var bX,Y,an=/#.*$/,ad=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,B=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,r=/^(?:GET|HEAD)$/,aC=/^\/\//,bN=/\?/,g=/)<[^<]*)*<\/script>/gi,P=/([?&])_=[^&]*/,aT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,bW=bG.fn.load,v={},a6={},aX=["*/"]+["*"];try{Y=aI.href}catch(bd){Y=o.createElement("a");Y.href="";Y=Y.href}bX=aT.exec(Y.toLowerCase())||[];function bI(e){return function(b2,b4){if(typeof b2!=="string"){b4=b2;b2="*"}var bZ,b5,b6,b1=b2.toLowerCase().split(aV),b0=0,b3=b1.length;if(bG.isFunction(b4)){for(;b0=0){e=b1.slice(b3,b1.length);b1=b1.slice(0,b3)}if(bG.isFunction(b4)){b5=b4;b4=aB}else{if(b4&&typeof b4==="object"){b2="POST"}}bG.ajax({url:b1,type:b2,dataType:"html",data:b4,complete:function(b7,b6){if(b5){bZ.each(b5,b0||[b7.responseText,b6,b7])}}}).done(function(b6){b0=arguments;bZ.html(e?bG("
      ").append(b6.replace(g,"")).find(e):b6)});return this};bG.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bZ){bG.fn[bZ]=function(b0){return this.on(bZ,b0)}});bG.each(["get","post"],function(e,bZ){bG[bZ]=function(b0,b2,b3,b1){if(bG.isFunction(b2)){b1=b1||b3;b3=b2;b2=aB}return bG.ajax({type:bZ,url:b0,data:b2,success:b3,dataType:b1})}});bG.extend({getScript:function(e,bZ){return bG.get(e,aB,bZ,"script")},getJSON:function(e,bZ,b0){return bG.get(e,bZ,b0,"json")},ajaxSetup:function(bZ,e){if(e){t(bZ,bG.ajaxSettings)}else{e=bZ;bZ=bG.ajaxSettings}t(bZ,e);return bZ},ajaxSettings:{url:Y,isLocal:B.test(bX[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a2.String,"text html":true,"text json":bG.parseJSON,"text xml":bG.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:bI(v),ajaxTransport:bI(a6),ajax:function(b4,b1){if(typeof b4==="object"){b1=b4;b4=aB}b1=b1||{};var b7,cl,b2,cg,b9,cd,b0,cf,b8=bG.ajaxSetup({},b1),cn=b8.context||b8,cb=cn!==b8&&(cn.nodeType||cn instanceof bG)?bG(cn):bG.event,cm=bG.Deferred(),ci=bG.Callbacks("once memory"),b5=b8.statusCode||{},cc={},cj={},b3=0,b6="canceled",ce={readyState:0,setRequestHeader:function(co,cp){if(!b3){var e=co.toLowerCase();co=cj[e]=cj[e]||co;cc[co]=cp}return this},getAllResponseHeaders:function(){return b3===2?cl:null},getResponseHeader:function(co){var e;if(b3===2){if(!b2){b2={};while((e=ad.exec(cl))){b2[e[1].toLowerCase()]=e[2]}}e=b2[co.toLowerCase()]}return e===aB?null:e},overrideMimeType:function(e){if(!b3){b8.mimeType=e}return this},abort:function(e){e=e||b6;if(cg){cg.abort(e)}ca(0,e);return this}};function ca(cs,co,ct,cq){var e,cw,cu,cr,cv,cp=co;if(b3===2){return}b3=2;if(b9){clearTimeout(b9)}cg=aB;cl=cq||"";ce.readyState=cs>0?4:0;if(ct){cr=h(b8,ce,ct)}if(cs>=200&&cs<300||cs===304){if(b8.ifModified){cv=ce.getResponseHeader("Last-Modified");if(cv){bG.lastModified[b7]=cv}cv=ce.getResponseHeader("Etag");if(cv){bG.etag[b7]=cv}}if(cs===304){cp="notmodified";e=true}else{e=ae(b8,cr);cp=e.state;cw=e.data;cu=e.error;e=!cu}}else{cu=cp;if(!cp||cs){cp="error";if(cs<0){cs=0}}}ce.status=cs;ce.statusText=(co||cp)+"";if(e){cm.resolveWith(cn,[cw,cp,ce])}else{cm.rejectWith(cn,[ce,cp,cu])}ce.statusCode(b5);b5=aB;if(b0){cb.trigger("ajax"+(e?"Success":"Error"),[ce,b8,e?cw:cu])}ci.fireWith(cn,[ce,cp]);if(b0){cb.trigger("ajaxComplete",[ce,b8]);if(!(--bG.active)){bG.event.trigger("ajaxStop")}}}cm.promise(ce);ce.success=ce.done;ce.error=ce.fail;ce.complete=ci.add;ce.statusCode=function(co){if(co){var e;if(b3<2){for(e in co){b5[e]=[b5[e],co[e]]}}else{e=co[ce.status];ce.always(e)}}return this};b8.url=((b4||b8.url)+"").replace(an,"").replace(aC,bX[1]+"//");b8.dataTypes=bG.trim(b8.dataType||"*").toLowerCase().split(aV);if(b8.crossDomain==null){cd=aT.exec(b8.url.toLowerCase());b8.crossDomain=!!(cd&&(cd[1]!==bX[1]||cd[2]!==bX[2]||(cd[3]||(cd[1]==="http:"?80:443))!=(bX[3]||(bX[1]==="http:"?80:443))))}if(b8.data&&b8.processData&&typeof b8.data!=="string"){b8.data=bG.param(b8.data,b8.traditional)}q(v,b8,b1,ce);if(b3===2){return ce}b0=b8.global;b8.type=b8.type.toUpperCase();b8.hasContent=!r.test(b8.type);if(b0&&bG.active++===0){bG.event.trigger("ajaxStart")}if(!b8.hasContent){if(b8.data){b8.url+=(bN.test(b8.url)?"&":"?")+b8.data;delete b8.data}b7=b8.url;if(b8.cache===false){var bZ=bG.now(),ck=b8.url.replace(P,"$1_="+bZ);b8.url=ck+((ck===b8.url)?(bN.test(b8.url)?"&":"?")+"_="+bZ:"")}}if(b8.data&&b8.hasContent&&b8.contentType!==false||b1.contentType){ce.setRequestHeader("Content-Type",b8.contentType)}if(b8.ifModified){b7=b7||b8.url;if(bG.lastModified[b7]){ce.setRequestHeader("If-Modified-Since",bG.lastModified[b7])}if(bG.etag[b7]){ce.setRequestHeader("If-None-Match",bG.etag[b7])}}ce.setRequestHeader("Accept",b8.dataTypes[0]&&b8.accepts[b8.dataTypes[0]]?b8.accepts[b8.dataTypes[0]]+(b8.dataTypes[0]!=="*"?", "+aX+"; q=0.01":""):b8.accepts["*"]);for(cf in b8.headers){ce.setRequestHeader(cf,b8.headers[cf])}if(b8.beforeSend&&(b8.beforeSend.call(cn,ce,b8)===false||b3===2)){return ce.abort()}b6="abort";for(cf in {success:1,error:1,complete:1}){ce[cf](b8[cf])}cg=q(a6,b8,b1,ce);if(!cg){ca(-1,"No Transport")}else{ce.readyState=1;if(b0){cb.trigger("ajaxSend",[ce,b8])}if(b8.async&&b8.timeout>0){b9=setTimeout(function(){ce.abort("timeout")},b8.timeout)}try{b3=1;cg.send(cc,ca)}catch(ch){if(b3<2){ca(-1,ch)}else{throw ch}}}return ce},active:0,lastModified:{},etag:{}});function h(b7,b6,b3){var b2,b4,b1,e,bZ=b7.contents,b5=b7.dataTypes,b0=b7.responseFields;for(b4 in b0){if(b4 in b3){b6[b0[b4]]=b3[b4]}}while(b5[0]==="*"){b5.shift();if(b2===aB){b2=b7.mimeType||b6.getResponseHeader("content-type")}}if(b2){for(b4 in bZ){if(bZ[b4]&&bZ[b4].test(b2)){b5.unshift(b4);break}}}if(b5[0] in b3){b1=b5[0]}else{for(b4 in b3){if(!b5[0]||b7.converters[b4+" "+b5[0]]){b1=b4;break}if(!e){e=b4}}b1=b1||e}if(b1){if(b1!==b5[0]){b5.unshift(b1)}return b3[b1]}}function ae(b9,b1){var b7,bZ,b5,b3,b6=b9.dataTypes.slice(),b0=b6[0],b8={},b2=0;if(b9.dataFilter){b1=b9.dataFilter(b1,b9.dataType)}if(b6[1]){for(b7 in b9.converters){b8[b7.toLowerCase()]=b9.converters[b7]}}for(;(b5=b6[++b2]);){if(b5!=="*"){if(b0!=="*"&&b0!==b5){b7=b8[b0+" "+b5]||b8["* "+b5];if(!b7){for(bZ in b8){b3=bZ.split(" ");if(b3[1]===b5){b7=b8[b0+" "+b3[0]]||b8["* "+b3[0]];if(b7){if(b7===true){b7=b8[bZ]}else{if(b8[bZ]!==true){b5=b3[0];b6.splice(b2--,0,b5)}}break}}}}if(b7!==true){if(b7&&b9["throws"]){b1=b7(b1)}else{try{b1=b7(b1)}catch(b4){return{state:"parsererror",error:b7?b4:"No conversion from "+b0+" to "+b5}}}}}b0=b5}}return{state:"success",data:b1}}var bp=[],aw=/\?/,a5=/(=)\?(?=&|$)|\?\?/,bl=bG.now();bG.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=bp.pop()||(bG.expando+"_"+(bl++));this[e]=true;return e}});bG.ajaxPrefilter("json jsonp",function(b8,b3,b7){var b6,e,b5,b1=b8.data,bZ=b8.url,b0=b8.jsonp!==false,b4=b0&&a5.test(bZ),b2=b0&&!b4&&typeof b1==="string"&&!(b8.contentType||"").indexOf("application/x-www-form-urlencoded")&&a5.test(b1);if(b8.dataTypes[0]==="jsonp"||b4||b2){b6=b8.jsonpCallback=bG.isFunction(b8.jsonpCallback)?b8.jsonpCallback():b8.jsonpCallback;e=a2[b6];if(b4){b8.url=bZ.replace(a5,"$1"+b6)}else{if(b2){b8.data=b1.replace(a5,"$1"+b6)}else{if(b0){b8.url+=(aw.test(bZ)?"&":"?")+b8.jsonp+"="+b6}}}b8.converters["script json"]=function(){if(!b5){bG.error(b6+" was not called")}return b5[0]};b8.dataTypes[0]="json";a2[b6]=function(){b5=arguments};b7.always(function(){a2[b6]=e;if(b8[b6]){b8.jsonpCallback=b3.jsonpCallback;bp.push(b6)}if(b5&&bG.isFunction(e)){e(b5[0])}b5=e=aB});return"script"}});bG.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){bG.globalEval(e);return e}}});bG.ajaxPrefilter("script",function(e){if(e.cache===aB){e.cache=false}if(e.crossDomain){e.type="GET";e.global=false}});bG.ajaxTransport("script",function(b0){if(b0.crossDomain){var e,bZ=o.head||o.getElementsByTagName("head")[0]||o.documentElement;return{send:function(b1,b2){e=o.createElement("script");e.async="async";if(b0.scriptCharset){e.charset=b0.scriptCharset}e.src=b0.url;e.onload=e.onreadystatechange=function(b4,b3){if(b3||!e.readyState||/loaded|complete/.test(e.readyState)){e.onload=e.onreadystatechange=null;if(bZ&&e.parentNode){bZ.removeChild(e)}e=aB;if(!b3){b2(200,"success")}}};bZ.insertBefore(e,bZ.firstChild)},abort:function(){if(e){e.onload(0,1)}}}}});var ah,aN=a2.ActiveXObject?function(){for(var e in ah){ah[e](0,1)}}:false,au=0;function bB(){try{return new a2.XMLHttpRequest()}catch(bZ){}}function bb(){try{return new a2.ActiveXObject("Microsoft.XMLHTTP")}catch(bZ){}}bG.ajaxSettings.xhr=a2.ActiveXObject?function(){return !this.isLocal&&bB()||bb()}:bB;(function(e){bG.extend(bG.support,{ajax:!!e,cors:!!e&&("withCredentials" in e)})})(bG.ajaxSettings.xhr());if(bG.support.ajax){bG.ajaxTransport(function(e){if(!e.crossDomain||bG.support.cors){var bZ;return{send:function(b5,b0){var b3,b2,b4=e.xhr();if(e.username){b4.open(e.type,e.url,e.async,e.username,e.password)}else{b4.open(e.type,e.url,e.async)}if(e.xhrFields){for(b2 in e.xhrFields){b4[b2]=e.xhrFields[b2]}}if(e.mimeType&&b4.overrideMimeType){b4.overrideMimeType(e.mimeType)}if(!e.crossDomain&&!b5["X-Requested-With"]){b5["X-Requested-With"]="XMLHttpRequest"}try{for(b2 in b5){b4.setRequestHeader(b2,b5[b2])}}catch(b1){}b4.send((e.hasContent&&e.data)||null);bZ=function(ce,b8){var b9,b7,b6,cc,cb;try{if(bZ&&(b8||b4.readyState===4)){bZ=aB;if(b3){b4.onreadystatechange=bG.noop;if(aN){delete ah[b3]}}if(b8){if(b4.readyState!==4){b4.abort()}}else{b9=b4.status;b6=b4.getAllResponseHeaders();cc={};cb=b4.responseXML;if(cb&&cb.documentElement){cc.xml=cb}try{cc.text=b4.responseText}catch(cd){}try{b7=b4.statusText}catch(cd){b7=""}if(!b9&&e.isLocal&&!e.crossDomain){b9=cc.text?200:404}else{if(b9===1223){b9=204}}}}}catch(ca){if(!b8){b0(-1,ca)}}if(cc){b0(b9,b7,cc,b6)}};if(!e.async){bZ()}else{if(b4.readyState===4){setTimeout(bZ,0)}else{b3=++au;if(aN){if(!ah){ah={};bG(a2).unload(aN)}ah[b3]=bZ}b4.onreadystatechange=bZ}}},abort:function(){if(bZ){bZ(0,1)}}}}})}var L,ab,bO=/^(?:toggle|show|hide)$/,bH=new RegExp("^(?:([-+])=|)("+bx+")([a-z%]*)$","i"),bM=/queueHooks$/,ax=[i],a1={"*":[function(e,b5){var b1,b6,b7=this.createTween(e,b5),b2=bH.exec(b5),b3=b7.cur(),bZ=+b3||0,b0=1,b4=20;if(b2){b1=+b2[2];b6=b2[3]||(bG.cssNumber[e]?"":"px");if(b6!=="px"&&bZ){bZ=bG.css(b7.elem,e,true)||b1||1;do{b0=b0||".5";bZ=bZ/b0;bG.style(b7.elem,e,bZ+b6)}while(b0!==(b0=b7.cur()/b3)&&b0!==1&&--b4)}b7.unit=b6;b7.start=bZ;b7.end=b2[1]?bZ+(b2[1]+1)*b1:b1}return b7}]};function bj(){setTimeout(function(){L=aB},0);return(L=bG.now())}function bc(bZ,e){bG.each(e,function(b4,b2){var b3=(a1[b4]||[]).concat(a1["*"]),b0=0,b1=b3.length;for(;b0-1,b7={},b6={},b0,b2;if(b9){b6=b3.position();b0=b6.top;b2=b6.left}else{b0=parseFloat(e)||0;b2=parseFloat(b8)||0}if(bG.isFunction(ca)){ca=ca.call(b1,b4,bZ)}if(ca.top!=null){b7.top=(ca.top-bZ.top)+b0}if(ca.left!=null){b7.left=(ca.left-bZ.left)+b2}if("using" in ca){ca.using.call(b1,b7)}else{b3.css(b7)}}};bG.fn.extend({position:function(){if(!this[0]){return}var b0=this[0],bZ=this.offsetParent(),b1=this.offset(),e=bm.test(bZ[0].nodeName)?{top:0,left:0}:bZ.offset();b1.top-=parseFloat(bG.css(b0,"marginTop"))||0;b1.left-=parseFloat(bG.css(b0,"marginLeft"))||0;e.top+=parseFloat(bG.css(bZ[0],"borderTopWidth"))||0;e.left+=parseFloat(bG.css(bZ[0],"borderLeftWidth"))||0;return{top:b1.top-e.top,left:b1.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.body;while(e&&(!bm.test(e.nodeName)&&bG.css(e,"position")==="static")){e=e.offsetParent}return e||o.body})}});bG.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b0,bZ){var e=/Y/.test(bZ);bG.fn[b0]=function(b1){return bG.access(this,function(b2,b5,b4){var b3=bn(b2);if(b4===aB){return b3?(bZ in b3)?b3[bZ]:b3.document.documentElement[b5]:b2[b5]}if(b3){b3.scrollTo(!e?b4:bG(b3).scrollLeft(),e?b4:bG(b3).scrollTop())}else{b2[b5]=b4}},b0,b1,arguments.length,null)}});function bn(e){return bG.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}bG.each({Height:"height",Width:"width"},function(e,bZ){bG.each({padding:"inner"+e,content:bZ,"":"outer"+e},function(b0,b1){bG.fn[b1]=function(b5,b4){var b3=arguments.length&&(b0||typeof b5!=="boolean"),b2=b0||(b5===true||b4===true?"margin":"border");return bG.access(this,function(b7,b6,b8){var b9;if(bG.isWindow(b7)){return b7.document.documentElement["client"+e]}if(b7.nodeType===9){b9=b7.documentElement;return Math.max(b7.body["scroll"+e],b9["scroll"+e],b7.body["offset"+e],b9["offset"+e],b9["client"+e])}return b8===aB?bG.css(b7,b6,b8,b2):bG.style(b7,b6,b8,b2)},bZ,b3?b5:aB,b3,null)}})});a2.jQuery=a2.$=bG;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return bG})}})(window); \ No newline at end of file diff --git a/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js b/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js new file mode 100644 index 000000000..a2f24a062 --- /dev/null +++ b/phpmyadmin/js/jquery/jquery-ui-1.9.2.custom.js @@ -0,0 +1,16 @@ +/*! jQuery UI - v1.9.2 - 2012-12-19 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ +(function(b,f){var a=0,e=/^ui-id-\d+$/;b.ui=b.ui||{};if(b.ui.version){return}b.extend(b.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}});b.fn.extend({_focus:b.fn.focus,focus:function(g,h){return typeof g==="number"?this.each(function(){var i=this;setTimeout(function(){b(i).focus();if(h){h.call(i)}},g)}):this._focus.apply(this,arguments)},scrollParent:function(){var g;if((b.ui.ie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){g=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(b.css(this,"position"))&&(/(auto|scroll)/).test(b.css(this,"overflow")+b.css(this,"overflow-y")+b.css(this,"overflow-x"))}).eq(0)}else{g=this.parents().filter(function(){return(/(auto|scroll)/).test(b.css(this,"overflow")+b.css(this,"overflow-y")+b.css(this,"overflow-x"))}).eq(0)}return(/fixed/).test(this.css("position"))||!g.length?b(document):g},zIndex:function(j){if(j!==f){return this.css("zIndex",j)}if(this.length){var h=b(this[0]),g,i;while(h.length&&h[0]!==document){g=h.css("position");if(g==="absolute"||g==="relative"||g==="fixed"){i=parseInt(h.css("zIndex"),10);if(!isNaN(i)&&i!==0){return i}}h=h.parent()}}return 0},uniqueId:function(){return this.each(function(){if(!this.id){this.id="ui-id-"+(++a)}})},removeUniqueId:function(){return this.each(function(){if(e.test(this.id)){b(this).removeAttr("id")}})}});function d(i,g){var k,j,h,l=i.nodeName.toLowerCase();if("area"===l){k=i.parentNode;j=k.name;if(!i.href||!j||k.nodeName.toLowerCase()!=="map"){return false}h=b("img[usemap=#"+j+"]")[0];return !!h&&c(h)}return(/input|select|textarea|button|object/.test(l)?!i.disabled:"a"===l?i.href||g:g)&&c(i)}function c(g){return b.expr.filters.visible(g)&&!b(g).parents().andSelf().filter(function(){return b.css(this,"visibility")==="hidden"}).length}b.extend(b.expr[":"],{data:b.expr.createPseudo?b.expr.createPseudo(function(g){return function(h){return !!b.data(h,g)}}):function(j,h,g){return !!b.data(j,g[3])},focusable:function(g){return d(g,!isNaN(b.attr(g,"tabindex")))},tabbable:function(i){var g=b.attr(i,"tabindex"),h=isNaN(g);return(h||g>=0)&&d(i,!h)}});b(function(){var g=document.body,h=g.appendChild(h=document.createElement("div"));h.offsetHeight;b.extend(h.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});b.support.minHeight=h.offsetHeight===100;b.support.selectstart="onselectstart" in h;g.removeChild(h).style.display="none"});if(!b("").outerWidth(1).jquery){b.each(["Width","Height"],function(j,g){var h=g==="Width"?["Left","Right"]:["Top","Bottom"],k=g.toLowerCase(),m={innerWidth:b.fn.innerWidth,innerHeight:b.fn.innerHeight,outerWidth:b.fn.outerWidth,outerHeight:b.fn.outerHeight};function l(o,n,i,p){b.each(h,function(){n-=parseFloat(b.css(o,"padding"+this))||0;if(i){n-=parseFloat(b.css(o,"border"+this+"Width"))||0}if(p){n-=parseFloat(b.css(o,"margin"+this))||0}});return n}b.fn["inner"+g]=function(i){if(i===f){return m["inner"+g].call(this)}return this.each(function(){b(this).css(k,l(this,i)+"px")})};b.fn["outer"+g]=function(i,n){if(typeof i!=="number"){return m["outer"+g].call(this,i)}return this.each(function(){b(this).css(k,l(this,i,true,n)+"px")})}})}if(b("").data("a-b","a").removeData("a-b").data("a-b")){b.fn.removeData=(function(g){return function(h){if(arguments.length){return g.call(this,b.camelCase(h))}else{return g.call(this)}}})(b.fn.removeData)}(function(){var g=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];b.ui.ie=g.length?true:false;b.ui.ie6=parseFloat(g[1],10)===6})();b.fn.extend({disableSelection:function(){return this.bind((b.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(g){g.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});b.extend(b.ui,{plugin:{add:function(h,j,l){var g,k=b.ui[h].prototype;for(g in l){k.plugins[g]=k.plugins[g]||[];k.plugins[g].push([j,l[g]])}},call:function(g,j,h){var k,l=g.plugins[j];if(!l||!g.element[0].parentNode||g.element[0].parentNode.nodeType===11){return}for(k=0;k0){return true}j[g]=1;i=(j[g]>0);j[g]=0;return i},isOverAxis:function(h,g,i){return(h>g)&&(h<(g+i))},isOver:function(l,h,k,j,g,i){return b.ui.isOverAxis(l,k,g)&&b.ui.isOverAxis(h,j,i)}})})(jQuery);(function(b,e){var a=0,d=Array.prototype.slice,c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)};b.widget=function(g,j,f){var m,l,i,k,h=g.split(".")[0];g=g.split(".")[1];m=h+"-"+g;if(!f){f=j;j=b.Widget}b.expr[":"][m.toLowerCase()]=function(n){return !!b.data(n,m)};b[h]=b[h]||{};l=b[h][g];i=b[h][g]=function(n,o){if(!this._createWidget){return new i(n,o)}if(arguments.length){this._createWidget(n,o)}};b.extend(i,l,{version:f.version,_proto:b.extend({},f),_childConstructors:[]});k=new j();k.options=b.widget.extend({},k.options);b.each(f,function(o,n){if(b.isFunction(n)){f[o]=(function(){var p=function(){return j.prototype[o].apply(this,arguments)},q=function(r){return j.prototype[o].apply(this,r)};return function(){var t=this._super,r=this._superApply,s;this._super=p;this._superApply=q;s=n.apply(this,arguments);this._super=t;this._superApply=r;return s}})()}});i.prototype=b.widget.extend(k,{widgetEventPrefix:l?k.widgetEventPrefix:g},f,{constructor:i,namespace:h,widgetName:g,widgetBaseClass:m,widgetFullName:m});if(l){b.each(l._childConstructors,function(o,p){var n=p.prototype;b.widget(n.namespace+"."+n.widgetName,i,p._proto)});delete l._childConstructors}else{j._childConstructors.push(i)}b.widget.bridge(g,i)};b.widget.extend=function(k){var g=d.call(arguments,1),j=0,f=g.length,h,i;for(;j",options:{disabled:false,create:null},_createWidget:function(f,g){g=b(g||this.defaultElement||this)[0];this.element=b(g);this.uuid=a++;this.eventNamespace="."+this.widgetName+this.uuid;this.options=b.widget.extend({},this.options,this._getCreateOptions(),f);this.bindings=b();this.hoverable=b();this.focusable=b();if(g!==this){b.data(g,this.widgetName,this);b.data(g,this.widgetFullName,this);this._on(true,this.element,{remove:function(h){if(h.target===g){this.destroy()}}});this.document=b(g.style?g.ownerDocument:g.document||g);this.window=b(this.document[0].defaultView||this.document[0].parentWindow)}this._create();this._trigger("create",null,this._getCreateEventData());this._init()},_getCreateOptions:b.noop,_getCreateEventData:b.noop,_create:b.noop,_init:b.noop,destroy:function(){this._destroy();this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(b.camelCase(this.widgetFullName));this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled");this.bindings.unbind(this.eventNamespace);this.hoverable.removeClass("ui-state-hover");this.focusable.removeClass("ui-state-focus")},_destroy:b.noop,widget:function(){return this.element},option:function(j,k){var f=j,l,h,g;if(arguments.length===0){return b.widget.extend({},this.options)}if(typeof j==="string"){f={};l=j.split(".");j=l.shift();if(l.length){h=f[j]=b.widget.extend({},this.options[j]);for(g=0;g=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target===this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(e,c){e.ui=e.ui||{};var i,j=Math.max,n=Math.abs,l=Math.round,d=/left|center|right/,g=/top|center|bottom/,a=/[\+\-]\d+%?/,k=/^\w+/,b=/%$/,f=e.fn.position;function m(q,p,o){return[parseInt(q[0],10)*(b.test(q[0])?p/100:1),parseInt(q[1],10)*(b.test(q[1])?o/100:1)]}function h(o,p){return parseInt(e.css(o,p),10)||0}e.position={scrollbarWidth:function(){if(i!==c){return i}var p,o,r=e("
      "),q=r.children()[0];e("body").append(r);p=q.offsetWidth;r.css("overflow","scroll");o=q.offsetWidth;if(p===o){o=r[0].clientWidth}r.remove();return(i=p-o)},getScrollInfo:function(s){var r=s.isWindow?"":s.element.css("overflow-x"),q=s.isWindow?"":s.element.css("overflow-y"),p=r==="scroll"||(r==="auto"&&s.width0?"right":"center",vertical:M<0?"top":P>0?"bottom":"middle"};if(vj(n(P),n(M))){L.important="horizontal"}else{L.important="vertical"}y.using.call(this,O,L)}}D.offset(e.extend(G,{using:K}))})};e.ui.position={fit:{left:function(s,r){var q=r.within,u=q.isWindow?q.scrollLeft:q.offset.left,w=q.width,t=s.left-r.collisionPosition.marginLeft,v=u-t,p=t+r.collisionWidth-w-u,o;if(r.collisionWidth>w){if(v>0&&p<=0){o=s.left+v+r.collisionWidth-w-u;s.left+=v-o}else{if(p>0&&v<=0){s.left=u}else{if(v>p){s.left=u+w-r.collisionWidth}else{s.left=u}}}}else{if(v>0){s.left+=v}else{if(p>0){s.left-=p}else{s.left=j(s.left-t,s.left)}}}},top:function(r,q){var p=q.within,v=p.isWindow?p.scrollTop:p.offset.top,w=q.within.height,t=r.top-q.collisionPosition.marginTop,u=v-t,s=t+q.collisionHeight-w-v,o;if(q.collisionHeight>w){if(u>0&&s<=0){o=r.top+u+q.collisionHeight-w-v;r.top+=u-o}else{if(s>0&&u<=0){r.top=v}else{if(u>s){r.top=v+w-q.collisionHeight}else{r.top=v}}}}else{if(u>0){r.top+=u}else{if(s>0){r.top-=s}else{r.top=j(r.top-t,r.top)}}}}},flip:{left:function(u,t){var s=t.within,y=s.offset.left+s.scrollLeft,B=s.width,q=s.isWindow?s.scrollLeft:s.offset.left,v=u.left-t.collisionPosition.marginLeft,z=v-q,p=v+t.collisionWidth-B-q,x=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,A=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,r=-2*t.offset[0],o,w;if(z<0){o=u.left+x+A+r+t.collisionWidth-B-y;if(o<0||o0){w=u.left-t.collisionPosition.marginLeft+x+A+r-q;if(w>0||n(w)x&&(p<0||p0){z=t.top-s.collisionPosition.marginTop+w+C+q-o;if((t.top+w+C+q)>u&&(z>0||n(z)10&&r<11;s.innerHTML="";u.removeChild(s)})();if(e.uiBackCompat!==false){(function(p){var o=p.fn.position;p.fn.position=function(r){if(!r||!r.offset){return o.call(this,r)}var s=r.offset.split(" "),q=r.at.split(" ");if(s.length===1){s[1]=s[0]}if(/^\d/.test(s[0])){s[0]="+"+s[0]}if(/^\d/.test(s[1])){s[1]="+"+s[1]}if(q.length===1){if(/left|center|right/.test(q[0])){q[1]="center"}else{q[1]=q[0];q[0]="center"}}return o.call(this,p.extend(r,{at:q[0]+s[0]+" "+q[1]+s[1],offset:c}))}}(jQuery))}}(jQuery));(function(a,b){a.widget("ui.draggable",a.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(c){var d=this.options;if(this.helper||d.disabled||a(c.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(c);if(!this.handle){return false}a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('
      ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")});return true},_mouseStart:function(c){var d=this.options;this.helper=this._createHelper(c);this.helper.addClass("ui-draggable-dragging");this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:c.pageX-this.offset.left,top:c.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(c);this.originalPageX=c.pageX;this.originalPageY=c.pageY;(d.cursorAt&&this._adjustOffsetFromHelper(d.cursorAt));if(d.containment){this._setContainment()}if(this._trigger("start",c)===false){this._clear();return false}this._cacheHelperProportions();if(a.ui.ddmanager&&!d.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,c)}this._mouseDrag(c,true);if(a.ui.ddmanager){a.ui.ddmanager.dragStart(this,c)}return true},_mouseDrag:function(c,e){this.position=this._generatePosition(c);this.positionAbs=this._convertPositionTo("absolute");if(!e){var d=this._uiHash();if(this._trigger("drag",c,d)===false){this._mouseUp({});return false}this.position=d.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,c)}return false},_mouseStop:function(e){var g=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){g=a.ui.ddmanager.drop(this,e)}if(this.dropped){g=this.dropped;this.dropped=false}var c=this.element[0],f=false;while(c&&(c=c.parentNode)){if(c==document){f=true}}if(!f&&this.options.helper==="original"){return false}if((this.options.revert=="invalid"&&!g)||(this.options.revert=="valid"&&g)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,g))){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){if(d._trigger("stop",e)!==false){d._clear()}})}else{if(this._trigger("stop",e)!==false){this._clear()}}return false},_mouseUp:function(c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});if(a.ui.ddmanager){a.ui.ddmanager.dragStop(this,c)}return a.ui.mouse.prototype._mouseUp.call(this,c)},cancel:function(){if(this.helper.is(".ui-draggable-dragging")){this._mouseUp({})}else{this._clear()}return this},_getHandle:function(c){var d=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==c.target){d=true}});return d},_createHelper:function(d){var e=this.options;var c=a.isFunction(e.helper)?a(e.helper.apply(this.element[0],[d])):(e.helper=="clone"?this.element.clone().removeAttr("id"):this.element);if(!c.parents("body").length){c.appendTo((e.appendTo=="parent"?this.element[0].parentNode:e.appendTo))}if(c[0]!=this.element[0]&&!(/(fixed|absolute)/).test(c.css("position"))){c.css("position","absolute")}return c},_adjustOffsetFromHelper:function(c){if(typeof c=="string"){c=c.split(" ")}if(a.isArray(c)){c={left:+c[0],top:+c[1]||0}}if("left" in c){this.offset.click.left=c.left+this.margins.left}if("right" in c){this.offset.click.left=this.helperProportions.width-c.right+this.margins.left}if("top" in c){this.offset.click.top=c.top+this.margins.top}if("bottom" in c){this.offset.click.top=this.helperProportions.height-c.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var c=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0])){c.left+=this.scrollParent.scrollLeft();c.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.ui.ie)){c={top:0,left:0}}return{top:c.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:c.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var c=this.element.position();return{top:c.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:c.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0),right:(parseInt(this.element.css("marginRight"),10)||0),bottom:(parseInt(this.element.css("marginBottom"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var g=this.options;if(g.containment=="parent"){g.containment=this.helper[0].parentNode}if(g.containment=="document"||g.containment=="window"){this.containment=[g.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,g.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(g.containment=="document"?0:a(window).scrollLeft())+a(g.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(g.containment=="document"?0:a(window).scrollTop())+(a(g.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(g.containment)&&g.containment.constructor!=Array){var h=a(g.containment);var e=h[0];if(!e){return}var f=h.offset();var d=(a(e).css("overflow")!="hidden");this.containment=[(parseInt(a(e).css("borderLeftWidth"),10)||0)+(parseInt(a(e).css("paddingLeft"),10)||0),(parseInt(a(e).css("borderTopWidth"),10)||0)+(parseInt(a(e).css("paddingTop"),10)||0),(d?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(a(e).css("borderLeftWidth"),10)||0)-(parseInt(a(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(d?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(a(e).css("borderTopWidth"),10)||0)-(parseInt(a(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=h}else{if(g.containment.constructor==Array){this.containment=g.containment}}},_convertPositionTo:function(g,i){if(!i){i=this.position}var e=g=="absolute"?1:-1;var f=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=(/(html|body)/i).test(c[0].tagName);return{top:(i.top+this.offset.relative.top*e+this.offset.parent.top*e-((this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(h?0:c.scrollTop()))*e)),left:(i.left+this.offset.relative.left*e+this.offset.parent.left*e-((this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:c.scrollLeft())*e))}},_generatePosition:function(d){var e=this.options,l=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(l[0].tagName);var h=d.pageX;var g=d.pageY;if(this.originalPosition){var c;if(this.containment){if(this.relative_container){var k=this.relative_container.offset();c=[this.containment[0]+k.left,this.containment[1]+k.top,this.containment[2]+k.left,this.containment[3]+k.top]}else{c=this.containment}if(d.pageX-this.offset.click.leftc[2]){h=c[2]+this.offset.click.left}if(d.pageY-this.offset.click.top>c[3]){g=c[3]+this.offset.click.top}}if(e.grid){var j=e.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/e.grid[1])*e.grid[1]:this.originalPageY;g=c?(!(j-this.offset.click.topc[3])?j:(!(j-this.offset.click.topc[2])?f:(!(f-this.offset.click.left=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y=p&&n<=k)||(m>=p&&m<=k)||(nk))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(ec));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(f,h){var c=a.ui.ddmanager.droppables[f.options.scope]||[];var g=h?h.type:null;var k=(f.currentItem||f.element).find(":data(droppable)").andSelf();droppablesLoop:for(var e=0;e
      ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var f=0;f');g.css({zIndex:k.zIndex});if("se"==j){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(g)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!h.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}h.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");h._handles.show()}).mouseleave(function(){if(k.disabled){return}if(!h.resizing){c(this).addClass("ui-resizable-autohide");h._handles.hide()}})}this._mouseInit()},_destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")}).insertAfter(f);f.remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var g=this.helper,f=this.options,l={},k=this,i=this.originalMousePosition,m=this.axis;var p=(e.pageX-i.left)||0,n=(e.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var j=h.apply(this,[e,p,n]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){j=this._updateRatio(j,e)}j=this._respectSize(j,e);this._propagate("resize",e);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(j);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,l=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:l.sizeDiff.height,k=e?0:l.sizeDiff.width;var n={width:(l.helper.width()-k),height:(l.helper.height()-f)},j=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,m=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:m,left:j}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var f=(c.ui.ie6?1:0),g=(c.ui.ie6?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,p){var m=c(this).data("resizable"),j=m.options;var h=m._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:m.sizeDiff.height,l=e?0:m.sizeDiff.width;var g={width:(m.size.width-l),height:(m.size.height-f)},k=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,n=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;m.element.animate(c.extend(g,n&&k?{top:n,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(m.element.css("width"),10),height:parseInt(m.element.css("height"),10),top:parseInt(m.element.css("top"),10),left:parseInt(m.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}m._updateCache(o);m._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,s){var q=c(this).data("resizable"),j=q.options,l=q.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}q.containerElement=c(k);if(/document/.test(g)||g==document){q.containerOffset={left:0,top:0};q.containerPosition={left:0,top:0};q.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});q.containerOffset=n.offset();q.containerPosition=n.position();q.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var r=q.containerOffset,e=q.containerSize.height,m=q.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),t=(c.ui.hasScroll(k)?k.scrollHeight:e);q.parentData={element:k,left:r.left,top:r.top,width:h,height:t}}},resize:function(g,r){var m=c(this).data("resizable"),i=m.options,f=m.containerSize,q=m.containerOffset,n=m.size,p=m.position,s=m._aspectRatio||g.shiftKey,e={top:0,left:0},h=m.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=q}if(p.left<(m._helper?q.left:0)){m.size.width=m.size.width+(m._helper?(m.position.left-q.left):(m.position.left-e.left));if(s){m.size.height=m.size.width/m.aspectRatio}m.position.left=i.helper?q.left:0}if(p.top<(m._helper?q.top:0)){m.size.height=m.size.height+(m._helper?(m.position.top-q.top):m.position.top);if(s){m.size.width=m.size.height*m.aspectRatio}m.position.top=m._helper?q.top:0}m.offset.left=m.parentData.left+m.position.left;m.offset.top=m.parentData.top+m.position.top;var l=Math.abs((m._helper?m.offset.left-e.left:(m.offset.left-e.left))+m.sizeDiff.width),t=Math.abs((m._helper?m.offset.top-e.top:(m.offset.top-q.top))+m.sizeDiff.height);var k=m.containerElement.get(0)==m.element.parent().get(0),j=/relative|absolute/.test(m.containerElement.css("position"));if(k&&j){l-=m.parentData.left}if(l+m.size.width>=m.parentData.width){m.size.width=m.parentData.width-l;if(s){m.size.height=m.size.width/m.aspectRatio}}if(t+m.size.height>=m.parentData.height){m.size.height=m.parentData.height-t;if(s){m.size.width=m.size.height*m.aspectRatio}}},stop:function(f,p){var l=c(this).data("resizable"),g=l.options,m=l.position,n=l.containerOffset,e=l.containerPosition,i=l.containerElement;var j=c(l.helper),r=j.offset(),q=j.outerWidth()-l.sizeDiff.width,k=j.outerHeight()-l.sizeDiff.height;if(l._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-n.left,width:q,height:k})}if(l._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-n.left,width:q,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var f=c(this).data("resizable"),i=f.options,e=f.size;f.ghost=f.originalElement.clone();f.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");f.ghost.appendTo(f.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,n){var k=c(this).data("resizable"),h=k.options,l=k.size,i=k.originalSize,j=k.originalPosition,p=k.axis,m=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((l.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((l.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(p)){k.size.width=i.width+g;k.size.height=i.height+f}else{if(/^(ne)$/.test(p)){k.size.width=i.width+g;k.size.height=i.height+f;k.position.top=j.top-f}else{if(/^(sw)$/.test(p)){k.size.width=i.width+g;k.size.height=i.height+f;k.position.left=j.left-g}else{k.size.width=i.width+g;k.size.height=i.height+f;k.position.top=j.top-f;k.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);(function(a,b){a.widget("ui.selectable",a.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var d;this.refresh=function(){d=a(c.options.filter,c.element[0]);d.addClass("ui-selectee");d.each(function(){var e=a(this);var f=e.offset();a.data(this,"selectable-item",{element:this,$element:e,left:f.left,top:f.top,right:f.left+e.outerWidth(),bottom:f.top+e.outerHeight(),startselected:false,selected:e.hasClass("ui-selected"),selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})};this.refresh();this.selectees=d.addClass("ui-selectee");this._mouseInit();this.helper=a("
      ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled");this._mouseDestroy()},_mouseStart:function(e){var d=this;this.opos=[e.pageX,e.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",e);a(c.appendTo).append(this.helper);this.helper.css({left:e.clientX,top:e.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var f=a.data(this,"selectable-item");f.startselected=true;if(!e.metaKey&&!e.ctrlKey){f.$element.removeClass("ui-selected");f.selected=false;f.$element.addClass("ui-unselecting");f.unselecting=true;d._trigger("unselecting",e,{unselecting:f.element})}});a(e.target).parents().andSelf().each(function(){var g=a.data(this,"selectable-item");if(g){var f=(!e.metaKey&&!e.ctrlKey)||!g.$element.hasClass("ui-selected");g.$element.removeClass(f?"ui-unselecting":"ui-selected").addClass(f?"ui-selecting":"ui-unselecting");g.unselecting=!f;g.selecting=f;g.selected=f;if(f){d._trigger("selecting",e,{selecting:g.element})}else{d._trigger("unselecting",e,{unselecting:g.element})}return false}})},_mouseDrag:function(j){var i=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],c=j.pageX,g=j.pageY;if(d>c){var f=c;c=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:c-d,height:g-h});this.selectees.each(function(){var k=a.data(this,"selectable-item");if(!k||k.element==i.element[0]){return}var l=false;if(e.tolerance=="touch"){l=(!(k.left>c||k.rightg||k.bottomd&&k.righth&&k.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000},_create:function(){var c=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?c.axis==="x"||(/left|right/).test(this.items[0].item.css("float"))||(/inline|table-cell/).test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit();this.ready=true},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled");this._mouseDestroy();for(var c=this.items.length-1;c>=0;c--){this.items[c].item.removeData(this.widgetName+"-item")}return this},_setOption:function(c,d){if(c==="disabled"){this.options[c]=d;this.widget().toggleClass("ui-sortable-disabled",!!d)}else{a.Widget.prototype._setOption.apply(this,arguments)}},_mouseCapture:function(f,g){var e=this;if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(f);var d=null,c=a(f.target).parents().each(function(){if(a.data(this,e.widgetName+"-item")==e){d=a(this);return false}});if(a.data(f.target,e.widgetName+"-item")==e){d=a(f.target)}if(!d){return false}if(this.options.handle&&!g){var h=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==f.target){h=true}});if(!h){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,c){var g=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;(g.cursorAt&&this._adjustOffsetFromHelper(g.cursorAt));this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!c){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,this._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(g){this.position=this._generatePosition(g);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var h=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-g.pageY=0;e--){var f=this.items[e],d=f.item[0],j=this._intersectsWithPointer(f);if(!j){continue}if(f.instance!==this.currentContainer){continue}if(d!=this.currentItem[0]&&this.placeholder[j==1?"next":"prev"]()[0]!=d&&!a.contains(this.placeholder[0],d)&&(this.options.type=="semi-dynamic"?!a.contains(this.element[0],d):true)){this.direction=j==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f)){this._rearrange(g,f)}else{break}this._trigger("change",g,this._uiHash());break}}this._contactContainers(g);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,g)}this._trigger("sort",g,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(d,e){if(!d){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,d)}if(this.options.revert){var c=this;var f=this.placeholder.offset();this.reverting=true;a(this.helper).animate({left:f.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:f.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(d)})}else{this._clear(d,e)}return false},cancel:function(){if(this.dragging){this._mouseUp({target:null});if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,this._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,this._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder){if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}}return this},serialize:function(e){var c=this._getItemsAsjQuery(e&&e.connected);var d=[];e=e||{};a(c).each(function(){var f=(a(e.item||this).attr(e.attribute||"id")||"").match(e.expression||(/(.+)[-=_](.+)/));if(f){d.push((e.key||f[1]+"[]")+"="+(e.key&&e.expression?f[1]:f[2]))}});if(!d.length&&e.key){d.push(e.key+"=")}return d.join("&")},toArray:function(e){var c=this._getItemsAsjQuery(e&&e.connected);var d=[];e=e||{};c.each(function(){d.push(a(e.item||this).attr(e.attribute||"id")||"")});return d},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)f&&(e+h)m[this.floating?"width":"height"])){return g}else{return(f0?"down":"up")},_getDragHorizontalDirection:function(){var c=this.positionAbs.left-this.lastPositionAbs.left;return c!=0&&(c>0?"right":"left")},refresh:function(c){this._refreshItems(c);this.refreshPositions();return this},_connectWith:function(){var c=this.options;return c.connectWith.constructor==String?[c.connectWith]:c.connectWith},_getItemsAsjQuery:function(h){var c=[];var e=[];var g=this._connectWith();if(g&&h){for(var f=g.length-1;f>=0;f--){var l=a(g[f]);for(var d=l.length-1;d>=0;d--){var k=a.data(l[d],this.widgetName);if(k&&k!=this&&!k.options.disabled){e.push([a.isFunction(k.options.items)?k.options.items.call(k.element):a(k.options.items,k.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),k])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var f=e.length-1;f>=0;f--){e[f][0].each(function(){c.push(this)})}return a(c)},_removeCurrentsFromItems:function(){var c=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=a.grep(this.items,function(e){for(var d=0;d=0;f--){var n=a(m[f]);for(var e=n.length-1;e>=0;e--){var h=a.data(n[e],this.widgetName);if(h&&h!=this&&!h.options.disabled){g.push([a.isFunction(h.options.items)?h.options.items.call(h.element[0],c,{item:this.currentItem}):a(h.options.items,h.element),h]);this.containers.push(h)}}}}for(var f=g.length-1;f>=0;f--){var l=g[f][1];var d=g[f][0];for(var e=0,o=d.length;e=0;e--){var f=this.items[e];if(f.instance!=this.currentContainer&&this.currentContainer&&f.item[0]!=this.currentItem[0]){continue}var d=this.options.toleranceElement?a(this.options.toleranceElement,f.item):f.item;if(!c){f.width=d.outerWidth();f.height=d.outerHeight()}var g=d.offset();f.left=g.left;f.top=g.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var e=this.containers.length-1;e>=0;e--){var g=this.containers[e].element.offset();this.containers[e].containerCache.left=g.left;this.containers[e].containerCache.top=g.top;this.containers[e].containerCache.width=this.containers[e].element.outerWidth();this.containers[e].containerCache.height=this.containers[e].element.outerHeight()}}return this},_createPlaceholder:function(d){d=d||this;var e=d.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(d.currentItem[0].nodeName)).addClass(c||d.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(d.currentItem.innerHeight()-parseInt(d.currentItem.css("paddingTop")||0,10)-parseInt(d.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(d.currentItem.innerWidth()-parseInt(d.currentItem.css("paddingLeft")||0,10)-parseInt(d.currentItem.css("paddingRight")||0,10))}}}}d.placeholder=a(e.placeholder.element.call(d.element,d.currentItem));d.currentItem.after(d.placeholder);e.placeholder.update(d,d.placeholder)},_contactContainers:function(c){var e=null,n=null;for(var h=this.containers.length-1;h>=0;h--){if(a.contains(this.currentItem[0],this.containers[h].element[0])){continue}if(this._intersectsWith(this.containers[h].containerCache)){if(e&&a.contains(this.containers[h].element[0],e.element[0])){continue}e=this.containers[h];n=h}else{if(this.containers[h].containerCache.over){this.containers[h]._trigger("out",c,this._uiHash(this));this.containers[h].containerCache.over=0}}}if(!e){return}if(this.containers.length===1){this.containers[n]._trigger("over",c,this._uiHash(this));this.containers[n].containerCache.over=1}else{var m=10000;var k=null;var l=this.containers[n].floating?"left":"top";var o=this.containers[n].floating?"width":"height";var d=this.positionAbs[l]+this.offset.click[l];for(var f=this.items.length-1;f>=0;f--){if(!a.contains(this.containers[n].element[0],this.items[f].item[0])){continue}if(this.items[f].item[0]==this.currentItem[0]){continue}var p=this.items[f].item.offset()[l];var g=false;if(Math.abs(p-d)>Math.abs(p+this.items[f][o]-d)){g=true;p+=this.items[f][o]}if(Math.abs(p-d)this.containment[2]){e=this.containment[2]+this.offset.click.left}if(f.pageY-this.offset.click.top>this.containment[3]){d=this.containment[3]+this.offset.click.top}}if(i.grid){var h=this.originalPageY+Math.round((d-this.originalPageY)/i.grid[1])*i.grid[1];d=this.containment?(!(h-this.offset.click.topthis.containment[3])?h:(!(h-this.offset.click.topthis.containment[2])?g:(!(g-this.offset.click.left=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var g=this.accordionId="ui-accordion-"+(this.element.attr("id")||++b),f=this.options;this.prevShow=this.prevHide=d();this.element.addClass("ui-accordion ui-widget ui-helper-reset");this.headers=this.element.find(f.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all");this._hoverable(this.headers);this._focusable(this.headers);this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide();if(!f.collapsible&&(f.active===false||f.active==null)){f.active=0}if(f.active<0){f.active+=this.headers.length}this.active=this._findActive(f.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top");this.active.next().addClass("ui-accordion-content-active").show();this._createIcons();this.refresh();this.element.attr("role","tablist");this.headers.attr("role","tab").each(function(l){var m=d(this),k=m.attr("id"),h=m.next(),j=h.attr("id");if(!k){k=g+"-header-"+l;m.attr("id",k)}if(!j){j=g+"-panel-"+l;h.attr("id",j)}m.attr("aria-controls",j);h.attr("aria-labelledby",k)}).next().attr("role","tabpanel");this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide();if(!this.active.length){this.headers.eq(0).attr("tabIndex",0)}else{this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"})}this._on(this.headers,{keydown:"_keydown"});this._on(this.headers.next(),{keydown:"_panelKeyDown"});this._setupEvents(f.event)},_getCreateEventData:function(){return{header:this.active,content:!this.active.length?d():this.active.next()}},_createIcons:function(){var f=this.options.icons;if(f){d("").addClass("ui-accordion-header-icon ui-icon "+f.header).prependTo(this.headers);this.active.children(".ui-accordion-header-icon").removeClass(f.header).addClass(f.activeHeader);this.headers.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var f;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){if(/^ui-accordion/.test(this.id)){this.removeAttribute("id")}});this._destroyIcons();f=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){if(/^ui-accordion/.test(this.id)){this.removeAttribute("id")}});if(this.options.heightStyle!=="content"){f.css("height","")}},_setOption:function(f,g){if(f==="active"){this._activate(g);return}if(f==="event"){if(this.options.event){this._off(this.headers,this.options.event)}this._setupEvents(g)}this._super(f,g);if(f==="collapsible"&&!g&&this.options.active===false){this._activate(0)}if(f==="icons"){this._destroyIcons();if(g){this._createIcons()}}if(f==="disabled"){this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!g)}},_keydown:function(i){if(i.altKey||i.ctrlKey){return}var j=d.ui.keyCode,h=this.headers.length,f=this.headers.index(i.target),g=false;switch(i.keyCode){case j.RIGHT:case j.DOWN:g=this.headers[(f+1)%h];break;case j.LEFT:case j.UP:g=this.headers[(f-1+h)%h];break;case j.SPACE:case j.ENTER:this._eventHandler(i);break;case j.HOME:g=this.headers[0];break;case j.END:g=this.headers[h-1];break}if(g){d(i.target).attr("tabIndex",-1);d(g).attr("tabIndex",0);g.focus();i.preventDefault()}},_panelKeyDown:function(f){if(f.keyCode===d.ui.keyCode.UP&&f.ctrlKey){d(f.currentTarget).prev().focus()}},refresh:function(){var h,i,f=this.options.heightStyle,g=this.element.parent();if(f==="fill"){if(!d.support.minHeight){i=g.css("overflow");g.css("overflow","hidden")}h=g.height();this.element.siblings(":visible").each(function(){var k=d(this),j=k.css("position");if(j==="absolute"||j==="fixed"){return}h-=k.outerHeight(true)});if(i){g.css("overflow",i)}this.headers.each(function(){h-=d(this).outerHeight(true)});this.headers.next().each(function(){d(this).height(Math.max(0,h-d(this).innerHeight()+d(this).height()))}).css("overflow","auto")}else{if(f==="auto"){h=0;this.headers.next().each(function(){h=Math.max(h,d(this).css("height","").height())}).height(h)}}},_activate:function(f){var g=this._findActive(f)[0];if(g===this.active[0]){return}g=g||this.active[0];this._eventHandler({target:g,currentTarget:g,preventDefault:d.noop})},_findActive:function(f){return typeof f==="number"?this.headers.eq(f):d()},_setupEvents:function(g){var f={};if(!g){return}d.each(g.split(" "),function(i,h){f[h]="_eventHandler"});this._on(this.headers,f)},_eventHandler:function(f){var n=this.options,i=this.active,j=d(f.currentTarget),l=j[0]===i[0],g=l&&n.collapsible,h=g?d():j.next(),k=i.next(),m={oldHeader:i,oldPanel:k,newHeader:g?d():j,newPanel:h};f.preventDefault();if((l&&!n.collapsible)||(this._trigger("beforeActivate",f,m)===false)){return}n.active=g?false:this.headers.index(j);this.active=l?d():j;this._toggle(m);i.removeClass("ui-accordion-header-active ui-state-active");if(n.icons){i.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header)}if(!l){j.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top");if(n.icons){j.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader)}j.next().addClass("ui-accordion-content-active")}},_toggle:function(h){var f=h.newPanel,g=this.prevShow.length?this.prevShow:h.oldPanel;this.prevShow.add(this.prevHide).stop(true,true);this.prevShow=f;this.prevHide=g;if(this.options.animate){this._animate(f,g,h)}else{g.hide();f.show();this._toggleComplete(h)}g.attr({"aria-expanded":"false","aria-hidden":"true"});g.prev().attr("aria-selected","false");if(f.length&&g.length){g.prev().attr("tabIndex",-1)}else{if(f.length){this.headers.filter(function(){return d(this).attr("tabIndex")===0}).attr("tabIndex",-1)}}f.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(f,n,j){var m,l,i,k=this,o=0,p=f.length&&(!n.length||(f.index()",options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var e,d,f;this.isMultiLine=this._isMultiLine();this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"];this.isNewMenu=true;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off");this._on(this.element,{keydown:function(g){if(this.element.prop("readOnly")){e=true;f=true;d=true;return}e=false;f=false;d=false;var h=a.ui.keyCode;switch(g.keyCode){case h.PAGE_UP:e=true;this._move("previousPage",g);break;case h.PAGE_DOWN:e=true;this._move("nextPage",g);break;case h.UP:e=true;this._keyEvent("previous",g);break;case h.DOWN:e=true;this._keyEvent("next",g);break;case h.ENTER:case h.NUMPAD_ENTER:if(this.menu.active){e=true;g.preventDefault();this.menu.select(g)}break;case h.TAB:if(this.menu.active){this.menu.select(g)}break;case h.ESCAPE:if(this.menu.element.is(":visible")){this._value(this.term);this.close(g);g.preventDefault()}break;default:d=true;this._searchTimeout(g);break}},keypress:function(g){if(e){e=false;g.preventDefault();return}if(d){return}var h=a.ui.keyCode;switch(g.keyCode){case h.PAGE_UP:this._move("previousPage",g);break;case h.PAGE_DOWN:this._move("nextPage",g);break;case h.UP:this._keyEvent("previous",g);break;case h.DOWN:this._keyEvent("next",g);break}},input:function(g){if(f){f=false;g.preventDefault();return}this._searchTimeout(g)},focus:function(){this.selectedItem=null;this.previous=this._value()},blur:function(g){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching);this.close(g);this._change(g)}});this._initSource();this.menu=a("
      ';var thead=(showWeek?'":"");for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="=5?' class="ui-datepicker-week-end"':"")+'>'+dayNamesMin[day]+""}calender+=thead+"";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var curRows=Math.ceil((leadDays+daysInMonth)/7);var numRows=(isMultiMonth?this.maxRows>curRows?this.maxRows:curRows:curRows);this.maxRows=numRows;var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow";var tbody=(!showWeek?"":'");for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=(otherMonth&&!selectOtherMonths)||!daySettings[0]||(minDate&&printDatemaxDate);tbody+='";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+""}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="
      '+this._get(inst,"weekHeader")+"
      '+this._get(inst,"calculateWeek")(printDate)+""+(otherMonth&&!showOtherMonths?" ":(unselectable?''+printDate.getDate()+"":''+printDate.getDate()+""))+"
      "+(isMultiMonth?"
      "+((numMonths[0]>0&&col==numMonths[1]-1)?'
      ':""):"");group+=calender}html+=group}html+=buttonPanel+($.ui.ie6&&!inst.inline?'':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,secondary,monthNames,monthNamesShort){var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='
      ';var monthHtml="";if(secondary||!changeMonth){monthHtml+=''+monthNames[drawMonth]+""}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='"}if(!showMonthAfterYear){html+=monthHtml+(secondary||!(changeMonth&&changeYear)?" ":"")}if(!inst.yearshtml){inst.yearshtml="";if(secondary||!changeYear){html+=''+drawYear+""}else{var years=this._get(inst,"yearRange").split(":");var thisYear=new Date().getFullYear();var determineYear=function(value){var year=(value.match(/c[+-].*/)?drawYear+parseInt(value.substring(1),10):(value.match(/[+-].*/)?thisYear+parseInt(value,10):parseInt(value,10)));return(isNaN(year)?thisYear:year)};var year=determineYear(years[0]);var endYear=Math.max(year,determineYear(years[1]||""));year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);inst.yearshtml+='";html+=inst.yearshtml;inst.yearshtml=null}}html+=this._get(inst,"yearSuffix");if(showMonthAfterYear){html+=(secondary||!(changeMonth&&changeYear)?" ":"")+monthHtml}html+="
      ";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._restrictMinMax(inst,this._daylightSavingAdjust(new Date(year,month,day)));inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_restrictMinMax:function(inst,date){var minDate=this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");var newDate=(minDate&&datemaxDate?maxDate:newDate);return newDate},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax){return this._determineDate(inst,this._get(inst,minMax+"Date"),null)},_getDaysInMonth:function(year,month){return 32-this._daylightSavingAdjust(new Date(year,month,32)).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[0]*numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var minDate=this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date.getTime()>=minDate.getTime())&&(!maxDate||date.getTime()<=maxDate.getTime()))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function bindHover(dpDiv){var selector="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return dpDiv.delegate(selector,"mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).delegate(selector,"mouseover",function(){if(!$.datepicker._isDisabledDatepicker(instActive.inline?dpDiv.parent()[0]:instActive.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}})}function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}$.fn.datepicker=function(options){if(!this.length){return this}if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate"||options=="widget")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.9.2";window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(d,e){var b="ui-dialog ui-widget ui-widget-content ui-corner-all ",a={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},c={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true};d.widget("ui.dialog",{version:"1.9.2",options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(g){var f=d(this).css(g).offset().top;if(f<0){d(this).css("top",g.top-f)}}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1000},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string"){this.originalTitle=""}this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)};this.options.title=this.options.title||this.originalTitle;var k=this,j=this.options,m=j.title||" ",h,l,f,i,g;h=(this.uiDialog=d("
      ")).addClass(b+j.dialogClass).css({display:"none",outline:0,zIndex:j.zIndex}).attr("tabIndex",-1).keydown(function(n){if(j.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===d.ui.keyCode.ESCAPE){k.close(n);n.preventDefault()}}).mousedown(function(n){k.moveToTop(false,n)}).appendTo("body");this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(h);l=(this.uiDialogTitlebar=d("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").bind("mousedown",function(){h.focus()}).prependTo(h);f=d("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(n){n.preventDefault();k.close(n)}).appendTo(l);(this.uiDialogTitlebarCloseText=d("")).addClass("ui-icon ui-icon-closethick").text(j.closeText).appendTo(f);i=d("").uniqueId().addClass("ui-dialog-title").html(m).prependTo(l);g=(this.uiDialogButtonPane=d("
      ")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");(this.uiButtonSet=d("
      ")).addClass("ui-dialog-buttonset").appendTo(g);h.attr({role:"dialog","aria-labelledby":i.attr("id")});l.find("*").add(l).disableSelection();this._hoverable(f);this._focusable(f);if(j.draggable&&d.fn.draggable){this._makeDraggable()}if(j.resizable&&d.fn.resizable){this._makeResizable()}this._createButtons(j.buttons);this._isOpen=false;if(d.fn.bgiframe){h.bgiframe()}this._on(h,{keydown:function(p){if(!j.modal||p.keyCode!==d.ui.keyCode.TAB){return}var o=d(":tabbable",h),q=o.filter(":first"),n=o.filter(":last");if(p.target===n[0]&&!p.shiftKey){q.focus(1);return false}else{if(p.target===q[0]&&p.shiftKey){n.focus(1);return false}}}})},_init:function(){if(this.options.autoOpen){this.open()}},_destroy:function(){var g,f=this.oldPosition;if(this.overlay){this.overlay.destroy()}this.uiDialog.hide();this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();if(this.originalTitle){this.element.attr("title",this.originalTitle)}g=f.parent.children().eq(f.index);if(g.length&&g[0]!==this.element[0]){g.before(this.element)}else{f.parent.append(this.element)}},widget:function(){return this.uiDialog},close:function(i){var h=this,g,f;if(!this._isOpen){return}if(false===this._trigger("beforeClose",i)){return}this._isOpen=false;if(this.overlay){this.overlay.destroy()}if(this.options.hide){this._hide(this.uiDialog,this.options.hide,function(){h._trigger("close",i)})}else{this.uiDialog.hide();this._trigger("close",i)}d.ui.dialog.overlay.resize();if(this.options.modal){g=0;d(".ui-dialog").each(function(){if(this!==h.uiDialog[0]){f=d(this).css("z-index");if(!isNaN(f)){g=Math.max(g,f)}}});d.ui.dialog.maxZ=g}return this},isOpen:function(){return this._isOpen},moveToTop:function(i,h){var g=this.options,f;if((g.modal&&!i)||(!g.stack&&!g.modal)){return this._trigger("focus",h)}if(g.zIndex>d.ui.dialog.maxZ){d.ui.dialog.maxZ=g.zIndex}if(this.overlay){d.ui.dialog.maxZ+=1;d.ui.dialog.overlay.maxZ=d.ui.dialog.maxZ;this.overlay.$el.css("z-index",d.ui.dialog.overlay.maxZ)}f={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()};d.ui.dialog.maxZ+=1;this.uiDialog.css("z-index",d.ui.dialog.maxZ);this.element.attr(f);this._trigger("focus",h);return this},open:function(){if(this._isOpen){return}var h,g=this.options,f=this.uiDialog;this._size();this._position(g.position);f.show(g.show);this.overlay=g.modal?new d.ui.dialog.overlay(this):null;this.moveToTop(true);h=this.element.find(":tabbable");if(!h.length){h=this.uiDialogButtonPane.find(":tabbable");if(!h.length){h=f}}h.eq(0).focus();this._isOpen=true;this._trigger("open");return this},_createButtons:function(h){var g=this,f=false;this.uiDialogButtonPane.remove();this.uiButtonSet.empty();if(typeof h==="object"&&h!==null){d.each(h,function(){return !(f=true)})}if(f){d.each(h,function(i,k){var j,l;k=d.isFunction(k)?{click:k,text:i}:k;k=d.extend({type:"button"},k);l=k.click;k.click=function(){l.apply(g.element[0],arguments)};j=d("",k).appendTo(g.uiButtonSet);if(d.fn.button){j.button()}});this.uiDialog.addClass("ui-dialog-buttons");this.uiDialogButtonPane.appendTo(this.uiDialog)}else{this.uiDialog.removeClass("ui-dialog-buttons")}},_makeDraggable:function(){var h=this,g=this.options;function f(i){return{position:i.position,offset:i.offset}}this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(i,j){d(this).addClass("ui-dialog-dragging");h._trigger("dragStart",i,f(j))},drag:function(i,j){h._trigger("drag",i,f(j))},stop:function(i,j){g.position=[j.position.left-h.document.scrollLeft(),j.position.top-h.document.scrollTop()];d(this).removeClass("ui-dialog-dragging");h._trigger("dragStop",i,f(j));d.ui.dialog.overlay.resize()}})},_makeResizable:function(j){j=(j===e?this.options.resizable:j);var k=this,i=this.options,f=this.uiDialog.css("position"),h=typeof j==="string"?j:"n,e,s,w,se,sw,ne,nw";function g(l){return{originalPosition:l.originalPosition,originalSize:l.originalSize,position:l.position,size:l.size}}this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:this._minHeight(),handles:h,start:function(l,m){d(this).addClass("ui-dialog-resizing");k._trigger("resizeStart",l,g(m))},resize:function(l,m){k._trigger("resize",l,g(m))},stop:function(l,m){d(this).removeClass("ui-dialog-resizing");i.height=d(this).height();i.width=d(this).width();k._trigger("resizeStop",l,g(m));d.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var f=this.options;if(f.height==="auto"){return f.minHeight}else{return Math.min(f.minHeight,f.height)}},_position:function(g){var h=[],i=[0,0],f;if(g){if(typeof g==="string"||(typeof g==="object"&&"0" in g)){h=g.split?g.split(" "):[g[0],g[1]];if(h.length===1){h[1]=h[0]}d.each(["left","top"],function(k,j){if(+h[k]===h[k]){i[k]=h[k];h[k]=j}});g={my:h[0]+(i[0]<0?i[0]:"+"+i[0])+" "+h[1]+(i[1]<0?i[1]:"+"+i[1]),at:h.join(" ")}}g=d.extend({},d.ui.dialog.prototype.options.position,g)}else{g=d.ui.dialog.prototype.options.position}f=this.uiDialog.is(":visible");if(!f){this.uiDialog.show()}this.uiDialog.position(g);if(!f){this.uiDialog.hide()}},_setOptions:function(h){var i=this,f={},g=false;d.each(h,function(j,k){i._setOption(j,k);if(j in a){g=true}if(j in c){f[j]=k}});if(g){this._size()}if(this.uiDialog.is(":data(resizable)")){this.uiDialog.resizable("option",f)}},_setOption:function(h,i){var g,j,f=this.uiDialog;switch(h){case"buttons":this._createButtons(i);break;case"closeText":this.uiDialogTitlebarCloseText.text(""+i);break;case"dialogClass":f.removeClass(this.options.dialogClass).addClass(b+i);break;case"disabled":if(i){f.addClass("ui-dialog-disabled")}else{f.removeClass("ui-dialog-disabled")}break;case"draggable":g=f.is(":data(draggable)");if(g&&!i){f.draggable("destroy")}if(!g&&i){this._makeDraggable()}break;case"position":this._position(i);break;case"resizable":j=f.is(":data(resizable)");if(j&&!i){f.resizable("destroy")}if(j&&typeof i==="string"){f.resizable("option","handles",i)}if(!j&&i!==false){this._makeResizable(i)}break;case"title":d(".ui-dialog-title",this.uiDialogTitlebar).html(""+(i||" "));break}this._super(h,i)},_size:function(){var g,j,i,h=this.options,f=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(h.minWidth>h.width){h.width=h.minWidth}g=this.uiDialog.css({height:"auto",width:h.width}).outerHeight();j=Math.max(0,h.minHeight-g);if(h.height==="auto"){if(d.support.minHeight){this.element.css({minHeight:j,height:"auto"})}else{this.uiDialog.show();i=this.element.css("height","auto").height();if(!f){this.uiDialog.hide()}this.element.height(Math.max(i,j))}}else{this.element.height(Math.max(h.height-g,0))}if(this.uiDialog.is(":data(resizable)")){this.uiDialog.resizable("option","minHeight",this._minHeight())}}});d.extend(d.ui.dialog,{uuid:0,maxZ:0,getTitleId:function(f){var g=f.attr("id");if(!g){this.uuid+=1;g=this.uuid}return"ui-dialog-title-"+g},overlay:function(f){this.$el=d.ui.dialog.overlay.create(f)}});d.extend(d.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:d.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(f){return f+".dialog-overlay"}).join(" "),create:function(g){if(this.instances.length===0){setTimeout(function(){if(d.ui.dialog.overlay.instances.length){d(document).bind(d.ui.dialog.overlay.events,function(h){if(d(h.target).zIndex()").addClass("ui-widget-overlay"));d(document).bind("keydown.dialog-overlay",function(h){var i=d.ui.dialog.overlay.instances;if(i.length!==0&&i[i.length-1]===f&&g.options.closeOnEscape&&!h.isDefaultPrevented()&&h.keyCode&&h.keyCode===d.ui.keyCode.ESCAPE){g.close(h);h.preventDefault()}});f.appendTo(document.body).css({width:this.width(),height:this.height()});if(d.fn.bgiframe){f.bgiframe()}this.instances.push(f);return f},destroy:function(f){var g=d.inArray(f,this.instances),h=0;if(g!==-1){this.oldInstances.push(this.instances.splice(g,1)[0])}if(this.instances.length===0){d([document,window]).unbind(".dialog-overlay")}f.height(0).width(0).remove();d.each(this.instances,function(){h=Math.max(h,this.css("z-index"))});this.maxZ=h},height:function(){var g,f;if(d.ui.ie){g=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);f=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(g",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element;this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,b.proxy(function(d){if(this.options.disabled){d.preventDefault()}},this));if(this.options.disabled){this.element.addClass("ui-state-disabled").attr("aria-disabled","true")}this._on({"mousedown .ui-menu-item > a":function(d){d.preventDefault()},"click .ui-state-disabled > a":function(d){d.preventDefault()},"click .ui-menu-item:has(a)":function(d){var e=b(d.target).closest(".ui-menu-item");if(!a&&e.not(".ui-state-disabled").length){a=true;this.select(d);if(e.has(".ui-menu").length){this.expand(d)}else{if(!this.element.is(":focus")){this.element.trigger("focus",[true]);if(this.active&&this.active.parents(".ui-menu").length===1){clearTimeout(this.timer)}}}}},"mouseenter .ui-menu-item":function(d){var e=b(d.currentTarget);e.siblings().children(".ui-state-active").removeClass("ui-state-active");this.focus(d,e)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(f,d){var e=this.active||this.element.children(".ui-menu-item").eq(0);if(!d){this.focus(f,e)}},blur:function(d){this._delay(function(){if(!b.contains(this.element[0],this.document[0].activeElement)){this.collapseAll(d)}})},keydown:"_keydown"});this.refresh();this._on(this.document,{click:function(d){if(!b(d.target).closest(".ui-menu").length){this.collapseAll(d)}a=false}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show();this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var d=b(this);if(d.data("ui-menu-submenu-carat")){d.remove()}});this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(j){var e,i,k,h,g,d=true;function f(l){return l.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}switch(j.keyCode){case b.ui.keyCode.PAGE_UP:this.previousPage(j);break;case b.ui.keyCode.PAGE_DOWN:this.nextPage(j);break;case b.ui.keyCode.HOME:this._move("first","first",j);break;case b.ui.keyCode.END:this._move("last","last",j);break;case b.ui.keyCode.UP:this.previous(j);break;case b.ui.keyCode.DOWN:this.next(j);break;case b.ui.keyCode.LEFT:this.collapse(j);break;case b.ui.keyCode.RIGHT:if(this.active&&!this.active.is(".ui-state-disabled")){this.expand(j)}break;case b.ui.keyCode.ENTER:case b.ui.keyCode.SPACE:this._activate(j);break;case b.ui.keyCode.ESCAPE:this.collapse(j);break;default:d=false;i=this.previousFilter||"";k=String.fromCharCode(j.keyCode);h=false;clearTimeout(this.filterTimer);if(k===i){h=true}else{k=i+k}g=new RegExp("^"+f(k),"i");e=this.activeMenu.children(".ui-menu-item").filter(function(){return g.test(b(this).children("a").text())});e=h&&e.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):e;if(!e.length){k=String.fromCharCode(j.keyCode);g=new RegExp("^"+f(k),"i");e=this.activeMenu.children(".ui-menu-item").filter(function(){return g.test(b(this).children("a").text())})}if(e.length){this.focus(j,e);if(e.length>1){this.previousFilter=k;this.filterTimer=this._delay(function(){delete this.previousFilter},1000)}else{delete this.previousFilter}}else{delete this.previousFilter}}if(d){j.preventDefault()}},_activate:function(d){if(!this.active.is(".ui-state-disabled")){if(this.active.children("a[aria-haspopup='true']").length){this.expand(d)}else{this.select(d)}}},refresh:function(){var f,e=this.options.icons.submenu,d=this.element.find(this.options.menus);d.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var i=b(this),h=i.prev("a"),g=b("").addClass("ui-menu-icon ui-icon "+e).data("ui-menu-submenu-carat",true);h.attr("aria-haspopup","true").prepend(g);i.attr("aria-labelledby",h.attr("id"))});f=d.add(this.element);f.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()});f.children(":not(.ui-menu-item)").each(function(){var g=b(this);if(!/[^\-—–\s]/.test(g.text())){g.addClass("ui-widget-content ui-menu-divider")}});f.children(".ui-state-disabled").attr("aria-disabled","true");if(this.active&&!b.contains(this.element[0],this.active[0])){this.blur()}},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,d){var g,f;this.blur(e,e&&e.type==="focus");this._scrollIntoView(d);this.active=d.first();f=this.active.children("a").addClass("ui-state-focus");if(this.options.role){this.element.attr("aria-activedescendant",f.attr("id"))}this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active");if(e&&e.type==="keydown"){this._close()}else{this.timer=this._delay(function(){this._close()},this.delay)}g=d.children(".ui-menu");if(g.length&&(/^mouse/.test(e.type))){this._startOpening(g)}this.activeMenu=d.parent();this._trigger("focus",e,{item:d})},_scrollIntoView:function(g){var j,f,h,d,e,i;if(this._hasScroll()){j=parseFloat(b.css(this.activeMenu[0],"borderTopWidth"))||0;f=parseFloat(b.css(this.activeMenu[0],"paddingTop"))||0;h=g.offset().top-this.activeMenu.offset().top-j-f;d=this.activeMenu.scrollTop();e=this.activeMenu.height();i=g.height();if(h<0){this.activeMenu.scrollTop(d+h)}else{if(h+i>e){this.activeMenu.scrollTop(d+h-e+i)}}}},blur:function(e,d){if(!d){clearTimeout(this.timer)}if(!this.active){return}this.active.children("a").removeClass("ui-state-focus");this.active=null;this._trigger("blur",e,{item:this.active})},_startOpening:function(d){clearTimeout(this.timer);if(d.attr("aria-hidden")!=="true"){return}this.timer=this._delay(function(){this._close();this._open(d)},this.delay)},_open:function(e){var d=b.extend({of:this.active},this.options.position);clearTimeout(this.timer);this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true");e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(d)},collapseAll:function(e,d){clearTimeout(this.timer);this.timer=this._delay(function(){var f=d?this.element:b(e&&e.target).closest(this.element.find(".ui-menu"));if(!f.length){f=this.element}this._close(f);this.blur(e);this.activeMenu=f},this.delay)},_close:function(d){if(!d){d=this.active?this.active.parent():this.element}d.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var d=this.active&&this.active.parent().closest(".ui-menu-item",this.element);if(d&&d.length){this._close();this.focus(e,d)}},expand:function(e){var d=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();if(d&&d.length){this._open(d.parent());this._delay(function(){this.focus(e,d)})}},next:function(d){this._move("next","first",d)},previous:function(d){this._move("prev","last",d)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(g,e,f){var d;if(this.active){if(g==="first"||g==="last"){d=this.active[g==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1)}else{d=this.active[g+"All"](".ui-menu-item").eq(0)}}if(!d||!d.length||!this.active){d=this.activeMenu.children(".ui-menu-item")[e]()}this.focus(f,d)},nextPage:function(f){var e,g,d;if(!this.active){this.next(f);return}if(this.isLastItem()){return}if(this._hasScroll()){g=this.active.offset().top;d=this.element.height();this.active.nextAll(".ui-menu-item").each(function(){e=b(this);return e.offset().top-g-d<0});this.focus(f,e)}else{this.focus(f,this.activeMenu.children(".ui-menu-item")[!this.active?"first":"last"]())}},previousPage:function(f){var e,g,d;if(!this.active){this.next(f);return}if(this.isFirstItem()){return}if(this._hasScroll()){g=this.active.offset().top;d=this.element.height();this.active.prevAll(".ui-menu-item").each(function(){e=b(this);return e.offset().top-g+d>0});this.focus(f,e)}else{this.focus(f,this.activeMenu.children(".ui-menu-item").first())}},_hasScroll:function(){return this.element.outerHeight()
      ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");this.valueDiv.remove()},value:function(c){if(c===b){return this._value()}this._setOption("value",c);return this},_setOption:function(c,d){if(c==="value"){this.options.value=d;this._refreshValue();if(this._value()===this.options.max){this._trigger("complete")}}this._super(c,d)},_value:function(){var c=this.options.value;if(typeof c!=="number"){c=0}return Math.min(this.options.max,Math.max(this.min,c))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var d=this.value(),c=this._percentage();if(this.oldValue!==d){this.oldValue=d;this._trigger("change")}this.valueDiv.toggle(d>this.min).toggleClass("ui-corner-right",d===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",d)}})})(jQuery);(function(b,c){var a=5;b.widget("ui.slider",b.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var f,d,j=this.options,h=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),g="",e=[];this._keySliding=false;this._mouseSliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all"+(j.disabled?" ui-slider-disabled ui-disabled":""));this.range=b([]);if(j.range){if(j.range===true){if(!j.values){j.values=[this._valueMin(),this._valueMin()]}if(j.values.length&&j.values.length!==2){j.values=[j.values[0],j.values[0]]}}this.range=b("
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+((j.range==="min"||j.range==="max")?" ui-slider-range-"+j.range:""))}d=(j.values&&j.values.length)||1;for(f=h.length;fp){e=p;h=b(this);l=o}});if(g.range===true&&this.values(1)===g.min){l+=1;h=b(this.handles[l])}n=this._start(f,l);if(n===false){return false}this._mouseSliding=true;this._handleIndex=l;h.addClass("ui-state-active").focus();i=h.offset();d=!b(f.target).parents().andSelf().is(".ui-slider-handle");this._clickOffset=d?{left:0,top:0}:{left:f.pageX-i.left-(h.width()/2),top:f.pageY-i.top-(h.height()/2)-(parseInt(h.css("borderTopWidth"),10)||0)-(parseInt(h.css("borderBottomWidth"),10)||0)+(parseInt(h.css("marginTop"),10)||0)};if(!this.handles.hasClass("ui-state-hover")){this._slide(f,l,m)}this._animateOff=true;return true},_mouseStart:function(){return true},_mouseDrag:function(f){var d={x:f.pageX,y:f.pageY},e=this._normValueFromMouse(d);this._slide(f,this._handleIndex,e);return false},_mouseStop:function(d){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(d,this._handleIndex);this._change(d,this._handleIndex);this._handleIndex=null;this._clickOffset=null;this._animateOff=false;return false},_detectOrientation:function(){this.orientation=(this.options.orientation==="vertical")?"vertical":"horizontal"},_normValueFromMouse:function(e){var d,h,g,f,i;if(this.orientation==="horizontal"){d=this.elementSize.width;h=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{d=this.elementSize.height;h=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}g=(h/d);if(g>1){g=1}if(g<0){g=0}if(this.orientation==="vertical"){g=1-g}f=this._valueMax()-this._valueMin();i=this._valueMin()+g*f;return this._trimAlignValue(i)},_start:function(f,e){var d={handle:this.handles[e],value:this.value()};if(this.options.values&&this.options.values.length){d.value=this.values(e);d.values=this.values()}return this._trigger("start",f,d)},_slide:function(h,g,f){var d,e,i;if(this.options.values&&this.options.values.length){d=this.values(g?0:1);if((this.options.values.length===2&&this.options.range===true)&&((g===0&&f>d)||(g===1&&f1){this.options.values[e]=this._trimAlignValue(h);this._refreshValue();this._change(null,e);return}if(arguments.length){if(b.isArray(arguments[0])){g=this.options.values;d=arguments[0];for(f=0;f=this._valueMax()){return this._valueMax()}var d=(this.options.step>0)?this.options.step:1,f=(g-this._valueMin())%d,e=g-f;if(Math.abs(f)*2>=d){e+=(f>0)?d:(-d)}return parseFloat(e.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var i,h,l,j,m,g=this.options.range,f=this.options,k=this,e=(!this._animateOff)?f.animate:false,d={};if(this.options.values&&this.options.values.length){this.handles.each(function(n){h=(k.values(n)-k._valueMin())/(k._valueMax()-k._valueMin())*100;d[k.orientation==="horizontal"?"left":"bottom"]=h+"%";b(this).stop(1,1)[e?"animate":"css"](d,f.animate);if(k.options.range===true){if(k.orientation==="horizontal"){if(n===0){k.range.stop(1,1)[e?"animate":"css"]({left:h+"%"},f.animate)}if(n===1){k.range[e?"animate":"css"]({width:(h-i)+"%"},{queue:false,duration:f.animate})}}else{if(n===0){k.range.stop(1,1)[e?"animate":"css"]({bottom:(h)+"%"},f.animate)}if(n===1){k.range[e?"animate":"css"]({height:(h-i)+"%"},{queue:false,duration:f.animate})}}}i=h})}else{l=this.value();j=this._valueMin();m=this._valueMax();h=(m!==j)?(l-j)/(m-j)*100:0;d[this.orientation==="horizontal"?"left":"bottom"]=h+"%";this.handle.stop(1,1)[e?"animate":"css"](d,f.animate);if(g==="min"&&this.orientation==="horizontal"){this.range.stop(1,1)[e?"animate":"css"]({width:h+"%"},f.animate)}if(g==="max"&&this.orientation==="horizontal"){this.range[e?"animate":"css"]({width:(100-h)+"%"},{queue:false,duration:f.animate})}if(g==="min"&&this.orientation==="vertical"){this.range.stop(1,1)[e?"animate":"css"]({height:h+"%"},f.animate)}if(g==="max"&&this.orientation==="vertical"){this.range[e?"animate":"css"]({height:(100-h)+"%"},{queue:false,duration:f.animate})}}}})}(jQuery));(function(b){function a(c){return function(){var d=this.element.val();c.apply(this,arguments);this._refresh();if(d!==this.element.val()){this._trigger("change")}}}b.widget("ui.spinner",{version:"1.9.2",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:true,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max);this._setOption("min",this.options.min);this._setOption("step",this.options.step);this._value(this.element.val(),true);this._draw();this._on(this._events);this._refresh();this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var c={},d=this.element;b.each(["min","max","step"],function(e,f){var g=d.attr(f);if(g!==undefined&&g.length){c[f]=g}});return c},_events:{keydown:function(c){if(this._start(c)&&this._keydown(c)){c.preventDefault()}},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(c){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh();if(this.previous!==this.element.val()){this._trigger("change",c)}},mousewheel:function(c,d){if(!d){return}if(!this.spinning&&!this._start(c)){return false}this._spin((d>0?1:-1)*this.options.step,c);clearTimeout(this.mousewheelTimer);this.mousewheelTimer=this._delay(function(){if(this.spinning){this._stop(c)}},100);c.preventDefault()},"mousedown .ui-spinner-button":function(d){var c;c=this.element[0]===this.document[0].activeElement?this.previous:this.element.val();function e(){var f=this.element[0]===this.document[0].activeElement;if(!f){this.element.focus();this.previous=c;this._delay(function(){this.previous=c})}}d.preventDefault();e.call(this);this.cancelBlur=true;this._delay(function(){delete this.cancelBlur;e.call(this)});if(this._start(d)===false){return}this._repeat(null,b(d.currentTarget).hasClass("ui-spinner-up")?1:-1,d)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(c){if(!b(c.currentTarget).hasClass("ui-state-active")){return}if(this._start(c)===false){return false}this._repeat(null,b(c.currentTarget).hasClass("ui-spinner-up")?1:-1,c)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var c=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton");this.buttons=c.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all");if(this.buttons.height()>Math.ceil(c.height()*0.5)&&c.height()>0){c.height(c.height())}if(this.options.disabled){this.disable()}},_keydown:function(d){var c=this.options,e=b.ui.keyCode;switch(d.keyCode){case e.UP:this._repeat(null,1,d);return true;case e.DOWN:this._repeat(null,-1,d);return true;case e.PAGE_UP:this._repeat(null,c.page,d);return true;case e.PAGE_DOWN:this._repeat(null,-c.page,d);return true}return false},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""},_start:function(c){if(!this.spinning&&this._trigger("start",c)===false){return false}if(!this.counter){this.counter=1}this.spinning=true;return true},_repeat:function(d,c,e){d=d||500;clearTimeout(this.timer);this.timer=this._delay(function(){this._repeat(40,c,e)},d);this._spin(c*this.options.step,e)},_spin:function(d,c){var e=this.value()||0;if(!this.counter){this.counter=1}e=this._adjustValue(e+d*this._increment(this.counter));if(!this.spinning||this._trigger("spin",c,{value:e})!==false){this._value(e);this.counter++}},_increment:function(c){var d=this.options.incremental;if(d){return b.isFunction(d)?d(c):Math.floor(c*c*c/50000-c*c/500+17*c/200+1)}return 1},_precision:function(){var c=this._precisionOf(this.options.step);if(this.options.min!==null){c=Math.max(c,this._precisionOf(this.options.min))}return c},_precisionOf:function(d){var e=d.toString(),c=e.indexOf(".");return c===-1?0:e.length-c-1},_adjustValue:function(e){var d,f,c=this.options;d=c.min!==null?c.min:0;f=e-d;f=Math.round(f/c.step)*c.step;e=d+f;e=parseFloat(e.toFixed(this._precision()));if(c.max!==null&&e>c.max){return c.max}if(c.min!==null&&e1&&g.href.replace(f,"")===location.href.replace(f,"").replace(/\s/g,"%20")}c.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:false,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var h=this,g=this.options,i=g.active,j=location.hash.substring(1);this.running=false;this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",g.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(k){if(c(this).is(".ui-state-disabled")){k.preventDefault()}}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){if(c(this).closest("li").is(".ui-state-disabled")){this.blur()}});this._processTabs();if(i===null){if(j){this.tabs.each(function(k,l){if(c(l).attr("aria-controls")===j){i=k;return false}})}if(i===null){i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))}if(i===null||i===-1){i=this.tabs.length?0:false}}if(i!==false){i=this.tabs.index(this.tabs.eq(i));if(i===-1){i=g.collapsible?false:0}}g.active=i;if(!g.collapsible&&g.active===false&&this.anchors.length){g.active=0}if(c.isArray(g.disabled)){g.disabled=c.unique(g.disabled.concat(c.map(this.tabs.filter(".ui-state-disabled"),function(k){return h.tabs.index(k)}))).sort()}if(this.options.active!==false&&this.anchors.length){this.active=this._findActive(this.options.active)}else{this.active=c()}this._refresh();if(this.active.length){this.load(g.active)}},_getCreateEventData:function(){return{tab:this.active,panel:!this.active.length?c():this._getPanelForTab(this.active)}},_tabKeydown:function(i){var h=c(this.document[0].activeElement).closest("li"),g=this.tabs.index(h),j=true;if(this._handlePageNav(i)){return}switch(i.keyCode){case c.ui.keyCode.RIGHT:case c.ui.keyCode.DOWN:g++;break;case c.ui.keyCode.UP:case c.ui.keyCode.LEFT:j=false;g--;break;case c.ui.keyCode.END:g=this.anchors.length-1;break;case c.ui.keyCode.HOME:g=0;break;case c.ui.keyCode.SPACE:i.preventDefault();clearTimeout(this.activating);this._activate(g);return;case c.ui.keyCode.ENTER:i.preventDefault();clearTimeout(this.activating);this._activate(g===this.options.active?false:g);return;default:return}i.preventDefault();clearTimeout(this.activating);g=this._focusNextTab(g,j);if(!i.ctrlKey){h.attr("aria-selected","false");this.tabs.eq(g).attr("aria-selected","true");this.activating=this._delay(function(){this.option("active",g)},this.delay)}},_panelKeydown:function(g){if(this._handlePageNav(g)){return}if(g.ctrlKey&&g.keyCode===c.ui.keyCode.UP){g.preventDefault();this.active.focus()}},_handlePageNav:function(g){if(g.altKey&&g.keyCode===c.ui.keyCode.PAGE_UP){this._activate(this._focusNextTab(this.options.active-1,false));return true}if(g.altKey&&g.keyCode===c.ui.keyCode.PAGE_DOWN){this._activate(this._focusNextTab(this.options.active+1,true));return true}},_findNextTab:function(h,i){var g=this.tabs.length-1;function j(){if(h>g){h=0}if(h<0){h=g}return h}while(c.inArray(j(),this.options.disabled)!==-1){h=i?h+1:h-1}return h},_focusNextTab:function(g,h){g=this._findNextTab(g,h);this.tabs.eq(g).focus();return g},_setOption:function(g,h){if(g==="active"){this._activate(h);return}if(g==="disabled"){this._setupDisabled(h);return}this._super(g,h);if(g==="collapsible"){this.element.toggleClass("ui-tabs-collapsible",h);if(!h&&this.options.active===false){this._activate(0)}}if(g==="event"){this._setupEvents(h)}if(g==="heightStyle"){this._setupHeightStyle(h)}},_tabId:function(g){return g.attr("aria-controls")||"ui-tabs-"+d()},_sanitizeSelector:function(g){return g?g.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var h=this.options,g=this.tablist.children(":has(a[href])");h.disabled=c.map(g.filter(".ui-state-disabled"),function(i){return g.index(i)});this._processTabs();if(h.active===false||!this.anchors.length){h.active=false;this.active=c()}else{if(this.active.length&&!c.contains(this.tablist[0],this.active[0])){if(this.tabs.length===h.disabled.length){h.active=false;this.active=c()}else{this._activate(this._findNextTab(Math.max(0,h.active-1),false))}}else{h.active=this.tabs.index(this.active)}}this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled);this._setupEvents(this.options.event);this._setupHeightStyle(this.options.heightStyle);this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1});this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"});if(!this.active.length){this.tabs.eq(0).attr("tabIndex",0)}else{this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0});this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})}},_processTabs:function(){var g=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist");this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1});this.anchors=this.tabs.map(function(){return c("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1});this.panels=c();this.anchors.each(function(n,l){var h,j,m,k=c(l).uniqueId().attr("id"),o=c(l).closest("li"),p=o.attr("aria-controls");if(b(l)){h=l.hash;j=g.element.find(g._sanitizeSelector(h))}else{m=g._tabId(o);h="#"+m;j=g.element.find(h);if(!j.length){j=g._createPanel(m);j.insertAfter(g.panels[n-1]||g.tablist)}j.attr("aria-live","polite")}if(j.length){g.panels=g.panels.add(j)}if(p){o.data("ui-tabs-aria-controls",p)}o.attr({"aria-controls":h.substring(1),"aria-labelledby":k});j.attr("aria-labelledby",k)});this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(g){return c("
      ").attr("id",g).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",true)},_setupDisabled:function(j){if(c.isArray(j)){if(!j.length){j=false}else{if(j.length===this.anchors.length){j=true}}}for(var h=0,g;(g=this.tabs[h]);h++){if(j===true||c.inArray(h,j)!==-1){c(g).addClass("ui-state-disabled").attr("aria-disabled","true")}else{c(g).removeClass("ui-state-disabled").removeAttr("aria-disabled")}}this.options.disabled=j},_setupEvents:function(h){var g={click:function(i){i.preventDefault()}};if(h){c.each(h.split(" "),function(j,i){g[i]="_eventHandler"})}this._off(this.anchors.add(this.tabs).add(this.panels));this._on(this.anchors,g);this._on(this.tabs,{keydown:"_tabKeydown"});this._on(this.panels,{keydown:"_panelKeydown"});this._focusable(this.tabs);this._hoverable(this.tabs)},_setupHeightStyle:function(g){var i,j,h=this.element.parent();if(g==="fill"){if(!c.support.minHeight){j=h.css("overflow");h.css("overflow","hidden")}i=h.height();this.element.siblings(":visible").each(function(){var l=c(this),k=l.css("position");if(k==="absolute"||k==="fixed"){return}i-=l.outerHeight(true)});if(j){h.css("overflow",j)}this.element.children().not(this.panels).each(function(){i-=c(this).outerHeight(true)});this.panels.each(function(){c(this).height(Math.max(0,i-c(this).innerHeight()+c(this).height()))}).css("overflow","auto")}else{if(g==="auto"){i=0;this.panels.each(function(){i=Math.max(i,c(this).height("").height())}).height(i)}}},_eventHandler:function(g){var p=this.options,k=this.active,l=c(g.currentTarget),j=l.closest("li"),n=j[0]===k[0],h=n&&p.collapsible,i=h?c():this._getPanelForTab(j),m=!k.length?c():this._getPanelForTab(k),o={oldTab:k,oldPanel:m,newTab:h?c():j,newPanel:i};g.preventDefault();if(j.hasClass("ui-state-disabled")||j.hasClass("ui-tabs-loading")||this.running||(n&&!p.collapsible)||(this._trigger("beforeActivate",g,o)===false)){return}p.active=h?false:this.tabs.index(j);this.active=n?c():j;if(this.xhr){this.xhr.abort()}if(!m.length&&!i.length){c.error("jQuery UI Tabs: Mismatching fragment identifier.")}if(i.length){this.load(this.tabs.index(j),g)}this._toggle(g,o)},_toggle:function(m,l){var k=this,g=l.newPanel,j=l.oldPanel;this.running=true;function i(){k.running=false;k._trigger("activate",m,l)}function h(){l.newTab.closest("li").addClass("ui-tabs-active ui-state-active");if(g.length&&k.options.show){k._show(g,k.options.show,i)}else{g.show();i()}}if(j.length&&this.options.hide){this._hide(j,this.options.hide,function(){l.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");h()})}else{l.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");j.hide();h()}j.attr({"aria-expanded":"false","aria-hidden":"true"});l.oldTab.attr("aria-selected","false");if(g.length&&j.length){l.oldTab.attr("tabIndex",-1)}else{if(g.length){this.tabs.filter(function(){return c(this).attr("tabIndex")===0}).attr("tabIndex",-1)}}g.attr({"aria-expanded":"true","aria-hidden":"false"});l.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(h){var g,i=this._findActive(h);if(i[0]===this.active[0]){return}if(!i.length){i=this.active}g=i.find(".ui-tabs-anchor")[0];this._eventHandler({target:g,currentTarget:g,preventDefault:c.noop})},_findActive:function(g){return g===false?c():this.tabs.eq(g)},_getIndex:function(g){if(typeof g==="string"){g=this.anchors.index(this.anchors.filter("[href$='"+g+"']"))}return g},_destroy:function(){if(this.xhr){this.xhr.abort()}this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible");this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role");this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId();this.tabs.add(this.panels).each(function(){if(c.data(this,"ui-tabs-destroy")){c(this).remove()}else{c(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}});this.tabs.each(function(){var g=c(this),h=g.data("ui-tabs-aria-controls");if(h){g.attr("aria-controls",h)}else{g.removeAttr("aria-controls")}});this.panels.show();if(this.options.heightStyle!=="content"){this.panels.css("height","")}},enable:function(g){var h=this.options.disabled;if(h===false){return}if(g===e){h=false}else{g=this._getIndex(g);if(c.isArray(h)){h=c.map(h,function(i){return i!==g?i:null})}else{h=c.map(this.tabs,function(i,j){return j!==g?j:null})}}this._setupDisabled(h)},disable:function(g){var h=this.options.disabled;if(h===true){return}if(g===e){h=true}else{g=this._getIndex(g);if(c.inArray(g,h)!==-1){return}if(c.isArray(h)){h=c.merge([g],h).sort()}else{h=[g]}}this._setupDisabled(h)},load:function(i,m){i=this._getIndex(i);var l=this,j=this.tabs.eq(i),h=j.find(".ui-tabs-anchor"),g=this._getPanelForTab(j),k={tab:j,panel:g};if(b(h[0])){return}this.xhr=c.ajax(this._ajaxSettings(h,m,k));if(this.xhr&&this.xhr.statusText!=="canceled"){j.addClass("ui-tabs-loading");g.attr("aria-busy","true");this.xhr.success(function(n){setTimeout(function(){g.html(n);l._trigger("load",m,k)},1)}).complete(function(o,n){setTimeout(function(){if(n==="abort"){l.panels.stop(false,true)}j.removeClass("ui-tabs-loading");g.removeAttr("aria-busy");if(o===l.xhr){delete l.xhr}},1)})}},_ajaxSettings:function(g,j,i){var h=this;return{url:g.attr("href"),beforeSend:function(l,k){return h._trigger("beforeLoad",j,c.extend({jqXHR:l,ajaxSettings:k},i))}}},_getPanelForTab:function(g){var h=c(g).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+h))}});if(c.uiBackCompat!==false){c.ui.tabs.prototype._ui=function(h,g){return{tab:h,panel:g,index:this.anchors.index(h)}};c.widget("ui.tabs",c.ui.tabs,{url:function(h,g){this.anchors.eq(h).attr("href",g)}});c.widget("ui.tabs",c.ui.tabs,{options:{ajaxOptions:null,cache:false},_create:function(){this._super();var g=this;this._on({tabsbeforeload:function(h,i){if(c.data(i.tab[0],"cache.tabs")){h.preventDefault();return}i.jqXHR.success(function(){if(g.options.cache){c.data(i.tab[0],"cache.tabs",true)}})}})},_ajaxSettings:function(h,i,j){var g=this.options.ajaxOptions;return c.extend({},g,{error:function(m,k){try{g.error(m,k,j.tab.closest("li").index(),j.tab[0])}catch(l){}}},this._superApply(arguments))},_setOption:function(g,h){if(g==="cache"&&h===false){this.anchors.removeData("cache.tabs")}this._super(g,h)},_destroy:function(){this.anchors.removeData("cache.tabs");this._super()},url:function(g){this.anchors.eq(g).removeData("cache.tabs");this._superApply(arguments)}});c.widget("ui.tabs",c.ui.tabs,{abort:function(){if(this.xhr){this.xhr.abort()}}});c.widget("ui.tabs",c.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super();this._on({tabsbeforeload:function(i,j){if(i.target!==this.element[0]||!this.options.spinner){return}var h=j.tab.find("span"),g=h.html();h.html(this.options.spinner);j.jqXHR.complete(function(){h.html(g)})}})}});c.widget("ui.tabs",c.ui.tabs,{options:{enable:null,disable:null},enable:function(i){var h=this.options,g;if(i&&h.disabled===true||(c.isArray(h.disabled)&&c.inArray(i,h.disabled)!==-1)){g=true}this._superApply(arguments);if(g){this._trigger("enable",null,this._ui(this.anchors[i],this.panels[i]))}},disable:function(i){var h=this.options,g;if(i&&h.disabled===false||(c.isArray(h.disabled)&&c.inArray(i,h.disabled)===-1)){g=true}this._superApply(arguments);if(g){this._trigger("disable",null,this._ui(this.anchors[i],this.panels[i]))}}});c.widget("ui.tabs",c.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
    • #{label}
    • "},add:function(l,k,j){if(j===e){j=this.anchors.length}var m,h,i=this.options,g=c(i.tabTemplate.replace(/#\{href\}/g,l).replace(/#\{label\}/g,k)),n=!l.indexOf("#")?l.replace("#",""):this._tabId(g);g.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",true);g.attr("aria-controls",n);m=j>=this.tabs.length;h=this.element.find("#"+n);if(!h.length){h=this._createPanel(n);if(m){if(j>0){h.insertAfter(this.panels.eq(-1))}else{h.appendTo(this.element)}}else{h.insertBefore(this.panels[j])}}h.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide();if(m){g.appendTo(this.tablist)}else{g.insertBefore(this.tabs[j])}i.disabled=c.map(i.disabled,function(o){return o>=j?++o:o});this.refresh();if(this.tabs.length===1&&i.active===false){this.option("active",0)}this._trigger("add",null,this._ui(this.anchors[j],this.panels[j]));return this},remove:function(i){i=this._getIndex(i);var h=this.options,j=this.tabs.eq(i).remove(),g=this._getPanelForTab(j).remove();if(j.hasClass("ui-tabs-active")&&this.anchors.length>2){this._activate(i+(i+1=i?--k:k});this.refresh();this._trigger("remove",null,this._ui(j.find("a")[0],g[0]));return this}});c.widget("ui.tabs",c.ui.tabs,{length:function(){return this.anchors.length}});c.widget("ui.tabs",c.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(h){var g=h.is("li")?h.find("a[href]"):h;g=g[0];return c(g).closest("li").attr("aria-controls")||g.title&&g.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+d()}});c.widget("ui.tabs",c.ui.tabs,{options:{panelTemplate:"
      "},_createPanel:function(g){return c(this.options.panelTemplate).attr("id",g).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",true)}});c.widget("ui.tabs",c.ui.tabs,{_create:function(){var g=this.options;if(g.active===null&&g.selected!==e){g.active=g.selected===-1?false:g.selected}this._super();g.selected=g.active;if(g.selected===false){g.selected=-1}},_setOption:function(h,i){if(h!=="selected"){return this._super(h,i)}var g=this.options;this._super("active",i===-1?false:i);g.selected=g.active;if(g.selected===false){g.selected=-1}},_eventHandler:function(){this._superApply(arguments);this.options.selected=this.options.active;if(this.options.selected===false){this.options.selected=-1}}});c.widget("ui.tabs",c.ui.tabs,{options:{show:null,select:null},_create:function(){this._super();if(this.options.active!==false){this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))}},_trigger:function(j,k,l){var i,g,h=this._superApply(arguments);if(!h){return false}if(j==="beforeActivate"){i=l.newTab.length?l.newTab:l.oldTab;g=l.newPanel.length?l.newPanel:l.oldPanel;h=this._super("select",k,{tab:i.find(".ui-tabs-anchor")[0],panel:g[0],index:i.closest("li").index()})}else{if(j==="activate"&&l.newTab.length){h=this._super("show",k,{tab:l.newTab.find(".ui-tabs-anchor")[0],panel:l.newPanel[0],index:l.newTab.closest("li").index()})}}return h}});c.widget("ui.tabs",c.ui.tabs,{select:function(g){g=this._getIndex(g);if(g===-1){if(this.options.collapsible&&this.options.selected!==-1){g=this.options.selected}else{return}}this.anchors.eq(g).trigger(this.options.event+this.eventNamespace)}});(function(){var g=0;c.widget("ui.tabs",c.ui.tabs,{options:{cookie:null},_create:function(){var h=this.options,i;if(h.active==null&&h.cookie){i=parseInt(this._cookie(),10);if(i===-1){i=false}h.active=i}this._super()},_cookie:function(i){var h=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+(++g))];if(arguments.length){h.push(i===false?-1:i);h.push(this.options.cookie)}return c.cookie.apply(null,h)},_refresh:function(){this._super();if(this.options.cookie){this._cookie(this.options.active,this.options.cookie)}},_eventHandler:function(){this._superApply(arguments);if(this.options.cookie){this._cookie(this.options.active,this.options.cookie)}},_destroy:function(){this._super();if(this.options.cookie){this._cookie(null,this.options.cookie)}}})})();c.widget("ui.tabs",c.ui.tabs,{_trigger:function(h,i,j){var g=c.extend({},j);if(h==="load"){g.panel=g.panel[0];g.tab=g.tab.find(".ui-tabs-anchor")[0]}return this._super(h,i,g)}});c.widget("ui.tabs",c.ui.tabs,{options:{fx:null},_getFx:function(){var h,g,i=this.options.fx;if(i){if(c.isArray(i)){h=i[0];g=i[1]}else{h=g=i}}return i?{show:g,hide:h}:null},_toggle:function(n,m){var l=this,g=m.newPanel,j=m.oldPanel,k=this._getFx();if(!k){return this._super(n,m)}l.running=true;function i(){l.running=false;l._trigger("activate",n,m)}function h(){m.newTab.closest("li").addClass("ui-tabs-active ui-state-active");if(g.length&&k.show){g.animate(k.show,k.show.duration,function(){i()})}else{g.show();i()}}if(j.length&&k.hide){j.animate(k.hide,k.hide.duration,function(){m.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");h()})}else{m.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");j.hide();h()}}})}})(jQuery);(function(d){var b=0;function c(f,g){var e=(f.attr("aria-describedby")||"").split(/\s+/);e.push(g);f.data("ui-tooltip-id",g).attr("aria-describedby",d.trim(e.join(" ")))}function a(g){var h=g.data("ui-tooltip-id"),f=(g.attr("aria-describedby")||"").split(/\s+/),e=d.inArray(h,f);if(e!==-1){f.splice(e,1)}g.removeData("ui-tooltip-id");f=d.trim(f.join(" "));if(f){g.attr("aria-describedby",f)}else{g.removeAttr("aria-describedby")}}d.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return d(this).attr("title")},hide:true,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:true,tooltipClass:null,track:false,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"});this.tooltips={};this.parents={};if(this.options.disabled){this._disable()}},_setOption:function(e,g){var f=this;if(e==="disabled"){this[g?"_disable":"_enable"]();this.options[e]=g;return}this._super(e,g);if(e==="content"){d.each(this.tooltips,function(i,h){f._updateContent(h)})}},_disable:function(){var e=this;d.each(this.tooltips,function(h,f){var g=d.Event("blur");g.target=g.currentTarget=f[0];e.close(g,true)});this.element.find(this.options.items).andSelf().each(function(){var f=d(this);if(f.is("[title]")){f.data("ui-tooltip-title",f.attr("title")).attr("title","")}})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var e=d(this);if(e.data("ui-tooltip-title")){e.attr("title",e.data("ui-tooltip-title"))}})},open:function(f){var e=this,g=d(f?f.target:this.element).closest(this.options.items);if(!g.length||g.data("ui-tooltip-id")){return}if(g.attr("title")){g.data("ui-tooltip-title",g.attr("title"))}g.data("ui-tooltip-open",true);if(f&&f.type==="mouseover"){g.parents().each(function(){var i=d(this),h;if(i.data("ui-tooltip-open")){h=d.Event("blur");h.target=h.currentTarget=this;e.close(h,true)}if(i.attr("title")){i.uniqueId();e.parents[this.id]={element:this,title:i.attr("title")};i.attr("title","")}})}this._updateContent(g,f)},_updateContent:function(j,i){var h,e=this.options.content,g=this,f=i?i.type:null;if(typeof e==="string"){return this._open(i,j,e)}h=e.call(j[0],function(k){if(!j.data("ui-tooltip-open")){return}g._delay(function(){if(i){i.type=f}this._open(i,j,k)})});if(h){this._open(i,j,h)}},_open:function(i,k,h){var j,g,f,l=d.extend({},this.options.position);if(!h){return}j=this._find(k);if(j.length){j.find(".ui-tooltip-content").html(h);return}if(k.is("[title]")){if(i&&i.type==="mouseover"){k.attr("title","")}else{k.removeAttr("title")}}j=this._tooltip(k);c(k,j.attr("id"));j.find(".ui-tooltip-content").html(h);function e(m){l.of=m;if(j.is(":hidden")){return}j.position(l)}if(this.options.track&&i&&/^mouse/.test(i.type)){this._on(this.document,{mousemove:e});e(i)}else{j.position(d.extend({of:k},this.options.position))}j.hide();this._show(j,this.options.show);if(this.options.show&&this.options.show.delay){f=setInterval(function(){if(j.is(":visible")){e(l.of);clearInterval(f)}},d.fx.interval)}this._trigger("open",i,{tooltip:j});g={keyup:function(m){if(m.keyCode===d.ui.keyCode.ESCAPE){var n=d.Event(m);n.currentTarget=k[0];this.close(n,true)}},remove:function(){this._removeTooltip(j)}};if(!i||i.type==="mouseover"){g.mouseleave="close"}if(!i||i.type==="focusin"){g.focusout="close"}this._on(true,k,g)},close:function(f){var e=this,h=d(f?f.currentTarget:this.element),g=this._find(h);if(this.closing){return}if(h.data("ui-tooltip-title")){h.attr("title",h.data("ui-tooltip-title"))}a(h);g.stop(true);this._hide(g,this.options.hide,function(){e._removeTooltip(d(this))});h.removeData("ui-tooltip-open");this._off(h,"mouseleave focusout keyup");if(h[0]!==this.element[0]){this._off(h,"remove")}this._off(this.document,"mousemove");if(f&&f.type==="mouseleave"){d.each(this.parents,function(j,i){d(i.element).attr("title",i.title);delete e.parents[j]})}this.closing=true;this._trigger("close",f,{tooltip:g});this.closing=false},_tooltip:function(e){var g="ui-tooltip-"+b++,f=d("
      ").attr({id:g,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));d("
      ").addClass("ui-tooltip-content").appendTo(f);f.appendTo(this.document[0].body);if(d.fn.bgiframe){f.bgiframe()}this.tooltips[g]=e;return f},_find:function(e){var f=e.data("ui-tooltip-id");return f?d("#"+f):d()},_removeTooltip:function(e){e.remove();delete this.tooltips[e.attr("id")]},_destroy:function(){var e=this;d.each(this.tooltips,function(h,f){var g=d.Event("blur");g.target=g.currentTarget=f[0];e.close(g,true);d("#"+h).remove();if(f.data("ui-tooltip-title")){f.attr("title",f.data("ui-tooltip-title"));f.removeData("ui-tooltip-title")}})}})}(jQuery));(jQuery.effects||(function(b,d){var a=b.uiBackCompat!==false,c="ui-effects-";b.effects={effect:{}}; +/*! + * jQuery Color Animations v2.0.0 + * http://jquery.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: Mon Aug 13 13:41:02 2012 -0500 + */ +(function(s,h){var o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),l=/^([\-+])=\s*(\d+\.?\d*)/,k=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1]*2.55,t[2]*2.55,t[3]*2.55,t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],i=s.Color=function(u,v,t,w){return new s.Color.fn.parse(u,v,t,w)},n={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},r={"byte":{floor:true,max:255},percent:{max:1},degrees:{mod:360,floor:true}},q=i.support={},f=s("

      ")[0],e,p=s.each;f.style.cssText="background-color:rgba(1,1,1,.5)";q.rgba=f.style.backgroundColor.indexOf("rgba")>-1;p(n,function(t,u){u.cache="_"+t;u.props.alpha={idx:3,type:"percent",def:1}});function m(u,w,v){var t=r[w.type]||{};if(u==null){return(v||!w.def)?null:w.def}u=t.floor?~~u:parseFloat(u);if(isNaN(u)){return w.def}if(t.mod){return(u+t.mod)%t.mod}return 0>u?0:t.maxF.mod/2){C+=F.mod}else{if(C-B>F.mod/2){C-=F.mod}}}t[D]=m((B-C)*A+C,G)}});return this[w](t)},blend:function(w){if(this._rgba[3]===1){return this}var v=this._rgba.slice(),u=v.pop(),t=i(w)._rgba;return i(s.map(v,function(x,y){return(1-u)*t[y]+u*x}))},toRgbaString:function(){var u="rgba(",t=s.map(this._rgba,function(w,x){return w==null?(x>2?1:0):w});if(t[3]===1){t.pop();u="rgb("}return u+t.join()+")"},toHslaString:function(){var u="hsla(",t=s.map(this.hsla(),function(w,x){if(w==null){w=x>2?1:0}if(x&&x<3){w=Math.round(w*100)+"%"}return w});if(t[3]===1){t.pop();u="hsl("}return u+t.join()+")"},toHexString:function(t){var u=this._rgba.slice(),v=u.pop();if(t){u.push(~~(v*255))}return"#"+s.map(u,function(w){w=(w||0).toString(16);return w.length===1?"0"+w:w}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}});i.fn.parse.prototype=i.fn;function g(v,u,t){t=(t+1)%1;if(t*6<1){return v+(u-v)*t*6}if(t*2<1){return u}if(t*3<2){return v+(u-v)*((2/3)-t)*6}return v}n.hsla.to=function(v){if(v[0]==null||v[1]==null||v[2]==null){return[null,null,null,v[3]]}var t=v[0]/255,y=v[1]/255,z=v[2]/255,B=v[3],A=Math.max(t,y,z),w=Math.min(t,y,z),C=A-w,D=A+w,u=D*0.5,x,E;if(w===A){x=0}else{if(t===A){x=(60*(y-z)/C)+360}else{if(y===A){x=(60*(z-t)/C)+120}else{x=(60*(t-y)/C)+240}}}if(u===0||u===1){E=u}else{if(u<=0.5){E=C/D}else{E=C/(2-D)}}return[Math.round(x)%360,E,u,B==null?1:B]};n.hsla.from=function(x){if(x[0]==null||x[1]==null||x[2]==null){return[null,null,null,x[3]]}var w=x[0]/360,v=x[1],u=x[2],t=x[3],y=u<=0.5?u*(1+v):u+v-u*v,z=2*u-y;return[Math.round(g(z,y,w+(1/3))*255),Math.round(g(z,y,w)*255),Math.round(g(z,y,w-(1/3))*255),t]};p(n,function(u,w){var v=w.props,t=w.cache,y=w.to,x=w.from;i.fn[u]=function(D){if(y&&!this[t]){this[t]=y(this._rgba)}if(D===h){return this[t].slice()}var A,C=s.type(D),z=(C==="array"||C==="object")?D:arguments,B=this[t].slice();p(v,function(E,G){var F=z[C==="object"?E:G.idx];if(F==null){F=B[G.idx]}B[G.idx]=m(F,G)});if(x){A=i(x(B));A[t]=B;return A}else{return i(B)}};p(v,function(z,A){if(i.fn[z]){return}i.fn[z]=function(E){var G=s.type(E),D=(z==="alpha"?(this._hsla?"hsla":"rgba"):u),C=this[D](),F=C[A.idx],B;if(G==="undefined"){return F}if(G==="function"){E=E.call(this,F);G=s.type(E)}if(E==null&&A.empty){return this}if(G==="string"){B=l.exec(E);if(B){E=F+parseFloat(B[2])*(B[1]==="+"?1:-1)}}C[A.idx]=E;return this[D](C)}})});p(o,function(t,u){s.cssHooks[u]={set:function(z,A){var w,y,v="";if(s.type(A)!=="string"||(w=j(A))){A=i(w||A);if(!q.rgba&&A._rgba[3]!==1){y=u==="backgroundColor"?z.parentNode:z;while((v===""||v==="transparent")&&y&&y.style){try{v=s.css(y,"backgroundColor");y=y.parentNode}catch(B){}}A=A.blend(v&&v!=="transparent"?v:"_default")}A=A.toRgbaString()}try{z.style[u]=A}catch(x){}}};s.fx.step[u]=function(v){if(!v.colorInit){v.start=i(v.elem,u);v.end=i(v.end);v.colorInit=true}s.cssHooks[u].set(v.elem,v.start.transition(v.end,v.pos))}});s.cssHooks.borderColor={expand:function(u){var t={};p(["Top","Right","Bottom","Left"],function(w,v){t["border"+v+"Color"]=u});return t}};e=s.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);(function(){var f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};b.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(i,j){b.fx.step[j]=function(k){if(k.end!=="none"&&!k.setAttr||k.pos===1&&!k.setAttr){jQuery.style(k.elem,j,k.end);k.setAttr=true}}});function h(){var k=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,l={},j,i;if(k&&k.length&&k[0]&&k[k[0]]){i=k.length;while(i--){j=k[i];if(typeof k[j]==="string"){l[b.camelCase(j)]=k[j]}}}else{for(j in k){if(typeof k[j]==="string"){l[j]=k[j]}}}return l}function e(i,k){var m={},j,l;for(j in k){l=k[j];if(i[j]!==l){if(!g[j]){if(b.fx.step[j]||!isNaN(parseFloat(l))){m[j]=l}}}}return m}b.effects.animateClass=function(i,j,m,l){var k=b.speed(j,m,l);return this.queue(function(){var p=b(this),n=p.attr("class")||"",o,q=k.children?p.find("*").andSelf():p;q=q.map(function(){var r=b(this);return{el:r,start:h.call(this)}});o=function(){b.each(f,function(r,s){if(i[s]){p[s+"Class"](i[s])}})};o();q=q.map(function(){this.end=h.call(this.el[0]);this.diff=e(this.start,this.end);return this});p.attr("class",n);q=q.map(function(){var t=this,r=b.Deferred(),s=jQuery.extend({},k,{queue:false,complete:function(){r.resolve(t)}});this.el.animate(this.diff,s);return r.promise()});b.when.apply(b,q.get()).done(function(){o();b.each(arguments,function(){var r=this.el;b.each(this.diff,function(s){r.css(s,"")})});k.complete.call(p[0])})})};b.fn.extend({_addClass:b.fn.addClass,addClass:function(j,i,l,k){return i?b.effects.animateClass.call(this,{add:j},i,l,k):this._addClass(j)},_removeClass:b.fn.removeClass,removeClass:function(j,i,l,k){return i?b.effects.animateClass.call(this,{remove:j},i,l,k):this._removeClass(j)},_toggleClass:b.fn.toggleClass,toggleClass:function(k,j,i,m,l){if(typeof j==="boolean"||j===d){if(!i){return this._toggleClass(k,j)}else{return b.effects.animateClass.call(this,(j?{add:k}:{remove:k}),i,m,l)}}else{return b.effects.animateClass.call(this,{toggle:k},j,i,m)}},switchClass:function(i,k,j,m,l){return b.effects.animateClass.call(this,{add:k,remove:i},j,m,l)}})})();(function(){b.extend(b.effects,{version:"1.9.2",save:function(h,j){for(var g=0;g

      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),g={width:h.width(),height:h.height()},k=document.activeElement;try{k.id}catch(j){k=document.body}h.wrap(l);if(h[0]===k||b.contains(h[0],k)){b(k).focus()}l=h.parent();if(h.css("position")==="static"){l.css({position:"relative"});h.css({position:"relative"})}else{b.extend(i,{position:h.css("position"),zIndex:h.css("z-index")});b.each(["top","left","bottom","right"],function(m,n){i[n]=h.css(n);if(isNaN(parseInt(i[n],10))){i[n]="auto"}});h.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}h.css(g);return l.css(i).show()},removeWrapper:function(g){var h=document.activeElement;if(g.parent().is(".ui-effects-wrapper")){g.parent().replaceWith(g);if(g[0]===h||b.contains(g[0],h)){b(h).focus()}}return g},setTransition:function(h,j,g,i){i=i||{};b.each(j,function(l,k){var m=h.cssUnit(k);if(m[0]>0){i[k]=m[0]*g+m[1]}});return i}});function e(h,g,i,j){if(b.isPlainObject(h)){g=h;h=h.effect}h={effect:h};if(g==null){g={}}if(b.isFunction(g)){j=g;i=null;g={}}if(typeof g==="number"||b.fx.speeds[g]){j=i;i=g;g={}}if(b.isFunction(i)){j=i;i=null}if(g){b.extend(h,g)}i=i||g.duration;h.duration=b.fx.off?0:typeof i==="number"?i:i in b.fx.speeds?b.fx.speeds[i]:b.fx.speeds._default;h.complete=j||g.complete;return h}function f(g){if(!g||typeof g==="number"||b.fx.speeds[g]){return true}if(typeof g==="string"&&!b.effects.effect[g]){if(a&&b.effects[g]){return false}return true}return false}b.fn.extend({effect:function(){var i=e.apply(this,arguments),l=i.mode,g=i.queue,h=b.effects.effect[i.effect],j=!h&&a&&b.effects[i.effect];if(b.fx.off||!(h||j)){if(l){return this[l](i.duration,i.complete)}else{return this.each(function(){if(i.complete){i.complete.call(this)}})}}function k(o){var p=b(this),n=i.complete,q=i.mode;function m(){if(b.isFunction(n)){n.call(p[0])}if(b.isFunction(o)){o()}}if(p.is(":hidden")?q==="hide":q==="show"){m()}else{h.call(p[0],i,m)}}if(h){return g===false?this.each(k):this.queue(g||"fx",k)}else{return j.call(this,{options:i,duration:i.duration,callback:i.complete,mode:i.mode})}},_show:b.fn.show,show:function(h){if(f(h)){return this._show.apply(this,arguments)}else{var g=e.apply(this,arguments);g.mode="show";return this.effect.call(this,g)}},_hide:b.fn.hide,hide:function(h){if(f(h)){return this._hide.apply(this,arguments)}else{var g=e.apply(this,arguments);g.mode="hide";return this.effect.call(this,g)}},__toggle:b.fn.toggle,toggle:function(h){if(f(h)||typeof h==="boolean"||b.isFunction(h)){return this.__toggle.apply(this,arguments)}else{var g=e.apply(this,arguments);g.mode="toggle";return this.effect.call(this,g)}},cssUnit:function(g){var h=this.css(g),i=[];b.each(["em","px","%","pt"],function(j,k){if(h.indexOf(k)>0){i=[parseFloat(h),k]}});return i}})})();(function(){var e={};b.each(["Quad","Cubic","Quart","Quint","Expo"],function(g,f){e[f]=function(h){return Math.pow(h,g+2)}});b.extend(e,{Sine:function(f){return 1-Math.cos(f*Math.PI/2)},Circ:function(f){return 1-Math.sqrt(1-f*f)},Elastic:function(f){return f===0||f===1?f:-Math.pow(2,8*(f-1))*Math.sin(((f-1)*80-7.5)*Math.PI/15)},Back:function(f){return f*f*(3*f-2)},Bounce:function(h){var f,g=4;while(h<((f=Math.pow(2,--g))-1)/11){}return 1/Math.pow(4,3-g)-7.5625*Math.pow((f*3-2)/22-h,2)}});b.each(e,function(g,f){b.easing["easeIn"+g]=f;b.easing["easeOut"+g]=function(h){return 1-f(1-h)};b.easing["easeInOut"+g]=function(h){return h<0.5?f(h*2)/2:1-f(h*-2+2)/2}})})()})(jQuery));(function(b,d){var a=/up|down|vertical/,c=/up|left|vertical|horizontal/;b.effects.effect.blind=function(g,m){var h=b(this),q=["position","top","bottom","left","right","height","width"],n=b.effects.setMode(h,g.mode||"hide"),r=g.direction||"up",j=a.test(r),i=j?"height":"width",p=j?"top":"left",t=c.test(r),l={},s=n==="show",f,e,k;if(h.parent().is(".ui-effects-wrapper")){b.effects.save(h.parent(),q)}else{b.effects.save(h,q)}h.show();f=b.effects.createWrapper(h).css({overflow:"hidden"});e=f[i]();k=parseFloat(f.css(p))||0;l[i]=s?e:0;if(!t){h.css(j?"bottom":"right",0).css(j?"top":"left","auto").css({position:"absolute"});l[p]=s?k:e+k}if(s){f.css(i,0);if(!t){f.css(p,k+e)}}f.animate(l,{duration:g.duration,easing:g.easing,queue:false,complete:function(){if(n==="hide"){h.hide()}b.effects.restore(h,q);b.effects.removeWrapper(h);m()}})}})(jQuery);(function(a,b){a.effects.effect.bounce=function(m,l){var c=a(this),d=["position","top","bottom","left","right","height","width"],k=a.effects.setMode(c,m.mode||"effect"),j=k==="hide",v=k==="show",w=m.direction||"up",e=m.distance,h=m.times||5,x=h*2+(v||j?1:0),u=m.duration/x,p=m.easing,f=(w==="up"||w==="down")?"top":"left",n=(w==="up"||w==="left"),t,g,s,q=c.queue(),r=q.length;if(v||j){d.push("opacity")}a.effects.save(c,d);c.show();a.effects.createWrapper(c);if(!e){e=c[f==="top"?"outerHeight":"outerWidth"]()/3}if(v){s={opacity:1};s[f]=0;c.css("opacity",0).css(f,n?-e*2:e*2).animate(s,u,p)}if(j){e=e/Math.pow(2,h-1)}s={};s[f]=0;for(t=0;t1){q.splice.apply(q,[1,0].concat(q.splice(r,x+1)))}c.dequeue()}})(jQuery);(function(a,b){a.effects.effect.clip=function(f,i){var g=a(this),m=["position","top","bottom","left","right","height","width"],l=a.effects.setMode(g,f.mode||"hide"),p=l==="show",n=f.direction||"vertical",k=n==="vertical",q=k?"height":"width",j=k?"top":"left",h={},d,e,c;a.effects.save(g,m);g.show();d=a.effects.createWrapper(g).css({overflow:"hidden"});e=(g[0].tagName==="IMG")?d:g;c=e[q]();if(p){e.css(q,0);e.css(j,c/2)}h[q]=p?c:0;h[j]=p?0:c/2;e.animate(h,{queue:false,duration:f.duration,easing:f.easing,complete:function(){if(!p){g.hide()}a.effects.restore(g,m);a.effects.removeWrapper(g);i()}})}})(jQuery);(function(a,b){a.effects.effect.drop=function(d,h){var e=a(this),j=["position","top","bottom","left","right","opacity","height","width"],i=a.effects.setMode(e,d.mode||"hide"),l=i==="show",k=d.direction||"left",f=(k==="up"||k==="down")?"top":"left",m=(k==="up"||k==="left")?"pos":"neg",g={opacity:l?1:0},c;a.effects.save(e,j);e.show();a.effects.createWrapper(e);c=d.distance||e[f==="top"?"outerHeight":"outerWidth"](true)/2;if(l){e.css("opacity",0).css(f,m==="pos"?-c:c)}g[f]=(l?(m==="pos"?"+=":"-="):(m==="pos"?"-=":"+="))+c;e.animate(g,{queue:false,duration:d.duration,easing:d.easing,complete:function(){if(i==="hide"){e.hide()}a.effects.restore(e,j);a.effects.removeWrapper(e);h()}})}})(jQuery);(function(a,b){a.effects.effect.explode=function(s,r){var k=s.pieces?Math.round(Math.sqrt(s.pieces)):3,d=k,c=a(this),m=a.effects.setMode(c,s.mode||"hide"),w=m==="show",g=c.show().css("visibility","hidden").offset(),t=Math.ceil(c.outerWidth()/d),q=Math.ceil(c.outerHeight()/k),h=[],v,u,e,p,n,l;function x(){h.push(this);if(h.length===k*d){f()}}for(v=0;v
      ").css({position:"absolute",visibility:"visible",left:-u*t,top:-v*q}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:t,height:q,left:e+(w?n*t:0),top:p+(w?l*q:0),opacity:w?0:1}).animate({left:e+(w?0:n*t),top:p+(w?0:l*q),opacity:w?1:0},s.duration||500,s.easing,x)}}function f(){c.css({visibility:"visible"});a(h).remove();if(!w){c.hide()}r()}}})(jQuery);(function(a,b){a.effects.effect.fade=function(f,c){var d=a(this),e=a.effects.setMode(d,f.mode||"toggle");d.animate({opacity:e},{queue:false,duration:f.duration,easing:f.easing,complete:c})}})(jQuery);(function(a,b){a.effects.effect.fold=function(e,i){var f=a(this),n=["position","top","bottom","left","right","height","width"],k=a.effects.setMode(f,e.mode||"hide"),r=k==="show",l=k==="hide",t=e.size||15,m=/([0-9]+)%/.exec(t),s=!!e.horizFirst,j=r!==s,g=j?["width","height"]:["height","width"],h=e.duration/2,d,c,q={},p={};a.effects.save(f,n);f.show();d=a.effects.createWrapper(f).css({overflow:"hidden"});c=j?[d.width(),d.height()]:[d.height(),d.width()];if(m){t=parseInt(m[1],10)/100*c[l?0:1]}if(r){d.css(s?{height:0,width:t}:{height:t,width:0})}q[g[0]]=r?c[0]:t;p[g[1]]=r?c[1]:0;d.animate(q,h,e.easing).animate(p,h,e.easing,function(){if(l){f.hide()}a.effects.restore(f,n);a.effects.removeWrapper(f);i()})}})(jQuery);(function(a,b){a.effects.effect.highlight=function(h,c){var e=a(this),d=["backgroundImage","backgroundColor","opacity"],g=a.effects.setMode(e,h.mode||"show"),f={backgroundColor:e.css("backgroundColor")};if(g==="hide"){f.opacity=0}a.effects.save(e,d);e.show().css({backgroundImage:"none",backgroundColor:h.color||"#ffff99"}).animate(f,{queue:false,duration:h.duration,easing:h.easing,complete:function(){if(g==="hide"){e.hide()}a.effects.restore(e,d);c()}})}})(jQuery);(function(a,b){a.effects.effect.pulsate=function(c,g){var e=a(this),k=a.effects.setMode(e,c.mode||"show"),p=k==="show",l=k==="hide",q=(p||k==="hide"),m=((c.times||5)*2)+(q?1:0),f=c.duration/m,n=0,j=e.queue(),d=j.length,h;if(p||!e.is(":visible")){e.css("opacity",0).show();n=1}for(h=1;h1){j.splice.apply(j,[1,0].concat(j.splice(d,m+1)))}e.dequeue()}})(jQuery);(function(a,b){a.effects.effect.puff=function(j,c){var h=a(this),i=a.effects.setMode(h,j.mode||"hide"),f=i==="hide",g=parseInt(j.percent,10)||150,e=g/100,d={height:h.height(),width:h.width(),outerHeight:h.outerHeight(),outerWidth:h.outerWidth()};a.extend(j,{effect:"scale",queue:false,fade:true,mode:i,complete:c,percent:f?g:100,from:f?d:{height:d.height*e,width:d.width*e,outerHeight:d.outerHeight*e,outerWidth:d.outerWidth*e}});h.effect(j)};a.effects.effect.scale=function(c,f){var d=a(this),l=a.extend(true,{},c),g=a.effects.setMode(d,c.mode||"effect"),h=parseInt(c.percent,10)||(parseInt(c.percent,10)===0?0:(g==="hide"?0:100)),j=c.direction||"both",k=c.origin,e={height:d.height(),width:d.width(),outerHeight:d.outerHeight(),outerWidth:d.outerWidth()},i={y:j!=="horizontal"?(h/100):1,x:j!=="vertical"?(h/100):1};l.effect="size";l.queue=false;l.complete=f;if(g!=="effect"){l.origin=k||["middle","center"];l.restore=true}l.from=c.from||(g==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:e);l.to={height:e.height*i.y,width:e.width*i.x,outerHeight:e.outerHeight*i.y,outerWidth:e.outerWidth*i.x};if(l.fade){if(g==="show"){l.from.opacity=0;l.to.opacity=1}if(g==="hide"){l.from.opacity=1;l.to.opacity=0}}d.effect(l)};a.effects.effect.size=function(l,k){var q,i,j,c=a(this),p=["position","top","bottom","left","right","width","height","overflow","opacity"],n=["position","top","bottom","left","right","overflow","opacity"],m=["width","height","overflow"],g=["fontSize"],s=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],h=a.effects.setMode(c,l.mode||"effect"),r=l.restore||h!=="effect",v=l.scale||"both",t=l.origin||["middle","center"],u=c.css("position"),e=r?p:n,f={height:0,width:0,outerHeight:0,outerWidth:0};if(h==="show"){c.show()}q={height:c.height(),width:c.width(),outerHeight:c.outerHeight(),outerWidth:c.outerWidth()};if(l.mode==="toggle"&&h==="show"){c.from=l.to||f;c.to=l.from||q}else{c.from=l.from||(h==="show"?f:q);c.to=l.to||(h==="hide"?f:q)}j={from:{y:c.from.height/q.height,x:c.from.width/q.width},to:{y:c.to.height/q.height,x:c.to.width/q.width}};if(v==="box"||v==="both"){if(j.from.y!==j.to.y){e=e.concat(s);c.from=a.effects.setTransition(c,s,j.from.y,c.from);c.to=a.effects.setTransition(c,s,j.to.y,c.to)}if(j.from.x!==j.to.x){e=e.concat(d);c.from=a.effects.setTransition(c,d,j.from.x,c.from);c.to=a.effects.setTransition(c,d,j.to.x,c.to)}}if(v==="content"||v==="both"){if(j.from.y!==j.to.y){e=e.concat(g).concat(m);c.from=a.effects.setTransition(c,g,j.from.y,c.from);c.to=a.effects.setTransition(c,g,j.to.y,c.to)}}a.effects.save(c,e);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(t){i=a.effects.getBaseline(t,q);c.from.top=(q.outerHeight-c.outerHeight())*i.y;c.from.left=(q.outerWidth-c.outerWidth())*i.x;c.to.top=(q.outerHeight-c.to.outerHeight)*i.y;c.to.left=(q.outerWidth-c.to.outerWidth)*i.x}c.css(c.from);if(v==="content"||v==="both"){s=s.concat(["marginTop","marginBottom"]).concat(g);d=d.concat(["marginLeft","marginRight"]);m=p.concat(s).concat(d);c.find("*[width]").each(function(){var w=a(this),o={height:w.height(),width:w.width(),outerHeight:w.outerHeight(),outerWidth:w.outerWidth()};if(r){a.effects.save(w,m)}w.from={height:o.height*j.from.y,width:o.width*j.from.x,outerHeight:o.outerHeight*j.from.y,outerWidth:o.outerWidth*j.from.x};w.to={height:o.height*j.to.y,width:o.width*j.to.x,outerHeight:o.height*j.to.y,outerWidth:o.width*j.to.x};if(j.from.y!==j.to.y){w.from=a.effects.setTransition(w,s,j.from.y,w.from);w.to=a.effects.setTransition(w,s,j.to.y,w.to)}if(j.from.x!==j.to.x){w.from=a.effects.setTransition(w,d,j.from.x,w.from);w.to=a.effects.setTransition(w,d,j.to.x,w.to)}w.css(w.from);w.animate(w.to,l.duration,l.easing,function(){if(r){a.effects.restore(w,m)}})})}c.animate(c.to,{queue:false,duration:l.duration,easing:l.easing,complete:function(){if(c.to.opacity===0){c.css("opacity",c.from.opacity)}if(h==="hide"){c.hide()}a.effects.restore(c,e);if(!r){if(u==="static"){c.css({position:"relative",top:c.to.top,left:c.to.left})}else{a.each(["top","left"],function(o,w){c.css(w,function(y,A){var z=parseInt(A,10),x=o?c.to.left:c.to.top;if(A==="auto"){return x+"px"}return z+x+"px"})})}}a.effects.removeWrapper(c);k()}})}})(jQuery);(function(a,b){a.effects.effect.shake=function(l,k){var c=a(this),d=["position","top","bottom","left","right","height","width"],j=a.effects.setMode(c,l.mode||"effect"),u=l.direction||"left",e=l.distance||20,h=l.times||3,v=h*2+1,q=Math.round(l.duration/v),g=(u==="up"||u==="down")?"top":"left",f=(u==="up"||u==="left"),t={},s={},r={},p,m=c.queue(),n=m.length;a.effects.save(c,d);c.show();a.effects.createWrapper(c);t[g]=(f?"-=":"+=")+e;s[g]=(f?"+=":"-=")+e*2;r[g]=(f?"-=":"+=")+e*2;c.animate(t,q,l.easing);for(p=1;p1){m.splice.apply(m,[1,0].concat(m.splice(n,v+1)))}c.dequeue()}})(jQuery);(function(a,b){a.effects.effect.slide=function(e,i){var f=a(this),k=["position","top","bottom","left","right","width","height"],j=a.effects.setMode(f,e.mode||"show"),m=j==="show",l=e.direction||"left",g=(l==="up"||l==="down")?"top":"left",d=(l==="up"||l==="left"),c,h={};a.effects.save(f,k);f.show();c=e.distance||f[g==="top"?"outerHeight":"outerWidth"](true);a.effects.createWrapper(f).css({overflow:"hidden"});if(m){f.css(g,d?(isNaN(c)?"-"+c:-c):c)}h[g]=(m?(d?"+=":"-="):(d?"-=":"+="))+c;f.animate(h,{queue:false,duration:e.duration,easing:e.easing,complete:function(){if(j==="hide"){f.hide()}a.effects.restore(f,k);a.effects.removeWrapper(f);i()}})}})(jQuery);(function(a,b){a.effects.effect.transfer=function(d,h){var f=a(this),k=a(d.to),n=k.css("position")==="fixed",j=a("body"),l=n?j.scrollTop():0,m=n?j.scrollLeft():0,c=k.offset(),g={top:c.top-l,left:c.left-m,height:k.innerHeight(),width:k.innerWidth()},i=f.offset(),e=a('
      ').appendTo(document.body).addClass(d.className).css({top:i.top-l,left:i.left-m,height:f.innerHeight(),width:f.innerWidth(),position:n?"fixed":"absolute"}).animate(g,d.duration,d.easing,function(){e.remove();h()})}})(jQuery); \ No newline at end of file diff --git a/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js b/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js new file mode 100644 index 000000000..55f9dc859 --- /dev/null +++ b/phpmyadmin/js/jquery/jquery-ui-timepicker-addon.js @@ -0,0 +1 @@ +(function($){$.ui.timepicker=$.ui.timepicker||{};if($.ui.timepicker.version){return}$.extend($.ui,{timepicker:{version:"1.1.1"}});function Timepicker(){this.regional=[];this.regional[""]={currentText:"Now",closeText:"Done",amNames:["AM","A"],pmNames:["PM","P"],timeFormat:"HH:mm",timeSuffix:"",timeOnlyTitle:"Choose Time",timeText:"Time",hourText:"Hour",minuteText:"Minute",secondText:"Second",millisecText:"Millisecond",timezoneText:"Time Zone",isRTL:false};this._defaults={showButtonPanel:true,timeOnly:false,showHour:true,showMinute:true,showSecond:false,showMillisec:false,showTimezone:false,showTime:true,stepHour:1,stepMinute:1,stepSecond:1,stepMillisec:1,hour:0,minute:0,second:0,millisec:0,timezone:null,useLocalTimezone:false,defaultTimezone:"+0000",hourMin:0,minuteMin:0,secondMin:0,millisecMin:0,hourMax:23,minuteMax:59,secondMax:59,millisecMax:999,minDateTime:null,maxDateTime:null,onSelect:null,hourGrid:0,minuteGrid:0,secondGrid:0,millisecGrid:0,alwaysSetTime:true,separator:" ",altFieldTimeOnly:true,altTimeFormat:null,altSeparator:null,altTimeSuffix:null,pickerTimeFormat:null,pickerTimeSuffix:null,showTimepicker:true,timezoneIso8601:false,timezoneList:null,addSliderAccess:false,sliderAccessArgs:null,controlType:"slider",defaultValue:null,parse:"strict"};$.extend(this._defaults,this.regional[""])}$.extend(Timepicker.prototype,{$input:null,$altInput:null,$timeObj:null,inst:null,hour_slider:null,minute_slider:null,second_slider:null,millisec_slider:null,timezone_select:null,hour:0,minute:0,second:0,millisec:0,timezone:null,defaultTimezone:"+0000",hourMinOriginal:null,minuteMinOriginal:null,secondMinOriginal:null,millisecMinOriginal:null,hourMaxOriginal:null,minuteMaxOriginal:null,secondMaxOriginal:null,millisecMaxOriginal:null,ampm:"",formattedDate:"",formattedTime:"",formattedDateTime:"",timezoneList:null,units:["hour","minute","second","millisec"],control:null,setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_newInst:function($input,o){var tp_inst=new Timepicker(),inlineSettings={},fns={},overrides,i;for(var attrName in this._defaults){if(this._defaults.hasOwnProperty(attrName)){var attrValue=$input.attr("time:"+attrName);if(attrValue){try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}}overrides={beforeShow:function(input,dp_inst){if($.isFunction(tp_inst._defaults.evnts.beforeShow)){return tp_inst._defaults.evnts.beforeShow.call($input[0],input,dp_inst,tp_inst)}},onChangeMonthYear:function(year,month,dp_inst){tp_inst._updateDateTime(dp_inst);if($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)){tp_inst._defaults.evnts.onChangeMonthYear.call($input[0],year,month,dp_inst,tp_inst)}},onClose:function(dateText,dp_inst){if(tp_inst.timeDefined===true&&$input.val()!==""){tp_inst._updateDateTime(dp_inst)}if($.isFunction(tp_inst._defaults.evnts.onClose)){tp_inst._defaults.evnts.onClose.call($input[0],dateText,dp_inst,tp_inst)}}};for(i in overrides){if(overrides.hasOwnProperty(i)){fns[i]=o[i]||null}}tp_inst._defaults=$.extend({},this._defaults,inlineSettings,o,overrides,{evnts:fns,timepicker:tp_inst});tp_inst.amNames=$.map(tp_inst._defaults.amNames,function(val){return val.toUpperCase()});tp_inst.pmNames=$.map(tp_inst._defaults.pmNames,function(val){return val.toUpperCase()});if(typeof(tp_inst._defaults.controlType)==="string"){if($.fn[tp_inst._defaults.controlType]===undefined){tp_inst._defaults.controlType="select"}tp_inst.control=tp_inst._controls[tp_inst._defaults.controlType]}else{tp_inst.control=tp_inst._defaults.controlType}if(tp_inst._defaults.timezoneList===null){var timezoneList=["-1200","-1100","-1000","-0930","-0900","-0800","-0700","-0600","-0500","-0430","-0400","-0330","-0300","-0200","-0100","+0000","+0100","+0200","+0300","+0330","+0400","+0430","+0500","+0530","+0545","+0600","+0630","+0700","+0800","+0845","+0900","+0930","+1000","+1030","+1100","+1130","+1200","+1245","+1300","+1400"];if(tp_inst._defaults.timezoneIso8601){timezoneList=$.map(timezoneList,function(val){return val=="+0000"?"Z":(val.substring(0,3)+":"+val.substring(3))})}tp_inst._defaults.timezoneList=timezoneList}tp_inst.timezone=tp_inst._defaults.timezone;tp_inst.hour=tp_inst._defaults.hour;tp_inst.minute=tp_inst._defaults.minute;tp_inst.second=tp_inst._defaults.second;tp_inst.millisec=tp_inst._defaults.millisec;tp_inst.ampm="";tp_inst.$input=$input;if(o.altField){tp_inst.$altInput=$(o.altField).css({cursor:"pointer"}).focus(function(){$input.trigger("focus")})}if(tp_inst._defaults.minDate===0||tp_inst._defaults.minDateTime===0){tp_inst._defaults.minDate=new Date()}if(tp_inst._defaults.maxDate===0||tp_inst._defaults.maxDateTime===0){tp_inst._defaults.maxDate=new Date()}if(tp_inst._defaults.minDate!==undefined&&tp_inst._defaults.minDate instanceof Date){tp_inst._defaults.minDateTime=new Date(tp_inst._defaults.minDate.getTime())}if(tp_inst._defaults.minDateTime!==undefined&&tp_inst._defaults.minDateTime instanceof Date){tp_inst._defaults.minDate=new Date(tp_inst._defaults.minDateTime.getTime())}if(tp_inst._defaults.maxDate!==undefined&&tp_inst._defaults.maxDate instanceof Date){tp_inst._defaults.maxDateTime=new Date(tp_inst._defaults.maxDate.getTime())}if(tp_inst._defaults.maxDateTime!==undefined&&tp_inst._defaults.maxDateTime instanceof Date){tp_inst._defaults.maxDate=new Date(tp_inst._defaults.maxDateTime.getTime())}tp_inst.$input.bind("focus",function(){tp_inst._onFocus()});return tp_inst},_addTimePicker:function(dp_inst){var currDT=(this.$altInput&&this._defaults.altFieldTimeOnly)?this.$input.val()+" "+this.$altInput.val():this.$input.val();this.timeDefined=this._parseTime(currDT);this._limitMinMaxDateTime(dp_inst,false);this._injectTimePicker()},_parseTime:function(timeString,withDate){if(!this.inst){this.inst=$.datepicker._getInst(this.$input[0])}if(withDate||!this._defaults.timeOnly){var dp_dateFormat=$.datepicker._get(this.inst,"dateFormat");try{var parseRes=parseDateTimeInternal(dp_dateFormat,this._defaults.timeFormat,timeString,$.datepicker._getFormatConfig(this.inst),this._defaults);if(!parseRes.timeObj){return false}$.extend(this,parseRes.timeObj)}catch(err){$.datepicker.log("Error parsing the date/time string: "+err+"\ndate/time string = "+timeString+"\ntimeFormat = "+this._defaults.timeFormat+"\ndateFormat = "+dp_dateFormat);return false}return true}else{var timeObj=$.datepicker.parseTime(this._defaults.timeFormat,timeString,this._defaults);if(!timeObj){return false}$.extend(this,timeObj);return true}},_injectTimePicker:function(){var $dp=this.inst.dpDiv,o=this.inst.settings,tp_inst=this,litem="",uitem="",max={},gridSize={},size=null;if($dp.find("div.ui-timepicker-div").length===0&&o.showTimepicker){var noDisplay=' style="display:none;"',html='
      "+o.timeText+'
      ";for(var i=0,l=this.units.length;i"+o[litem+"Text"]+'
      ";if(o["show"+uitem]&&o[litem+"Grid"]>0){html+='
      ';if(litem=="hour"){for(var h=o[litem+"Min"];h<=max[litem];h+=parseInt(o[litem+"Grid"],10)){gridSize[litem]++;var tmph=$.datepicker.formatTime(useAmpm(o.pickerTimeFormat||o.timeFormat)?"hht":"HH",{hour:h},o);html+='"}}else{for(var m=o[litem+"Min"];m<=max[litem];m+=parseInt(o[litem+"Grid"],10)){gridSize[litem]++;html+='"}}html+="
      '+tmph+"'+((m<10)?"0":"")+m+"
      "}html+="
      "}html+='
      "+o.timezoneText+"
      ";html+='
      ";html+="
      ";var $tp=$(html);if(o.timeOnly===true){$tp.prepend('
      '+o.timeOnlyTitle+"
      ");$dp.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()}for(var i=0,l=tp_inst.units.length;i0){size=100*gridSize[litem]*o[litem+"Grid"]/(max[litem]-o[litem+"Min"]);$tp.find(".ui_tpicker_"+litem+" table").css({width:size+"%",marginLeft:o.isRTL?"0":((size/(-2*gridSize[litem]))+"%"),marginRight:o.isRTL?((size/(-2*gridSize[litem]))+"%"):"0",borderCollapse:"collapse"}).find("td").click(function(e){var $t=$(this),h=$t.html(),n=parseInt(h.replace(/[^0-9]/g),10),ap=h.replace(/[^apm]/ig),f=$t.data("for");if(f=="hour"){if(ap.indexOf("p")!==-1&&n<12){n+=12}else{if(ap.indexOf("a")!==-1&&n===12){n=0}}}tp_inst.control.value(tp_inst,tp_inst[f+"_slider"],litem,n);tp_inst._onTimeChange();tp_inst._onSelectHandler()}).css({cursor:"pointer",width:(100/gridSize[litem])+"%",textAlign:"center",overflow:"hidden"})}}this.timezone_select=$tp.find(".ui_tpicker_timezone").append("").find("select");$.fn.append.apply(this.timezone_select,$.map(o.timezoneList,function(val,idx){return $("
      '; + $retval .= '
      '; + $retval .= '
      '; + } + + return $retval; + } +} +?> diff --git a/phpmyadmin/libraries/navigation/NavigationHeader.class.php b/phpmyadmin/libraries/navigation/NavigationHeader.class.php new file mode 100644 index 000000000..b1513d2c0 --- /dev/null +++ b/phpmyadmin/libraries/navigation/NavigationHeader.class.php @@ -0,0 +1,298 @@ + true + ) + ); + $class = ' class="list_container'; + if ($GLOBALS['cfg']['NavigationTreePointerEnable']) { + $class .= ' highlight'; + } + $class .= '"'; + $buffer = '
      '; + $buffer .= '
      '; + $buffer .= '
      '; + $buffer .= '
      '; + $buffer .= sprintf( + '', + $link_url + ); + $buffer .= $this->_logo(); + $buffer .= $this->_links(); + $buffer .= $this->_serverChoice(); + $buffer .= $this->_recent(); + $buffer .= PMA_Util::getImage( + 'ajax_clock_small.gif', + __('Loading'), + array('style' => 'visibility: hidden;', 'class' => 'throbber') + ); + $buffer .= '
      '; + return $buffer; + } + + /** + * Create the code for displaying the phpMyAdmin + * logo based on configuration settings + * + * @return string HTML code for the logo + */ + private function _logo() + { + $retval = ''; + // display Logo, depending on $GLOBALS['cfg']['NavigationDisplayLogo'] + if ($GLOBALS['cfg']['NavigationDisplayLogo']) { + $logo = 'phpMyAdmin'; + if (@file_exists($GLOBALS['pmaThemeImage'] . 'logo_left.png')) { + $logo = ''; + } elseif (@file_exists($GLOBALS['pmaThemeImage'] . 'pma_logo2.png')) { + $logo = ''; + } + $retval .= '"; + } + } + } + if ($node->hasSiblings() || isset($_REQUEST['results'])) { + $retval .= ""; + } + return $retval; + } + + /** + * Makes some nodes visible based on the which node is active + * + * @return nothing + */ + private function _setVisibility() + { + foreach ($this->_vPath as $path) { + $node = $this->_tree; + foreach ($path as $value) { + $child = $node->getChild($value); + if ($child !== false) { + $child->visible = true; + $node = $child; + } + } + } + } + + /** + * Generates the HTML code for displaying the fast filter for tables + * + * @param Node $node The node for which to generate the fast filter html + * + * @return string LI element used for the fast filter + */ + private function _fastFilterHtml($node) + { + $retval = ''; + if ($node === $this->_tree + && $this->_tree->getPresence() >= (int)$GLOBALS['cfg']['NavigationTreeDisplayDbFilterMinimum'] + ) { + $url_params = array( + 'pos' => 0 + ); + $retval .= "
        "; + $retval .= "
      • "; + $retval .= "
        "; + $retval .= PMA_getHiddenFields($url_params); + $retval .= ""; + $retval .= "X"; + $retval .= "
        "; + $retval .= "
      • "; + $retval .= "
      "; + } else if (($node->type == Node::CONTAINER + && ( $node->real_name == 'tables' + || $node->real_name == 'views' + || $node->real_name == 'functions' + || $node->real_name == 'procedures' + || $node->real_name == 'events') + ) + && $node->realParent()->getPresence($node->real_name) >= (int)$GLOBALS['cfg']['NavigationTreeDisplayItemFilterMinimum'] + ) { + $paths = $node->getPaths(); + $url_params = array( + 'pos' => $this->_pos, + 'aPath' => $paths['aPath'], + 'vPath' => $paths['vPath'], + 'pos2_name' => $node->real_name, + 'pos2_value' => 0 + ); + $retval .= "
    • "; + $retval .= "
      "; + $retval .= PMA_getHiddenFields($url_params); + $retval .= ""; + $retval .= "X"; + $retval .= "
      "; + $retval .= "
    • "; + } + return $retval; + } + + /** + * Generates the HTML code for displaying the list pagination + * + * @param Node $node The node for whose children the page + * selector will be created + * + * @return string + */ + private function _getPageSelector($node) + { + $retval = ''; + if ($node === $this->_tree) { + $retval .= PMA_Util::getListNavigator( + $this->_tree->getPresence('databases', $this->_searchClause), + $this->_pos, + array('server' => $GLOBALS['server']), + 'navigation.php', + 'frame_navigation', + $GLOBALS['cfg']['MaxNavigationItems'], + 'pos', + array('dbselector') + ); + } else if ($node->type == Node::CONTAINER && ! $node->is_group) { + $paths = $node->getPaths(); + + $level = isset($paths['aPath_clean'][4]) ? 3 : 2; + $_url_params = array( + 'aPath' => $paths['aPath'], + 'vPath' => $paths['vPath'], + 'pos' => $this->_pos, + 'server' => $GLOBALS['server'], + 'pos2_name' => $paths['aPath_clean'][2] + ); + if ($level == 3) { + $pos = $node->pos3; + $_url_params['pos2_value'] = $node->pos2; + $_url_params['pos3_name'] = $paths['aPath_clean'][4]; + } else { + $pos = $node->pos2; + } + $num = $node->realParent()->getPresence( + $node->real_name, + $this->_searchClause2 + ); + $retval .= PMA_Util::getListNavigator( + $num, + $pos, + $_url_params, + 'navigation.php', + 'frame_navigation', + $GLOBALS['cfg']['MaxNavigationItems'], + 'pos' . $level . '_value' + ); + } + return $retval; + } + + /** + * Called by usort() for sorting the nodes in a container + * + * @param Node $a The first element used in the comparison + * @param Node $b The second element used in the comparison + * + * @return int See strnatcmp() and strcmp() + */ + static public function sortNode($a, $b) + { + if ($a->isNew) { + return -1; + } else if ($b->isNew) { + return 1; + } + if ($GLOBALS['cfg']['NaturalOrder']) { + return strnatcasecmp($a->name, $b->name); + } else { + return strcasecmp($a->name, $b->name); + } + } +} +?> diff --git a/phpmyadmin/libraries/navigation/NodeFactory.class.php b/phpmyadmin/libraries/navigation/NodeFactory.class.php new file mode 100644 index 000000000..7d8106af9 --- /dev/null +++ b/phpmyadmin/libraries/navigation/NodeFactory.class.php @@ -0,0 +1,97 @@ + diff --git a/phpmyadmin/libraries/navigation/Nodes/Node.class.php b/phpmyadmin/libraries/navigation/Nodes/Node.class.php new file mode 100644 index 000000000..a1f0e3b44 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node.class.php @@ -0,0 +1,455 @@ +name = $name; + $this->real_name = $name; + } + if ($type === Node::CONTAINER) { + $this->type = Node::CONTAINER; + } + $this->is_group = (bool)$is_group; + } + + /** + * Adds a child node to this node + * + * @param Node $child A child node + * + * @return nothing + */ + public function addChild($child) + { + $this->children[] = $child; + $child->parent = $this; + } + + /** + * Returns a child node given it's name + * + * @param string $name The name of requested child + * @param bool $real_name Whether to use the "real_name" + * instead of "name" in comparisons + * + * @return false|Node The requested child node or false, + * if the requested node cannot be found + */ + public function getChild($name, $real_name = false) + { + if ($real_name) { + foreach ($this->children as $child) { + if ($child->real_name == $name) { + return $child; + } + } + } else { + foreach ($this->children as $child) { + if ($child->name == $name) { + return $child; + } + } + } + return false; + } + + /** + * Removes a child node from this node + * + * @param string $name The name of child to be removed + * + * @return nothing + */ + public function removeChild($name) + { + foreach ($this->children as $key => $child) { + if ($child->name == $name) { + unset($this->children[$key]); + break; + } + } + } + + /** + * Retreives the parents for a node + * + * @param bool $self Whether to include the Node itself in the results + * @param bool $containers Whether to include nodes of type CONTAINER + * @param bool $groups Whether to include nodes which have $group == true + * + * @return array An array of parent Nodes + */ + public function parents($self = false, $containers = false, $groups = false) + { + $parents = array(); + if ($self + && ($this->type != Node::CONTAINER || $containers) + && ($this->is_group != true || $groups) + ) { + $parents[] = $this; + $self = false; + } + $parent = $this->parent; + while (isset($parent)) { + if ( ($parent->type != Node::CONTAINER || $containers) + && ($parent->is_group != true || $groups) + ) { + $parents[] = $parent; + } + $parent = $parent->parent; + } + return $parents; + } + + /** + * Returns the actual parent of a node. If used twice on an index or columns + * node, it will return the table and database nodes. The names of the returned + * nodes can be used in SQL queries, etc... + * + * @return Node + */ + public function realParent() + { + $retval = $this->parents(); + if (count($retval) > 0) { + return $retval[0]; + } else { + return false; + } + } + + /** + * This function checks if the node has children nodes associated with it + * + * @param bool $count_empty_containers Whether to count empty child + * containers as valid children + * + * @return bool Whether the node has child nodes + */ + public function hasChildren($count_empty_containers = true) + { + $retval = false; + if ($count_empty_containers) { + if (count($this->children)) { + $retval = true; + } + } else { + foreach ($this->children as $child) { + if ($child->type == Node::OBJECT || $child->hasChildren(false)) { + $retval = true; + break; + } + } + } + return $retval; + } + + /** + * Returns true the node has some siblings (other nodes on the same tree level, + * in the same branch), false otherwise. The only exception is for nodes on + * the third level of the tree (columns and indexes), for which the function + * always returns true. This is because we want to render the containers + * for these nodes + * + * @return bool + */ + public function hasSiblings() + { + $retval = false; + $paths = $this->getPaths(); + if (count($paths['aPath_clean']) > 3) { + $retval = true; + } else { + foreach ($this->parent->children as $child) { + if ($child != $this + && ($child->type == Node::OBJECT || $child->hasChildren(false)) + ) { + $retval = true; + break; + } + } + } + return $retval; + } + + /** + * Returns the number of child nodes that a node has associated with it + * + * @return int The number of children nodes + */ + public function numChildren() + { + $retval = 0; + foreach ($this->children as $child) { + if ($child->type == Node::OBJECT) { + $retval++; + } else { + $retval += $child->numChildren(); + } + } + return $retval; + } + + /** + * Returns the actual path and the virtual paths for a node + * both as clean arrays and base64 encoded strings + * + * @return array + */ + public function getPaths() + { + $aPath = array(); + $aPath_clean = array(); + foreach ($this->parents(true, true, false) as $parent) { + $aPath[] = base64_encode($parent->real_name); + $aPath_clean[] = $parent->real_name; + } + $aPath = implode('.', array_reverse($aPath)); + $aPath_clean = array_reverse($aPath_clean); + + $vPath = array(); + $vPath_clean = array(); + foreach ($this->parents(true, true, true) as $parent) { + $vPath[] = base64_encode($parent->name); + $vPath_clean[] = $parent->name; + } + $vPath = implode('.', array_reverse($vPath)); + $vPath_clean = array_reverse($vPath_clean); + + return array( + 'aPath' => $aPath, + 'aPath_clean' => $aPath_clean, + 'vPath' => $vPath, + 'vPath_clean' => $vPath_clean + ); + } + + /** + * Returns the names of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('tables', 'views', etc) + * @param int $pos The offset of the list within the results + * @param string $searchClause A string used to filter the results of the query + * + * @return array + */ + public function getData($type, $pos, $searchClause = '') + { + // @todo obey the DisableIS directive + $query = "SELECT `SCHEMA_NAME` "; + $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $query .= $this->_getWhereClause($searchClause); + $query .= "ORDER BY `SCHEMA_NAME` ASC "; + $query .= "LIMIT $pos, {$GLOBALS['cfg']['MaxNavigationItems']}"; + return PMA_DBI_fetch_result($query); + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + return ''; + } + + /** + * Returns the number of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('tables', 'views', etc) + * @param string $searchClause A string used to filter the results of the query + * + * @return int + */ + public function getPresence($type = '', $searchClause = '') + { + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` "; + $query .= $this->_getWhereClause($searchClause); + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $query = "SHOW DATABASES "; + if (! empty($searchClause)) { + $query .= "LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%' "; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + return $retval; + } + + /** + * Returns the WHERE clause depending on the $searchClause parameter + * and the hide_db directive + * + * @param string $searchClause A string used to filter the results of the query + * + * @return string + */ + private function _getWhereClause($searchClause = '') + { + $whereClause = "WHERE TRUE "; + if (! empty($searchClause)) { + $whereClause .= "AND `SCHEMA_NAME` LIKE '%"; + $whereClause .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $whereClause .= "%' "; + } + + if (! empty($GLOBALS['cfg']['Server']['hide_db'])) { + $whereClause .= "AND `SCHEMA_NAME` NOT REGEXP '" + . $GLOBALS['cfg']['Server']['hide_db'] . "' "; + } + + if (! empty($GLOBALS['cfg']['Server']['only_db'])) { + if (is_string($GLOBALS['cfg']['Server']['only_db'])) { + $GLOBALS['cfg']['Server']['only_db'] = array( + $GLOBALS['cfg']['Server']['only_db'] + ); + } + $whereClause .= "AND ("; + $subClauses = array(); + foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) { + $subClauses[] = " `SCHEMA_NAME` LIKE '" + . $each_only_db . "' "; + } + $whereClause .= implode("OR", $subClauses) . ")"; + } + return $whereClause; + } + +} +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php new file mode 100644 index 000000000..9c663e7ad --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Column.class.php @@ -0,0 +1,71 @@ +icon = PMA_Util::getImage('pause.png', ''); + $this->links = array( + 'text' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s&field=%1$s' + . '&change_column=1' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s&field=%1$s' + . '&change_column=1' + . '&token=' . $GLOBALS['token'] + ); + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + $db = PMA_Util::sqlAddSlashes( + $this->realParent()->realParent()->real_name + ); + $table = PMA_Util::sqlAddSlashes( + $this->realParent()->real_name + ); + $column = PMA_Util::sqlAddSlashes( + $this->real_name + ); + $query = "SELECT `COLUMN_COMMENT` "; + $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_NAME`='$table' "; + $query .= "AND `COLUMN_NAME`='$column' "; + return PMA_DBI_fetch_value($query); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php new file mode 100644 index 000000000..1ae57a8f7 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Column_Container.class.php @@ -0,0 +1,56 @@ +icon = PMA_Util::getImage('pause.png', ''); + $this->links = array( + 'text' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&token=' . $GLOBALS['token'], + ); + $this->real_name = 'columns'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new column', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_column_add.png', ''); + $new->links = array( + 'text' => 'tbl_addfield.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s' + . '&field_where=last&after_field=' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_addfield.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s' + . '&field_where=last&after_field=' + . '&token=' . $GLOBALS['token'], + ); + $new->classes = 'new_column italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php new file mode 100644 index 000000000..5c0815f40 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Database.class.php @@ -0,0 +1,447 @@ +icon = PMA_Util::getImage('s_db.png'); + $this->links = array( + 'text' => $GLOBALS['cfg']['DefaultTabDatabase'] + . '?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_operations.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'] + ); + } + + /** + * Returns the number of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('tables', 'views', etc) + * @param string $searchClause A string used to filter the results of the query + * + * @return int + */ + public function getPresence($type = '', $searchClause = '') + { + $retval = 0; + $db = $this->real_name; + switch ($type) { + case 'tables': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_TYPE`='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND `TABLE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $query = "SHOW FULL TABLES FROM "; + $query .= PMA_Util::backquote($db); + $query .= " WHERE `Table_type`='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND " . PMA_Util::backquote( + "Tables_in_" . $db + ); + $query .= " LIKE '%" . PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + case 'views': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_TYPE`!='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND `TABLE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $query = "SHOW FULL TABLES FROM "; + $query .= PMA_Util::backquote($db); + $query .= " WHERE `Table_type`!='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND " . PMA_Util::backquote( + "Tables_in_" . $db + ); + $query .= " LIKE '%" . PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + case 'procedures': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db'"; + $query .= "AND `ROUTINE_TYPE`='PROCEDURE' "; + if (! empty($searchClause)) { + $query .= "AND `ROUTINE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + case 'functions': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db' "; + $query .= "AND `ROUTINE_TYPE`='FUNCTION' "; + if (! empty($searchClause)) { + $query .= "AND `ROUTINE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SHOW FUNCTION STATUS WHERE `Db`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + case 'events': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` "; + $query .= "WHERE `EVENT_SCHEMA`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `EVENT_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::backquote($db); + $query = "SHOW EVENTS FROM $db "; + if (! empty($searchClause)) { + $query .= "WHERE `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + default: + break; + } + return $retval; + } + + /** + * Returns the names of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('tables', 'views', etc) + * @param int $pos The offset of the list within the results + * @param string $searchClause A string used to filter the results of the query + * + * @return array + */ + public function getData($type, $pos, $searchClause = '') + { + $maxItems = $GLOBALS['cfg']['MaxNavigationItems']; + $retval = array(); + $db = $this->real_name; + switch ($type) { + case 'tables': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `TABLE_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_TYPE`='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND `TABLE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $query .= "ORDER BY `TABLE_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $query = " SHOW FULL TABLES FROM "; + $query .= PMA_Util::backquote($db); + $query .= " WHERE `Table_type`='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND " . PMA_Util::backquote( + "Tables_in_" . $db + ); + $query .= " LIKE '%" . PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr[0]; + $count++; + } + $pos--; + } + } + } + break; + case 'views': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `TABLE_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_TYPE`!='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND `TABLE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $query .= "ORDER BY `TABLE_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $query = "SHOW FULL TABLES FROM "; + $query .= PMA_Util::backquote($db); + $query .= " WHERE `Table_type`!='BASE TABLE' "; + if (! empty($searchClause)) { + $query .= "AND " . PMA_Util::backquote( + "Tables_in_" . $db + ); + $query .= " LIKE '%" . PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr[0]; + $count++; + } + $pos--; + } + } + } + break; + case 'procedures': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `ROUTINE_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db'"; + $query .= "AND `ROUTINE_TYPE`='PROCEDURE' "; + if (! empty($searchClause)) { + $query .= "AND `ROUTINE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $query .= "ORDER BY `ROUTINE_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Name']; + $count++; + } + $pos--; + } + } + } + break; + case 'functions': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `ROUTINE_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db' "; + $query .= "AND `ROUTINE_TYPE`='FUNCTION' "; + if (! empty($searchClause)) { + $query .= "AND `ROUTINE_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $query .= "ORDER BY `ROUTINE_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SHOW FUNCTION STATUS WHERE `Db`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Name']; + $count++; + } + $pos--; + } + } + } + break; + case 'events': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `EVENT_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` "; + $query .= "WHERE `EVENT_SCHEMA`='$db' "; + if (! empty($searchClause)) { + $query .= "AND `EVENT_NAME` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $query .= "ORDER BY `EVENT_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $db = PMA_Util::backquote($db); + $query = "SHOW EVENTS FROM $db "; + if (! empty($searchClause)) { + $query .= "WHERE `Name` LIKE '%"; + $query .= PMA_Util::sqlAddSlashes( + $searchClause, true + ); + $query .= "%'"; + } + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Name']; + $count++; + } + $pos--; + } + } + } + break; + default: + break; + } + return $retval; + } + + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + return PMA_getDbComment($this->real_name); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php new file mode 100644 index 000000000..5b8299960 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Event.class.php @@ -0,0 +1,66 @@ +icon = PMA_Util::getImage('b_events.png'); + $this->links = array( + 'text' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&edit_item=1' + . '&token=' . $GLOBALS['token'], + 'icon' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&export_item=1' + . '&token=' . $GLOBALS['token'] + ); + $this->classes = 'event'; + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + $db = PMA_Util::sqlAddSlashes( + $this->realParent()->real_name + ); + $event = PMA_Util::sqlAddSlashes( + $this->real_name + ); + $query = "SELECT `EVENT_COMMENT` "; + $query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` "; + $query .= "WHERE `EVENT_SCHEMA`='$db' "; + $query .= "AND `EVENT_NAME`='$event' "; + return PMA_DBI_fetch_value($query); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php new file mode 100644 index 000000000..16bdd0019 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Event_Container.class.php @@ -0,0 +1,52 @@ +icon = PMA_Util::getImage('b_events.png', ''); + $this->links = array( + 'text' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + ); + $this->real_name = 'events'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new event', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_event_add.png', ''); + $new->links = array( + 'text' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1', + 'icon' => 'db_events.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1', + ); + $new->classes = 'new_event italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php new file mode 100644 index 000000000..f6e01a5e4 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Function.class.php @@ -0,0 +1,67 @@ +icon = PMA_Util::getImage('b_routines.png'); + $this->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&item_type=FUNCTION' + . '&edit_item=1&token=' . $GLOBALS['token'], + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&item_type=FUNCTION' + . '&export_item=1&token=' . $GLOBALS['token'] + ); + $this->classes = 'function'; + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + $db = PMA_Util::sqlAddSlashes( + $this->realParent()->real_name + ); + $routine = PMA_Util::sqlAddSlashes( + $this->real_name + ); + $query = "SELECT `ROUTINE_COMMENT` "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db' "; + $query .= "AND `ROUTINE_NAME`='$routine' "; + $query .= "AND `ROUTINE_TYPE`='FUNCTION' "; + return PMA_DBI_fetch_value($query); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php new file mode 100644 index 000000000..1ddc313ab --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Function_Container.class.php @@ -0,0 +1,52 @@ +icon = PMA_Util::getImage('b_routines.png'); + $this->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + ); + $this->real_name = 'functions'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new function', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_routine_add.png', ''); + $new->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1&item_type=FUNCTION', + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1&item_type=FUNCTION', + ); + $new->classes = 'new_function italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php new file mode 100644 index 000000000..918a2123e --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Index.class.php @@ -0,0 +1,45 @@ +icon = PMA_Util::getImage('b_index.png'); + $this->links = array( + 'text' => 'tbl_indexes.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s&index=%1$s' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_indexes.php?server=' . $GLOBALS['server'] + . '&db=%3$s&table=%2$s&index=%1$s' + . '&token=' . $GLOBALS['token'] + ); + $this->classes = 'index'; + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php new file mode 100644 index 000000000..732dfddf3 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Index_Container.class.php @@ -0,0 +1,54 @@ +icon = PMA_Util::getImage('b_index.png', ''); + $this->links = array( + 'text' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&token=' . $GLOBALS['token'], + ); + $this->real_name = 'indexes'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new index', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_index_add.png', ''); + $new->links = array( + 'text' => 'tbl_indexes.php?server=' . $GLOBALS['server'] + . '&create_index=1&added_fields=2' + . '&db=%3$s&table=%2$s&token=' . $GLOBALS['token'], + 'icon' => 'tbl_indexes.php?server=' . $GLOBALS['server'] + . '&create_index=1&added_fields=2' + . '&db=%3$s&table=%2$s&token=' . $GLOBALS['token'], + ); + $new->classes = 'new_index italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php new file mode 100644 index 000000000..e89fe2f98 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure.class.php @@ -0,0 +1,67 @@ +icon = PMA_Util::getImage('b_routines.png'); + $this->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&item_type=PROCEDURE' + . '&edit_item=1&token=' . $GLOBALS['token'], + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&item_name=%1$s&item_type=PROCEDURE' + . '&export_item=1&token=' . $GLOBALS['token'] + ); + $this->classes = 'procedure'; + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + $db = PMA_Util::sqlAddSlashes( + $this->realParent()->real_name + ); + $routine = PMA_Util::sqlAddSlashes( + $this->real_name + ); + $query = "SELECT `ROUTINE_COMMENT` "; + $query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` "; + $query .= "WHERE `ROUTINE_SCHEMA`='$db' "; + $query .= "AND `ROUTINE_NAME`='$routine' "; + $query .= "AND `ROUTINE_TYPE`='PROCEDURE' "; + return PMA_DBI_fetch_value($query); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php new file mode 100644 index 000000000..8af1185c7 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Procedure_Container.class.php @@ -0,0 +1,52 @@ +icon = PMA_Util::getImage('b_routines.png'); + $this->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + ); + $this->real_name = 'procedures'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new procedure', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_routine_add.png', ''); + $new->links = array( + 'text' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1', + 'icon' => 'db_routines.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'] + . '&add_item=1', + ); + $new->classes = 'new_procedure italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php new file mode 100644 index 000000000..c5449d922 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Table.class.php @@ -0,0 +1,229 @@ +icon = PMA_Util::getImage('b_browse.png'); + $this->links = array( + 'text' => 'sql.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&pos=0&token=' . $GLOBALS['token'], + 'icon' => $GLOBALS['cfg']['NavigationTreeDefaultTabTable'] + . '?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token'] + ); + } + + /** + * Returns the number of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('columns' or 'indexes') + * @param string $searchClause A string used to filter the results of the query + * + * @return int + */ + public function getPresence($type = '', $searchClause = '') + { + $retval = 0; + $db = $this->realParent()->real_name; + $table = $this->real_name; + switch ($type) { + case 'columns': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` "; + $query .= "WHERE `TABLE_NAME`='$table' "; + $query .= "AND `TABLE_SCHEMA`='$db'"; + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::backquote($db); + $table = PMA_Util::backquote($table); + $query = "SHOW COLUMNS FROM $table FROM $db"; + $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + case 'indexes': + $db = PMA_Util::backquote($db); + $table = PMA_Util::backquote($table); + $query = "SHOW INDEXES FROM $table FROM $db"; + $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query)); + break; + case 'triggers': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SELECT COUNT(*) "; + $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` "; + $query .= "WHERE `EVENT_OBJECT_SCHEMA`='$db' "; + $query .= "AND `EVENT_OBJECT_TABLE`='$table'"; + $retval = (int)PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::backquote($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'"; + $retval = (int)PMA_DBI_num_rows(PMA_DBI_try_query($query)); + } + break; + default: + break; + } + return $retval; + } + + /** + * Returns the names of children of type $type present inside this container + * This method is overridden by the Node_Database and Node_Table classes + * + * @param string $type The type of item we are looking for + * ('tables', 'views', etc) + * @param int $pos The offset of the list within the results + * @param string $searchClause A string used to filter the results of the query + * + * @return array + */ + public function getData($type, $pos, $searchClause = '') + { + $maxItems = $GLOBALS['cfg']['MaxNavigationItems']; + $retval = array(); + $db = $this->realParent()->real_name; + $table = $this->real_name; + switch ($type) { + case 'columns': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SELECT `COLUMN_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` "; + $query .= "WHERE `TABLE_NAME`='$table' "; + $query .= "AND `TABLE_SCHEMA`='$db' "; + $query .= "ORDER BY `COLUMN_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $db = PMA_Util::backquote($db); + $table = PMA_Util::backquote($table); + $query = "SHOW COLUMNS FROM $table FROM $db"; + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Field']; + $count++; + } + $pos--; + } + } + } + break; + case 'indexes': + $db = PMA_Util::backquote($db); + $table = PMA_Util::backquote($table); + $query = "SHOW INDEXES FROM $table FROM $db"; + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if (! in_array($arr['Key_name'], $retval)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Key_name']; + $count++; + } + $pos--; + } + } + } + break; + case 'triggers': + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SELECT `TRIGGER_NAME` AS `name` "; + $query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` "; + $query .= "WHERE `EVENT_OBJECT_SCHEMA`='$db' "; + $query .= "AND `EVENT_OBJECT_TABLE`='$table' "; + $query .= "ORDER BY `TRIGGER_NAME` ASC "; + $query .= "LIMIT " . intval($pos) . ", $maxItems"; + $retval = PMA_DBI_fetch_result($query); + } else { + $db = PMA_Util::backquote($db); + $table = PMA_Util::sqlAddSlashes($table); + $query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'"; + $handle = PMA_DBI_try_query($query); + if ($handle !== false) { + $count = 0; + while ($arr = PMA_DBI_fetch_array($handle)) { + if ($pos <= 0 && $count < $maxItems) { + $retval[] = $arr['Trigger']; + $count++; + } + $pos--; + } + } + } + break; + default: + break; + } + return $retval; + } + + /** + * Returns the comment associated with node + * This method should be overridden by specific type of nodes + * + * @return string + */ + public function getComment() + { + $db = $this->realParent()->real_name; + $table = PMA_Util::sqlAddSlashes($this->real_name); + if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) { + $db = PMA_Util::sqlAddSlashes($db); + $query = "SELECT `TABLE_COMMENT` "; + $query .= "FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='$db' "; + $query .= "AND `TABLE_NAME`='$table' "; + $retval = PMA_DBI_fetch_value($query); + } else { + $db = PMA_Util::backquote($db); + $query = "SHOW TABLE STATUS FROM $db "; + $query .= "WHERE Name = '$table'"; + $arr = PMA_DBI_fetch_assoc(PMA_DBI_try_query($query)); + $retval = $arr['Comment']; + } + return $retval; + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php new file mode 100644 index 000000000..3d3ef146d --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Table_Container.class.php @@ -0,0 +1,54 @@ +icon = PMA_Util::getImage('b_browse.png', ''); + $this->links = array( + 'text' => 'db_structure.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_structure.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + ); + if ($GLOBALS['cfg']['NavigationTreeEnableGrouping']) { + $this->separator = $GLOBALS['cfg']['NavigationTreeTableSeparator']; + $this->separator_depth = (int)($GLOBALS['cfg']['NavigationTreeTableLevel']); + } + $this->real_name = 'tables'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new table', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_table_add.png', ''); + $new->links = array( + 'text' => 'tbl_create.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'], + 'icon' => 'tbl_create.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'], + ); + $new->classes = 'new_table italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php new file mode 100644 index 000000000..bc51106ca --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger.class.php @@ -0,0 +1,45 @@ +icon = PMA_Util::getImage('b_triggers.png'); + $this->links = array( + 'text' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%3$s&item_name=%1$s&edit_item=1' + . '&token=' . $GLOBALS['token'], + 'icon' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%3$s&item_name=%1$s&export_item=1' + . '&token=' . $GLOBALS['token'] + ); + $this->classes = 'trigger'; + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php new file mode 100644 index 000000000..7f8f3cb94 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_Trigger_Container.class.php @@ -0,0 +1,53 @@ +icon = PMA_Util::getImage('b_triggers.png'); + $this->links = array( + 'text' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s&token=' . $GLOBALS['token'] + ); + $this->real_name = 'triggers'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new trigger', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_trigger_add.png', ''); + $new->links = array( + 'text' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%3$s&token=' . $GLOBALS['token'] + . '&add_item=1', + 'icon' => 'db_triggers.php?server=' . $GLOBALS['server'] + . '&db=%3$s&token=' . $GLOBALS['token'] + . '&add_item=1', + ); + $new->classes = 'new_trigger italics'; + $this->addChild($new); + } + +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php new file mode 100644 index 000000000..3f47579a7 --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_View.class.php @@ -0,0 +1,44 @@ +icon = PMA_Util::getImage('b_views.png'); + $this->links = array( + 'text' => 'sql.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s&pos=0' + . '&token=' . $GLOBALS['token'], + 'icon' => 'tbl_structure.php?server=' . $GLOBALS['server'] + . '&db=%2$s&table=%1$s' + . '&token=' . $GLOBALS['token'] + ); + } +} + +?> diff --git a/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php b/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php new file mode 100644 index 000000000..ada9027ff --- /dev/null +++ b/phpmyadmin/libraries/navigation/Nodes/Node_View_Container.class.php @@ -0,0 +1,50 @@ +icon = PMA_Util::getImage('b_views.png', ''); + $this->links = array( + 'text' => 'db_structure.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + 'icon' => 'db_structure.php?server=' . $GLOBALS['server'] + . '&db=%1$s&token=' . $GLOBALS['token'], + ); + $this->real_name = 'views'; + + $new = PMA_NodeFactory::getInstance('Node', _pgettext('Create new view', 'New')); + $new->isNew = true; + $new->icon = PMA_Util::getImage('b_view_add.png', ''); + $new->links = array( + 'text' => 'view_create.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'], + 'icon' => 'view_create.php?server=' . $GLOBALS['server'] + . '&db=%2$s&token=' . $GLOBALS['token'], + ); + $new->classes = 'new_view italics'; + $this->addChild($new); + } +} + +?> diff --git a/phpmyadmin/libraries/opendocument.lib.php b/phpmyadmin/libraries/opendocument.lib.php new file mode 100644 index 000000000..b1325034d --- /dev/null +++ b/phpmyadmin/libraries/opendocument.lib.php @@ -0,0 +1,170 @@ + addFile($mime, 'mimetype'); + $zipfile -> addFile($data, 'content.xml'); + $zipfile -> addFile( + '' + . '' + . '' + . 'phpMyAdmin ' . PMA_VERSION . '' + . 'phpMyAdmin ' . PMA_VERSION + . '' + . '' . strftime('%Y-%m-%dT%H:%M:%S') + . '' + . '' + . '', + 'meta.xml' + ); + $zipfile -> addFile( + '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . '', + 'styles.xml' + ); + $zipfile -> addFile( + '' + . '' + . '' + . '' + . '' + . '' + . '', + 'META-INF/manifest.xml' + ); + return $zipfile -> file(); +} +?> diff --git a/phpmyadmin/libraries/operations.lib.php b/phpmyadmin/libraries/operations.lib.php new file mode 100644 index 000000000..94be5a2eb --- /dev/null +++ b/phpmyadmin/libraries/operations.lib.php @@ -0,0 +1,1609 @@ +' + . '
      ' + . PMA_generate_common_hidden_inputs($db) + . '
      ' + . ''; + if ($GLOBALS['cfg']['PropertiesIconic']) { + $html_output .= ''; + } + $html_output .= __('Database comment: '); + $html_output .= ''; + $html_output .= '' + . '
      '; + $html_output .= '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML output for rename database + * + * @param string $db database name + * + * @return string $html_output + */ +function PMA_getHtmlForRenameDatabase($db) +{ + $html_output = '
      ' + . '
      '; + if (isset($_REQUEST['db_collation'])) { + $html_output .= '' . "\n"; + } + $html_output .= '' + . '' + . PMA_generate_common_hidden_inputs($db) + . '
      ' + . ''; + + if ($GLOBALS['cfg']['PropertiesIconic']) { + $html_output .= PMA_Util::getImage('b_edit.png'); + } + $html_output .= __('Rename database to') . ':' + . ''; + + $html_output .= '' + . '
      ' + . '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML for database drop link + * + * @param string $db database name + * + * @return string $html_output + */ +function PMA_getHtmlForDropDatabaseLink($db) +{ + $this_sql_query = 'DROP DATABASE ' . PMA_Util::backquote($db); + $this_url_params = array( + 'sql_query' => $this_sql_query, + 'back' => 'db_operations.php', + 'goto' => 'index.php', + 'reload' => '1', + 'purge' => '1', + 'message_to_show' => sprintf( + __('Database %s has been dropped.'), + htmlspecialchars(PMA_Util::backquote($db)) + ), + 'db' => null, + ); + + $html_output = '
      ' + . '
      '; + $html_output .= ''; + if ($GLOBALS['cfg']['PropertiesIconic']) { + $html_output .= PMA_Util::getImage('b_deltbl.png'); + } + $html_output .= __('Remove database') + . ''; + $html_output .= '
        '; + $html_output .= PMA_getDeleteDataOrTablelink( + $this_url_params, + 'DROP_DATABASE', + __('Drop the database (DROP)'), + 'drop_db_anchor' + ); + $html_output .= '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML snippet for copy database + * + * @param string $db database name + * + * @return string $html_output + */ +function PMA_getHtmlForCopyDatabase($db) +{ + $drop_clause = 'DROP TABLE / DROP VIEW'; + $choices = array( + 'structure' => __('Structure only'), + 'data' => __('Structure and data'), + 'dataonly' => __('Data only') + ); + + if (isset($_COOKIE) + && isset($_COOKIE['pma_switch_to_new']) + && $_COOKIE['pma_switch_to_new'] == 'true' + ) { + $pma_switch_to_new = 'true'; + } + + $html_output = '
      '; + $html_output .= '
      '; + + if (isset($_REQUEST['db_collation'])) { + $html_output .= '' . "\n"; + } + $html_output .= '' . "\n" + . PMA_generate_common_hidden_inputs($db); + $html_output .= '
      ' + . ''; + + if ($GLOBALS['cfg']['PropertiesIconic']) { + $html_output .= PMA_Util::getImage('b_edit.png'); + } + $html_output .= __('Copy database to') . ':' + . '' + . '
      ' + . PMA_Util::getRadioFields( + 'what', $choices, 'data', true + ); + $html_output .= ''; + $html_output .= '
      '; + $html_output .= ''; + $html_output .= '
      '; + $html_output .= ''; + $html_output .= '
      '; + $html_output .= ''; + $html_output .= '
      '; + $html_output .= ''; + $html_output .= '' + . '
      '; + $html_output .= '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML snippet for change database charset + * + * @param string $db database name + * @param string $table tabel name + * + * @return string $html_output + */ +function PMA_getHtmlForChangeDatabaseCharset($db, $table) +{ + $html_output = '
      ' + . '
      '; + if ($GLOBALS['cfg']['PropertiesIconic']) { + $html_output .= PMA_Util::getImage('s_asci.png'); + } + $html_output .= '' . "\n" + . '' . "\n" + . PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_COLLATION, + 'db_collation', + 'select_db_collation', + isset($_REQUEST['db_collation']) ? $_REQUEST['db_collation'] : '', + false, + 3 + ) + . '' + . '
      ' + . '' . "\n" + . '
      ' . "\n" + . '
      ' . "\n"; + + return $html_output; +} + +/** + * Get HTML snippet for export relational schema view + * + * @param string $url_query + * + * @return string $html_output + */ +function PMA_getHtmlForExportRelationalSchemaView($url_query) +{ + $html_output = ''; + + return $html_output; +} + +/** + * Run the Procedure definitions and function definitions + * + * to avoid selecting alternatively the current and new db + * we would need to modify the CREATE definitions to qualify + * the db name + * + * @param string $db database name + * + * @return void + */ +function PMA_runProcedureAndFunctionDefinitions($db) +{ + $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE'); + if ($procedure_names) { + foreach ($procedure_names as $procedure_name) { + PMA_DBI_select_db($db); + $tmp_query = PMA_DBI_get_definition( + $db, 'PROCEDURE', $procedure_name + ); + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + PMA_DBI_select_db($_REQUEST['newname']); + PMA_DBI_query($tmp_query); + } + } + + $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION'); + if ($function_names) { + foreach ($function_names as $function_name) { + PMA_DBI_select_db($db); + $tmp_query = PMA_DBI_get_definition($db, 'FUNCTION', $function_name); + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + PMA_DBI_select_db($_REQUEST['newname']); + PMA_DBI_query($tmp_query); + } + } +} + +/** + * Get sql query and create database before copy + * + * @return string $sql_query + */ +function PMA_getSqlQueryAndCreateDbBeforeCopy() +{ + // lower_case_table_names=1 `DB` becomes `db` + if (! PMA_DRIZZLE) { + $lower_case_table_names = PMA_DBI_fetch_value( + 'SHOW VARIABLES LIKE "lower_case_table_names"', 0, 1 + ); + if ($lower_case_table_names === '1') { + $_REQUEST['newname'] = PMA_strtolower($_REQUEST['newname']); + } + } + + $local_query = 'CREATE DATABASE IF NOT EXISTS ' + . PMA_Util::backquote($_REQUEST['newname']); + if (isset($_REQUEST['db_collation'])) { + $local_query .= ' DEFAULT' + . PMA_generateCharsetQueryPart($_REQUEST['db_collation']); + } + $local_query .= ';'; + $sql_query = $local_query; + // save the original db name because Tracker.class.php which + // may be called under PMA_DBI_query() changes $GLOBALS['db'] + // for some statements, one of which being CREATE DATABASE + $original_db = $GLOBALS['db']; + PMA_DBI_query($local_query); + $GLOBALS['db'] = $original_db; + + // rebuild the database list because PMA_Table::moveCopy + // checks in this list if the target db exists + $GLOBALS['pma']->databases->build(); + + return $sql_query; +} + +/** + * remove all foreign key constraints and return + * sql constraints query for full database + * + * @param array $tables_full array of all tables in given db or dbs + * @param object $export_sql_plugin export plugin instance + * @param boolean $move whether databse name is empty or not + * @param string $db database name + * + * @return string sql constraints query for full databases + */ +function PMA_getSqlConstraintsQueryForFullDb( + $tables_full, $export_sql_plugin, $move, $db +) { + $sql_constraints_query_full_db = array(); + foreach ($tables_full as $each_table => $tmp) { + $sql_constraints = ''; + $sql_drop_foreign_keys = ''; + $sql_structure = $export_sql_plugin->getTableDef( + $db, $each_table, "\n", '', false, false + ); + if ($move && ! empty($sql_drop_foreign_keys)) { + PMA_DBI_query($sql_drop_foreign_keys); + } + // keep the constraint we just dropped + if (! empty($sql_constraints)) { + $sql_constraints_query_full_db[] = $sql_constraints; + } + } + return $sql_constraints_query_full_db; +} + +/** + * Get views as an array and create SQL view stand-in + * + * @param array $tables_full array of all tables in given db or dbs + * @param object $export_sql_plugin export plugin instance + * @param strin $db database name + * + * @return array $views + */ +function PMA_getViewsAndCreateSqlViewStandIn( + $tables_full, $export_sql_plugin, $db +) { + $views = array(); + foreach ($tables_full as $each_table => $tmp) { + // to be able to rename a db containing views, + // first all the views are collected and a stand-in is created + // the real views are created after the tables + if (PMA_Table::isView($db, $each_table)) { + $views[] = $each_table; + // Create stand-in definition to resolve view dependencies + $sql_view_standin = $export_sql_plugin->getTableDefStandIn( + $db, $each_table, "\n" + ); + PMA_DBI_select_db($_REQUEST['newname']); + PMA_DBI_query($sql_view_standin); + $GLOBALS['sql_query'] .= "\n" . $sql_view_standin; + } + } + return $views; +} + +/** + * Get sql query for copy/rename table and boolean for whether copy/rename or not + * + * @param array $tables_full array of all tables in given db or dbs + * @param string $sql_query sql query for all operations + * @param boolean $move whether databse name is empty or not + * @param string $db database name + * + * @return array ($sql_query, $error) + */ +function PMA_getSqlQueryForCopyTable($tables_full, $sql_query, $move, $db) +{ + $error = false; + foreach ($tables_full as $each_table => $tmp) { + // skip the views; we have creted stand-in definitions + if (PMA_Table::isView($db, $each_table)) { + continue; + } + $back = $sql_query; + $sql_query = ''; + + // value of $what for this table only + $this_what = $_REQUEST['what']; + + // do not copy the data from a Merge table + // note: on the calling FORM, 'data' means 'structure and data' + if (PMA_Table::isMerge($db, $each_table)) { + if ($this_what == 'data') { + $this_what = 'structure'; + } + if ($this_what == 'dataonly') { + $this_what = 'nocopy'; + } + } + + if ($this_what != 'nocopy') { + // keep the triggers from the original db+table + // (third param is empty because delimiters are only intended + // for importing via the mysql client or our Import feature) + $triggers = PMA_DBI_get_triggers($db, $each_table, ''); + + if (! PMA_Table::moveCopy( + $db, $each_table, $_REQUEST['newname'], $each_table, + (isset($this_what) ? $this_what : 'data'), + $move, 'db_copy' + )) { + $error = true; + // $sql_query is filled by PMA_Table::moveCopy() + $sql_query = $back . $sql_query; + break; + } + // apply the triggers to the destination db+table + if ($triggers) { + PMA_DBI_select_db($_REQUEST['newname']); + foreach ($triggers as $trigger) { + PMA_DBI_query($trigger['create']); + $GLOBALS['sql_query'] .= "\n" . $trigger['create'] . ';'; + } + } + + // this does not apply to a rename operation + if (isset($_REQUEST['add_constraints']) + && ! empty($GLOBALS['sql_constraints_query']) + ) { + $GLOBALS['sql_constraints_query_full_db'][] + = $GLOBALS['sql_constraints_query']; + unset($GLOBALS['sql_constraints_query']); + } + } + // $sql_query is filled by PMA_Table::moveCopy() + $sql_query = $back . $sql_query; + } + return array($sql_query, $error); +} + +/** + * Run the EVENT definition for selected database + * + * to avoid selecting alternatively the current and new db + * we would need to modify the CREATE definitions to qualify + * the db name + * + * @param string $db database name + * + * @return void + */ +function PMA_runEventDefinitionsForDb($db) +{ + $event_names = PMA_DBI_fetch_result( + 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \'' + . PMA_Util::sqlAddSlashes($db, true) . '\';' + ); + if ($event_names) { + foreach ($event_names as $event_name) { + PMA_DBI_select_db($db); + $tmp_query = PMA_DBI_get_definition($db, 'EVENT', $event_name); + // collect for later display + $GLOBALS['sql_query'] .= "\n" . $tmp_query; + PMA_DBI_select_db($_REQUEST['newname']); + PMA_DBI_query($tmp_query); + } + } +} + +/** + * Handle the views, return the boolean value whether table rename/copy or not + * + * @param array $views views as an array + * @param boolean $move whether databse name is empty or not + * @param string $db database name + * + * @return boolean $_error whether table rename/copy or not + */ +function PMA_handleTheViews($views, $move, $db) +{ + $_error = false; + // temporarily force to add DROP IF EXIST to CREATE VIEW query, + // to remove stand-in VIEW that was created earlier + // ( $_REQUEST['drop_if_exists'] is used in moveCopy() ) + if (isset($_REQUEST['drop_if_exists'])) { + $temp_drop_if_exists = $_REQUEST['drop_if_exists']; + } + $_REQUEST['drop_if_exists'] = 'true'; + + foreach ($views as $view) { + $copying_succeeded = PMA_Table::moveCopy( + $db, $view, $_REQUEST['newname'], $view, 'structure', $move, 'db_copy' + ); + if (! $copying_succeeded) { + $_error = true; + break; + } + } + unset($_REQUEST['drop_if_exists']); + if (isset($temp_drop_if_exists)) { + // restore previous value + $_REQUEST['drop_if_exists'] = $temp_drop_if_exists; + } + return $_error; +} + +/** + * Create all accumulated constraaints + * + * @return void + */ +function PMA_createAllAccumulatedConstraints() +{ + PMA_DBI_select_db($_REQUEST['newname']); + foreach ($GLOBALS['sql_constraints_query_full_db'] as $one_query) { + PMA_DBI_query($one_query); + // and prepare to display them + $GLOBALS['sql_query'] .= "\n" . $one_query; + } + unset($GLOBALS['sql_constraints_query_full_db']); +} + +/** + * Duplicate the bookmarks for the db (done once for each db) + * + * @param boolean $_error whether table rename/copy or not + * @param string $db database name + * + * @return void + */ +function PMA_duplicateBookmarks($_error, $db) +{ + if (! $_error && $db != $_REQUEST['newname']) { + $get_fields = array('user', 'label', 'query'); + $where_fields = array('dbase' => $db); + $new_fields = array('dbase' => $_REQUEST['newname']); + PMA_Table::duplicateInfo( + 'bookmarkwork', 'bookmark', $get_fields, + $where_fields, $new_fields + ); + } +} + +/** + * Get the HTML snippet for order the table + * + * @param array $columns columns array + * + * @return string $html_out + */ +function PMA_getHtmlForOrderTheTable($columns) +{ + $html_output = '
      '; + $html_output .= '
      '; + $html_output .= PMA_generate_common_hidden_inputs( + $GLOBALS['db'], $GLOBALS['table'] + ); + $html_output .= '
      ' + . '' . __('Alter table order by') . '' + . ' ' . __('(singly)') . ' ' + . '' + . '
      ' + . '
      ' + . '' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get the HTML snippet for move table + * + * @return string $html_output + */ +function PMA_getHtmlForMoveTable() +{ + $html_output = '
      '; + $html_output .= '
      ' + . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']); + + $html_output .= '' + . '' + . '
      '; + + $html_output .= '' . __('Move table to (database.table):') + . ''; + + if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= ' . '; + $html_output .= '
      '; + + // starting with MySQL 5.0.24, SHOW CREATE TABLE includes the AUTO_INCREMENT + // next value but users can decide if they want it or not for the operation + + $html_output .= '' + . '
      ' + . '
      '; + + $html_output .= '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get the HTML div for Table option + * + * @param string $comment Comment + * @param array $tbl_collation table collation + * @param string $tbl_storage_engine table storage engine + * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not + * @param boolean $is_isam whether ISAM or not + * @param array $pack_keys pack keys + * @param string $auto_increment value of auto increment + * @param string $delay_key_write delay key write + * @param string $transactional value of transactional + * @param string $page_checksum value of page checksum + * @param boolean $is_innodb whether INNODB or not + * @param boolean $is_pbxt whether PBXT or not + * @param boolean $is_aria whether ARIA or not + * @param string $checksum the checksum + * + * @return string $html_output + */ +function PMA_getTableOptionDiv($comment, $tbl_collation, $tbl_storage_engine, + $is_myisam_or_aria, $is_isam, $pack_keys, $auto_increment, $delay_key_write, + $transactional, $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum +) { + $html_output = '
      '; + $html_output .= '
      ' + . '' + . '' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML fieldset for Table option, it contains HTML table for options + * + * @param string $comment Comment + * @param array $tbl_collation table collation + * @param string $tbl_storage_engine table storage engine + * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not + * @param boolean $is_isam whether ISAM or not + * @param array $pack_keys pack keys + * @param string $delay_key_write delay key write + * @param string $auto_increment value of auto increment + * @param string $transactional value of transactional + * @param string $page_checksum value of page checksum + * @param boolean $is_innodb whether INNODB or not + * @param boolean $is_pbxt whether PBXT or not + * @param boolean $is_aria whether ARIA or not + * @param string $checksum the checksum + * + * @return string $html_output + */ +function PMA_getTableOptionFieldset($comment, $tbl_collation, + $tbl_storage_engine, $is_myisam_or_aria, $is_isam, $pack_keys, + $delay_key_write, $auto_increment, $transactional, + $page_checksum, $is_innodb, $is_pbxt, $is_aria, $checksum +) { + $html_output = '
      ' + . '' . __('Table options') . ''; + + $html_output .= ''; + //Change table name + $html_output .= '' + . '' + . ''; + + //Table comments + $html_output .= '' + . '' + . ''; + + //Storage engine + $html_output .= '' + . '' + . ''; + + //Table character set + $html_output .= '' + . '' + . ''; + + if ($is_myisam_or_aria || $is_isam) { + $html_output .= '' + . '' + . '' + . ''; + } // end if (MYISAM|ISAM) + + if ($is_myisam_or_aria) { + $html_output .= PMA_getHtmlForTableRow( + 'new_checksum', + 'CHECKSUM', + $checksum + ); + + $html_output .= PMA_getHtmlForTableRow( + 'new_delay_key_write', + 'DELAY_KEY_WRITE', + $delay_key_write + ); + } // end if (MYISAM) + + if ($is_aria) { + $html_output .= PMA_getHtmlForTableRow( + 'new_transactional', + 'TRANSACTIONAL', + $transactional + ); + + $html_output .= PMA_getHtmlForTableRow( + 'new_page_checksum', + 'PAGE_CHECKSUM', + $page_checksum + ); + } // end if (ARIA) + + if (strlen($auto_increment) > 0 + && ($is_myisam_or_aria || $is_innodb || $is_pbxt) + ) { + $html_output .= '' + . '' + . ' '; + } // end if (MYISAM|INNODB) + + $possible_row_formats = PMA_getPossibleRowFormat(); + + // for MYISAM there is also COMPRESSED but it can be set only by the + // myisampack utility, so don't offer here the choice because if we + // try it inside an ALTER TABLE, MySQL (at least in 5.1.23-maria) + // does not return a warning + // (if the table was compressed, it can be seen on the Structure page) + + if (isset($possible_row_formats[$tbl_storage_engine])) { + $current_row_format = strtoupper($GLOBALS['showtable']['Row_format']); + $html_output .= '' + . ''; + } + $html_output .= '
      ' . __('Rename table to') . '' + . '' + . '
      ' . __('Table comments') . '' + . '' + . '
      ' . __('Storage Engine') + . PMA_Util::showMySQLDocu( + 'Storage_engines', 'Storage_engines' + ) + . '' + . PMA_StorageEngine::getHtmlSelect( + 'new_tbl_storage_engine', null, $tbl_storage_engine + ) + . '
      ' . __('Collation') . '' + . PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_COLLATION, + 'tbl_collation', null, $tbl_collation, false, 3 + ) + . '
      ' + . '
      ' + . ''; + $html_output .= PMA_Util::getDropdown( + 'new_row_format', $possible_row_formats[$tbl_storage_engine], + $current_row_format, 'new_row_format' + ); + $html_output .= '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get the common HTML table row (tr) for new_checksum, new_delay_key_write, + * new_transactional and new_page_checksum + * + * @param string $attribute class, name and id attribute + * @param string $label label value + * @param string $val checksum, delay_key_write, transactional, page_checksum + * + * @return string $html_output + */ +function PMA_getHtmlForTableRow($attribute, $label, $val) +{ + return '' + . '' + . '' + . ''; +} + +/** + * Get array of possible row formats + * + * @return array $possible_row_formats + */ +function PMA_getPossibleRowFormat() +{ + // the outer array is for engines, the inner array contains the dropdown + // option values as keys then the dropdown option labels + + $possible_row_formats = array( + 'ARIA' => array( + 'FIXED' => 'FIXED', + 'DYNAMIC' => 'DYNAMIC', + 'PAGE' => 'PAGE' + ), + 'MARIA' => array( + 'FIXED' => 'FIXED', + 'DYNAMIC' => 'DYNAMIC', + 'PAGE' => 'PAGE' + ), + 'MYISAM' => array( + 'FIXED' => 'FIXED', + 'DYNAMIC' => 'DYNAMIC' + ), + 'PBXT' => array( + 'FIXED' => 'FIXED', + 'DYNAMIC' => 'DYNAMIC' + ), + 'INNODB' => array( + 'COMPACT' => 'COMPACT', + 'REDUNDANT' => 'REDUNDANT' + ) + ); + + $innodb_engine_plugin = PMA_StorageEngine::getEngine('innodb'); + $innodb_plugin_version = $innodb_engine_plugin->getInnodbPluginVersion(); + if (!empty($innodb_plugin_version)) { + $innodb_file_format = $innodb_engine_plugin->getInnodbFileFormat(); + } else { + $innodb_file_format = ''; + } + if ('Barracuda' == $innodb_file_format + && $innodb_engine_plugin->supportsFilePerTable() + ) { + $possible_row_formats['INNODB']['DYNAMIC'] = 'DYNAMIC'; + $possible_row_formats['INNODB']['COMPRESSED'] = 'COMPRESSED'; + } + + return $possible_row_formats; +} + +/** + * Get HTML div for copy table + * + * @return string $html_output + */ +function PMA_getHtmlForCopytable() +{ + $html_output = '
      '; + $html_output .= '
      ' + . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']) + . ''; + + $html_output .= '
      '; + $html_output .= '' + . __('Copy table to (database.table):') . ''; + + if (count($GLOBALS['pma']->databases) > $GLOBALS['cfg']['MaxDbList']) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= ' . '; + $html_output .= '
      '; + + $choices = array( + 'structure' => __('Structure only'), + 'data' => __('Structure and data'), + 'dataonly' => __('Data only')); + + $html_output .= PMA_Util::getRadioFields( + 'what', $choices, 'data', true + ); + + $html_output .= '' + . '
      ' + . '' + . '
      '; + + // display "Add constraints" choice only if there are + // foreign keys + if (PMA_getForeigners($GLOBALS['db'], $GLOBALS['table'], '', 'foreign')) { + $html_output .= ''; + $html_output .= '
      '; + } // endif + + if (isset($_COOKIE['pma_switch_to_new']) + && $_COOKIE['pma_switch_to_new'] == 'true' + ) { + $pma_switch_to_new = 'true'; + } + + $html_output .= ''); + $html_output .= '' + . '
      '; + + $html_output .= '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML snippet for table maintence + * + * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not + * @param boolean $is_innodb whether innodb or not + * @param boolean $is_berkeleydb whether berkeleydb or not + * @param array $url_params array of URL parameters + * + * @return string $html_output + */ +function PMA_getHtmlForTableMaintenance( + $is_myisam_or_aria, $is_innodb, $is_berkeleydb, $url_params +) { + $html_output = '
      '; + $html_output .= '
      ' + . '' . __('Table maintenance') . ''; + $html_output .= '
        '; + + // Note: BERKELEY (BDB) is no longer supported, starting with MySQL 5.1 + $html_output .= PMA_getListofMaintainActionLink( + $is_myisam_or_aria, $is_innodb, $url_params, $is_berkeleydb + ); + + $html_output .= '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get HTML 'li' having a link of maintain action + * + * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not + * @param boolean $is_innodb whether innodb or not + * @param array $url_params array of URL parameters + * @param boolean $is_berkeleydb whether berkeleydb or not + * + * @return string $html_output + */ +function PMA_getListofMaintainActionLink($is_myisam_or_aria, + $is_innodb, $url_params, $is_berkeleydb +) { + $html_output = ''; + + if ($is_myisam_or_aria || $is_innodb || $is_berkeleydb) { + if ($is_myisam_or_aria || $is_innodb) { + $params = array( + 'sql_query' => 'CHECK TABLE ' + . PMA_Util::backquote($GLOBALS['table']), + 'table_maintenance' => 'Go', + ); + $html_output .= PMA_getMaintainActionlink( + __('Check table'), + $params, + $url_params, + 'CHECK_TABLE' + ); + } + if ($is_innodb) { + $params = array( + 'sql_query' => 'ALTER TABLE ' + . PMA_Util::backquote($GLOBALS['table']) + . ' ENGINE = InnoDB;' + ); + $html_output .= PMA_getMaintainActionlink( + __('Defragment table'), + $params, + $url_params, + 'InnoDB_File_Defragmenting', + 'Table_types' + ); + } + if ($is_myisam_or_aria || $is_berkeleydb) { + $params = array( + 'sql_query' => 'ANALYZE TABLE ' + . PMA_Util::backquote($GLOBALS['table']), + 'table_maintenance' => 'Go', + ); + $html_output .= PMA_getMaintainActionlink( + __('Analyze table'), + $params, + $url_params, + 'ANALYZE_TABLE' + ); + } + if ($is_myisam_or_aria && !PMA_DRIZZLE) { + $params = array( + 'sql_query' => 'REPAIR TABLE ' + . PMA_Util::backquote($GLOBALS['table']), + 'table_maintenance' => 'Go', + ); + $html_output .= PMA_getMaintainActionlink( + __('Repair table'), + $params, + $url_params, + 'REPAIR_TABLE' + ); + } + if (($is_myisam_or_aria || $is_innodb || $is_berkeleydb) + && !PMA_DRIZZLE + ) { + $params = array( + 'sql_query' => 'OPTIMIZE TABLE ' + . PMA_Util::backquote($GLOBALS['table']), + 'table_maintenance' => 'Go', + ); + $html_output .= PMA_getMaintainActionlink( + __('Optimize table'), + $params, + $url_params, + 'OPTIMIZE_TABLE' + ); + } + } // end MYISAM or BERKELEYDB case + + $params = array( + 'sql_query' => 'FLUSH TABLE ' + . PMA_Util::backquote($GLOBALS['table']), + 'message_to_show' => sprintf( + __('Table %s has been flushed'), + htmlspecialchars($GLOBALS['table']) + ), + 'reload' => 1, + ); + + $html_output .= PMA_getMaintainActionlink( + __('Flush the table (FLUSH)'), + $params, + $url_params, + 'FLUSH' + ); + + return $html_output; +} + +/** + * Get maintain action HTML link + * + * @param string $action + * @param array $params url parameters array + * @param array $url_params + * @param string $link contains name of page/anchor that is being linked + * @param string $chapter chapter of "HTML, one page per chapter" documentation + * + * @return string $html_output + */ +function PMA_getMaintainActionlink($action, $params, $url_params, $link, + $chapter = 'MySQL_Database_Administration' +) { + return '
    • ' + . '' + . $action + . '' + . PMA_Util::showMySQLDocu($chapter, $link) + . '
    • '; +} + +/** + * Get HTML for Delete data or table (truncate table, drop table) + * + * @param array $truncate_table_url_params url parameter array for truncate table + * @param array $drop_table_url_params url parameter array for drop table + * + * @return string $html_output + */ +function PMA_getHtmlForDeleteDataOrTable( + $truncate_table_url_params, + $drop_table_url_params +) { + $html_output = '
      ' + . '
      ' + . '' . __('Delete data or table') . ''; + + $html_output .= '
        '; + + if (! empty($truncate_table_url_params)) { + $html_output .= PMA_getDeleteDataOrTablelink( + $truncate_table_url_params, + 'TRUNCATE_TABLE', + __('Empty the table (TRUNCATE)'), + 'truncate_tbl_anchor' + ); + } + if (!empty ($drop_table_url_params)) { + $html_output .= PMA_getDeleteDataOrTablelink( + $drop_table_url_params, + 'DROP_TABLE', + __('Delete the table (DROP)'), + 'drop_tbl_anchor' + ); + } + $html_output .= '
      '; + + return $html_output; +} + +/** + * Get the HTML link for Truncate table, Drop table and Drop db + * + * @param array $url_params url parameter array for delete data or table + * @param string $syntax TRUNCATE_TABLE or DROP_TABLE or DROP_DATABASE + * @param string $link link to be shown + * @param string $id id of the link + * + * @return String html output + */ +function PMA_getDeleteDataOrTablelink($url_params, $syntax, $link, $id) +{ + return '
    • ' + . $link . '' + . PMA_Util::showMySQLDocu( + 'SQL-Syntax', $syntax + ) + . '
    • '; +} + +/** + * Get HTML snippet for partition maintenance + * + * @param array $partition_names array of partition names for a specific db/table + * @param array $url_params url parameters + * + * @return string $html_output + */ +function PMA_getHtmlForPartitionMaintenance($partition_names, $url_params) +{ + $choices = array( + 'ANALYZE' => __('Analyze'), + 'CHECK' => __('Check'), + 'OPTIMIZE' => __('Optimize'), + 'REBUILD' => __('Rebuild'), + 'REPAIR' => __('Repair') + ); + + $html_output = '
      ' + . '
      ' + . PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']) + . '
      ' + . '' . __('Partition maintenance') . ''; + + $html_select = '' . "\n"; + $html_output .= sprintf(__('Partition %s'), $html_select); + + $html_output .= PMA_Util::getRadioFields( + 'partition_operation', $choices, '', false + ); + $html_output .= PMA_Util::showMySQLDocu( + 'partitioning_maintenance', + 'partitioning_maintenance' + ); + $this_url_params = array_merge( + $url_params, + array( + 'sql_query' => 'ALTER TABLE ' + . PMA_Util::backquote($GLOBALS['table']) + . ' REMOVE PARTITIONING;' + ) + ); + $html_output .= '
      ' + . __('Remove partitioning') . ''; + + $html_output .= '
      ' + . '
      ' + . '' + . '
      ' + . '
      ' + . '
      '; + + return $html_output; +} + +/** + * Get the HTML for Referential Integrity check + * + * @param array $foreign all Relations to foreign tables for a given table + * or optionally a given column in a table + * @param array $url_params array of url parameters + * + * @return string $html_output + */ +function PMA_getHtmlForReferentialIntegrityCheck($foreign, $url_params) +{ + $html_output = '
      ' + . '
      ' + . '' . __('Check referential integrity:') . ''; + + $html_output .= '
        '; + + foreach ($foreign AS $master => $arr) { + $join_query = 'SELECT ' + . PMA_Util::backquote($GLOBALS['table']) . '.*' + . ' FROM ' . PMA_Util::backquote($GLOBALS['table']) + . ' LEFT JOIN ' + . PMA_Util::backquote($arr['foreign_db']) + . '.' + . PMA_Util::backquote($arr['foreign_table']); + if ($arr['foreign_table'] == $GLOBALS['table']) { + $foreign_table = $GLOBALS['table'] . '1'; + $join_query .= ' AS ' . PMA_Util::backquote($foreign_table); + } else { + $foreign_table = $arr['foreign_table']; + } + $join_query .= ' ON ' + . PMA_Util::backquote($GLOBALS['table']) . '.' + . PMA_Util::backquote($master) + . ' = ' + . PMA_Util::backquote($arr['foreign_db']) + . '.' + . PMA_Util::backquote($foreign_table) . '.' + . PMA_Util::backquote($arr['foreign_field']) + . ' WHERE ' + . PMA_Util::backquote($arr['foreign_db']) + . '.' + . PMA_Util::backquote($foreign_table) . '.' + . PMA_Util::backquote($arr['foreign_field']) + . ' IS NULL AND ' + . PMA_Util::backquote($GLOBALS['table']) . '.' + . PMA_Util::backquote($master) + . ' IS NOT NULL'; + $this_url_params = array_merge( + $url_params, + array('sql_query' => $join_query) + ); + + $html_output .= '
      • ' + . '' + . $master . ' -> ' . $arr['foreign_table'] . '.' + . $arr['foreign_field'] + . '
      • ' . "\n"; + } // foreach $foreign + $html_output .= '
      '; + + return $html_output; +} + +function PMA_getQueryAndResultForReorderingTable() +{ + $sql_query = 'ALTER TABLE ' + . PMA_Util::backquote($GLOBALS['table']) + . ' ORDER BY ' + . PMA_Util::backquote(urldecode($_REQUEST['order_field'])); + if (isset($_REQUEST['order_order']) + && $_REQUEST['order_order'] === 'desc' + ) { + $sql_query .= ' DESC'; + } + $sql_query .= ';'; + $result = PMA_DBI_query($sql_query); + + return array($sql_query, $result); +} + +/** + * Get table alters array + * + * @param boolean $is_myisam_or_aria whether MYISAM | ARIA or not + * @param boolean $is_isam whether ISAM or not + * @param string $pack_keys pack keys + * @param string $checksum value of checksum + * @param boolean $is_aria whether ARIA or not + * @param string $page_checksum value of page checksum + * @param string $delay_key_write delay key write + * @param boolean $is_innodb whether INNODB or not + * @param boolean $is_pbxt whether PBXT or not + * @param string $row_format row format + * @param string $tbl_storage_engine table storage engine + * @param string $transactional value of transactional + * @param string $tbl_collation collation of the table + * + * @return array $table_alters + */ +function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys, + $checksum, $is_aria, $page_checksum, $delay_key_write, $is_innodb, + $is_pbxt, $row_format, $new_tbl_storage_engine, $transactional, $tbl_collation +) { + global $auto_increment; + + $table_alters = array(); + + if (isset($_REQUEST['comment']) + && urldecode($_REQUEST['prev_comment']) !== $_REQUEST['comment'] + ) { + $table_alters[] = 'COMMENT = \'' + . PMA_Util::sqlAddSlashes($_REQUEST['comment']) . '\''; + } + if (! empty($new_tbl_storage_engine) + && strtolower($new_tbl_storage_engine) !== strtolower($GLOBALS['tbl_storage_engine']) + ) { + $table_alters[] = 'ENGINE = ' . $new_tbl_storage_engine; + } + if (! empty($_REQUEST['tbl_collation']) + && $_REQUEST['tbl_collation'] !== $tbl_collation + ) { + $table_alters[] = 'DEFAULT ' + . PMA_generateCharsetQueryPart($_REQUEST['tbl_collation']); + } + + if (($is_myisam_or_aria || $is_isam) + && isset($_REQUEST['new_pack_keys']) + && $_REQUEST['new_pack_keys'] != (string)$pack_keys + ) { + $table_alters[] = 'pack_keys = ' . $_REQUEST['new_pack_keys']; + } + + $_REQUEST['new_checksum'] = empty($_REQUEST['new_checksum']) ? '0' : '1'; + if ($is_myisam_or_aria + && $_REQUEST['new_checksum'] !== $checksum + ) { + $table_alters[] = 'checksum = ' . $_REQUEST['new_checksum']; + } + + $_REQUEST['new_transactional'] + = empty($_REQUEST['new_transactional']) ? '0' : '1'; + if ($is_aria + && $_REQUEST['new_transactional'] !== $transactional + ) { + $table_alters[] = 'TRANSACTIONAL = ' . $_REQUEST['new_transactional']; + } + + $_REQUEST['new_page_checksum'] + = empty($_REQUEST['new_page_checksum']) ? '0' : '1'; + if ($is_aria + && $_REQUEST['new_page_checksum'] !== $page_checksum + ) { + $table_alters[] = 'PAGE_CHECKSUM = ' . $_REQUEST['new_page_checksum']; + } + + $_REQUEST['new_delay_key_write'] + = empty($_REQUEST['new_delay_key_write']) ? '0' : '1'; + if ($is_myisam_or_aria + && $_REQUEST['new_delay_key_write'] !== $delay_key_write + ) { + $table_alters[] = 'delay_key_write = ' . $_REQUEST['new_delay_key_write']; + } + + if (($is_myisam_or_aria || $is_innodb || $is_pbxt) + && ! empty($_REQUEST['new_auto_increment']) + && (! isset($auto_increment) + || $_REQUEST['new_auto_increment'] !== $auto_increment) + ) { + $table_alters[] = 'auto_increment = ' + . PMA_Util::sqlAddSlashes($_REQUEST['new_auto_increment']); + } + + if (($is_myisam_or_aria || $is_innodb || $is_pbxt) + && ! empty($_REQUEST['new_row_format']) + && (!strlen($row_format) + || strtolower($_REQUEST['new_row_format']) !== strtolower($row_format)) + ) { + $table_alters[] = 'ROW_FORMAT = ' + . PMA_Util::sqlAddSlashes($_REQUEST['new_row_format']); + } + + return $table_alters; +} + +/** + * set initial value of the set of variables, based on the current table engine + * + * @param string $tbl_storage_engine table storage engine + * + * @return array ($is_myisam_or_aria, $is_innodb, $is_isam, + * $is_berkeleydb, $is_aria, $is_pbxt) + */ +function PMA_setGlobalVariablesForEngine($tbl_storage_engine) +{ + $is_myisam_or_aria = $is_isam = $is_innodb = $is_berkeleydb + = $is_aria = $is_pbxt = false; + $upper_tbl_storage_engine = strtoupper($tbl_storage_engine); + + //Options that apply to MYISAM usually apply to ARIA + $is_myisam_or_aria = ($upper_tbl_storage_engine == 'MYISAM' + || $upper_tbl_storage_engine == 'ARIA' + || $upper_tbl_storage_engine == 'MARIA' + ); + $is_aria = ($upper_tbl_storage_engine == 'ARIA'); + + $is_isam = ($upper_tbl_storage_engine == 'ISAM'); + $is_innodb = ($upper_tbl_storage_engine == 'INNODB'); + $is_berkeleydb = ($upper_tbl_storage_engine == 'BERKELEYDB'); + $is_pbxt = ($upper_tbl_storage_engine == 'PBXT'); + + return array( + $is_myisam_or_aria, $is_innodb, $is_isam, + $is_berkeleydb, $is_aria, $is_pbxt + ); +} + +/** + * Get warning messages array + * + * @return array $warning_messages + */ +function PMA_getWarningMessagesArray() +{ + $warning_messages = array(); + foreach (PMA_DBI_get_warnings() as $warning) { + // In MariaDB 5.1.44, when altering a table from Maria to MyISAM + // and if TRANSACTIONAL was set, the system reports an error; + // I discussed with a Maria developer and he agrees that this + // should not be reported with a Level of Error, so here + // I just ignore it. But there are other 1478 messages + // that it's better to show. + if (! ($_REQUEST['new_tbl_storage_engine'] == 'MyISAM' + && $warning['Code'] == '1478' + && $warning['Level'] == 'Error') + ) { + $warning_messages[] = $warning['Level'] . ': #' . $warning['Code'] + . ' ' . $warning['Message']; + } + } + return $warning_messages; +} + +/** + * Get SQL query and result after ran this SQL query for a partition operation + * has been requested by the user + * + * @return array $sql_query, $result + */ +function PMA_getQueryAndResultForPartition() +{ + $sql_query = 'ALTER TABLE ' + . PMA_Util::backquote($GLOBALS['table']) . ' ' + . $_REQUEST['partition_operation'] + . ' PARTITION ' + . $_REQUEST['partition_name'] . ';'; + $result = PMA_DBI_query($sql_query); + + return array($sql_query, $result); +} + +?> diff --git a/phpmyadmin/libraries/parse_analyze.lib.php b/phpmyadmin/libraries/parse_analyze.lib.php new file mode 100644 index 000000000..9b9c80068 --- /dev/null +++ b/phpmyadmin/libraries/parse_analyze.lib.php @@ -0,0 +1,61 @@ + diff --git a/phpmyadmin/libraries/php-gettext/gettext.inc b/phpmyadmin/libraries/php-gettext/gettext.inc new file mode 100644 index 000000000..00b966692 --- /dev/null +++ b/phpmyadmin/libraries/php-gettext/gettext.inc @@ -0,0 +1,536 @@ + + Copyright (c) 2009 Danilo Segan + + Drop in replacement for native gettext. + + This file is part of PHP-gettext. + + PHP-gettext 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 2 of the License, or + (at your option) any later version. + + PHP-gettext 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 PHP-gettext; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +/* +LC_CTYPE 0 +LC_NUMERIC 1 +LC_TIME 2 +LC_COLLATE 3 +LC_MONETARY 4 +LC_MESSAGES 5 +LC_ALL 6 +*/ + +// LC_MESSAGES is not available if php-gettext is not loaded +// while the other constants are already available from session extension. +if (!defined('LC_MESSAGES')) { + define('LC_MESSAGES', 5); +} + +require('streams.php'); +require('gettext.php'); + + +// Variables + +global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE; +$text_domains = array(); +$default_domain = 'messages'; +$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL'); +$EMULATEGETTEXT = 0; +$CURRENTLOCALE = ''; + +/* Class to hold a single domain included in $text_domains. */ +class domain { + var $l10n; + var $path; + var $codeset; +} + +// Utility functions + +/** + * Return a list of locales to try for any POSIX-style locale specification. + */ +function get_list_of_locales($locale) { + /* Figure out all possible locale names and start with the most + * specific ones. I.e. for sr_CS.UTF-8@latin, look through all of + * sr_CS.UTF-8@latin, sr_CS@latin, sr@latin, sr_CS.UTF-8, sr_CS, sr. + */ + $locale_names = array(); + $lang = NULL; + $country = NULL; + $charset = NULL; + $modifier = NULL; + if ($locale) { + if (preg_match("/^(?P[a-z]{2,3})" // language code + ."(?:_(?P[A-Z]{2}))?" // country code + ."(?:\.(?P[-A-Za-z0-9_]+))?" // charset + ."(?:@(?P[-A-Za-z0-9_]+))?$/", // @ modifier + $locale, $matches)) { + + if (isset($matches["lang"])) $lang = $matches["lang"]; + if (isset($matches["country"])) $country = $matches["country"]; + if (isset($matches["charset"])) $charset = $matches["charset"]; + if (isset($matches["modifier"])) $modifier = $matches["modifier"]; + + if ($modifier) { + if ($country) { + if ($charset) + array_push($locale_names, "${lang}_$country.$charset@$modifier"); + array_push($locale_names, "${lang}_$country@$modifier"); + } elseif ($charset) + array_push($locale_names, "${lang}.$charset@$modifier"); + array_push($locale_names, "$lang@$modifier"); + } + if ($country) { + if ($charset) + array_push($locale_names, "${lang}_$country.$charset"); + array_push($locale_names, "${lang}_$country"); + } elseif ($charset) + array_push($locale_names, "${lang}.$charset"); + array_push($locale_names, $lang); + } + + // If the locale name doesn't match POSIX style, just include it as-is. + if (!in_array($locale, $locale_names)) + array_push($locale_names, $locale); + } + return $locale_names; +} + +/** + * Utility function to get a StreamReader for the given text domain. + */ +function _get_reader($domain=null, $category=5, $enable_cache=true) { + global $text_domains, $default_domain, $LC_CATEGORIES; + if (!isset($domain)) $domain = $default_domain; + if (!isset($text_domains[$domain]->l10n)) { + // get the current locale + $locale = _setlocale(LC_MESSAGES, 0); + $bound_path = isset($text_domains[$domain]->path) ? + $text_domains[$domain]->path : './'; + $subpath = $LC_CATEGORIES[$category] ."/$domain.mo"; + + $locale_names = get_list_of_locales($locale); + $input = null; + foreach ($locale_names as $locale) { + $full_path = $bound_path . $locale . "/" . $subpath; + if (file_exists($full_path)) { + $input = new FileReader($full_path); + break; + } + } + + if (!array_key_exists($domain, $text_domains)) { + // Initialize an empty domain object. + $text_domains[$domain] = new domain(); + } + $text_domains[$domain]->l10n = new gettext_reader($input, + $enable_cache); + } + return $text_domains[$domain]->l10n; +} + +/** + * Returns whether we are using our emulated gettext API or PHP built-in one. + */ +function locale_emulation() { + global $EMULATEGETTEXT; + return $EMULATEGETTEXT; +} + +/** + * Checks if the current locale is supported on this system. + */ +function _check_locale_and_function($function=false) { + global $EMULATEGETTEXT; + if ($function and !function_exists($function)) + return false; + return !$EMULATEGETTEXT; +} + +/** + * Get the codeset for the given domain. + */ +function _get_codeset($domain=null) { + global $text_domains, $default_domain, $LC_CATEGORIES; + if (!isset($domain)) $domain = $default_domain; + return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding'); +} + +/** + * Convert the given string to the encoding set by bind_textdomain_codeset. + */ +function _encode($text) { + $source_encoding = mb_detect_encoding($text); + $target_encoding = _get_codeset(); + if ($source_encoding != $target_encoding) { + return mb_convert_encoding($text, $target_encoding, $source_encoding); + } + else { + return $text; + } +} + + +// Custom implementation of the standard gettext related functions + +/** + * Returns passed in $locale, or environment variable $LANG if $locale == ''. + */ +function _get_default_locale($locale) { + if ($locale == '') // emulate variable support + return getenv('LANG'); + else + return $locale; +} + +/** + * Sets a requested locale, if needed emulates it. + */ +function _setlocale($category, $locale) { + global $CURRENTLOCALE, $EMULATEGETTEXT; + if ($locale === 0) { // use === to differentiate between string "0" + if ($CURRENTLOCALE != '') + return $CURRENTLOCALE; + else + // obey LANG variable, maybe extend to support all of LC_* vars + // even if we tried to read locale without setting it first + return _setlocale($category, $CURRENTLOCALE); + } else { + if (function_exists('setlocale')) { + $ret = setlocale($category, $locale); + if (($locale == '' and !$ret) or // failed setting it by env + ($locale != '' and $ret != $locale)) { // failed setting it + // Failed setting it according to environment. + $CURRENTLOCALE = _get_default_locale($locale); + $EMULATEGETTEXT = 1; + } else { + $CURRENTLOCALE = $ret; + $EMULATEGETTEXT = 0; + } + } else { + // No function setlocale(), emulate it all. + $CURRENTLOCALE = _get_default_locale($locale); + $EMULATEGETTEXT = 1; + } + // Allow locale to be changed on the go for one translation domain. + global $text_domains, $default_domain; + if (array_key_exists($default_domain, $text_domains)) { + unset($text_domains[$default_domain]->l10n); + } + return $CURRENTLOCALE; + } +} + +/** + * Sets the path for a domain. + */ +function _bindtextdomain($domain, $path) { + global $text_domains; + // ensure $path ends with a slash ('/' should work for both, but lets still play nice) + if (substr(php_uname(), 0, 7) == "Windows") { + if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/') + $path .= '\\'; + } else { + if ($path[strlen($path)-1] != '/') + $path .= '/'; + } + if (!array_key_exists($domain, $text_domains)) { + // Initialize an empty domain object. + $text_domains[$domain] = new domain(); + } + $text_domains[$domain]->path = $path; +} + +/** + * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. + */ +function _bind_textdomain_codeset($domain, $codeset) { + global $text_domains; + $text_domains[$domain]->codeset = $codeset; +} + +/** + * Sets the default domain. + */ +function _textdomain($domain) { + global $default_domain; + $default_domain = $domain; +} + +/** + * Lookup a message in the current domain. + */ +function _gettext($msgid) { + $l10n = _get_reader(); + return _encode($l10n->translate($msgid)); +} + +/** + * Alias for gettext. + */ +function __($msgid) { + return _gettext($msgid); +} + +/** + * Plural version of gettext. + */ +function _ngettext($singular, $plural, $number) { + $l10n = _get_reader(); + return _encode($l10n->ngettext($singular, $plural, $number)); +} + +/** + * Override the current domain. + */ +function _dgettext($domain, $msgid) { + $l10n = _get_reader($domain); + return _encode($l10n->translate($msgid)); +} + +/** + * Plural version of dgettext. + */ +function _dngettext($domain, $singular, $plural, $number) { + $l10n = _get_reader($domain); + return _encode($l10n->ngettext($singular, $plural, $number)); +} + +/** + * Overrides the domain and category for a single lookup. + */ +function _dcgettext($domain, $msgid, $category) { + $l10n = _get_reader($domain, $category); + return _encode($l10n->translate($msgid)); +} +/** + * Plural version of dcgettext. + */ +function _dcngettext($domain, $singular, $plural, $number, $category) { + $l10n = _get_reader($domain, $category); + return _encode($l10n->ngettext($singular, $plural, $number)); +} + +/** + * Context version of gettext. + */ +function _pgettext($context, $msgid) { + $l10n = _get_reader(); + return _encode($l10n->pgettext($context, $msgid)); +} + +/** + * Override the current domain in a context gettext call. + */ +function _dpgettext($domain, $context, $msgid) { + $l10n = _get_reader($domain); + return _encode($l10n->pgettext($context, $msgid)); +} + +/** + * Overrides the domain and category for a single context-based lookup. + */ +function _dcpgettext($domain, $context, $msgid, $category) { + $l10n = _get_reader($domain, $category); + return _encode($l10n->pgettext($context, $msgid)); +} + +/** + * Context version of ngettext. + */ +function _npgettext($context, $singular, $plural) { + $l10n = _get_reader(); + return _encode($l10n->npgettext($context, $singular, $plural)); +} + +/** + * Override the current domain in a context ngettext call. + */ +function _dnpgettext($domain, $context, $singular, $plural) { + $l10n = _get_reader($domain); + return _encode($l10n->npgettext($context, $singular, $plural)); +} + +/** + * Overrides the domain and category for a plural context-based lookup. + */ +function _dcnpgettext($domain, $context, $singular, $plural, $category) { + $l10n = _get_reader($domain, $category); + return _encode($l10n->npgettext($context, $singular, $plural)); +} + + + +// Wrappers to use if the standard gettext functions are available, +// but the current locale is not supported by the system. +// Use the standard impl if the current locale is supported, use the +// custom impl otherwise. + +function T_setlocale($category, $locale) { + return _setlocale($category, $locale); +} + +function T_bindtextdomain($domain, $path) { + if (_check_locale_and_function()) return bindtextdomain($domain, $path); + else return _bindtextdomain($domain, $path); +} +function T_bind_textdomain_codeset($domain, $codeset) { + // bind_textdomain_codeset is available only in PHP 4.2.0+ + if (_check_locale_and_function('bind_textdomain_codeset')) + return bind_textdomain_codeset($domain, $codeset); + else return _bind_textdomain_codeset($domain, $codeset); +} +function T_textdomain($domain) { + if (_check_locale_and_function()) return textdomain($domain); + else return _textdomain($domain); +} +function T_gettext($msgid) { + if (_check_locale_and_function()) return gettext($msgid); + else return _gettext($msgid); +} +function T_($msgid) { + if (_check_locale_and_function()) return _($msgid); + return __($msgid); +} +function T_ngettext($singular, $plural, $number) { + if (_check_locale_and_function()) + return ngettext($singular, $plural, $number); + else return _ngettext($singular, $plural, $number); +} +function T_dgettext($domain, $msgid) { + if (_check_locale_and_function()) return dgettext($domain, $msgid); + else return _dgettext($domain, $msgid); +} +function T_dngettext($domain, $singular, $plural, $number) { + if (_check_locale_and_function()) + return dngettext($domain, $singular, $plural, $number); + else return _dngettext($domain, $singular, $plural, $number); +} +function T_dcgettext($domain, $msgid, $category) { + if (_check_locale_and_function()) + return dcgettext($domain, $msgid, $category); + else return _dcgettext($domain, $msgid, $category); +} +function T_dcngettext($domain, $singular, $plural, $number, $category) { + if (_check_locale_and_function()) + return dcngettext($domain, $singular, $plural, $number, $category); + else return _dcngettext($domain, $singular, $plural, $number, $category); +} + +function T_pgettext($context, $msgid) { + if (_check_locale_and_function('pgettext')) + return pgettext($context, $msgid); + else + return _pgettext($context, $msgid); +} + +function T_dpgettext($domain, $context, $msgid) { + if (_check_locale_and_function('dpgettext')) + return dpgettext($domain, $context, $msgid); + else + return _dpgettext($domain, $context, $msgid); +} + +function T_dcpgettext($domain, $context, $msgid, $category) { + if (_check_locale_and_function('dcpgettext')) + return dcpgettext($domain, $context, $msgid, $category); + else + return _dcpgettext($domain, $context, $msgid, $category); +} + +function T_npgettext($context, $singular, $plural, $number) { + if (_check_locale_and_function('npgettext')) + return npgettext($context, $singular, $plural, $number); + else + return _npgettext($context, $singular, $plural, $number); +} + +function T_dnpgettext($domain, $context, $singular, $plural, $number) { + if (_check_locale_and_function('dnpgettext')) + return dnpgettext($domain, $context, $singular, $plural, $number); + else + return _dnpgettext($domain, $context, $singular, $plural, $number); +} + +function T_dcnpgettext($domain, $context, $singular, $plural, + $number, $category) { + if (_check_locale_and_function('dcnpgettext')) + return dcnpgettext($domain, $context, $singular, + $plural, $number, $category); + else + return _dcnpgettext($domain, $context, $singular, + $plural, $number, $category); +} + + + +// Wrappers used as a drop in replacement for the standard gettext functions + +if (!function_exists('gettext')) { + function bindtextdomain($domain, $path) { + return _bindtextdomain($domain, $path); + } + function bind_textdomain_codeset($domain, $codeset) { + return _bind_textdomain_codeset($domain, $codeset); + } + function textdomain($domain) { + return _textdomain($domain); + } + function gettext($msgid) { + return _gettext($msgid); + } + function _($msgid) { + return __($msgid); + } + function ngettext($singular, $plural, $number) { + return _ngettext($singular, $plural, $number); + } + function dgettext($domain, $msgid) { + return _dgettext($domain, $msgid); + } + function dngettext($domain, $singular, $plural, $number) { + return _dngettext($domain, $singular, $plural, $number); + } + function dcgettext($domain, $msgid, $category) { + return _dcgettext($domain, $msgid, $category); + } + function dcngettext($domain, $singular, $plural, $number, $category) { + return _dcngettext($domain, $singular, $plural, $number, $category); + } + function pgettext($context, $msgid) { + return _pgettext($context, $msgid); + } + function npgettext($context, $singular, $plural, $number) { + return _npgettext($context, $singular, $plural, $number); + } + function dpgettext($domain, $context, $msgid) { + return _dpgettext($domain, $context, $msgid); + } + function dnpgettext($domain, $context, $singular, $plural, $number) { + return _dnpgettext($domain, $context, $singular, $plural, $number); + } + function dcpgettext($domain, $context, $msgid, $category) { + return _dcpgettext($domain, $context, $msgid, $category); + } + function dcnpgettext($domain, $context, $singular, $plural, + $number, $category) { + return _dcnpgettext($domain, $context, $singular, $plural, + $number, $category); + } +} + +?> diff --git a/phpmyadmin/libraries/php-gettext/gettext.php b/phpmyadmin/libraries/php-gettext/gettext.php new file mode 100644 index 000000000..5064047cb --- /dev/null +++ b/phpmyadmin/libraries/php-gettext/gettext.php @@ -0,0 +1,432 @@ +. + Copyright (c) 2005 Nico Kaiser + + This file is part of PHP-gettext. + + PHP-gettext 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 2 of the License, or + (at your option) any later version. + + PHP-gettext 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 PHP-gettext; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/** + * Provides a simple gettext replacement that works independently from + * the system's gettext abilities. + * It can read MO files and use them for translating strings. + * The files are passed to gettext_reader as a Stream (see streams.php) + * + * This version has the ability to cache all strings and translations to + * speed up the string lookup. + * While the cache is enabled by default, it can be switched off with the + * second parameter in the constructor (e.g. whenusing very large MO files + * that you don't want to keep in memory) + */ +class gettext_reader { + //public: + var $error = 0; // public variable that holds error code (0 if no error) + + //private: + var $BYTEORDER = 0; // 0: low endian, 1: big endian + var $STREAM = NULL; + var $short_circuit = false; + var $enable_cache = false; + var $originals = NULL; // offset of original table + var $translations = NULL; // offset of translation table + var $pluralheader = NULL; // cache header field for plural forms + var $total = 0; // total string count + var $table_originals = NULL; // table for original strings (offsets) + var $table_translations = NULL; // table for translated strings (offsets) + var $cache_translations = NULL; // original -> translation mapping + + + /* Methods */ + + + /** + * Reads a 32bit Integer from the Stream + * + * @access private + * @return Integer from the Stream + */ + function readint() { + if ($this->BYTEORDER == 0) { + // low endian + $input=unpack('V', $this->STREAM->read(4)); + return array_shift($input); + } else { + // big endian + $input=unpack('N', $this->STREAM->read(4)); + return array_shift($input); + } + } + + function read($bytes) { + return $this->STREAM->read($bytes); + } + + /** + * Reads an array of Integers from the Stream + * + * @param int count How many elements should be read + * @return Array of Integers + */ + function readintarray($count) { + if ($this->BYTEORDER == 0) { + // low endian + return unpack('V'.$count, $this->STREAM->read(4 * $count)); + } else { + // big endian + return unpack('N'.$count, $this->STREAM->read(4 * $count)); + } + } + + /** + * Constructor + * + * @param object Reader the StreamReader object + * @param boolean enable_cache Enable or disable caching of strings (default on) + */ + function gettext_reader($Reader, $enable_cache = true) { + // If there isn't a StreamReader, turn on short circuit mode. + if (! $Reader || isset($Reader->error) ) { + $this->short_circuit = true; + return; + } + + // Caching can be turned off + $this->enable_cache = $enable_cache; + + $MAGIC1 = "\x95\x04\x12\xde"; + $MAGIC2 = "\xde\x12\x04\x95"; + + $this->STREAM = $Reader; + $magic = $this->read(4); + if ($magic == $MAGIC1) { + $this->BYTEORDER = 1; + } elseif ($magic == $MAGIC2) { + $this->BYTEORDER = 0; + } else { + $this->error = 1; // not MO file + return false; + } + + // FIXME: Do we care about revision? We should. + $revision = $this->readint(); + + $this->total = $this->readint(); + $this->originals = $this->readint(); + $this->translations = $this->readint(); + } + + /** + * Loads the translation tables from the MO file into the cache + * If caching is enabled, also loads all strings into a cache + * to speed up translation lookups + * + * @access private + */ + function load_tables() { + if (is_array($this->cache_translations) && + is_array($this->table_originals) && + is_array($this->table_translations)) + return; + + /* get original and translations tables */ + if (!is_array($this->table_originals)) { + $this->STREAM->seekto($this->originals); + $this->table_originals = $this->readintarray($this->total * 2); + } + if (!is_array($this->table_translations)) { + $this->STREAM->seekto($this->translations); + $this->table_translations = $this->readintarray($this->total * 2); + } + + if ($this->enable_cache) { + $this->cache_translations = array (); + /* read all strings in the cache */ + for ($i = 0; $i < $this->total; $i++) { + $this->STREAM->seekto($this->table_originals[$i * 2 + 2]); + $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]); + $this->STREAM->seekto($this->table_translations[$i * 2 + 2]); + $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]); + $this->cache_translations[$original] = $translation; + } + } + } + + /** + * Returns a string from the "originals" table + * + * @access private + * @param int num Offset number of original string + * @return string Requested string if found, otherwise '' + */ + function get_original_string($num) { + $length = $this->table_originals[$num * 2 + 1]; + $offset = $this->table_originals[$num * 2 + 2]; + if (! $length) + return ''; + $this->STREAM->seekto($offset); + $data = $this->STREAM->read($length); + return (string)$data; + } + + /** + * Returns a string from the "translations" table + * + * @access private + * @param int num Offset number of original string + * @return string Requested string if found, otherwise '' + */ + function get_translation_string($num) { + $length = $this->table_translations[$num * 2 + 1]; + $offset = $this->table_translations[$num * 2 + 2]; + if (! $length) + return ''; + $this->STREAM->seekto($offset); + $data = $this->STREAM->read($length); + return (string)$data; + } + + /** + * Binary search for string + * + * @access private + * @param string string + * @param int start (internally used in recursive function) + * @param int end (internally used in recursive function) + * @return int string number (offset in originals table) + */ + function find_string($string, $start = -1, $end = -1) { + if (($start == -1) or ($end == -1)) { + // find_string is called with only one parameter, set start end end + $start = 0; + $end = $this->total; + } + if (abs($start - $end) <= 1) { + // We're done, now we either found the string, or it doesn't exist + $txt = $this->get_original_string($start); + if ($string == $txt) + return $start; + else + return -1; + } else if ($start > $end) { + // start > end -> turn around and start over + return $this->find_string($string, $end, $start); + } else { + // Divide table in two parts + $half = (int)(($start + $end) / 2); + $cmp = strcmp($string, $this->get_original_string($half)); + if ($cmp == 0) + // string is exactly in the middle => return it + return $half; + else if ($cmp < 0) + // The string is in the upper half + return $this->find_string($string, $start, $half); + else + // The string is in the lower half + return $this->find_string($string, $half, $end); + } + } + + /** + * Translates a string + * + * @access public + * @param string string to be translated + * @return string translated string (or original, if not found) + */ + function translate($string) { + if ($this->short_circuit) + return $string; + $this->load_tables(); + + if ($this->enable_cache) { + // Caching enabled, get translated string from cache + if (array_key_exists($string, $this->cache_translations)) + return $this->cache_translations[$string]; + else + return $string; + } else { + // Caching not enabled, try to find string + $num = $this->find_string($string); + if ($num == -1) + return $string; + else + return $this->get_translation_string($num); + } + } + + /** + * Sanitize plural form expression for use in PHP eval call. + * + * @access private + * @return string sanitized plural form expression + */ + function sanitize_plural_expression($expr) { + // Get rid of disallowed characters. + $expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr); + + // Add parenthesis for tertiary '?' operator. + $expr .= ';'; + $res = ''; + $p = 0; + for ($i = 0; $i < strlen($expr); $i++) { + $ch = $expr[$i]; + switch ($ch) { + case '?': + $res .= ' ? ('; + $p++; + break; + case ':': + $res .= ') : ('; + break; + case ';': + $res .= str_repeat( ')', $p) . ';'; + $p = 0; + break; + default: + $res .= $ch; + } + } + return $res; + } + + /** + * Parse full PO header and extract only plural forms line. + * + * @access private + * @return string verbatim plural form header field + */ + function extract_plural_forms_header_from_po_header($header) { + if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs)) + $expr = $regs[2]; + else + $expr = "nplurals=2; plural=n == 1 ? 0 : 1;"; + return $expr; + } + + /** + * Get possible plural forms from MO header + * + * @access private + * @return string plural form header + */ + function get_plural_forms() { + // lets assume message number 0 is header + // this is true, right? + $this->load_tables(); + + // cache header field for plural forms + if (! is_string($this->pluralheader)) { + if ($this->enable_cache) { + $header = $this->cache_translations[""]; + } else { + $header = $this->get_translation_string(0); + } + $expr = $this->extract_plural_forms_header_from_po_header($header); + $this->pluralheader = $this->sanitize_plural_expression($expr); + } + return $this->pluralheader; + } + + /** + * Detects which plural form to take + * + * @access private + * @param n count + * @return int array index of the right plural form + */ + function select_string($n) { + $string = $this->get_plural_forms(); + $string = str_replace('nplurals',"\$total",$string); + $string = str_replace("n",$n,$string); + $string = str_replace('plural',"\$plural",$string); + + $total = 0; + $plural = 0; + + eval("$string"); + if ($plural >= $total) $plural = $total - 1; + return $plural; + } + + /** + * Plural version of gettext + * + * @access public + * @param string single + * @param string plural + * @param string number + * @return translated plural form + */ + function ngettext($single, $plural, $number) { + if ($this->short_circuit) { + if ($number != 1) + return $plural; + else + return $single; + } + + // find out the appropriate form + $select = $this->select_string($number); + + // this should contains all strings separated by NULLs + $key = $single . chr(0) . $plural; + + + if ($this->enable_cache) { + if (! array_key_exists($key, $this->cache_translations)) { + return ($number != 1) ? $plural : $single; + } else { + $result = $this->cache_translations[$key]; + $list = explode(chr(0), $result); + return $list[$select]; + } + } else { + $num = $this->find_string($key); + if ($num == -1) { + return ($number != 1) ? $plural : $single; + } else { + $result = $this->get_translation_string($num); + $list = explode(chr(0), $result); + return $list[$select]; + } + } + } + + function pgettext($context, $msgid) { + $key = $context . chr(4) . $msgid; + $ret = $this->translate($key); + if (strpos($ret, "\004") !== FALSE) { + return $msgid; + } else { + return $ret; + } + } + + function npgettext($context, $singular, $plural, $number) { + $key = $context . chr(4) . $singular; + $ret = $this->ngettext($key, $plural, $number); + if (strpos($ret, "\004") !== FALSE) { + return $singular; + } else { + return $ret; + } + + } +} + +?> diff --git a/phpmyadmin/libraries/php-gettext/streams.php b/phpmyadmin/libraries/php-gettext/streams.php new file mode 100644 index 000000000..3cdc1584e --- /dev/null +++ b/phpmyadmin/libraries/php-gettext/streams.php @@ -0,0 +1,167 @@ +. + + This file is part of PHP-gettext. + + PHP-gettext 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 2 of the License, or + (at your option) any later version. + + PHP-gettext 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 PHP-gettext; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + + + // Simple class to wrap file streams, string streams, etc. + // seek is essential, and it should be byte stream +class StreamReader { + // should return a string [FIXME: perhaps return array of bytes?] + function read($bytes) { + return false; + } + + // should return new position + function seekto($position) { + return false; + } + + // returns current position + function currentpos() { + return false; + } + + // returns length of entire stream (limit for seekto()s) + function length() { + return false; + } +}; + +class StringReader { + var $_pos; + var $_str; + + function StringReader($str='') { + $this->_str = $str; + $this->_pos = 0; + } + + function read($bytes) { + $data = substr($this->_str, $this->_pos, $bytes); + $this->_pos += $bytes; + if (strlen($this->_str)<$this->_pos) + $this->_pos = strlen($this->_str); + + return $data; + } + + function seekto($pos) { + $this->_pos = $pos; + if (strlen($this->_str)<$this->_pos) + $this->_pos = strlen($this->_str); + return $this->_pos; + } + + function currentpos() { + return $this->_pos; + } + + function length() { + return strlen($this->_str); + } + +}; + + +class FileReader { + var $_pos; + var $_fd; + var $_length; + + function FileReader($filename) { + if (file_exists($filename)) { + + $this->_length=filesize($filename); + $this->_pos = 0; + $this->_fd = fopen($filename,'rb'); + if (!$this->_fd) { + $this->error = 3; // Cannot read file, probably permissions + return false; + } + } else { + $this->error = 2; // File doesn't exist + return false; + } + } + + function read($bytes) { + if ($bytes) { + fseek($this->_fd, $this->_pos); + + // PHP 5.1.1 does not read more than 8192 bytes in one fread() + // the discussions at PHP Bugs suggest it's the intended behaviour + $data = ''; + while ($bytes > 0) { + $chunk = fread($this->_fd, $bytes); + $data .= $chunk; + $bytes -= strlen($chunk); + } + $this->_pos = ftell($this->_fd); + + return $data; + } else return ''; + } + + function seekto($pos) { + fseek($this->_fd, $pos); + $this->_pos = ftell($this->_fd); + return $this->_pos; + } + + function currentpos() { + return $this->_pos; + } + + function length() { + return $this->_length; + } + + function close() { + fclose($this->_fd); + } + +}; + +// Preloads entire file in memory first, then creates a StringReader +// over it (it assumes knowledge of StringReader internals) +class CachedFileReader extends StringReader { + function CachedFileReader($filename) { + if (file_exists($filename)) { + + $length=filesize($filename); + $fd = fopen($filename,'rb'); + + if (!$fd) { + $this->error = 3; // Cannot read file, probably permissions + return false; + } + $this->_str = fread($fd, $length); + fclose($fd); + + } else { + $this->error = 2; // File doesn't exist + return false; + } + } +}; + + +?> diff --git a/phpmyadmin/libraries/phpseclib/Crypt/AES.php b/phpmyadmin/libraries/phpseclib/Crypt/AES.php new file mode 100644 index 000000000..58c8b52c9 --- /dev/null +++ b/phpmyadmin/libraries/phpseclib/Crypt/AES.php @@ -0,0 +1,612 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $aes->decrypt($aes->encrypt($plaintext)); + * ?> + * + * + * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @category Crypt + * @package Crypt_AES + * @author Jim Wigginton + * @copyright MMVIII Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $ + * @link http://phpseclib.sourceforge.net + */ + +/** + * Include Crypt_Rijndael + */ +if (!class_exists('Crypt_Rijndael')) { + require_once 'Rijndael.php'; +} + +/**#@+ + * @access public + * @see Crypt_AES::encrypt() + * @see Crypt_AES::decrypt() + */ +/** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + */ +define('CRYPT_AES_MODE_CTR', -1); +/** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + */ +define('CRYPT_AES_MODE_ECB', 1); +/** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + */ +define('CRYPT_AES_MODE_CBC', 2); +/** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + */ +define('CRYPT_AES_MODE_CFB', 3); +/** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + */ +define('CRYPT_AES_MODE_OFB', 4); +/**#@-*/ + +/**#@+ + * @access private + * @see Crypt_AES::Crypt_AES() + */ +/** + * Toggles the internal implementation + */ +define('CRYPT_AES_MODE_INTERNAL', 1); +/** + * Toggles the mcrypt implementation + */ +define('CRYPT_AES_MODE_MCRYPT', 2); +/**#@-*/ + +/** + * Pure-PHP implementation of AES. + * + * @author Jim Wigginton + * @version 0.1.0 + * @access public + * @package Crypt_AES + */ +class Crypt_AES extends Crypt_Rijndael { + /** + * mcrypt resource for encryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see Crypt_AES::encrypt() + * @var String + * @access private + */ + var $enmcrypt; + + /** + * mcrypt resource for decryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see Crypt_AES::decrypt() + * @var String + * @access private + */ + var $demcrypt; + + /** + * mcrypt resource for CFB mode + * + * @see Crypt_AES::encrypt() + * @see Crypt_AES::decrypt() + * @var String + * @access private + */ + var $ecb; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be + * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used. + * + * @param optional Integer $mode + * @return Crypt_AES + * @access public + */ + function Crypt_AES($mode = CRYPT_AES_MODE_CBC) + { + if ( !defined('CRYPT_AES_MODE') ) { + switch (true) { + case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()): + define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT); + break; + default: + define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL); + } + } + + switch ( CRYPT_AES_MODE ) { + case CRYPT_AES_MODE_MCRYPT: + switch ($mode) { + case CRYPT_AES_MODE_ECB: + $this->paddable = true; + $this->mode = MCRYPT_MODE_ECB; + break; + case CRYPT_AES_MODE_CTR: + // ctr doesn't have a constant associated with it even though it appears to be fairly widely + // supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to + // include a compatibility layer. the layer has been implemented but, for now, is commented out. + $this->mode = 'ctr'; + //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR; + break; + case CRYPT_AES_MODE_CFB: + $this->mode = 'ncfb'; + break; + case CRYPT_AES_MODE_OFB: + $this->mode = MCRYPT_MODE_NOFB; + break; + case CRYPT_AES_MODE_CBC: + default: + $this->paddable = true; + $this->mode = MCRYPT_MODE_CBC; + } + + $this->debuffer = $this->enbuffer = ''; + + break; + default: + switch ($mode) { + case CRYPT_AES_MODE_ECB: + $this->paddable = true; + $this->mode = CRYPT_RIJNDAEL_MODE_ECB; + break; + case CRYPT_AES_MODE_CTR: + $this->mode = CRYPT_RIJNDAEL_MODE_CTR; + break; + case CRYPT_AES_MODE_CFB: + $this->mode = CRYPT_RIJNDAEL_MODE_CFB; + break; + case CRYPT_AES_MODE_OFB: + $this->mode = CRYPT_RIJNDAEL_MODE_OFB; + break; + case CRYPT_AES_MODE_CBC: + default: + $this->paddable = true; + $this->mode = CRYPT_RIJNDAEL_MODE_CBC; + } + } + + if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) { + parent::Crypt_Rijndael($this->mode); + } + } + + /** + * Dummy function + * + * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything. + * + * @access public + * @param Integer $length + */ + function setBlockLength($length) + { + return; + } + + + /** + * Sets the initialization vector. (optional) + * + * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed + * to be all zero's. + * + * @access public + * @param String $iv + */ + function setIV($iv) + { + parent::setIV($iv); + if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) { + $this->changed = true; + } + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the + * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that + * length. + * + * @see Crypt_AES::decrypt() + * @access public + * @param String $plaintext + */ + function encrypt($plaintext) + { + if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) { + $changed = $this->changed; + $this->_mcryptSetup(); + /* + if ($this->mode == CRYPT_AES_MODE_CTR) { + $iv = $this->encryptIV; + $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv)); + $ciphertext = $plaintext ^ $xor; + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + return $ciphertext; + } + */ + // re: http://phpseclib.sourceforge.net/cfb-demo.phps + // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's + // rewritten CFB implementation the above outputs the same thing twice. + if ($this->mode == 'ncfb') { + if ($changed) { + $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); + mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); + } + + if (strlen($this->enbuffer)) { + $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer)); + $this->enbuffer.= $ciphertext; + if (strlen($this->enbuffer) == 16) { + $this->encryptIV = $this->enbuffer; + $this->enbuffer = ''; + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + } + $plaintext = substr($plaintext, strlen($ciphertext)); + } else { + $ciphertext = ''; + } + + $last_pos = strlen($plaintext) & 0xFFFFFFF0; + $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : ''; + + if (strlen($plaintext) & 0xF) { + if (strlen($ciphertext)) { + $this->encryptIV = substr($ciphertext, -16); + } + $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV); + $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV; + $ciphertext.= $this->enbuffer; + } + + return $ciphertext; + } + + if ($this->paddable) { + $plaintext = $this->_pad($plaintext); + } + + $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); + + if (!$this->continuousBuffer) { + mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv); + } + + return $ciphertext; + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is. + * + * @see Crypt_AES::encrypt() + * @access public + * @param String $ciphertext + */ + function decrypt($ciphertext) + { + if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) { + $changed = $this->changed; + $this->_mcryptSetup(); + /* + if ($this->mode == CRYPT_AES_MODE_CTR) { + $iv = $this->decryptIV; + $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv)); + $plaintext = $ciphertext ^ $xor; + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + return $plaintext; + } + */ + if ($this->mode == 'ncfb') { + if ($changed) { + $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); + mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); + } + + if (strlen($this->debuffer)) { + $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer)); + + $this->debuffer.= substr($ciphertext, 0, strlen($plaintext)); + if (strlen($this->debuffer) == 16) { + $this->decryptIV = $this->debuffer; + $this->debuffer = ''; + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + } + $ciphertext = substr($ciphertext, strlen($plaintext)); + } else { + $plaintext = ''; + } + + $last_pos = strlen($ciphertext) & 0xFFFFFFF0; + $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : ''; + + if (strlen($ciphertext) & 0xF) { + if (strlen($plaintext)) { + $this->decryptIV = substr($ciphertext, $last_pos - 16, 16); + } + $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV); + $this->debuffer = substr($ciphertext, $last_pos); + $plaintext.= $this->debuffer ^ $this->decryptIV; + } + + return $plaintext; + } + + if ($this->paddable) { + // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic : + // "The data is padded with "\0" to make sure the length of the data is n * blocksize." + $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0)); + } + + $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); + + if (!$this->continuousBuffer) { + mcrypt_generic_init($this->demcrypt, $this->key, $this->iv); + } + + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + return parent::decrypt($ciphertext); + } + + /** + * Setup mcrypt + * + * Validates all the variables. + * + * @access private + */ + function _mcryptSetup() + { + if (!$this->changed) { + return; + } + + if (!$this->explicit_key_length) { + // this just copied from Crypt_Rijndael::_setup() + $length = strlen($this->key) >> 2; + if ($length > 8) { + $length = 8; + } else if ($length < 4) { + $length = 4; + } + $this->Nk = $length; + $this->key_size = $length << 2; + } + + switch ($this->Nk) { + case 4: // 128 + $this->key_size = 16; + break; + case 5: // 160 + case 6: // 192 + $this->key_size = 24; + break; + case 7: // 224 + case 8: // 256 + $this->key_size = 32; + } + + $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0)); + $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0)); + + if (!isset($this->enmcrypt)) { + $mode = $this->mode; + //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode; + + $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, ''); + $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, ''); + } // else should mcrypt_generic_deinit be called? + + mcrypt_generic_init($this->demcrypt, $this->key, $this->iv); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv); + + $this->changed = false; + } + + /** + * Encrypts a block + * + * Optimized over Crypt_Rijndael's implementation by means of loop unrolling. + * + * @see Crypt_Rijndael::_encryptBlock() + * @access private + * @param String $in + * @return String + */ + function _encryptBlock($in) + { + $state = unpack('N*word', $in); + + $Nr = $this->Nr; + $w = $this->w; + $t0 = $this->t0; + $t1 = $this->t1; + $t2 = $this->t2; + $t3 = $this->t3; + + // addRoundKey and reindex $state + $state = array( + $state['word1'] ^ $w[0][0], + $state['word2'] ^ $w[0][1], + $state['word3'] ^ $w[0][2], + $state['word4'] ^ $w[0][3] + ); + + // shiftRows + subWord + mixColumns + addRoundKey + // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields + // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it. + for ($round = 1; $round < $this->Nr; $round++) { + $state = array( + $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0], + $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1], + $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2], + $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3] + ); + + } + + // subWord + $state = array( + $this->_subWord($state[0]), + $this->_subWord($state[1]), + $this->_subWord($state[2]), + $this->_subWord($state[3]) + ); + + // shiftRows + addRoundKey + $state = array( + ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0], + ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1], + ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2], + ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3] + ); + + return pack('N*', $state[0], $state[1], $state[2], $state[3]); + } + + /** + * Decrypts a block + * + * Optimized over Crypt_Rijndael's implementation by means of loop unrolling. + * + * @see Crypt_Rijndael::_decryptBlock() + * @access private + * @param String $in + * @return String + */ + function _decryptBlock($in) + { + $state = unpack('N*word', $in); + + $Nr = $this->Nr; + $dw = $this->dw; + $dt0 = $this->dt0; + $dt1 = $this->dt1; + $dt2 = $this->dt2; + $dt3 = $this->dt3; + + // addRoundKey and reindex $state + $state = array( + $state['word1'] ^ $dw[$this->Nr][0], + $state['word2'] ^ $dw[$this->Nr][1], + $state['word3'] ^ $dw[$this->Nr][2], + $state['word4'] ^ $dw[$this->Nr][3] + ); + + + // invShiftRows + invSubBytes + invMixColumns + addRoundKey + for ($round = $this->Nr - 1; $round > 0; $round--) { + $state = array( + $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0], + $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1], + $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2], + $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3] + ); + } + + // invShiftRows + invSubWord + addRoundKey + $state = array( + $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0], + $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1], + $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2], + $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3] + ); + + return pack('N*', $state[0], $state[1], $state[2], $state[3]); + } +} + +// vim: ts=4:sw=4:et: +// vim6: fdl=1: +?> diff --git a/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php b/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php new file mode 100644 index 000000000..b5aef38a9 --- /dev/null +++ b/phpmyadmin/libraries/phpseclib/Crypt/Rijndael.php @@ -0,0 +1,1479 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); + * ?> + * + * + * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @category Crypt + * @package Crypt_Rijndael + * @author Jim Wigginton + * @copyright MMVIII Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $ + * @link http://phpseclib.sourceforge.net + */ + +/**#@+ + * @access public + * @see Crypt_Rijndael::encrypt() + * @see Crypt_Rijndael::decrypt() + */ +/** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + */ +define('CRYPT_RIJNDAEL_MODE_CTR', -1); +/** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + */ +define('CRYPT_RIJNDAEL_MODE_ECB', 1); +/** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + */ +define('CRYPT_RIJNDAEL_MODE_CBC', 2); +/** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + */ +define('CRYPT_RIJNDAEL_MODE_CFB', 3); +/** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + */ +define('CRYPT_RIJNDAEL_MODE_OFB', 4); +/**#@-*/ + +/**#@+ + * @access private + * @see Crypt_Rijndael::Crypt_Rijndael() + */ +/** + * Toggles the internal implementation + */ +define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1); +/** + * Toggles the mcrypt implementation + */ +define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2); +/**#@-*/ + +/** + * Pure-PHP implementation of Rijndael. + * + * @author Jim Wigginton + * @version 0.1.0 + * @access public + * @package Crypt_Rijndael + */ +class Crypt_Rijndael { + /** + * The Encryption Mode + * + * @see Crypt_Rijndael::Crypt_Rijndael() + * @var Integer + * @access private + */ + var $mode; + + /** + * The Key + * + * @see Crypt_Rijndael::setKey() + * @var String + * @access private + */ + var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + /** + * The Initialization Vector + * + * @see Crypt_Rijndael::setIV() + * @var String + * @access private + */ + var $iv = ''; + + /** + * A "sliding" Initialization Vector + * + * @see Crypt_Rijndael::enableContinuousBuffer() + * @var String + * @access private + */ + var $encryptIV = ''; + + /** + * A "sliding" Initialization Vector + * + * @see Crypt_Rijndael::enableContinuousBuffer() + * @var String + * @access private + */ + var $decryptIV = ''; + + /** + * Continuous Buffer status + * + * @see Crypt_Rijndael::enableContinuousBuffer() + * @var Boolean + * @access private + */ + var $continuousBuffer = false; + + /** + * Padding status + * + * @see Crypt_Rijndael::enablePadding() + * @var Boolean + * @access private + */ + var $padding = true; + + /** + * Does the key schedule need to be (re)calculated? + * + * @see setKey() + * @see setBlockLength() + * @see setKeyLength() + * @var Boolean + * @access private + */ + var $changed = true; + + /** + * Has the key length explicitly been set or should it be derived from the key, itself? + * + * @see setKeyLength() + * @var Boolean + * @access private + */ + var $explicit_key_length = false; + + /** + * The Key Schedule + * + * @see _setup() + * @var Array + * @access private + */ + var $w; + + /** + * The Inverse Key Schedule + * + * @see _setup() + * @var Array + * @access private + */ + var $dw; + + /** + * The Block Length + * + * @see setBlockLength() + * @var Integer + * @access private + * @internal The max value is 32, the min value is 16. All valid values are multiples of 4. Exists in conjunction with + * $Nb because we need this value and not $Nb to pad strings appropriately. + */ + var $block_size = 16; + + /** + * The Block Length divided by 32 + * + * @see setBlockLength() + * @var Integer + * @access private + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could + * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once. + * + */ + var $Nb = 4; + + /** + * The Key Length + * + * @see setKeyLength() + * @var Integer + * @access private + * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $key_size + * because the encryption / decryption / key schedule creation requires this number and not $key_size. We could + * derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once. + */ + var $key_size = 16; + + /** + * The Key Length divided by 32 + * + * @see setKeyLength() + * @var Integer + * @access private + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 + */ + var $Nk = 4; + + /** + * The Number of Rounds + * + * @var Integer + * @access private + * @internal The max value is 14, the min value is 10. + */ + var $Nr; + + /** + * Shift offsets + * + * @var Array + * @access private + */ + var $c; + + /** + * Precomputed mixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $t0; + + /** + * Precomputed mixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $t1; + + /** + * Precomputed mixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $t2; + + /** + * Precomputed mixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $t3; + + /** + * Precomputed invMixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $dt0; + + /** + * Precomputed invMixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $dt1; + + /** + * Precomputed invMixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $dt2; + + /** + * Precomputed invMixColumns table + * + * @see Crypt_Rijndael() + * @var Array + * @access private + */ + var $dt3; + + /** + * Is the mode one that is paddable? + * + * @see Crypt_Rijndael::Crypt_Rijndael() + * @var Boolean + * @access private + */ + var $paddable = false; + + /** + * Encryption buffer for CTR, OFB and CFB modes + * + * @see Crypt_Rijndael::encrypt() + * @var String + * @access private + */ + var $enbuffer = array('encrypted' => '', 'xor' => ''); + + /** + * Decryption buffer for CTR, OFB and CFB modes + * + * @see Crypt_Rijndael::decrypt() + * @var String + * @access private + */ + var $debuffer = array('ciphertext' => ''); + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be + * CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC. If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used. + * + * @param optional Integer $mode + * @return Crypt_Rijndael + * @access public + */ + function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC) + { + switch ($mode) { + case CRYPT_RIJNDAEL_MODE_ECB: + case CRYPT_RIJNDAEL_MODE_CBC: + $this->paddable = true; + $this->mode = $mode; + break; + case CRYPT_RIJNDAEL_MODE_CTR: + case CRYPT_RIJNDAEL_MODE_CFB: + case CRYPT_RIJNDAEL_MODE_OFB: + $this->mode = $mode; + break; + default: + $this->paddable = true; + $this->mode = CRYPT_RIJNDAEL_MODE_CBC; + } + + $t3 = &$this->t3; + $t2 = &$this->t2; + $t1 = &$this->t1; + $t0 = &$this->t0; + + $dt3 = &$this->dt3; + $dt2 = &$this->dt2; + $dt1 = &$this->dt1; + $dt0 = &$this->dt0; + + // according to (section 5.2.1), + // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so + // those are the names we'll use. + $t3 = array( + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C + ); + + $dt3 = array( + 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, + 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, + 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, + 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, + 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, + 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, + 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, + 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, + 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, + 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, + 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, + 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, + 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, + 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, + 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, + 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, + 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, + 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, + 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, + 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, + 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, + 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, + 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, + 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, + 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, + 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, + 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, + 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, + 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, + 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, + 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, + 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 + ); + + for ($i = 0; $i < 256; $i++) { + $t2[$i << 8] = (($t3[$i] << 8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF); + $t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF); + $t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >> 8) & 0x00FFFFFF); + + $dt2[$i << 8] = (($this->dt3[$i] << 8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF); + $dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF); + $dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >> 8) & 0x00FFFFFF); + } + } + + /** + * Sets the key. + * + * Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and + * whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length + * up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the + * excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * @access public + * @param String $key + */ + function setKey($key) + { + $this->key = $key; + $this->changed = true; + } + + /** + * Sets the initialization vector. (optional) + * + * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used. If not explictly set, it'll be assumed + * to be all zero's. + * + * @access public + * @param String $iv + */ + function setIV($iv) + { + $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0)); + } + + /** + * Sets the key length + * + * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount. + * + * @access public + * @param Integer $length + */ + function setKeyLength($length) + { + $length >>= 5; + if ($length > 8) { + $length = 8; + } else if ($length < 4) { + $length = 4; + } + $this->Nk = $length; + $this->key_size = $length << 2; + + $this->explicit_key_length = true; + $this->changed = true; + } + + /** + * Sets the password. + * + * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}: + * $hash, $salt, $count + * Set $dkLen by calling setKeyLength() + * + * @param String $password + * @param optional String $method + * @access public + */ + function setPassword($password, $method = 'pbkdf2') + { + $key = ''; + + switch ($method) { + default: // 'pbkdf2' + list(, , $hash, $salt, $count) = func_get_args(); + if (!isset($hash)) { + $hash = 'sha1'; + } + // WPA and WPA use the SSID as the salt + if (!isset($salt)) { + $salt = 'phpseclib/salt'; + } + // RFC2898#section-4.2 uses 1,000 iterations by default + // WPA and WPA2 use 4,096. + if (!isset($count)) { + $count = 1000; + } + + if (!class_exists('Crypt_Hash')) { + require_once('Crypt/Hash.php'); + } + + $i = 1; + while (strlen($key) < $this->key_size) { // $dkLen == $this->key_size + //$dk.= $this->_pbkdf($password, $salt, $count, $i++); + $hmac = new Crypt_Hash(); + $hmac->setHash($hash); + $hmac->setKey($password); + $f = $u = $hmac->hash($salt . pack('N', $i++)); + for ($j = 2; $j <= $count; $j++) { + $u = $hmac->hash($u); + $f^= $u; + } + $key.= $f; + } + } + + $this->setKey(substr($key, 0, $this->key_size)); + } + + /** + * Sets the block length + * + * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount. + * + * @access public + * @param Integer $length + */ + function setBlockLength($length) + { + $length >>= 5; + if ($length > 8) { + $length = 8; + } else if ($length < 4) { + $length = 4; + } + $this->Nb = $length; + $this->block_size = $length << 2; + $this->changed = true; + } + + /** + * Generate CTR XOR encryption key + * + * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the + * plaintext / ciphertext in CTR mode. + * + * @see Crypt_Rijndael::decrypt() + * @see Crypt_Rijndael::encrypt() + * @access public + * @param Integer $length + * @param String $iv + */ + function _generate_xor($length, &$iv) + { + $xor = ''; + $block_size = $this->block_size; + $num_blocks = floor(($length + ($block_size - 1)) / $block_size); + for ($i = 0; $i < $num_blocks; $i++) { + $xor.= $iv; + for ($j = 4; $j <= $block_size; $j+=4) { + $temp = substr($iv, -$j, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4); + break; + case "\x7F\xFF\xFF\xFF": + $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4); + break 2; + default: + extract(unpack('Ncount', $temp)); + $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4); + break 2; + } + } + } + + return $xor; + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other Rjindael + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that + * length. + * + * @see Crypt_Rijndael::decrypt() + * @access public + * @param String $plaintext + */ + function encrypt($plaintext) + { + $this->_setup(); + if ($this->paddable) { + $plaintext = $this->_pad($plaintext); + } + + $block_size = $this->block_size; + $buffer = &$this->enbuffer; + $continuousBuffer = $this->continuousBuffer; + $ciphertext = ''; + switch ($this->mode) { + case CRYPT_RIJNDAEL_MODE_ECB: + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size)); + } + break; + case CRYPT_RIJNDAEL_MODE_CBC: + $xor = $this->encryptIV; + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $block = $this->_encryptBlock($block ^ $xor); + $xor = $block; + $ciphertext.= $block; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + } + break; + case CRYPT_RIJNDAEL_MODE_CTR: + $xor = $this->encryptIV; + if (!empty($buffer['encrypted'])) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $buffer['encrypted'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + $key = $this->_string_shift($buffer['encrypted'], $block_size); + $ciphertext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + $ciphertext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted']; + } + } + break; + case CRYPT_RIJNDAEL_MODE_CFB: + if (!empty($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $iv = $buffer['encrypted'] . $ciphertext; + $start = strlen($ciphertext); + $buffer['encrypted'].= $ciphertext; + $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); + } else { + $ciphertext = ''; + $iv = $this->encryptIV; + $start = 0; + } + + for ($i = $start; $i < strlen($plaintext); $i+=$block_size) { + $block = substr($plaintext, $i, $block_size); + $xor = $this->_encryptBlock($iv); + $iv = $block ^ $xor; + if ($continuousBuffer && strlen($iv) != $block_size) { + $buffer = array( + 'encrypted' => $iv, + 'xor' => substr($xor, strlen($iv)) + ); + } + $ciphertext.= $iv; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; + case CRYPT_RIJNDAEL_MODE_OFB: + $xor = $this->encryptIV; + if (strlen($buffer)) { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $buffer.= $xor; + $key = $this->_string_shift($buffer, $block_size); + $ciphertext.= substr($plaintext, $i, $block_size) ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer = substr($key, $start) . $buffer; + } + } + } + + return $ciphertext; + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * @see Crypt_Rijndael::encrypt() + * @access public + * @param String $ciphertext + */ + function decrypt($ciphertext) + { + $this->_setup(); + + if ($this->paddable) { + // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic : + // "The data is padded with "\0" to make sure the length of the data is n * blocksize." + $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0)); + } + + $block_size = $this->block_size; + $buffer = &$this->debuffer; + $continuousBuffer = $this->continuousBuffer; + $plaintext = ''; + switch ($this->mode) { + case CRYPT_RIJNDAEL_MODE_ECB: + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size)); + } + break; + case CRYPT_RIJNDAEL_MODE_CBC: + $xor = $this->decryptIV; + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $plaintext.= $this->_decryptBlock($block) ^ $xor; + $xor = $block; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + } + break; + case CRYPT_RIJNDAEL_MODE_CTR: + $xor = $this->decryptIV; + if (!empty($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $buffer['ciphertext'].= $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + $key = $this->_string_shift($buffer['ciphertext'], $block_size); + $plaintext.= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor)); + $plaintext.= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['encrypted']; + } + } + break; + case CRYPT_RIJNDAEL_MODE_CFB: + if (!empty($buffer['ciphertext'])) { + $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext'])); + $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext)); + if (strlen($buffer['ciphertext']) == $block_size) { + $xor = $this->_encryptBlock($buffer['ciphertext']); + $buffer['ciphertext'] = ''; + } + $start = strlen($plaintext); + $block = $this->decryptIV; + } else { + $plaintext = ''; + $xor = $this->_encryptBlock($this->decryptIV); + $start = 0; + } + + for ($i = $start; $i < strlen($ciphertext); $i+=$block_size) { + $block = substr($ciphertext, $i, $block_size); + $plaintext.= $block ^ $xor; + if ($continuousBuffer && strlen($block) != $block_size) { + $buffer['ciphertext'].= $block; + $block = $xor; + } else if (strlen($block) == $block_size) { + $xor = $this->_encryptBlock($block); + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $block; + } + break; + case CRYPT_RIJNDAEL_MODE_OFB: + $xor = $this->decryptIV; + if (strlen($buffer)) { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $buffer.= $xor; + $key = $this->_string_shift($buffer, $block_size); + $plaintext.= substr($ciphertext, $i, $block_size) ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) { + $xor = $this->_encryptBlock($xor); + $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer = substr($key, $start) . $buffer; + } + } + } + + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; + } + + /** + * Encrypts a block + * + * @access private + * @param String $in + * @return String + */ + function _encryptBlock($in) + { + $state = array(); + $words = unpack('N*word', $in); + + $w = $this->w; + $t0 = $this->t0; + $t1 = $this->t1; + $t2 = $this->t2; + $t3 = $this->t3; + $Nb = $this->Nb; + $Nr = $this->Nr; + $c = $this->c; + + // addRoundKey + $i = 0; + foreach ($words as $word) { + $state[] = $word ^ $w[0][$i++]; + } + + // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - + // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding + // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. + // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. + // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], + // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. + + // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf + $temp = array(); + for ($round = 1; $round < $Nr; $round++) { + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + + while ($i < $this->Nb) { + $temp[$i] = $t0[$state[$i] & 0xFF000000] ^ + $t1[$state[$j] & 0x00FF0000] ^ + $t2[$state[$k] & 0x0000FF00] ^ + $t3[$state[$l] & 0x000000FF] ^ + $w[$round][$i]; + $i++; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + for ($i = 0; $i < $Nb; $i++) { + $state[$i] = $temp[$i]; + } + } + + // subWord + for ($i = 0; $i < $Nb; $i++) { + $state[$i] = $this->_subWord($state[$i]); + } + + // shiftRows + addRoundKey + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + while ($i < $this->Nb) { + $temp[$i] = ($state[$i] & 0xFF000000) ^ + ($state[$j] & 0x00FF0000) ^ + ($state[$k] & 0x0000FF00) ^ + ($state[$l] & 0x000000FF) ^ + $w[$Nr][$i]; + $i++; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + + array_unshift($state, 'N*'); + + return call_user_func_array('pack', $state); + } + + /** + * Decrypts a block + * + * @access private + * @param String $in + * @return String + */ + function _decryptBlock($in) + { + $state = array(); + $words = unpack('N*word', $in); + + $num_states = count($state); + $dw = $this->dw; + $dt0 = $this->dt0; + $dt1 = $this->dt1; + $dt2 = $this->dt2; + $dt3 = $this->dt3; + $Nb = $this->Nb; + $Nr = $this->Nr; + $c = $this->c; + + // addRoundKey + $i = 0; + foreach ($words as $word) { + $state[] = $word ^ $dw[$Nr][$i++]; + } + + $temp = array(); + for ($round = $Nr - 1; $round > 0; $round--) { + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $temp[$i] = $dt0[$state[$i] & 0xFF000000] ^ + $dt1[$state[$j] & 0x00FF0000] ^ + $dt2[$state[$k] & 0x0000FF00] ^ + $dt3[$state[$l] & 0x000000FF] ^ + $dw[$round][$i]; + $i++; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + for ($i = 0; $i < $Nb; $i++) { + $state[$i] = $temp[$i]; + } + } + + // invShiftRows + invSubWord + addRoundKey + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $temp[$i] = $dw[0][$i] ^ + $this->_invSubWord(($state[$i] & 0xFF000000) | + ($state[$j] & 0x00FF0000) | + ($state[$k] & 0x0000FF00) | + ($state[$l] & 0x000000FF)); + $i++; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + $state = $temp; + + array_unshift($state, 'N*'); + + return call_user_func_array('pack', $state); + } + + /** + * Setup Rijndael + * + * Validates all the variables and calculates $Nr - the number of rounds that need to be performed - and $w - the key + * key schedule. + * + * @access private + */ + function _setup() + { + // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. + // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse + static $rcon = array(0, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, + 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, + 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, + 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 + ); + + if (!$this->changed) { + return; + } + + if (!$this->explicit_key_length) { + // we do >> 2, here, and not >> 5, as we do above, since strlen($this->key) tells us the number of bytes - not bits + $length = strlen($this->key) >> 2; + if ($length > 8) { + $length = 8; + } else if ($length < 4) { + $length = 4; + } + $this->Nk = $length; + $this->key_size = $length << 2; + } + + $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0)); + $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, chr(0)); + + // see Rijndael-ammended.pdf#page=44 + $this->Nr = max($this->Nk, $this->Nb) + 6; + + // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, + // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" + // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, + // "Table 2: Shift offsets for different block lengths" + switch ($this->Nb) { + case 4: + case 5: + case 6: + $this->c = array(0, 1, 2, 3); + break; + case 7: + $this->c = array(0, 1, 2, 4); + break; + case 8: + $this->c = array(0, 1, 3, 4); + } + + $key = $this->key; + + $w = array_values(unpack('N*words', $key)); + + $length = $this->Nb * ($this->Nr + 1); + for ($i = $this->Nk; $i < $length; $i++) { + $temp = $w[$i - 1]; + if ($i % $this->Nk == 0) { + // according to , "the size of an integer is platform-dependent". + // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, + // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' + // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. + $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord + $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk]; + } else if ($this->Nk > 6 && $i % $this->Nk == 4) { + $temp = $this->_subWord($temp); + } + $w[$i] = $w[$i - $this->Nk] ^ $temp; + } + + // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns + // and generate the inverse key schedule. more specifically, + // according to (section 5.3.3), + // "The key expansion for the Inverse Cipher is defined as follows: + // 1. Apply the Key Expansion. + // 2. Apply InvMixColumn to all Round Keys except the first and the last one." + // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" + $temp = array(); + for ($i = $row = $col = 0; $i < $length; $i++, $col++) { + if ($col == $this->Nb) { + if ($row == 0) { + $this->dw[0] = $this->w[0]; + } else { + // subWord + invMixColumn + invSubWord = invMixColumn + $j = 0; + while ($j < $this->Nb) { + $dw = $this->_subWord($this->w[$row][$j]); + $temp[$j] = $this->dt0[$dw & 0xFF000000] ^ + $this->dt1[$dw & 0x00FF0000] ^ + $this->dt2[$dw & 0x0000FF00] ^ + $this->dt3[$dw & 0x000000FF]; + $j++; + } + $this->dw[$row] = $temp; + } + + $col = 0; + $row++; + } + $this->w[$row][$col] = $w[$i]; + } + + $this->dw[$row] = $this->w[$row]; + + $this->changed = false; + } + + /** + * Performs S-Box substitutions + * + * @access private + */ + function _subWord($word) + { + static $sbox0, $sbox1, $sbox2, $sbox3; + + if (empty($sbox0)) { + $sbox0 = array( + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + ); + + $sbox1 = array(); + $sbox2 = array(); + $sbox3 = array(); + + for ($i = 0; $i < 256; $i++) { + $sbox1[$i << 8] = $sbox0[$i] << 8; + $sbox2[$i << 16] = $sbox0[$i] << 16; + $sbox3[$i << 24] = $sbox0[$i] << 24; + } + } + + return $sbox0[$word & 0x000000FF] | + $sbox1[$word & 0x0000FF00] | + $sbox2[$word & 0x00FF0000] | + $sbox3[$word & 0xFF000000]; + } + + /** + * Performs inverse S-Box substitutions + * + * @access private + */ + function _invSubWord($word) + { + static $sbox0, $sbox1, $sbox2, $sbox3; + + if (empty($sbox0)) { + $sbox0 = array( + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D + ); + + $sbox1 = array(); + $sbox2 = array(); + $sbox3 = array(); + + for ($i = 0; $i < 256; $i++) { + $sbox1[$i << 8] = $sbox0[$i] << 8; + $sbox2[$i << 16] = $sbox0[$i] << 16; + $sbox3[$i << 24] = $sbox0[$i] << 24; + } + } + + return $sbox0[$word & 0x000000FF] | + $sbox1[$word & 0x0000FF00] | + $sbox2[$word & 0x00FF0000] | + $sbox3[$word & 0xFF000000]; + } + + /** + * Pad "packets". + * + * Rijndael works by encrypting between sixteen and thirty-two bytes at a time, provided that number is also a multiple + * of four. If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see Crypt_Rijndael::disablePadding() + * @access public + */ + function enablePadding() + { + $this->padding = true; + } + + /** + * Do not pad packets. + * + * @see Crypt_Rijndael::enablePadding() + * @access public + */ + function disablePadding() + { + $this->padding = false; + } + + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $block_size - (strlen($text) % $block_size) bytes are added, each of which is equal to + * chr($block_size - (strlen($text) % $block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see Crypt_Rijndael::_unpad() + * @access private + */ + function _pad($text) + { + $length = strlen($text); + + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE); + $this->padding = true; + } + } + + $pad = $this->block_size - ($length % $this->block_size); + + return str_pad($text, $length + $pad, chr($pad)); + } + + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see Crypt_Rijndael::_pad() + * @access private + */ + function _unpad($text) + { + if (!$this->padding) { + return $text; + } + + $length = ord($text[strlen($text) - 1]); + + if (!$length || $length > $this->block_size) { + return false; + } + + return substr($text, 0, -$length); + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the Crypt_Rijndael() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * @see Crypt_Rijndael::disableContinuousBuffer() + * @access public + */ + function enableContinuousBuffer() + { + $this->continuousBuffer = true; + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * @see Crypt_Rijndael::enableContinuousBuffer() + * @access public + */ + function disableContinuousBuffer() + { + $this->continuousBuffer = false; + $this->encryptIV = $this->iv; + $this->decryptIV = $this->iv; + } + + /** + * String Shift + * + * Inspired by array_shift + * + * @param String $string + * @param optional Integer $index + * @return String + * @access private + */ + function _string_shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } +} + +// vim: ts=4:sw=4:et: +// vim6: fdl=1: +?> diff --git a/phpmyadmin/libraries/plugin_interface.lib.php b/phpmyadmin/libraries/plugin_interface.lib.php new file mode 100644 index 000000000..b4fe7f6d6 --- /dev/null +++ b/phpmyadmin/libraries/plugin_interface.lib.php @@ -0,0 +1,508 @@ +'; + $default = PMA_pluginGetDefault($section, $cfgname); + foreach ($list as $plugin) { + $plugin_name = strtolower(substr(get_class($plugin), strlen($section))); + $ret .= 'getProperties(); + $text = null; + if ($properties != null) { + $text = $properties->getText(); + } + $ret .= ' value="' . $plugin_name . '">' + . PMA_getString($text) + . '' . "\n"; + } + $ret .= '' . "\n"; + + // Whether each plugin has to be saved as a file + foreach ($list as $plugin) { + $plugin_name = strtolower(substr(get_class($plugin), strlen($section))); + $ret .= ''. "\n"; + } + + return $ret; +} + +/** + * Returns single option in a list element + * + * @param string $section name of config section in + * $GLOBALS['cfg'][$section] for plugin + * @param string $plugin_name unique plugin name + * @param array &$propertyGroup options property main group instance + * @param boolean $is_subgroup if this group is a subgroup + * + * @return string table row with option + */ +function PMA_pluginGetOneOption( + $section, + $plugin_name, + &$propertyGroup, + $is_subgroup = false +) { + $ret = "\n"; + + if (! $is_subgroup) { + // for subgroup headers + if (strpos(get_class($propertyGroup), "PropertyItem")) { + $properties = array($propertyGroup); + } else { + // for main groups + $ret .= '
      '; + + if (method_exists($propertyGroup, 'getText')) { + $text = $propertyGroup->getText(); + } + + if ($text != null) { + $ret .= '

      ' . PMA_getString($text) . '

      '; + } + $ret .= '
        '; + } + } + + if (! isset($properties)) { + $not_subgroup_header = true; + if (method_exists($propertyGroup, 'getProperties')) { + $properties = $propertyGroup->getProperties(); + } + } + + if (isset($properties)) { + foreach ($properties as $propertyItem) { + $property_class = get_class($propertyItem); + // if the property is a subgroup, we deal with it recursively + if (strpos($property_class, "Subgroup")) { + // for subgroups + // each subgroup can have a header, which may also be a form element + $subgroup_header = $propertyItem->getSubgroupHeader(); + if (isset($subgroup_header)) { + $ret .= PMA_pluginGetOneOption( + $section, + $plugin_name, + $subgroup_header + ); + } + + $ret .= '
      • getName() . '">'; + } else { + $ret .= '>'; + } + + $ret .= PMA_pluginGetOneOption( + $section, + $plugin_name, + $propertyItem, + true + ); + } else { + // single property item + switch ($property_class) { + case "BoolPropertyItem": + $ret .= '
      • ' . "\n"; + $ret .= 'getName() + ); + + if ($propertyItem->getForce() != null) { + // Same code is also few lines lower, update both if needed + $ret .= ' onclick="if (!this.checked && ' + . '(!document.getElementById(\'checkbox_' . $plugin_name + . '_' . $propertyItem->getForce() . '\') ' + . '|| !document.getElementById(\'checkbox_' + . $plugin_name . '_' . $propertyItem->getForce() + . '\').checked)) ' + . 'return false; else return true;"'; + } + $ret .= ' />'; + $ret .= ''; + break; + case "DocPropertyItem": + echo "DocPropertyItem"; + break; + case "HiddenPropertyItem": + $ret .= '
      • '; + break; + case "MessageOnlyPropertyItem": + $ret .= '
      • ' . "\n"; + $ret .= '

        ' . PMA_getString($propertyItem->getText()) . '

        '; + break; + case "RadioPropertyItem": + $default = PMA_pluginGetDefault( + $section, + $plugin_name . '_' . $propertyItem->getName() + ); + foreach ($propertyItem->getValues() as $key => $val) { + $ret .= '
      • ' + . PMA_getString($val) . '
      • '; + } + break; + case "SelectPropertyItem": + $ret .= '
      • ' . "\n"; + $ret .= ''; + $ret .= ''; + break; + case "TextPropertyItem": + $ret .= '
      • ' . "\n"; + $ret .= ''; + $ret .= 'getSize() != null + ? ' size="' . $propertyItem->getSize() . '"' + : '') + . ($propertyItem->getLen() != null + ? ' maxlength="' . $propertyItem->getLen() . '"' + : '') + . ' />'; + break; + default:; + } + } + } + } + + if ($is_subgroup) { + // end subgroup + $ret .= '
      '; + } else { + // end main group + if (! empty($not_subgroup_header)) { + $ret .= '
      '; + } + } + + if (method_exists($propertyGroup, "getDoc")) { + $doc = $propertyGroup->getDoc(); + if ($doc != null) { + if (count($doc) == 3) { + $ret .= PMA_Util::showMySQLDocu( + $doc[0], + $doc[1], + false, + $doc[2] + ); + } elseif (count($doc) == 1) { + $ret .= PMA_Util::showDocu('faq', $doc[0]); + } else { + $ret .= PMA_Util::showMySQLDocu( + $doc[0], + $doc[1] + ); + } + } + } + + // Close the list element after $doc link is displayed + if (isset($property_class)) { + if ($property_class == 'BoolPropertyItem' + || $property_class == 'MessageOnlyPropertyItem' + || $property_class == 'SelectPropertyItem' + || $property_class == 'TextPropertyItem' + ) { + $ret .= ''; + } + } + $ret .= "\n"; + return $ret; +} + +/** + * Returns html div with editable options for plugin + * + * @param string $section name of config section in $GLOBALS['cfg'][$section] + * @param array &$list array with plugin instances + * + * @return string html fieldset with plugin options + */ +function PMA_pluginGetOptions($section, &$list) +{ + $ret = ''; + $default = PMA_pluginGetDefault('Export', 'format'); + // Options for plugins that support them + foreach ($list as $plugin) { + $properties = $plugin->getProperties(); + if ($properties != null) { + $text = $properties->getText(); + $options = $properties->getOptions(); + } + + $plugin_name = strtolower(substr(get_class($plugin), strlen($section))); + $ret .= '
      '; + $ret .= '

      ' . PMA_getString($text) . '

      '; + + $no_options = true; + if ($options != null && count($options) > 0) { + foreach ($options->getProperties() + as $propertyMainGroup + ) { + // check for hidden properties + $no_options = true; + foreach ($propertyMainGroup->getProperties() as $propertyItem) { + if (strcmp("HiddenPropertyItem", get_class($propertyItem))) { + $no_options = false; + break; + } + } + + $ret .= PMA_pluginGetOneOption( + $section, + $plugin_name, + $propertyMainGroup + ); + } + } + + if ($no_options) { + $ret .= '

      ' . __('This format has no options') . '

      '; + } + $ret .= '
      '; + } + return $ret; +} diff --git a/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php b/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php new file mode 100644 index 000000000..3ddf55ee2 --- /dev/null +++ b/phpmyadmin/libraries/plugins/AuthenticationPlugin.class.php @@ -0,0 +1,51 @@ + authentication failed + * + * @return boolean + */ + abstract public function authFails(); +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/ExportPlugin.class.php b/phpmyadmin/libraries/plugins/ExportPlugin.class.php new file mode 100644 index 000000000..0af20d3c2 --- /dev/null +++ b/phpmyadmin/libraries/plugins/ExportPlugin.class.php @@ -0,0 +1,205 @@ +properties; + } + + /** + * Sets the export plugins properties and is implemented by each export + * plugin + * + * @return void + */ + abstract protected function setProperties(); +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/ImportPlugin.class.php b/phpmyadmin/libraries/plugins/ImportPlugin.class.php new file mode 100644 index 000000000..0890dcf53 --- /dev/null +++ b/phpmyadmin/libraries/plugins/ImportPlugin.class.php @@ -0,0 +1,59 @@ +properties; + } + + /** + * Sets the export plugins properties and is implemented by each import + * plugin + * + * @return void + */ + abstract protected function setProperties(); +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/PluginManager.class.php b/phpmyadmin/libraries/plugins/PluginManager.class.php new file mode 100644 index 000000000..28400b7b6 --- /dev/null +++ b/phpmyadmin/libraries/plugins/PluginManager.class.php @@ -0,0 +1,132 @@ +_storage = new SplObjectStorage(); + } + + /** + * Attaches an SplObserver so that it can be notified of updates + * + * @param SplObserver $observer The SplObserver to attach + * + * @return void + */ + function attach (SplObserver $observer ) + { + $this->_storage->attach($observer); + } + + /** + * Detaches an observer from the subject to no longer notify it of updates + * + * @param SplObserver $observer The SplObserver to detach + * + * @return void + */ + function detach (SplObserver $observer) + { + $this->_storage->detach($observer); + } + + /** + * It is called after setStatus() was run by a certain plugin, and has + * the role of sending a notification to all of the plugins in $_storage, + * by calling the update() method for each of them. + * + * @todo implement + * @return void + */ + function notify () + { + } + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + /** + * Gets the list with all the plugins that attach to it + * + * @return type SplObjectStorage + */ + public function getStorage() + { + return $this->_storage; + } + + /** + * Setter for $_storage + * + * @param SplObjectStorage $_storage the list with all the plugins that + * attach to it + * + * @return void + */ + public function setStorage($_storage) + { + $this->_storage = $_storage; + } + + /** + * Gets the information about the current plugin state + * It is called by all the plugins in $_storage in their update() method + * + * @return type mixed + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Setter for $_status + * If a plugin changes its status, this has to be remembered in order to + * notify the rest of the plugins that they should update + * + * @param mixed $_status contains information about the current plugin state + * + * @return void + */ + public function setStatus($_status) + { + $this->_status = $_status; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/PluginObserver.class.php b/phpmyadmin/libraries/plugins/PluginObserver.class.php new file mode 100644 index 000000000..520d62a4d --- /dev/null +++ b/phpmyadmin/libraries/plugins/PluginObserver.class.php @@ -0,0 +1,90 @@ +_pluginManager = $pluginManager; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * TODO Declare this function abstract, removing its body, + * as soon as we drop support for PHP 5.2.x. + * See bug #3538655. + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + throw new Exception( + 'PluginObserver::update must be overridden in child classes.' + ); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the PluginManager instance that contains the list with all the + * plugins that attached to it + * + * @return type PluginManager + */ + public function getPluginManager() + { + return $this->_pluginManager; + } + + /** + * Setter for $_pluginManager + * + * @param PluginManager $_pluginManager the private instance that it will + * attach to + * + * @return void + */ + public function setPluginManager($_pluginManager) + { + $this->_pluginManager = $_pluginManager; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/TransformationsInterface.int.php b/phpmyadmin/libraries/plugins/TransformationsInterface.int.php new file mode 100644 index 000000000..1bcb8af45 --- /dev/null +++ b/phpmyadmin/libraries/plugins/TransformationsInterface.int.php @@ -0,0 +1,49 @@ + diff --git a/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php new file mode 100644 index 000000000..959a8e191 --- /dev/null +++ b/phpmyadmin/libraries/plugins/TransformationsPlugin.class.php @@ -0,0 +1,49 @@ + diff --git a/phpmyadmin/libraries/plugins/UploadInterface.int.php b/phpmyadmin/libraries/plugins/UploadInterface.int.php new file mode 100644 index 000000000..ab660d610 --- /dev/null +++ b/phpmyadmin/libraries/plugins/UploadInterface.int.php @@ -0,0 +1,36 @@ +upload plugins + * + * @package PhpMyAdmin + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/** + * Provides a common interface that will have to implemented by all of the + * import->upload plugins. + * + * @package PhpMyAdmin + */ +interface UploadInterface +{ + /** + * Gets the specific upload ID Key + * + * @return string ID Key + */ + public static function getIdKey(); + + /** + * Returns upload status. + * + * @param string $id upload id + * + * @return array|null + */ + public static function getUploadStatus($id); +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php new file mode 100644 index 000000000..07ad7cb55 --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/AuthenticationConfig.class.php @@ -0,0 +1,172 @@ + authentication failed + * + * @global string the MySQL error message PHP returns + * @global string the connection type (persistent or not) + * @global string the MySQL server port to use + * @global string the MySQL socket port to use + * @global array the current server settings + * @global string the font face to use in case of failure + * @global string the default font size to use in case of failure + * @global string the big font size to use in case of failure + * @global boolean tell the "PMA_mysqlDie()" function headers have been + * sent + * + * @return boolean always true (no return indeed) + */ + public function authFails() + { + $conn_error = PMA_DBI_getError(); + if (! $conn_error) { + $conn_error = __('Cannot connect: invalid settings.'); + } + + /* HTML header */ + $response = PMA_Response::getInstance(); + $response->getFooter()->setMinimal(); + $header = $response->getHeader(); + $header->setBodyId('loginform'); + $header->setTitle(__('Access denied')); + $header->disableMenu(); + echo '

      +
      +

      '; + echo sprintf(__('Welcome to %s'), ' phpMyAdmin '); + echo '

      +
      +
      + + + + + + + ' . "\n"; + if (count($GLOBALS['cfg']['Servers']) > 1) { + // offer a chance to login to other servers if the current one failed + include_once './libraries/select_server.lib.php'; + echo '' . "\n"; + echo ' ' . "\n"; + echo '' . "\n"; + } + echo '
      '; + if (isset($GLOBALS['allowDeny_forbidden']) + && $GLOBALS['allowDeny_forbidden'] + ) { + trigger_error(__('Access denied'), E_USER_NOTICE); + } else { + // Check whether user has configured something + if ($GLOBALS['PMA_Config']->source_mtime == 0) { + echo '

      ' . sprintf( + __( + 'You probably did not create a configuration file.' + . ' You might want to use the %1$ssetup script%2$s to' + . ' create one.' + ), + '', + '' + ) . '

      ' . "\n"; + } elseif (! isset($GLOBALS['errno']) + || (isset($GLOBALS['errno']) && $GLOBALS['errno'] != 2002) + && $GLOBALS['errno'] != 2003 + ) { + // if we display the "Server not responding" error, do not confuse + // users by telling them they have a settings problem + // (note: it's true that they could have a badly typed host name, + // but anyway the current message tells that the server + // rejected the connection, which is not really what happened) + // 2002 is the error given by mysqli + // 2003 is the error given by mysql + trigger_error( + __( + 'phpMyAdmin tried to connect to the MySQL server, and the' + . ' server rejected the connection. You should check the' + . ' host, username and password in your configuration and' + . ' make sure that they correspond to the information given' + . ' by the administrator of the MySQL server.' + ), E_USER_WARNING + ); + } + echo PMA_Util::mysqlDie( + $conn_error, '', true, '', false + ); + } + $GLOBALS['error_handler']->dispUserErrors(); + echo '
      ' . "\n"; + echo '' + . __('Retry to connect') + . '' . "\n"; + echo '
      ' . "\n"; + echo PMA_selectServer(true, true); + echo '
      ' . "\n"; + exit; + return true; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php new file mode 100644 index 000000000..72274d9e3 --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/AuthenticationCookie.class.php @@ -0,0 +1,696 @@ +setCookie( + 'pma_mcrypt_iv', + base64_encode($iv) + ); + } +} + +/** + * Handles the cookie authentication method + * + * @package PhpMyAdmin-Authentication + */ +class AuthenticationCookie extends AuthenticationPlugin +{ + /** + * Displays authentication form + * + * this function MUST exit/quit the application + * + * @global string the last connection error + * + * @return void + */ + public function auth() + { + global $conn_error; + + $response = PMA_Response::getInstance(); + if ($response->isAjax()) { + $response->isSuccess(false); + + $login_link = '

      [ ' . + sprintf( + '', + $GLOBALS['cfg']['PmaAbsoluteUri'], + __('Log in') + ) + . ' ]'; + + if (! empty($conn_error)) { + + $conn_error .= $login_link; + + $response->addJSON( + 'message', + PMA_Message::error( + $conn_error + ) + ); + } else { + $response->addJSON( + 'message', + PMA_Message::error( + __('Your session has expired. Please log in again.') . + $login_link + ) + ); + } + exit; + } + + /* Perform logout to custom URL */ + if (! empty($_REQUEST['old_usr']) + && ! empty($GLOBALS['cfg']['Server']['LogoutURL']) + ) { + PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']); + exit; + } + + // No recall if blowfish secret is not configured as it would produce + // garbage + if ($GLOBALS['cfg']['LoginCookieRecall'] + && ! empty($GLOBALS['cfg']['blowfish_secret']) + ) { + $default_user = $GLOBALS['PHP_AUTH_USER']; + $default_server = $GLOBALS['pma_auth_server']; + $autocomplete = ''; + } else { + $default_user = ''; + $default_server = ''; + // skip the IE autocomplete feature. + $autocomplete = ' autocomplete="off"'; + } + + $cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right'; + + $response->getFooter()->setMinimal(); + $header = $response->getHeader(); + $header->setBodyId('loginform'); + $header->setTitle('phpMyAdmin'); + $header->disableMenu(); + $header->disableWarnings(); + + if (file_exists(CUSTOM_HEADER_FILE)) { + include CUSTOM_HEADER_FILE; + } + echo ' +
      + +

      '; + echo sprintf( + __('Welcome to %s'), + 'phpMyAdmin' + ); + echo "

      "; + + // Show error message + if (! empty($conn_error)) { + PMA_Message::rawError($conn_error)->display(); + } + + echo "\n"; + + echo "
      "; + // Displays the languages form + if (empty($GLOBALS['cfg']['Lang'])) { + include_once './libraries/display_select_lang.lib.php'; + // use fieldset, don't show doc link + echo PMA_getLanguageSelectorHtml(true, false); + } + echo '
      +
      + + '; + + // BEGIN Swekey Integration + Swekey_login('input_username', 'input_go'); + // END Swekey Integration + + if ($GLOBALS['error_handler']->hasDisplayErrors()) { + echo '
      '; + $GLOBALS['error_handler']->dispErrors(); + echo '
      '; + } + echo '
      '; + if (file_exists(CUSTOM_FOOTER_FILE)) { + include CUSTOM_FOOTER_FILE; + } + exit; + } + + /** + * Gets advanced authentication settings + * + * this function DOES NOT check authentication - it just checks/provides + * authentication credentials required to connect to the MySQL server + * usually with PMA_DBI_connect() + * + * it returns false if something is missing - which usually leads to + * auth() which displays login form + * + * it returns true if all seems ok which usually leads to auth_set_user() + * + * it directly switches to authFails() if user inactivity timout is reached + * + * @todo AllowArbitraryServer on does not imply that the user wants an + * arbitrary server, or? so we should also check if this is filled + * and not only if allowed + * + * @return boolean whether we get authentication settings or not + */ + public function authCheck() + { + // Initialization + /** + * @global $GLOBALS['pma_auth_server'] the user provided server to + * connect to + */ + $GLOBALS['pma_auth_server'] = ''; + + $GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = ''; + $GLOBALS['from_cookie'] = false; + + // BEGIN Swekey Integration + if (! Swekey_auth_check()) { + return false; + } + // END Swekey Integration + + if (defined('PMA_CLEAR_COOKIES')) { + foreach ($GLOBALS['cfg']['Servers'] as $key => $val) { + $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key); + $GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key); + $GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key); + } + return false; + } + + if (! empty($_REQUEST['old_usr'])) { + // The user wants to be logged out + // -> delete his choices that were stored in session + + // according to the PHP manual we should do this before the destroy: + //$_SESSION = array(); + + session_destroy(); + // -> delete password cookie(s) + if ($GLOBALS['cfg']['LoginCookieDeleteAll']) { + foreach ($GLOBALS['cfg']['Servers'] as $key => $val) { + $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key); + if (isset($_COOKIE['pmaPass-' . $key])) { + unset($_COOKIE['pmaPass-' . $key]); + } + } + } else { + $GLOBALS['PMA_Config']->removeCookie( + 'pmaPass-' . $GLOBALS['server'] + ); + if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) { + unset($_COOKIE['pmaPass-' . $GLOBALS['server']]); + } + } + } + + if (! empty($_REQUEST['pma_username'])) { + // The user just logged in + $GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username']; + $GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password']) + ? '' + : $_REQUEST['pma_password']; + if ($GLOBALS['cfg']['AllowArbitraryServer'] + && isset($_REQUEST['pma_servername']) + ) { + $GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername']; + } + return true; + } + + // At the end, try to set the $GLOBALS['PHP_AUTH_USER'] + // and $GLOBALS['PHP_AUTH_PW'] variables from cookies + + // servername + if ($GLOBALS['cfg']['AllowArbitraryServer'] + && ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']]) + ) { + $GLOBALS['pma_auth_server'] + = $_COOKIE['pmaServer-' . $GLOBALS['server']]; + } + + // username + if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) { + return false; + } + + $GLOBALS['PHP_AUTH_USER'] = $this->blowfishDecrypt( + $_COOKIE['pmaUser-' . $GLOBALS['server']], + $this->_getBlowfishSecret() + ); + + // user was never logged in since session start + if (empty($_SESSION['last_access_time'])) { + return false; + } + + // User inactive too long + $last_access_time = time() - $GLOBALS['cfg']['LoginCookieValidity']; + if ($_SESSION['last_access_time'] < $last_access_time + ) { + PMA_Util::cacheUnset('is_create_db_priv', true); + PMA_Util::cacheUnset('is_process_priv', true); + PMA_Util::cacheUnset('is_reload_priv', true); + PMA_Util::cacheUnset('db_to_create', true); + PMA_Util::cacheUnset('dbs_where_create_table_allowed', true); + $GLOBALS['no_activity'] = true; + $this->authFails(); + exit; + } + + // password + if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) { + return false; + } + + $GLOBALS['PHP_AUTH_PW'] = $this->blowfishDecrypt( + $_COOKIE['pmaPass-' . $GLOBALS['server']], + $this->_getBlowfishSecret() + ); + + if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") { + $GLOBALS['PHP_AUTH_PW'] = ''; + } + + $GLOBALS['from_cookie'] = true; + + return true; + } + + /** + * Set the user and password after last checkings if required + * + * @return boolean always true + */ + public function authSetUser() + { + global $cfg; + + // Ensures valid authentication mode, 'only_db', bookmark database and + // table names and relation table name are used + if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) { + foreach ($cfg['Servers'] as $idx => $current) { + if ($current['host'] == $cfg['Server']['host'] + && $current['port'] == $cfg['Server']['port'] + && $current['socket'] == $cfg['Server']['socket'] + && $current['ssl'] == $cfg['Server']['ssl'] + && $current['connect_type'] == $cfg['Server']['connect_type'] + && $current['user'] == $GLOBALS['PHP_AUTH_USER'] + ) { + $GLOBALS['server'] = $idx; + $cfg['Server'] = $current; + break; + } + } // end foreach + } // end if + + if ($GLOBALS['cfg']['AllowArbitraryServer'] + && ! empty($GLOBALS['pma_auth_server']) + ) { + /* Allow to specify 'host port' */ + $parts = explode(' ', $GLOBALS['pma_auth_server']); + if (count($parts) == 2) { + $tmp_host = $parts[0]; + $tmp_port = $parts[1]; + } else { + $tmp_host = $GLOBALS['pma_auth_server']; + $tmp_port = ''; + } + if ($cfg['Server']['host'] != $GLOBALS['pma_auth_server']) { + $cfg['Server']['host'] = $tmp_host; + if (! empty($tmp_port)) { + $cfg['Server']['port'] = $tmp_port; + } + } + unset($tmp_host, $tmp_port, $parts); + } + $cfg['Server']['user'] = $GLOBALS['PHP_AUTH_USER']; + $cfg['Server']['password'] = $GLOBALS['PHP_AUTH_PW']; + + // Avoid showing the password in phpinfo()'s output + unset($GLOBALS['PHP_AUTH_PW']); + unset($_SERVER['PHP_AUTH_PW']); + + $_SESSION['last_access_time'] = time(); + + // Name and password cookies need to be refreshed each time + // Duration = one month for username + $GLOBALS['PMA_Config']->setCookie( + 'pmaUser-' . $GLOBALS['server'], + $this->blowfishEncrypt( + $cfg['Server']['user'], + $this->_getBlowfishSecret() + ) + ); + + // Duration = as configured + $GLOBALS['PMA_Config']->setCookie( + 'pmaPass-' . $GLOBALS['server'], + $this->blowfishEncrypt( + ! empty($cfg['Server']['password']) + ? $cfg['Server']['password'] : "\xff(blank)", + $this->_getBlowfishSecret() + ), + null, + $GLOBALS['cfg']['LoginCookieStore'] + ); + + // Set server cookies if required (once per session) and, in this case, + // force reload to ensure the client accepts cookies + if (! $GLOBALS['from_cookie']) { + if ($GLOBALS['cfg']['AllowArbitraryServer']) { + if (! empty($GLOBALS['pma_auth_server'])) { + // Duration = one month for servername + $GLOBALS['PMA_Config']->setCookie( + 'pmaServer-' . $GLOBALS['server'], + $cfg['Server']['host'] + ); + } else { + // Delete servername cookie + $GLOBALS['PMA_Config']->removeCookie( + 'pmaServer-' . $GLOBALS['server'] + ); + } + } + + // URL where to go: + $redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php'; + + // any parameters to pass? + $url_params = array(); + if (strlen($GLOBALS['db'])) { + $url_params['db'] = $GLOBALS['db']; + } + if (strlen($GLOBALS['table'])) { + $url_params['table'] = $GLOBALS['table']; + } + // any target to pass? + if (! empty($GLOBALS['target']) + && $GLOBALS['target'] != 'index.php' + ) { + $url_params['target'] = $GLOBALS['target']; + } + + /** + * Clear user cache. + */ + PMA_Util::clearUserCache(); + + PMA_Response::getInstance()->disable(); + + PMA_sendHeaderLocation( + $redirect_url . PMA_generate_common_url($url_params, '&'), + true + ); + exit; + } // end if + + return true; + + } + + /** + * User is not allowed to login to MySQL -> authentication failed + * + * prepares error message and switches to auth() which display the error + * and the login form + * + * this function MUST exit/quit the application, + * currently doen by call to auth() + * + * @return void + */ + public function authFails() + { + global $conn_error; + + // Deletes password cookie and displays the login form + $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']); + + if (! empty($GLOBALS['login_without_password_is_forbidden'])) { + $conn_error = __( + 'Login without a password is forbidden by configuration' + . ' (see AllowNoPassword)' + ); + } elseif (! empty($GLOBALS['allowDeny_forbidden'])) { + $conn_error = __('Access denied'); + } elseif (! empty($GLOBALS['no_activity'])) { + $conn_error = sprintf( + __('No activity within %s seconds; please log in again'), + $GLOBALS['cfg']['LoginCookieValidity'] + ); + } elseif (PMA_DBI_getError()) { + $conn_error = '#' . $GLOBALS['errno'] . ' ' + . __('Cannot log in to the MySQL server'); + } else { + $conn_error = __('Cannot log in to the MySQL server'); + } + + // needed for PHP-CGI (not need for FastCGI or mod-php) + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Pragma: no-cache'); + + $this->auth(); + } + + /** + * Returns blowfish secret or generates one if needed. + * + * @return string + */ + private function _getBlowfishSecret() + { + if (empty($GLOBALS['cfg']['blowfish_secret'])) { + if (empty($_SESSION['auto_blowfish_secret'])) { + // this returns 23 characters + $_SESSION['auto_blowfish_secret'] = uniqid('', true); + } + return $_SESSION['auto_blowfish_secret']; + } else { + // apply md5() to work around too long secrets (returns 32 characters) + return md5($GLOBALS['cfg']['blowfish_secret']); + } + } + + /** + * Encryption using blowfish algorithm (mcrypt) + * or phpseclib's AES if mcrypt not available + * + * @param string $data original data + * @param string $secret the secret + * + * @return string the encrypted result + */ + public function blowfishEncrypt($data, $secret) + { + global $iv; + if (! function_exists('mcrypt_encrypt')) { + /** + * This library uses mcrypt when available, so + * we could always call it instead of having an + * if/then/else logic, however the include_once + * call is costly + */ + include_once "./libraries/phpseclib/Crypt/AES.php"; + $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); + $cipher->setKey($secret); + return base64_encode($cipher->encrypt($data)); + } else { + return base64_encode( + mcrypt_encrypt( + MCRYPT_BLOWFISH, + $secret, + $data, + MCRYPT_MODE_CBC, + $iv + ) + ); + } + } + + /** + * Decryption using blowfish algorithm (mcrypt) + * or phpseclib's AES if mcrypt not available + * + * @param string $encdata encrypted data + * @param string $secret the secret + * + * @return string original data + */ + public function blowfishDecrypt($encdata, $secret) + { + global $iv; + if (! function_exists('mcrypt_encrypt')) { + include_once "./libraries/phpseclib/Crypt/AES.php"; + $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); + $cipher->setKey($secret); + return $cipher->decrypt(base64_decode($encdata)); + } else { + $data = base64_decode($encdata); + $decrypted = mcrypt_decrypt( + MCRYPT_BLOWFISH, + $secret, + $data, + MCRYPT_MODE_CBC, + $iv + ); + return trim($decrypted); + } + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php new file mode 100644 index 000000000..f81ab92a5 --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/AuthenticationHttp.class.php @@ -0,0 +1,249 @@ +getFooter()->setMinimal(); + $header = $response->getHeader(); + $header->setTitle(__('Access denied')); + $header->disableMenu(); + $header->setBodyId('loginform'); + + $response->addHTML('

      '); + $response->addHTML(sprintf(__('Welcome to %s'), ' phpMyAdmin')); + $response->addHTML('

      '); + $response->addHTML('

      '); + $response->addHTML( + PMA_Message::error( + __('Wrong username/password. Access denied.') + ) + ); + $response->addHTML('

      '); + + if (file_exists(CUSTOM_FOOTER_FILE)) { + include CUSTOM_FOOTER_FILE; + } + + exit; + } + + /** + * Gets advanced authentication settings + * + * @global string the username if register_globals is on + * @global string the password if register_globals is on + * @global array the array of server variables if register_globals is + * off + * @global array the array of environment variables if register_globals + * is off + * @global string the username for the ? server + * @global string the password for the ? server + * @global string the username for the WebSite Professional server + * @global string the password for the WebSite Professional server + * @global string the username of the user who logs out + * + * @return boolean whether we get authentication settings or not + */ + public function authCheck() + { + global $PHP_AUTH_USER, $PHP_AUTH_PW; + + // Grabs the $PHP_AUTH_USER variable whatever are the values of the + // 'register_globals' and the 'variables_order' directives + if (empty($PHP_AUTH_USER)) { + if (PMA_getenv('PHP_AUTH_USER')) { + $PHP_AUTH_USER = PMA_getenv('PHP_AUTH_USER'); + } elseif (PMA_getenv('REMOTE_USER')) { + // CGI, might be encoded, see below + $PHP_AUTH_USER = PMA_getenv('REMOTE_USER'); + } elseif (PMA_getenv('REDIRECT_REMOTE_USER')) { + // CGI, might be encoded, see below + $PHP_AUTH_USER = PMA_getenv('REDIRECT_REMOTE_USER'); + } elseif (PMA_getenv('AUTH_USER')) { + // WebSite Professional + $PHP_AUTH_USER = PMA_getenv('AUTH_USER'); + } elseif (PMA_getenv('HTTP_AUTHORIZATION') + && false === strpos(PMA_getenv('HTTP_AUTHORIZATION'), '<') + ) { + // IIS, might be encoded, see below; also prevent XSS + $PHP_AUTH_USER = PMA_getenv('HTTP_AUTHORIZATION'); + } elseif (PMA_getenv('Authorization')) { + // FastCGI, might be encoded, see below + $PHP_AUTH_USER = PMA_getenv('Authorization'); + } + } + // Grabs the $PHP_AUTH_PW variable whatever are the values of the + // 'register_globals' and the 'variables_order' directives + if (empty($PHP_AUTH_PW)) { + if (PMA_getenv('PHP_AUTH_PW')) { + $PHP_AUTH_PW = PMA_getenv('PHP_AUTH_PW'); + } elseif (PMA_getenv('REMOTE_PASSWORD')) { + // Apache/CGI + $PHP_AUTH_PW = PMA_getenv('REMOTE_PASSWORD'); + } elseif (PMA_getenv('AUTH_PASSWORD')) { + // WebSite Professional + $PHP_AUTH_PW = PMA_getenv('AUTH_PASSWORD'); + } + } + + // Decode possibly encoded information (used by IIS/CGI/FastCGI) + // (do not use explode() because a user might have a colon in his password + if (strcmp(substr($PHP_AUTH_USER, 0, 6), 'Basic ') == 0) { + $usr_pass = base64_decode(substr($PHP_AUTH_USER, 6)); + if (! empty($usr_pass)) { + $colon = strpos($usr_pass, ':'); + if ($colon) { + $PHP_AUTH_USER = substr($usr_pass, 0, $colon); + $PHP_AUTH_PW = substr($usr_pass, $colon + 1); + } + unset($colon); + } + unset($usr_pass); + } + + // User logged out -> ensure the new username is not the same + $old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : ''; + if (! empty($old_usr) + && (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER) + ) { + $PHP_AUTH_USER = ''; + // -> delete user's choices that were stored in session + session_destroy(); + } + + // Returns whether we get authentication settings or not + if (empty($PHP_AUTH_USER)) { + return false; + } else { + return true; + } + } + + /** + * Set the user and password after last checkings if required + * + * @global array the valid servers settings + * @global integer the id of the current server + * @global array the current server settings + * @global string the current username + * @global string the current password + * + * @return boolean always true + */ + public function authSetUser() + { + global $cfg, $server; + global $PHP_AUTH_USER, $PHP_AUTH_PW; + + // Ensures valid authentication mode, 'only_db', bookmark database and + // table names and relation table name are used + if ($cfg['Server']['user'] != $PHP_AUTH_USER) { + $servers_cnt = count($cfg['Servers']); + for ($i = 1; $i <= $servers_cnt; $i++) { + if (isset($cfg['Servers'][$i]) + && ($cfg['Servers'][$i]['host'] == $cfg['Server']['host'] + && $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER) + ) { + $server = $i; + $cfg['Server'] = $cfg['Servers'][$i]; + break; + } + } // end for + } // end if + + $cfg['Server']['user'] = $PHP_AUTH_USER; + $cfg['Server']['password'] = $PHP_AUTH_PW; + + // Avoid showing the password in phpinfo()'s output + unset($GLOBALS['PHP_AUTH_PW']); + unset($_SERVER['PHP_AUTH_PW']); + + return true; + } + + /** + * User is not allowed to login to MySQL -> authentication failed + * + * @return boolean always true (no return indeed) + */ + public function authFails() + { + $error = PMA_DBI_getError(); + if ($error && $GLOBALS['errno'] != 1045) { + PMA_fatalError($error); + } else { + $this->auth(); + return true; + } + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} diff --git a/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php b/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php new file mode 100644 index 000000000..ee1cf364b --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/AuthenticationSignon.class.php @@ -0,0 +1,284 @@ + authentication failed + * + * @return boolean always true (no return indeed) + */ + public function authFails() + { + /* Session name */ + $session_name = $GLOBALS['cfg']['Server']['SignonSession']; + + /* Does session exist? */ + if (isset($_COOKIE[$session_name])) { + /* End current session */ + $old_session = session_name(); + $old_id = session_id(); + session_write_close(); + + /* Load single signon session */ + session_name($session_name); + session_id($_COOKIE[$session_name]); + session_start(); + + /* Set error message */ + if (! empty($GLOBALS['login_without_password_is_forbidden'])) { + $_SESSION['PMA_single_signon_error_message'] = __( + 'Login without a password is forbidden by configuration ' + . '(see AllowNoPassword)' + ); + } elseif (! empty($GLOBALS['allowDeny_forbidden'])) { + $_SESSION['PMA_single_signon_error_message'] = __('Access denied'); + } elseif (! empty($GLOBALS['no_activity'])) { + $_SESSION['PMA_single_signon_error_message'] = sprintf( + __('No activity within %s seconds; please log in again'), + $GLOBALS['cfg']['LoginCookieValidity'] + ); + } elseif (PMA_DBI_getError()) { + $_SESSION['PMA_single_signon_error_message'] = PMA_sanitize( + PMA_DBI_getError() + ); + } else { + $_SESSION['PMA_single_signon_error_message'] = __( + 'Cannot log in to the MySQL server' + ); + } + } + $this->auth(); + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php b/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php new file mode 100644 index 000000000..1977f883e --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/swekey/authentication.inc.php @@ -0,0 +1,172 @@ + + + diff --git a/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt b/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt new file mode 100644 index 000000000..2a31ad18f --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/swekey/musbe-ca.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIJAMjw7QcLWCd6MA0GCSqGSIb3DQEBBQUAMGsxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5j +LjESMBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2Jl +LmNvbTAeFw0wODA5MDQxNDE2MTNaFw0zNzEyMjExNDE2MTNaMGsxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES +MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBhOljxVzQfK4gted2I +d3BemcjW4abAUOzn3KYWXpPO5xIfVeXNDGkDbyH+X+7fo94sX25/ewuKNFDSOcvo +tXHq7uQenTHB35r+a+LY81KceUHgW90a3XsqPAkwAjyYcgo3zmM2DtLvw+5Yod8T +wAHk9m3qavnQ1uk99jBTwL7RZ9jIZHh9pFCL93uJc2obtd8O96Iycbn2q0w/AWbb ++eUVWIHzvLtfPvROeL3lJzr/Uz5LjKapxJ3qyqASflfHpnj9pU8l6g2TQ6Hg5KT5 +tLFkRe7uGhOfRtOQ/+NjaWrEuNCFnpyN4Q5Fv+5qA1Ip1IpH0200sWbAf/k2u0Qp +Sx0CAwEAAaOB0DCBzTAdBgNVHQ4EFgQUczJrQ7hCvtsnzcqiDIZ/GSn/CiwwgZ0G +A1UdIwSBlTCBkoAUczJrQ7hCvtsnzcqiDIZ/GSn/Ciyhb6RtMGsxCzAJBgNVBAYT +AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES +MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv +bYIJAMjw7QcLWCd6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGxk +8xzIljeBDQWWVRr0NEALVSv3i09V4jAKkyEOfmZ8lKMKJi0atwbtjrXTzLnNYj+Q +pyUbyY/8ItWvV7pnVxMiF9qcer7e9X4vw358GZuMVE/da1nWxz+CwzTm5oO30RzA +antM9bISFFr9lJq69bDWOnCUi1IG8DSL3TxtlABso7S4vqiZ+sB33l6k1K4a/Njb +QkU9UejKhKkVVZTsOrumfnOJ4MCmPfX8Y/AY2o670y5HnzpxerIYziCVzApPVrW7 +sKH0tuVGturMfQOKgstYe4/m9glBTeTLMkjD+6MJC2ONBD7GAiOO95gNl5M1fzJQ +FEe5CJ7DCYl0GdmLXXw= +-----END CERTIFICATE----- diff --git a/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php b/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php new file mode 100644 index 000000000..2231de469 --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/swekey/swekey.auth.lib.php @@ -0,0 +1,293 @@ + + + \n"; +// if (file_exists($caFile)) +// echo "\n"; + } + + if (file_exists($caFile)) { + Swekey_SetCAFile($caFile); + } elseif (! empty($caFile) && (substr($_SESSION['SWEKEY']['CONF_SERVER_CHECK'], 0, 8) == "https://")) { + return "Internal Error: CA File $caFile not found"; + } + + $result = null; + $swekey_id = $_GET['swekey_id']; + $swekey_otp = $_GET['swekey_otp']; + + if (isset($swekey_id)) { + unset($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']); + if (! isset($_SESSION['SWEKEY']['RND_TOKEN'])) { + unset($swekey_id); + } else { + if (strlen($swekey_id) == 32) { + $res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp); + unset($_SESSION['SWEKEY']['RND_TOKEN']); + if (! $res) { + $result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')'; + } else { + $_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id; + $_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id]; + return null; + } + } else { + $result = __('No valid authentication key plugged'); + if ($_SESSION['SWEKEY']['CONF_DEBUG']) { + $result .= "
      " . htmlspecialchars($swekey_id); + } + unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file + } + } + } else { + unset($_SESSION['SWEKEY']); + } + + $_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken(); + if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) { + $result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')'; + unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file + } + + if (! isset($swekey_id)) { + ?> + + display(); + if ($GLOBALS['error_handler']->hasDisplayErrors()) { + echo '
      '; + $GLOBALS['error_handler']->dispErrors(); + echo '
      '; + } + } + + if (isset($_SESSION['SWEKEY']) && $_SESSION['SWEKEY']['ENABLED']) { + echo ''; + } +} + +if (!empty($_GET['session_to_unset'])) { + session_write_close(); + session_id($_GET['session_to_unset']); + session_start(); + $_SESSION = array(); + session_write_close(); + session_destroy(); + exit; +} + +if (isset($_GET['swekey_reset'])) { + unset($_SESSION['SWEKEY']); +} + +?> diff --git a/phpmyadmin/libraries/plugins/auth/swekey/swekey.php b/phpmyadmin/libraries/plugins/auth/swekey/swekey.php new file mode 100644 index 000000000..d495d45b4 --- /dev/null +++ b/phpmyadmin/libraries/plugins/auth/swekey/swekey.php @@ -0,0 +1,522 @@ +"; + +/** + * Servers addresses + * Use the Swekey_SetXxxServer($server) functions to set them + */ + +global $gSwekeyCheckServer; +if (! isset($gSwekeyCheckServer)) { + $gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER; +} + +global $gSwekeyRndTokenServer; +if (! isset($gSwekeyRndTokenServer)) { + $gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER; +} + +global $gSwekeyStatusServer; +if (! isset($gSwekeyStatusServer)) { + $gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER; +} + +global $gSwekeyCA; + +global $gSwekeyTokenCacheEnabled; +if (! isset($gSwekeyTokenCacheEnabled)) { + $gSwekeyTokenCacheEnabled = true; +} + +/** + * Change the address of the Check server. + * If $server is empty the default value 'http://auth-check.musbe.net' will be used + * + * @param server The protocol and hostname to use + * + * @access public + */ +function Swekey_SetCheckServer($server) +{ + global $gSwekeyCheckServer; + if (empty($server)) { + $gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER; + } else { + $gSwekeyCheckServer = $server; + } +} + +/** + * Change the address of the Random Token Generator server. + * If $server is empty the default value 'http://auth-rnd-gen.musbe.net' will be used + * + * @param server The protocol and hostname to use + * + * @access public + */ +function Swekey_SetRndTokenServer($server) +{ + global $gSwekeyRndTokenServer; + if (empty($server)) { + $gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER; + } else { + $gSwekeyRndTokenServer = $server; + } +} + +/** + * Change the address of the Satus server. + * If $server is empty the default value 'http://auth-status.musbe.net' will be used + * + * @param server The protocol and hostname to use + * + * @access public + */ +function Swekey_SetStatusServer($server) +{ + global $gSwekeyStatusServer; + if (empty($server)) { + $gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER; + } else { + $gSwekeyStatusServer = $server; + } +} + +/** + * Change the certificat file in case of the the severs use https instead of http + * + * @param cafile The path of the crt file to use + * + * @access public + */ +function Swekey_SetCAFile($cafile) +{ + global $gSwekeyCA; + $gSwekeyCA = $cafile; +} + +/** + * Enable or disable the random token caching + * Because everybody has full access to the cache file, it can be a DOS vulnerability + * So disable it if you are running in a non secure enviromnement + * + * @param $enable + * + * @access public + */ +function Swekey_EnableTokenCache($enable) +{ + global $gSwekeyTokenCacheEnabled; + $gSwekeyTokenCacheEnabled = ! empty($enable); +} + + +/** + * Return the last error. + * + * @return The Last Error + * @access public + */ +function Swekey_GetLastError() +{ + global $gSwekeyLastError; + return $gSwekeyLastError; +} + +/** + * Return the last result. + * + * @return The Last Error + * @access public + */ +function Swekey_GetLastResult() +{ + global $gSwekeyLastResult; + return $gSwekeyLastResult; +} + +/** + * Send a synchronous request to the server. + * This function manages timeout then will not block if one of the server is down + * + * @param url The url to get + * @param response_code The response code + * + * @return The body of the response or "" in case of error + * @access private + */ +function Swekey_HttpGet($url, &$response_code) +{ + global $gSwekeyLastError; + $gSwekeyLastError = 0; + global $gSwekeyLastResult; + $gSwekeyLastResult = ""; + + // use curl if available + if (function_exists('curl_init')) { + $sess = curl_init($url); + if (substr($url, 0, 8) == "https://") { + global $gSwekeyCA; + + if (! empty($gSwekeyCA)) { + if (file_exists($gSwekeyCA)) { + if (! curl_setopt($sess, CURLOPT_CAINFO, $gSwekeyCA)) { + error_log("SWEKEY_ERROR:Could not set CA file : ".curl_error($sess)); + } else { + $caFileOk = true; + } + } else { + error_log("SWEKEY_ERROR:Could not find CA file $gSwekeyCA getting $url"); + } + } + + curl_setopt($sess, CURLOPT_SSL_VERIFYHOST, '2'); + curl_setopt($sess, CURLOPT_SSL_VERIFYPEER, '2'); + curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '20'); + curl_setopt($sess, CURLOPT_TIMEOUT, '20'); + } else { + curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '3'); + curl_setopt($sess, CURLOPT_TIMEOUT, '5'); + } + + curl_setopt($sess, CURLOPT_RETURNTRANSFER, '1'); + $res=curl_exec($sess); + $response_code = curl_getinfo($sess, CURLINFO_HTTP_CODE); + $curlerr = curl_error($sess); + curl_close($sess); + + if ($response_code == 200) { + $gSwekeyLastResult = $res; + return $res; + } + + if (! empty($response_code)) { + $gSwekeyLastError = $response_code; + error_log("SWEKEY_ERROR:Error $gSwekeyLastError ($curlerr) getting $url"); + return ""; + } + + $response_code = 408; // Request Timeout + $gSwekeyLastError = $response_code; + error_log("SWEKEY_ERROR:Error $curlerr getting $url"); + return ""; + } + + // use pecl_http if available + if (class_exists('HttpRequest')) { + // retry if one of the server is down + for ($num=1; $num <= 3; $num++ ) { + $r = new HttpRequest($url); + $options = array('timeout' => '3'); + + if (substr($url, 0, 6) == "https:") { + $sslOptions = array(); + $sslOptions['verifypeer'] = true; + $sslOptions['verifyhost'] = true; + + $capath = __FILE__; + $name = strrchr($capath, '/'); + // windows + if (empty($name)) { + $name = strrchr($capath, '\\'); + } + $capath = substr($capath, 0, strlen($capath) - strlen($name) + 1).'musbe-ca.crt'; + + if (! empty($gSwekeyCA)) { + $sslOptions['cainfo'] = $gSwekeyCA; + } + + $options['ssl'] = $sslOptions; + } + + $r->setOptions($options); + + // try + { + $reply = $r->send(); + $res = $reply->getBody(); + $info = $r->getResponseInfo(); + $response_code = $info['response_code']; + if ($response_code != 200) { + $gSwekeyLastError = $response_code; + error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url); + return ""; + } + + + $gSwekeyLastResult = $res; + return $res; + } + // catch (HttpException $e) + // { + // error_log("SWEKEY_WARNING:HttpException ".$e." getting ".$url); + // } + } + + $response_code = 408; // Request Timeout + $gSwekeyLastError = $response_code; + error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url); + return ""; + } + + global $http_response_header; + $res = @file_get_contents($url); + $response_code = substr($http_response_header[0], 9, 3); //HTTP/1.0 + if ($response_code == 200) { + $gSwekeyLastResult = $res; + return $res; + } + + $gSwekeyLastError = $response_code; + error_log("SWEKEY_ERROR:Error ".$response_code." getting ".$url); + return ""; +} + +/** + * Get a Random Token from a Token Server + * The RT is a 64 vhars hexadecimal value + * You should better use Swekey_GetFastRndToken() for performance + * @access public + */ +function Swekey_GetRndToken() +{ + global $gSwekeyRndTokenServer; + return Swekey_HttpGet($gSwekeyRndTokenServer.'/FULL-RND-TOKEN', $response_code); +} + +/** + * Get a Half Random Token from a Token Server + * The RT is a 64 vhars hexadecimal value + * Use this value if you want to make your own Swekey_GetFastRndToken() + * @access public + */ +function Swekey_GetHalfRndToken() +{ + global $gSwekeyRndTokenServer; + return Swekey_HttpGet($gSwekeyRndTokenServer.'/HALF-RND-TOKEN', $response_code); +} + +/** + * Get a Half Random Token + * The RT is a 64 vhars hexadecimal value + * This function get a new random token and reuse it. + * Token are refetched from the server only once every 30 seconds. + * You should always use this function to get half random token. + * @access public + */ +function Swekey_GetFastHalfRndToken() +{ + global $gSwekeyTokenCacheEnabled; + + $res = ""; + $cachefile = ""; + + // We check if we have a valid RT is the session + if (isset($_SESSION['rnd-token-date'])) { + if (time() - $_SESSION['rnd-token-date'] < 30) { + $res = $_SESSION['rnd-token']; + } + } + + // If not we try to get it from a temp file (PHP >= 5.2.1 only) + if (strlen($res) != 32 && $gSwekeyTokenCacheEnabled) { + if (function_exists('sys_get_temp_dir')) { + $tempdir = sys_get_temp_dir(); + $cachefile = $tempdir."/swekey-rnd-token-".get_current_user(); + $modif = filemtime($cachefile); + if ($modif != false) { + if (time() - $modif < 30) { + $res = @file_get_contents($cachefile); + if (strlen($res) != 32) { + $res = ""; + } else { + $_SESSION['rnd-token'] = $res; + $_SESSION['rnd-token-date'] = $modif; + } + } + } + } + } + + // If we don't have a valid RT here we have to get it from the server + if (strlen($res) != 32) { + $res = substr(Swekey_GetHalfRndToken(), 0, 32); + $_SESSION['rnd-token'] = $res; + $_SESSION['rnd-token-date'] = time(); + if (! empty($cachefile)) { + // we unlink the file so no possible tempfile race attack + unlink($cachefile); + $file = fopen($cachefile, "x"); + if ($file != false) { + @fwrite($file, $res); + @fclose($file); + } + } + } + + return $res."00000000000000000000000000000000"; +} + +/** + * Get a Random Token + * The RT is a 64 vhars hexadecimal value + * This function generates a unique random token for each call but call the + * server only once every 30 seconds. + * You should always use this function to get random token. + * @access public + */ +function Swekey_GetFastRndToken() +{ + $res = Swekey_GetFastHalfRndToken(); + if (strlen($res) == 64) { + return substr($res, 0, 32).strtoupper(md5("Musbe Authentication Key" . mt_rand() . date(DATE_ATOM))); + } + return ""; +} + + +/** + * Checks that an OTP generated by a Swekey is valid + * + * @param id The id of the swekey + * @param rt The random token used to generate the otp + * @param otp The otp generated by the swekey + * + * @return true or false + * @access public + */ +function Swekey_CheckOtp($id, $rt, $otp) +{ + global $gSwekeyCheckServer; + $res = Swekey_HttpGet($gSwekeyCheckServer.'/CHECK-OTP/'.$id.'/'.$rt.'/'.$otp, $response_code); + return $response_code == 200 && $res == "OK"; +} + +/** + * Values that are associated with a key. + * The following values can be returned by the Swekey_GetStatus() function + */ +define("SWEKEY_STATUS_OK", 0); +define("SWEKEY_STATUS_NOT_FOUND", 1); // The key does not exist in the db +define("SWEKEY_STATUS_INACTIVE", 2); // The key has never been activated +define("SWEKEY_STATUS_LOST", 3); // The user has lost his key +define("SWEKEY_STATUS_STOLEN", 4); // The key was stolen +define("SWEKEY_STATUS_FEE_DUE", 5); // The annual fee was not paid +define("SWEKEY_STATUS_OBSOLETE", 6); // The hardware is no longer supported +define("SWEKEY_STATUS_UNKOWN", 201); // We could not connect to the authentication server + +/** + * Values that are associated with a key. + * The Javascript Api can also return the following values + */ +define("SWEKEY_STATUS_REPLACED", 100); // This key has been replaced by a backup key +define("SWEKEY_STATUS_BACKUP_KEY", 101); // This key is a backup key that is not activated yet +define("SWEKEY_STATUS_NOTPLUGGED", 200); // This key is not plugged in the computer + + +/** + * Return the text corresponding to the integer status of a key + * + * @param status The status + * + * @return The text corresponding to the status + * @access public + */ +function Swekey_GetStatusStr($status) +{ + switch($status) + { + case SWEKEY_STATUS_OK : + return 'OK'; + case SWEKEY_STATUS_NOT_FOUND : + return 'Key does not exist in the db'; + case SWEKEY_STATUS_INACTIVE : + return 'Key not activated'; + case SWEKEY_STATUS_LOST : + return 'Key was lost'; + case SWEKEY_STATUS_STOLEN : + return 'Key was stolen'; + case SWEKEY_STATUS_FEE_DUE : + return 'The annual fee was not paid'; + case SWEKEY_STATUS_OBSOLETE : + return 'Key no longer supported'; + case SWEKEY_STATUS_REPLACED : + return 'This key has been replaced by a backup key'; + case SWEKEY_STATUS_BACKUP_KEY : + return 'This key is a backup key that is not activated yet'; + case SWEKEY_STATUS_NOTPLUGGED : + return 'This key is not plugged in the computer'; + case SWEKEY_STATUS_UNKOWN : + return 'Unknow Status, could not connect to the authentication server'; + } + return 'unknown status '.$status; +} + +/** + * If your web site requires a key to login you should check that the key + * is still valid (has not been lost or stolen) before requiring it. + * A key can be authenticated only if its status is SWEKEY_STATUS_OK + * + * @param id The id of the swekey + * + * @return The status of the swekey + * @access public + */ +function Swekey_GetStatus($id) +{ + global $gSwekeyStatusServer; + $res = Swekey_HttpGet($gSwekeyStatusServer.'/GET-STATUS/'.$id, $response_code); + if ($response_code == 200) { + return intval($res); + } + return SWEKEY_STATUS_UNKOWN; +} + +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php b/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php new file mode 100644 index 000000000..d0a2216a4 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportCodegen.class.php @@ -0,0 +1,423 @@ +initSpecificVariables(); + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export CodeGen + * + * @return void + */ + protected function initSpecificVariables() + { + $this->_setCgFormats( + array( + "NHibernate C# DO", + "NHibernate XML" + ) + ); + + $this->_setCgHandlers( + array( + "_handleNHibernateCSBody", + "_handleNHibernateXMLBody" + ) + ); + } + + /** + * Sets the export CodeGen properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('CodeGen'); + $exportPluginProperties->setExtension('cs'); + $exportPluginProperties->setMimeType('text/cs'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + $leaf = new SelectPropertyItem(); + $leaf->setName("format"); + $leaf->setText(__('Format:')); + $leaf->setValues($this->_getCgFormats()); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $CG_FORMATS = $this->_getCgFormats(); + $CG_HANDLERS = $this->_getCgHandlers(); + + $format = $GLOBALS['codegen_format']; + if (isset($CG_FORMATS[$format])) { + return PMA_exportOutputHandler( + $this->$CG_HANDLERS[$format]($db, $table, $crlf) + ); + } + return PMA_exportOutputHandler(sprintf("%s is not supported.", $format)); + } + + /** + * Used to make identifiers (from table or database names) + * + * @param string $str name to be converted + * @param bool $ucfirst whether to make the first character uppercase + * + * @return string identifier + */ + public static function cgMakeIdentifier($str, $ucfirst = true) + { + // remove unsafe characters + $str = preg_replace('/[^\p{L}\p{Nl}_]/u', '', $str); + // make sure first character is a letter or _ + if (! preg_match('/^\pL/u', $str)) { + $str = '_' . $str; + } + if ($ucfirst) { + $str = ucfirst($str); + } + return $str; + } + + /** + * C# Handler + * + * @param string $db database name + * @param string $table table name + * @param string $crlf line separator + * + * @return string containing C# code lines, separated by "\n" + */ + private function _handleNHibernateCSBody($db, $table, $crlf) + { + $lines = array(); + + $result = PMA_DBI_query( + sprintf( + 'DESC %s.%s', PMA_Util::backquote($db), + PMA_Util::backquote($table) + ) + ); + if ($result) { + $tableProperties = array(); + while ($row = PMA_DBI_fetch_row($result)) { + $tableProperties[] = new TableProperty($row); + } + PMA_DBI_free_result($result); + $lines[] = 'using System;'; + $lines[] = 'using System.Collections;'; + $lines[] = 'using System.Collections.Generic;'; + $lines[] = 'using System.Text;'; + $lines[] = 'namespace ' . ExportCodegen::cgMakeIdentifier($db); + $lines[] = '{'; + $lines[] = ' #region ' . ExportCodegen::cgMakeIdentifier($table); + $lines[] = ' public class ' . ExportCodegen::cgMakeIdentifier($table); + $lines[] = ' {'; + $lines[] = ' #region Member Variables'; + foreach ($tableProperties as $tableProperty) { + $lines[] = $tableProperty->formatCs( + ' protected #dotNetPrimitiveType# _#name#;' + ); + } + $lines[] = ' #endregion'; + $lines[] = ' #region Constructors'; + $lines[] = ' public ' + . ExportCodegen::cgMakeIdentifier($table) . '() { }'; + $temp = array(); + foreach ($tableProperties as $tableProperty) { + if (! $tableProperty->isPK()) { + $temp[] = $tableProperty->formatCs( + '#dotNetPrimitiveType# #name#' + ); + } + } + $lines[] = ' public ' + . ExportCodegen::cgMakeIdentifier($table) + . '(' + . implode(', ', $temp) + . ')'; + $lines[] = ' {'; + foreach ($tableProperties as $tableProperty) { + if (! $tableProperty->isPK()) { + $lines[] = $tableProperty->formatCs( + ' this._#name#=#name#;' + ); + } + } + $lines[] = ' }'; + $lines[] = ' #endregion'; + $lines[] = ' #region Public Properties'; + foreach ($tableProperties as $tableProperty) { + $lines[] = $tableProperty->formatCs( + ' public virtual #dotNetPrimitiveType# #ucfirstName#' + . "\n" + . ' {' . "\n" + . ' get {return _#name#;}' . "\n" + . ' set {_#name#=value;}' . "\n" + . ' }' + ); + } + $lines[] = ' #endregion'; + $lines[] = ' }'; + $lines[] = ' #endregion'; + $lines[] = '}'; + } + return implode("\n", $lines); + } + + /** + * XML Handler + * + * @param string $db database name + * @param string $table table name + * @param string $crlf line separator + * + * @return string containing XML code lines, separated by "\n" + */ + private function _handleNHibernateXMLBody($db, $table, $crlf) + { + $lines = array(); + $lines[] = ''; + $lines[] = ''; + $lines[] = ' '; + $result = PMA_DBI_query( + sprintf( + "DESC %s.%s", PMA_Util::backquote($db), + PMA_Util::backquote($table) + ) + ); + if ($result) { + while ($row = PMA_DBI_fetch_row($result)) { + $tableProperty = new TableProperty($row); + if ($tableProperty->isPK()) { + $lines[] = $tableProperty->formatXml( + ' ' . "\n" + . ' ' . "\n" + . ' ' . "\n" + . ' ' + ); + } else { + $lines[] = $tableProperty->formatXml( + ' ' . "\n" + . ' ' . "\n" + . ' ' + ); + } + } + PMA_DBI_free_result($result); + } + $lines[] = ' '; + $lines[] = ''; + return implode("\n", $lines); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Getter for CodeGen formats + * + * @return array + */ + private function _getCgFormats() + { + return $this->_cgFormats; + } + + /** + * Setter for CodeGen formats + * + * @param array $CG_FORMATS contains CodeGen Formats + * + * @return void + */ + private function _setCgFormats($CG_FORMATS) + { + $this->_cgFormats = $CG_FORMATS; + } + + /** + * Getter for CodeGen handlers + * + * @return array + */ + private function _getCgHandlers() + { + return $this->_cgHandlers; + } + + /** + * Setter for CodeGen handlers + * + * @param array $CG_HANDLERS contains CodeGen handler methods + * + * @return void + */ + private function _setCgHandlers($CG_HANDLERS) + { + $this->_cgHandlers = $CG_HANDLERS; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportCsv.class.php b/phpmyadmin/libraries/plugins/export/ExportCsv.class.php new file mode 100644 index 000000000..98558e925 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportCsv.class.php @@ -0,0 +1,345 @@ +setProperties(); + } + + /** + * Sets the export CSV properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('CSV'); + $exportPluginProperties->setExtension('csv'); + $exportPluginProperties->setMimeType('text/comma-separated-values'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create leaf items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("separator"); + $leaf->setText(__('Columns separated with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("enclosed"); + $leaf->setText(__('Columns enclosed with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("escaped"); + $leaf->setText(__('Columns escaped with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("terminated"); + $leaf->setText(__('Lines terminated with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('removeCRLF'); + $leaf->setText( + __('Remove carriage return/line feed characters within columns') + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('columns'); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName('structure_or_data'); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped; + + // Here we just prepare some values for export + if ($what == 'excel') { + $csv_terminated = "\015\012"; + switch($GLOBALS['excel_edition']) { + case 'win': + // as tested on Windows with Excel 2002 and Excel 2007 + $csv_separator = ';'; + break; + case 'mac_excel2003': + $csv_separator = ';'; + break; + case 'mac_excel2008': + $csv_separator = ','; + break; + } + $csv_enclosed = '"'; + $csv_escaped = '"'; + if (isset($GLOBALS['excel_columns'])) { + $GLOBALS['csv_columns'] = 'yes'; + } + } else { + if (empty($csv_terminated) || strtolower($csv_terminated) == 'auto') { + $csv_terminated = $GLOBALS['crlf']; + } else { + $csv_terminated = str_replace('\\r', "\015", $csv_terminated); + $csv_terminated = str_replace('\\n', "\012", $csv_terminated); + $csv_terminated = str_replace('\\t', "\011", $csv_terminated); + } // end if + $csv_separator = str_replace('\\t', "\011", $csv_separator); + } + + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in CSV format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS['csv_columns'])) { + $schema_insert = ''; + for ($i = 0; $i < $fields_cnt; $i++) { + if ($csv_enclosed == '') { + $schema_insert .= stripslashes(PMA_DBI_field_name($result, $i)); + } else { + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . $csv_enclosed; + } + $schema_insert .= $csv_separator; + } // end for + $schema_insert = trim(substr($schema_insert, 0, -1)); + if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $schema_insert = ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $schema_insert .= $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + // always enclose fields + if ($what == 'excel') { + $row[$j] = preg_replace("/\015(\012)?/", "\012", $row[$j]); + } + // remove CRLF characters within field + if (isset($GLOBALS[$what . '_removeCRLF']) + && $GLOBALS[$what . '_removeCRLF'] + ) { + $row[$j] = str_replace( + "\n", + "", + str_replace( + "\r", + "", + $row[$j] + ) + ); + } + if ($csv_enclosed == '') { + $schema_insert .= $row[$j]; + } else { + // also double the escape string if found in the data + if ($csv_escaped != $csv_enclosed) { + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + str_replace( + $csv_escaped, + $csv_escaped . $csv_escaped, + $row[$j] + ) + ) + . $csv_enclosed; + } else { + // avoid a problem when escape string equals enclose + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + $row[$j] + ) + . $csv_enclosed; + } + } + } else { + $schema_insert .= ''; + } + if ($j < $fields_cnt-1) { + $schema_insert .= $csv_separator; + } + } // end for + + if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + + return true; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportExcel.class.php b/phpmyadmin/libraries/plugins/export/ExportExcel.class.php new file mode 100644 index 000000000..1bb1060d2 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportExcel.class.php @@ -0,0 +1,105 @@ +setText('CSV for MS Excel'); + $exportPluginProperties->setExtension('csv'); + $exportPluginProperties->setMimeType('text/comma-separated-values'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('removeCRLF'); + $leaf->setText( + __('Remove carriage return/line feed characters within columns') + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('columns'); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new SelectPropertyItem(); + $leaf->setName('edition'); + $leaf->setValues( + array( + 'win' => 'Windows', + 'mac_excel2003' => 'Excel 2003 / Macintosh', + 'mac_excel2008' => 'Excel 2008 / Macintosh' + ) + ); + $leaf->setText(__('Excel edition:')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName('structure_or_data'); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php b/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php new file mode 100644 index 000000000..cdd5ec683 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportHtmlword.class.php @@ -0,0 +1,645 @@ +setProperties(); + } + + /** + * Sets the export HTML-Word properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('Microsoft Word 2000'); + $exportPluginProperties->setExtension('doc'); + $exportPluginProperties->setMimeType('application/vnd.ms-word'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("dump_what"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("dump_what"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("null"); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $charset_of_file; + + return PMA_exportOutputHandler( + ' + + + + + + + ' + ); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return PMA_exportOutputHandler(''); + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return PMA_exportOutputHandler( + '

      ' . __('Database') . ' ' . htmlspecialchars($db) . '

      ' + ); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in HTML-Word format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + if (! PMA_exportOutputHandler( + '

      ' + . __('Dumping data for table') . ' ' . htmlspecialchars($table) + . '

      ' + )) { + return false; + } + if (! PMA_exportOutputHandler( + '' + )) { + return false; + } + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS['htmlword_columns'])) { + $schema_insert = ''; + for ($i = 0; $i < $fields_cnt; $i++) { + $schema_insert .= ''; + } // end for + $schema_insert .= ''; + if (! PMA_exportOutputHandler($schema_insert)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $schema_insert = ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $value = $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + $value = $row[$j]; + } else { + $value = ''; + } + $schema_insert .= ''; + } // end for + $schema_insert .= ''; + if (! PMA_exportOutputHandler($schema_insert)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + if (! PMA_exportOutputHandler('
      ')) { + return false; + } + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + public function getTableDefStandIn($db, $view, $crlf) + { + $schema_insert = '' + . '' + . '' + . '' + . '' + . '' + . ''; + + /** + * Get the unique keys in the view + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $view); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $schema_insert .= $this->formatOneColumnDefinition( + $column, + $unique_keys + ); + $schema_insert .= ''; + } + + $schema_insert .= '
      '; + return $schema_insert; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line + * at the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + // set $cfgRelation here, because there is a chance that it's modified + // since the class initialization + global $cfgRelation; + + $schema_insert = ''; + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $schema_insert .= ''; + + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments && $cfgRelation['commwork']) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + + $schema_insert .= ''; + $schema_insert .= ''; + $schema_insert .= ''; + $schema_insert .= ''; + $schema_insert .= ''; + if ($do_relation && $have_rel) { + $schema_insert .= ''; + } + if ($do_comments) { + $schema_insert .= ''; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $schema_insert .= ''; + $mime_map = PMA_getMIME($db, $table, true); + } + $schema_insert .= ''; + + $columns = PMA_DBI_get_columns($db, $table); + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + foreach ($columns as $column) { + $schema_insert .= $this->formatOneColumnDefinition( + $column, + $unique_keys + ); + $field_name = $column['Field']; + + if ($do_relation && $have_rel) { + $schema_insert .= ''; + } + if ($do_comments && $cfgRelation['commwork']) { + $schema_insert .= ''; + } + if ($do_mime && $cfgRelation['mimework']) { + $schema_insert .= ''; + } + + $schema_insert .= ''; + } // end foreach + + $schema_insert .= '
      ' + . (isset($res_rel[$field_name]) + ? htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] + . ')' + ) + : '') . '' + . (isset($comments[$field_name]) + ? htmlspecialchars($comments[$field_name]) + : '') . '' + . (isset($mime_map[$field_name]) ? + htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + : '') . '
      '; + return $schema_insert; + } + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return string Formatted triggers list + */ + protected function getTriggers($db, $table) + { + $dump = ''; + $dump .= ''; + $dump .= ''; + $dump .= ''; + $dump .= ''; + $dump .= ''; + $dump .= ''; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $dump .= ''; + $dump .= '' + . '' + . '' + . '' + . ''; + } + + $dump .= '
      '; + return $dump; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + $dump = ''; + + switch($export_mode) { + case 'create_table': + $dump .= '

      ' + . __('Table structure for table') . ' ' . htmlspecialchars($table) + . '

      '; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, + $dates + ); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= '

      ' + . __('Triggers') . ' ' . htmlspecialchars($table) + . '

      '; + $dump .= $this->getTriggers($db, $table); + } + break; + case 'create_view': + $dump .= '

      ' + . __('Structure for view') . ' ' . htmlspecialchars($table) + . '

      '; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, + $dates, true, true + ); + break; + case 'stand_in': + $dump .= '

      ' + . __('Stand-in structure for view') . ' ' . htmlspecialchars($table) + . '

      '; + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return PMA_exportOutputHandler($dump); + } + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * @param array $unique_keys unique keys of the table + * + * @return string Formatted column definition + */ + protected function formatOneColumnDefinition( + $column, $unique_keys + ) { + $definition = ''; + + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + + $type = htmlspecialchars($extracted_columnspec['print_type']); + if (empty($type)) { + $type = ' '; + } + + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } + } + + $fmt_pre = ''; + $fmt_post = ''; + if (in_array($column['Field'], $unique_keys)) { + $fmt_pre = '' . $fmt_pre; + $fmt_post = $fmt_post . ''; + } + if ($column['Key'] == 'PRI') { + $fmt_pre = '' . $fmt_pre; + $fmt_post = $fmt_post . ''; + } + $definition .= '' . $fmt_pre + . htmlspecialchars($column['Field']) . $fmt_post . ''; + $definition .= '' . htmlspecialchars($type) + . ''; + $definition .= '' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') + : __('Yes')) + . ''; + $definition .= '' + . htmlspecialchars( + isset($column['Default']) + ? $column['Default'] + : '' + ) + . ''; + + return $definition; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportJson.class.php b/phpmyadmin/libraries/plugins/export/ExportJson.class.php new file mode 100644 index 000000000..299e248c0 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportJson.class.php @@ -0,0 +1,221 @@ +setProperties(); + } + + /** + * Sets the export JSON properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('JSON'); + $exportPluginProperties->setExtension('json'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + '/**' . $GLOBALS['crlf'] + . ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf'] + . ' @version 0.1' . $GLOBALS['crlf'] + . ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + PMA_exportOutputHandler('// Database \'' . $db . '\'' . $GLOBALS['crlf']); + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $columns_cnt = PMA_DBI_num_fields($result); + + // Get field information + $fields_meta = PMA_DBI_get_fields_meta($result); + + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ''; + $record_cnt = 0; + while ($record = PMA_DBI_fetch_row($result)) { + + $record_cnt++; + + // Output table name as comment if this is the first record of the table + if ($record_cnt == 1) { + $buffer .= '// ' . $db . '.' . $table . $crlf . $crlf; + $buffer .= '[{'; + } else { + $buffer .= ', {'; + } + + for ($i = 0; $i < $columns_cnt; $i++) { + $isLastLine = ($i + 1 >= $columns_cnt); + $column = $columns[$i]; + if (is_null($record[$i])) { + $buffer .= '"' . addslashes($column) + . '": null' + . (! $isLastLine ? ',' : ''); + } elseif ($fields_meta[$i]->numeric) { + $buffer .= '"' . addslashes($column) + . '": ' + . $record[$i] + . (! $isLastLine ? ',' : ''); + } else { + $buffer .= '"' . addslashes($column) + . '": "' + . addslashes($record[$i]) + . '"' + . (! $isLastLine ? ',' : ''); + } + } + + $buffer .= '}'; + } + + if ($record_cnt) { + $buffer .= ']'; + } + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportLatex.class.php b/phpmyadmin/libraries/plugins/export/ExportLatex.class.php new file mode 100644 index 000000000..0f5c953a8 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportLatex.class.php @@ -0,0 +1,655 @@ +initSpecificVariables(); + + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export Latex + * + * @return void + */ + protected function initSpecificVariables() + { + /* Messages used in default captions */ + $GLOBALS['strLatexContent'] = __('Content of table @TABLE@'); + $GLOBALS['strLatexContinued'] = __('(continued)'); + $GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@'); + } + + /** + * Sets the export Latex properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + } + + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('LaTeX'); + $exportPluginProperties->setExtension('tex'); + $exportPluginProperties->setMimeType('application/x-tex'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("caption"); + $leaf->setText(__('Include table caption')); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("dump_what"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("structure_caption"); + $leaf->setText(__('Table caption')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("structure_continued_caption"); + $leaf->setText(__('Table caption (continued)')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("structure_label"); + $leaf->setText(__('Label key')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("relation"); + $leaf->setText(__('Display foreign key relationships')); + $structureOptions->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("comments"); + $leaf->setText(__('Display comments')); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("mime"); + $leaf->setText(__('Display MIME types')); + $structureOptions->addProperty($leaf); + } + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_caption"); + $leaf->setText(__('Table caption')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_continued_caption"); + $leaf->setText(__('Table caption (continued)')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_label"); + $leaf->setText(__('Label key')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $crlf; + global $cfg; + + $head = '% phpMyAdmin LaTeX Dump' . $crlf + . '% version ' . PMA_VERSION . $crlf + . '% http://www.phpmyadmin.net' . $crlf + . '%' . $crlf + . '% ' . __('Host') . ': ' . $cfg['Server']['host']; + if (! empty($cfg['Server']['port'])) { + $head .= ':' . $cfg['Server']['port']; + } + $head .= $crlf + . '% ' . __('Generation Time') . ': ' + . PMA_Util::localisedDate() . $crlf + . '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf + . '% ' . __('PHP Version') . ': ' . phpversion() . $crlf; + return PMA_exportOutputHandler($head); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + global $crlf; + $head = '% ' . $crlf + . '% ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf + . '% ' . $crlf; + return PMA_exportOutputHandler($head); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = PMA_DBI_field_name($result, $i); + } + unset($i); + + $buffer = $crlf . '%' . $crlf . '% ' . __('Data') . ': ' . $table + . $crlf . '%' . $crlf . ' \\begin{longtable}{|'; + + for ($index = 0; $index < $columns_cnt; $index++) { + $buffer .= 'l|'; + } + $buffer .= '} ' . $crlf ; + + $buffer .= ' \\hline \\endhead \\hline \\endfoot \\hline ' . $crlf; + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\label{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_label'], + null, + array('table' => $table, 'database' => $db) + ) + . '} \\\\'; + } + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + // show column names + if (isset($GLOBALS['latex_columns'])) { + $buffer = '\\hline '; + for ($i = 0; $i < $columns_cnt; $i++) { + $buffer .= '\\multicolumn{1}{|c|}{\\textbf{' + . self::texEscape(stripslashes($columns[$i])) . '}} & '; + } + + $buffer = substr($buffer, 0, -2) . '\\\\ \\hline \hline '; + if (! PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) { + return false; + } + if (isset($GLOBALS['latex_caption'])) { + if (! PMA_exportOutputHandler( + '\\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_continued_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' + . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\\\ ' + )) { + return false; + } + } + if (! PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) { + return false; + } + } else { + if (! PMA_exportOutputHandler('\\\\ \hline')) { + return false; + } + } + + // print the whole table + while ($record = PMA_DBI_fetch_assoc($result)) { + $buffer = ''; + // print each row + for ($i = 0; $i < $columns_cnt; $i++) { + if ((! function_exists('is_null') + || ! is_null($record[$columns[$i]])) + && isset($record[$columns[$i]]) + ) { + $column_value = self::texEscape( + stripslashes($record[$columns[$i]]) + ); + } else { + $column_value = $GLOBALS['latex_null']; + } + + // last column ... no need for & character + if ($i == ($columns_cnt - 1)) { + $buffer .= $column_value; + } else { + $buffer .= $column_value . " & "; + } + } + $buffer .= ' \\\\ \\hline ' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + + $buffer = ' \\end{longtable}' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } // end getTableLaTeX + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + global $cfgRelation; + + /* We do not export triggers */ + if ($export_mode == 'triggers') { + return true; + } + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $buffer = $crlf . '%' . $crlf . '% ' . __('Structure') . ': ' . $table + . $crlf . '%' . $crlf . ' \\begin{longtable}{'; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + $columns_cnt = 4; + $alignment = '|l|c|c|c|'; + if ($do_relation && $have_rel) { + $columns_cnt++; + $alignment .= 'l|'; + } + if ($do_comments) { + $columns_cnt++; + $alignment .= 'l|'; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + $alignment .='l|'; + } + $buffer = $alignment . '} ' . $crlf ; + + $header = ' \\hline '; + $header .= '\\multicolumn{1}{|c|}{\\textbf{' . __('Column') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Type') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Null') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Default') . '}}'; + if ($do_relation && $have_rel) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Links to') . '}}'; + } + if ($do_comments) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Comments') . '}}'; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{MIME}}'; + $mime_map = PMA_getMIME($db, $table, true); + } + + // Table caption for first page and label + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\label{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_label'], + null, + array('table' => $table, 'database' => $db) + ) + . '} \\\\' . $crlf; + } + $buffer .= $header . ' \\\\ \\hline \\hline' . $crlf + . '\\endfirsthead' . $crlf; + // Table caption on next pages + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_continued_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\\\ ' . $crlf; + } + $buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + $fields = PMA_DBI_get_columns($db, $table); + foreach ($fields as $row) { + $extracted_columnspec + = PMA_Util::extractColumnSpec( + $row['Type'] + ); + $type = $extracted_columnspec['print_type']; + if (empty($type)) { + $type = ' '; + } + + if (! isset($row['Default'])) { + if ($row['Null'] != 'NO') { + $row['Default'] = 'NULL'; + } + } + + $field_name = $row['Field']; + + $local_buffer = $field_name . "\000" . $type . "\000" + . (($row['Null'] == '' || $row['Null'] == 'NO') + ? __('No') : __('Yes')) + . "\000" . (isset($row['Default']) ? $row['Default'] : ''); + + if ($do_relation && $have_rel) { + $local_buffer .= "\000"; + if (isset($res_rel[$field_name])) { + $local_buffer .= $res_rel[$field_name]['foreign_table'] . ' (' + . $res_rel[$field_name]['foreign_field'] . ')'; + } + } + if ($do_comments && $cfgRelation['commwork']) { + $local_buffer .= "\000"; + if (isset($comments[$field_name])) { + $local_buffer .= $comments[$field_name]; + } + } + if ($do_mime && $cfgRelation['mimework']) { + $local_buffer .= "\000"; + if (isset($mime_map[$field_name])) { + $local_buffer .= str_replace( + '_', + '/', + $mime_map[$field_name]['mimetype'] + ); + } + } + $local_buffer = self::texEscape($local_buffer); + if ($row['Key']=='PRI') { + $pos=strpos($local_buffer, "\000"); + $local_buffer = '\\textit{' + . substr($local_buffer, 0, $pos) + . '}' . substr($local_buffer, $pos); + } + if (in_array($field_name, $unique_keys)) { + $pos=strpos($local_buffer, "\000"); + $local_buffer = '\\textbf{' + . substr($local_buffer, 0, $pos) + . '}' . substr($local_buffer, $pos); + } + $buffer = str_replace("\000", ' & ', $local_buffer); + $buffer .= ' \\\\ \\hline ' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } // end while + + $buffer = ' \\end{longtable}' . $crlf; + return PMA_exportOutputHandler($buffer); + } // end of the 'exportStructure' method + + /** + * Escapes some special characters for use in TeX/LaTeX + * + * @param string $string the string to convert + * + * @return string the converted string with escape codes + */ + public static function texEscape($string) + { + $escape = array('$', '%', '{', '}', '&', '#', '_', '^'); + $cnt_escape = count($escape); + for ($k = 0; $k < $cnt_escape; $k++) { + $string = str_replace($escape[$k], '\\' . $escape[$k], $string); + } + return $string; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php b/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php new file mode 100644 index 000000000..89afe7100 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportMediawiki.class.php @@ -0,0 +1,364 @@ +setProperties(); + } + + /** + * Sets the export MediaWiki properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/groups/OptionsPropertySubgroup.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('MediaWiki Table'); + $exportPluginProperties->setExtension('mediawiki'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + $generalOptions->setText(__('Dump table')); + + // what to dump (structure/data/both) + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("dump_table"); + $subgroup->setText("Dump table"); + $leaf = new RadioPropertyItem(); + $leaf->setName('structure_or_data'); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $subgroup->setSubgroupHeader($leaf); + $generalOptions->addProperty($subgroup); + + // export table name + $leaf = new BoolPropertyItem(); + $leaf->setName("caption"); + $leaf->setText(__('Export table names')); + $generalOptions->addProperty($leaf); + + // export table headers + $leaf = new BoolPropertyItem(); + $leaf->setName("headers"); + $leaf->setText(__('Export table headers')); + $generalOptions->addProperty($leaf); + //add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table','triggers','create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; this is + * deprecated but the parameter is left here + * because export.php calls exportStructure() + * also for other export types which use this + * parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + switch($export_mode) { + case 'create_table': + $columns = PMA_DBI_get_columns($db, $table); + $columns = array_values($columns); + $row_cnt = count($columns); + + // Print structure comment + $output = $this->_exportComment( + "Table structure for " + . PMA_Util::backquote($table) + ); + + // Begin the table construction + $output .= "{| class=\"wikitable\" style=\"text-align:center;\"" + . $this->_exportCRLF(); + + // Add the table name + if ($GLOBALS['mediawiki_caption']) { + $output .= "|+'''" . $table . "'''" . $this->_exportCRLF(); + } + + // Add the table headers + if ($GLOBALS['mediawiki_headers']) { + $output .= "|- style=\"background:#ffdead;\"" . $this->_exportCRLF(); + $output .= "! style=\"background:#ffffff\" | " + . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Field']. $this->_exportCRLF(); + } + } + + // Add the table structure + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Type" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Type'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Null" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Null'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Default" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Default'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Extra" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Extra'] . $this->_exportCRLF(); + } + + $output .= "|}" . str_repeat($this->_exportCRLF(), 2); + break; + } // end switch + + return PMA_exportOutputHandler($output); + } + + /** + * Outputs the content of a table in MediaWiki format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData( + $db, + $table, + $crlf, + $error_url, + $sql_query + ) { + // Print data comment + $output = $this->_exportComment( + "Table data for ". PMA_Util::backquote($table) + ); + + // Begin the table construction + // Use the "wikitable" class for style + // Use the "sortable" class for allowing tables to be sorted by column + $output .= "{| class=\"wikitable sortable\" style=\"text-align:center;\"" + . $this->_exportCRLF(); + + // Add the table name + if ($GLOBALS['mediawiki_caption']) { + $output .= "|+'''" . $table . "'''" . $this->_exportCRLF(); + } + + // Add the table headers + if ($GLOBALS['mediawiki_headers']) { + // Get column names + $column_names = PMA_DBI_get_column_names($db, $table); + + // Add column names as table headers + if ( ! is_null($column_names) ) { + // Use '|-' for separating rows + $output .= "|-" . $this->_exportCRLF(); + + // Use '!' for separating table headers + foreach ($column_names as $column) { + $output .= " ! " . $column . "" . $this->_exportCRLF(); + } + } + } + + // Get the table data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + while ($row = PMA_DBI_fetch_row($result)) { + $output .= "|-" . $this->_exportCRLF(); + + // Use '|' for separating table columns + for ($i = 0; $i < $fields_cnt; ++ $i) { + $output .= " | " . $row[$i] . "" . $this->_exportCRLF(); + } + } + + // End table construction + $output .= "|}" . str_repeat($this->_exportCRLF(), 2); + return PMA_exportOutputHandler($output); + } + + /** + * Outputs comments containing info about the exported tables + * + * @param string $text Text of comment + * + * @return string The formatted comment + */ + private function _exportComment($text = '') + { + // see http://www.mediawiki.org/wiki/Help:Formatting + $comment = $this->_exportCRLF(); + $comment .= '' . str_repeat($this->_exportCRLF(), 2); + + return $comment; + } + + /** + * Outputs CRLF + * + * @return string CRLF + */ + private function _exportCRLF() + { + // The CRLF expected by the mediawiki format is "\n" + return "\n"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportOds.class.php b/phpmyadmin/libraries/plugins/export/ExportOds.class.php new file mode 100644 index 000000000..b1e9f91e7 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportOds.class.php @@ -0,0 +1,334 @@ +setProperties(); + } + + /** + * Sets the export ODS properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('OpenDocument Spreadsheet'); + $exportPluginProperties->setExtension('ods'); + $exportPluginProperties->setMimeType( + 'application/vnd.oasis.opendocument.spreadsheet' + ); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("null"); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $GLOBALS['ods_buffer'] .= '' + . '' + . '' + . '' + . '' + . '/' + . '' + . '/' + . '' + . '' + . '' + . '' + . ':' + . '' + . ':' + . '' + . ' ' + . '' + . '' + . '' + . '' + . '/' + . '' + . '/' + . '' + . ' ' + . '' + . ':' + . '' + . ' ' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . ''; + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $GLOBALS['ods_buffer'] .= '' + . '' + . ''; + if (! PMA_exportOutputHandler( + PMA_createOpenDocument( + 'application/vnd.oasis.opendocument.spreadsheet', + $GLOBALS['ods_buffer'] + ) + )) { + return false; + } + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + $GLOBALS['ods_buffer'] .= + ''; + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $GLOBALS['ods_buffer'] .= ''; + for ($i = 0; $i < $fields_cnt; $i++) { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . '' + . ''; + } // end for + $GLOBALS['ods_buffer'] .= ''; + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $GLOBALS['ods_buffer'] .= ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($GLOBALS[$what . '_null']) + . '' + . ''; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + ) { + // ignore BLOB + $GLOBALS['ods_buffer'] .= + '' + . '' + . ''; + } elseif ($fields_meta[$j]->type == "date") { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } elseif ($fields_meta[$j]->type == "time") { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } elseif ($fields_meta[$j]->type == "datetime") { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } elseif (($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob) || $fields_meta[$j]->type == 'real' + ) { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } else { + $GLOBALS['ods_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } + } // end for + $GLOBALS['ods_buffer'] .= ''; + } // end while + PMA_DBI_free_result($result); + + $GLOBALS['ods_buffer'] .= ''; + + return true; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportOdt.class.php b/phpmyadmin/libraries/plugins/export/ExportOdt.class.php new file mode 100644 index 000000000..bb608f0e6 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportOdt.class.php @@ -0,0 +1,734 @@ +setProperties(); + } + + /** + * Sets the export ODT properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + } + + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('OpenDocument Text'); + $exportPluginProperties->setExtension('odt'); + $exportPluginProperties->setMimeType( + 'application/vnd.oasis.opendocument.text' + ); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("general_opts"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + // create primary items and add them to the group + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("relation"); + $leaf->setText(__('Display foreign key relationships')); + $structureOptions->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("comments"); + $leaf->setText(__('Display comments')); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("mime"); + $leaf->setText(__('Display MIME types')); + $structureOptions->addProperty($leaf); + } + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $GLOBALS['odt_buffer'] .= '' + . '' + . '' + . ''; + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $GLOBALS['odt_buffer'] .= '' + . '' + . ''; + if (! PMA_exportOutputHandler( + PMA_createOpenDocument( + 'application/vnd.oasis.opendocument.text', + $GLOBALS['odt_buffer'] + ) + )) { + return false; + } + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + $GLOBALS['odt_buffer'] .= + '' + . __('Database') . ' ' . htmlspecialchars($db) + . ''; + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + $GLOBALS['odt_buffer'] .= + '' + . __('Dumping data for table') . ' ' . htmlspecialchars($table) + . '' + . '' + . ''; + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $GLOBALS['odt_buffer'] .= ''; + for ($i = 0; $i < $fields_cnt; $i++) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . '' + . ''; + } // end for + $GLOBALS['odt_buffer'] .= ''; + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $GLOBALS['odt_buffer'] .= ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars($GLOBALS[$what . '_null']) + . '' + . ''; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + ) { + // ignore BLOB + $GLOBALS['odt_buffer'] .= + '' + . '' + . ''; + } elseif ($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob + ) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } else { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars($row[$j]) + . '' + . ''; + } + } // end for + $GLOBALS['odt_buffer'] .= ''; + } // end while + PMA_DBI_free_result($result); + + $GLOBALS['odt_buffer'] .= ''; + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return bool true + */ + public function getTableDefStandIn($db, $view, $crlf) + { + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + /** + * Displays the table structure + */ + $GLOBALS['odt_buffer'] .= + ''; + $columns_cnt = 4; + $GLOBALS['odt_buffer'] .= + ''; + /* Header */ + $GLOBALS['odt_buffer'] .= '' + . '' + . '' . __('Column') . '' + . '' + . '' + . '' . __('Type') . '' + . '' + . '' + . '' . __('Null') . '' + . '' + . '' + . '' . __('Default') . '' + . '' + . ''; + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column); + $GLOBALS['odt_buffer'] .= ''; + } // end foreach + + $GLOBALS['odt_buffer'] .= ''; + return true; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line at + * the end + * @param bool $view whether we're handling a view + * + * @return bool true + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $cfgRelation; + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $GLOBALS['odt_buffer'] .= ''; + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + $GLOBALS['odt_buffer'] .= ''; + /* Header */ + $GLOBALS['odt_buffer'] .= '' + . '' + . '' . __('Column') . '' + . '' + . '' + . '' . __('Type') . '' + . '' + . '' + . '' . __('Null') . '' + . '' + . '' + . '' . __('Default') . '' + . ''; + if ($do_relation && $have_rel) { + $GLOBALS['odt_buffer'] .= '' + . '' . __('Links to') . '' + . ''; + } + if ($do_comments) { + $GLOBALS['odt_buffer'] .= '' + . '' . __('Comments') . '' + . ''; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $GLOBALS['odt_buffer'] .= '' + . '' . __('MIME type') . '' + . ''; + $mime_map = PMA_getMIME($db, $table, true); + } + $GLOBALS['odt_buffer'] .= ''; + + $columns = PMA_DBI_get_columns($db, $table); + foreach ($columns as $column) { + $field_name = $column['Field']; + $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column); + + if ($do_relation && $have_rel) { + if (isset($res_rel[$field_name])) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] . ')' + ) + . '' + . ''; + } + } + if ($do_comments) { + if (isset($comments[$field_name])) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars($comments[$field_name]) + . '' + . ''; + } else { + $GLOBALS['odt_buffer'] .= + '' + . '' + . ''; + } + } + if ($do_mime && $cfgRelation['mimework']) { + if (isset($mime_map[$field_name])) { + $GLOBALS['odt_buffer'] .= + '' + . '' + . htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + . '' + . ''; + } else { + $GLOBALS['odt_buffer'] .= + '' + . '' + . ''; + } + } + $GLOBALS['odt_buffer'] .= ''; + } // end foreach + + $GLOBALS['odt_buffer'] .= ''; + return true; + } // end of the '$this->getTableDef()' function + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return bool true + */ + protected function getTriggers($db, $table) + { + $GLOBALS['odt_buffer'] .= '' + . '' + . '' + . '' + . '' . __('Name') . '' + . '' + . '' + . '' . __('Time') . '' + . '' + . '' + . '' . __('Event') . '' + . '' + . '' + . '' . __('Definition') . '' + . '' + . ''; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $GLOBALS['odt_buffer'] .= ''; + $GLOBALS['odt_buffer'] .= '' + . '' + . htmlspecialchars($trigger['name']) + . '' + . ''; + $GLOBALS['odt_buffer'] .= '' + . '' + . htmlspecialchars($trigger['action_timing']) + . '' + . ''; + $GLOBALS['odt_buffer'] .= '' + . '' + . htmlspecialchars($trigger['event_manipulation']) + . '' + . ''; + $GLOBALS['odt_buffer'] .= '' + . '' + . htmlspecialchars($trigger['definition']) + . '' + . ''; + $GLOBALS['odt_buffer'] .= ''; + } + + $GLOBALS['odt_buffer'] .= ''; + return true; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + switch($export_mode) { + case 'create_table': + $GLOBALS['odt_buffer'] .= + '' + . __('Table structure for table') . ' ' . + htmlspecialchars($table) + . ''; + $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates + ); + break; + case 'triggers': + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $GLOBALS['odt_buffer'] .= + '' + . __('Triggers') . ' ' + . htmlspecialchars($table) + . ''; + $this->getTriggers($db, $table); + } + break; + case 'create_view': + $GLOBALS['odt_buffer'] .= + '' + . __('Structure for view') . ' ' + . htmlspecialchars($table) + . ''; + $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates, true, true + ); + break; + case 'stand_in': + $GLOBALS['odt_buffer'] .= + '' + . __('Stand-in structure for view') . ' ' + . htmlspecialchars($table) + . ''; + // export a stand-in definition to resolve view dependencies + $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return true; + } // end of the '$this->exportStructure' function + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * + * @return string Formatted column definition + */ + protected function formatOneColumnDefinition($column) + { + $field_name = $column['Field']; + $definition = ''; + $definition .= '' + . '' . htmlspecialchars($field_name) . '' + . ''; + + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + $type = htmlspecialchars($extracted_columnspec['print_type']); + if (empty($type)) { + $type = ' '; + } + + $definition .= '' + . '' . htmlspecialchars($type) . '' + . ''; + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } else { + $column['Default'] = ''; + } + } else { + $column['Default'] = $column['Default']; + } + $definition .= '' + . '' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') + : __('Yes')) + . '' + . ''; + $definition .= '' + . '' . htmlspecialchars($column['Default']) . '' + . ''; + return $definition; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportPdf.class.php b/phpmyadmin/libraries/plugins/export/ExportPdf.class.php new file mode 100644 index 000000000..ffabb96ef --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportPdf.class.php @@ -0,0 +1,268 @@ +initSpecificVariables(); + + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export PDF + * + * @return void + */ + protected function initSpecificVariables() + { + $this->_setPdfReportTitle(""); + $this->_setPdf(new PMA_ExportPdf('L', 'pt', 'A3')); + } + + /** + * Sets the export PDF properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('PDF'); + $exportPluginProperties->setExtension('pdf'); + $exportPluginProperties->setMimeType('application/pdf'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new MessageOnlyPropertyItem(); + $leaf->setName("explanation"); + $leaf->setText( + __('(Generates a report containing the data of a single table)') + ); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("report_title"); + $leaf->setText(__('Report title:')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $pdf_report_title = $this->_getPdfReportTitle(); + $pdf = $this->_getPdf(); + $pdf->Open(); + + $attr = array('titleFontSize' => 18, 'titleText' => $pdf_report_title); + $pdf->setAttributes($attr); + $pdf->setTopMargin(30); + + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $pdf = $this->_getPdf(); + + // instead of $pdf->Output(): + if (! PMA_exportOutputHandler($pdf->getPDFData())) { + return false; + } + + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $pdf = $this->_getPdf(); + + $attr = array('currentDb' => $db, 'currentTable' => $table); + $pdf->setAttributes($attr); + $pdf->mysqlReport($sql_query); + + return true; + } // end of the 'PMA_exportData()' function + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the PMA_ExportPdf instance + * + * @return PMA_ExportPdf + */ + private function _getPdf() + { + return $this->_pdf; + } + + /** + * Instantiates the PMA_ExportPdf class + * + * @param string $pdf PMA_ExportPdf instance + * + * @return void + */ + private function _setPdf($pdf) + { + $this->_pdf = $pdf; + } + + /** + * Gets the PDF report title + * + * @return string + */ + private function _getPdfReportTitle() + { + return $this->_pdfReportTitle; + } + + /** + * Sets the PDF report title + * + * @param string $pdfReportTitle PDF report title + * + * @return void + */ + private function _setPdfReportTitle($pdfReportTitle) + { + $this->_pdfReportTitle = $pdfReportTitle; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php b/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php new file mode 100644 index 000000000..2d3b73c54 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportPhparray.class.php @@ -0,0 +1,227 @@ +setProperties(); + } + + /** + * Sets the export PHP Array properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('PHP array'); + $exportPluginProperties->setExtension('php'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + ' " . var_export($record[$i], true) + . (($i + 1 >= $columns_cnt) ? '' : ','); + } + + $buffer .= ')'; + } + + $buffer .= $crlf . ');' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportSql.class.php b/phpmyadmin/libraries/plugins/export/ExportSql.class.php new file mode 100644 index 000000000..448101372 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportSql.class.php @@ -0,0 +1,1876 @@ +setProperties(); + + // Avoids undefined variables, use NULL so isset() returns false + if (! isset($GLOBALS['sql_backquotes'])) { + $GLOBALS['sql_backquotes'] = null; + } + } + + /** + * Sets the export SQL properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + + $hide_sql = false; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + $hide_sql = true; + } + + if (! $hide_sql) { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/groups/OptionsPropertySubgroup.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('SQL'); + $exportPluginProperties->setExtension('sql'); + $exportPluginProperties->setMimeType('text/x-sql'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // comments + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("include_comments"); + $leaf = new BoolPropertyItem(); + $leaf->setName('include_comments'); + $leaf->setText( + __( + 'Display comments (includes info such as export' + . ' timestamp, PHP version, and server version)' + ) + ); + $subgroup->setSubgroupHeader($leaf); + + $leaf = new TextPropertyItem(); + $leaf->setName('header_comment'); + $leaf->setText( + __('Additional custom header comment (\n splits lines):') + ); + $subgroup->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('dates'); + $leaf->setText( + __( + 'Include a timestamp of when databases were created, last' + . ' updated, and last checked' + ) + ); + $subgroup->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName('relation'); + $leaf->setText(__('Display foreign key relationships')); + $subgroup->addProperty($leaf); + } + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName('mime'); + $leaf->setText(__('Display MIME types')); + $subgroup->addProperty($leaf); + } + $generalOptions->addProperty($subgroup); + + // enclose in a transaction + $leaf = new BoolPropertyItem(); + $leaf->setName("use_transaction"); + $leaf->setText(__('Enclose export in a transaction')); + $leaf->setDoc( + array( + 'programs', + 'mysqldump', + 'option_mysqldump_single-transaction' + ) + ); + $generalOptions->addProperty($leaf); + + // disable foreign key checks + $leaf = new BoolPropertyItem(); + $leaf->setName("disable_fk"); + $leaf->setText(__('Disable foreign key checks')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'server-system-variables', + 'sysvar_foreign_key_checks' + ) + ); + $generalOptions->addProperty($leaf); + + // compatibility maximization + $compats = PMA_DBI_getCompatibilities(); + if (count($compats) > 0) { + $values = array(); + foreach ($compats as $val) { + $values[$val] = $val; + } + + $leaf = new SelectPropertyItem(); + $leaf->setName("compatibility"); + $leaf->setText( + __( + 'Database system or older MySQL server to maximize output' + . ' compatibility with:' + ) + ); + $leaf->setValues($values); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'Server_SQL_mode' + ) + ); + $generalOptions->addProperty($leaf); + + unset($values); + } + + // server export options + if ($plugin_param['export_type'] == 'server') { + $leaf = new BoolPropertyItem(); + $leaf->setName("drop_database"); + $leaf->setText( + sprintf(__('Add %s statement'), 'DROP DATABASE') + ); + $generalOptions->addProperty($leaf); + } + + // what to dump (structure/data/both) + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("dump_table"); + $subgroup->setText("Dump table"); + $leaf = new RadioPropertyItem(); + $leaf->setName('structure_or_data'); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $subgroup->setSubgroupHeader($leaf); + $generalOptions->addProperty($subgroup); + + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + + // begin SQL Statements + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setName('add_statements'); + $leaf->setText(__('Add statements:')); + $subgroup->setSubgroupHeader($leaf); + if ($plugin_param['export_type'] == 'table') { + if (PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])) { + $drop_clause = 'DROP VIEW'; + } else { + $drop_clause = 'DROP TABLE'; + } + } else { + if (PMA_DRIZZLE) { + $drop_clause = 'DROP TABLE'; + } else { + $drop_clause = 'DROP TABLE / VIEW / PROCEDURE' + . ' / FUNCTION'; + if (PMA_MYSQL_INT_VERSION > 50100) { + $drop_clause .= ' / EVENT'; + } + } + } + $leaf = new BoolPropertyItem(); + $leaf->setName('drop_table'); + $leaf->setText(sprintf(__('Add %s statement'), $drop_clause)); + $subgroup->addProperty($leaf); + // Drizzle doesn't support procedures and functions + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName('procedure_function'); + $leaf->setText( + sprintf( + __('Add %s statement'), + 'CREATE PROCEDURE / FUNCTION' + . (PMA_MYSQL_INT_VERSION > 50100 + ? ' / EVENT' : '') + ) + ); + $subgroup->addProperty($leaf); + } + + // begin CREATE TABLE statements + $subgroup_create_table = new OptionsPropertySubgroup(); + $leaf = new BoolPropertyItem(); + $leaf->setName('create_table_statements'); + $leaf->setText(__('CREATE TABLE options:')); + $subgroup_create_table->setSubgroupHeader($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('if_not_exists'); + $leaf->setText('IF NOT EXISTS'); + $subgroup_create_table->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('auto_increment'); + $leaf->setText('AUTO_INCREMENT'); + $subgroup_create_table->addProperty($leaf); + $subgroup->addProperty($subgroup_create_table); + $structureOptions->addProperty($subgroup); + + $leaf = new BoolPropertyItem(); + $leaf->setName("backquotes"); + $leaf->setText( + __( + 'Enclose table and column names with backquotes ' + . '(Protects column and table names formed with' + . ' special characters or keywords)' + ) + ); + + $structureOptions->addProperty($leaf); + + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + + // begin Data options + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data creation options')); + $dataOptions->setForce('structure'); + $leaf = new BoolPropertyItem(); + $leaf->setName("truncate"); + $leaf->setText(__('Truncate table before insert')); + $dataOptions->addProperty($leaf); + + // begin SQL Statements + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setText(__('Instead of INSERT statements, use:')); + $subgroup->setSubgroupHeader($leaf); + // Not supported in Drizzle + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("delayed"); + $leaf->setText(__('INSERT DELAYED statements')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'insert_delayed' + ) + ); + $subgroup->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("ignore"); + $leaf->setText(__('INSERT IGNORE statements')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'insert' + ) + ); + $subgroup->addProperty($leaf); + $dataOptions->addProperty($subgroup); + + // Function to use when dumping dat + $leaf = new SelectPropertyItem(); + $leaf->setName("type"); + $leaf->setText(__('Function to use when dumping data:')); + $leaf->setValues( + array( + 'INSERT' => 'INSERT', + 'UPDATE' => 'UPDATE', + 'REPLACE' => 'REPLACE' + ) + ); + $dataOptions->addProperty($leaf); + + /* Syntax to use when inserting data */ + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setText(__('Syntax to use when inserting data:')); + $subgroup->setSubgroupHeader($leaf); + $leaf = new RadioPropertyItem(); + $leaf->setName("insert_syntax"); + $leaf->setText(__('INSERT IGNORE statements')); + $leaf->setValues( + array( + 'complete' => __( + 'include column names in every INSERT statement' + . '
            Example: INSERT INTO' + . ' tbl_name (col_A,col_B,col_C) VALUES (1,2,3)' + ), + 'extended' => __( + 'insert multiple rows in every INSERT statement' + . '
            Example: INSERT INTO' + . ' tbl_name VALUES (1,2,3), (4,5,6), (7,8,9)' + ), + 'both' => __( + 'both of the above
            Example:' + . ' INSERT INTO tbl_name (col_A,col_B) VALUES (1,2,3),' + . ' (4,5,6), (7,8,9)' + ), + 'none' => __( + 'neither of the above
            Example:' + . ' INSERT INTO tbl_name VALUES (1,2,3)' + ) + ) + ); + $subgroup->addProperty($leaf); + $dataOptions->addProperty($subgroup); + + // Max length of query + $leaf = new TextPropertyItem(); + $leaf->setName("max_query_size"); + $leaf->setText(__('Maximal length of created query')); + $dataOptions->addProperty($leaf); + + // Dump binary columns in hexadecimal + $leaf = new BoolPropertyItem(); + $leaf->setName("hex_for_blob"); + $leaf->setText( + __( + 'Dump binary columns in hexadecimal notation' + . ' (for example, "abc" becomes 0x616263)' + ) + ); + $dataOptions->addProperty($leaf); + + // Drizzle works only with UTC timezone + if (! PMA_DRIZZLE) { + // Dump time in UTC + $leaf = new BoolPropertyItem(); + $leaf->setName("utc_time"); + $leaf->setText( + __( + 'Dump TIMESTAMP columns in UTC (enables TIMESTAMP columns' + . ' to be dumped and reloaded between servers in different' + . ' time zones)' + ) + ); + $dataOptions->addProperty($leaf); + } + + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Exports routines (procedures and functions) + * + * @param string $db Database + * + * @return bool Whether it succeeded + */ + public function exportRoutines($db) + { + global $crlf; + + $text = ''; + $delimiter = '$$'; + + $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE'); + $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION'); + + if ($procedure_names || $function_names) { + $text .= $crlf + . 'DELIMITER ' . $delimiter . $crlf; + } + + if ($procedure_names) { + $text .= + $this->_exportComment() + . $this->_exportComment(__('Procedures')) + . $this->_exportComment(); + + foreach ($procedure_names as $procedure_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP PROCEDURE IF EXISTS ' + . PMA_Util::backquote($procedure_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'PROCEDURE', $procedure_name) + . $delimiter . $crlf . $crlf; + } + } + + if ($function_names) { + $text .= + $this->_exportComment() + . $this->_exportComment(__('Functions')) + . $this->_exportComment(); + + foreach ($function_names as $function_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP FUNCTION IF EXISTS ' + . PMA_Util::backquote($function_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'FUNCTION', $function_name) + . $delimiter . $crlf . $crlf; + } + } + + if ($procedure_names || $function_names) { + $text .= 'DELIMITER ;' . $crlf; + } + + if (! empty($text)) { + return PMA_exportOutputHandler($text); + } else { + return false; + } + } + + /** + * Possibly outputs comment + * + * @param string $text Text of comment + * + * @return string The formatted comment + */ + private function _exportComment($text = '') + { + if (isset($GLOBALS['sql_include_comments']) + && $GLOBALS['sql_include_comments'] + ) { + // see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html + return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf']; + } else { + return ''; + } + } + + /** + * Possibly outputs CRLF + * + * @return string $crlf or nothing + */ + private function _possibleCRLF() + { + if (isset($GLOBALS['sql_include_comments']) + && $GLOBALS['sql_include_comments'] + ) { + return $GLOBALS['crlf']; + } else { + return ''; + } + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter() + { + global $crlf, $mysql_charset_map; + + $foot = ''; + + if (isset($GLOBALS['sql_disable_fk'])) { + $foot .= 'SET FOREIGN_KEY_CHECKS=1;' . $crlf; + } + + if (isset($GLOBALS['sql_use_transaction'])) { + $foot .= 'COMMIT;' . $crlf; + } + + // restore connection settings + $charset_of_file = isset($GLOBALS['charset_of_file']) + ? $GLOBALS['charset_of_file'] : ''; + if (! empty($GLOBALS['asfile']) + && isset($mysql_charset_map[$charset_of_file]) + && ! PMA_DRIZZLE + ) { + $foot .= $crlf + . '/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;' + . $crlf + . '/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;' + . $crlf + . '/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;' + . $crlf; + } + + /* Restore timezone */ + if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) { + PMA_DBI_query('SET time_zone = "' . $GLOBALS['old_tz'] . '"'); + } + + return PMA_exportOutputHandler($foot); + } + + /** + * Outputs export header. It is the first method to be called, so all + * the required variables are initialized here. + * + * @return bool Whether it succeeded + */ + public function exportHeader() + { + global $crlf, $cfg; + global $mysql_charset_map; + + if (isset($GLOBALS['sql_compatibility'])) { + $tmp_compat = $GLOBALS['sql_compatibility']; + if ($tmp_compat == 'NONE') { + $tmp_compat = ''; + } + PMA_DBI_try_query('SET SQL_MODE="' . $tmp_compat . '"'); + unset($tmp_compat); + } + $head = $this->_exportComment('phpMyAdmin SQL Dump') + . $this->_exportComment('version ' . PMA_VERSION) + . $this->_exportComment('http://www.phpmyadmin.net') + . $this->_exportComment(); + $host_string = __('Host') . ': ' . $cfg['Server']['host']; + if (! empty($cfg['Server']['port'])) { + $host_string .= ':' . $cfg['Server']['port']; + } + $head .= $this->_exportComment($host_string); + $head .= + $this->_exportComment( + __('Generation Time') . ': ' + . PMA_Util::localisedDate() + ) + . $this->_exportComment( + __('Server version') . ': ' . PMA_MYSQL_STR_VERSION + ) + . $this->_exportComment(__('PHP Version') . ': ' . phpversion()) + . $this->_possibleCRLF(); + + if (isset($GLOBALS['sql_header_comment']) + && ! empty($GLOBALS['sql_header_comment']) + ) { + // '\n' is not a newline (like "\n" would be), it's the characters + // backslash and n, as explained on the export interface + $lines = explode('\n', $GLOBALS['sql_header_comment']); + $head .= $this->_exportComment(); + foreach ($lines as $one_line) { + $head .= $this->_exportComment($one_line); + } + $head .= $this->_exportComment(); + } + + if (isset($GLOBALS['sql_disable_fk'])) { + $head .= 'SET FOREIGN_KEY_CHECKS=0;' . $crlf; + } + + // We want exported AUTO_INCREMENT columns to have still same value, + // do this only for recent MySQL exports + if ((! isset($GLOBALS['sql_compatibility']) + || $GLOBALS['sql_compatibility'] == 'NONE') + && ! PMA_DRIZZLE + ) { + $head .= 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";' . $crlf; + } + + if (isset($GLOBALS['sql_use_transaction'])) { + $head .= 'SET AUTOCOMMIT = 0;' . $crlf + . 'START TRANSACTION;' . $crlf; + } + + /* Change timezone if we should export timestamps in UTC */ + if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) { + $head .= 'SET time_zone = "+00:00";' . $crlf; + $GLOBALS['old_tz'] = PMA_DBI_fetch_value('SELECT @@session.time_zone'); + PMA_DBI_query('SET time_zone = "+00:00"'); + } + + $head .= $this->_possibleCRLF(); + + if (! empty($GLOBALS['asfile']) && ! PMA_DRIZZLE) { + // we are saving as file, therefore we provide charset information + // so that a utility like the mysql client can interpret + // the file correctly + if (isset($GLOBALS['charset_of_file']) + && isset($mysql_charset_map[$GLOBALS['charset_of_file']]) + ) { + // we got a charset from the export dialog + $set_names = $mysql_charset_map[$GLOBALS['charset_of_file']]; + } else { + // by default we use the connection charset + $set_names = $mysql_charset_map['utf-8']; + } + $head .= $crlf + . '/*!40101 SET @OLD_CHARACTER_SET_CLIENT=' + . '@@CHARACTER_SET_CLIENT */;' . $crlf + . '/*!40101 SET @OLD_CHARACTER_SET_RESULTS=' + . '@@CHARACTER_SET_RESULTS */;' . $crlf + . '/*!40101 SET @OLD_COLLATION_CONNECTION=' + . '@@COLLATION_CONNECTION */;'. $crlf + . '/*!40101 SET NAMES ' . $set_names . ' */;' . $crlf . $crlf; + } + + return PMA_exportOutputHandler($head); + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + global $crlf; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + if (isset($GLOBALS['sql_drop_database'])) { + if (! PMA_exportOutputHandler( + 'DROP DATABASE ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) : $db) + . ';' . $crlf + )) { + return false; + } + } + $create_query = 'CREATE DATABASE IF NOT EXISTS ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) : $db); + $collation = PMA_getDbCollation($db); + if (PMA_DRIZZLE) { + $create_query .= ' COLLATE ' . $collation; + } else { + if (strpos($collation, '_')) { + $create_query .= ' DEFAULT CHARACTER SET ' + . substr($collation, 0, strpos($collation, '_')) + . ' COLLATE ' . $collation; + } else { + $create_query .= ' DEFAULT CHARACTER SET ' . $collation; + } + } + $create_query .= ';' . $crlf; + if (! PMA_exportOutputHandler($create_query)) { + return false; + } + if (isset($GLOBALS['sql_backquotes']) + && ((isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'NONE') + || PMA_DRIZZLE) + ) { + $result = PMA_exportOutputHandler( + 'USE ' . PMA_Util::backquoteCompat($db, $compat) + . ';' . $crlf + ); + } else { + $result = PMA_exportOutputHandler('USE ' . $db . ';' . $crlf); + } + + return $result; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader($db) + { + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + $head = $this->_exportComment() + . $this->_exportComment( + __('Database') . ': ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) + : '\'' . $db . '\'') + ) + . $this->_exportComment(); + return PMA_exportOutputHandler($head); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter($db) + { + global $crlf; + + $result = true; + if (isset($GLOBALS['sql_constraints'])) { + $result = PMA_exportOutputHandler($GLOBALS['sql_constraints']); + unset($GLOBALS['sql_constraints']); + } + + if (($GLOBALS['sql_structure_or_data'] == 'structure' + || $GLOBALS['sql_structure_or_data'] == 'structure_and_data') + && isset($GLOBALS['sql_procedure_function']) + ) { + $text = ''; + $delimiter = '$$'; + + if (PMA_MYSQL_INT_VERSION > 50100) { + $event_names = PMA_DBI_fetch_result( + 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE' + . ' EVENT_SCHEMA= \'' + . PMA_Util::sqlAddSlashes($db, true) + . '\';' + ); + } else { + $event_names = array(); + } + + if ($event_names) { + $text .= $crlf + . 'DELIMITER ' . $delimiter . $crlf; + + $text .= + $this->_exportComment() + . $this->_exportComment(__('Events')) + . $this->_exportComment(); + + foreach ($event_names as $event_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP EVENT ' + . PMA_Util::backquote($event_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'EVENT', $event_name) + . $delimiter . $crlf . $crlf; + } + + $text .= 'DELIMITER ;' . $crlf; + } + + if (! empty($text)) { + $result = PMA_exportOutputHandler($text); + } + } + return $result; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + public function getTableDefStandIn($db, $view, $crlf) + { + $create_query = ''; + if (! empty($GLOBALS['sql_drop_table'])) { + $create_query .= 'DROP VIEW IF EXISTS ' + . PMA_Util::backquote($view) + . ';' . $crlf; + } + + $create_query .= 'CREATE TABLE '; + + if (isset($GLOBALS['sql_if_not_exists']) + && $GLOBALS['sql_if_not_exists'] + ) { + $create_query .= 'IF NOT EXISTS '; + } + $create_query .= PMA_Util::backquote($view) . ' (' . $crlf; + $tmp = array(); + $columns = PMA_DBI_get_columns_full($db, $view); + foreach ($columns as $column_name => $definition) { + $tmp[] = PMA_Util::backquote($column_name) . ' ' . + $definition['Type'] . $crlf; + } + $create_query .= implode(',', $tmp) . ');'; + return($create_query); + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $show_dates whether to include creation/update/check + * dates + * @param bool $add_semicolon whether to add semicolon and end-of-line at + * the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $sql_drop_table, $sql_backquotes, $sql_constraints, + $sql_constraints_query, $sql_drop_foreign_keys; + + $schema_create = ''; + $auto_increment = ''; + $new_crlf = $crlf; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli + $result = PMA_DBI_query( + 'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) + . ' LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\'', + null, + PMA_DBI_QUERY_STORE + ); + if ($result != false) { + if (PMA_DBI_num_rows($result) > 0) { + $tmpres = PMA_DBI_fetch_assoc($result); + if (PMA_DRIZZLE && $show_dates) { + // Drizzle doesn't give Create_time and Update_time in + // SHOW TABLE STATUS, add it + $sql ="SELECT + TABLE_CREATION_TIME AS Create_time, + TABLE_UPDATE_TIME AS Update_time + FROM data_dictionary.TABLES + WHERE TABLE_SCHEMA = '" + . PMA_Util::sqlAddSlashes($db) . "' + AND TABLE_NAME = '" + . PMA_Util::sqlAddSlashes($table) . "'"; + $tmpres = array_merge(PMA_DBI_fetch_single_row($sql), $tmpres); + } + // Here we optionally add the AUTO_INCREMENT next value, + // but starting with MySQL 5.0.24, the clause is already included + // in SHOW CREATE TABLE so we'll remove it below + // It's required for Drizzle because SHOW CREATE TABLE uses + // the value from table's creation time + if (isset($GLOBALS['sql_auto_increment']) + && ! empty($tmpres['Auto_increment']) + ) { + $auto_increment .= ' AUTO_INCREMENT=' + . $tmpres['Auto_increment'] . ' '; + } + + if ($show_dates + && isset($tmpres['Create_time']) + && ! empty($tmpres['Create_time']) + ) { + $schema_create .= $this->_exportComment( + __('Creation') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Create_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + + if ($show_dates + && isset($tmpres['Update_time']) + && ! empty($tmpres['Update_time']) + ) { + $schema_create .= $this->_exportComment( + __('Last update') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Update_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + + if ($show_dates + && isset($tmpres['Check_time']) + && ! empty($tmpres['Check_time']) + ) { + $schema_create .= $this->_exportComment( + __('Last check') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Check_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + } + PMA_DBI_free_result($result); + } + + $schema_create .= $new_crlf; + + // no need to generate a DROP VIEW here, it was done earlier + if (! empty($sql_drop_table) && ! PMA_Table::isView($db, $table)) { + $schema_create .= 'DROP TABLE IF EXISTS ' + . PMA_Util::backquote($table, $sql_backquotes) . ';' + . $crlf; + } + + // Complete table dump, + // Whether to quote table and column names or not + // Drizzle always quotes names + if (! PMA_DRIZZLE) { + if ($sql_backquotes) { + PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1'); + } else { + PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0'); + } + } + + // I don't see the reason why this unbuffered query could cause problems, + // because SHOW CREATE TABLE returns only one row, and we free the + // results below. Nonetheless, we got 2 user reports about this + // (see bug 1562533) so I removed the unbuffered mode. + // $result = PMA_DBI_query('SHOW CREATE TABLE ' . backquote($db) + // . '.' . backquote($table), null, PMA_DBI_QUERY_UNBUFFERED); + // + // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not + // produce a displayable result for the default value of a BIT + // column, nor does the mysqldump command. See MySQL bug 35796 + $result = PMA_DBI_try_query( + 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table) + ); + // an error can happen, for example the table is crashed + $tmp_error = PMA_DBI_getError(); + if ($tmp_error) { + return $this->_exportComment(__('in use') . '(' . $tmp_error . ')'); + } + + if ($result != false && ($row = PMA_DBI_fetch_row($result))) { + $create_query = $row[1]; + unset($row); + + // Convert end of line chars to one that we want (note that MySQL + // doesn't return query it will accept in all cases) + if (strpos($create_query, "(\r\n ")) { + $create_query = str_replace("\r\n", $crlf, $create_query); + } elseif (strpos($create_query, "(\n ")) { + $create_query = str_replace("\n", $crlf, $create_query); + } elseif (strpos($create_query, "(\r ")) { + $create_query = str_replace("\r", $crlf, $create_query); + } + + /* + * Drop database name from VIEW creation. + * + * This is a bit tricky, but we need to issue SHOW CREATE TABLE with + * database name, but we don't want name to show up in CREATE VIEW + * statement. + */ + if ($view) { + $create_query = preg_replace( + '/' . PMA_Util::backquote($db) . '\./', + '', + $create_query + ); + } + + // Should we use IF NOT EXISTS? + // It always must be OFF for MSSQL compatibility mode + if (isset($GLOBALS['sql_if_not_exists']) && $compat != 'MSSQL') { + $create_query = preg_replace( + '/^CREATE TABLE/', + 'CREATE TABLE IF NOT EXISTS', + $create_query + ); + } + + // In MSSQL + // 1. DATE field doesn't exists, we will use DATETIME instead + // 2. UNSIGNED attribute doesn't exist + // 3. No length on INT, TINYINT, SMALLINT, BIGINT and no precision on + // FLOAT fields + // 4. No KEY and INDEX inside CREATE TABLE + // 5. DOUBLE field doesn't exists, we will use FLOAT instead + if ($compat == 'MSSQL') { + // first we need to replace all lines ended with '" DATE ...,\n' + // last preg_replace preserve us from situation with date text + // inside DEFAULT field value + $create_query = preg_replace( + "/\" date DEFAULT NULL(,)?\n/", + '" datetime DEFAULT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + "/\" date NOT NULL(,)?\n/", + '" datetime NOT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" date NOT NULL DEFAULT \'([^\'])/', + '" datetime NOT NULL DEFAULT \'$1', + $create_query + ); + + // next we need to replace all lines ended with ') UNSIGNED ...,' + // last preg_replace preserve us from situation with unsigned text + // inside DEFAULT field value + $create_query = preg_replace( + "/\) unsigned NOT NULL(,)?\n/", + ') NOT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + "/\) unsigned DEFAULT NULL(,)?\n/", + ') DEFAULT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + '/\) unsigned NOT NULL DEFAULT \'([^\'])/', + ') NOT NULL DEFAULT \'$1', + $create_query + ); + + // we need to replace all lines ended with + // '" INT|TINYINT([0-9]{1,}) ...,' last preg_replace preserve us + // from situation with int([0-9]{1,}) text inside DEFAULT field + // value + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) DEFAULT NULL(,)?\n/', + '" $1 DEFAULT NULL$2' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL(,)?\n/', + '" $1 NOT NULL$2' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL DEFAULT \'([^\'])/', + '" $1 NOT NULL DEFAULT \'$2', + $create_query + ); + + // we need to replace all lines ended with + // '" FLOAT|DOUBLE([0-9,]{1,}) ...,' + // last preg_replace preserve us from situation with + // float([0-9,]{1,}) text inside DEFAULT field value + $create_query = preg_replace( + '/" (float|double)(\([0-9]+,[0-9,]+\))? DEFAULT NULL(,)?\n/', + '" float DEFAULT NULL$3' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL(,)?\n/', + '" float NOT NULL$3' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL DEFAULT \'([^\'])/', + '" float NOT NULL DEFAULT \'$3', + $create_query + ); + + // @todo remove indexes from CREATE TABLE + } + + // Drizzle (checked on 2011.03.13) returns ROW_FORMAT surrounded + // with quotes, which is not accepted by parser + if (PMA_DRIZZLE) { + $create_query = preg_replace( + '/ROW_FORMAT=\'(\S+)\'/', + 'ROW_FORMAT=$1', + $create_query + ); + } + + // are there any constraints to cut out? + if (preg_match('@CONSTRAINT|FOREIGN[\s]+KEY@', $create_query)) { + + // Split the query into lines, so we can easily handle it. + // We know lines are separated by $crlf (done few lines above). + $sql_lines = explode($crlf, $create_query); + $sql_count = count($sql_lines); + + // lets find first line with constraints + for ($i = 0; $i < $sql_count; $i++) { + if (preg_match( + '@^[\s]*(CONSTRAINT|FOREIGN[\s]+KEY)@', + $sql_lines[$i] + )) { + break; + } + } + + // If we really found a constraint + if ($i != $sql_count) { + + // remove, from the end of create statement + $sql_lines[$i - 1] = preg_replace( + '@,$@', + '', + $sql_lines[$i - 1] + ); + + // prepare variable for constraints + if (! isset($sql_constraints)) { + if (isset($GLOBALS['no_constraints_comments'])) { + $sql_constraints = ''; + } else { + $sql_constraints = $crlf + . $this->_exportComment() + . $this->_exportComment( + __('Constraints for dumped tables') + ) + . $this->_exportComment(); + } + } + + // comments for current table + if (! isset($GLOBALS['no_constraints_comments'])) { + $sql_constraints .= $crlf + . $this->_exportComment() + . $this->_exportComment( + __('Constraints for table') + . ' ' + . PMA_Util::backquoteCompat($table, $compat) + ) + . $this->_exportComment(); + } + + // let's do the work + $sql_constraints_query .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + $sql_constraints .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + $sql_drop_foreign_keys .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($db, $compat) . '.' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + + $first = true; + for ($j = $i; $j < $sql_count; $j++) { + if (preg_match( + '@CONSTRAINT|FOREIGN[\s]+KEY@', + $sql_lines[$j] + )) { + if (! $first) { + $sql_constraints .= $crlf; + } + if (strpos($sql_lines[$j], 'CONSTRAINT') === false) { + $tmp_str = preg_replace( + '/(FOREIGN[\s]+KEY)/', + 'ADD \1', + $sql_lines[$j] + ); + $sql_constraints_query .= $tmp_str; + $sql_constraints .= $tmp_str; + } else { + $tmp_str = preg_replace( + '/(CONSTRAINT)/', + 'ADD \1', + $sql_lines[$j] + ); + $sql_constraints_query .= $tmp_str; + $sql_constraints .= $tmp_str; + preg_match( + '/(CONSTRAINT)([\s])([\S]*)([\s])/', + $sql_lines[$j], + $matches + ); + if (! $first) { + $sql_drop_foreign_keys .= ', '; + } + $sql_drop_foreign_keys .= 'DROP FOREIGN KEY ' + . $matches[3]; + } + $first = false; + } else { + break; + } + } + $sql_constraints .= ';' . $crlf; + $sql_constraints_query .= ';'; + + $create_query = implode( + $crlf, + array_slice($sql_lines, 0, $i) + ) + . $crlf + . implode( + $crlf, + array_slice($sql_lines, $j, $sql_count - 1) + ); + unset($sql_lines); + } + } + $schema_create .= $create_query; + } + + // remove a possible "AUTO_INCREMENT = value" clause + // that could be there starting with MySQL 5.0.24 + // in Drizzle it's useless as it contains the value given at table + // creation time + $schema_create = preg_replace( + '/AUTO_INCREMENT\s*=\s*([0-9])+/', + '', + $schema_create + ); + + $schema_create .= ($compat != 'MSSQL') ? $auto_increment : ''; + + PMA_DBI_free_result($result); + return $schema_create . ($add_semicolon ? ';' . $crlf : ''); + } // end of the 'getTableDef()' function + + /** + * Returns $table's comments, relations etc. + * + * @param string $db database name + * @param string $table table name + * @param string $crlf end of line sequence + * @param bool $do_relation whether to include relation comments + * @param bool $do_mime whether to include mime comments + * + * @return string resulting comments + */ + private function _getTableComments( + $db, + $table, + $crlf, + $do_relation = false, + $do_mime = false + ) { + global $cfgRelation, $sql_backquotes; + + $schema_create = ''; + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + if ($do_mime && $cfgRelation['mimework']) { + if (! ($mime_map = PMA_getMIME($db, $table, true))) { + unset($mime_map); + } + } + + if (isset($mime_map) && count($mime_map) > 0) { + $schema_create .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('MIME TYPES FOR TABLE'). ' ' + . PMA_Util::backquote($table, $sql_backquotes) . ':' + ); + @reset($mime_map); + foreach ($mime_map AS $mime_field => $mime) { + $schema_create .= + $this->_exportComment( + ' ' + . PMA_Util::backquote($mime_field, $sql_backquotes) + ) + . $this->_exportComment( + ' ' + . PMA_Util::backquote( + $mime['mimetype'], + $sql_backquotes + ) + ); + } + $schema_create .= $this->_exportComment(); + } + + if ($have_rel) { + $schema_create .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('RELATIONS FOR TABLE') . ' ' + . PMA_Util::backquote($table, $sql_backquotes) + . ':' + ); + foreach ($res_rel AS $rel_field => $rel) { + $schema_create .= + $this->_exportComment( + ' ' + . PMA_Util::backquote($rel_field, $sql_backquotes) + ) + . $this->_exportComment( + ' ' + . PMA_Util::backquote( + $rel['foreign_table'], + $sql_backquotes + ) + . ' -> ' + . PMA_Util::backquote( + $rel['foreign_field'], + $sql_backquotes + ) + ); + } + $schema_create .= $this->_exportComment(); + } + + return $schema_create; + + } // end of the '_getTableComments()' function + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table','triggers','create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $relation whether to include relation comments + * @param bool $comments whether to include the pmadb-style column + * comments as comments in the structure; this is + * deprecated but the parameter is left here + * because export.php calls exportStructure() + * also for other export types which use this + * parameter + * @param bool $mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $relation = false, + $comments = false, + $mime = false, + $dates = false + ) { + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + $formatted_table_name = (isset($GLOBALS['sql_backquotes'])) + ? PMA_Util::backquoteCompat($table, $compat) + : '\'' . $table . '\''; + $dump = $this->_possibleCRLF() + . $this->_exportComment(str_repeat('-', 56)) + . $this->_possibleCRLF() + . $this->_exportComment(); + + switch($export_mode) { + case 'create_table': + $dump .= $this->_exportComment( + __('Table structure for table') . ' '. $formatted_table_name + ); + $dump .= $this->_exportComment(); + $dump .= $this->getTableDef($db, $table, $crlf, $error_url, $dates); + $dump .= $this->_getTableComments($db, $table, $crlf, $relation, $mime); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Triggers') . ' ' . $formatted_table_name + ) + . $this->_exportComment(); + $delimiter = '//'; + foreach ($triggers as $trigger) { + $dump .= $trigger['drop'] . ';' . $crlf; + $dump .= 'DELIMITER ' . $delimiter . $crlf; + $dump .= $trigger['create']; + $dump .= 'DELIMITER ;' . $crlf; + } + } + break; + case 'create_view': + $dump .= + $this->_exportComment( + __('Structure for view') + . ' ' + . $formatted_table_name + ) + . $this->_exportComment(); + // delete the stand-in table previously created (if any) + if ($export_type != 'table') { + $dump .= 'DROP TABLE IF EXISTS ' + . PMA_Util::backquote($table) . ';' . $crlf; + } + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $dates, true, true + ); + break; + case 'stand_in': + $dump .= + $this->_exportComment( + __('Stand-in structure for view') . ' ' . $formatted_table_name + ) + . $this->_exportComment(); + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + // this one is built by getTableDef() to use in table copy/move + // but not in the case of export + unset($GLOBALS['sql_constraints_query']); + + return PMA_exportOutputHandler($dump); + } + + /** + * Outputs the content of a table in SQL format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $current_row, $sql_backquotes; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + $formatted_table_name = (isset($GLOBALS['sql_backquotes'])) + ? PMA_Util::backquoteCompat($table, $compat) + : '\'' . $table . '\''; + + // Do not export data for a VIEW + // (For a VIEW, this is called only when exporting a single VIEW) + if (PMA_Table::isView($db, $table)) { + $head = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment('VIEW ' . ' ' . $formatted_table_name) + . $this->_exportComment(__('Data') . ': ' . __('None')) + . $this->_exportComment() + . $this->_possibleCRLF(); + + if (! PMA_exportOutputHandler($head)) { + return false; + } + return true; + } + + // analyze the query to get the true column names, not the aliases + // (this fixes an undefined index, also if Complete inserts + // are used, we did not get the true column name in case of aliases) + $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query)); + + $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + // a possible error: the table has crashed + $tmp_error = PMA_DBI_getError(); + if ($tmp_error) { + return PMA_exportOutputHandler( + $this->_exportComment( + __('Error reading data:') . ' (' . $tmp_error . ')' + ) + ); + } + + if ($result != false) { + $fields_cnt = PMA_DBI_num_fields($result); + + // Get field information + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + for ($j = 0; $j < $fields_cnt; $j++) { + if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { + $field_set[$j] = PMA_Util::backquoteCompat( + $analyzed_sql[0]['select_expr'][$j]['column'], + $compat, + $sql_backquotes + ); + } else { + $field_set[$j] = PMA_Util::backquoteCompat( + $fields_meta[$j]->name, + $compat, + $sql_backquotes + ); + } + } + + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'UPDATE' + ) { + // update + $schema_insert = 'UPDATE '; + if (isset($GLOBALS['sql_ignore'])) { + $schema_insert .= 'IGNORE '; + } + // avoid EOL blank + $schema_insert .= PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) . ' SET'; + } else { + // insert or replace + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'REPLACE' + ) { + $sql_command = 'REPLACE'; + } else { + $sql_command = 'INSERT'; + } + + // delayed inserts? + if (isset($GLOBALS['sql_delayed'])) { + $insert_delayed = ' DELAYED'; + } else { + $insert_delayed = ''; + } + + // insert ignore? + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'INSERT' + && isset($GLOBALS['sql_ignore']) + ) { + $insert_delayed .= ' IGNORE'; + } + //truncate table before insert + if (isset($GLOBALS['sql_truncate']) + && $GLOBALS['sql_truncate'] + && $sql_command == 'INSERT' + ) { + $truncate = 'TRUNCATE TABLE ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) . ";"; + $truncatehead = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Truncate table before insert') . ' ' + . $formatted_table_name + ) + . $this->_exportComment() + . $crlf; + PMA_exportOutputHandler($truncatehead); + PMA_exportOutputHandler($truncate); + } else { + $truncate = ''; + } + + // scheme for inserting fields + if ($GLOBALS['sql_insert_syntax'] == 'complete' + || $GLOBALS['sql_insert_syntax'] == 'both' + ) { + $fields = implode(', ', $field_set); + $schema_insert = $sql_command . $insert_delayed .' INTO ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) + // avoid EOL blank + . ' (' . $fields . ') VALUES'; + } else { + $schema_insert = $sql_command . $insert_delayed .' INTO ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) + . ' VALUES'; + } + } + + //\x08\\x09, not required + $search = array("\x00", "\x0a", "\x0d", "\x1a"); + $replace = array('\0', '\n', '\r', '\Z'); + $current_row = 0; + $query_size = 0; + if (($GLOBALS['sql_insert_syntax'] == 'extended' + || $GLOBALS['sql_insert_syntax'] == 'both') + && (! isset($GLOBALS['sql_type']) + || $GLOBALS['sql_type'] != 'UPDATE') + ) { + $separator = ','; + $schema_insert .= $crlf; + } else { + $separator = ';'; + } + + while ($row = PMA_DBI_fetch_row($result)) { + if ($current_row == 0) { + $head = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Dumping data for table') . ' ' + . $formatted_table_name + ) + . $this->_exportComment() + . $crlf; + if (! PMA_exportOutputHandler($head)) { + return false; + } + } + // We need to SET IDENTITY_INSERT ON for MSSQL + if (isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'MSSQL' + && $current_row == 0 + ) { + if (! PMA_exportOutputHandler( + 'SET IDENTITY_INSERT ' + . PMA_Util::backquoteCompat( + $table, + $compat + ) + . ' ON ;'.$crlf + )) { + return false; + } + } + $current_row++; + for ($j = 0; $j < $fields_cnt; $j++) { + // NULL + if (! isset($row[$j]) || is_null($row[$j])) { + $values[] = 'NULL'; + } elseif ($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob + ) { + // a number + // timestamp is numeric on some MySQL 4.1, BLOBs are + // sometimes numeric + $values[] = $row[$j]; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + && isset($GLOBALS['sql_hex_for_blob']) + ) { + // a true BLOB + // - mysqldump only generates hex data when the --hex-blob + // option is used, for fields having the binary attribute + // no hex is generated + // - a TEXT field returns type blob but a real blob + // returns also the 'binary' flag + + // empty blobs need to be different, but '0' is also empty + // :-( + if (empty($row[$j]) && $row[$j] != '0') { + $values[] = '\'\''; + } else { + $values[] = '0x' . bin2hex($row[$j]); + } + } elseif ($fields_meta[$j]->type == 'bit') { + // detection of 'bit' works only on mysqli extension + $values[] = "b'" . PMA_Util::sqlAddSlashes( + PMA_Util::printableBitValue( + $row[$j], $fields_meta[$j]->length + ) + ) + . "'"; + } else { + // something else -> treat as a string + $values[] = '\'' + . str_replace( + $search, $replace, + PMA_Util::sqlAddSlashes($row[$j]) + ) + . '\''; + } // end if + } // end for + + // should we make update? + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'UPDATE' + ) { + + $insert_line = $schema_insert; + for ($i = 0; $i < $fields_cnt; $i++) { + if (0 == $i) { + $insert_line .= ' '; + } + if ($i > 0) { + // avoid EOL blank + $insert_line .= ','; + } + $insert_line .= $field_set[$i] . ' = ' . $values[$i]; + } + + list($tmp_unique_condition, $tmp_clause_is_unique) + = PMA_Util::getUniqueCondition( + $result, + $fields_cnt, + $fields_meta, + $row + ); + $insert_line .= ' WHERE ' . $tmp_unique_condition; + unset($tmp_unique_condition, $tmp_clause_is_unique); + + } else { + + // Extended inserts case + if ($GLOBALS['sql_insert_syntax'] == 'extended' + || $GLOBALS['sql_insert_syntax'] == 'both' + ) { + if ($current_row == 1) { + $insert_line = $schema_insert . '(' + . implode(', ', $values) . ')'; + } else { + $insert_line = '(' . implode(', ', $values) . ')'; + $sql_max_size = $GLOBALS['sql_max_query_size']; + if (isset($sql_max_size) + && $sql_max_size > 0 + && $query_size + strlen($insert_line) > $sql_max_size + ) { + if (! PMA_exportOutputHandler(';' . $crlf)) { + return false; + } + $query_size = 0; + $current_row = 1; + $insert_line = $schema_insert . $insert_line; + } + } + $query_size += strlen($insert_line); + // Other inserts case + } else { + $insert_line = $schema_insert + . '(' + . implode(', ', $values) + . ')'; + } + } + unset($values); + + if (! PMA_exportOutputHandler( + ($current_row == 1 ? '' : $separator . $crlf) + . $insert_line + )) { + return false; + } + + } // end while + + if ($current_row > 0) { + if (! PMA_exportOutputHandler(';' . $crlf)) { + return false; + } + } + + // We need to SET IDENTITY_INSERT OFF for MSSQL + if (isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'MSSQL' + && $current_row > 0 + ) { + $outputSucceeded = PMA_exportOutputHandler( + $crlf . 'SET IDENTITY_INSERT ' + . PMA_Util::backquoteCompat($table, $compat) + . ' OFF;' . $crlf + ); + if (! $outputSucceeded) { + return false; + } + } + } // end if ($result != false) + PMA_DBI_free_result($result); + + return true; + } // end of the 'exportData()' function +} diff --git a/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php b/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php new file mode 100644 index 000000000..3aa609c34 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportTexytext.class.php @@ -0,0 +1,574 @@ +setProperties(); + } + + /** + * Sets the export Texy! text properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('Texy! text'); + $exportPluginProperties->setExtension('txt'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("general_opts"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return PMA_exportOutputHandler( + '===' . __('Database') . ' ' . $db . "\n\n" + ); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + if (! PMA_exportOutputHandler( + '== ' . __('Dumping data for table') . ' ' . $table . "\n\n" + )) { + return false; + } + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $text_output = "|------\n"; + for ($i = 0; $i < $fields_cnt; $i++) { + $text_output .= '|' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ); + } // end for + $text_output .= "\n|------\n"; + if (! PMA_exportOutputHandler($text_output)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $text_output = ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $value = $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + $value = $row[$j]; + } else { + $value = ' '; + } + $text_output .= '|' + . str_replace( + '|', '|', htmlspecialchars($value) + ); + } // end for + $text_output .= "\n"; + if (! PMA_exportOutputHandler($text_output)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + function getTableDefStandIn($db, $view, $crlf) + { + $text_output = ''; + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $view); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + /** + * Displays the table structure + */ + + $text_output .= "|------\n" + . '|' . __('Column') + . '|' . __('Type') + . '|' . __('Null') + . '|' . __('Default') + . "\n|------\n"; + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $text_output .= $this->formatOneColumnDefinition($column, $unique_keys); + $text_output .= "\n"; + } // end foreach + + return $text_output; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * $this->exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line + * at the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $cfgRelation; + + $text_output = ''; + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments && $cfgRelation['commwork']) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + + $text_output .= "|------\n"; + $text_output .= '|' . __('Column'); + $text_output .= '|' . __('Type'); + $text_output .= '|' . __('Null'); + $text_output .= '|' . __('Default'); + if ($do_relation && $have_rel) { + $text_output .= '|' . __('Links to'); + } + if ($do_comments) { + $text_output .= '|' . __('Comments'); + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $text_output .= '|' . htmlspecialchars('MIME'); + $mime_map = PMA_getMIME($db, $table, true); + } + $text_output .= "\n|------\n"; + + $columns = PMA_DBI_get_columns($db, $table); + foreach ($columns as $column) { + $text_output .= $this->formatOneColumnDefinition($column, $unique_keys); + $field_name = $column['Field']; + + if ($do_relation && $have_rel) { + $text_output .= '|' + . (isset($res_rel[$field_name]) + ? htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] . ')' + ) + : ''); + } + if ($do_comments && $cfgRelation['commwork']) { + $text_output .= '|' + . (isset($comments[$field_name]) + ? htmlspecialchars($comments[$field_name]) + : ''); + } + if ($do_mime && $cfgRelation['mimework']) { + $text_output .= '|' + . (isset($mime_map[$field_name]) + ? htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + : ''); + } + + $text_output .= "\n"; + } // end foreach + + return $text_output; + } // end of the '$this->getTableDef()' function + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return string Formatted triggers list + */ + function getTriggers($db, $table) + { + $text_output .= "|------\n"; + $text_output .= '|' . __('Column'); + $dump = "|------\n"; + $dump .= '|' . __('Name'); + $dump .= '|' . __('Time'); + $dump .= '|' . __('Event'); + $dump .= '|' . __('Definition'); + $dump .= "\n|------\n"; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $dump .= '|' . $trigger['name']; + $dump .= '|' . $trigger['action_timing']; + $dump .= '|' . $trigger['event_manipulation']; + $dump .= '|' . + str_replace( + '|', + '|', + htmlspecialchars($trigger['definition']) + ); + $dump .= "\n"; + } + + return $dump; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * $this->exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + $dump = ''; + + switch($export_mode) { + case 'create_table': + $dump .= '== ' . __('Table structure for table') . ' ' .$table . "\n\n"; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates + ); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= '== ' . __('Triggers') . ' ' .$table . "\n\n"; + $dump .= $this->getTriggers($db, $table); + } + break; + case 'create_view': + $dump .= '== ' . __('Structure for view') . ' ' .$table . "\n\n"; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates, true, true + ); + break; + case 'stand_in': + $dump .= '== ' . __('Stand-in structure for view') + . ' ' .$table . "\n\n"; + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return PMA_exportOutputHandler($dump); + } + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * @param array $unique_keys unique keys for this table + * + * @return string Formatted column definition + */ + function formatOneColumnDefinition( + $column, $unique_keys + ) { + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + $type = $extracted_columnspec['print_type']; + if (empty($type)) { + $type = ' '; + } + + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } + } + + $fmt_pre = ''; + $fmt_post = ''; + if (in_array($column['Field'], $unique_keys)) { + $fmt_pre = '**' . $fmt_pre; + $fmt_post = $fmt_post . '**'; + } + if ($column['Key']=='PRI') { + $fmt_pre = '//' . $fmt_pre; + $fmt_post = $fmt_post . '//'; + } + $definition = '|' + . $fmt_pre . htmlspecialchars($column['Field']) . $fmt_post; + $definition .= '|' . htmlspecialchars($type); + $definition .= '|' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') : __('Yes')); + $definition .= '|' + . htmlspecialchars( + isset($column['Default']) ? $column['Default'] : '' + ); + return $definition; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/ExportXml.class.php b/phpmyadmin/libraries/plugins/export/ExportXml.class.php new file mode 100644 index 000000000..711824c32 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportXml.class.php @@ -0,0 +1,536 @@ +setProperties(); + } + + /** + * Initialize the local variables that are used for export PDF + * + * @return void + */ + protected function initSpecificVariables() + { + global $table, $tables; + $this->_setTable($table); + $this->_setTables($tables); + } + + /** + * Sets the export XML properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + // create the export plugin property item + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('XML'); + $exportPluginProperties->setExtension('xml'); + $exportPluginProperties->setMimeType('text/xml'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // export structure main group + $structure = new OptionsPropertyMainGroup(); + $structure->setName("structure"); + $structure->setText(__('Object creation options (all are recommended)')); + // create primary items and add them to the group + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("export_functions"); + $leaf->setText(__('Functions')); + $structure->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("export_procedures"); + $leaf->setText(__('Procedures')); + $structure->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("export_tables"); + $leaf->setText(__('Tables')); + $structure->addProperty($leaf); + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("export_triggers"); + $leaf->setText(__('Triggers')); + $structure->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("export_views"); + $leaf->setText(__('Views')); + $structure->addProperty($leaf); + } + $exportSpecificOptions->addProperty($structure); + + // data main group + $data = new OptionsPropertyMainGroup(); + $data->setName("data"); + $data->setText(__('Data dump options')); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("export_contents"); + $leaf->setText(__('Export contents')); + $data->addProperty($leaf); + $exportSpecificOptions->addProperty($data); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header. It is the first method to be called, so all + * the required variables are initialized here. + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $this->initSpecificVariables(); + global $crlf, $cfg, $db; + $table = $this->_getTable(); + $tables = $this->_getTables(); + + $export_struct = isset($GLOBALS['xml_export_functions']) + || isset($GLOBALS['xml_export_procedures']) + || isset($GLOBALS['xml_export_tables']) + || isset($GLOBALS['xml_export_triggers']) + || isset($GLOBALS['xml_export_views']); + $export_data = isset($GLOBALS['xml_export_contents']) ? true : false; + + if ($GLOBALS['output_charset_conversion']) { + $charset = $GLOBALS['charset_of_file']; + } else { + $charset = 'utf-8'; + } + + $head = '' . $crlf + . '' . $crlf . $crlf; + + $head .= '' . $crlf; + + if ($export_struct) { + if (PMA_DRIZZLE) { + $result = PMA_DBI_fetch_result( + "SELECT + 'utf8' AS DEFAULT_CHARACTER_SET_NAME, + DEFAULT_COLLATION_NAME + FROM data_dictionary.SCHEMAS + WHERE SCHEMA_NAME = '" + . PMA_Util::sqlAddSlashes($db) . "'" + ); + } else { + $result = PMA_DBI_fetch_result( + 'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`' + . ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`' + . ' = \''.PMA_Util::sqlAddSlashes($db).'\' LIMIT 1' + ); + } + $db_collation = $result[0]['DEFAULT_COLLATION_NAME']; + $db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME']; + + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + + if (count($tables) == 0) { + $tables[] = $table; + } + + foreach ($tables as $table) { + // Export tables and views + $result = PMA_DBI_fetch_result( + 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table), + 0 + ); + $tbl = $result[$table][1]; + + $is_view = PMA_Table::isView($db, $table); + + if ($is_view) { + $type = 'view'; + } else { + $type = 'table'; + } + + if ($is_view && ! isset($GLOBALS['xml_export_views'])) { + continue; + } + + if (! $is_view && ! isset($GLOBALS['xml_export_tables'])) { + continue; + } + + $head .= ' ' + . $crlf; + + $tbl = " " . htmlspecialchars($tbl); + $tbl = str_replace("\n", "\n ", $tbl); + + $head .= $tbl . ';' . $crlf; + $head .= ' ' . $crlf; + + if (isset($GLOBALS['xml_export_triggers']) + && $GLOBALS['xml_export_triggers'] + ) { + // Export triggers + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + foreach ($triggers as $trigger) { + $code = $trigger['create']; + $head .= ' ' . $crlf; + + // Do some formatting + $code = substr(rtrim($code), 0, -3); + $code = " " . htmlspecialchars($code); + $code = str_replace("\n", "\n ", $code); + + $head .= $code . $crlf; + $head .= ' ' . $crlf; + } + + unset($trigger); + unset($triggers); + } + } + } + + if (isset($GLOBALS['xml_export_functions']) + && $GLOBALS['xml_export_functions'] + ) { + // Export functions + $functions = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION'); + if ($functions) { + foreach ($functions as $function) { + $head .= ' ' . $crlf; + + // Do some formatting + $sql = PMA_DBI_get_definition($db, 'FUNCTION', $function); + $sql = rtrim($sql); + $sql = " " . htmlspecialchars($sql); + $sql = str_replace("\n", "\n ", $sql); + + $head .= $sql . $crlf; + $head .= ' ' . $crlf; + } + + unset($function); + unset($functions); + } + } + + if (isset($GLOBALS['xml_export_procedures']) + && $GLOBALS['xml_export_procedures'] + ) { + // Export procedures + $procedures = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE'); + if ($procedures) { + foreach ($procedures as $procedure) { + $head .= ' ' . $crlf; + + // Do some formatting + $sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure); + $sql = rtrim($sql); + $sql = " " . htmlspecialchars($sql); + $sql = str_replace("\n", "\n ", $sql); + + $head .= $sql . $crlf; + $head .= ' ' . $crlf; + } + + unset($procedure); + unset($procedures); + } + } + + unset($result); + + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + + if ($export_data) { + $head .= $crlf; + } + } + + return PMA_exportOutputHandler($head); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $foot = ''; + + return PMA_exportOutputHandler($foot); + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + global $crlf; + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + $head = ' ' . $crlf + . ' ' . $crlf; + + return PMA_exportOutputHandler($head); + } else { + return true; + } + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + global $crlf; + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + return PMA_exportOutputHandler(' ' . $crlf); + } else { + return true; + } + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in XML format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData ($db, $table, $crlf, $error_url, $sql_query) + { + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + $columns = array(); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ' ' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + while ($record = PMA_DBI_fetch_row($result)) { + $buffer = ' ' . $crlf; + for ($i = 0; $i < $columns_cnt; $i++) { + // If a cell is NULL, still export it to preserve + // the XML structure + if (! isset($record[$i]) || is_null($record[$i])) { + $record[$i] = 'NULL'; + } + $buffer .= ' ' + . htmlspecialchars((string)$record[$i]) + . '' . $crlf; + } + $buffer .= '
      ' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + PMA_DBI_free_result($result); + } + + return true; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the table name + * + * @return void + */ + private function _getTable() + { + return $this->_table; + } + + /** + * Sets the table name + * + * @param string $table table name + * + * @return void + */ + private function _setTable($table) + { + $this->_table = $table; + } + + /** + * Gets the table names + * + * @return array + */ + private function _getTables() + { + return $this->_tables; + } + + /** + * Sets the table names + * + * @param array $tables table names + * + * @return void + */ + private function _setTables($tables) + { + $this->_tables = $tables; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/export/ExportYaml.class.php b/phpmyadmin/libraries/plugins/export/ExportYaml.class.php new file mode 100644 index 000000000..044daeee4 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/ExportYaml.class.php @@ -0,0 +1,214 @@ +setProperties(); + } + + /** + * Sets the export YAML properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('YAML'); + $exportPluginProperties->setExtension('yml'); + $exportPluginProperties->setMimeType('text/yaml'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + '%YAML 1.1' . $GLOBALS['crlf'] . '---' . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + PMA_exportOutputHandler('...' . $GLOBALS['crlf']); + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ''; + $record_cnt = 0; + while ($record = PMA_DBI_fetch_row($result)) { + $record_cnt++; + + // Output table name as comment if this is the first record of the table + if ($record_cnt == 1) { + $buffer = '# ' . $db . '.' . $table . $crlf; + $buffer .= '-' . $crlf; + } else { + $buffer = '-' . $crlf; + } + + for ($i = 0; $i < $columns_cnt; $i++) { + if (! isset($record[$i])) { + continue; + } + + $column = $columns[$i]; + + if (is_null($record[$i])) { + $buffer .= ' ' . $column . ': null' . $crlf; + continue; + } + + if (is_numeric($record[$i])) { + $buffer .= ' ' . $column . ': ' . $record[$i] . $crlf; + continue; + } + + $record[$i] = str_replace( + array('\\', '"', "\n", "\r"), + array('\\\\', '\"', '\n', '\r'), + $record[$i] + ); + $buffer .= ' ' . $column . ': "' . $record[$i] . '"' . $crlf; + } + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + PMA_DBI_free_result($result); + + return true; + } // end getTableYAML +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php b/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php new file mode 100644 index 000000000..1913d5ecd --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/PMA_ExportPdf.class.php @@ -0,0 +1,408 @@ +empty_string($y)) { + $y = $this->y; + } + $current_page = $this->page; + if ((($y + $h) > $this->PageBreakTrigger) + AND (! $this->InFooter) + AND ($this->AcceptPageBreak()) + ) { + if ($addpage) { + //Automatic page break + $x = $this->x; + $this->AddPage($this->CurOrientation); + $this->y = $this->dataY; + $oldpage = $this->page - 1; + + $this_page_orm = $this->pagedim[$this->page]['orm']; + $old_page_orm = $this->pagedim[$oldpage]['orm']; + $this_page_olm = $this->pagedim[$this->page]['olm']; + $old_page_olm = $this->pagedim[$oldpage]['olm']; + if ($this->rtl) { + if ($this_page_orm!= $old_page_orm) { + $this->x = $x - ($this_page_orm - $old_page_orm); + } else { + $this->x = $x; + } + } else { + if ($this_page_olm != $old_page_olm) { + $this->x = $x + ($this_page_olm - $old_page_olm); + } else { + $this->x = $x; + } + } + } + return true; + } + if ($current_page != $this->page) { + // account for columns mode + return true; + } + return false; + } + + /** + * This method is used to render the page header. + * + * @return void + */ + function Header() + { + global $maxY; + // We don't want automatic page breaks while generating header + // as this can lead to infinite recursion as auto generated page + // will want header as well causing another page break + // FIXME: Better approach might be to try to compact the content + $this->SetAutoPageBreak(false); + // Check if header for this page already exists + if (! isset($this->headerset[$this->page])) { + $fullwidth = 0; + foreach ($this->tablewidths as $width) { + $fullwidth += $width; + } + $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 5); + $this->cellFontSize = $this->FontSizePt ; + $this->SetFont( + PMA_PDF_FONT, + '', + ($this->titleFontSize + ? $this->titleFontSize + : $this->FontSizePt) + ); + $this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C'); + $this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize); + $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 2.5); + $this->Cell( + 0, + $this->FontSizePt, + __('Database') . ': ' . $this->currentDb . ', ' + . __('Table') . ': ' . $this->currentTable, + 0, 1, 'L' + ); + $l = ($this->lMargin); + foreach ($this->colTitles as $col => $txt) { + $this->SetXY($l, ($this->tMargin)); + $this->MultiCell( + $this->tablewidths[$col], + $this->FontSizePt, + $txt + ); + $l += $this->tablewidths[$col] ; + $maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ; + } + $this->SetXY($this->lMargin, $this->tMargin); + $this->setFillColor(200, 200, 200); + $l = ($this->lMargin); + foreach ($this->colTitles as $col => $txt) { + $this->SetXY($l, $this->tMargin); + $this->cell( + $this->tablewidths[$col], + $maxY-($this->tMargin), + '', + 1, + 0, + 'L', + 1 + ); + $this->SetXY($l, $this->tMargin); + $this->MultiCell( + $this->tablewidths[$col], + $this->FontSizePt, + $txt, + 0, + 'C' + ); + $l += $this->tablewidths[$col]; + } + $this->setFillColor(255, 255, 255); + // set headerset + $this->headerset[$this->page] = 1; + } + + $this->dataY = $maxY; + $this->SetAutoPageBreak(true); + } + + function morepagestable($lineheight = 8) + { + // some things to set and 'remember' + $l = $this->lMargin; + $startheight = $h = $this->dataY; + $startpage = $currpage = $this->page; + + // calculate the whole width + $fullwidth = 0; + foreach ($this->tablewidths as $width) { + $fullwidth += $width; + } + + // Now let's start to write the table + $row = 0; + $tmpheight = array(); + $maxpage = $this->page; + + while ($data = PMA_DBI_fetch_row($this->results)) { + $this->page = $currpage; + // write the horizontal borders + $this->Line($l, $h, $fullwidth+$l, $h); + // write the content and remember the height of the highest col + foreach ($data as $col => $txt) { + $this->page = $currpage; + $this->SetXY($l, $h); + if ($this->tablewidths[$col] > 0) { + $this->MultiCell( + $this->tablewidths[$col], + $lineheight, + $txt, + 0, + $this->colAlign[$col] + ); + $l += $this->tablewidths[$col]; + } + + if (! isset($tmpheight[$row.'-'.$this->page])) { + $tmpheight[$row.'-'.$this->page] = 0; + } + if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) { + $tmpheight[$row.'-'.$this->page] = $this->GetY(); + } + if ($this->page > $maxpage) { + $maxpage = $this->page; + } + unset($data[$col]); + } + + // get the height we were in the last used page + $h = $tmpheight[$row.'-'.$maxpage]; + // set the "pointer" to the left margin + $l = $this->lMargin; + // set the $currpage to the last page + $currpage = $maxpage; + unset($data[$row]); + $row++; + } + // draw the borders + // we start adding a horizontal line on the last page + $this->page = $maxpage; + $this->Line($l, $h, $fullwidth+$l, $h); + // now we start at the top of the document and walk down + for ($i = $startpage; $i <= $maxpage; $i++) { + $this->page = $i; + $l = $this->lMargin; + $t = ($i == $startpage) ? $startheight : $this->tMargin; + $lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin; + $this->Line($l, $t, $l, $lh); + foreach ($this->tablewidths as $width) { + $l += $width; + $this->Line($l, $t, $l, $lh); + } + } + // set it to the last page, if not it'll cause some problems + $this->page = $maxpage; + } + + /** + * Sets a set of attributes. + * + * @param array $attr array containing the attributes + * + * @return void + */ + function setAttributes($attr = array()) + { + foreach ($attr as $key => $val) { + $this->$key = $val ; + } + } + + /** + * Defines the top margin. + * The method can be called before creating the first page. + * + * @param float $topMargin the margin + * + * @return void + */ + function setTopMargin($topMargin) + { + $this->tMargin = $topMargin; + } + + function mysqlReport($query) + { + unset($this->tablewidths); + unset($this->colTitles); + unset($this->titleWidth); + unset($this->colFits); + unset($this->display_column); + unset($this->colAlign); + + /** + * Pass 1 for column widths + */ + $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); + $this->numFields = PMA_DBI_num_fields($this->results); + $this->fields = PMA_DBI_get_fields_meta($this->results); + + // sColWidth = starting col width (an average size width) + $availableWidth = $this->w - $this->lMargin - $this->rMargin; + $this->sColWidth = $availableWidth / $this->numFields; + $totalTitleWidth = 0; + + // loop through results header and set initial + // col widths/ titles/ alignment + // if a col title is less than the starting col width, + // reduce that column size + $colFits = array(); + for ($i = 0; $i < $this->numFields; $i++) { + $stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ; + // save the real title's width + $titleWidth[$i] = $stringWidth; + $totalTitleWidth += $stringWidth; + + // set any column titles less than the start width to + // the column title width + if ($stringWidth < $this->sColWidth) { + $colFits[$i] = $stringWidth ; + } + $this->colTitles[$i] = $this->fields[$i]->name; + $this->display_column[$i] = true; + + switch ($this->fields[$i]->type) { + case 'int': + $this->colAlign[$i] = 'R'; + break; + case 'blob': + case 'tinyblob': + case 'mediumblob': + case 'longblob': + /** + * @todo do not deactivate completely the display + * but show the field's name and [BLOB] + */ + if (stristr($this->fields[$i]->flags, 'BINARY')) { + $this->display_column[$i] = false; + unset($this->colTitles[$i]); + } + $this->colAlign[$i] = 'L'; + break; + default: + $this->colAlign[$i] = 'L'; + } + } + + // title width verification + if ($totalTitleWidth > $availableWidth) { + $adjustingMode = true; + } else { + $adjustingMode = false; + // we have enough space for all the titles at their + // original width so use the true title's width + foreach ($titleWidth as $key => $val) { + $colFits[$key] = $val; + } + } + + // loop through the data; any column whose contents + // is greater than the column size is resized + /** + * @todo force here a LIMIT to avoid reading all rows + */ + while ($row = PMA_DBI_fetch_row($this->results)) { + foreach ($colFits as $key => $val) { + $stringWidth = $this->getstringwidth($row[$key]) + 6 ; + if ($adjustingMode && ($stringWidth > $this->sColWidth)) { + // any column whose data's width is bigger than + // the start width is now discarded + unset($colFits[$key]); + } else { + // if data's width is bigger than the current column width, + // enlarge the column (but avoid enlarging it if the + // data's width is very big) + if ($stringWidth > $val + && $stringWidth < ($this->sColWidth * 3) + ) { + $colFits[$key] = $stringWidth ; + } + } + } + } + + $totAlreadyFitted = 0; + foreach ($colFits as $key => $val) { + // set fitted columns to smallest size + $this->tablewidths[$key] = $val; + // to work out how much (if any) space has been freed up + $totAlreadyFitted += $val; + } + + if ($adjustingMode) { + $surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted; + $surplusToAdd = $surplus / ($this->numFields - sizeof($colFits)); + } else { + $surplusToAdd = 0; + } + + for ($i = 0; $i < $this->numFields; $i++) { + if (! in_array($i, array_keys($colFits))) { + $this->tablewidths[$i] = $this->sColWidth + $surplusToAdd; + } + if ($this->display_column[$i] == false) { + $this->tablewidths[$i] = 0; + } + } + + ksort($this->tablewidths); + + PMA_DBI_free_result($this->results); + + // Pass 2 + + $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); + $this->setY($this->tMargin); + $this->AddPage(); + $this->SetFont(PMA_PDF_FONT, '', 9); + $this->morepagestable($this->FontSizePt); + PMA_DBI_free_result($this->results); + + } // end of mysqlReport function + +} // end of PMA_Export_PDF class +?> diff --git a/phpmyadmin/libraries/plugins/export/README b/phpmyadmin/libraries/plugins/export/README new file mode 100644 index 000000000..68d5a26f1 --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/README @@ -0,0 +1,276 @@ +This directory holds export plugins for phpMyAdmin. Any new plugin should +basically follow the structure presented here. Official plugins need to +have str* messages with their definition in language files, but if you build +some plugins for your use, you can directly use texts in plugin. + +setProperties(); + } + + // optional - declare global variables and use getters later + /** + * Initialize the local variables that are used specific for export SQL + * + * @global type $global_variable_name + * [..] + * + * @return void + */ + protected function initSpecificVariables() + { + global $global_variable_name; + $this->_setGlobalVariableName($global_variable_name); + } + + /** + * Sets the export plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + // set properties + $props = 'libraries/properties/'; + // include the main class for properties for the export plug-ins + include_once "$props/plugins/ExportPluginProperties.class.php"; + // include the group properties classes + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + // include the needed single property items + include_once "$props/options/items/RadioPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('[name]'); // the name of your plug-in + $exportPluginProperties->setExtension('[ext]'); // extension this plug-in can handle + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // optional : + // create primary items and add them to the group + // type - one of the classes listed in libraries/properties/options/items/ + // name - form element name + // text - description in GUI + // size - size of text element + // len - maximal size of input + // values - possible values of the item + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + // implementation + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + // implementation + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + // implementation + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + // implementation + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + // implementation + return true; + } + + /** + * Outputs the content of a table in [Name] format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + // implementation; + return true; + } + + // optional - implement other methods defined in ExportPlugin.class.php: + // - exportRoutines() + // - exportStructure() + // - getTableDefStandIn() + // - getTriggers() + + // optional - implement other private methods in order to avoid + // having huge methods or avoid duplicate code. Make use of them + // as well as of the getters and setters declared both here + // and in the ExportPlugin class + + + // optional: + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Getter description + * + * @return type + */ + private function _getMyOptionalVariable() + { + return $this->_myOptionalVariable; + } + + /** + * Setter description + * + * @param type $my_optional_variable description + * + * @return void + */ + private function _setMyOptionalVariable($my_optional_variable) + { + $this->_myOptionalVariable = $my_optional_variable; + } + + /** + * Getter description + * + * @return type + */ + private function _getGlobalVariableName() + { + return $this->_globalVariableName; + } + + /** + * Setter description + * + * @param type $global_variable_name description + * + * @return void + */ + private function _setGlobalVariableName($global_variable_name) + { + $this->_globalVariableName = $global_variable_name; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/export/TableProperty.class.php b/phpmyadmin/libraries/plugins/export/TableProperty.class.php new file mode 100644 index 000000000..a928a6c3d --- /dev/null +++ b/phpmyadmin/libraries/plugins/export/TableProperty.class.php @@ -0,0 +1,288 @@ +name = trim($row[0]); + $this->type = trim($row[1]); + $this->nullable = trim($row[2]); + $this->key = trim($row[3]); + $this->defaultValue = trim($row[4]); + $this->ext = trim($row[5]); + } + + /** + * Gets the pure type + * + * @return string type + */ + function getPureType() + { + $pos = strpos($this->type, "("); + if ($pos > 0) { + return substr($this->type, 0, $pos); + } + return $this->type; + } + + /** + * Tells whether the key is null or not + * + * @return bool true if the key is not null, false otherwise + */ + function isNotNull() + { + return $this->nullable == "NO" ? "true" : "false"; + } + + /** + * Tells whether the key is unique or not + * + * @return bool true if the key is unique, false otherwise + */ + function isUnique() + { + return $this->key == "PRI" || $this->key == "UNI" ? "true" : "false"; + } + + /** + * Gets the .NET primitive type + * + * @return string type + */ + function getDotNetPrimitiveType() + { + if (strpos($this->type, "int") === 0) { + return "int"; + } + if (strpos($this->type, "long") === 0) { + return "long"; + } + if (strpos($this->type, "char") === 0) { + return "string"; + } + if (strpos($this->type, "varchar") === 0) { + return "string"; + } + if (strpos($this->type, "text") === 0) { + return "string"; + } + if (strpos($this->type, "longtext") === 0) { + return "string"; + } + if (strpos($this->type, "tinyint") === 0) { + return "bool"; + } + if (strpos($this->type, "datetime") === 0) { + return "DateTime"; + } + return "unknown"; + } + + /** + * Gets the .NET object type + * + * @return string type + */ + function getDotNetObjectType() + { + if (strpos($this->type, "int") === 0) { + return "Int32"; + } + if (strpos($this->type, "long") === 0) { + return "Long"; + } + if (strpos($this->type, "char") === 0) { + return "String"; + } + if (strpos($this->type, "varchar") === 0) { + return "String"; + } + if (strpos($this->type, "text") === 0) { + return "String"; + } + if (strpos($this->type, "longtext") === 0) { + return "String"; + } + if (strpos($this->type, "tinyint") === 0) { + return "Boolean"; + } + if (strpos($this->type, "datetime") === 0) { + return "DateTime"; + } + return "Unknown"; + } + + /** + * Gets the index name + * + * @return string containing the name of the index + */ + function getIndexName() + { + if (strlen($this->key) > 0) { + return "index=\"" + . htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8') + . "\""; + } + return ""; + } + + /** + * Tells whether the key is primary or not + * + * @return bool true if the key is primary, false otherwise + */ + function isPK() + { + return $this->key=="PRI"; + } + + /** + * Formats a string for C# + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function formatCs($text) + { + $text = str_replace( + "#name#", + ExportCodegen::cgMakeIdentifier($this->name, false), + $text + ); + return $this->format($text); + } + + /** + * Formats a string for XML + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function formatXml($text) + { + $text = str_replace( + "#name#", + htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8'), + $text + ); + $text = str_replace( + "#indexName#", + $this->getIndexName(), + $text + ); + return $this->format($text); + } + + /** + * Formats a string + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function format($text) + { + $text = str_replace( + "#ucfirstName#", + ExportCodegen::cgMakeIdentifier($this->name), + $text + ); + $text = str_replace( + "#dotNetPrimitiveType#", + $this->getDotNetPrimitiveType(), + $text + ); + $text = str_replace( + "#dotNetObjectType#", + $this->getDotNetObjectType(), + $text + ); + $text = str_replace( + "#type#", + $this->getPureType(), + $text + ); + $text = str_replace( + "#notNull#", + $this->isNotNull(), + $text + ); + $text = str_replace( + "#unique#", + $this->isUnique(), + $text + ); + return $text; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php b/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php new file mode 100644 index 000000000..62ca8bb54 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/AbstractImportCsv.class.php @@ -0,0 +1,91 @@ +setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $importPluginProperties + // this will be shown as "Format specific options" + $importSpecificOptions = new OptionsPropertyRootGroup(); + $importSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // create common items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("replace"); + $leaf->setText(__('Replace table data with file')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("terminated"); + $leaf->setText(__('Columns separated with:')); + $leaf->setSize(2); + $leaf->setLen(2); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("enclosed"); + $leaf->setText(__('Columns enclosed with:')); + $leaf->setSize(2); + $leaf->setLen(2); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("escaped"); + $leaf->setText(__('Columns escaped with:')); + $leaf->setSize(2); + $leaf->setLen(2); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("new_line"); + $leaf->setText(__('Lines terminated with:')); + $leaf->setSize(2); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $importSpecificOptions->addProperty($generalOptions); + + // set the options for the import plugin property item + $importPluginProperties->setOptions($importSpecificOptions); + $this->properties = $importPluginProperties; + + return $generalOptions; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ImportCsv.class.php b/phpmyadmin/libraries/plugins/import/ImportCsv.class.php new file mode 100644 index 000000000..d48056484 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportCsv.class.php @@ -0,0 +1,588 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $this->_setAnalyze(false); + + if ($GLOBALS['plugin_param'] !== 'table') { + $this->_setAnalyze(true); + } + + $generalOptions = parent::setProperties(); + $this->properties->setText('CSV'); + $this->properties->setExtension('csv'); + + if ($GLOBALS['plugin_param'] !== 'table') { + $leaf = new BoolPropertyItem(); + $leaf->setName("col_names"); + $leaf->setText( + __( + 'The first line of the file contains the table column names' + . ' (if this is unchecked, the first line will become part' + . ' of the data)' + ) + ); + $generalOptions->addProperty($leaf); + } else { + $hint = new PMA_Message( + __( + 'If the data in each row of the file is not' + . ' in the same order as in the database, list the corresponding' + . ' column names here. Column names must be separated by commas' + . ' and not enclosed in quotations.' + ) + ); + $leaf = new TextPropertyItem(); + $leaf->setName("columns"); + $leaf->setText( + __('Column names: ') + . PMA_Util::showHint($hint) + ); + $generalOptions->addProperty($leaf); + } + + $leaf = new BoolPropertyItem(); + $leaf->setName("ignore"); + $leaf->setText(__('Do not abort on INSERT error')); + $generalOptions->addProperty($leaf); + + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $db, $table, $csv_terminated, $csv_enclosed, $csv_escaped, + $csv_new_line, $csv_columns, $err_url; + // $csv_replace and $csv_ignore should have been here, + // but we use directly from $_POST + global $error, $timeout_passed, $finished, $message; + + $replacements = array( + '\\n' => "\n", + '\\t' => "\t", + '\\r' => "\r", + ); + $csv_terminated = strtr($csv_terminated, $replacements); + $csv_enclosed = strtr($csv_enclosed, $replacements); + $csv_escaped = strtr($csv_escaped, $replacements); + $csv_new_line = strtr($csv_new_line, $replacements); + + $param_error = false; + if (strlen($csv_terminated) != 1) { + $message = PMA_Message::error( + __('Invalid parameter for CSV import: %s') + ); + $message->addParam(__('Columns terminated by'), false); + $error = true; + $param_error = true; + // The default dialog of MS Excel when generating a CSV produces a + // semi-colon-separated file with no chance of specifying the + // enclosing character. Thus, users who want to import this file + // tend to remove the enclosing character on the Import dialog. + // I could not find a test case where having no enclosing characters + // confuses this script. + // But the parser won't work correctly with strings so we allow just + // one character. + } elseif (strlen($csv_enclosed) > 1) { + $message = PMA_Message::error( + __('Invalid parameter for CSV import: %s') + ); + $message->addParam(__('Columns enclosed by'), false); + $error = true; + $param_error = true; + } elseif (strlen($csv_escaped) != 1) { + $message = PMA_Message::error( + __('Invalid parameter for CSV import: %s') + ); + $message->addParam(__('Columns escaped by'), false); + $error = true; + $param_error = true; + } elseif (strlen($csv_new_line) != 1 && $csv_new_line != 'auto') { + $message = PMA_Message::error( + __('Invalid parameter for CSV import: %s') + ); + $message->addParam(__('Lines terminated by'), false); + $error = true; + $param_error = true; + } + + // If there is an error in the parameters entered, + // indicate that immediately. + if ($param_error) { + PMA_Util::mysqlDie($message->getMessage(), '', '', $err_url); + } + + $buffer = ''; + $required_fields = 0; + + if (! $this->_getAnalyze()) { + if (isset($_POST['csv_replace'])) { + $sql_template = 'REPLACE'; + } else { + $sql_template = 'INSERT'; + if (isset($_POST['csv_ignore'])) { + $sql_template .= ' IGNORE'; + } + } + $sql_template .= ' INTO ' . PMA_Util::backquote($table); + + $tmp_fields = PMA_DBI_get_columns($db, $table); + + if (empty($csv_columns)) { + $fields = $tmp_fields; + } else { + $sql_template .= ' ('; + $fields = array(); + $tmp = preg_split('/,( ?)/', $csv_columns); + foreach ($tmp as $key => $val) { + if (count($fields) > 0) { + $sql_template .= ', '; + } + /* Trim also `, if user already included backquoted fields */ + $val = trim($val, " \t\r\n\0\x0B`"); + $found = false; + foreach ($tmp_fields as $field) { + if ($field['Field'] == $val) { + $found = true; + break; + } + } + if (! $found) { + $message = PMA_Message::error( + __( + 'Invalid column (%s) specified! Ensure that columns' + . ' names are spelled correctly, separated by commas' + . ', and not enclosed in quotes.' + ) + ); + $message->addParam($val); + $error = true; + break; + } + $fields[] = $field; + $sql_template .= PMA_Util::backquote($val); + } + $sql_template .= ') '; + } + + $required_fields = count($fields); + + $sql_template .= ' VALUES ('; + } + + // Defaults for parser + $i = 0; + $len = 0; + $line = 1; + $lasti = -1; + $values = array(); + $csv_finish = false; + + $tempRow = array(); + $rows = array(); + $col_names = array(); + $tables = array(); + + $col_count = 0; + $max_cols = 0; + + while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) { + $data = PMA_importGetNextChunk(); + if ($data === false) { + // subtract data we didn't handle yet and stop processing + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + // Handle rest of buffer + } else { + // Append new data to buffer + $buffer .= $data; + unset($data); + // Do not parse string when we're not at the end + // and don't have new line inside + if (($csv_new_line == 'auto' + && strpos($buffer, "\r") === false + && strpos($buffer, "\n") === false) + || ($csv_new_line != 'auto' + && strpos($buffer, $csv_new_line) === false) + ) { + continue; + } + } + + // Current length of our buffer + $len = strlen($buffer); + // Currently parsed char + $ch = $buffer[$i]; + while ($i < $len) { + // Deadlock protection + if ($lasti == $i && $lastlen == $len) { + $message = PMA_Message::error( + __('Invalid format of CSV input on line %d.') + ); + $message->addParam($line); + $error = true; + break; + } + $lasti = $i; + $lastlen = $len; + + // This can happen with auto EOL and \r at the end of buffer + if (! $csv_finish) { + // Grab empty field + if ($ch == $csv_terminated) { + if ($i == $len - 1) { + break; + } + $values[] = ''; + $i++; + $ch = $buffer[$i]; + continue; + } + + // Grab one field + $fallbacki = $i; + if ($ch == $csv_enclosed) { + if ($i == $len - 1) { + break; + } + $need_end = true; + $i++; + $ch = $buffer[$i]; + } else { + $need_end = false; + } + $fail = false; + $value = ''; + while (($need_end + && ( $ch != $csv_enclosed || $csv_enclosed == $csv_escaped )) + || ( ! $need_end + && ! ( $ch == $csv_terminated + || $ch == $csv_new_line + || ( $csv_new_line == 'auto' + && ( $ch == "\r" || $ch == "\n" ) ) ) ) + ) { + if ($ch == $csv_escaped) { + if ($i == $len - 1) { + $fail = true; + break; + } + $i++; + $ch = $buffer[$i]; + if ($csv_enclosed == $csv_escaped + && ($ch == $csv_terminated + || $ch == $csv_new_line + || ($csv_new_line == 'auto' + && ($ch == "\r" || $ch == "\n"))) + ) { + break; + } + } + $value .= $ch; + if ($i == $len - 1) { + if (! $finished) { + $fail = true; + } + break; + } + $i++; + $ch = $buffer[$i]; + } + + // unquoted NULL string + if (false === $need_end && $value === 'NULL') { + $value = null; + } + + if ($fail) { + $i = $fallbacki; + $ch = $buffer[$i]; + break; + } + // Need to strip trailing enclosing char? + if ($need_end && $ch == $csv_enclosed) { + if ($finished && $i == $len - 1) { + $ch = null; + } elseif ($i == $len - 1) { + $i = $fallbacki; + $ch = $buffer[$i]; + break; + } else { + $i++; + $ch = $buffer[$i]; + } + } + // Are we at the end? + if ($ch == $csv_new_line + || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) + || ($finished && $i == $len - 1) + ) { + $csv_finish = true; + } + // Go to next char + if ($ch == $csv_terminated) { + if ($i == $len - 1) { + $i = $fallbacki; + $ch = $buffer[$i]; + break; + } + $i++; + $ch = $buffer[$i]; + } + // If everything went okay, store value + $values[] = $value; + } + + // End of line + if ($csv_finish + || $ch == $csv_new_line + || ($csv_new_line == 'auto' && ($ch == "\r" || $ch == "\n")) + ) { + if ($csv_new_line == 'auto' && $ch == "\r") { // Handle "\r\n" + if ($i >= ($len - 2) && ! $finished) { + break; // We need more data to decide new line + } + if ($buffer[$i + 1] == "\n") { + $i++; + } + } + // We didn't parse value till the end of line, so there was + // empty one + if (! $csv_finish) { + $values[] = ''; + } + + if ($this->_getAnalyze()) { + foreach ($values as $val) { + $tempRow[] = $val; + ++$col_count; + } + + if ($col_count > $max_cols) { + $max_cols = $col_count; + } + $col_count = 0; + + $rows[] = $tempRow; + $tempRow = array(); + } else { + // Do we have correct count of values? + if (count($values) != $required_fields) { + + // Hack for excel + if ($values[count($values) - 1] == ';') { + unset($values[count($values) - 1]); + } else { + $message = PMA_Message::error( + __('Invalid column count in CSV input on line %d.') + ); + $message->addParam($line); + $error = true; + break; + } + } + + $first = true; + $sql = $sql_template; + foreach ($values as $key => $val) { + if (! $first) { + $sql .= ', '; + } + if ($val === null) { + $sql .= 'NULL'; + } else { + $sql .= '\'' + . PMA_Util::sqlAddSlashes($val) + . '\''; + } + + $first = false; + } + $sql .= ')'; + + /** + * @todo maybe we could add original line to verbose + * SQL in comment + */ + PMA_importRunQuery($sql, $sql); + } + + $line++; + $csv_finish = false; + $values = array(); + $buffer = substr($buffer, $i + 1); + $len = strlen($buffer); + $i = 0; + $lasti = -1; + $ch = $buffer[0]; + } + } // End of parser loop + } // End of import loop + + if ($this->_getAnalyze()) { + /* Fill out all rows */ + $num_rows = count($rows); + for ($i = 0; $i < $num_rows; ++$i) { + for ($j = count($rows[$i]); $j < $max_cols; ++$j) { + $rows[$i][] = 'NULL'; + } + } + + if (isset($_REQUEST['csv_col_names'])) { + $col_names = array_splice($rows, 0, 1); + $col_names = $col_names[0]; + } + + if ((isset($col_names) && count($col_names) != $max_cols) + || ! isset($col_names) + ) { + // Fill out column names + for ($i = 0; $i < $max_cols; ++$i) { + $col_names[] = 'COL '.($i+1); + } + } + + if (strlen($db)) { + $result = PMA_DBI_fetch_result('SHOW TABLES'); + $tbl_name = 'TABLE '.(count($result) + 1); + } else { + $tbl_name = 'TBL_NAME'; + } + + $tables[] = array($tbl_name, $col_names, $rows); + + /* Obtain the best-fit MySQL types for each column */ + $analyses = array(); + $analyses[] = PMA_analyzeTable($tables[0]); + + /** + * string $db_name (no backquotes) + * + * array $table = array(table_name, array() column_names, array()() rows) + * array $tables = array of "$table"s + * + * array $analysis = array(array() column_types, array() column_sizes) + * array $analyses = array of "$analysis"s + * + * array $create = array of SQL strings + * + * array $options = an associative array of options + */ + + /* Set database name to the currently selected one, if applicable */ + if (strlen($db)) { + $db_name = $db; + $options = array('create_db' => false); + } else { + $db_name = 'CSV_DB'; + $options = null; + } + + /* Non-applicable parameters */ + $create = null; + + /* Created and execute necessary SQL statements from data */ + PMA_buildSQL($db_name, $tables, $analyses, $create, $options); + + unset($tables); + unset($analyses); + } + + // Commit any possible data in buffers + PMA_importRunQuery(); + + if (count($values) != 0 && ! $error) { + $message = PMA_Message::error( + __('Invalid format of CSV input on line %d.') + ); + $message->addParam($line); + $error = true; + } + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Returns true if the table should be analyzed, false otherwise + * + * @return bool + */ + private function _getAnalyze() + { + return $this->_analyze; + } + + /** + * Sets to true if the table should be analyzed, false otherwise + * + * @param bool $analyze status + * + * @return void + */ + private function _setAnalyze($analyze) + { + $this->_analyze = $analyze; + } +} diff --git a/phpmyadmin/libraries/plugins/import/ImportLdi.class.php b/phpmyadmin/libraries/plugins/import/ImportLdi.class.php new file mode 100644 index 000000000..e38def9c8 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportLdi.class.php @@ -0,0 +1,172 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + if ($GLOBALS['cfg']['Import']['ldi_local_option'] == 'auto') { + $GLOBALS['cfg']['Import']['ldi_local_option'] = false; + + $result = PMA_DBI_try_query('SHOW VARIABLES LIKE \'local\\_infile\';'); + if ($result != false && PMA_DBI_num_rows($result) > 0) { + $tmp = PMA_DBI_fetch_row($result); + if ($tmp[1] == 'ON') { + $GLOBALS['cfg']['Import']['ldi_local_option'] = true; + } + } + PMA_DBI_free_result($result); + unset($result); + } + + $generalOptions = parent::setProperties(); + $this->properties->setText('CSV using LOAD DATA'); + $this->properties->setExtension('ldi'); + + $leaf = new TextPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Column names: ')); + $generalOptions->addProperty($leaf); + + $leaf = new BoolPropertyItem(); + $leaf->setName("ignore"); + $leaf->setText(__('Do not abort on INSERT error')); + $generalOptions->addProperty($leaf); + + $leaf = new BoolPropertyItem(); + $leaf->setName("local_option"); + $leaf->setText(__('Use LOCAL keyword')); + $generalOptions->addProperty($leaf); + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $finished, $error, $import_file, $compression, $charset_conversion, $table; + global $ldi_local_option, $ldi_replace, $ldi_ignore, $ldi_terminated, $ldi_enclosed, + $ldi_escaped, $ldi_new_line, $skip_queries, $ldi_columns; + + if ($import_file == 'none' + || $compression != 'none' + || $charset_conversion + ) { + // We handle only some kind of data! + $message = PMA_Message::error( + __('This plugin does not support compressed imports!') + ); + $error = true; + return; + } + + $sql = 'LOAD DATA'; + if (isset($ldi_local_option)) { + $sql .= ' LOCAL'; + } + $sql .= ' INFILE \'' . PMA_Util::sqlAddSlashes($import_file) . '\''; + if (isset($ldi_replace)) { + $sql .= ' REPLACE'; + } elseif (isset($ldi_ignore)) { + $sql .= ' IGNORE'; + } + $sql .= ' INTO TABLE ' . PMA_Util::backquote($table); + + if (strlen($ldi_terminated) > 0) { + $sql .= ' FIELDS TERMINATED BY \'' . $ldi_terminated . '\''; + } + if (strlen($ldi_enclosed) > 0) { + $sql .= ' ENCLOSED BY \'' + . PMA_Util::sqlAddSlashes($ldi_enclosed) . '\''; + } + if (strlen($ldi_escaped) > 0) { + $sql .= ' ESCAPED BY \'' + . PMA_Util::sqlAddSlashes($ldi_escaped) . '\''; + } + if (strlen($ldi_new_line) > 0) { + if ($ldi_new_line == 'auto') { + $ldi_new_line + = (PMA_Util::whichCrlf() == "\n") + ? '\n' + : '\r\n'; + } + $sql .= ' LINES TERMINATED BY \'' . $ldi_new_line . '\''; + } + if ($skip_queries > 0) { + $sql .= ' IGNORE ' . $skip_queries . ' LINES'; + $skip_queries = 0; + } + if (strlen($ldi_columns) > 0) { + $sql .= ' ('; + $tmp = preg_split('/,( ?)/', $ldi_columns); + $cnt_tmp = count($tmp); + for ($i = 0; $i < $cnt_tmp; $i++) { + if ($i > 0) { + $sql .= ', '; + } + /* Trim also `, if user already included backquoted fields */ + $sql .= PMA_Util::backquote( + trim($tmp[$i], " \t\r\n\0\x0B`") + ); + } // end for + $sql .= ')'; + } + + PMA_importRunQuery($sql, $sql); + PMA_importRunQuery(); + $finished = true; + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php b/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php new file mode 100644 index 000000000..767c966c1 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportMediawiki.class.php @@ -0,0 +1,573 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $this->_setAnalyze(false); + if ($GLOBALS['plugin_param'] !== 'table') { + $this->_setAnalyze(true); + } + + $props = 'libraries/properties/'; + include_once "$props/plugins/ImportPluginProperties.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText(__('MediaWiki Table')); + $importPluginProperties->setExtension('txt'); + $importPluginProperties->setMimeType('text/plain'); + $importPluginProperties->setOptions(array()); + $importPluginProperties->setOptionsText(__('Options')); + + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $error, $timeout_passed, $finished; + + // Defaults for parser + + // The buffer that will be used to store chunks read from the imported file + $buffer = ''; + + // Used as storage for the last part of the current chunk data + // Will be appended to the first line of the next chunk, if there is one + $last_chunk_line = ''; + + // Remembers whether the current buffer line is part of a comment + $inside_comment = false; + // Remembers whether the current buffer line is part of a data comment + $inside_data_comment = false; + // Remembers whether the current buffer line is part of a structure comment + $inside_structure_comment = false; + + // MediaWiki only accepts "\n" as row terminator + $mediawiki_new_line = "\n"; + + // Initialize the name of the current table + $cur_table_name = ""; + + while (! $finished && ! $error && ! $timeout_passed ) { + $data = PMA_importGetNextChunk(); + + if ($data === false) { + // Subtract data we didn't handle yet and stop processing + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + // Handle rest of buffer + } else { + // Append new data to buffer + $buffer = $data; + unset($data); + // Don't parse string if we're not at the end + // and don't have a new line inside + if ( strpos($buffer, $mediawiki_new_line) === false ) { + continue; + } + } + + // Because of reading chunk by chunk, the first line from the buffer + // contains only a portion of an actual line from the imported file. + // Therefore, we have to append it to the last line from the previous + // chunk. If we are at the first chunk, $last_chunk_line should be empty. + $buffer = $last_chunk_line . $buffer; + + // Process the buffer line by line + $buffer_lines = explode($mediawiki_new_line, $buffer); + + $full_buffer_lines_count = count($buffer_lines); + // If the reading is not finalised, the final line of the current chunk + // will not be complete + if (! $finished) { + $full_buffer_lines_count -= 1; + $last_chunk_line = $buffer_lines[$full_buffer_lines_count]; + } + + for ($line_nr = 0; $line_nr < $full_buffer_lines_count; ++ $line_nr) { + $cur_buffer_line = trim($buffer_lines[$line_nr]); + + // If the line is empty, go to the next one + if ( $cur_buffer_line === '' ) { + continue; + } + + $first_character = $cur_buffer_line[0]; + $matches = array(); + + // Check beginnning of comment + if (! strcmp(substr($cur_buffer_line, 0, 4), "")) { + // Only data comments are closed. The structure comments + // will be closed when a data comment begins (in order to + // skip structure tables) + if ($inside_data_comment) { + $inside_data_comment = false; + } + + // End comments that are not related to table structure + if (! $inside_structure_comment) { + $inside_comment = false; + } + } else { + // Check table name + $match_table_name = array(); + if (preg_match( + "/^Table data for `(.*)`$/", + $cur_buffer_line, + $match_table_name + ) + ) { + $cur_table_name = $match_table_name[1]; + $inside_data_comment = true; + + // End ignoring structure rows + if ($inside_structure_comment) { + $inside_structure_comment = false; + } + } elseif (preg_match( + "/^Table structure for `(.*)`$/", + $cur_buffer_line, + $match_table_name + ) + ) { + // The structure comments will be ignored + $inside_structure_comment = true; + } + } + continue; + } elseif (preg_match('/^\{\|(.*)$/', $cur_buffer_line, $matches)) { + // Check start of table + + // This will store all the column info on all rows from + // the current table read from the buffer + $cur_temp_table = array(); + + // Will be used as storage for the current row in the buffer + // Once all its columns are read, it will be added to + // $cur_temp_table and then it will be emptied + $cur_temp_line = array(); + + // Helps us differentiate the header columns + // from the normal columns + $in_table_header = false; + // End processing because the current line does not + // contain any column information + } elseif (substr($cur_buffer_line, 0, 2) === '|-' + || substr($cur_buffer_line, 0, 2) === '|+' + || substr($cur_buffer_line, 0, 2) === '|}' + ) { + // Check begin row or end table + + // Add current line to the values storage + if (! empty($cur_temp_line)) { + // If the current line contains header cells + // ( marked with '!' ), + // it will be marked as table header + if ( $in_table_header ) { + // Set the header columns + $cur_temp_table_headers = $cur_temp_line; + } else { + // Normal line, add it to the table + $cur_temp_table [] = $cur_temp_line; + } + } + + // Empty the temporary buffer + $cur_temp_line = array(); + + // No more processing required at the end of the table + if (substr($cur_buffer_line, 0, 2) === '|}') { + $current_table = array( + $cur_table_name, + $cur_temp_table_headers, + $cur_temp_table + ); + + // Import the current table data into the database + $this->_importDataOneTable($current_table); + + // Reset table name + $cur_table_name = ""; + } + // What's after the row tag is now only attributes + + } elseif (($first_character === '|') || ($first_character === '!')) { + // Check cell elements + + // Header cells + if ($first_character === '!') { + // Mark as table header, but treat as normal row + $cur_buffer_line = str_replace('!!', '||', $cur_buffer_line); + // Will be used to set $cur_temp_line as table header + $in_table_header = true; + } else { + $in_table_header = false; + } + + // Loop through each table cell + $cells = $this->_explodeMarkup($cur_buffer_line); + foreach ($cells as $cell) { + // A cell could contain both parameters and data + $cell_data = explode('|', $cell, 2); + + // A '|' inside an invalid link should not + // be mistaken as delimiting cell parameters + if (strpos($cell_data[0], '[[') === true ) { + if (count($cell_data) == 1) { + $cell = $cell_data[0]; + } else { + $cell = $cell_data[1]; + } + } + + // Delete the beginning of the column, if there is one + $cell = trim($cell); + $col_start_chars = array( "|", "!"); + foreach ($col_start_chars as $col_start_char) { + if (strpos($cell, $col_start_char) === 0) { + $cell = trim(substr($cell, 1)); + } + } + + // Add the cell to the row + $cur_temp_line [] = $cell; + } // foreach $cells + } else { + // If it's none of the above, then the current line has a bad + // format + $message = PMA_Message::error( + __('Invalid format of mediawiki input on line:
      %s.') + ); + $message->addParam($cur_buffer_line); + $error = true; + } + } // End treating full buffer lines + } // while - finished parsing buffer + } + + /** + * Imports data from a single table + * + * @param array $table containing all table info: + * + * $table[0] - string containing table name + * $table[1] - array[] of table headers + * $table[2] - array[][] of table content rows + * + * + * @global bool $analyze whether to scan for column types + * + * @return void + */ + private function _importDataOneTable ($table) + { + $analyze = $this->_getAnalyze(); + if ($analyze) { + // Set the table name + $this->_setTableName($table[0]); + + // Set generic names for table headers if they don't exist + $this->_setTableHeaders($table[1], $table[2][0]); + + // Create the tables array to be used in PMA_buildSQL() + $tables = array(); + $tables [] = array($table[0], $table[1], $table[2]); + + // Obtain the best-fit MySQL types for each column + $analyses = array(); + $analyses [] = PMA_analyzeTable($tables[0]); + + $this->_executeImportTables($tables, $analyses); + } + + // Commit any possible data in buffers + PMA_importRunQuery(); + } + + /** + * Sets the table name + * + * @param string &$table_name reference to the name of the table + * + * @return void + */ + private function _setTableName(&$table_name) + { + if (empty($table_name)) { + $result = PMA_DBI_fetch_result('SHOW TABLES'); + // todo check if the name below already exists + $table_name = 'TABLE '.(count($result) + 1); + } + } + + /** + * Set generic names for table headers, if they don't exist + * + * @param array &$table_headers reference to the array containing the headers + * of a table + * @param array $table_row array containing the first content row + * + * @return void + */ + private function _setTableHeaders(&$table_headers, $table_row) + { + if (empty($table_headers)) { + // The first table row should contain the number of columns + // If they are not set, generic names will be given (COL 1, COL 2, etc) + $num_cols = count($table_row); + for ($i = 0; $i < $num_cols; ++ $i) { + $table_headers [$i] = 'COL '. ($i + 1); + } + } + } + + /** + * Sets the database name and additional options and calls PMA_buildSQL() + * Used in PMA_importDataAllTables() and $this->_importDataOneTable() + * + * @param array &$tables structure: + * array( + * array(table_name, array() column_names, array()() rows) + * ) + * @param array &$analyses structure: + * $analyses = array( + * array(array() column_types, array() column_sizes) + * ) + * + * @global string $db name of the database to import in + * + * @return void + */ + private function _executeImportTables(&$tables, &$analyses) + { + global $db; + + // $db_name : The currently selected database name, if applicable + // No backquotes + // $options : An associative array of options + if (strlen($db)) { + $db_name = $db; + $options = array('create_db' => false); + } else { + $db_name = 'mediawiki_DB'; + $options = null; + } + + // Array of SQL strings + // Non-applicable parameters + $create = null; + + // Create and execute necessary SQL statements from data + PMA_buildSQL($db_name, $tables, $analyses, $create, $options); + + unset($tables); + unset($analyses); + } + + + /** + * Replaces all instances of the '||' separator between delimiters + * in a given string + * + * @param string $start_delim start delimiter + * @param string $end_delim end delimiter + * @param string $replace the string to be replaced with + * @param string $subject the text to be replaced + * + * @return string with replacements + */ + private function _delimiterReplace($start_delim, $end_delim, $replace, $subject) + { + // String that will be returned + $cleaned = ""; + // Possible states of current character + $inside_tag = false; + $inside_attribute = false; + // Attributes can be declared with either " or ' + $start_attribute_character = false; + + // The full separator is "||"; + // This rembembers if the previous character was '|' + $partial_separator = false; + + // Parse text char by char + for ($i = 0; $i < strlen($subject); $i ++) { + $cur_char = $subject[$i]; + // Check for separators + if ($cur_char == '|') { + // If we're not inside a tag, then this is part of a real separator, + // so we append it to the current segment + if (! $inside_attribute) { + $cleaned .= $cur_char; + if ($partial_separator) { + $inside_tag = false; + $inside_attribute = false; + } + } elseif ($partial_separator) { + // If we are inside a tag, we replace the current char with + // the placeholder and append that to the current segment + $cleaned .= $replace; + } + + // If the previous character was also '|', then this ends a + // full separator. If not, this may be the beginning of one + $partial_separator = ! $partial_separator; + } else { + // If we're inside a tag attribute and the current character is + // not '|', but the previous one was, it means that the single '|' + // was not appended, so we append it now + if ($partial_separator && $inside_attribute) { + $cleaned .= "|"; + } + // If the char is different from "|", no separator can be formed + $partial_separator = false; + + // any other character should be appended to the current segment + $cleaned .= $cur_char; + + if ($cur_char == '<' && ! $inside_attribute) { + // start of a tag + $inside_tag = true; + } elseif ($cur_char == '>' && ! $inside_attribute) { + // end of a tag + $inside_tag = false; + } elseif (($cur_char == '"' || $cur_char == "'") && $inside_tag) { + // start or end of an attribute + if (! $inside_attribute) { + $inside_attribute = true; + // remember the attribute`s declaration character (" or ') + $start_attribute_character = $cur_char; + } else { + if ($cur_char == $start_attribute_character) { + $inside_attribute = false; + // unset attribute declaration character + $start_attribute_character = false; + } + } + } + } + } // end for each character in $subject + + return $cleaned; + } + + /** + * Separates a string into items, similarly to explode + * Uses the '||' separator (which is standard in the mediawiki format) + * and ignores any instances of it inside markup tags + * Used in parsing buffer lines containing data cells + * + * @param string $text text to be split + * + * @return array + */ + private function _explodeMarkup($text) + { + $separator = "||"; + $placeholder = "\x00"; + + // Remove placeholder instances + $text = str_replace($placeholder, '', $text); + + // Replace instances of the separator inside HTML-like + // tags with the placeholder + $cleaned = $this->_delimiterReplace("<", ">", $placeholder, $text); + // Explode, then put the replaced separators back in + $items = explode($separator, $cleaned); + foreach ($items as $i => $str) { + $items[$i] = str_replace($placeholder, $separator, $str); + } + + return $items; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Returns true if the table should be analyzed, false otherwise + * + * @return bool + */ + private function _getAnalyze() + { + return $this->_analyze; + } + + /** + * Sets to true if the table should be analyzed, false otherwise + * + * @param bool $analyze status + * + * @return void + */ + private function _setAnalyze($analyze) + { + $this->_analyze = $analyze; + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ImportOds.class.php b/phpmyadmin/libraries/plugins/import/ImportOds.class.php new file mode 100644 index 000000000..5a681e97a --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportOds.class.php @@ -0,0 +1,415 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ImportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText('OpenDocument Spreadsheet'); + $importPluginProperties->setExtension('ods'); + $importPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $importPluginProperties + // this will be shown as "Format specific options" + $importSpecificOptions = new OptionsPropertyRootGroup(); + $importSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("col_names"); + $leaf->setText( + __( + 'The first line of the file contains the table column names' + . ' (if this is unchecked, the first line will become part' + . ' of the data)' + ) + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("empty_rows"); + $leaf->setText(__('Do not import empty rows')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("recognize_percentages"); + $leaf->setText( + __( + 'Import percentages as proper decimals (ex. 12.00% to .12)' + ) + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("recognize_currency"); + $leaf->setText(__('Import currencies (ex. $5.00 to 5.00)')); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $importSpecificOptions->addProperty($generalOptions); + + // set the options for the import plugin property item + $importPluginProperties->setOptions($importSpecificOptions); + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $db, $error, $timeout_passed, $finished; + + $i = 0; + $len = 0; + $buffer = ""; + + /** + * Read in the file via PMA_importGetNextChunk so that + * it can process compressed files + */ + while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) { + $data = PMA_importGetNextChunk(); + if ($data === false) { + /* subtract data we didn't handle yet and stop processing */ + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + /* Handle rest of buffer */ + } else { + /* Append new data to buffer */ + $buffer .= $data; + unset($data); + } + } + + unset($data); + + /** + * Disable loading of external XML entities. + */ + libxml_disable_entity_loader(); + + /** + * Load the XML string + * + * The option LIBXML_COMPACT is specified because it can + * result in increased performance without the need to + * alter the code in any way. It's basically a freebee. + */ + $xml = simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT); + + unset($buffer); + + if ($xml === false) { + $sheets = array(); + $message = PMA_Message::error( + __( + 'The XML file specified was either malformed or incomplete.' + . ' Please correct the issue and try again.' + ) + ); + $error = true; + } else { + $root = $xml->children('office', true)->{'body'}->{'spreadsheet'}; + if (empty($root)) { + $sheets = array(); + $message = PMA_Message::error( + __('Could not parse OpenDocument Spreasheet!') + ); + $error = true; + } else { + $sheets = $root->children('table', true); + } + } + + $tables = array(); + + $max_cols = 0; + + $row_count = 0; + $col_count = 0; + $col_names = array(); + + $tempRow = array(); + $tempRows = array(); + $rows = array(); + + /* Iterate over tables */ + foreach ($sheets as $sheet) { + $col_names_in_first_row = isset($_REQUEST['ods_col_names']); + + /* Iterate over rows */ + foreach ($sheet as $row) { + $type = $row->getName(); + if (! strcmp('table-row', $type)) { + /* Iterate over columns */ + foreach ($row as $cell) { + $text = $cell->children('text', true); + $cell_attrs = $cell->attributes('office', true); + + if (count($text) != 0) { + $attr = $cell->attributes('table', true); + $num_repeat = (int) $attr['number-columns-repeated']; + $num_iterations = $num_repeat ? $num_repeat : 1; + + for ($k = 0; $k < $num_iterations; $k++) { + if ($_REQUEST['ods_recognize_percentages'] + && ! strcmp( + 'percentage', + $cell_attrs['value-type'] + ) + ) { + $value = (double)$cell_attrs['value']; + } elseif ($_REQUEST['ods_recognize_currency'] + && !strcmp('currency', $cell_attrs['value-type']) + ) { + $value = (double)$cell_attrs['value']; + } else { + /* We need to concatenate all paragraphs */ + $values = array(); + foreach ($text as $paragraph) { + $values[] = (string)$paragraph; + } + $value = implode("\n", $values); + } + if (! $col_names_in_first_row) { + $tempRow[] = $value; + } else { + $col_names[] = $value; + } + + ++$col_count; + } + } else { + /* Number of blank columns repeated */ + if ($col_count < count($row->children('table', true)) - 1 + ) { + $attr = $cell->attributes('table', true); + $num_null = (int)$attr['number-columns-repeated']; + + if ($num_null) { + if (! $col_names_in_first_row) { + for ($i = 0; $i < $num_null; ++$i) { + $tempRow[] = 'NULL'; + ++$col_count; + } + } else { + for ($i = 0; $i < $num_null; ++$i) { + $col_names[] = PMA_getColumnAlphaName( + $col_count + 1 + ); + ++$col_count; + } + } + } else { + if (! $col_names_in_first_row) { + $tempRow[] = 'NULL'; + } else { + $col_names[] = PMA_getColumnAlphaName( + $col_count + 1 + ); + } + + ++$col_count; + } + } + } + } + + /* Find the widest row */ + if ($col_count > $max_cols) { + $max_cols = $col_count; + } + + /* Don't include a row that is full of NULL values */ + if (! $col_names_in_first_row) { + if ($_REQUEST['ods_empty_rows']) { + foreach ($tempRow as $cell) { + if (strcmp('NULL', $cell)) { + $tempRows[] = $tempRow; + break; + } + } + } else { + $tempRows[] = $tempRow; + } + } + + $col_count = 0; + $col_names_in_first_row = false; + $tempRow = array(); + } + } + + /* Skip over empty sheets */ + if (count($tempRows) == 0 || count($tempRows[0]) == 0) { + $col_names = array(); + $tempRow = array(); + $tempRows = array(); + continue; + } + + /** + * Fill out each row as necessary to make + * every one exactly as wide as the widest + * row. This included column names. + */ + + /* Fill out column names */ + for ($i = count($col_names); $i < $max_cols; ++$i) { + $col_names[] = PMA_getColumnAlphaName($i + 1); + } + + /* Fill out all rows */ + $num_rows = count($tempRows); + for ($i = 0; $i < $num_rows; ++$i) { + for ($j = count($tempRows[$i]); $j < $max_cols; ++$j) { + $tempRows[$i][] = 'NULL'; + } + } + + /* Store the table name so we know where to place the row set */ + $tbl_attr = $sheet->attributes('table', true); + $tables[] = array((string)$tbl_attr['name']); + + /* Store the current sheet in the accumulator */ + $rows[] = array((string)$tbl_attr['name'], $col_names, $tempRows); + $tempRows = array(); + $col_names = array(); + $max_cols = 0; + } + + unset($tempRow); + unset($tempRows); + unset($col_names); + unset($sheets); + unset($xml); + + /** + * Bring accumulated rows into the corresponding table + */ + $num_tbls = count($tables); + for ($i = 0; $i < $num_tbls; ++$i) { + for ($j = 0; $j < count($rows); ++$j) { + if (! strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) { + if (! isset($tables[$i][COL_NAMES])) { + $tables[$i][] = $rows[$j][COL_NAMES]; + } + + $tables[$i][ROWS] = $rows[$j][ROWS]; + } + } + } + + /* No longer needed */ + unset($rows); + + /* Obtain the best-fit MySQL types for each column */ + $analyses = array(); + + $len = count($tables); + for ($i = 0; $i < $len; ++$i) { + $analyses[] = PMA_analyzeTable($tables[$i]); + } + + /** + * string $db_name (no backquotes) + * + * array $table = array(table_name, array() column_names, array()() rows) + * array $tables = array of "$table"s + * + * array $analysis = array(array() column_types, array() column_sizes) + * array $analyses = array of "$analysis"s + * + * array $create = array of SQL strings + * + * array $options = an associative array of options + */ + + /* Set database name to the currently selected one, if applicable */ + if (strlen($db)) { + $db_name = $db; + $options = array('create_db' => false); + } else { + $db_name = 'ODS_DB'; + $options = null; + } + + /* Non-applicable parameters */ + $create = null; + + /* Created and execute necessary SQL statements from data */ + PMA_buildSQL($db_name, $tables, $analyses, $create, $options); + + unset($tables); + unset($analyses); + + /* Commit any possible data in buffers */ + PMA_importRunQuery(); + } +} diff --git a/phpmyadmin/libraries/plugins/import/ImportShp.class.php b/phpmyadmin/libraries/plugins/import/ImportShp.class.php new file mode 100644 index 000000000..39af95403 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportShp.class.php @@ -0,0 +1,342 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ImportPluginProperties.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText(__('ESRI Shape File')); + $importPluginProperties->setExtension('shp'); + $importPluginProperties->setOptions(array()); + $importPluginProperties->setOptionsText(__('Options')); + + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $db, $error, $finished, $compression, + $import_file, $local_import_file; + + if ((int) ini_get('memory_limit') < 512) { + @ini_set('memory_limit', '512M'); + } + @set_time_limit(300); + + $GLOBALS['finished'] = false; + $buffer = ''; + $eof = false; + + + $shp = new PMA_ShapeFile(1); + // If the zip archive has more than one file, + // get the correct content to the buffer from .shp file. + if ($compression == 'application/zip' + && PMA_getNoOfFilesInZip($import_file) > 1 + ) { + $zip_content = PMA_getZipContents($import_file, '/^.*\.shp$/i'); + $GLOBALS['import_text'] = $zip_content['data']; + } + + $temp_dbf_file = false; + // We need dbase extension to handle .dbf file + if (extension_loaded('dbase')) { + // If we can extract the zip archive to 'TempDir' + // and use the files in it for import + if ($compression == 'application/zip' + && ! empty($GLOBALS['cfg']['TempDir']) + && is_writable($GLOBALS['cfg']['TempDir']) + ) { + $dbf_file_name = PMA_findFileFromZipArchive( + '/^.*\.dbf$/i', $import_file + ); + // If the corresponding .dbf file is in the zip archive + if ($dbf_file_name) { + // Extract the .dbf file and point to it. + $extracted = PMA_zipExtract( + $import_file, + realpath($GLOBALS['cfg']['TempDir']), + array($dbf_file_name) + ); + if ($extracted) { + $dbf_file_path = realpath($GLOBALS['cfg']['TempDir']) + . (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name; + $temp_dbf_file = true; + // Replace the .dbf with .*, as required + // by the bsShapeFiles library. + $file_name = substr( + $dbf_file_path, 0, strlen($dbf_file_path) - 4 + ) . '.*'; + $shp->FileName = $file_name; + } + } + } elseif (! empty($local_import_file) + && ! empty($GLOBALS['cfg']['UploadDir']) + && $compression == 'none' + ) { + // If file is in UploadDir, use .dbf file in the same UploadDir + // to load extra data. + // Replace the .shp with .*, + // so the bsShapeFiles library correctly locates .dbf file. + $file_name = substr($import_file, 0, strlen($import_file) - 4) + . '.*'; + $shp->FileName = $file_name; + } + } + + // Load data + $shp->loadFromFile(''); + if ($shp->lastError != "") { + $error = true; + $message = PMA_Message::error( + __('There was an error importing the ESRI shape file: "%s".') + ); + $message->addParam($shp->lastError); + return; + } + + // Delete the .dbf file extracted to 'TempDir' + if ($temp_dbf_file + && isset($dbf_file_path) + && file_exists($dbf_file_path) + ) { + unlink($dbf_file_path); + } + + $esri_types = array( + 0 => 'Null Shape', + 1 => 'Point', + 3 => 'PolyLine', + 5 => 'Polygon', + 8 => 'MultiPoint', + 11 => 'PointZ', + 13 => 'PolyLineZ', + 15 => 'PolygonZ', + 18 => 'MultiPointZ', + 21 => 'PointM', + 23 => 'PolyLineM', + 25 => 'PolygonM', + 28 => 'MultiPointM', + 31 => 'MultiPatch', + ); + + switch ($shp->shapeType) { + // ESRI Null Shape + case 0: + break; + // ESRI Point + case 1: + $gis_type = 'point'; + break; + // ESRI PolyLine + case 3: + $gis_type = 'multilinestring'; + break; + // ESRI Polygon + case 5: + $gis_type = 'multipolygon'; + break; + // ESRI MultiPoint + case 8: + $gis_type = 'multipoint'; + break; + default: + $error = true; + if (! isset($esri_types[$shp->shapeType])) { + $message = PMA_Message::error( + __( + 'You tried to import an invalid file or the imported file' + . ' contains invalid data' + ) + ); + } else { + $message = PMA_Message::error( + __('MySQL Spatial Extension does not support ESRI type "%s".') + ); + $message->addParam($param); + } + return; + } + + if (isset($gis_type)) { + include_once './libraries/gis/pma_gis_factory.php'; + $gis_obj = PMA_GIS_Factory::factory($gis_type); + } else { + $gis_obj = null; + } + + $num_rows = count($shp->records); + // If .dbf file is loaded, the number of extra data columns + $num_data_cols = isset($shp->DBFHeader) ? count($shp->DBFHeader) : 0; + + $rows = array(); + $col_names = array(); + if ($num_rows != 0) { + foreach ($shp->records as $record) { + $tempRow = array(); + if ($gis_obj == null) { + $tempRow[] = null; + } else { + $tempRow[] = "GeomFromText('" + . $gis_obj->getShape($record->SHPData) . "')"; + } + + if (isset($shp->DBFHeader)) { + foreach ($shp->DBFHeader as $c) { + $cell = trim($record->DBFData[$c[0]]); + + if (! strcmp($cell, '')) { + $cell = 'NULL'; + } + + $tempRow[] = $cell; + } + } + $rows[] = $tempRow; + } + } + + if (count($rows) == 0) { + $error = true; + $message = PMA_Message::error( + __('The imported file does not contain any data') + ); + return; + } + + // Column names for spatial column and the rest of the columns, + // if they are available + $col_names[] = 'SPATIAL'; + for ($n = 0; $n < $num_data_cols; $n++) { + $col_names[] = $shp->DBFHeader[$n][0]; + } + + // Set table name based on the number of tables + if (strlen($db)) { + $result = PMA_DBI_fetch_result('SHOW TABLES'); + $table_name = 'TABLE '.(count($result) + 1); + } else { + $table_name = 'TBL_NAME'; + } + $tables = array(array($table_name, $col_names, $rows)); + + // Use data from shape file to chose best-fit MySQL types for each column + $analyses = array(); + $analyses[] = PMA_analyzeTable($tables[0]); + + $table_no = 0; $spatial_col = 0; + $analyses[$table_no][TYPES][$spatial_col] = GEOMETRY; + $analyses[$table_no][FORMATTEDSQL][$spatial_col] = true; + + // Set database name to the currently selected one, if applicable + if (strlen($db)) { + $db_name = $db; + $options = array('create_db' => false); + } else { + $db_name = 'SHP_DB'; + $options = null; + } + + // Created and execute necessary SQL statements from data + $null_param = null; + PMA_buildSQL($db_name, $tables, $analyses, $null_param, $options); + + unset($tables); + unset($analyses); + + $finished = true; + $error = false; + + // Commit any possible data in buffers + PMA_importRunQuery(); + } + + /** + * Returns specified number of bytes from the buffer. + * Buffer automatically fetches next chunk of data when the buffer + * falls short. + * Sets $eof when $GLOBALS['finished'] is set and the buffer falls short. + * + * @param int $length number of bytes + * + * @return string + */ + public static function readFromBuffer($length) + { + global $buffer, $eof; + + if (strlen($buffer) < $length) { + if ($GLOBALS['finished']) { + $eof = true; + } else { + $buffer .= PMA_importGetNextChunk(); + } + } + $result = substr($buffer, 0, $length); + $buffer = substr($buffer, $length); + return $result; + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ImportSql.class.php b/phpmyadmin/libraries/plugins/import/ImportSql.class.php new file mode 100644 index 000000000..146485a23 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportSql.class.php @@ -0,0 +1,440 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ImportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText('SQL'); + $importPluginProperties->setExtension('sql'); + $importPluginProperties->setOptionsText(__('Options')); + + $compats = PMA_DBI_getCompatibilities(); + if (count($compats) > 0) { + $values = array(); + foreach ($compats as $val) { + $values[$val] = $val; + } + + // create the root group that will be the options field for + // $importPluginProperties + // this will be shown as "Format specific options" + $importSpecificOptions = new OptionsPropertyRootGroup(); + $importSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new SelectPropertyItem(); + $leaf->setName("compatibility"); + $leaf->setText(__('SQL compatibility mode:')); + $leaf->setValues($values); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'Server_SQL_mode', + ) + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("no_auto_value_on_zero"); + $leaf->setText( + __('Do not use AUTO_INCREMENT for zero values') + ); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'Server_SQL_mode', + 'sqlmode_no_auto_value_on_zero' + ) + ); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $importSpecificOptions->addProperty($generalOptions); + // set the options for the import plugin property item + $importPluginProperties->setOptions($importSpecificOptions); + } + + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @param array &$sql_data 2-element array with sql data + * + * @return void + */ + public function doImport(&$sql_data = array()) + { + global $error, $timeout_passed; + + $buffer = ''; + // Defaults for parser + $sql = ''; + $start_pos = 0; + $i = 0; + $len= 0; + $big_value = 2147483647; + // include the space because it's mandatory + $delimiter_keyword = 'DELIMITER '; + $length_of_delimiter_keyword = strlen($delimiter_keyword); + + if (isset($_POST['sql_delimiter'])) { + $sql_delimiter = $_POST['sql_delimiter']; + } else { + $sql_delimiter = ';'; + } + + // Handle compatibility options + $sql_modes = array(); + if (isset($_REQUEST['sql_compatibility']) + && 'NONE' != $_REQUEST['sql_compatibility'] + ) { + $sql_modes[] = $_REQUEST['sql_compatibility']; + } + if (isset($_REQUEST['sql_no_auto_value_on_zero'])) { + $sql_modes[] = 'NO_AUTO_VALUE_ON_ZERO'; + } + if (count($sql_modes) > 0) { + PMA_DBI_try_query('SET SQL_MODE="' . implode(',', $sql_modes) . '"'); + } + unset($sql_modes); + + /** + * will be set in PMA_importGetNextChunk() + * + * @global boolean $GLOBALS['finished'] + */ + $GLOBALS['finished'] = false; + + while (! ($GLOBALS['finished'] && $i >= $len) + && ! $error + && ! $timeout_passed + ) { + $data = PMA_importGetNextChunk(); + if ($data === false) { + // subtract data we didn't handle yet and stop processing + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + // Handle rest of buffer + } else { + // Append new data to buffer + $buffer .= $data; + // free memory + unset($data); + // Do not parse string when we're not at the end + // and don't have ; inside + if ((strpos($buffer, $sql_delimiter, $i) === false) + && ! $GLOBALS['finished'] + ) { + continue; + } + } + // Current length of our buffer + $len = strlen($buffer); + + // Grab some SQL queries out of it + while ($i < $len) { + $found_delimiter = false; + // Find first interesting character + $old_i = $i; + // this is about 7 times faster that looking for each sequence i + // one by one with strpos() + $match = preg_match( + '/(\'|"|#|-- |\/\*|`|(?i)(? unclosed quote, + // but we handle it as end of query + if ($GLOBALS['finished']) { + $endq = true; + $i = $len - 1; + } + $found_delimiter = false; + break; + } + // Was not the quote escaped? + $j = $pos - 1; + while ($buffer[$j] == '\\') { + $j--; + } + // Even count means it was not escaped + $endq = (((($pos - 1) - $j) % 2) == 0); + // Skip the string + $i = $pos; + + if ($first_sql_delimiter < $pos) { + $found_delimiter = false; + } + } + if (! $endq) { + break; + } + $i++; + // Aren't we at the end? + if ($GLOBALS['finished'] && $i == $len) { + $i--; + } else { + continue; + } + } + + // Not enough data to decide + if ((($i == ($len - 1) && ($ch == '-' || $ch == '/')) + || ($i == ($len - 2) && (($ch == '-' && $buffer[$i + 1] == '-') + || ($ch == '/' && $buffer[$i + 1] == '*')))) + && ! $GLOBALS['finished'] + ) { + break; + } + + // Comments + if ($ch == '#' + || ($i < ($len - 1) && $ch == '-' && $buffer[$i + 1] == '-' + && (($i < ($len - 2) && $buffer[$i + 2] <= ' ') + || ($i == ($len - 1) && $GLOBALS['finished']))) + || ($i < ($len - 1) && $ch == '/' && $buffer[$i + 1] == '*') + ) { + // Copy current string to SQL + if ($start_pos != $i) { + $sql .= substr($buffer, $start_pos, $i - $start_pos); + } + // Skip the rest + $start_of_comment = $i; + // do not use PHP_EOL here instead of "\n", because the export + // file might have been produced on a different system + $i = strpos($buffer, $ch == '/' ? '*/' : "\n", $i); + // didn't we hit end of string? + if ($i === false) { + if ($GLOBALS['finished']) { + $i = $len - 1; + } else { + break; + } + } + // Skip * + if ($ch == '/') { + $i++; + } + // Skip last char + $i++; + // We need to send the comment part in case we are defining + // a procedure or function and comments in it are valuable + $sql .= substr( + $buffer, + $start_of_comment, + $i - $start_of_comment + ); + // Next query part will start here + $start_pos = $i; + // Aren't we at the end? + if ($i == $len) { + $i--; + } else { + continue; + } + } + // Change delimiter, if redefined, and skip it + // (don't send to server!) + if (($i + $length_of_delimiter_keyword < $len) + && strtoupper( + substr($buffer, $i, $length_of_delimiter_keyword) + ) == $delimiter_keyword + ) { + // look for EOL on the character immediately after 'DELIMITER ' + // (see previous comment about PHP_EOL) + $new_line_pos = strpos( + $buffer, + "\n", + $i + $length_of_delimiter_keyword + ); + // it might happen that there is no EOL + if (false === $new_line_pos) { + $new_line_pos = $len; + } + $sql_delimiter = substr( + $buffer, + $i + $length_of_delimiter_keyword, + $new_line_pos - $i - $length_of_delimiter_keyword + ); + $i = $new_line_pos + 1; + // Next query part will start here + $start_pos = $i; + continue; + } + + // End of SQL + if ($found_delimiter + || ($GLOBALS['finished'] + && ($i == $len - 1)) + ) { + $tmp_sql = $sql; + if ($start_pos < $len) { + $length_to_grab = $i - $start_pos; + + if (! $found_delimiter) { + $length_to_grab++; + } + $tmp_sql .= substr($buffer, $start_pos, $length_to_grab); + unset($length_to_grab); + } + // Do not try to execute empty SQL + if (! preg_match('/^([\s]*;)*$/', trim($tmp_sql))) { + $sql = $tmp_sql; + PMA_importRunQuery( + $sql, + substr($buffer, 0, $i + strlen($sql_delimiter)), + false, + $sql_data + ); + $buffer = substr($buffer, $i + strlen($sql_delimiter)); + // Reset parser: + $len = strlen($buffer); + $sql = ''; + $i = 0; + $start_pos = 0; + // Any chance we will get a complete query? + //if ((strpos($buffer, ';') === false) + //&& ! $GLOBALS['finished']) { + if (strpos($buffer, $sql_delimiter) === false + && ! $GLOBALS['finished'] + ) { + break; + } + } else { + $i++; + $start_pos = $i; + } + } + } // End of parser loop + } // End of import loop + // Commit any possible data in buffers + PMA_importRunQuery('', substr($buffer, 0, $len), false, $sql_data); + PMA_importRunQuery('', '', false, $sql_data); + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ImportXml.class.php b/phpmyadmin/libraries/plugins/import/ImportXml.class.php new file mode 100644 index 000000000..9c0e99959 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ImportXml.class.php @@ -0,0 +1,379 @@ +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ImportPluginProperties.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText(__('XML')); + $importPluginProperties->setExtension('xml'); + $importPluginProperties->setMimeType('text/xml'); + $importPluginProperties->setOptions(array()); + $importPluginProperties->setOptionsText(__('Options')); + + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + global $error, $timeout_passed, $finished, $db; + + $i = 0; + $len = 0; + $buffer = ""; + + /** + * Read in the file via PMA_importGetNextChunk so that + * it can process compressed files + */ + while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) { + $data = PMA_importGetNextChunk(); + if ($data === false) { + /* subtract data we didn't handle yet and stop processing */ + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + /* Handle rest of buffer */ + } else { + /* Append new data to buffer */ + $buffer .= $data; + unset($data); + } + } + + unset($data); + + /** + * Disable loading of external XML entities. + */ + libxml_disable_entity_loader(); + + /** + * Load the XML string + * + * The option LIBXML_COMPACT is specified because it can + * result in increased performance without the need to + * alter the code in any way. It's basically a freebee. + */ + $xml = simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT); + + unset($buffer); + + /** + * The XML was malformed + */ + if ($xml === false) { + PMA_Message::error( + __( + 'The XML file specified was either malformed or incomplete.' + . ' Please correct the issue and try again.' + ) + )->display(); + unset($xml); + $GLOBALS['finished'] = false; + return; + } + + /** + * Table accumulator + */ + $tables = array(); + /** + * Row accumulator + */ + $rows = array(); + + /** + * Temp arrays + */ + $tempRow = array(); + $tempCells = array(); + + /** + * CREATE code included (by default: no) + */ + $struct_present = false; + + /** + * Analyze the data in each table + */ + $namespaces = $xml->getNameSpaces(true); + + /** + * Get the database name, collation and charset + */ + $db_attr = $xml->children($namespaces['pma']) + ->{'structure_schemas'}->{'database'}; + + if ($db_attr instanceof SimpleXMLElement) { + $db_attr = $db_attr->attributes(); + $db_name = (string)$db_attr['name']; + $collation = (string)$db_attr['collation']; + $charset = (string)$db_attr['charset']; + } else { + /** + * If the structure section is not present + * get the database name from the data section + */ + $db_attr = $xml->children()->attributes(); + $db_name = (string)$db_attr['name']; + $collation = null; + $charset = null; + } + + /** + * The XML was malformed + */ + if ($db_name === null) { + PMA_Message::error( + __( + 'The XML file specified was either malformed or incomplete.' + . ' Please correct the issue and try again.' + ) + )->display(); + unset($xml); + $GLOBALS['finished'] = false; + return; + } + + /** + * Retrieve the structure information + */ + if (isset($namespaces['pma'])) { + /** + * Get structures for all tables + */ + $struct = $xml->children($namespaces['pma']); + + $create = array(); + + foreach ($struct as $tier1 => $val1) { + foreach ($val1 as $tier2 => $val2) { + // Need to select the correct database for the creation of + // tables, views, triggers, etc. + /** + * @todo Generating a USE here blocks importing of a table + * into another database. + */ + $attrs = $val2->attributes(); + $create[] = "USE " + . PMA_Util::backquote( + $attrs["name"] + ); + + foreach ($val2 as $val3) { + /** + * Remove the extra cosmetic spacing + */ + $val3 = str_replace(" ", "", (string)$val3); + $create[] = $val3; + } + } + } + + $struct_present = true; + } + + /** + * Move down the XML tree to the actual data + */ + $xml = $xml->children()->children(); + + $data_present = false; + + /** + * Only attempt to analyze/collect data if there is data present + */ + if ($xml && @count($xml->children())) { + $data_present = true; + + /** + * Process all database content + */ + foreach ($xml as $k1 => $v1) { + $tbl_attr = $v1->attributes(); + + $isInTables = false; + for ($i = 0; $i < count($tables); ++$i) { + if (! strcmp($tables[$i][TBL_NAME], (string)$tbl_attr['name'])) { + $isInTables = true; + break; + } + } + + if ($isInTables == false) { + $tables[] = array((string)$tbl_attr['name']); + } + + foreach ($v1 as $k2 => $v2) { + $row_attr = $v2->attributes(); + if (! array_search((string)$row_attr['name'], $tempRow)) { + $tempRow[] = (string)$row_attr['name']; + } + $tempCells[] = (string)$v2; + } + + $rows[] = array((string)$tbl_attr['name'], $tempRow, $tempCells); + + $tempRow = array(); + $tempCells = array(); + } + + unset($tempRow); + unset($tempCells); + unset($xml); + + /** + * Bring accumulated rows into the corresponding table + */ + $num_tbls = count($tables); + for ($i = 0; $i < $num_tbls; ++$i) { + for ($j = 0; $j < count($rows); ++$j) { + if (! strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) { + if (! isset($tables[$i][COL_NAMES])) { + $tables[$i][] = $rows[$j][COL_NAMES]; + } + + $tables[$i][ROWS][] = $rows[$j][ROWS]; + } + } + } + + unset($rows); + + if (! $struct_present) { + $analyses = array(); + + $len = count($tables); + for ($i = 0; $i < $len; ++$i) { + $analyses[] = PMA_analyzeTable($tables[$i]); + } + } + } + + unset($xml); + unset($tempRows); + unset($tempCells); + unset($rows); + + /** + * Only build SQL from data if there is data present + */ + if ($data_present) { + /** + * Set values to NULL if they were not present + * to maintain PMA_buildSQL() call integrity + */ + if (! isset($analyses)) { + $analyses = null; + if (! $struct_present) { + $create = null; + } + } + } + + /** + * string $db_name (no backquotes) + * + * array $table = array(table_name, array() column_names, array()() rows) + * array $tables = array of "$table"s + * + * array $analysis = array(array() column_types, array() column_sizes) + * array $analyses = array of "$analysis"s + * + * array $create = array of SQL strings + * + * array $options = an associative array of options + */ + + /* Set database name to the currently selected one, if applicable */ + if (strlen($db)) { + /* Override the database name in the XML file, if one is selected */ + $db_name = $db; + $options = array('create_db' => false); + } else { + if ($db_name === null) { + $db_name = 'XML_DB'; + } + + /* Set database collation/charset */ + $options = array( + 'db_collation' => $collation, + 'db_charset' => $charset, + ); + } + + /* Created and execute necessary SQL statements from data */ + PMA_buildSQL($db_name, $tables, $analyses, $create, $options); + + unset($analyses); + unset($tables); + unset($create); + + /* Commit any possible data in buffers */ + PMA_importRunQuery(); + } +} \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/README b/phpmyadmin/libraries/plugins/import/README new file mode 100644 index 000000000..76d2b07cc --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/README @@ -0,0 +1,173 @@ +This directory holds import plugins for phpMyAdmin. Any new plugin should +basically follow the structure presented here. Official plugins need to +have str* messages with their definition in language files, but if you build +some plugins for your use, you can directly use texts in plugin. + +setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + // set properties + $props = 'libraries/properties/'; + // include the main class for properties for the import plug-ins + include_once "$props/plugins/ImportPluginProperties.class.php"; + // include the group properties classes + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + // include the needed single property items + include_once "$props/options/items/RadioPropertyItem.class.php"; + + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText('[name]'); // the name of your plug-in + $importPluginProperties->setExtension('[ext]'); // extension this plug-in can handle + $importPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $importPluginProperties + // this will be shown as "Format specific options" + $importSpecificOptions = new OptionsPropertyRootGroup(); + $importSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // optional : + // create primary items and add them to the group + // type - one of the classes listed in libraries/properties/options/items/ + // name - form element name + // text - description in GUI + // size - size of text element + // len - maximal size of input + // values - possible values of the item + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $importSpecificOptions->addProperty($generalOptions); + + // set the options for the import plugin property item + $importPluginProperties->setOptions($importSpecificOptions); + $this->properties = $importPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Handles the whole import logic + * + * @return void + */ + public function doImport() + { + // get globals (others are optional) + global $error, $timeout_passed, $finished; + + $buffer = ''; + while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) { + $data = PMA_importGetNextChunk(); + if ($data === false) { + // subtract data we didn't handle yet and stop processing + $offset -= strlen($buffer); + break; + } elseif ($data === true) { + // Handle rest of buffer + } else { + // Append new data to buffer + $buffer .= $data; + } + // PARSE $buffer here, post sql queries using: + PMA_importRunQuery($sql, $verbose_sql_with_comments); + } // End of import loop + // Commit any possible data in buffers + PMA_importRunQuery(); + } + + + // optional: + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Getter description + * + * @return type + */ + private function _getMyOptionalVariable() + { + return $this->_myOptionalVariable; + } + + /** + * Setter description + * + * @param type $my_optional_variable description + * + * @return void + */ + private function _setMyOptionalVariable($my_optional_variable) + { + $this->_myOptionalVariable = $my_optional_variable; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/ShapeFile.class.php b/phpmyadmin/libraries/plugins/import/ShapeFile.class.php new file mode 100644 index 000000000..121bf124d --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ShapeFile.class.php @@ -0,0 +1,102 @@ +_loadHeaders(); + $this->_loadRecords(); + if ($this->_isDbaseLoaded()) { + $this->_closeDBFFile(); + } + } + + /** + * Loads metadata from the ESRI shape file header + * + * @return void + * @see ShapeFile::_loadHeaders() + */ + function _loadHeaders() + { + ImportShp::readFromBuffer(24); + $this->fileLength = loadData("N", ImportShp::readFromBuffer(4)); + + ImportShp::readFromBuffer(4); + $this->shapeType = loadData("V", ImportShp::readFromBuffer(4)); + + $this->boundingBox = array(); + $this->boundingBox["xmin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->boundingBox["ymin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->boundingBox["xmax"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->boundingBox["ymax"] = loadData("d", ImportShp::readFromBuffer(8)); + + if ($this->_isDbaseLoaded() && $this->_openDBFFile()) { + $this->DBFHeader = $this->_loadDBFHeader(); + } + } + + /** + * Loads geometry data from the ESRI shape file + * + * @return void + * @see ShapeFile::_loadRecords() + */ + function _loadRecords() + { + global $eof; + ImportShp::readFromBuffer(32); + while (true) { + $record = new PMA_ShapeRecord(-1); + $record->loadFromFile($this->SHPFile, $this->DBFFile); + if ($record->lastError != "") { + return false; + } + if ($eof) { + break; + } + + $this->records[] = $record; + } + } +} +?> diff --git a/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php b/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php new file mode 100644 index 000000000..efefd0c80 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/ShapeRecord.class.php @@ -0,0 +1,161 @@ +DBFFile = $DBFFile; + $this->_loadHeaders(); + + switch ($this->shapeType) { + case 0: + $this->_loadNullRecord(); + break; + case 1: + $this->_loadPointRecord(); + break; + case 3: + $this->_loadPolyLineRecord(); + break; + case 5: + $this->_loadPolygonRecord(); + break; + case 8: + $this->_loadMultiPointRecord(); + break; + default: + $this->setError( + sprintf( + __("Geometry type '%s' is not supported by MySQL."), + $this->shapeType + ) + ); + break; + } + if (extension_loaded('dbase') && isset($this->DBFFile)) { + $this->_loadDBFData(); + } + } + + /** + * Loads metadata from the ESRI shape record header + * + * @return void + * @see ShapeRecord::_loadHeaders() + */ + function _loadHeaders() + { + $this->recordNumber = loadData("N", ImportShp::readFromBuffer(4)); + ImportShp::readFromBuffer(4); + $this->shapeType = loadData("V", ImportShp::readFromBuffer(4)); + } + + /** + * Loads data from a point record + * + * @return void + * @see ShapeRecord::_loadPoint() + */ + function _loadPoint() + { + $data = array(); + + $data["x"] = loadData("d", ImportShp::readFromBuffer(8)); + $data["y"] = loadData("d", ImportShp::readFromBuffer(8)); + + return $data; + } + + /** + * Loads data from a multipoint record + * + * @return void + * @see ShapeRecord::_loadMultiPointRecord() + */ + function _loadMultiPointRecord() + { + $this->SHPData = array(); + $this->SHPData["xmin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["ymin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["xmax"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["ymax"] = loadData("d", ImportShp::readFromBuffer(8)); + + $this->SHPData["numpoints"] = loadData("V", ImportShp::readFromBuffer(4)); + + for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) { + $this->SHPData["points"][] = $this->_loadPoint(); + } + } + + /** + * Loads data from a polyline record + * + * @return void + * @see ShapeRecord::_loadPolyLineRecord() + */ + function _loadPolyLineRecord() + { + $this->SHPData = array(); + $this->SHPData["xmin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["ymin"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["xmax"] = loadData("d", ImportShp::readFromBuffer(8)); + $this->SHPData["ymax"] = loadData("d", ImportShp::readFromBuffer(8)); + + $this->SHPData["numparts"] = loadData("V", ImportShp::readFromBuffer(4)); + $this->SHPData["numpoints"] = loadData("V", ImportShp::readFromBuffer(4)); + + for ($i = 0; $i < $this->SHPData["numparts"]; $i++) { + $this->SHPData["parts"][$i] = loadData( + "V", ImportShp::readFromBuffer(4) + ); + } + + $readPoints = 0; + reset($this->SHPData["parts"]); + while (list($partIndex, $partData) = each($this->SHPData["parts"])) { + if (! isset($this->SHPData["parts"][$partIndex]["points"]) + || !is_array($this->SHPData["parts"][$partIndex]["points"]) + ) { + $this->SHPData["parts"][$partIndex] = array(); + $this->SHPData["parts"][$partIndex]["points"] = array(); + } + while (! in_array($readPoints, $this->SHPData["parts"]) + && ($readPoints < ($this->SHPData["numpoints"])) + ) { + $this->SHPData["parts"][$partIndex]["points"][] + = $this->_loadPoint(); + $readPoints++; + } + } + } +} +?> diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php new file mode 100644 index 000000000..881832fda --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/upload/UploadApc.class.php @@ -0,0 +1,84 @@ + $id, + 'finished' => false, + 'percent' => 0, + 'total' => 0, + 'complete' => 0, + 'plugin' => UploadApc::getIdKey() + ); + } + $ret = $_SESSION[$SESSION_KEY][$id]; + + if (! PMA_import_apcCheck() || $ret['finished']) { + return $ret; + } + $status = apc_fetch('upload_' . $id); + + if ($status) { + $ret['finished'] = (bool)$status['done']; + $ret['total'] = $status['total']; + $ret['complete'] = $status['current']; + + if ($ret['total'] > 0) { + $ret['percent'] = $ret['complete'] / $ret['total'] * 100; + } + + if ($ret['percent'] == 100) { + $ret['finished'] = (bool)true; + } + + $_SESSION[$SESSION_KEY][$id] = $ret; + } + + return $ret; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php new file mode 100644 index 000000000..90148ded4 --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/upload/UploadNoplugin.class.php @@ -0,0 +1,64 @@ + $id, + 'finished' => false, + 'percent' => 0, + 'total' => 0, + 'complete' => 0, + 'plugin' => UploadNoplugin::getIdKey() + ); + } + $ret = $_SESSION[$SESSION_KEY][$id]; + + return $ret; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php new file mode 100644 index 000000000..1a507763d --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/upload/UploadProgress.class.php @@ -0,0 +1,94 @@ + $id, + 'finished' => false, + 'percent' => 0, + 'total' => 0, + 'complete' => 0, + 'plugin' => UploadProgress::getIdKey() + ); + } + $ret = $_SESSION[$SESSION_KEY][$id]; + + if (! PMA_import_progressCheck() || $ret['finished']) { + return $ret; + } + + $status = uploadprogress_get_info($id); + + if ($status) { + if ($status['bytes_uploaded'] == $status['bytes_total']) { + $ret['finished'] = true; + } else { + $ret['finished'] = false; + } + $ret['total'] = $status['bytes_total']; + $ret['complete'] = $status['bytes_uploaded']; + + if ($ret['total'] > 0) { + $ret['percent'] = $ret['complete'] / $ret['total'] * 100; + } + } else { + $ret = array( + 'id' => $id, + 'finished' => true, + 'percent' => 100, + 'total' => $ret['total'], + 'complete' => $ret['total'], + 'plugin' => UploadProgress::getIdKey() + ); + } + + $_SESSION[$SESSION_KEY][$id] = $ret; + return $ret; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php b/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php new file mode 100644 index 000000000..36404133e --- /dev/null +++ b/phpmyadmin/libraries/plugins/import/upload/UploadSession.class.php @@ -0,0 +1,96 @@ + $id, + 'finished' => false, + 'percent' => 0, + 'total' => 0, + 'complete' => 0, + 'plugin' => UploadSession::getIdKey() + ); + } + $ret = $_SESSION[$SESSION_KEY][$id]; + + if (! PMA_import_sessionCheck() || $ret['finished']) { + return $ret; + } + + $status = false; + $sessionkey = ini_get('session.upload_progress.prefix') . $id; + + if (isset($_SESSION[$sessionkey])) { + $status = $_SESSION[$sessionkey]; + } + + if ($status) { + $ret['finished'] = $status['done']; + $ret['total'] = $status['content_length']; + $ret['complete'] = $status['bytes_processed']; + + if ($ret['total'] > 0) { + $ret['percent'] = $ret['complete'] / $ret['total'] * 100; + } + } else { + $ret = array( + 'id' => $id, + 'finished' => true, + 'percent' => 100, + 'total' => $ret['total'], + 'complete' => $ret['total'], + 'plugin' => UploadSession::getIdKey() + ); + } + + $_SESSION[$SESSION_KEY][$id] = $ret; + + return $ret; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php new file mode 100644 index 000000000..46bda7045 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Download.class.php @@ -0,0 +1,64 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php new file mode 100644 index 000000000..f876abbe3 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Application_Octetstream_Hex.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php new file mode 100644 index 000000000..934df75ea --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Inline.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php new file mode 100644 index 000000000..fc04040f2 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Image_JPEG_Link.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php b/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php new file mode 100644 index 000000000..e879c2374 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Image_PNG_Inline.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/README b/phpmyadmin/libraries/plugins/transformations/README new file mode 100644 index 000000000..7d7a1255d --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/README @@ -0,0 +1,4 @@ +TRANSFORMATION USAGE (Garvin Hicking, ) +==================== + +See the documentation for complete instructions on how to use transformation plugins. diff --git a/phpmyadmin/libraries/plugins/transformations/TEMPLATE b/phpmyadmin/libraries/plugins/transformations/TEMPLATE new file mode 100644 index 000000000..b0ce2f045 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/TEMPLATE @@ -0,0 +1,68 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT b/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT new file mode 100644 index 000000000..5cc1d26bd --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/TEMPLATE_ABSTRACT @@ -0,0 +1,89 @@ +mimetype contains the original MimeType of the field (i.e. 'text/plain', 'image/jpeg' etc.) + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the TransformationName of the specific plugin + * + * @return string + */ + public static function getName() + { + return "[TransformationName]"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php new file mode 100644 index 000000000..8a102cbfd --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Append.class.php @@ -0,0 +1,66 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php new file mode 100644 index 000000000..ed8c9e561 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Dateformat.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php new file mode 100644 index 000000000..1aa321a51 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_External.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php new file mode 100644 index 000000000..5c6b683e7 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Formatted.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php new file mode 100644 index 000000000..4cb180072 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Imagelink.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php new file mode 100644 index 000000000..1e642039b --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Link.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php new file mode 100644 index 000000000..44eea5070 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Longtoipv4.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php new file mode 100644 index 000000000..cc9249142 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Sql.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php new file mode 100644 index 000000000..b04231ff2 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/Text_Plain_Substring.class.php @@ -0,0 +1,65 @@ + diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php new file mode 100644 index 000000000..0fc3b4de7 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/AppendTransformationsPlugin.class.php @@ -0,0 +1,86 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php new file mode 100644 index 000000000..530379f10 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/DateFormatTransformationsPlugin.class.php @@ -0,0 +1,178 @@ +type == 'int') { + $timestamp = $buffer; + + // Detect TIMESTAMP(6 | 8 | 10 | 12 | 14) + // TIMESTAMP (2 | 4) not supported here. + // (Note: prior to MySQL 4.1, TIMESTAMP has a display size + // for example TIMESTAMP(8) means YYYYMMDD) + } else if (preg_match('/^(\d{2}){3,7}$/', $buffer)) { + + if (strlen($buffer) == 14 || strlen($buffer) == 8) { + $offset = 4; + } else { + $offset = 2; + } + + $d = array(); + $d['year'] = substr($buffer, 0, $offset); + $d['month'] = substr($buffer, $offset, 2); + $d['day'] = substr($buffer, $offset + 2, 2); + $d['hour'] = substr($buffer, $offset + 4, 2); + $d['minute'] = substr($buffer, $offset + 6, 2); + $d['second'] = substr($buffer, $offset + 8, 2); + + if (checkdate($d['month'], $d['day'], $d['year'])) { + $timestamp = mktime( + $d['hour'], + $d['minute'], + $d['second'], + $d['month'], + $d['day'], + $d['year'] + ); + } + // If all fails, assume one of the dozens of valid strtime() syntaxes + // (http://www.gnu.org/manual/tar-1.12/html_chapter/tar_7.html) + } else { + if (preg_match('/^[0-9]\d{1,9}$/', $buffer)) { + $timestamp = (int)$buffer; + } else { + $timestamp = strtotime($buffer); + } + } + + // If all above failed, maybe it's a Unix timestamp already? + if ($timestamp < 0 && preg_match('/^[1-9]\d{1,9}$/', $buffer)) { + $timestamp = $buffer; + } + + // Reformat a valid timestamp + if ($timestamp >= 0) { + $timestamp -= $options[0] * 60 * 60; + $source = $buffer; + if ($options[2] == 'local') { + $text = PMA_Util::localisedDate( + $timestamp, + $options[1] + ); + } elseif ($options[2] == 'utc') { + $text = gmdate($options[1], $timestamp); + } else { + $text = 'INVALID DATE TYPE'; + } + $buffer = '' . $text . ''; + } + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Date Format"; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php new file mode 100644 index 000000000..82eda40f7 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/DownloadTransformationsPlugin.class.php @@ -0,0 +1,110 @@ + $val) { + if ($val->name == $options[1]) { + $pos = $key; + break; + } + } + if (isset($pos)) { + $cn = $row[$pos]; + } + } + if (empty($cn)) { + $cn = 'binary_file.dat'; + } + } + + return sprintf( + '%s', + $options['wrapper_link'], + urlencode($cn), + htmlspecialchars($cn), + htmlspecialchars($cn) + ); + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Download"; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php new file mode 100644 index 000000000..f93f0695a --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/ExternalTransformationsPlugin.class.php @@ -0,0 +1,182 @@ += 4.3.0 + $newstring = ''; + $descriptorspec = array( + 0 => array("pipe", "r"), + 1 => array("pipe", "w") + ); + $process = proc_open($program . ' ' . $poptions, $descriptorspec, $pipes); + if (is_resource($process)) { + fwrite($pipes[0], $buffer); + fclose($pipes[0]); + + while (!feof($pipes[1])) { + $newstring .= fgets($pipes[1], 1024); + } + fclose($pipes[1]); + // we don't currently use the return value + proc_close($process); + } + + if ($options[2] == 1 || $options[2] == '2') { + $retstring = htmlspecialchars($newstring); + } else { + $retstring = $newstring; + } + + return $retstring; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "External"; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php new file mode 100644 index 000000000..e6bb8d9ba --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/FormattedTransformationsPlugin.class.php @@ -0,0 +1,80 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php new file mode 100644 index 000000000..8022da9e0 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/HexTransformationsPlugin.class.php @@ -0,0 +1,91 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php new file mode 100644 index 000000000..456f102bd --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/ImageLinkTransformationsPlugin.class.php @@ -0,0 +1,89 @@ + '[BLOB]' + ); + $buffer = PMA_transformation_global_html_replace( + $buffer, + $transform_options + ); + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Link"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php new file mode 100644 index 000000000..b1ef0ae45 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/InlineTransformationsPlugin.class.php @@ -0,0 +1,103 @@ + '[__BUFFER__]' + ); + } else { + $transform_options = array ( + 'string' => '[__BUFFER__]' + ); + } + $buffer = PMA_transformation_global_html_replace( + $buffer, + $transform_options + ); + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Inline"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php new file mode 100644 index 000000000..58dda957e --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/LongToIPv4TransformationsPlugin.class.php @@ -0,0 +1,83 @@ + 4294967295) { + return $buffer; + } + + return long2ip($buffer); + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Long To IPv4"; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php new file mode 100644 index 000000000..2123cdb3d --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/SQLTransformationsPlugin.class.php @@ -0,0 +1,81 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php new file mode 100644 index 000000000..2de48e6bb --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/SubstringTransformationsPlugin.class.php @@ -0,0 +1,116 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php new file mode 100644 index 000000000..054b2f9b8 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/TextImageLinkTransformationsPlugin.class.php @@ -0,0 +1,96 @@ + '' + . $buffer . '' + ); + + $buffer = PMA_transformation_global_html_replace( + $buffer, + $transform_options + ); + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Image Link"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php b/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php new file mode 100644 index 000000000..fdc33b29b --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/abstract/TextLinkTransformationsPlugin.class.php @@ -0,0 +1,98 @@ + '' . (isset($options[1]) ? $options[1] : $buffer) + . '' + ); + + $buffer = PMA_transformation_global_html_replace( + $buffer, + $transform_options + ); + + return $buffer; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @todo implement + * @return void + */ + public function update (SplSubject $subject) + { + ; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the transformation name of the specific plugin + * + * @return string + */ + public static function getName() + { + return "Link"; + } +} +?> diff --git a/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh b/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh new file mode 100755 index 000000000..05876671a --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/generator_main_class.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Shell script that creates only the main class for a new transformation +# plug-in, using a template +# +# $1: MIMEType +# $2: MIMESubtype +# $3: Transformation Name + +if [ $# != 3 ] +then + echo -e "Usage: ./generator_main_class.sh MIMEType MIMESubtype TransformationName\n" + exit 65 +fi + +./generator_plugin.sh "$1" "$2" "$3" "--generate_only_main_class" \ No newline at end of file diff --git a/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh b/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh new file mode 100755 index 000000000..225a2cb98 --- /dev/null +++ b/phpmyadmin/libraries/plugins/transformations/generator_plugin.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Shell script that creates a new transformation plug-in (both main and +# abstract class) using a template. +# +# The 'description' parameter will add a new entry in the language file. +# Watch out for special escaping. +# +# $1: MIMEType +# $2: MIMESubtype +# $3: Transformation Name +# $4: (optional) Description + +echo $# +if [ $# -ne 3 -a $# -ne 4 ]; then + echo -e "Usage: ./generator_plugin.sh MIMEType MIMESubtype TransformationName [Description]\n" + exit 65 +fi + +# make sure that the MIME Type, MIME Subtype and Transformation names +# are in the correct format + +# make all names lowercase +MT="`echo $1 | tr [:upper:] [:lower:]`" +MS="`echo $2 | tr [:upper:] [:lower:]`" +TN="`echo $3 | tr [:upper:] [:lower:]`" +# make first letter uppercase +MT="${MT^}" +MS="${MS^}" +TN="${TN^}" +# make the first letter after each underscore uppercase +MT="`echo $MT`" +MT="`echo $MT | sed -e 's/_./\U&\E/g'`" +MS="`echo $MS`" +MS="`echo $MS | sed -e 's/_./\U&\E/g'`" +TN="`echo $TN`" +TN="`echo $TN | sed -e 's/_./\U&\E/g'`" + +# define the name of the main class file and of its template +ClassFile=$MT\_$MS\_$TN.class.php +Template=TEMPLATE +# define the name of the abstract class file and its template +AbstractClassFile=abstract/"$TN"TransformationsPlugin.class.php +AbstractTemplate=TEMPLATE_ABSTRACT +# replace template names with argument names +sed "s/\[MIMEType]/$MT/; s/\[MIMESubtype\]/$MS/; s/\[TransformationName\]/$TN/;" < $Template > $ClassFile +echo "Created $ClassFile" + +GenerateAbstractClass=1 +if [ -n $4 ]; then + if [ "$4" == "--generate_only_main_class" ]; then + if [ -e $AbstractClassFile ]; then + GenerateAbstractClass=0 + fi + fi +fi + +if [ $GenerateAbstractClass -eq 1 ]; then + # replace template names with argument names + sed "s/\[TransformationName\]/$TN/; s/Description of the transformation./$4/;" < $AbstractTemplate > $AbstractClassFile + echo "Created $AbstractClassFile" +fi + +echo "" \ No newline at end of file diff --git a/phpmyadmin/libraries/pmd_common.php b/phpmyadmin/libraries/pmd_common.php new file mode 100644 index 000000000..5bf7c58bb --- /dev/null +++ b/phpmyadmin/libraries/pmd_common.php @@ -0,0 +1,262 @@ + internal ".$GLOBALS['db']." - ".$val[0]." - "; + //print_r($row); + if ($row !== false) { + foreach ($row as $field => $value) { + $con['C_NAME'][$i] = ''; + $con['DTN'][$i] = urlencode($GLOBALS['db'] . "." . $val[0]); + $con['DCN'][$i] = urlencode($field); + $con['STN'][$i] = urlencode( + $value['foreign_db'] . "." . $value['foreign_table'] + ); + $con['SCN'][$i] = urlencode($value['foreign_field']); + $i++; + } + } + $row = PMA_getForeigners($GLOBALS['db'], $val[0], '', 'foreign'); + //echo "
      INNO "; + //print_r($row); + if ($row !== false) { + foreach ($row as $field => $value) { + $con['C_NAME'][$i] = ''; + $con['DTN'][$i] = urlencode($GLOBALS['db'].".".$val[0]); + $con['DCN'][$i] = urlencode($field); + $con['STN'][$i] = urlencode( + $value['foreign_db'].".".$value['foreign_table'] + ); + $con['SCN'][$i] = urlencode($value['foreign_field']); + $i++; + } + } + } + + $ti = 0; + $retval = array(); + for ($i = 0, $cnt = count($con["C_NAME"]); $i < $cnt; $i++) { + $c_name_i = $con['C_NAME'][$i]; + $dtn_i = $con['DTN'][$i]; + $retval[$ti] = array(); + $retval[$ti][$c_name_i] = array(); + if (in_array($dtn_i, $GLOBALS['PMD_URL']["TABLE_NAME"]) + && in_array($con['STN'][$i], $GLOBALS['PMD_URL']["TABLE_NAME"]) + ) { + $retval[$ti][$c_name_i][$dtn_i] = array(); + $retval[$ti][$c_name_i][$dtn_i][$con['DCN'][$i]] = array( + 0 => $con['STN'][$i], + 1 => $con['SCN'][$i] + ); + } + $ti++; + } + return $retval; +} + +/** + * Returns UNIQUE and PRIMARY indices + * + * @return array unique or primary indices + */ +function get_pk_or_unique_keys() +{ + return get_all_keys(true); +} + +/** + * returns all indices + * + * @param bool $unique_only whether to include only unique ones + * + * @return array indices + */ +function get_all_keys($unique_only = false) +{ + include_once './libraries/Index.class.php'; + + $keys = array(); + + foreach ($GLOBALS['PMD']['TABLE_NAME_SMALL'] as $I => $table) { + $schema = $GLOBALS['PMD']['OWNER'][$I]; + // for now, take into account only the first index segment + foreach (PMA_Index::getFromTable($table, $schema) as $index) { + if ($unique_only && ! $index->isUnique()) { + continue; + } + $columns = $index->getColumns(); + foreach ($columns as $column_name => $dummy) { + $keys[$schema . '.' .$table . '.' . $column_name] = 1; + } + } + } + return $keys; +} + +/** + * Return script to create j_tab and h_tab arrays + * + * @return string + */ +function get_script_tabs() +{ + $script_tabs = 'var j_tabs = new Array();' . "\n" + . 'var h_tabs = new Array();' . "\n" ; + + $retval = array( + 'j_tabs' => array(), + 'h_tabs' => array() + ); + + for ($i = 0, $cnt = count($GLOBALS['PMD']['TABLE_NAME']); $i < $cnt; $i++) { + $j = 0; + if (PMA_Util::isForeignKeySupported($GLOBALS['PMD']['TABLE_TYPE'][$i])) { + $j = 1; + } + $retval['j_tabs'][$GLOBALS['PMD_URL']['TABLE_NAME'][$i]] = $j; + $retval['h_tabs'][$GLOBALS['PMD_URL']['TABLE_NAME'][$i]] = 1; + } + return $retval; +} + +/** + * Returns table position + * + * @return array table positions and sizes + */ +function get_tab_pos() +{ + $cfgRelation = PMA_getRelationsParam(); + + if (! $cfgRelation['designerwork']) { + return null; + } + + $query = " + SELECT CONCAT_WS('.', `db_name`, `table_name`) AS `name`, + `x` AS `X`, + `y` AS `Y`, + `v` AS `V`, + `h` AS `H` + FROM " . PMA_Util::backquote($cfgRelation['db']) + . "." . PMA_Util::backquote($cfgRelation['designer_coords']); + $tab_pos = PMA_DBI_fetch_result( + $query, 'name', null, $GLOBALS['controllink'], PMA_DBI_QUERY_STORE + ); + return count($tab_pos) ? $tab_pos : null; +} +?> diff --git a/phpmyadmin/libraries/properties/PropertyItem.class.php b/phpmyadmin/libraries/properties/PropertyItem.class.php new file mode 100644 index 000000000..21d50682c --- /dev/null +++ b/phpmyadmin/libraries/properties/PropertyItem.class.php @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php new file mode 100644 index 000000000..ebff9b321 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/OptionsPropertyGroup.class.php @@ -0,0 +1,104 @@ +getProperties() == null + && in_array($property, $this->getProperties(), true) + ) { + return; + } + $this->_properties [] = $property; + } + + /** + * Removes a property from the group of properties + * + * @param OptionsPropertyItem $property the property instance to be removed + * from the group + * + * @return void + */ + public function removeProperty($property) + { + $this->_properties = array_udiff( + $this->getProperties(), + array($property), + // for PHP 5.2 compability + create_function( + '$a, $b', + 'return ($a === $b ) ? 0 : 1' + ) + ); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the instance of the class + * + * @return array + */ + public function getGroup() + { + return $this; + } + + /** + * Gets the group of properties + * + * @return array + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Gets the number of properties + * + * @return int + */ + public function getNrOfProperties() + { + return count($this->_properties); + } +} +?> diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php new file mode 100644 index 000000000..a1718a2fc --- /dev/null +++ b/phpmyadmin/libraries/properties/options/OptionsPropertyItem.class.php @@ -0,0 +1,127 @@ +_name; + } + + /** + * Sets the name + * + * @param string $name name + * + * @return void + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Gets the text + * + * @return string + */ + public function getText() + { + return $this->_text; + } + + /** + * Sets the text + * + * @param string $text text + * + * @return void + */ + public function setText($text) + { + $this->_text = $text; + } + + /** + * Gets the force parameter + * + * @return string + */ + public function getForce() + { + return $this->_force; + } + + /** + * Sets the force paramter + * + * @param string $force force parameter + * + * @return void + */ + public function setForce($force) + { + $this->_force = $force; + } + + /** + * Returns the property type ( either "options", or "plugin" ). + * + * @return string + */ + public function getPropertyType() + { + return "options"; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php b/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php new file mode 100644 index 000000000..e19c15cd4 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/OptionsPropertyOneItem.class.php @@ -0,0 +1,172 @@ +_force; + } + + /** + * Sets the force parameter + * + * @param bool $force force parameter + * + * @return void + */ + public function setForce($force) + { + $this->_force = $force; + } + + /** + * Gets the values + * + * @return string + */ + public function getValues() + { + return $this->_values; + } + + /** + * Sets the values + * + * @param array $values values + * + * @return void + */ + public function setValues($values) + { + $this->_values = $values; + } + + /** + * Gets the type of the newline character + * + * @return string + */ + public function getDoc() + { + return $this->_doc; + } + + /** + * Sets the doc + * + * @param string $doc doc + * + * @return void + */ + public function setDoc($doc) + { + $this->_doc = $doc; + } + + /** + * Gets the length + * + * @return int + */ + public function getLen() + { + return $this->_len; + } + + /** + * Sets the length + * + * @param int $len length + * + * @return void + */ + public function setLen($len) + { + $this->_len = $len; + } + + /** + * Gets the size + * + * @return int + */ + public function getSize() + { + return $this->_size; + } + + /** + * Sets the size + * + * @param int $size size + * + * @return void + */ + public function setSize($size) + { + $this->_size = $size; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php new file mode 100644 index 000000000..4e69aa7ac --- /dev/null +++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyMainGroup.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php new file mode 100644 index 000000000..a081744fa --- /dev/null +++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertyRootGroup.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php b/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php new file mode 100644 index 000000000..0eeb52437 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/groups/OptionsPropertySubgroup.class.php @@ -0,0 +1,68 @@ +_subgroupHeader; + } + + /** + * Sets the subgroup header + * + * @param string $subgroupHeader subgroup header + * + * @return void + */ + public function setSubgroupHeader($subgroupHeader) + { + $this->_subgroupHeader = $subgroupHeader; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php new file mode 100644 index 000000000..f33067fcd --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/BoolPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php new file mode 100644 index 000000000..55aff6147 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/DocPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php new file mode 100644 index 000000000..53bfe465a --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/HiddenPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php new file mode 100644 index 000000000..98f2e709f --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/MessageOnlyPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php new file mode 100644 index 000000000..4d8ed7a21 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/RadioPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php new file mode 100644 index 000000000..28460c95a --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/SelectPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php b/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php new file mode 100644 index 000000000..9339cdf07 --- /dev/null +++ b/phpmyadmin/libraries/properties/options/items/TextPropertyItem.class.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php b/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php new file mode 100644 index 000000000..617089718 --- /dev/null +++ b/phpmyadmin/libraries/properties/plugins/ExportPluginProperties.class.php @@ -0,0 +1,214 @@ +_text; + } + + /** + * Sets the text + * + * @param string $text text + * + * @return void + */ + public function setText($text) + { + $this->_text = $text; + } + + /** + * Gets the extension + * + * @return string + */ + public function getExtension() + { + return $this->_extension; + } + + /** + * Sets the extension + * + * @param string $extension extension + * + * @return void + */ + public function setExtension($extension) + { + $this->_extension = $extension; + } + + /** + * Gets the options + * + * @return OptionsPropertyRootGroup + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Sets the options + * + * @param OptionsPropertyRootGroup $options options + * + * @return void + */ + public function setOptions($options) + { + $this->_options = $options; + } + + /** + * Gets the options text + * + * @return string + */ + public function getOptionsText() + { + return $this->_optionsText; + } + + /** + * Sets the options text + * + * @param string $optionsText optionsText + * + * @return void + */ + public function setOptionsText($optionsText) + { + $this->_optionsText = $optionsText; + } + + /** + * Gets the MIME type + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Sets the MIME type + * + * @param string $mimeType MIME type + * + * @return void + */ + public function setMimeType($mimeType) + { + $this->_mimeType = $mimeType; + } + + /** + * Gets the force file parameter + * + * @return bool + */ + public function getForceFile() + { + return $this->_forceFile; + } + + /** + * Sets the force file parameter + * + * @param bool $forceFile the force file parameter + * + * @return void + */ + public function setForceFile($forceFile) + { + $this->_forceFile = $forceFile; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php b/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php new file mode 100644 index 000000000..65c3092cf --- /dev/null +++ b/phpmyadmin/libraries/properties/plugins/ImportPluginProperties.class.php @@ -0,0 +1,184 @@ +_text; + } + + /** + * Sets the text + * + * @param string $text text + * + * @return void + */ + public function setText($text) + { + $this->_text = $text; + } + + /** + * Gets the extension + * + * @return string + */ + public function getExtension() + { + return $this->_extension; + } + + /** + * Sets the extension + * + * @param string $extension extension + * + * @return void + */ + public function setExtension($extension) + { + $this->_extension = $extension; + } + + /** + * Gets the options + * + * @return OptionsPropertyRootGroup + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Sets the options + * + * @param OptionsPropertyRootGroup $options options + * + * @return void + */ + public function setOptions($options) + { + $this->_options = $options; + } + + /** + * Gets the options text + * + * @return string + */ + public function getOptionsText() + { + return $this->_optionsText; + } + + /** + * Sets the options text + * + * @param string $optionsText options text + * + * @return void + */ + public function setOptionsText($optionsText) + { + $this->_optionsText = $optionsText; + } + + /** + * Gets the MIME type + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Sets the MIME type + * + * @param string $mimeType MIME type + * + * @return void + */ + public function setMimeType($mimeType) + { + $this->_mimeType = $mimeType; + } +} +?> \ No newline at end of file diff --git a/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php b/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php new file mode 100644 index 000000000..af46be225 --- /dev/null +++ b/phpmyadmin/libraries/properties/plugins/PluginPropertyItem.class.php @@ -0,0 +1,36 @@ + \ No newline at end of file diff --git a/phpmyadmin/libraries/relation.lib.php b/phpmyadmin/libraries/relation.lib.php new file mode 100644 index 000000000..efa02110c --- /dev/null +++ b/phpmyadmin/libraries/relation.lib.php @@ -0,0 +1,1396 @@ +' + . __('not OK') + . '' + . ' [ ' + . __('Documentation') + . ' ]'; + + $messages['ok'] = '' + . _pgettext('Correctly working', 'OK') + . ''; + + $messages['enabled'] = '' . __('Enabled') . ''; + $messages['disabled'] = '' . __('Disabled') . ''; + + if (false === $GLOBALS['cfg']['Server']['pmadb']) { + $retval .= 'PMA Database ... ' + . sprintf($messages['error'], 'pmadb') + . '
      ' . "\n" + . __('General relation features') + . ' ' . __('Disabled') + . '' . "\n"; + } else { + $retval .= '' . "\n"; + $retval .= PMA_getDiagMessageForParameter( + 'pmadb', + $GLOBALS['cfg']['Server']['pmadb'], + $messages, + 'pmadb' + ); + $retval .= PMA_getDiagMessageForParameter( + 'relation', + isset($cfgRelation['relation']), + $messages, + 'relation' + ); + $retval .= PMA_getDiagMessageForFeature( + __('General relation features'), + 'relwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'table_info', + isset($cfgRelation['table_info']), + $messages, + 'table_info' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Display Features'), + 'displaywork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'table_coords', + isset($cfgRelation['table_coords']), + $messages, + 'table_coords' + ); + $retval .= PMA_getDiagMessageForParameter( + 'pdf_pages', + isset($cfgRelation['pdf_pages']), + $messages, + 'pdf_pages' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Creation of PDFs'), + 'pdfwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'column_info', + isset($cfgRelation['column_info']), + $messages, + 'column_info' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Displaying Column Comments'), + 'commwork', + $messages, + false + ); + $retval .= PMA_getDiagMessageForFeature( + __('Browser transformation'), + 'mimework', + $messages + ); + if ($cfgRelation['commwork'] && ! $cfgRelation['mimework']) { + $retval .= ''; + } + $retval .= PMA_getDiagMessageForParameter( + 'bookmarktable', + isset($cfgRelation['bookmark']), + $messages, + 'bookmark' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Bookmarked SQL query'), + 'bookmarkwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'history', + isset($cfgRelation['history']), + $messages, + 'history' + ); + $retval .= PMA_getDiagMessageForFeature( + __('SQL history'), + 'historywork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'designer_coords', + isset($cfgRelation['designer_coords']), + $messages, + 'designer_coords' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Designer'), + 'designerwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'recent', + isset($cfgRelation['recent']), + $messages, + 'recent' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Persistent recently used tables'), + 'recentwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'table_uiprefs', + isset($cfgRelation['table_uiprefs']), + $messages, + 'table_uiprefs' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Persistent tables\' UI preferences'), + 'uiprefswork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'tracking', + isset($cfgRelation['tracking']), + $messages, + 'tracking' + ); + $retval .= PMA_getDiagMessageForFeature( + __('Tracking'), + 'trackingwork', + $messages + ); + $retval .= PMA_getDiagMessageForParameter( + 'userconfig', + isset($cfgRelation['userconfig']), + $messages, + 'userconfig' + ); + $retval .= PMA_getDiagMessageForFeature( + __('User preferences'), + 'userconfigwork', + $messages + ); + $retval .= '
      '; + $retval .= __('Please see the documentation on how to update your column_comments table'); + $retval .= '
      ' . "\n"; + + $retval .= '

      ' . __('Quick steps to setup advanced features:') . '

      '; + $retval .= '
        '; + $retval .= '
      • '; + $retval .= __( + 'Create the needed tables with the ' + . 'examples/create_tables.sql.' + ); + $retval .= ' ' . PMA_Util::showDocu('setup', 'linked-tables'); + $retval .= '
      • '; + $retval .= '
      • '; + $retval .= __('Create a pma user and give access to these tables.'); + $retval .= ' ' . PMA_Util::showDocu('config', 'cfg_Servers_controluser'); + $retval .= '
      • '; + $retval .= '
      • '; + $retval .= __( + 'Enable advanced features in configuration file ' + . '(config.inc.php), for example by ' + . 'starting from config.sample.inc.php.' + ); + $retval .= ' ' . PMA_Util::showDocu('setup', 'quick-install'); + $retval .= '
      • '; + $retval .= '
      • '; + $retval .= __( + 'Re-login to phpMyAdmin to load the updated configuration file.' + ); + $retval .= '
      • '; + $retval .= '
      '; + } + + return $retval; +} + +/** + * prints out one diagnostic message for a feature + * + * @param string $feature_name feature name in a message string + * @param string $relation_parameter the $GLOBALS['cfgRelation'] parameter to check + * @param array $messages utility messages + * @param boolean $skip_line whether to skip a line after the message + * + * @return string + */ +function PMA_getDiagMessageForFeature($feature_name, + $relation_parameter, $messages, $skip_line = true +) { + $retval = ' ' . $feature_name . ': '; + if ($GLOBALS['cfgRelation'][$relation_parameter]) { + $retval .= $messages['enabled']; + } else { + $retval .= $messages['disabled']; + } + $retval .= ''; + if ($skip_line) { + $retval .= ' '; + } + return $retval; +} + +/** + * prints out one diagnostic message for a configuration parameter + * + * @param string $parameter config parameter name to display + * @param boolean $relation_parameter_set whether this parameter is set + * @param array $messages utility messages + * @param string $doc_anchor anchor in documentation + * + * @return void + */ +function PMA_getDiagMessageForParameter($parameter, + $relation_parameter_set, $messages, $doc_anchor +) { + $retval = ''; + $retval .= '$cfg[\'Servers\'][$i][\'' . $parameter . '\'] ... '; + $retval .= ''; + if ($relation_parameter_set) { + $retval .= $messages['ok']; + } else { + $retval .= sprintf( + $messages['error'], + PMA_Util::getDocuLink('config', 'cfg_Servers_' . $doc_anchor) + ); + } + $retval .= '' . "\n"; + return $retval; +} + + +/** + * Defines the relation parameters for the current user + * just a copy of the functions used for relations ;-) + * but added some stuff to check what will work + * + * @access protected + * @return array the relation parameters for the current user + */ +function PMA__getRelationsParam() +{ + $cfgRelation = array(); + $cfgRelation['relwork'] = false; + $cfgRelation['displaywork'] = false; + $cfgRelation['bookmarkwork']= false; + $cfgRelation['pdfwork'] = false; + $cfgRelation['commwork'] = false; + $cfgRelation['mimework'] = false; + $cfgRelation['historywork'] = false; + $cfgRelation['recentwork'] = false; + $cfgRelation['uiprefswork'] = false; + $cfgRelation['trackingwork'] = false; + $cfgRelation['designerwork'] = false; + $cfgRelation['userconfigwork'] = false; + $cfgRelation['allworks'] = false; + $cfgRelation['user'] = null; + $cfgRelation['db'] = null; + + if ($GLOBALS['server'] == 0 || empty($GLOBALS['cfg']['Server']['pmadb']) + || ! PMA_DBI_select_db($GLOBALS['cfg']['Server']['pmadb'], $GLOBALS['controllink']) + ) { + // No server selected -> no bookmark table + // we return the array with the falses in it, + // to avoid some 'Unitialized string offset' errors later + $GLOBALS['cfg']['Server']['pmadb'] = false; + return $cfgRelation; + } + + + $cfgRelation['user'] = $GLOBALS['cfg']['Server']['user']; + $cfgRelation['db'] = $GLOBALS['cfg']['Server']['pmadb']; + + // Now I just check if all tables that i need are present so I can for + // example enable relations but not pdf... + // I was thinking of checking if they have all required columns but I + // fear it might be too slow + + $tab_query = 'SHOW TABLES FROM ' + . PMA_Util::backquote( + $GLOBALS['cfg']['Server']['pmadb'] + ); + $tab_rs = PMA_queryAsControlUser($tab_query, false, PMA_DBI_QUERY_STORE); + + if (! $tab_rs) { + // query failed ... ? + //$GLOBALS['cfg']['Server']['pmadb'] = false; + return $cfgRelation; + } + + while ($curr_table = @PMA_DBI_fetch_row($tab_rs)) { + if ($curr_table[0] == $GLOBALS['cfg']['Server']['bookmarktable']) { + $cfgRelation['bookmark'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['relation']) { + $cfgRelation['relation'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_info']) { + $cfgRelation['table_info'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_coords']) { + $cfgRelation['table_coords'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['designer_coords']) { + $cfgRelation['designer_coords'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['column_info']) { + $cfgRelation['column_info'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['pdf_pages']) { + $cfgRelation['pdf_pages'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['history']) { + $cfgRelation['history'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['recent']) { + $cfgRelation['recent'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['table_uiprefs']) { + $cfgRelation['table_uiprefs'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['tracking']) { + $cfgRelation['tracking'] = $curr_table[0]; + } elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['userconfig']) { + $cfgRelation['userconfig'] = $curr_table[0]; + } + } // end while + PMA_DBI_free_result($tab_rs); + + if (isset($cfgRelation['relation'])) { + $cfgRelation['relwork'] = true; + if (isset($cfgRelation['table_info'])) { + $cfgRelation['displaywork'] = true; + } + } + + if (isset($cfgRelation['table_coords']) && isset($cfgRelation['pdf_pages'])) { + $cfgRelation['pdfwork'] = true; + } + + if (isset($cfgRelation['column_info'])) { + $cfgRelation['commwork'] = true; + $cfgRelation['mimework'] = true; + } + + if (isset($cfgRelation['history'])) { + $cfgRelation['historywork'] = true; + } + + if (isset($cfgRelation['recent'])) { + $cfgRelation['recentwork'] = true; + } + + if (isset($cfgRelation['table_uiprefs'])) { + $cfgRelation['uiprefswork'] = true; + } + + if (isset($cfgRelation['tracking'])) { + $cfgRelation['trackingwork'] = true; + } + + if (isset($cfgRelation['userconfig'])) { + $cfgRelation['userconfigwork'] = true; + } + + // we do not absolutely need that the internal relations or the PDF + // schema feature be activated + if (isset($cfgRelation['designer_coords'])) { + $cfgRelation['designerwork'] = true; + } + + if (isset($cfgRelation['bookmark'])) { + $cfgRelation['bookmarkwork'] = true; + } + + if ($cfgRelation['relwork'] && $cfgRelation['displaywork'] + && $cfgRelation['pdfwork'] && $cfgRelation['commwork'] + && $cfgRelation['mimework'] && $cfgRelation['historywork'] + && $cfgRelation['recentwork'] && $cfgRelation['uiprefswork'] + && $cfgRelation['trackingwork'] && $cfgRelation['userconfigwork'] + && $cfgRelation['bookmarkwork'] && $cfgRelation['designerwork'] + ) { + $cfgRelation['allworks'] = true; + } + + return $cfgRelation; +} // end of the 'PMA_getRelationsParam()' function + +/** + * Gets all Relations to foreign tables for a given table or + * optionally a given column in a table + * + * @param string $db the name of the db to check for + * @param string $table the name of the table to check for + * @param string $column the name of the column to check for + * @param string $source the source for foreign key information + * + * @return array db,table,column + * + * @access public + */ +function PMA_getForeigners($db, $table, $column = '', $source = 'both') +{ + $cfgRelation = PMA_getRelationsParam(); + $foreign = array(); + + if ($cfgRelation['relwork'] && ($source == 'both' || $source == 'internal')) { + $rel_query = ' + SELECT `master_field`, + `foreign_db`, + `foreign_table`, + `foreign_field` + FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['relation']) . ' + WHERE `master_db` = \'' . PMA_Util::sqlAddSlashes($db) . '\' + AND `master_table` = \'' . PMA_Util::sqlAddSlashes($table) . '\' '; + if (strlen($column)) { + $rel_query .= ' AND `master_field` = \'' . PMA_Util::sqlAddSlashes($column) . '\''; + } + $foreign = PMA_DBI_fetch_result($rel_query, 'master_field', null, $GLOBALS['controllink']); + } + + if (($source == 'both' || $source == 'foreign') && strlen($table)) { + + $show_create_table_query = 'SHOW CREATE TABLE ' + . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table); + $show_create_table = PMA_DBI_fetch_value($show_create_table_query, 0, 1); + $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table)); + + foreach ($analyzed_sql[0]['foreign_keys'] as $one_key) { + // The analyzer may return more than one column name in the + // index list or the ref_index_list; if this happens, + // the current logic just discards the whole index; having + // more than one index field is currently unsupported (see FAQ 3.6) + if (count($one_key['index_list']) == 1) { + foreach ($one_key['index_list'] as $i => $field) { + // If a foreign key is defined in the 'internal' source (pmadb) + // and as a native foreign key, we won't get it twice + // if $source='both' because we use $field as key + + // The parser looks for a CONSTRAINT clause just before + // the FOREIGN KEY clause. It finds it (as output from + // SHOW CREATE TABLE) in MySQL 4.0.13, but not in older + // versions like 3.23.58. + // In those cases, the FOREIGN KEY parsing will put numbers + // like -1, 0, 1... instead of the constraint number. + + if (isset($one_key['constraint'])) { + $foreign[$field]['constraint'] = $one_key['constraint']; + } + + if (isset($one_key['ref_db_name'])) { + $foreign[$field]['foreign_db'] = $one_key['ref_db_name']; + } else { + $foreign[$field]['foreign_db'] = $db; + } + $foreign[$field]['foreign_table'] = $one_key['ref_table_name']; + $foreign[$field]['foreign_field'] = $one_key['ref_index_list'][$i]; + if (isset($one_key['on_delete'])) { + $foreign[$field]['on_delete'] = $one_key['on_delete']; + } + if (isset($one_key['on_update'])) { + $foreign[$field]['on_update'] = $one_key['on_update']; + } + } + } + } + } + + /** + * Emulating relations for some information_schema and data_dictionary tables + */ + $is_information_schema = strtolower($db) == 'information_schema'; + $is_data_dictionary = PMA_DRIZZLE && strtolower($db) == 'data_dictionary'; + if (($is_information_schema || $is_data_dictionary) && ($source == 'internal' || $source == 'both')) { + if ($is_information_schema) { + $relations_key = 'information_schema_relations'; + include_once './libraries/information_schema_relations.lib.php'; + } else { + $relations_key = 'data_dictionary_relations'; + include_once './libraries/data_dictionary_relations.lib.php'; + } + if (isset($GLOBALS[$relations_key][$table])) { + foreach ($GLOBALS[$relations_key][$table] as $field => $relations) { + if ((! strlen($column) || $column == $field) + && (! isset($foreign[$field]) || ! strlen($foreign[$field])) + ) { + $foreign[$field] = $relations; + } + } + } + } + + return $foreign; +} // end of the 'PMA_getForeigners()' function + +/** + * Gets the display field of a table + * + * @param string $db the name of the db to check for + * @param string $table the name of the table to check for + * + * @return string field name + * + * @access public + */ +function PMA_getDisplayField($db, $table) +{ + $cfgRelation = PMA_getRelationsParam(); + + /** + * Try to fetch the display field from DB. + */ + if ($cfgRelation['displaywork']) { + $disp_query = ' + SELECT `display_field` + FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['table_info']) . ' + WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($db) . '\' + AND `table_name` = \'' . PMA_Util::sqlAddSlashes($table) . '\''; + + $row = PMA_DBI_fetch_single_row($disp_query, 'ASSOC', $GLOBALS['controllink']); + if (isset($row['display_field'])) { + return $row['display_field']; + } + } + + /** + * Emulating the display field for some information_schema tables. + */ + if ($db == 'information_schema') { + switch ($table) { + case 'CHARACTER_SETS': + return 'DESCRIPTION'; + case 'TABLES': + return 'TABLE_COMMENT'; + } + } + + /** + * No Luck... + */ + return false; + +} // end of the 'PMA_getDisplayField()' function + +/** + * Gets the comments for all columns of a table or the db itself + * + * @param string $db the name of the db to check for + * @param string $table the name of the table to check for + * + * @return array [column_name] = comment + * + * @access public + */ +function PMA_getComments($db, $table = '') +{ + $comments = array(); + + if ($table != '') { + // MySQL native column comments + $columns = PMA_DBI_get_columns($db, $table, null, true); + if ($columns) { + foreach ($columns as $column) { + if (! empty($column['Comment'])) { + $comments[$column['Field']] = $column['Comment']; + } + } + } + } else { + $comments[] = PMA_getDbComment($db); + } + + return $comments; +} // end of the 'PMA_getComments()' function + +/** + * Gets the comment for a db + * + * @param string $db the name of the db to check for + * + * @return string comment + * + * @access public + */ +function PMA_getDbComment($db) +{ + $cfgRelation = PMA_getRelationsParam(); + $comment = ''; + + if ($cfgRelation['commwork']) { + // pmadb internal db comment + $com_qry = " + SELECT `comment` + FROM " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . " + WHERE db_name = '" . PMA_Util::sqlAddSlashes($db) . "' + AND table_name = '' + AND column_name = '(db_comment)'"; + $com_rs = PMA_queryAsControlUser($com_qry, true, PMA_DBI_QUERY_STORE); + + if ($com_rs && PMA_DBI_num_rows($com_rs) > 0) { + $row = PMA_DBI_fetch_assoc($com_rs); + $comment = $row['comment']; + } + PMA_DBI_free_result($com_rs); + } + + return $comment; +} // end of the 'PMA_getDbComment()' function + +/** + * Gets the comment for a db + * + * @access public + * + * @return string comment + */ +function PMA_getDbComments() +{ + $cfgRelation = PMA_getRelationsParam(); + $comments = array(); + + if ($cfgRelation['commwork']) { + // pmadb internal db comment + $com_qry = " + SELECT `db_name`, `comment` + FROM " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . " + WHERE `column_name` = '(db_comment)'"; + $com_rs = PMA_queryAsControlUser($com_qry, true, PMA_DBI_QUERY_STORE); + + if ($com_rs && PMA_DBI_num_rows($com_rs) > 0) { + while ($row = PMA_DBI_fetch_assoc($com_rs)) { + $comments[$row['db_name']] = $row['comment']; + } + } + PMA_DBI_free_result($com_rs); + } + + return $comments; +} // end of the 'PMA_getDbComments()' function + +/** + * Set a database comment to a certain value. + * + * @param string $db the name of the db + * @param string $comment the value of the column + * + * @return boolean true, if comment-query was made. + * + * @access public + */ +function PMA_setDbComment($db, $comment = '') +{ + $cfgRelation = PMA_getRelationsParam(); + + if (! $cfgRelation['commwork']) { + return false; + } + + if (strlen($comment)) { + $upd_query = " + INSERT INTO + " . PMA_Util::backquote($cfgRelation['db']) . "." . PMA_Util::backquote($cfgRelation['column_info']) . " + (`db_name`, `table_name`, `column_name`, `comment`) + VALUES ( + '" . PMA_Util::sqlAddSlashes($db) . "', + '', + '(db_comment)', + '" . PMA_Util::sqlAddSlashes($comment) . "') + ON DUPLICATE KEY UPDATE + `comment` = '" . PMA_Util::sqlAddSlashes($comment) . "'"; + } else { + $upd_query = ' + DELETE FROM + ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['column_info']) . ' + WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($db) . '\' + AND `table_name` = \'\' + AND `column_name` = \'(db_comment)\''; + } + + if (isset($upd_query)) { + return PMA_queryAsControlUser($upd_query); + } + + return false; +} // end of 'PMA_setDbComment()' function + +/** + * Set a SQL history entry + * + * @param string $db the name of the db + * @param string $table the name of the table + * @param string $username the username + * @param string $sqlquery the sql query + * + * @return void + * + * @access public + */ +function PMA_setHistory($db, $table, $username, $sqlquery) +{ + // Prevent to run this automatically on Footer class destroying in testsuite + if (defined('TESTSUITE') || strlen($sqlquery) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { + return; + } + + $cfgRelation = PMA_getRelationsParam(); + + if (! isset($_SESSION['sql_history'])) { + $_SESSION['sql_history'] = array(); + } + + $key = md5($sqlquery . $db . $table); + + if (isset($_SESSION['sql_history'][$key])) { + unset($_SESSION['sql_history'][$key]); + } + + $_SESSION['sql_history'][$key] = array( + 'db' => $db, + 'table' => $table, + 'sqlquery' => $sqlquery, + ); + + if (count($_SESSION['sql_history']) > $GLOBALS['cfg']['QueryHistoryMax']) { + // history should not exceed a maximum count + array_shift($_SESSION['sql_history']); + } + + if (! $cfgRelation['historywork'] || ! $GLOBALS['cfg']['QueryHistoryDB']) { + return; + } + + PMA_queryAsControlUser( + 'INSERT INTO + ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . ' + (`username`, + `db`, + `table`, + `timevalue`, + `sqlquery`) + VALUES + (\'' . PMA_Util::sqlAddSlashes($username) . '\', + \'' . PMA_Util::sqlAddSlashes($db) . '\', + \'' . PMA_Util::sqlAddSlashes($table) . '\', + NOW(), + \'' . PMA_Util::sqlAddSlashes($sqlquery) . '\')' + ); +} // end of 'PMA_setHistory()' function + +/** + * Gets a SQL history entry + * + * @param string $username the username + * + * @return array list of history items + * + * @access public + */ +function PMA_getHistory($username) +{ + $cfgRelation = PMA_getRelationsParam(); + + if (! $cfgRelation['historywork']) { + return false; + } + + $hist_query = ' + SELECT `db`, + `table`, + `sqlquery` + FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . ' + WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\' + ORDER BY `id` DESC'; + + return PMA_DBI_fetch_result($hist_query, null, null, $GLOBALS['controllink']); +} // end of 'PMA_getHistory()' function + +/** + * purges SQL history + * + * deletes entries that exceeds $cfg['QueryHistoryMax'], oldest first, for the + * given user + * + * @param string $username the username + * + * @return void + * + * @access public + */ +function PMA_purgeHistory($username) +{ + $cfgRelation = PMA_getRelationsParam(); + if (! $GLOBALS['cfg']['QueryHistoryDB'] || ! $cfgRelation['historywork']) { + return; + } + + if (! $cfgRelation['historywork']) { + return; + } + + $search_query = ' + SELECT `timevalue` + FROM ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . ' + WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\' + ORDER BY `timevalue` DESC + LIMIT ' . $GLOBALS['cfg']['QueryHistoryMax'] . ', 1'; + + if ($max_time = PMA_DBI_fetch_value($search_query, 0, 0, $GLOBALS['controllink'])) { + PMA_queryAsControlUser( + 'DELETE FROM + ' . PMA_Util::backquote($cfgRelation['db']) . '.' . PMA_Util::backquote($cfgRelation['history']) . ' + WHERE `username` = \'' . PMA_Util::sqlAddSlashes($username) . '\' + AND `timevalue` <= \'' . $max_time . '\'' + ); + } +} // end of 'PMA_purgeHistory()' function + +/** + * Prepares the dropdown for one mode + * + * @param array $foreign the keys and values for foreigns + * @param string $data the current data of the dropdown + * @param string $mode the needed mode + * + * @return array the '; + } elseif ($mode == 'id-content') { + $reloptions[] = $reloption . '>' . htmlspecialchars($key) . ' - ' . $value . ''; + } elseif ($mode == 'id-only') { + $reloptions[] = $reloption . '>' . htmlspecialchars($key) . ''; + } + } // end foreach + + return $reloptions; +} // end of 'PMA__foreignDropdownBuild' function + +/** + * Outputs dropdown with values of foreign fields + * + * @param array $disp_row array of the displayed row + * @param string $foreign_field the foreign field + * @param string $foreign_display the foreign field to display + * @param string $data the current data of the dropdown (field in row) + * @param int $max maximum number of items in the dropdown + * + * @return string the '; + $top_count = count($top); + if ($max == -1 || $top_count < $max) { + $ret .= implode('', $top); + if ($foreign_display && $top_count > 0) { + // this empty option is to visually mark the beginning of the + // second series of values (bottom) + $ret .= ''; + } + } + if ($foreign_display) { + $ret .= implode('', $bottom); + } + + return $ret; +} // end of 'PMA_foreignDropdown()' function + +/** + * Gets foreign keys in preparation for a drop-down selector + * + * @param array $foreigners array of the foreign keys + * @param string $field the foreign field name + * @param bool $override_total whether to override the total + * @param string $foreign_filter a possible filter + * @param string $foreign_limit a possible LIMIT clause + * + * @return array data about the foreign keys + * + * @access public + */ + +function PMA_getForeignData($foreigners, $field, $override_total, $foreign_filter, $foreign_limit) +{ + // we always show the foreign field in the drop-down; if a display + // field is defined, we show it besides the foreign field + $foreign_link = false; + if ($foreigners && isset($foreigners[$field])) { + $foreigner = $foreigners[$field]; + $foreign_db = $foreigner['foreign_db']; + $foreign_table = $foreigner['foreign_table']; + $foreign_field = $foreigner['foreign_field']; + + // Count number of rows in the foreign table. Currently we do + // not use a drop-down if more than ForeignKeyMaxLimit rows in the + // foreign table, + // for speed reasons and because we need a better interface for this. + // + // We could also do the SELECT anyway, with a LIMIT, and ensure that + // the current value of the field is one of the choices. + + $the_total = PMA_Table::countRecords($foreign_db, $foreign_table, true); + + if ($override_total == true || $the_total < $GLOBALS['cfg']['ForeignKeyMaxLimit']) { + // foreign_display can be false if no display field defined: + $foreign_display = PMA_getDisplayField($foreign_db, $foreign_table); + + $f_query_main = 'SELECT ' . PMA_Util::backquote($foreign_field) + . (($foreign_display == false) ? '' : ', ' . PMA_Util::backquote($foreign_display)); + $f_query_from = ' FROM ' . PMA_Util::backquote($foreign_db) . '.' . PMA_Util::backquote($foreign_table); + $f_query_filter = empty($foreign_filter) ? '' : ' WHERE ' . PMA_Util::backquote($foreign_field) + . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"' + . (($foreign_display == false) ? '' : ' OR ' . PMA_Util::backquote($foreign_display) + . ' LIKE "%' . PMA_Util::sqlAddSlashes($foreign_filter, true) . '%"' + ); + $f_query_order = ($foreign_display == false) ? '' :' ORDER BY ' . PMA_Util::backquote($foreign_table) . '.' . PMA_Util::backquote($foreign_display); + $f_query_limit = isset($foreign_limit) ? $foreign_limit : ''; + + if (!empty($foreign_filter)) { + $res = PMA_DBI_query('SELECT COUNT(*)' . $f_query_from . $f_query_filter); + if ($res) { + $the_total = PMA_DBI_fetch_value($res); + @PMA_DBI_free_result($res); + } else { + $the_total = 0; + } + } + + $disp = PMA_DBI_query($f_query_main . $f_query_from . $f_query_filter . $f_query_order . $f_query_limit); + if ($disp && PMA_DBI_num_rows($disp) > 0) { + // If a resultset has been created, pre-cache it in the $disp_row array + // This helps us from not needing to use mysql_data_seek by accessing a pre-cached + // PHP array. Usually those resultsets are not that big, so a performance hit should + // not be expected. + $disp_row = array(); + while ($single_disp_row = @PMA_DBI_fetch_assoc($disp)) { + $disp_row[] = $single_disp_row; + } + @PMA_DBI_free_result($disp); + } + } else { + $disp_row = null; + $foreign_link = true; + } + } // end if $foreigners + + $foreignData['foreign_link'] = $foreign_link; + $foreignData['the_total'] = isset($the_total) ? $the_total : null; + $foreignData['foreign_display'] = isset($foreign_display) ? $foreign_display : null; + $foreignData['disp_row'] = isset($disp_row) ? $disp_row : null; + $foreignData['foreign_field'] = isset($foreign_field) ? $foreign_field : null; + return $foreignData; +} // end of 'PMA_getForeignData()' function + +/** + * Finds all related tables + * + * @param array $all_tables All the involved tables + * @param string $master The master table to form the LEFT JOIN clause + * + * @return string LEFT JOIN + * @access private + */ +function PMA_getRelatives($all_tables, $master) +{ + $fromclause = ''; + $emerg = ''; + + // The list of tables that we still couldn't connect + $remaining_tables = $all_tables; + unset($remaining_tables[$master]); + // The list of allready connected tables + $known_tables[$master] = $master; + $run = 0; + while (count($remaining_tables) > 0) { + // Whether to go from master to foreign or vice versa + if ($run % 2 == 0) { + $from = 'master'; + $to = 'foreign'; + } else { + $from = 'foreign'; + $to = 'master'; + } + $in_know = '(\'' . implode('\', \'', $known_tables) . '\')'; + $in_left = '(\'' . implode('\', \'', $remaining_tables) . '\')'; + $rel_query = 'SELECT *' + . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) + . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['relation']) + . ' WHERE ' . $from . '_db = \'' . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\'' + . ' AND ' . $to . '_db = \'' . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\'' + . ' AND ' . $from . '_table IN ' . $in_know + . ' AND ' . $to . '_table IN ' . $in_left; + $relations = @PMA_DBI_query($rel_query, $GLOBALS['controllink']); + while ($row = PMA_DBI_fetch_assoc($relations)) { + $found_table = $row[$to . '_table']; + if (isset($remaining_tables[$found_table])) { + $fromclause + .= "\n" . ' LEFT JOIN ' + . PMA_Util::backquote($GLOBALS['db']) . '.' . PMA_Util::backquote($row[$to . '_table']) . ' ON ' + . PMA_Util::backquote($row[$from . '_table']) . '.' + . PMA_Util::backquote($row[$from . '_field']) . ' = ' + . PMA_Util::backquote($row[$to . '_table']) . '.' + . PMA_Util::backquote($row[$to . '_field']) . ' '; + $known_tables[$found_table] = $found_table; + unset($remaining_tables[$found_table]); + } + } // end while + $run++; + if ($run > 5) { + foreach ($remaining_tables as $table) { + $emerg .= ', ' . PMA_Util::backquote($table); + unset($remaining_tables[$table]); + } + } + } // end while + $fromclause = $emerg . $fromclause; + return $fromclause; +} // end of the "PMA_getRelatives()" function + +/** + * Rename a field in relation tables + * + * usually called after a column in a table was renamed + * + * @param string $db databse name + * @param string $table table name + * @param string $field old field name + * @param string $new_name new field name + * + * @return void + */ +function PMA_REL_renameField($db, $table, $field, $new_name) +{ + $cfgRelation = PMA_getRelationsParam(); + + if ($cfgRelation['displaywork']) { + $table_query = 'UPDATE ' + . PMA_Util::backquote($cfgRelation['db']) . '.' + . PMA_Util::backquote($cfgRelation['table_info']) + . ' SET display_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\'' + . ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'' + . ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'' + . ' AND display_field = \'' . PMA_Util::sqlAddSlashes($field) . '\''; + PMA_queryAsControlUser($table_query); + } + + if ($cfgRelation['relwork']) { + $table_query = 'UPDATE ' + . PMA_Util::backquote($cfgRelation['db']) . '.' + . PMA_Util::backquote($cfgRelation['relation']) + . ' SET master_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\'' + . ' WHERE master_db = \'' . PMA_Util::sqlAddSlashes($db) . '\'' + . ' AND master_table = \'' . PMA_Util::sqlAddSlashes($table) . '\'' + . ' AND master_field = \'' . PMA_Util::sqlAddSlashes($field) . '\''; + PMA_queryAsControlUser($table_query); + + $table_query = 'UPDATE ' + . PMA_Util::backquote($cfgRelation['db']) . '.' + . PMA_Util::backquote($cfgRelation['relation']) + . ' SET foreign_field = \'' . PMA_Util::sqlAddSlashes($new_name) . '\'' + . ' WHERE foreign_db = \'' . PMA_Util::sqlAddSlashes($db) . '\'' + . ' AND foreign_table = \'' . PMA_Util::sqlAddSlashes($table) . '\'' + . ' AND foreign_field = \'' . PMA_Util::sqlAddSlashes($field) . '\''; + PMA_queryAsControlUser($table_query); + + } // end if relwork +} + + +/** + * Performs SQL query used for renaming table. + * + * @param string $table Relation table to use + * @param string $source_db Source database name + * @param string $target_db Target database name + * @param string $source_table Source table name + * @param string $target_table Target table name + * @param string $db_field Name of database field + * @param string $table_field Name of table field + * + * @return nothing. + */ +function PMA_REL_renameSingleTable($table, + $source_db, $target_db, + $source_table, $target_table, + $db_field, $table_field +) { + $query = 'UPDATE ' + . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' + . PMA_Util::backquote($GLOBALS['cfgRelation'][$table]) + . ' SET ' . $db_field . ' = \'' . PMA_Util::sqlAddSlashes($target_db) . '\', ' + . ' ' . $table_field . ' = \'' . PMA_Util::sqlAddSlashes($target_table) . '\'' + . ' WHERE ' + . $db_field . ' = \'' . PMA_Util::sqlAddSlashes($source_db) . '\'' + . ' AND ' + . $table_field . ' = \'' . PMA_Util::sqlAddSlashes($source_table) . '\''; + PMA_queryAsControlUser($query); +} + + +/** + * Rename a table in relation tables + * + * usually called after table has been moved + * + * @param string $source_db Source database name + * @param string $target_db Target database name + * @param string $source_table Source table name + * @param string $target_table Target table name + * + * @return nothing + */ +function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_table) +{ + // Move old entries from PMA-DBs to new table + if ($GLOBALS['cfgRelation']['commwork']) { + PMA_REL_renameSingleTable( + 'column_info', + $source_db, $target_db, + $source_table, $target_table, + 'db_name', 'table_name' + ); + } + + // updating bookmarks is not possible since only a single table is + // moved, and not the whole DB. + + if ($GLOBALS['cfgRelation']['displaywork']) { + PMA_REL_renameSingleTable( + 'table_info', + $source_db, $target_db, + $source_table, $target_table, + 'db_name', 'table_name' + ); + } + + if ($GLOBALS['cfgRelation']['relwork']) { + PMA_REL_renameSingleTable( + 'relation', + $source_db, $target_db, + $source_table, $target_table, + 'foreign_db', 'foreign_table' + ); + + PMA_REL_renameSingleTable( + 'relation', + $source_db, $target_db, + $source_table, $target_table, + 'master_db', 'master_table' + ); + } + + /** + * @todo Can't get moving PDFs the right way. The page numbers + * always get screwed up independently from duplication because the + * numbers do not seem to be stored on a per-database basis. Would + * the author of pdf support please have a look at it? + */ + + if ($GLOBALS['cfgRelation']['pdfwork']) { + PMA_REL_renameSingleTable( + 'table_coords', + $source_db, $target_db, + $source_table, $target_table, + 'db_name', 'table_name' + ); + } + + if ($GLOBALS['cfgRelation']['designerwork']) { + PMA_REL_renameSingleTable( + 'designer_coords', + $source_db, $target_db, + $source_table, $target_table, + 'db_name', 'table_name' + ); + } +} + +/** + * Create a PDF page + * + * @param string $newpage name of the new PDF page + * @param array $cfgRelation Relation configuration + * @param string $db database name + * + * @return string $pdf_page_number + */ +function PMA_REL_createPage($newpage, $cfgRelation, $db) +{ + if (! isset($newpage) || $newpage == '') { + $newpage = __('no description'); + } + $ins_query = 'INSERT INTO ' + . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) . '.' + . PMA_Util::backquote($cfgRelation['pdf_pages']) + . ' (db_name, page_descr)' + . ' VALUES (\'' + . PMA_Util::sqlAddSlashes($db) . '\', \'' + . PMA_Util::sqlAddSlashes($newpage) . '\')'; + PMA_queryAsControlUser($ins_query, false); + + return PMA_DBI_insert_id( + isset($GLOBALS['controllink']) ? $GLOBALS['controllink'] : '' + ); +} +?> diff --git a/phpmyadmin/libraries/relation_cleanup.lib.php b/phpmyadmin/libraries/relation_cleanup.lib.php new file mode 100644 index 000000000..1c86a4b78 --- /dev/null +++ b/phpmyadmin/libraries/relation_cleanup.lib.php @@ -0,0 +1,165 @@ + diff --git a/phpmyadmin/libraries/replication.inc.php b/phpmyadmin/libraries/replication.inc.php new file mode 100644 index 000000000..467b3d541 --- /dev/null +++ b/phpmyadmin/libraries/replication.inc.php @@ -0,0 +1,307 @@ + 'No', + 'Slave_SQL_Running' => 'No', +); +$slave_variables_oks = array( + 'Slave_IO_Running' => 'Yes', + 'Slave_SQL_Running' => 'Yes', +); + +// check which replication is available and +// set $server_{master/slave}_status and assign values + +// replication info is more easily passed to functions +/* + * @todo use $replication_info everywhere instead of the generated variable names + */ +$replication_info = array(); + +foreach ($replication_types as $type) { + if (count(${"server_{$type}_replication"}) > 0) { + ${"server_{$type}_status"} = true; + $replication_info[$type]['status'] = true; + } else { + ${"server_{$type}_status"} = false; + $replication_info[$type]['status'] = false; + } + if (${"server_{$type}_status"}) { + if ($type == "master") { + ${"server_{$type}_Do_DB"} = explode(",", $server_master_replication[0]["Binlog_Do_DB"]); + $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"}; + + ${"server_{$type}_Ignore_DB"} = explode(",", $server_master_replication[0]["Binlog_Ignore_DB"]); + $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"}; + } elseif ($type == "slave") { + ${"server_{$type}_Do_DB"} = explode(",", $server_slave_replication[0]["Replicate_Do_DB"]); + $replication_info[$type]['Do_DB'] = ${"server_{$type}_Do_DB"}; + + ${"server_{$type}_Ignore_DB"} = explode(",", $server_slave_replication[0]["Replicate_Ignore_DB"]); + $replication_info[$type]['Ignore_DB'] = ${"server_{$type}_Ignore_DB"}; + + ${"server_{$type}_Do_Table"} = explode(",", $server_slave_replication[0]["Replicate_Do_Table"]); + $replication_info[$type]['Do_Table'] = ${"server_{$type}_Do_Table"}; + + ${"server_{$type}_Ignore_Table"} = explode(",", $server_slave_replication[0]["Replicate_Ignore_Table"]); + $replication_info[$type]['Ignore_Table'] = ${"server_{$type}_Ignore_Table"}; + + ${"server_{$type}_Wild_Do_Table"} = explode(",", $server_slave_replication[0]["Replicate_Wild_Do_Table"]); + $replication_info[$type]['Wild_Do_Table'] = ${"server_{$type}_Wild_Do_Table"}; + + ${"server_{$type}_Wild_Ignore_Table"} = explode(",", $server_slave_replication[0]["Replicate_Wild_Ignore_Table"]); + $replication_info[$type]['Wild_Ignore_Table'] = ${"server_{$type}_Wild_Ignore_Table"}; + } + } +} + +/** + * Extracts database or table name from string + * + * @param string $string contains "dbname.tablename" + * @param string $what what to extract (db|table) + * + * @return $string the extracted part + */ +function PMA_extract_db_or_table($string, $what = 'db') +{ + $list = explode(".", $string); + if ('db' == $what) { + return $list[0]; + } else { + return $list[1]; + } +} + +/** + * Configures replication slave + * + * @param string $action possible values: START or STOP + * @param string $control default: null, possible values: SQL_THREAD or IO_THREAD or null. + * If it is set to null, it controls both SQL_THREAD and IO_THREAD + * @param mixed $link mysql link + * + * @return mixed output of PMA_DBI_try_query + */ +function PMA_replication_slave_control($action, $control = null, $link = null) +{ + $action = strtoupper($action); + $control = strtoupper($control); + + if ($action != "START" && $action != "STOP") { + return -1; + } + if ($control != "SQL_THREAD" && $control != "IO_THREAD" && $control != null) { + return -1; + } + + return PMA_DBI_try_query($action . " SLAVE " . $control . ";", $link); +} + +/** + * Changes master for replication slave + * + * @param string $user replication user on master + * @param string $password password for the user + * @param string $host master's hostname or IP + * @param int $port port, where mysql is running + * @param array $pos position of mysql replication, + * array should contain fields File and Position + * @param bool $stop shall we stop slave? + * @param bool $start shall we start slave? + * @param mixed $link mysql link + * + * @return output of CHANGE MASTER mysql command + */ +function PMA_replication_slave_change_master($user, $password, $host, $port, + $pos, $stop = true, $start = true, $link = null +) { + if ($stop) { + PMA_replication_slave_control("STOP", null, $link); + } + + $out = PMA_DBI_try_query( + 'CHANGE MASTER TO ' . + 'MASTER_HOST=\'' . $host . '\',' . + 'MASTER_PORT=' . ($port * 1) . ',' . + 'MASTER_USER=\'' . $user . '\',' . + 'MASTER_PASSWORD=\'' . $password . '\',' . + 'MASTER_LOG_FILE=\'' . $pos["File"] . '\',' . + 'MASTER_LOG_POS=' . $pos["Position"] . ';', $link + ); + + if ($start) { + PMA_replication_slave_control("START", null, $link); + } + + return $out; +} + +/** + * This function provides connection to remote mysql server + * + * @param string $user mysql username + * @param string $password password for the user + * @param string $host mysql server's hostname or IP + * @param int $port mysql remote port + * @param string $socket path to unix socket + * + * @return mixed $link mysql link on success + */ +function PMA_replication_connect_to_master($user, $password, $host = null, $port = null, $socket = null) +{ + $server = array(); + $server["host"] = $host; + $server["port"] = $port; + $server["socket"] = $socket; + + // 5th parameter set to true means that it's an auxiliary connection + // and we must not go back to login page if it fails + return PMA_DBI_connect($user, $password, false, $server, true); +} +/** + * Fetches position and file of current binary log on master + * + * @param mixed $link mysql link + * + * @return array an array containing File and Position in MySQL replication + * on master server, useful for PMA_replication_slave_change_master + */ +function PMA_replication_slave_bin_log_master($link = null) +{ + $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $link); + $output = array(); + + if (! empty($data)) { + $output["File"] = $data[0]["File"]; + $output["Position"] = $data[0]["Position"]; + } + return $output; +} + +/** + * Get list of replicated databases on master server + * + * @param mixed $link mysql link + * + * @return array array of replicated databases + */ + +function PMA_replication_master_replicated_dbs($link = null) +{ + // let's find out, which databases are replicated + $data = PMA_DBI_fetch_result('SHOW MASTER STATUS', null, null, $link); + + $do_db = array(); + $ignore_db = array(); + + if (! empty($data[0]['Binlog_Do_DB'])) { + $do_db = explode(',', $data[0]['Binlog_Do_DB']); + } + if (! empty($data[0]['Binlog_Ignore_DB'])) { + $ignore_db = explode(',', $data[0]['Binlog_Ignore_DB']); + } + + $tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $link); + while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) { + if (PMA_is_system_schema($tmp_row[0])) { + continue; + } + if (count($do_db) == 0) { + if (array_search($tmp_row[0], $ignore_db) !== false) { + continue; + } + $dblist[] = $tmp_row[0]; + + } else { + if (array_search($tmp_row[0], $do_db) !== false) { + $dblist[] = $tmp_row[0]; + } + } + } // end while + + return $link; +} +?> diff --git a/phpmyadmin/libraries/replication_gui.lib.php b/phpmyadmin/libraries/replication_gui.lib.php new file mode 100644 index 000000000..3743f39fe --- /dev/null +++ b/phpmyadmin/libraries/replication_gui.lib.php @@ -0,0 +1,401 @@ +'; + + foreach ($GLOBALS['pma']->databases as $current_db) { + if (PMA_is_system_schema($current_db)) { + continue; + } + if (! empty($selectall) || (isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|'))) { + $is_selected = ' selected="selected"'; + } else { + $is_selected = ''; + } + $current_db = htmlspecialchars($current_db); + $multi_values .= ' '; + } // end while + + $multi_values .= ''; + $multi_values .= '
      ' . __('Uncheck All') . ''; + + return $multi_values; +} + +/** + * prints out code for changing master + * + * @param String $submitname - submit button name + * + * @return void + */ + +function PMA_replication_gui_changemaster($submitname) +{ + + list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length(); + + echo '
      '; + echo PMA_generate_common_hidden_inputs('', ''); + echo '
      '; + echo ' ' . __('Slave configuration') . ' - ' . __('Change or reconfigure master server') . ''; + echo __('Make sure, you have unique server-id in your configuration file (my.cnf). If not, please add the following line into [mysqld] section:') . '
      '; + echo '
      server-id=' . time() . '
      '; + echo '
      '; + echo ' '; + echo ' '; + echo '
      '; + echo '
      '; + echo ' '; + echo ' '; + echo '
      '; + echo '
      '; + echo ' '; + echo ' '; + echo '
      '; + echo '
      '; + echo ' '; + echo ' '; + echo '
      '; + echo '
      '; + echo ' '; + echo '
      '; +} + +/** + * This function prints out table with replication status. + * + * @param string $type either master or slave + * @param boolean $hidden if true, then default style is set to hidden, default value false + * @param boolen $title if true, then title is displayed, default true + * + * @return void + */ +function PMA_replication_print_status_table($type, $hidden = false, $title = true) +{ + global ${"{$type}_variables"}; + global ${"{$type}_variables_alerts"}; + global ${"{$type}_variables_oks"}; + global ${"server_{$type}_replication"}; + global ${"strReplicationStatus_{$type}"}; + + // TODO check the Masters server id? + // seems to default to '1' when queried via SHOW VARIABLES , but resulted in error on the master when slave connects + // [ERROR] Error reading packet from server: Misconfigured master - server id was not set ( server_errno=1236) + // [ERROR] Got fatal error 1236: 'Misconfigured master - server id was not set' from master when reading data from binary log + // + //$server_id = PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'server_id'", 0, 1); + + echo '
      '; + + if ($title) { + if ($type == 'master') { + echo '

      ' . __('Master status') . '

      '; + } else { + echo '

      ' . __('Slave status') . '

      '; + } + } else { + echo '
      '; + } + + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + + $odd_row = true; + foreach (${"{$type}_variables"} as $variable) { + echo ' '; + echo ' '; + echo ' '; + echo ' '; + + $odd_row = ! $odd_row; + } + + echo ' '; + echo '
      ' . __('Variable') . '' . __('Value') . '
      '; + echo $variable; + echo ' '; + + + // TODO change to regexp or something, to allow for negative match + if (isset(${"{$type}_variables_alerts"}[$variable]) + && ${"{$type}_variables_alerts"}[$variable] == ${"server_{$type}_replication"}[0][$variable] + ) { + echo ''; + + } elseif (isset(${"{$type}_variables_oks"}[$variable]) + && ${"{$type}_variables_oks"}[$variable] == ${"server_{$type}_replication"}[0][$variable] + ) { + echo ''; + } else { + echo ''; + } + // allow wrapping long table lists into multiple lines + static $variables_wrap = array( + 'Replicate_Do_DB', 'Replicate_Ignore_DB', + 'Replicate_Do_Table', 'Replicate_Ignore_Table', + 'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table'); + if (in_array($variable, $variables_wrap)) { + echo str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]); + } else { + echo ${"server_{$type}_replication"}[0][$variable]; + } + echo ''; + + echo '
      '; + echo '
      '; + echo '
      '; + +} + +/** + * Prints table with slave users connected to this master + * + * @param boolean $hidden - if true, then default style is set to hidden, default value false + * + * @return void + */ +function PMA_replication_print_slaves_table($hidden = false) +{ + + // Fetch data + $data = PMA_DBI_fetch_result('SHOW SLAVE HOSTS', null, null); + + echo '
      '; + echo '
      '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + echo ' '; + + $odd_row = true; + foreach ($data as $slave) { + echo ' '; + echo ' '; + echo ' '; + echo ' '; + + $odd_row = ! $odd_row; + } + + echo ' '; + echo '
      ' . __('Server ID') . '' . __('Host') . '
      ' . $slave['Server_id'] . '' . $slave['Host'] . '
      '; + echo '
      '; + PMA_Message::notice(__('Only slaves started with the --report-host=host_name option are visible in this list.'))->display(); + echo '
      '; + echo '
      '; +} + +/** + * get the correct username and hostname lengths for this MySQL server + * + * @return array username length, hostname length + */ + +function PMA_replication_get_username_hostname_length() +{ + $fields_info = PMA_DBI_get_columns('mysql', 'user'); + $username_length = 16; + $hostname_length = 41; + foreach ($fields_info as $val) { + if ($val['Field'] == 'User') { + strtok($val['Type'], '()'); + $v = strtok('()'); + if (is_int($v)) { + $username_length = $v; + } + } elseif ($val['Field'] == 'Host') { + strtok($val['Type'], '()'); + $v = strtok('()'); + if (is_int($v)) { + $hostname_length = $v; + } + } + } + return array($username_length, $hostname_length); +} + +/** + * Print code to add a replication slave user to the master + * + * @return void + */ +function PMA_replication_gui_master_addslaveuser() +{ + + list($username_length, $hostname_length) = PMA_replication_get_username_hostname_length(); + + if (isset($GLOBALS['username']) && strlen($GLOBALS['username']) === 0) { + $GLOBALS['pred_username'] = 'any'; + } + echo '
      '; + echo '
      '; + echo PMA_generate_common_hidden_inputs('', ''); + echo '
      ' + . ''.__('Add slave replication user').'' + . '' + . '' + . '' + . '' + . '' + . '' + . '
      ' + . '' + . '' + . ' ' + . '' + . '' + . '
      ' + . '
      ' + . '' + . '' + . ' ' + . '' + . '' + . PMA_Util::showHint( + __('When Host table is used, this field is ignored and values stored in Host table are used instead.') + ) + . '
      ' + . '
      ' + . '' + . '' + . ' ' + . '' + . '' + . '
      ' + . '
      ' + . '' + . ' ' + . '' + . '
      ' + . '
      ' + . '' + . '' + . ' ' + . '' + . '' + . '
      ' + . '
      '; + echo ''; + echo '
      '; + echo '
      '; +} +?> diff --git a/phpmyadmin/libraries/rte/rte_events.lib.php b/phpmyadmin/libraries/rte/rte_events.lib.php new file mode 100644 index 000000000..7d4ce6cf3 --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_events.lib.php @@ -0,0 +1,637 @@ + array('ENABLE', + 'DISABLE', + 'DISABLE ON SLAVE'), + 'display' => array('ENABLED', + 'DISABLED', + 'SLAVESIDE_DISABLED') + ); + $event_type = array('RECURRING', + 'ONE TIME'); + $event_interval = array('YEAR', + 'QUARTER', + 'MONTH', + 'DAY', + 'HOUR', + 'MINUTE', + 'WEEK', + 'SECOND', + 'YEAR_MONTH', + 'DAY_HOUR', + 'DAY_MINUTE', + 'DAY_SECOND', + 'HOUR_MINUTE', + 'HOUR_SECOND', + 'MINUTE_SECOND'); +} + +/** + * Main function for the events functionality + * + * @return void + */ +function PMA_EVN_main() +{ + global $db; + + PMA_EVN_setGlobals(); + /** + * Process all requests + */ + PMA_EVN_handleEditor(); + PMA_EVN_handleExport(); + /** + * Display a list of available events + */ + $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`"; + $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` " + . "WHERE $where ORDER BY `EVENT_NAME` ASC;"; + $items = PMA_DBI_fetch_result($query); + echo PMA_RTE_getList('event', $items); + /** + * Display a link for adding a new event, if + * the user has the privileges and a link to + * toggle the state of the event scheduler. + */ + echo PMA_EVN_getFooterLinks(); +} // end PMA_EVN_main() + +/** + * Handles editor requests for adding or editing an item + * + * @return void + */ +function PMA_EVN_handleEditor() +{ + global $_REQUEST, $_POST, $errors, $db; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + $sql_query = ''; + + $item_query = PMA_EVN_getQueryFromRequest(); + + if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest() + // Execute the created query + if (! empty($_REQUEST['editor_process_edit'])) { + // Backup the old trigger, in case something goes wrong + $create_item = PMA_DBI_get_definition( + $db, + 'EVENT', + $_REQUEST['item_original_name'] + ); + $drop_item = "DROP EVENT " + . PMA_Util::backquote($_REQUEST['item_original_name']) . ";\n"; + $result = PMA_DBI_try_query($drop_item); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($drop_item) + ) + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old item, but were unable to create + // the new one. Try to restore the backup query + $result = PMA_DBI_try_query($create_item); + if (! $result) { + // OMG, this is really bad! We dropped the query, + // failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle + // this just in case. + $errors[] = __( + 'Sorry, we failed to restore the dropped event.' + ) + . '
      ' + . __('The backed up query was:') + . "\"" . htmlspecialchars($create_item) . "\"" + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success( + __('Event %1$s has been modified.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $drop_item . $item_query; + } + } + } else { + // 'Add a new item' mode + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '

      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success( + __('Event %1$s has been created.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $item_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); + $message->addString('
        '); + foreach ($errors as $string) { + $message->addString('
      • ' . $string . '
      • '); + } + $message->addString('
      '); + } + + $output = PMA_Util::getMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + if ($message->isSuccess()) { + $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`"; + $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' " + . "AND EVENT_NAME='" + . PMA_Util::sqlAddSlashes($_REQUEST['item_name']) . "'"; + $query = "SELECT " . $columns + . " FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE " . $where. ";"; + $event = PMA_DBI_fetch_single_row($query); + $response->addJSON( + 'name', + htmlspecialchars(strtoupper($_REQUEST['item_name'])) + ); + $response->addJSON('new_row', PMA_EVN_getRowForList($event)); + $response->addJSON('insert', ! empty($event)); + $response->addJSON('message', $output); + } else { + $response->isSuccess(false); + $response->addJSON('message', $message); + } + exit; + } + } + /** + * Display a form used to add/edit a trigger, if necessary + */ + if (count($errors) + || (empty($_REQUEST['editor_process_add']) + && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) + || ! empty($_REQUEST['edit_item']) + || ! empty($_REQUEST['item_changetype']))) + ) { // FIXME: this must be simpler than that + $operation = ''; + if (! empty($_REQUEST['item_changetype'])) { + $operation = 'change'; + } + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = PMA_RTE_getWord('add'); + $item = PMA_EVN_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit event"); + if (! empty($_REQUEST['item_name']) + && empty($_REQUEST['editor_process_edit']) + && empty($_REQUEST['item_changetype']) + ) { + $item = PMA_EVN_getDataFromName($_REQUEST['item_name']); + if ($item !== false) { + $item['item_original_name'] = $item['item_name']; + } + } else { + $item = PMA_EVN_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($item !== false) { + // Show form + $editor = PMA_EVN_getEditorForm($mode, $operation, $item); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->addJSON('message', $editor); + $response->addJSON('title', $title); + } else { + echo "\n\n

      $title

      \n\n$editor"; + unset($_POST); + } + exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_Util::backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $message); + exit; + } else { + $message->display(); + } + } + } +} // end PMA_EVN_handleEditor() + +/** + * This function will generate the values that are required to for the editor + * + * @return array Data necessary to create the editor. + */ +function PMA_EVN_getDataFromRequest() +{ + $retval = array(); + $indices = array('item_name', + 'item_original_name', + 'item_status', + 'item_execute_at', + 'item_interval_value', + 'item_interval_field', + 'item_starts', + 'item_ends', + 'item_definition', + 'item_preserve', + 'item_comment', + 'item_definer'); + foreach ($indices as $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + $retval['item_type'] = 'ONE TIME'; + $retval['item_type_toggle'] = 'RECURRING'; + if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'RECURRING') { + $retval['item_type'] = 'RECURRING'; + $retval['item_type_toggle'] = 'ONE TIME'; + } + return $retval; +} // end PMA_EVN_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit event" form given the name of a event. + * + * @param string $name The name of the event. + * + * @return array Data necessary to create the editor. + */ +function PMA_EVN_getDataFromName($name) +{ + global $db; + + $retval = array(); + $columns = "`EVENT_NAME`, `STATUS`, `EVENT_TYPE`, `EXECUTE_AT`, " + . "`INTERVAL_VALUE`, `INTERVAL_FIELD`, `STARTS`, `ENDS`, " + . "`EVENT_DEFINITION`, `ON_COMPLETION`, `DEFINER`, `EVENT_COMMENT`"; + $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' " + . "AND EVENT_NAME='" . PMA_Util::sqlAddSlashes($name) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;"; + $item = PMA_DBI_fetch_single_row($query); + if (! $item) { + return false; + } + $retval['item_name'] = $item['EVENT_NAME']; + $retval['item_status'] = $item['STATUS']; + $retval['item_type'] = $item['EVENT_TYPE']; + if ($retval['item_type'] == 'RECURRING') { + $retval['item_type_toggle'] = 'ONE TIME'; + } else { + $retval['item_type_toggle'] = 'RECURRING'; + } + $retval['item_execute_at'] = $item['EXECUTE_AT']; + $retval['item_interval_value'] = $item['INTERVAL_VALUE']; + $retval['item_interval_field'] = $item['INTERVAL_FIELD']; + $retval['item_starts'] = $item['STARTS']; + $retval['item_ends'] = $item['ENDS']; + $retval['item_preserve'] = ''; + if ($item['ON_COMPLETION'] == 'PRESERVE') { + $retval['item_preserve'] = " checked='checked'"; + } + $retval['item_definition'] = $item['EVENT_DEFINITION']; + $retval['item_definer'] = $item['DEFINER']; + $retval['item_comment'] = $item['EVENT_COMMENT']; + + return $retval; +} // end PMA_EVN_getDataFromName() + +/** + * Displays a form used to add/edit an event + * + * @param string $mode If the editor will be used edit an event + * or add a new one: 'edit' or 'add'. + * @param string $operation If the editor was previously invoked with + * JS turned off, this will hold the name of + * the current operation + * @param array $item Data for the event returned by + * PMA_EVN_getDataFromRequest() or + * PMA_EVN_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_EVN_getEditorForm($mode, $operation, $item) +{ + global $db, $table, $event_status, $event_type, $event_interval; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_type', + 'item_execute_at', + 'item_interval_value', + 'item_starts', + 'item_ends', + 'item_definition', + 'item_definer', + 'item_comment' + ); + foreach ($need_escape as $index) { + $item[$index] = htmlentities($item[$index], ENT_QUOTES); + } + $original_data = ''; + if ($mode == 'edit') { + $original_data = "\n"; + } + // Handle some logic first + if ($operation == 'change') { + if ($item['item_type'] == 'RECURRING') { + $item['item_type'] = 'ONE TIME'; + $item['item_type_toggle'] = 'RECURRING'; + } else { + $item['item_type'] = 'RECURRING'; + $item['item_type_toggle'] = 'ONE TIME'; + } + } + if ($item['item_type'] == 'ONE TIME') { + $isrecurring_class = ' hide'; + $isonetime_class = ''; + } else { + $isrecurring_class = ''; + $isonetime_class = ' hide'; + } + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
      \n"; + $retval .= "\n"; + $retval .= $original_data; + $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n"; + $retval .= "
      \n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_RTN_getRowForList() + +/** + * Creates the contents for a row in the list of triggers + * + * @param array $trigger An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a cell for the list of triggers + */ +function PMA_TRI_getRowForList($trigger, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $table, $titles; + + $retval = " \n"; + $retval .= " \n"; + if (empty($table)) { + $retval .= " \n"; + } + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_TRI_getRowForList() + +/** + * Creates the contents for a row in the list of events + * + * @param array $event An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a cell for the list of events + */ +function PMA_EVN_getRowForList($event, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $titles; + + $sql_drop = sprintf( + 'DROP EVENT IF EXISTS %s', + PMA_Util::backquote($event['EVENT_NAME']) + ); + + $retval = " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_EVN_getRowForList() + +?> diff --git a/phpmyadmin/libraries/rte/rte_main.inc.php b/phpmyadmin/libraries/rte/rte_main.inc.php new file mode 100644 index 000000000..355240f70 --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_main.inc.php @@ -0,0 +1,92 @@ + '', + 'edit' => '', + 'exec' => '', + 'drop' => '', + 'export' => '' +); +$ajax_class = array( + 'add' => 'class="ajax add_anchor"', + 'edit' => 'class="ajax edit_anchor"', + 'exec' => 'class="ajax exec_anchor"', + 'drop' => 'class="ajax drop_anchor"', + 'export' => 'class="ajax export_anchor"' +); + +/** + * Create labels for the list + */ +$titles = PMA_Util::buildActionTitles(); + +/** + * Keep a list of errors that occured while + * processing an 'Add' or 'Edit' operation. + */ +$errors = array(); + + +/** + * Call the appropriate main function + */ +switch ($_PMA_RTE) { +case 'RTN': + PMA_RTN_main(); + break; +case 'TRI': + PMA_TRI_main(); + break; +case 'EVN': + PMA_EVN_main(); + break; +} + +?> diff --git a/phpmyadmin/libraries/rte/rte_routines.lib.php b/phpmyadmin/libraries/rte/rte_routines.lib.php new file mode 100644 index 000000000..b69c4bb4c --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_routines.lib.php @@ -0,0 +1,1676 @@ + '', + 1 => '', + 2 => '', + 3 => '', + 4 => ''); + $parsed_param = PMA_SQP_parse($value); + $pos = 0; + if (in_array(strtoupper($parsed_param[$pos]['data']), $param_directions)) { + $retval[0] = strtoupper($parsed_param[0]['data']); + $pos++; + } + if ($parsed_param[$pos]['type'] == 'alpha_identifier' + || $parsed_param[$pos]['type'] == 'quote_backtick' + ) { + $retval[1] = PMA_Util::unQuote( + $parsed_param[$pos]['data'] + ); + $pos++; + } + $depth = 0; + $param_length = ''; + $param_opts = array(); + for ($i=$pos; $i<$parsed_param['len']; $i++) { + if (($parsed_param[$i]['type'] == 'alpha_columnType' + || $parsed_param[$i]['type'] == 'alpha_functionName') && $depth == 0 + ) { + $retval[2] = strtoupper($parsed_param[$i]['data']); + } else if ($parsed_param[$i]['type'] == 'punct_bracket_open_round' + && $depth == 0 + ) { + $depth = 1; + } else if ($parsed_param[$i]['type'] == 'punct_bracket_close_round' + && $depth == 1 + ) { + $depth = 0; + } else if ($depth == 1) { + $param_length .= $parsed_param[$i]['data']; + } else if ($parsed_param[$i]['type'] == 'alpha_reservedWord' + && strtoupper($parsed_param[$i]['data']) == 'CHARSET' && $depth == 0 + ) { + if ($parsed_param[$i+1]['type'] == 'alpha_charset' + || $parsed_param[$i+1]['type'] == 'alpha_identifier' + ) { + $param_opts[] = strtolower($parsed_param[$i+1]['data']); + } + } else if ($parsed_param[$i]['type'] == 'alpha_columnAttrib' + && $depth == 0 + ) { + $param_opts[] = strtoupper($parsed_param[$i]['data']); + } + } + $retval[3] = $param_length; + sort($param_opts); + $retval[4] = implode(' ', $param_opts); + + return $retval; +} // end PMA_RTN_parseOneParameter() + +/** + * This function looks through the contents of a parsed + * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts + * information about the routine's parameters. + * + * @param array $parsed_query Parsed query, returned by by PMA_SQP_parse() + * @param string $routine_type Routine type: 'PROCEDURE' or 'FUNCTION' + * + * @return array Information about the parameteres of a routine. + */ +function PMA_RTN_parseAllParameters($parsed_query, $routine_type) +{ + $retval = array(); + $retval['num'] = 0; + + // First get the list of parameters from the query + $buffer = ''; + $params = array(); + $fetching = false; + $depth = 0; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' + && $parsed_query[$i]['data'] == $routine_type + ) { + $fetching = true; + } else if ($fetching == true + && $parsed_query[$i]['type'] == 'punct_bracket_open_round' + ) { + $depth++; + if ($depth > 1) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } + } else if ($fetching == true + && $parsed_query[$i]['type'] == 'punct_bracket_close_round' + ) { + $depth--; + if ($depth > 0) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } else { + break; + } + } else if ($parsed_query[$i]['type'] == 'punct_listsep' && $depth == 1) { + $params[] = $buffer; + $retval['num']++; + $buffer = ''; + } else if ($fetching == true && $depth > 0) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } + } + if (! empty($buffer)) { + $params[] = $buffer; + $retval['num']++; + } + // Now parse each parameter individually + foreach ($params as $key => $value) { + list($retval['dir'][], + $retval['name'][], + $retval['type'][], + $retval['length'][], + $retval['opts'][]) = PMA_RTN_parseOneParameter($value); + } + // Since some indices of $retval may be still undefined, we fill + // them each with an empty array to avoid E_ALL errors in PHP. + foreach (array('dir', 'name', 'type', 'length', 'opts') as $key => $index) { + if (! isset($retval[$index])) { + $retval[$index] = array(); + } + } + + return $retval; +} // end PMA_RTN_parseAllParameters() + +/** + * This function looks through the contents of a parsed + * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts + * information about the routine's definer. + * + * @param array $parsed_query Parsed query, returned by PMA_SQP_parse() + * + * @return string The definer of a routine. + */ +function PMA_RTN_parseRoutineDefiner($parsed_query) +{ + $retval = ''; + $fetching = false; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' + && $parsed_query[$i]['data'] == 'DEFINER' + ) { + $fetching = true; + } else if ($fetching == true + && $parsed_query[$i]['type'] != 'quote_backtick' + && substr($parsed_query[$i]['type'], 0, 5) != 'punct' + ) { + break; + } else if ($fetching == true + && $parsed_query[$i]['type'] == 'quote_backtick' + ) { + $retval .= PMA_Util::unQuote( + $parsed_query[$i]['data'] + ); + } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_user') { + $retval .= $parsed_query[$i]['data']; + } + } + return $retval; +} // end PMA_RTN_parseRoutineDefiner() + +/** + * Handles editor requests for adding or editing an item + * + * @return Does not return + */ +function PMA_RTN_handleEditor() +{ + global $_GET, $_POST, $_REQUEST, $GLOBALS, $db, $errors; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + /** + * Handle a request to create/edit a routine + */ + $sql_query = ''; + $routine_query = PMA_RTN_getQueryFromRequest(); + if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest() + // Execute the created query + if (! empty($_REQUEST['editor_process_edit'])) { + if (! in_array($_REQUEST['item_original_type'], array('PROCEDURE', 'FUNCTION'))) { + $errors[] = sprintf( + __('Invalid routine type: "%s"'), + htmlspecialchars($_REQUEST['item_original_type']) + ); + } else { + // Backup the old routine, in case something goes wrong + $create_routine = PMA_DBI_get_definition( + $db, $_REQUEST['item_original_type'], + $_REQUEST['item_original_name'] + ); + $drop_routine = "DROP {$_REQUEST['item_original_type']} " + . PMA_Util::backquote($_REQUEST['item_original_name']) + . ";\n"; + $result = PMA_DBI_try_query($drop_routine); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($drop_routine) + ) + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($routine_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($routine_query) + ) + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old routine, + // but were unable to create the new one + // Try to restore the backup query + $result = PMA_DBI_try_query($create_routine); + if (! $result) { + // OMG, this is really bad! We dropped the query, + // failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle + // this just in case. + $errors[] = __( + 'Sorry, we failed to restore' + . ' the dropped routine.' + ) + . '
      ' + . __('The backed up query was:') + . "\"" . htmlspecialchars($create_routine) . "\"" + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success( + __('Routine %1$s has been modified.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $drop_routine . $routine_query; + } + } + } + } else { + // 'Add a new routine' mode + $result = PMA_DBI_try_query($routine_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($routine_query) + ) + . '

      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success( + __('Routine %1$s has been created.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $routine_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error( + __( + 'One or more errors have occured while' + . ' processing your request:' + ) + ); + $message->addString('
        '); + foreach ($errors as $string) { + $message->addString('
      • ' . $string . '
      • '); + } + $message->addString('
      '); + } + + $output = PMA_Util::getMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + if ($message->isSuccess()) { + $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`," + . " `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`"; + $where = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' " + . "AND ROUTINE_NAME='" + . PMA_Util::sqlAddSlashes($_REQUEST['item_name']) . "'" + . "AND ROUTINE_TYPE='" + . PMA_Util::sqlAddSlashes($_REQUEST['item_type']) . "'"; + $routine = PMA_DBI_fetch_single_row( + "SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES`" + . " WHERE $where;" + ); + $response->addJSON( + 'name', htmlspecialchars(strtoupper($_REQUEST['item_name'])) + ); + $response->addJSON('new_row', PMA_RTN_getRowForList($routine)); + $response->addJSON('insert', ! empty($routine)); + $response->addJSON('message', $output); + } else { + $response->isSuccess(false); + $response->addJSON('message', $output); + } + exit; + } + } + + /** + * Display a form used to add/edit a routine, if necessary + */ + // FIXME: this must be simpler than that + if (count($errors) + || ( empty($_REQUEST['editor_process_add']) + && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item']) + || ! empty($_REQUEST['routine_addparameter']) + || ! empty($_REQUEST['routine_removeparameter']) + || ! empty($_REQUEST['routine_changetype']))) + ) { + // Handle requests to add/remove parameters and changing routine type + // This is necessary when JS is disabled + $operation = ''; + if (! empty($_REQUEST['routine_addparameter'])) { + $operation = 'add'; + } else if (! empty($_REQUEST['routine_removeparameter'])) { + $operation = 'remove'; + } else if (! empty($_REQUEST['routine_changetype'])) { + $operation = 'change'; + } + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = PMA_RTE_getWord('add'); + $routine = PMA_RTN_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit routine"); + if (! $operation && ! empty($_REQUEST['item_name']) + && empty($_REQUEST['editor_process_edit']) + ) { + $routine = PMA_RTN_getDataFromName( + $_REQUEST['item_name'], $_REQUEST['item_type'] + ); + if ($routine !== false) { + $routine['item_original_name'] = $routine['item_name']; + $routine['item_original_type'] = $routine['item_type']; + } + } else { + $routine = PMA_RTN_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($routine !== false) { + // Show form + $editor = PMA_RTN_getEditorForm($mode, $operation, $routine); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->addJSON('message', $editor); + $response->addJSON('title', $title); + $response->addJSON('param_template', PMA_RTN_getParameterRow()); + $response->addJSON('type', $routine['item_type']); + } else { + echo "\n\n

      $title

      \n\n$editor"; + } + exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_Util::backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + $response->isSuccess(false); + $response->addJSON('message', $message); + exit; + } else { + $message->display(); + } + } + } +} // end PMA_RTN_handleEditor() + +/** + * This function will generate the values that are required to + * complete the editor form. It is especially necessary to handle + * the 'Add another parameter', 'Remove last parameter' and + * 'Change routine type' functionalities when JS is disabled. + * + * @return array Data necessary to create the routine editor. + */ +function PMA_RTN_getDataFromRequest() +{ + global $_REQUEST, $param_directions, $param_sqldataaccess; + + $retval = array(); + $indices = array('item_name', + 'item_original_name', + 'item_returnlength', + 'item_returnopts_num', + 'item_returnopts_text', + 'item_definition', + 'item_comment', + 'item_definer'); + foreach ($indices as $key => $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + + $retval['item_type'] = 'PROCEDURE'; + $retval['item_type_toggle'] = 'FUNCTION'; + if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'FUNCTION') { + $retval['item_type'] = 'FUNCTION'; + $retval['item_type_toggle'] = 'PROCEDURE'; + } + $retval['item_original_type'] = 'PROCEDURE'; + if (isset($_REQUEST['item_original_type']) + && $_REQUEST['item_original_type'] == 'FUNCTION' + ) { + $retval['item_original_type'] = 'FUNCTION'; + } + $retval['item_num_params'] = 0; + $retval['item_param_dir'] = array(); + $retval['item_param_name'] = array(); + $retval['item_param_type'] = array(); + $retval['item_param_length'] = array(); + $retval['item_param_opts_num'] = array(); + $retval['item_param_opts_text'] = array(); + if ( isset($_REQUEST['item_param_name']) + && isset($_REQUEST['item_param_type']) + && isset($_REQUEST['item_param_length']) + && isset($_REQUEST['item_param_opts_num']) + && isset($_REQUEST['item_param_opts_text']) + && is_array($_REQUEST['item_param_name']) + && is_array($_REQUEST['item_param_type']) + && is_array($_REQUEST['item_param_length']) + && is_array($_REQUEST['item_param_opts_num']) + && is_array($_REQUEST['item_param_opts_text']) + ) { + if ($_REQUEST['item_type'] == 'PROCEDURE') { + $retval['item_param_dir'] = $_REQUEST['item_param_dir']; + foreach ($retval['item_param_dir'] as $key => $value) { + if (! in_array($value, $param_directions, true)) { + $retval['item_param_dir'][$key] = ''; + } + } + } + $retval['item_param_name'] = $_REQUEST['item_param_name']; + $retval['item_param_type'] = $_REQUEST['item_param_type']; + foreach ($retval['item_param_type'] as $key => $value) { + if (! in_array($value, PMA_Util::getSupportedDatatypes(), true)) { + $retval['item_param_type'][$key] = ''; + } + } + $retval['item_param_length'] = $_REQUEST['item_param_length']; + $retval['item_param_opts_num'] = $_REQUEST['item_param_opts_num']; + $retval['item_param_opts_text'] = $_REQUEST['item_param_opts_text']; + $retval['item_num_params'] = max( + count($retval['item_param_name']), + count($retval['item_param_type']), + count($retval['item_param_length']), + count($retval['item_param_opts_num']), + count($retval['item_param_opts_text']) + ); + } + $retval['item_returntype'] = ''; + if (isset($_REQUEST['item_returntype']) + && in_array($_REQUEST['item_returntype'], PMA_Util::getSupportedDatatypes()) + ) { + $retval['item_returntype'] = $_REQUEST['item_returntype']; + } + + $retval['item_isdeterministic'] = ''; + if (isset($_REQUEST['item_isdeterministic']) + && strtolower($_REQUEST['item_isdeterministic']) == 'on' + ) { + $retval['item_isdeterministic'] = " checked='checked'"; + } + $retval['item_securitytype_definer'] = ''; + $retval['item_securitytype_invoker'] = ''; + if (isset($_REQUEST['item_securitytype'])) { + if ($_REQUEST['item_securitytype'] === 'DEFINER') { + $retval['item_securitytype_definer'] = " selected='selected'"; + } else if ($_REQUEST['item_securitytype'] === 'INVOKER') { + $retval['item_securitytype_invoker'] = " selected='selected'"; + } + } + $retval['item_sqldataaccess'] = ''; + if (isset($_REQUEST['item_sqldataaccess']) + && in_array($_REQUEST['item_sqldataaccess'], $param_sqldataaccess, true) + ) { + $retval['item_sqldataaccess'] = $_REQUEST['item_sqldataaccess']; + } + + return $retval; +} // end function PMA_RTN_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit routine" form given the name of a routine. + * + * @param string $name The name of the routine. + * @param string $type Type of routine (ROUTINE|PROCEDURE) + * @param bool $all Whether to return all data or just + * the info about parameters. + * + * @return array Data necessary to create the routine editor. + */ +function PMA_RTN_getDataFromName($name, $type, $all = true) +{ + global $db; + + $retval = array(); + + // Build and execute the query + $fields = "SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, " + . "ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, " + . "ROUTINE_COMMENT, SECURITY_TYPE"; + $where = "ROUTINE_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' " + . "AND SPECIFIC_NAME='" . PMA_Util::sqlAddSlashes($name) . "'" + . "AND ROUTINE_TYPE='" . PMA_Util::sqlAddSlashes($type) . "'"; + $query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;"; + + $routine = PMA_DBI_fetch_single_row($query); + + if (! $routine) { + return false; + } + + // Get required data + $retval['item_name'] = $routine['SPECIFIC_NAME']; + $retval['item_type'] = $routine['ROUTINE_TYPE']; + $parsed_query = PMA_SQP_parse( + PMA_DBI_get_definition( + $db, + $routine['ROUTINE_TYPE'], + $routine['SPECIFIC_NAME'] + ) + ); + $params = PMA_RTN_parseAllParameters($parsed_query, $routine['ROUTINE_TYPE']); + $retval['item_num_params'] = $params['num']; + $retval['item_param_dir'] = $params['dir']; + $retval['item_param_name'] = $params['name']; + $retval['item_param_type'] = $params['type']; + $retval['item_param_length'] = $params['length']; + $retval['item_param_opts_num'] = $params['opts']; + $retval['item_param_opts_text'] = $params['opts']; + + // Get extra data + if ($all) { + if ($retval['item_type'] == 'FUNCTION') { + $retval['item_type_toggle'] = 'PROCEDURE'; + } else { + $retval['item_type_toggle'] = 'FUNCTION'; + } + $retval['item_returntype'] = ''; + $retval['item_returnlength'] = ''; + $retval['item_returnopts_num'] = ''; + $retval['item_returnopts_text'] = ''; + if (! empty($routine['DTD_IDENTIFIER'])) { + if (strlen($routine['DTD_IDENTIFIER']) > 63) { + // If the DTD_IDENTIFIER string from INFORMATION_SCHEMA is + // at least 64 characters, then it may actually have been + // chopped because that column is a varchar(64), so we will + // parse the output of SHOW CREATE query to get accurate + // information about the return variable. + $dtd = ''; + $fetching = false; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' + && strtoupper($parsed_query[$i]['data']) == 'RETURNS' + ) { + $fetching = true; + } else if ($fetching == true + && $parsed_query[$i]['type'] == 'alpha_reservedWord' + ) { + // We will not be looking for options such as UNSIGNED + // or ZEROFILL because there is no way that a numeric + // field's DTD_IDENTIFIER can be longer than 64 + // characters. We can safely assume that the return + // datatype is either ENUM or SET, so we only look + // for CHARSET. + $word = strtoupper($parsed_query[$i]['data']); + if ($word == 'CHARSET' + && ($parsed_query[$i+1]['type'] == 'alpha_charset' + || $parsed_query[$i+1]['type'] == 'alpha_identifier') + ) { + $dtd .= $word . ' ' . $parsed_query[$i+1]['data']; + } + break; + } else if ($fetching == true) { + $dtd .= $parsed_query[$i]['data'] . ' '; + } + } + $routine['DTD_IDENTIFIER'] = $dtd; + } + $returnparam = PMA_RTN_parseOneParameter($routine['DTD_IDENTIFIER']); + $retval['item_returntype'] = $returnparam[2]; + $retval['item_returnlength'] = $returnparam[3]; + $retval['item_returnopts_num'] = $returnparam[4]; + $retval['item_returnopts_text'] = $returnparam[4]; + } + $retval['item_definer'] = PMA_RTN_parseRoutineDefiner($parsed_query); + $retval['item_definition'] = $routine['ROUTINE_DEFINITION']; + $retval['item_isdeterministic'] = ''; + if ($routine['IS_DETERMINISTIC'] == 'YES') { + $retval['item_isdeterministic'] = " checked='checked'"; + } + $retval['item_securitytype_definer'] = ''; + $retval['item_securitytype_invoker'] = ''; + if ($routine['SECURITY_TYPE'] == 'DEFINER') { + $retval['item_securitytype_definer'] = " selected='selected'"; + } else if ($routine['SECURITY_TYPE'] == 'INVOKER') { + $retval['item_securitytype_invoker'] = " selected='selected'"; + } + $retval['item_sqldataaccess'] = $routine['SQL_DATA_ACCESS']; + $retval['item_comment'] = $routine['ROUTINE_COMMENT']; + } + + return $retval; +} // PMA_RTN_getDataFromName() + +/** + * Creates one row for the parameter table used in the routine editor. + * + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromRequest() or + * PMA_RTN_getDataFromName() + * @param mixed $index Either a numeric index of the row being processed + * or NULL to create a template row for AJAX request + * @param string $class Class used to hide the direction column, if the + * row is for a stored function. + * + * @return string HTML code of one row of parameter table for the editor. + */ +function PMA_RTN_getParameterRow($routine = array(), $index = null, $class = '') +{ + global $param_directions, $param_opts_num, $titles; + + if ($index === null) { + // template row for AJAX request + $i = 0; + $index = '%s'; + $drop_class = ''; + $routine = array( + 'item_param_dir' => array(0 => ''), + 'item_param_name' => array(0 => ''), + 'item_param_type' => array(0 => ''), + 'item_param_length' => array(0 => ''), + 'item_param_opts_num' => array(0 => ''), + 'item_param_opts_text' => array(0 => '') + ); + } else if (! empty($routine)) { + // regular row for routine editor + $drop_class = ' hide'; + $i = $index; + } else { + // No input data. This shouldn't happen, + // but better be safe than sorry. + return ''; + } + + // Create the output + $retval = ""; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_RTN_getParameterRow() + +/** + * Displays a form used to add/edit a routine + * + * @param string $mode If the editor will be used edit a routine + * or add a new one: 'edit' or 'add'. + * @param string $operation If the editor was previously invoked with + * JS turned off, this will hold the name of + * the current operation + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromRequest() or + * PMA_RTN_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_RTN_getEditorForm($mode, $operation, $routine) +{ + global $db, $errors, $param_sqldataaccess, $param_opts_num; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_returnlength', + 'item_definition', + 'item_definer', + 'item_comment' + ); + foreach ($need_escape as $key => $index) { + $routine[$index] = htmlentities($routine[$index], ENT_QUOTES, 'UTF-8'); + } + for ($i=0; $i<$routine['item_num_params']; $i++) { + $routine['item_param_name'][$i] = htmlentities( + $routine['item_param_name'][$i], + ENT_QUOTES + ); + $routine['item_param_length'][$i] = htmlentities( + $routine['item_param_length'][$i], + ENT_QUOTES + ); + } + + // Handle some logic first + if ($operation == 'change') { + if ($routine['item_type'] == 'PROCEDURE') { + $routine['item_type'] = 'FUNCTION'; + $routine['item_type_toggle'] = 'PROCEDURE'; + } else { + $routine['item_type'] = 'PROCEDURE'; + $routine['item_type_toggle'] = 'FUNCTION'; + } + } else if ($operation == 'add' + || ($routine['item_num_params'] == 0 && $mode == 'add' && ! $errors) + ) { + $routine['item_param_dir'][] = ''; + $routine['item_param_name'][] = ''; + $routine['item_param_type'][] = ''; + $routine['item_param_length'][] = ''; + $routine['item_param_opts_num'][] = ''; + $routine['item_param_opts_text'][] = ''; + $routine['item_num_params']++; + } else if ($operation == 'remove') { + unset($routine['item_param_dir'][$routine['item_num_params']-1]); + unset($routine['item_param_name'][$routine['item_num_params']-1]); + unset($routine['item_param_type'][$routine['item_num_params']-1]); + unset($routine['item_param_length'][$routine['item_num_params']-1]); + unset($routine['item_param_opts_num'][$routine['item_num_params']-1]); + unset($routine['item_param_opts_text'][$routine['item_num_params']-1]); + $routine['item_num_params']--; + } + $disable_remove_parameter = ''; + if (! $routine['item_num_params']) { + $disable_remove_parameter = " color: gray;' disabled='disabled"; + } + $original_routine = ''; + if ($mode == 'edit') { + $original_routine = "\n" + . "\n"; + } + $isfunction_class = ''; + $isprocedure_class = ''; + $isfunction_select = ''; + $isprocedure_select = ''; + if ($routine['item_type'] == 'PROCEDURE') { + $isfunction_class = ' hide'; + $isprocedure_select = " selected='selected'"; + } else { + $isprocedure_class = ' hide'; + $isfunction_select = " selected='selected'"; + } + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= $original_routine; + $retval .= PMA_generate_common_hidden_inputs($db) . "\n"; + $retval .= "
      \n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "
      " . __('Event name') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
      " . __('Event type') . "\n"; + if ($GLOBALS['is_ajax_request']) { + $retval .= " \n"; + } else { + $retval .= " \n"; + $retval .= " {$item['item_type']}\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " $value) { + $selected = ""; + if (! empty($item['item_interval_field']) + && $item['item_interval_field'] == $value + ) { + $selected = " selected='selected'"; + } + $retval .= "$value"; + } + $retval .= " \n"; + $retval .= "
      " . _pgettext('Start of recurring event', 'Start'); + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
      " . __('On completion preserve') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_EVN_getEditorForm() + +/** + * Composes the query necessary to create an event from an HTTP request. + * + * @return string The CREATE EVENT query. + */ +function PMA_EVN_getQueryFromRequest() +{ + global $_REQUEST, $errors, $event_status, $event_type, $event_interval; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]); + $query .= '@' . PMA_Util::backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + $query .= 'EVENT '; + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_Util::backquote($_REQUEST['item_name']) . ' '; + } else { + $errors[] = __('You must provide an event name'); + } + $query .= 'ON SCHEDULE '; + if (! empty($_REQUEST['item_type']) + && in_array($_REQUEST['item_type'], $event_type) + ) { + if ($_REQUEST['item_type'] == 'RECURRING') { + if (! empty($_REQUEST['item_interval_value']) + && !empty($_REQUEST['item_interval_field']) + && in_array($_REQUEST['item_interval_field'], $event_interval) + ) { + $query .= 'EVERY ' . intval($_REQUEST['item_interval_value']) . ' '; + $query .= $_REQUEST['item_interval_field'] . ' '; + } else { + $errors[] = __('You must provide a valid interval value for the event.'); + } + if (! empty($_REQUEST['item_starts'])) { + $query .= "STARTS '" + . PMA_Util::sqlAddSlashes($_REQUEST['item_starts']) . "' "; + } + if (! empty($_REQUEST['item_ends'])) { + $query .= "ENDS '" + . PMA_Util::sqlAddSlashes($_REQUEST['item_ends']) . "' "; + } + } else { + if (! empty($_REQUEST['item_execute_at'])) { + $query .= "AT '" + . PMA_Util::sqlAddSlashes($_REQUEST['item_execute_at']) . "' "; + } else { + $errors[] = __('You must provide a valid execution time for the event.'); + } + } + } else { + $errors[] = __('You must provide a valid type for the event.'); + } + $query .= 'ON COMPLETION '; + if (empty($_REQUEST['item_preserve'])) { + $query .= 'NOT '; + } + $query .= 'PRESERVE '; + if (! empty($_REQUEST['item_status'])) { + foreach ($event_status['display'] as $key => $value) { + if ($value == $_REQUEST['item_status']) { + $query .= $event_status['query'][$key] . ' '; + break; + } + } + } + if (! empty($_REQUEST['item_comment'])) { + $query .= "COMMENT '" . PMA_Util::sqlAddslashes( + $_REQUEST['item_comment'] + ) . "' "; + } + $query .= 'DO '; + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide an event definition.'); + } + + return $query; +} // end PMA_EVN_getQueryFromRequest() + +?> diff --git a/phpmyadmin/libraries/rte/rte_export.lib.php b/phpmyadmin/libraries/rte/rte_export.lib.php new file mode 100644 index 000000000..a553ae9be --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_export.lib.php @@ -0,0 +1,122 @@ +' + . htmlspecialchars(trim($export_data)) . ''; + $title = sprintf(PMA_RTE_getWord('export'), $item_name); + if ($GLOBALS['is_ajax_request'] == true) { + $response = PMA_Response::getInstance(); + $response->addJSON('message', $export_data); + $response->addJSON('title', $title); + exit; + } else { + echo "
      \n" + . "$title\n" + . $export_data + . "
      \n"; + } + } else { + $_db = htmlspecialchars(PMA_Util::backquote($db)); + $response = __('Error in Processing Request') . ' : ' + . sprintf(PMA_RTE_getWord('not_found'), $item_name, $_db); + $response = PMA_message::error($response); + if ($GLOBALS['is_ajax_request'] == true) { + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $response); + exit; + } else { + $response->display(); + } + } +} // end PMA_RTE_handleExport() + +/** + * If necessary, prepares event information and passes + * it to PMA_RTE_handleExport() for the actual export. + * + * @return void + */ +function PMA_EVN_handleExport() +{ + global $_GET, $db; + + if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) { + $item_name = $_GET['item_name']; + $export_data = PMA_DBI_get_definition($db, 'EVENT', $item_name); + PMA_RTE_handleExport($item_name, $export_data); + } +} // end PMA_EVN_handleExport() + +/** + * If necessary, prepares routine information and passes + * it to PMA_RTE_handleExport() for the actual export. + * + * @return void + */ +function PMA_RTN_handleExport() +{ + global $_GET, $db; + + if ( ! empty($_GET['export_item']) + && ! empty($_GET['item_name']) + && ! empty($_GET['item_type']) + ) { + if ($_GET['item_type'] == 'FUNCTION' || $_GET['item_type'] == 'PROCEDURE') { + $export_data = PMA_DBI_get_definition( + $db, + $_GET['item_type'], + $_GET['item_name'] + ); + PMA_RTE_handleExport($_GET['item_name'], $export_data); + } + } +} // end PMA_RTN_handleExport() + +/** + * If necessary, prepares trigger information and passes + * it to PMA_RTE_handleExport() for the actual export. + * + * @return void + */ +function PMA_TRI_handleExport() +{ + global $_GET, $db, $table; + + if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) { + $item_name = $_GET['item_name']; + $triggers = PMA_DBI_get_triggers($db, $table, ''); + $export_data = false; + foreach ($triggers as $trigger) { + if ($trigger['name'] === $item_name) { + $export_data = $trigger['create']; + break; + } + } + PMA_RTE_handleExport($item_name, $export_data); + } +} // end PMA_TRI_handleExport() +?> diff --git a/phpmyadmin/libraries/rte/rte_footer.lib.php b/phpmyadmin/libraries/rte/rte_footer.lib.php new file mode 100644 index 000000000..88d31d35a --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_footer.lib.php @@ -0,0 +1,127 @@ +\n"; + $retval .= "
      \n"; + $retval .= " " . _pgettext('Create new procedure', 'New') . "\n"; + $retval .= " \n"; + $retval .= "
      \n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTE_getFooterLinks() + +/** + * Creates a fieldset for adding a new routine, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_RTN_getFooterLinks() +{ + return PMA_RTE_getFooterLinks('CREATE_PROCEDURE', 'CREATE ROUTINE', 'ROUTINE'); +}// end PMA_RTN_getFooterLinks() + +/** + * Creates a fieldset for adding a new trigger, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_TRI_getFooterLinks() +{ + return PMA_RTE_getFooterLinks('CREATE_TRIGGER', 'TRIGGER', 'TRIGGER'); +} // end PMA_TRI_getFooterLinks() + +/** + * Creates a fieldset for adding a new event, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_EVN_getFooterLinks() +{ + global $db, $url_query; + + /** + * For events, we show the usual 'Add event' form and also + * a form for toggling the state of the event scheduler + */ + // Init options for the event scheduler toggle functionality + $es_state = PMA_DBI_fetch_value( + "SHOW GLOBAL VARIABLES LIKE 'event_scheduler'", + 0, + 1 + ); + $es_state = strtolower($es_state); + $options = array( + 0 => array( + 'label' => __('OFF'), + 'value' => "SET GLOBAL event_scheduler=\"OFF\"", + 'selected' => ($es_state != 'on') + ), + 1 => array( + 'label' => __('ON'), + 'value' => "SET GLOBAL event_scheduler=\"ON\"", + 'selected' => ($es_state == 'on') + ) + ); + // Generate output + $retval = "\n"; + $retval .= "
      \n"; + // show the usual footer + $retval .= PMA_RTE_getFooterLinks('CREATE_EVENT', 'EVENT', 'EVENT'); + $retval .= "
      \n"; + $retval .= " \n"; + $retval .= " " . __('Event scheduler status') . "\n"; + $retval .= " \n"; + $retval .= "
      \n"; + // show the toggle button + $retval .= PMA_Util::toggleButton( + "sql.php?$url_query&goto=db_events.php" . urlencode("?db=$db"), + 'sql_query', + $options, + 'PMA_slidingMessage(data.sql_query);' + ); + $retval .= "
      \n"; + $retval .= "
      \n"; + $retval .= "
      \n"; + $retval .= "
      "; + $retval .= "\n"; + + return $retval; +} // end PMA_EVN_getFooterLinks() + +?> diff --git a/phpmyadmin/libraries/rte/rte_list.lib.php b/phpmyadmin/libraries/rte/rte_list.lib.php new file mode 100644 index 000000000..d531cd86f --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_list.lib.php @@ -0,0 +1,366 @@ +\n"; + $retval .= "
      \n"; + $retval .= " \n"; + $retval .= " " . PMA_RTE_getWord('title') . "\n"; + $retval .= " " . PMA_Util::showMySQLDocu('SQL-Syntax', PMA_RTE_getWord('docu')) . "\n"; + $retval .= " \n"; + $retval .= "
      \n"; + $retval .= " " . PMA_RTE_getWord('nothing') . "\n"; + $retval .= "
      \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + // th cells with a colspan need corresponding td cells, according to W3C + switch ($type) { + case 'routine': + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; // see comment above + for ($i = 0; $i < 7; $i++) { + $retval .= " \n"; + } + break; + case 'trigger': + $retval .= " \n"; + if (empty($table)) { + $retval .= " \n"; + } + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; // see comment above + for ($i = 0; $i < (empty($table) ? 7 : 6); $i++) { + $retval .= " \n"; + } + break; + case 'event': + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; // see comment above + for ($i = 0; $i < 6; $i++) { + $retval .= " \n"; + } + break; + default: + break; + } + $retval .= " \n"; + $retval .= " \n"; + $ct = 0; + foreach ($items as $item) { + $rowclass = ($ct % 2 == 0) ? 'odd' : 'even'; + if ($GLOBALS['is_ajax_request'] && empty($_REQUEST['ajax_page_request'])) { + $rowclass .= ' ajaxInsert hide'; + } + // Get each row from the correct function + switch ($type) { + case 'routine': + $retval .= PMA_RTN_getRowForList($item, $rowclass); + break; + case 'trigger': + $retval .= PMA_TRI_getRowForList($item, $rowclass); + break; + case 'event': + $retval .= PMA_EVN_getRowForList($item, $rowclass); + break; + default: + break; + } + $ct++; + } + $retval .= "
      " . __('Name') . "" . __('Action') . "" . __('Type') . "" . __('Returns') . "
      " . __('Name') . "" . __('Table') . "" . __('Action') . "" . __('Time') . "" . __('Event') . "
      " . __('Name') . "" . __('Status') . "" . __('Action') . "" . __('Type') . "
      \n"; + $retval .= "
      \n"; + $retval .= "\n"; + + return $retval; +} // end PMA_RTE_getList() + +/** + * Creates the contents for a row in the list of routines + * + * @param array $routine An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a row for the list of routines + */ +function PMA_RTN_getRowForList($routine, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $titles; + + $sql_drop = sprintf( + 'DROP %s IF EXISTS %s', + $routine['ROUTINE_TYPE'], + PMA_Util::backquote($routine['SPECIFIC_NAME']) + ); + $type_link = "item_type={$routine['ROUTINE_TYPE']}"; + + $retval = "
      \n"; + $retval .= " " . htmlspecialchars($sql_drop) . "\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($routine['SPECIFIC_NAME']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + if ($routine['ROUTINE_DEFINITION'] !== null + && PMA_Util::currentUserHasPrivilege('ALTER ROUTINE', $db) + && PMA_Util::currentUserHasPrivilege('CREATE ROUTINE', $db) + ) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + if ($routine['ROUTINE_DEFINITION'] !== null + && PMA_Util::currentUserHasPrivilege('EXECUTE', $db) + ) { + // Check if he routine has any input parameters. If it does, + // we will show a dialog to get values for these parameters, + // otherwise we can execute it directly. + $routine_details = PMA_RTN_getDataFromName( + $routine['SPECIFIC_NAME'], + $routine['ROUTINE_TYPE'], + false + ); + if ($routine !== false) { + $execute_action = 'execute_routine'; + for ($i=0; $i<$routine_details['item_num_params']; $i++) { + if ($routine_details['item_type'] == 'PROCEDURE' + && $routine_details['item_param_dir'][$i] == 'OUT' + ) { + continue; + } + $execute_action = 'execute_dialog'; + break; + } + $retval .= ' ' . $titles['Execute'] . "\n"; + } + } else { + $retval .= " {$titles['NoExecute']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_Util::currentUserHasPrivilege('ALTER ROUTINE', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$routine['ROUTINE_TYPE']}\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($routine['DTD_IDENTIFIER']) . "\n"; + $retval .= "
      \n"; + $retval .= " " . htmlspecialchars($trigger['drop']) . "\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($trigger['name']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " " + . $trigger['table'] . "\n"; + $retval .= " \n"; + if (PMA_Util::currentUserHasPrivilege('TRIGGER', $db, $table)) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_Util::currentUserHasPrivilege('TRIGGER', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$trigger['action_timing']}\n"; + $retval .= " \n"; + $retval .= " {$trigger['event_manipulation']}\n"; + $retval .= "
      \n"; + $retval .= " " . htmlspecialchars($sql_drop) . "\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($event['EVENT_NAME']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " {$event['STATUS']}\n"; + $retval .= " \n"; + if (PMA_Util::currentUserHasPrivilege('EVENT', $db)) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_Util::currentUserHasPrivilege('EVENT', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$event['EVENT_TYPE']}\n"; + $retval .= "
      \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " ---\n"; + $retval .= PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_CHARSET, + "item_param_opts_text[$index]", + null, + $routine['item_param_opts_text'][$i] + ); + $retval .= " ---\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " {$titles['Drop']}\n"; + $retval .= " \n"; + $retval .= "
      \n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + // parameter handling end + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= "
      " . __('Routine name') . "\n"; + $retval .= " \n"; + if ($GLOBALS['is_ajax_request']) { + $retval .= " \n"; + } else { + $retval .= "\n" + . "
      \n" + . $routine['item_type'] . "\n" + . "
      \n" + . "\n"; + } + $retval .= "
      " . __('Parameters') . "\n"; + // parameter handling start + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " "; + for ($i=0; $i<$routine['item_num_params']; $i++) { // each parameter + $retval .= PMA_RTN_getParameterRow($routine, $i, $isprocedure_class); + } + $retval .= "
      " + . __('Direction') . "" . __('Name') . "" . __('Type') . "" . __('Length/Values') . "" . __('Options') . " 
      \n"; + $retval .= "
       \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
      " . __('Return type') . "
      " . __('Return length/values') . "\n"; + $retval .= "
      \n"; + $retval .= PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_CHARSET, + "item_returnopts_text", + null, + $routine['item_returnopts_text'] + ); + $retval .= "\n
      \n"; + $retval .= "
      \n"; + $retval .= "
      ---
      \n"; + $retval .= "
      " . __('Definition') . "
      " . __('Is deterministic') . "
      " . __('Definer') . "\n"; + $retval .= "
      " . __('SQL data access') . "
      " . __('Comment') . "\n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTN_getEditorForm() + +/** + * Composes the query necessary to create a routine from an HTTP request. + * + * @return string The CREATE [ROUTINE | PROCEDURE] query. + */ +function PMA_RTN_getQueryFromRequest() +{ + global $_REQUEST, $errors, $param_sqldataaccess, $param_directions; + + $_REQUEST['item_type'] = isset($_REQUEST['item_type']) + ? $_REQUEST['item_type'] : ''; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]); + $query .= '@' . PMA_Util::backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + if ($_REQUEST['item_type'] == 'FUNCTION' + || $_REQUEST['item_type'] == 'PROCEDURE' + ) { + $query .= $_REQUEST['item_type'] . ' '; + } else { + $errors[] = sprintf( + __('Invalid routine type: "%s"'), + htmlspecialchars($_REQUEST['item_type']) + ); + } + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_Util::backquote($_REQUEST['item_name']); + } else { + $errors[] = __('You must provide a routine name'); + } + $params = ''; + $warned_about_dir = false; + $warned_about_name = false; + $warned_about_length = false; + if ( ! empty($_REQUEST['item_param_name']) + && ! empty($_REQUEST['item_param_type']) + && ! empty($_REQUEST['item_param_length']) + && is_array($_REQUEST['item_param_name']) + && is_array($_REQUEST['item_param_type']) + && is_array($_REQUEST['item_param_length']) + ) { + for ($i=0; $igetTypeClass($_REQUEST['item_param_type'][$i]) == 'CHAR') { + $params .= ' CHARSET ' + . strtolower($_REQUEST['item_param_opts_text'][$i]); + } + } + if (! empty($_REQUEST['item_param_opts_num'][$i])) { + if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_param_type'][$i]) == 'NUMBER') { + $params .= ' ' + . strtoupper($_REQUEST['item_param_opts_num'][$i]); + } + } + if ($i != count($_REQUEST['item_param_name'])-1) { + $params .= ", "; + } + } else if (! $warned_about_name) { + $warned_about_name = true; + $errors[] = __( + 'You must provide a name and a type for each routine parameter.' + ); + break; + } + } + } + $query .= "(" . $params . ") "; + if ($_REQUEST['item_type'] == 'FUNCTION') { + if (! empty($_REQUEST['item_returntype']) + && in_array( + $_REQUEST['item_returntype'], PMA_Util::getSupportedDatatypes() + ) + ) { + $query .= "RETURNS {$_REQUEST['item_returntype']}"; + } else { + $errors[] = __('You must provide a valid return type for the routine.'); + } + if (! empty($_REQUEST['item_returnlength']) + && !preg_match( + '@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN)$@i', + $_REQUEST['item_returntype'] + ) + ) { + $query .= "(" . $_REQUEST['item_returnlength'] . ")"; + } else if (empty($_REQUEST['item_returnlength']) + && preg_match( + '@^(ENUM|SET|VARCHAR|VARBINARY)$@i', $_REQUEST['item_returntype'] + ) + ) { + if (! $warned_about_length) { + $warned_about_length = true; + $errors[] = __( + 'You must provide length/values for routine parameters' + . ' of type ENUM, SET, VARCHAR and VARBINARY.' + ); + } + } + if (! empty($_REQUEST['item_returnopts_text'])) { + if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_returntype']) == 'CHAR') { + $query .= ' CHARSET ' + . strtolower($_REQUEST['item_returnopts_text']); + } + } + if (! empty($_REQUEST['item_returnopts_num'])) { + if ($GLOBALS['PMA_Types']->getTypeClass($_REQUEST['item_returntype']) == 'NUMBER') { + $query .= ' ' . strtoupper($_REQUEST['item_returnopts_num']); + } + } + $query .= ' '; + } + if (! empty($_REQUEST['item_comment'])) { + $query .= "COMMENT '" . PMA_Util::sqlAddslashes($_REQUEST['item_comment']) + . "' "; + } + if (isset($_REQUEST['item_isdeterministic'])) { + $query .= 'DETERMINISTIC '; + } else { + $query .= 'NOT DETERMINISTIC '; + } + if (! empty($_REQUEST['item_sqldataaccess']) + && in_array($_REQUEST['item_sqldataaccess'], $param_sqldataaccess) + ) { + $query .= $_REQUEST['item_sqldataaccess'] . ' '; + } + if (! empty($_REQUEST['item_securitytype'])) { + if ($_REQUEST['item_securitytype'] == 'DEFINER' + || $_REQUEST['item_securitytype'] == 'INVOKER' + ) { + $query .= 'SQL SECURITY ' . $_REQUEST['item_securitytype'] . ' '; + } + } + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide a routine definition.'); + } + + return $query; +} // end PMA_RTN_getQueryFromRequest() + +/** + * Handles requests for executing a routine + * + * @return Does not return + */ +function PMA_RTN_handleExecute() +{ + global $_GET, $_POST, $_REQUEST, $GLOBALS, $db; + + /** + * Handle all user requests other than the default of listing routines + */ + if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['item_name'])) { + // Build the queries + $routine = PMA_RTN_getDataFromName( + $_REQUEST['item_name'], $_REQUEST['item_type'], false + ); + if ($routine !== false) { + $queries = array(); + $end_query = array(); + $args = array(); + $all_functions = $GLOBALS['PMA_Types']->getAllFunctions(); + for ($i=0; $i<$routine['item_num_params']; $i++) { + if (isset($_REQUEST['params'][$routine['item_param_name'][$i]])) { + $value = $_REQUEST['params'][$routine['item_param_name'][$i]]; + if (is_array($value)) { // is SET type + $value = implode(',', $value); + } + $value = PMA_Util::sqlAddSlashes($value); + if (! empty($_REQUEST['funcs'][$routine['item_param_name'][$i]]) + && in_array( + $_REQUEST['funcs'][$routine['item_param_name'][$i]], + $all_functions + ) + ) { + $queries[] = "SET @p$i=" + . $_REQUEST['funcs'][$routine['item_param_name'][$i]] + . "('$value');\n"; + } else { + $queries[] = "SET @p$i='$value';\n"; + } + $args[] = "@p$i"; + } else { + $args[] = "@p$i"; + } + if ($routine['item_type'] == 'PROCEDURE') { + if ($routine['item_param_dir'][$i] == 'OUT' + || $routine['item_param_dir'][$i] == 'INOUT' + ) { + $end_query[] = "@p$i AS " + . PMA_Util::backquote($routine['item_param_name'][$i]); + } + } + } + if ($routine['item_type'] == 'PROCEDURE') { + $queries[] = "CALL " . PMA_Util::backquote($routine['item_name']) + . "(" . implode(', ', $args) . ");\n"; + if (count($end_query)) { + $queries[] = "SELECT " . implode(', ', $end_query) . ";\n"; + } + } else { + $queries[] = "SELECT " . PMA_Util::backquote($routine['item_name']) + . "(" . implode(', ', $args) . ") " + . "AS " . PMA_Util::backquote($routine['item_name']) + . ";\n"; + } + + // Get all the queries as one SQL statement + $multiple_query = implode("", $queries); + + $outcome = true; + $affected = 0; + + // Execute query + if (! PMA_DBI_try_multi_query($multiple_query)) { + $outcome = false; + } + + // Generate output + if ($outcome) { + + // Pass the SQL queries through the "pretty printer" + $output = ''; + $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries))); + $output .= ''; + + // Display results + $output .= "
      "; + $output .= sprintf( + __('Execution results of routine %s'), + PMA_Util::backquote(htmlspecialchars($routine['item_name'])) + ); + $output .= ""; + + $num_of_rusults_set_to_display = 0; + + do { + + $result = PMA_DBI_store_result(); + $num_rows = PMA_DBI_num_rows($result); + + if (($result !== false) && ($num_rows > 0)) { + + $output .= ""; + foreach (PMA_DBI_get_fields_meta($result) as $key => $field) { + $output .= ""; + } + $output .= ""; + + $color_class = 'odd'; + + while ($row = PMA_DBI_fetch_assoc($result)) { + $output .= ""; + foreach ($row as $key => $value) { + if ($value === null) { + $value = 'NULL'; + } else { + $value = htmlspecialchars($value); + } + $output .= ""; + } + $output .= ""; + $color_class = ($color_class == 'odd') ? 'even' : 'odd'; + } + + $output .= "
      "; + $output .= htmlspecialchars($field->name); + $output .= "
      " + . $value . "
      "; + $num_of_rusults_set_to_display++; + $affected = $num_rows; + + } + + if (! PMA_DBI_more_results()) { + break; + } + + $output .= "
      "; + + PMA_DBI_free_result($result); + + } while (PMA_DBI_next_result()); + + $output .= "
      "; + + $message = __('Your SQL query has been executed successfully'); + if ($routine['item_type'] == 'PROCEDURE') { + $message .= '
      '; + + // TODO : message need to be modified according to the + // output from the routine + $message .= sprintf( + _ngettext( + '%d row affected by the last statement inside the procedure', + '%d rows affected by the last statement inside the procedure', + $affected + ), + $affected + ); + } + $message = PMA_message::success($message); + + if ($num_of_rusults_set_to_display == 0) { + $notice = __( + 'MySQL returned an empty result set (i.e. zero rows).' + ); + $output .= PMA_message::notice($notice)->getDisplay(); + } + + } else { + $output = ''; + $message = PMA_message::error( + sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($multiple_query) + ) + . '

      ' + . __('MySQL said: ') . PMA_DBI_getError(null) + ); + } + + // Print/send output + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->isSuccess($message->isSuccess()); + $response->addJSON('message', $message->getDisplay() . $output); + $response->addJSON('dialog', false); + exit; + } else { + echo $message->getDisplay() . $output; + if ($message->isError()) { + // At least one query has failed, so shouldn't + // execute any more queries, so we quit. + exit; + } + unset($_POST); + // Now deliberately fall through to displaying the routines list + } + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_Util::backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $message); + exit; + } else { + echo $message->getDisplay(); + unset($_POST); + } + } + } else if (! empty($_GET['execute_dialog']) && ! empty($_GET['item_name'])) { + /** + * Display the execute form for a routine. + */ + $routine = PMA_RTN_getDataFromName( + $_GET['item_name'], $_GET['item_type'], true + ); + if ($routine !== false) { + $form = PMA_RTN_getExecuteForm($routine); + if ($GLOBALS['is_ajax_request'] == true) { + $title = __("Execute routine") . " " . PMA_Util::backquote( + htmlentities($_GET['item_name'], ENT_QUOTES) + ); + $response = PMA_Response::getInstance(); + $response->addJSON('message', $form); + $response->addJSON('title', $title); + $response->addJSON('dialog', true); + } else { + echo "\n\n

      " . __("Execute routine") . "

      \n\n"; + echo $form; + } + exit; + } else if (($GLOBALS['is_ajax_request'] == true)) { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_Util::backquote($db)) + ); + $message = PMA_message::error($message); + + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $message); + exit; + } + } +} + +/** + * Creates the HTML code that shows the routine execution dialog. + * + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromName() + * + * @return string HTML code for the routine execution dialog. + */ +function PMA_RTN_getExecuteForm($routine) +{ + global $db, $cfg; + + // Escape special characters + $routine['item_name'] = htmlentities($routine['item_name'], ENT_QUOTES); + for ($i=0; $i<$routine['item_num_params']; $i++) { + $routine['item_param_name'][$i] = htmlentities( + $routine['item_param_name'][$i], + ENT_QUOTES + ); + } + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
      \n"; + $retval .= "\n"; + $retval .= "\n"; + } + $retval .= "\n"; + $retval .= "\n"; + $retval .= "\n"; + if ($cfg['ShowFunctionFields']) { + $retval .= "\n"; + } + $retval .= "\n"; + $retval .= "\n"; + // Get a list of data types that are not yet supported. + $no_support_types = PMA_Util::unsupportedDatatypes(); + for ($i=0; $i<$routine['item_num_params']; $i++) { // Each parameter + if ($routine['item_type'] == 'PROCEDURE' + && $routine['item_param_dir'][$i] == 'OUT' + ) { + continue; + } + $rowclass = ($i % 2 == 0) ? 'even' : 'odd'; + $retval .= "\n\n"; + $retval .= "\n"; + $retval .= "\n"; + if ($cfg['ShowFunctionFields']) { + $retval .= "\n"; + } + // Append a class to date/time fields so that + // jQuery can attach a datepicker to them + $class = ''; + if ($routine['item_param_type'][$i] == 'DATETIME' + || $routine['item_param_type'][$i] == 'TIMESTAMP' + ) { + $class = 'datetimefield'; + } else if ($routine['item_param_type'][$i] == 'DATE') { + $class = 'datefield'; + } + $retval .= "\n"; + $retval .= "\n"; + } + $retval .= "\n
      " . __('Name') . "" . __('Type') . "" . __('Function') . "" . __('Value') . "
      {$routine['item_param_name'][$i]}{$routine['item_param_type'][$i]}\n"; + if (stristr($routine['item_param_type'][$i], 'enum') + || stristr($routine['item_param_type'][$i], 'set') + || in_array( + strtolower($routine['item_param_type'][$i]), $no_support_types + ) + ) { + $retval .= "--\n"; + } else { + $field = array( + 'True_Type' => strtolower($routine['item_param_type'][$i]), + 'Type' => '', + 'Key' => '', + 'Field' => '', + 'Default' => '', + 'first_timestamp' => false + ); + $retval .= ""; + } + $retval .= "\n"; + if (in_array($routine['item_param_type'][$i], array('ENUM', 'SET'))) { + $tokens = PMA_SQP_parse($routine['item_param_length'][$i]); + if ($routine['item_param_type'][$i] == 'ENUM') { + $input_type = 'radio'; + } else { + $input_type = 'checkbox'; + } + for ($j=0; $j<$tokens['len']; $j++) { + if ($tokens[$j]['type'] != 'punct_listsep') { + $tokens[$j]['data'] = htmlentities( + PMA_Util::unquote($tokens[$j]['data']), + ENT_QUOTES + ); + $retval .= "" + . "{$tokens[$j]['data']}
      \n"; + } + } + } else if (in_array( + strtolower($routine['item_param_type'][$i]), $no_support_types + )) { + $retval .= "\n"; + } else { + $retval .= "\n"; + } + $retval .= "
      \n"; + if ($GLOBALS['is_ajax_request'] != true) { + $retval .= "\n\n"; + $retval .= "
      \n"; + $retval .= " \n"; + $retval .= "
      \n"; + } else { + $retval .= ""; + $retval .= ""; + } + $retval .= "
      \n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTN_getExecuteForm() + +?> diff --git a/phpmyadmin/libraries/rte/rte_triggers.lib.php b/phpmyadmin/libraries/rte/rte_triggers.lib.php new file mode 100644 index 000000000..504eb9824 --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_triggers.lib.php @@ -0,0 +1,486 @@ +' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old item, but were unable to create the new one + // Try to restore the backup query + $result = PMA_DBI_try_query($create_item); + if (! $result) { + // OMG, this is really bad! We dropped the query, + // failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle + // this just in case. + $errors[] = __( + 'Sorry, we failed to restore the dropped trigger.' + ) + . '
      ' + . __('The backed up query was:') + . "\"" . htmlspecialchars($create_item) . "\"" + . '
      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success( + __('Trigger %1$s has been modified.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $drop_item . $item_query; + } + } + } else { + // 'Add a new item' mode + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '

      ' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success( + __('Trigger %1$s has been created.') + ); + $message->addParam( + PMA_Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $item_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); + $message->addString('
        '); + foreach ($errors as $string) { + $message->addString('
      • ' . $string . '
      • '); + } + $message->addString('
      '); + } + + $output = PMA_Util::getMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + if ($message->isSuccess()) { + $items = PMA_DBI_get_triggers($db, $table, ''); + $trigger = false; + foreach ($items as $value) { + if ($value['name'] == $_REQUEST['item_name']) { + $trigger = $value; + } + } + $insert = false; + if (empty($table) + || ($trigger !== false && $table == $trigger['table']) + ) { + $insert = true; + $response->addJSON('new_row', PMA_TRI_getRowForList($trigger)); + $response->addJSON( + 'name', + htmlspecialchars( + strtoupper($_REQUEST['item_name']) + ) + ); + } + $response->addJSON('insert', $insert); + $response->addJSON('message', $output); + } else { + $response->addJSON('message', $message); + $response->isSuccess(false); + } + exit; + } + } + + /** + * Display a form used to add/edit a trigger, if necessary + */ + if (count($errors) + || (empty($_REQUEST['editor_process_add']) + && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) + || ! empty($_REQUEST['edit_item']))) // FIXME: this must be simpler than that + ) { + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = PMA_RTE_getWord('add'); + $item = PMA_TRI_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit trigger"); + if (! empty($_REQUEST['item_name']) + && empty($_REQUEST['editor_process_edit']) + ) { + $item = PMA_TRI_getDataFromName($_REQUEST['item_name']); + if ($item !== false) { + $item['item_original_name'] = $item['item_name']; + } + } else { + $item = PMA_TRI_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($item !== false) { + // Show form + $editor = PMA_TRI_getEditorForm($mode, $item); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->addJSON('message', $editor); + $response->addJSON('title', $title); + } else { + echo "\n\n

      $title

      \n\n$editor"; + unset($_POST); + } + exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_Util::backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $message); + exit; + } else { + $message->display(); + } + } + } +} // end PMA_TRI_handleEditor() + +/** + * This function will generate the values that are required to for the editor + * + * @return array Data necessary to create the editor. + */ +function PMA_TRI_getDataFromRequest() +{ + $retval = array(); + $indices = array('item_name', + 'item_table', + 'item_original_name', + 'item_action_timing', + 'item_event_manipulation', + 'item_definition', + 'item_definer'); + foreach ($indices as $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + return $retval; +} // end PMA_TRI_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit trigger" form given the name of a trigger. + * + * @param string $name The name of the trigger. + * + * @return array Data necessary to create the editor. + */ +function PMA_TRI_getDataFromName($name) +{ + global $db, $table, $_REQUEST; + + $temp = array(); + $items = PMA_DBI_get_triggers($db, $table, ''); + foreach ($items as $value) { + if ($value['name'] == $name) { + $temp = $value; + } + } + if (empty($temp)) { + return false; + } else { + $retval = array(); + $retval['create'] = $temp['create']; + $retval['drop'] = $temp['drop']; + $retval['item_name'] = $temp['name']; + $retval['item_table'] = $temp['table']; + $retval['item_action_timing'] = $temp['action_timing']; + $retval['item_event_manipulation'] = $temp['event_manipulation']; + $retval['item_definition'] = $temp['definition']; + $retval['item_definer'] = $temp['definer']; + return $retval; + } +} // end PMA_TRI_getDataFromName() + +/** + * Displays a form used to add/edit a trigger + * + * @param string $mode If the editor will be used edit a trigger + * or add a new one: 'edit' or 'add'. + * @param array $item Data for the trigger returned by PMA_TRI_getDataFromRequest() + * or PMA_TRI_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_TRI_getEditorForm($mode, $item) +{ + global $db, $table, $event_manipulations, $action_timings; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_definition', + 'item_definer' + ); + foreach ($need_escape as $key => $index) { + $item[$index] = htmlentities($item[$index], ENT_QUOTES, 'UTF-8'); + } + $original_data = ''; + if ($mode == 'edit') { + $original_data = "\n"; + } + $query = "SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` "; + $query .= "WHERE `TABLE_SCHEMA`='" . PMA_Util::sqlAddSlashes($db) . "' "; + $query .= "AND `TABLE_TYPE`='BASE TABLE'"; + $tables = PMA_DBI_fetch_result($query); + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
      \n"; + $retval .= "\n"; + $retval .= $original_data; + $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n"; + $retval .= "
      \n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= "
      " . __('Trigger name') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
      " . _pgettext('Trigger action time', 'Time') . "
      " . __('Event') . "
      " . __('Definition') . "
      " . __('Definer') . "\n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_TRI_getEditorForm() + +/** + * Composes the query necessary to create a trigger from an HTTP request. + * + * @return string The CREATE TRIGGER query. + */ +function PMA_TRI_getQueryFromRequest() +{ + global $_REQUEST, $db, $errors, $action_timings, $event_manipulations; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]); + $query .= '@' . PMA_Util::backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + $query .= 'TRIGGER '; + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_Util::backquote($_REQUEST['item_name']) . ' '; + } else { + $errors[] = __('You must provide a trigger name'); + } + if (! empty($_REQUEST['item_timing']) + && in_array($_REQUEST['item_timing'], $action_timings) + ) { + $query .= $_REQUEST['item_timing'] . ' '; + } else { + $errors[] = __('You must provide a valid timing for the trigger'); + } + if (! empty($_REQUEST['item_event']) + && in_array($_REQUEST['item_event'], $event_manipulations) + ) { + $query .= $_REQUEST['item_event'] . ' '; + } else { + $errors[] = __('You must provide a valid event for the trigger'); + } + $query .= 'ON '; + if (! empty($_REQUEST['item_table']) + && in_array($_REQUEST['item_table'], PMA_DBI_get_tables($db)) + ) { + $query .= PMA_Util::backquote($_REQUEST['item_table']); + } else { + $errors[] = __('You must provide a valid table name'); + } + $query .= ' FOR EACH ROW '; + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide a trigger definition.'); + } + + return $query; +} // end PMA_TRI_getQueryFromRequest() + +?> diff --git a/phpmyadmin/libraries/rte/rte_words.lib.php b/phpmyadmin/libraries/rte/rte_words.lib.php new file mode 100644 index 000000000..2aabfde67 --- /dev/null +++ b/phpmyadmin/libraries/rte/rte_words.lib.php @@ -0,0 +1,64 @@ + __('Add routine'), + 'docu' => 'STORED_ROUTINES', + 'export' => __('Export of routine %s'), + 'human' => __('routine'), + 'no_create' => __('You do not have the necessary privileges to create a routine'), + 'not_found' => __('No routine with name %1$s found in database %2$s'), + 'nothing' => __('There are no routines to display.'), + 'title' => __('Routines'), + ); + break; + case 'TRI': + $words = array( + 'add' => __('Add trigger'), + 'docu' => 'TRIGGERS', + 'export' => __('Export of trigger %s'), + 'human' => __('trigger'), + 'no_create' => __('You do not have the necessary privileges to create a trigger'), + 'not_found' => __('No trigger with name %1$s found in database %2$s'), + 'nothing' => __('There are no triggers to display.'), + 'title' => __('Triggers'), + ); + break; + case 'EVN': + $words = array( + 'add' => __('Add event'), + 'docu' => 'EVENTS', + 'export' => __('Export of event %s'), + 'human' => __('event'), + 'no_create' => __('You do not have the necessary privileges to create an event'), + 'not_found' => __('No event with name %1$s found in database %2$s'), + 'nothing' => __('There are no events to display.'), + 'title' => __('Events'), + ); + break; + default: + $words = array(); + break; + } + + return isset($words[$index]) ? $words[$index] : ''; +} // end PMA_RTE_getWord() + +?> diff --git a/phpmyadmin/libraries/sanitizing.lib.php b/phpmyadmin/libraries/sanitizing.lib.php new file mode 100644 index 000000000..edfb39774 --- /dev/null +++ b/phpmyadmin/libraries/sanitizing.lib.php @@ -0,0 +1,190 @@ +'; +} + +/** + * Callback function for replacing [doc@anchor] links in bb code. + * + * @param array $found Array of preg matches + * + * @return string Replaced string + */ +function PMA_replaceDocLink($found) +{ + $anchor = $found[1]; + if (strncmp('faq', $anchor, 3) == 0) { + $page = 'faq'; + } else if (strncmp('cfg', $anchor, 3) == 0) { + $page = 'cfg'; + } else { + /* Guess */ + $page = 'setup'; + } + $link = PMA_Util::getDocuLink($page, $anchor); + return ''; +} + +/** + * Sanitizes $message, taking into account our special codes + * for formatting. + * + * If you want to include result in element attribute, you should escape it. + * + * Examples: + * + *

      + * + *
      bar + * + * @param string $message the message + * @param boolean $escape whether to escape html in result + * @param boolean $safe whether string is safe (can keep < and > chars) + * + * @return string the sanitized message + */ +function PMA_sanitize($message, $escape = false, $safe = false) +{ + if (!$safe) { + $message = strtr($message, array('<' => '<', '>' => '>')); + } + + /* Interpret bb code */ + $replace_pairs = array( + '[em]' => '', + '[/em]' => '', + '[strong]' => '', + '[/strong]' => '', + '[code]' => '', + '[/code]' => '', + '[kbd]' => '', + '[/kbd]' => '', + '[br]' => '
      ', + '[/a]' => '', + '[/doc]' => '', + '[sup]' => '', + '[/sup]' => '', + // used in common.inc.php: + '[conferr]' => '