[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_4_3_1-14706-g9147f30
Marc Delisle
lem9 at users.sourceforge.net
Fri Aug 12 20:45:22 CEST 2011
The branch, master has been updated
via 9147f30dc6b00dc63c998f1d2d3972d1a47e6c57 (commit)
via 8f7312956d76eefd1fbf9567a3bb18634e8db560 (commit)
via 1b7e2f6c7be6c7a96d780a7e9870d498f84e7339 (commit)
via ae5ef42beff0475de4a841ff18953e4f66880c40 (commit)
via 67dc02f23db70391220dc0336f2110645a34a9d2 (commit)
via 557734c57f45e24abae08a031dde25dab73f1a05 (commit)
via 201331275bff7e3e67e3d5f3fb2bc706e302ad27 (commit)
via e3cb99d540a305caaa58f91d71a5f87d96f28e50 (commit)
via 57af6f950289ce2283ebe0d4d56b68119b75322b (commit)
via 33ad955596696415c0cfe0422a067f64f95d1d15 (commit)
via 241caff7818f69531400eecd1ea63849009bffa9 (commit)
via e4b676e3567f2992d9b77f623d328af2fa90cef8 (commit)
via 7880782588e1609dac657a3c2b2f5a3630929859 (commit)
via 00c420c74b4663fddf0b5fc47ac50fdd15dd23c6 (commit)
via df0848fa9c94a100d153cb4500d723566e8c25c0 (commit)
via e83f3acd26fbfb51366cae9b184e69e5376ae10d (commit)
via 32969f3d4211a96575e2fd7e609cc21ddc63bbaf (commit)
via 9388cd35b643ea65473ffa95cdf21213bcc4785f (commit)
via cb63a92b44a3ab1ee38ec66d63d33432a6273f94 (commit)
via d9486e259721b812cb0cd56ca057e55359250cc9 (commit)
via e09759bef84ae8113f2e468117be66fb43d4b932 (commit)
via 18a6f0b0701457dd6a33d6517915c89729d1c11c (commit)
via 6cc3ff46f853960bdc90eb00fd595591e6a26f2e (commit)
via 95ea722d73fc635b4b27c6731aeedfd430628ce8 (commit)
via bedd413217a87770852671c4a2b211ca067df5e0 (commit)
via 830f2fdaa72a05497448b5b83b6fb961bf2bd7d2 (commit)
via 7c66a8bed58fffd66becd643c845027e57e43862 (commit)
via b6cb93b017ddd35ab7c2083591228a9874eab60d (commit)
via 1ce7ea6fb0180722ffadd056b565f63eaf215d4f (commit)
via 36ec09e6ccec0f46ebc1c92b8c8bc5a396b9a136 (commit)
via c01e39a716c5ba33d00ff45f1791d3094fe1c777 (commit)
via 04e82bb1e908e233f1eb619324b84b18312282d7 (commit)
via 811996e92a9365afc4c2ff8549ae887336ace5ad (commit)
via cdf70921a4976d6fbd79793ba7fa2b5c873bbe2b (commit)
via d5d9b38af093708d443a01f9172cc97867343796 (commit)
via d90a58d06150f27f008d63c9fee8b92e56afaeea (commit)
via 362a57f7e1663de26149f27abc4ef49144e8f744 (commit)
via ea171beebec90c31107b5972d58761100f9cd122 (commit)
via c520c098ad1b4728c751d334dc356bead56a4937 (commit)
via 12c1471c9b7683f150db76082506d4d90f034787 (commit)
via 57dc8ce4a595498a7de06ee34c7aa5129da7f934 (commit)
via 41715e512a7eca3bdc83524fb1c1bf8c3f88fa51 (commit)
via 28b142b5c314204ddf8590eb194eca2efd4061e5 (commit)
via 03a1a84b7886d7a8170d8520ad9b8948f1403d7a (commit)
via 602a64a1d2bf596d51de87618d11eba67c8bf1b4 (commit)
via 78f93fdd3c64dfe84d1f8459c4c16a39fbf61d60 (commit)
via 2a4c47c0a244366f3bc623a375ce8280c8dfddcd (commit)
via 543df4c802d7f21dc0443b207390c4353cfacf4f (commit)
via eaea0030641c6be215915684bcd40930ae2d61c8 (commit)
via fb8a4956a8fb948f3e2a9e6c2ef3debf5797f2ca (commit)
via 1653fd340c080d2caefb4c6bf1bd21a98443baa9 (commit)
via 9498f5d4cd59799f6c7753354180952936cd4680 (commit)
via 64425ccb66a518fe7c38bfd1c5f09d2e35afce3e (commit)
via f64dffd44ab787598eedf500bf8718a3e8d448cf (commit)
via f939564bfdfafe0960840b8482fd0a35e249c491 (commit)
via 763fa66d7281930d57f618c1fba6712394d0a05c (commit)
via 18694f2d7c81110c35aaa56942cbad5e3d7a4904 (commit)
via a4fda9e8f9910a7dc7bec484b722a940e5eec8c0 (commit)
via af1f872d81ed31e457094a4294fb3bedda826b85 (commit)
via 70167fed52368079d1cbffd445514480f29d9ff3 (commit)
via c7cef3b0ba0de9af03bcd9d733290e69882d5a29 (commit)
via e794690417b8ff32824862909a08fd2b9165e391 (commit)
via 91d372f9bcca4b92e6e63d7354fcf2a81b6b8f18 (commit)
via b225436331c6a770914fdd180327690697d3c478 (commit)
via 459b57ca578ee4bfcfa6839136dbedbbdabb33a2 (commit)
via 7396fa3aa9544c480b11edc1b3b2d687b1bca5e8 (commit)
via ae44636606a9c7b98d9f5d4998486579a4610a83 (commit)
via aac58fd425e4ee4064fa5dbbe666304c5e2b6f2c (commit)
via 699ca1d3904b0324a8d1fe0359ac40a725e6e92f (commit)
from b319651b70b95c1c70d084ab8519109dae9e5450 (commit)
- Log -----------------------------------------------------------------
commit 9147f30dc6b00dc63c998f1d2d3972d1a47e6c57
Author: Marc Delisle <marc at infomarc.info>
Date: Fri Aug 12 14:44:55 2011 -0400
Zoom-search in table Search
commit 8f7312956d76eefd1fbf9567a3bb18634e8db560
Merge: b319651 1b7e2f6
Author: Marc Delisle <marc at infomarc.info>
Date: Fri Aug 12 14:40:56 2011 -0400
Merge commit '1b7e2f6c7be6c7a96d780a7e9870d498f84e7339'
commit 1b7e2f6c7be6c7a96d780a7e9870d498f84e7339
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 23:30:21 2011 +0530
Added: Missing rgbcolor.js file
commit ae5ef42beff0475de4a841ff18953e4f66880c40
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 23:15:38 2011 +0530
Fixed: Timestamp for time associated fields needed extra 19800000 (+5:30) value
commit 67dc02f23db70391220dc0336f2110645a34a9d2
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 20:06:27 2011 +0530
Fixed: false timestamp error
commit 557734c57f45e24abae08a031dde25dab73f1a05
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 20:03:03 2011 +0530
bug fix
commit 201331275bff7e3e67e3d5f3fb2bc706e302ad27
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 18:38:53 2011 +0530
Fixed: yAxis min value determined on plot generation and not 0 by default
commit e3cb99d540a305caaa58f91d71a5f87d96f28e50
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 01:39:22 2011 +0530
Added better support for datetime fields
commit 57af6f950289ce2283ebe0d4d56b68119b75322b
Merge: 33ad955 d585bba
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Aug 12 00:10:17 2011 +0530
Merge remote branch 'phpmyadmin/master'
Conflicts:
js/tbl_select.js
commit 33ad955596696415c0cfe0422a067f64f95d1d15
Merge: 241caff a5394bd
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Aug 7 10:55:41 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 241caff7818f69531400eecd1ea63849009bffa9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Wed Aug 3 09:17:16 2011 +0530
Used AJAX to get data row on point select, hence reducing the amount of data to be sent from server initially for plot.
commit e4b676e3567f2992d9b77f623d328af2fa90cef8
Merge: 7880782 54fbcaa
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Wed Aug 3 09:15:29 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 7880782588e1609dac657a3c2b2f5a3630929859
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Aug 1 10:01:42 2011 +0530
Added 'Max rows to plot' as input criteria
commit 00c420c74b4663fddf0b5fc47ac50fdd15dd23c6
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 31 12:50:24 2011 +0530
Edit feature with support for string plot. Also made some optimizations to avoid unnecesarry replot
commit df0848fa9c94a100d153cb4500d723566e8c25c0
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 31 12:41:09 2011 +0530
String plotting: truncated axis labels with length greater than 10.
commit e83f3acd26fbfb51366cae9b184e69e5376ae10d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 31 12:35:07 2011 +0530
Added to 'How to use' message content, strings are converted into integers for plotting purpose.
commit 32969f3d4211a96575e2fd7e609cc21ddc63bbaf
Merge: 9388cd3 e3b91b7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 31 07:14:01 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 9388cd35b643ea65473ffa95cdf21213bcc4785f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 25 19:50:02 2011 +0530
Re:Validations for input form submit (missed addidng messages.php file)
commit cb63a92b44a3ab1ee38ec66d63d33432a6273f94
Merge: d9486e2 c63172f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 25 19:46:55 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit d9486e259721b812cb0cd56ca057e55359250cc9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 25 19:45:00 2011 +0530
Validations for input form submit
commit e09759bef84ae8113f2e468117be66fb43d4b932
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 25 04:50:47 2011 +0530
Added support for ploting strings(char,varchar,enums)
commit 18a6f0b0701457dd6a33d6517915c89729d1c11c
Merge: 6cc3ff4 73ee863
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 25 04:49:22 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 6cc3ff46f853960bdc90eb00fd595591e6a26f2e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 22 17:53:13 2011 +0530
Data point content is now displayed as a dialog box which opens on clicking a point and closes on finishing an edit
commit 95ea722d73fc635b4b27c6731aeedfd430628ce8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 22 17:51:53 2011 +0530
Fixed redirection issue on tbl_zoom_select.php page
commit bedd413217a87770852671c4a2b211ca067df5e0
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 22 17:50:09 2011 +0530
Resolved merge conflict
commit 830f2fdaa72a05497448b5b83b6fb961bf2bd7d2
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 22 16:58:52 2011 +0530
Merge remote tracking branch 'phpmyadmin'
commit 7c66a8bed58fffd66becd643c845027e57e43862
Merge: b6cb93b 8489f41
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 22 16:50:30 2011 +0530
Merge remote branch 'phpmyadmin/master'
Conflicts:
js/highcharts/highcharts.js
commit b6cb93b017ddd35ab7c2083591228a9874eab60d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 20:04:15 2011 +0530
Default datalabel bugfix (defaulted to display field everytime)
commit 1ce7ea6fb0180722ffadd056b565f63eaf215d4f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 19:39:42 2011 +0530
Display field is set as the defualt selected item in the datalabel select element
commit 36ec09e6ccec0f46ebc1c92b8c8bc5a396b9a136
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 02:18:29 2011 +0530
Changed 'How to use?' lnk message onClick event function from this.remove() to PMA_ajaxRemoveMessage()
commit c01e39a716c5ba33d00ff45f1791d3094fe1c777
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 00:43:41 2011 +0530
xAxis type changed to linear (earliear it defaulted to timeseries)
commit 04e82bb1e908e233f1eb619324b84b18312282d7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 00:38:51 2011 +0530
Default data label now taken from table display field
commit 811996e92a9365afc4c2ff8549ae887336ace5ad
Merge: cdf7092 117dd68
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 15 00:38:31 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit cdf70921a4976d6fbd79793ba7fa2b5c873bbe2b
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jul 12 06:51:20 2011 +0530
Fixed misfunction of edit mode
commit d5d9b38af093708d443a01f9172cc97867343796
Merge: d90a58d 4bb11fd
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jul 12 06:50:46 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit d90a58d06150f27f008d63c9fee8b92e56afaeea
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 10 08:37:15 2011 +0530
Some indentation errors fixed from previous commit
commit 362a57f7e1663de26149f27abc4ef49144e8f744
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 10 08:14:00 2011 +0530
Functionality for edit data points added (primitive)
commit ea171beebec90c31107b5972d58761100f9cd122
Merge: c520c09 1962e36
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun Jul 10 08:13:46 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit c520c098ad1b4728c751d334dc356bead56a4937
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 8 02:34:49 2011 +0530
On submit of an edit, the data point remains selected in the plot.
commit 12c1471c9b7683f150db76082506d4d90f034787
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 8 02:26:56 2011 +0530
Changed text for 'How to use?' link 9$js_messages['strDisplayHelp'])
commit 57dc8ce4a595498a7de06ee34c7aa5129da7f934
Merge: 41715e5 5140c38
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Thu Jul 7 21:00:10 2011 +0530
Merge remote branch 'phpmyadmin/master'
Conflicts:
libraries/config.default.php
tbl_select.php
commit 41715e512a7eca3bdc83524fb1c1bf8c3f88fa51
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Thu Jul 7 20:53:32 2011 +0530
Removed mode feature, appended a missing configuration directive and changed help link duration to 10sec
commit 28b142b5c314204ddf8590eb194eca2efd4061e5
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jul 5 05:22:38 2011 +0530
Made some changes
-> Browse Mode makes the dialog fields disabled
-> New name for max row to plot directive
-> Show/Hide search criteria
-> Link for displaying Help
commit 03a1a84b7886d7a8170d8520ad9b8948f1403d7a
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jul 5 05:21:16 2011 +0530
Test
commit 602a64a1d2bf596d51de87618d11eba67c8bf1b4
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 4 21:59:17 2011 +0530
Added the Show/Hide search criteria feature
commit 78f93fdd3c64dfe84d1f8459c4c16a39fbf61d60
Merge: 2a4c47c 064d399
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jul 4 21:58:47 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 2a4c47c0a244366f3bc623a375ce8280c8dfddcd
Merge: 543df4c 2279fd9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 1 15:34:39 2011 +0530
Merge remote branch 'phpmyadmin/master'
Conflicts:
tbl_select.php
commit 543df4c802d7f21dc0443b207390c4353cfacf4f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jul 1 15:31:56 2011 +0530
Added interface for browsing/editing points
commit eaea0030641c6be215915684bcd40930ae2d61c8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jun 21 05:04:00 2011 +0530
Added some features
-> Limit on max number of rows retreived(500)
-> An instruction link regarding how to use
-> Resize plot by dragging it by the bottom right corner
-> Two additional search criteria
commit fb8a4956a8fb948f3e2a9e6c2ef3debf5797f2ca
Merge: 1653fd3 d9304ef
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue Jun 21 04:35:24 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 1653fd340c080d2caefb4c6bf1bd21a98443baa9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jun 17 01:31:31 2011 +0530
Plot functionality using Hihcharts
commit 9498f5d4cd59799f6c7753354180952936cd4680
Merge: 64425cc 4338b70
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jun 17 01:06:38 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 64425ccb66a518fe7c38bfd1c5f09d2e35afce3e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jun 10 06:58:23 2011 +0530
Fixed some issues and added support for plotting strings
commit f64dffd44ab787598eedf500bf8718a3e8d448cf
Merge: f939564 cd5cddb
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri Jun 10 06:56:52 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit f939564bfdfafe0960840b8482fd0a35e249c491
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Thu Jun 9 03:03:22 2011 +0530
Created the SVG based scatter-plot functionality
-> Created classes corresponding to the plot and data objects, currently only data points
-> Plots only for numeric fields
commit 763fa66d7281930d57f618c1fba6712394d0a05c
Merge: 18694f2 90099b7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Thu Jun 9 02:54:33 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 18694f2d7c81110c35aaa56942cbad5e3d7a4904
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jun 6 04:18:47 2011 +0530
Added generate plot feature using SVG ( only for numeric fields )
commit a4fda9e8f9910a7dc7bec484b722a940e5eec8c0
Merge: af1f872 8b47a1d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon Jun 6 04:16:55 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit af1f872d81ed31e457094a4294fb3bedda826b85
Merge: 70167fe 75091e5
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sat Jun 4 13:55:18 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 70167fed52368079d1cbffd445514480f29d9ff3
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Wed Jun 1 01:22:31 2011 +0530
Made suggested change to tbl_select.php and tbl_zoom_select.php
commit c7cef3b0ba0de9af03bcd9d733290e69882d5a29
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue May 31 19:02:50 2011 +0530
Refactored the tbl_select.php and tbl_zoom_select.php code in libraries/tbl_select.lib.php
Parts refactored are:
-> Setting titles
-> getting fields list
-> setting sub-tabs
-> setting table header of QBE display
-> displaying foreign data
-> search criteria input elements
commit e794690417b8ff32824862909a08fd2b9165e391
Merge: 91d372f a47ac24
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Tue May 31 18:59:28 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 91d372f9bcca4b92e6e63d7354fcf2a81b6b8f18
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun May 29 12:16:13 2011 +0530
Added a library file for the table-search and zoom-search code
Contains two functions:
-> Get Field list and details
-> Get where clause of query generation process
commit b225436331c6a770914fdd180327690697d3c478
Merge: 459b57c ae0af9e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Sun May 29 12:14:04 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 459b57ca578ee4bfcfa6839136dbedbbdabb33a2
Merge: 7396fa3 434d233
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Fri May 27 17:46:30 2011 +0530
Merge remote branch 'phpmyadmin/master'
commit 7396fa3aa9544c480b11edc1b3b2d687b1bca5e8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Thu May 26 12:22:16 2011 +0530
Designed the zoom-search form(tbl_zoom_select.php)
-> User selecte exactly two columns.
-> Generates two queries, one for each column criteria.
commit ae44636606a9c7b98d9f5d4998486579a4610a83
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date: Mon May 23 21:26:07 2011 +0530
Made some changes on the tbl_select.php page to add a link for Zoom Search.
Please dont mind the coding, I just coded very quickly to get back comments. If the flow of the interface is ok I'll code it properly.
commit aac58fd425e4ee4064fa5dbbe666304c5e2b6f2c
Author: root <root at localhost.localdomain>
Date: Wed May 18 22:40:33 2011 +0530
testing for push
commit 699ca1d3904b0324a8d1fe0359ac40a725e6e92f
Author: root <root at localhost.localdomain>
Date: Wed May 18 22:30:26 2011 +0530
Just testing upload
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 1 +
config.sample.inc.php | 2 +-
db_structure.php | 1 +
js/canvg/canvg.js | 304 +++-----------
js/canvg/rgbcolor.js | 288 +++++++++++++
js/date.js | 335 +++++++++++++++
js/messages.php | 6 +
js/tbl_select.js | 2 +-
js/tbl_zoom_plot.js | 605 +++++++++++++++++++++++++++
libraries/common.inc.php | 1 +
libraries/config.default.php | 425 +++++++++++++++++--
libraries/svg_plot/pma_scatter_plot.php | 267 ++++++++++++
libraries/svg_plot/pma_svg_data_element.php | 50 +++
libraries/svg_plot/pma_svg_data_point.php | 86 ++++
libraries/tbl_select.lib.php | 390 +++++++++++++++++
tbl_select.php | 280 +++----------
tbl_zoom_select.php | 447 ++++++++++++++++++++
17 files changed, 2976 insertions(+), 514 deletions(-)
create mode 100644 js/canvg/rgbcolor.js
create mode 100644 js/date.js
create mode 100644 js/tbl_zoom_plot.js
create mode 100644 libraries/svg_plot/pma_scatter_plot.php
create mode 100644 libraries/svg_plot/pma_svg_data_element.php
create mode 100644 libraries/svg_plot/pma_svg_data_point.php
create mode 100644 libraries/tbl_select.lib.php
create mode 100644 tbl_zoom_select.php
diff --git a/ChangeLog b/ChangeLog
index 633d481..e6c1bc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,7 @@ phpMyAdmin - ChangeLog
+ AJAX for table Operations copy table
- bug #3380946 [export] no uid Query result export (Suhosin limit)
+ Grid editing in browse mode (replaces row inline edit)
++ Zoom-search in table Search
3.4.5.0 (not yet released)
- bug #3375325 [interface] Page list in navigation frame looks odd
diff --git a/config.sample.inc.php b/config.sample.inc.php
index edffd03..778785e 100644
--- a/config.sample.inc.php
+++ b/config.sample.inc.php
@@ -14,7 +14,7 @@
* This is needed for cookie based authentication to encrypt password in
* cookie
*/
-$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
+$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
/*
* Servers configuration
diff --git a/db_structure.php b/db_structure.php
index d76bcca..9c2e045 100644
--- a/db_structure.php
+++ b/db_structure.php
@@ -57,6 +57,7 @@ require_once './libraries/db_structure.lib.php';
$titles = PMA_buildActionTitles();
// 1. No tables
+
if ($num_tables == 0) {
echo '<p>' . __('No tables found in database') . '</p>' . "\n";
diff --git a/js/canvg/canvg.js b/js/canvg/canvg.js
index 19a47a7..dbc5a9d 100644
--- a/js/canvg/canvg.js
+++ b/js/canvg/canvg.js
@@ -12,6 +12,7 @@ if(!window.console) {
window.console.dir = function(str) {};
}
+// <3 IE
if(!Array.indexOf){
Array.prototype.indexOf = function(obj){
for(var i=0; i<this.length; i++){
@@ -27,7 +28,7 @@ if(!Array.indexOf){
// canvg(target, s)
// empty parameters: replace all 'svg' elements on page with 'canvas' elements
// target: canvas element or the id of a canvas element
- // s: svg string, url to svg file, or xml document
+ // s: svg string or url to svg file
// opts: optional hash of options
// ignoreMouse: true => ignore mouse events
// ignoreAnimation: true => ignore animations
@@ -74,11 +75,7 @@ if(!Array.indexOf){
svg.opts = opts;
var ctx = target.getContext('2d');
- if (typeof(s.documentElement) != 'undefined') {
- // load from xml doc
- svg.loadXmlDoc(ctx, s);
- }
- else if (s.substr(0,1) == '<') {
+ if (s.substr(0,1) == '<') {
// load from xml string
svg.loadXml(ctx, s);
}
@@ -92,7 +89,6 @@ if(!Array.indexOf){
var svg = { };
svg.FRAMERATE = 30;
- svg.MAX_VIRTUAL_PIXELS = 30000;
// globals
svg.init = function(ctx) {
@@ -103,7 +99,6 @@ if(!Array.indexOf){
svg.ctx = ctx;
svg.ViewPort = new (function () {
this.viewPorts = [];
- this.Clear = function() { this.viewPorts = []; }
this.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); }
this.RemoveCurrent = function() { this.viewPorts.pop(); }
this.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; }
@@ -556,7 +551,7 @@ if(!Array.indexOf){
}
}
- var data = svg.trim(svg.compressSpaces(v)).split(/\s(?=[a-z])/);
+ var data = v.split(/\s(?=[a-z])/);
for (var i=0; i<data.length; i++) {
var type = data[i].split('(')[0];
var s = data[i].split('(')[1].replace(')','');
@@ -621,7 +616,7 @@ if(!Array.indexOf){
return a;
}
- // get or create style, crawls up node tree
+ // get or create style
this.style = function(name, createIfNotExists) {
var s = this.styles[name];
if (s != null) return s;
@@ -630,14 +625,6 @@ if(!Array.indexOf){
if (a != null && a.hasValue()) {
return a;
}
-
- var p = this.parent;
- if (p != null) {
- var ps = p.style(name);
- if (ps != null && ps.hasValue()) {
- return ps;
- }
- }
s = new svg.Property(name, '');
if (createIfNotExists == true) this.styles[name] = s;
@@ -648,9 +635,6 @@ if(!Array.indexOf){
this.render = function(ctx) {
// don't render display=none
if (this.attribute('display').value == 'none') return;
-
- // don't render visibility=hidden
- if (this.attribute('visibility').value == 'hidden') return;
ctx.save();
this.setContext(ctx);
@@ -697,7 +681,7 @@ if(!Array.indexOf){
}
// add tag styles
- var styles = svg.Styles[node.nodeName];
+ var styles = svg.Styles[this.type];
if (styles != null) {
for (var name in styles) {
this.styles[name] = styles[name];
@@ -714,12 +698,6 @@ if(!Array.indexOf){
this.styles[name] = styles[name];
}
}
- styles = svg.Styles[node.nodeName+'.'+classes[j]];
- if (styles != null) {
- for (var name in styles) {
- this.styles[name] = styles[name];
- }
- }
}
}
@@ -878,7 +856,7 @@ if(!Array.indexOf){
var width = svg.ViewPort.width();
var height = svg.ViewPort.height();
- if (typeof(this.root) == 'undefined' && this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
+ if (this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
width = this.attribute('width').Length.toPixels('x');
height = this.attribute('height').Length.toPixels('y');
@@ -1208,6 +1186,9 @@ if(!Array.indexOf){
pp.reset();
var bb = new svg.BoundingBox();
+
+ if(this.attribute('visibility').value=='hidden') return;
+
if (ctx != null) ctx.beginPath();
while (!pp.isEnd()) {
pp.nextCommand();
@@ -1488,37 +1469,6 @@ if(!Array.indexOf){
for (var i=0; i<stopsContainer.stops.length; i++) {
g.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);
}
-
- if (this.attribute('gradientTransform').hasValue()) {
- // render as transformed pattern on temporary canvas
- var rootView = svg.ViewPort.viewPorts[0];
-
- var rect = new svg.Element.rect();
- rect.attributes['x'] = new svg.Property('x', -svg.MAX_VIRTUAL_PIXELS/3.0);
- rect.attributes['y'] = new svg.Property('y', -svg.MAX_VIRTUAL_PIXELS/3.0);
- rect.attributes['width'] = new svg.Property('width', svg.MAX_VIRTUAL_PIXELS);
- rect.attributes['height'] = new svg.Property('height', svg.MAX_VIRTUAL_PIXELS);
-
- var group = new svg.Element.g();
- group.attributes['transform'] = new svg.Property('transform', this.attribute('gradientTransform').value);
- group.children = [ rect ];
-
- var tempSvg = new svg.Element.svg();
- tempSvg.attributes['x'] = new svg.Property('x', 0);
- tempSvg.attributes['y'] = new svg.Property('y', 0);
- tempSvg.attributes['width'] = new svg.Property('width', rootView.width);
- tempSvg.attributes['height'] = new svg.Property('height', rootView.height);
- tempSvg.children = [ group ];
-
- var c = document.createElement('canvas');
- c.width = rootView.width;
- c.height = rootView.height;
- var tempCtx = c.getContext('2d');
- tempCtx.fillStyle = g;
- tempSvg.render(tempCtx);
- return tempCtx.createPattern(c, 'no-repeat');
- }
-
return g;
}
}
@@ -1544,8 +1494,16 @@ if(!Array.indexOf){
var y2 = (this.gradientUnits == 'objectBoundingBox'
? bb.y() + bb.height() * this.attribute('y2').numValue()
: this.attribute('y2').Length.toPixels('y'));
-
- return ctx.createLinearGradient(x1, y1, x2, y2);
+
+ var p1 = new svg.Point(x1, y1);
+ var p2 = new svg.Point(x2, y2);
+ if (this.attribute('gradientTransform').hasValue()) {
+ var transform = new svg.Transform(this.attribute('gradientTransform').value);
+ transform.applyToPoint(p1);
+ transform.applyToPoint(p2);
+ }
+
+ return ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
}
}
svg.Element.linearGradient.prototype = new svg.Element.GradientBase;
@@ -1582,7 +1540,22 @@ if(!Array.indexOf){
? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()
: this.attribute('r').Length.toPixels());
- return ctx.createRadialGradient(fx, fy, 0, cx, cy, r);
+ var c = new svg.Point(cx, cy);
+ var f = new svg.Point(fx, fy);
+ if (this.attribute('gradientTransform').hasValue()) {
+ var transform = new svg.Transform(this.attribute('gradientTransform').value);
+ transform.applyToPoint(c);
+ transform.applyToPoint(f);
+
+ for (var i=0; i<transform.transforms.length; i++) {
+ // average the scaling part of the transform, apply to radius
+ var scale1 = transform.transforms[i].m[0];
+ var scale2 = transform.transforms[i].m[3];
+ r = r * ((scale1 + scale2) / 2.0);
+ }
+ }
+
+ return ctx.createRadialGradient(f.x, f.y, 0, c.x, c.y, r);
}
}
svg.Element.radialGradient.prototype = new svg.Element.GradientBase;
@@ -1720,73 +1693,6 @@ if(!Array.indexOf){
}
svg.Element.animateTransform.prototype = new svg.Element.animate;
- // font element
- svg.Element.font = function(node) {
- this.base = svg.Element.ElementBase;
- this.base(node);
-
- this.horizAdvX = this.attribute('horiz-adv-x').numValue();
-
- this.isRTL = false;
- this.isArabic = false;
- this.fontFace = null;
- this.missingGlyph = null;
- this.glyphs = [];
- for (var i=0; i<this.children.length; i++) {
- var child = this.children[i];
- if (child.type == 'font-face') {
- this.fontFace = child;
- if (child.style('font-family').hasValue()) {
- svg.Definitions[child.style('font-family').value] = this;
- }
- }
- else if (child.type == 'missing-glyph') this.missingGlyph = child;
- else if (child.type == 'glyph') {
- if (child.arabicForm != '') {
- this.isRTL = true;
- this.isArabic = true;
- if (typeof(this.glyphs[child.unicode]) == 'undefined') this.glyphs[child.unicode] = [];
- this.glyphs[child.unicode][child.arabicForm] = child;
- }
- else {
- this.glyphs[child.unicode] = child;
- }
- }
- }
- }
- svg.Element.font.prototype = new svg.Element.ElementBase;
-
- // font-face element
- svg.Element.fontface = function(node) {
- this.base = svg.Element.ElementBase;
- this.base(node);
-
- this.ascent = this.attribute('ascent').value;
- this.descent = this.attribute('descent').value;
- this.unitsPerEm = this.attribute('units-per-em').numValue();
- }
- svg.Element.fontface.prototype = new svg.Element.ElementBase;
-
- // missing-glyph element
- svg.Element.missingglyph = function(node) {
- this.base = svg.Element.path;
- this.base(node);
-
- this.horizAdvX = 0;
- }
- svg.Element.missingglyph.prototype = new svg.Element.path;
-
- // glyph element
- svg.Element.glyph = function(node) {
- this.base = svg.Element.path;
- this.base(node);
-
- this.horizAdvX = this.attribute('horiz-adv-x').numValue();
- this.unicode = this.attribute('unicode').value;
- this.arabicForm = this.attribute('arabic-form').value;
- }
- svg.Element.glyph.prototype = new svg.Element.path;
-
// text element
svg.Element.text = function(node) {
this.base = svg.Element.RenderedElementBase;
@@ -1809,16 +1715,19 @@ if(!Array.indexOf){
this.baseSetContext = this.setContext;
this.setContext = function(ctx) {
this.baseSetContext(ctx);
- if (this.style('text-anchor').hasValue()) {
- var textAnchor = this.style('text-anchor').value;
+ if (this.attribute('text-anchor').hasValue()) {
+ var textAnchor = this.attribute('text-anchor').value;
ctx.textAlign = textAnchor == 'middle' ? 'center' : textAnchor;
}
if (this.attribute('alignment-baseline').hasValue()) ctx.textBaseline = this.attribute('alignment-baseline').value;
}
this.renderChildren = function(ctx) {
+ if(this.attribute('visibility').value=='hidden') return;
+
var x = this.attribute('x').Length.toPixels('x');
var y = this.attribute('y').Length.toPixels('y');
+
for (var i=0; i<this.children.length; i++) {
var child = this.children[i];
@@ -1850,63 +1759,8 @@ if(!Array.indexOf){
this.base = svg.Element.RenderedElementBase;
this.base(node);
- this.getGlyph = function(font, text, i) {
- var c = text[i];
- var glyph = null;
- if (font.isArabic) {
- var arabicForm = 'isolated';
- if ((i==0 || text[i-1]==' ') && i<text.length-2 && text[i+1]!=' ') arabicForm = 'terminal';
- if (i>0 && text[i-1]!=' ' && i<text.length-2 && text[i+1]!=' ') arabicForm = 'medial';
- if (i>0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial';
- if (typeof(font.glyphs[c]) != 'undefined') {
- glyph = font.glyphs[c][arabicForm];
- if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c];
- }
- }
- else {
- glyph = font.glyphs[c];
- }
- if (glyph == null) glyph = font.missingGlyph;
- return glyph;
- }
-
this.renderChildren = function(ctx) {
- var customFont = this.parent.style('font-family').Definition.getDefinition();
- if (customFont != null) {
- var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
- var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle);
- var text = this.getText();
- if (customFont.isRTL) text = text.split("").reverse().join("");
-
- if (this.parent.style('text-anchor').value == 'middle') {
- this.x = this.x - this.measureText(ctx) / 2.0;
- }
-
- var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
- for (var i=0; i<text.length; i++) {
- var glyph = this.getGlyph(customFont, text, i);
- var scale = fontSize / customFont.fontFace.unitsPerEm;
- ctx.translate(this.x, this.y);
- ctx.scale(scale, -scale);
- var lw = ctx.lineWidth;
- ctx.lineWidth = ctx.lineWidth * customFont.fontFace.unitsPerEm / fontSize;
- if (fontStyle == 'italic') ctx.transform(1, 0, .4, 1, 0, 0);
- glyph.render(ctx);
- if (fontStyle == 'italic') ctx.transform(1, 0, -.4, 1, 0, 0);
- ctx.lineWidth = lw;
- ctx.scale(1/scale, -1/scale);
- ctx.translate(-this.x, -this.y);
-
- this.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / customFont.fontFace.unitsPerEm;
- if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
- this.x += dx[i];
- }
- }
- return;
- }
-
- if (ctx.strokeStyle != '') ctx.strokeText(svg.compressSpaces(this.getText()), this.x, this.y);
- if (ctx.fillStyle != '') ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);
+ ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);
}
this.getText = function() {
@@ -1914,23 +1768,6 @@ if(!Array.indexOf){
}
this.measureText = function(ctx) {
- var customFont = this.parent.style('font-family').Definition.getDefinition();
- if (customFont != null) {
- var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
- var measure = 0;
- var text = this.getText();
- if (customFont.isRTL) text = text.split("").reverse().join("");
- var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
- for (var i=0; i<text.length; i++) {
- var glyph = this.getGlyph(customFont, text, i);
- measure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;
- if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
- measure += dx[i];
- }
- }
- return measure;
- }
-
var textToMeasure = svg.compressSpaces(this.getText());
if (!ctx.measureText) return textToMeasure.length * 10;
return ctx.measureText(textToMeasure).width;
@@ -1943,9 +1780,8 @@ if(!Array.indexOf){
this.base = svg.Element.TextElementBase;
this.base(node);
- this.text = node.nodeType == 3 ? node.nodeValue : // text
- node.childNodes.length > 0 ? node.childNodes[0].nodeValue : // element
- node.text;
+ // TEXT ELEMENT
+ this.text = node.nodeType == 3 ? node.nodeValue : node.childNodes[0].nodeValue;
this.getText = function() {
return this.text;
}
@@ -2095,9 +1931,8 @@ if(!Array.indexOf){
this.base = svg.Element.ElementBase;
this.base(node);
- // text, or spaces then CDATA
- var css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : '');
- css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments
+ var css = node.childNodes[0].nodeValue;
+ css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(\/\/.*)/gm, ''); // remove comments
css = svg.compressSpaces(css); // replace whitespace
var cssDefs = css.split('}');
for (var i=0; i<cssDefs.length; i++) {
@@ -2110,31 +1945,14 @@ if(!Array.indexOf){
if (cssClass != '') {
var props = {};
for (var k=0; k<cssProps.length; k++) {
- var prop = cssProps[k].indexOf(':');
- var name = cssProps[k].substr(0, prop);
- var value = cssProps[k].substr(prop + 1, cssProps[k].length - prop);
+ var prop = cssProps[k].split(':');
+ var name = prop[0];
+ var value = prop[1];
if (name != null && value != null) {
- props[svg.trim(name)] = new svg.Property(svg.trim(name), svg.trim(value));
+ props[svg.trim(prop[0])] = new svg.Property(svg.trim(prop[0]), svg.trim(prop[1]));
}
}
svg.Styles[cssClass] = props;
- if (cssClass == '@font-face') {
- var fontFamily = props['font-family'].value.replace(/"/g,'');
- var srcs = props['src'].value.split(',');
- for (var s=0; s<srcs.length; s++) {
- if (srcs[s].indexOf('format("svg")') > 0) {
- var urlStart = srcs[s].indexOf('url');
- var urlEnd = srcs[s].indexOf(')', urlStart);
- var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6);
- var doc = svg.parseXml(svg.ajax(url));
- var fonts = doc.getElementsByTagName('font');
- for (var f=0; f<fonts.length; f++) {
- var font = svg.CreateElement(fonts[f]);
- svg.Definitions[fontFamily] = font;
- }
- }
- }
- }
}
}
}
@@ -2186,10 +2004,6 @@ if(!Array.indexOf){
}
}
}
-
- this.render = function(ctx) {
- // NO RENDER
- }
}
svg.Element.clipPath.prototype = new svg.Element.ElementBase;
@@ -2210,8 +2024,7 @@ if(!Array.indexOf){
// element factory
svg.CreateElement = function(node) {
- var className = node.nodeName.replace(/^[^:]+:/,''); // remove namespace
- className = className.replace(/\-/g,''); // remove dashes
+ var className = node.nodeName.replace(/^[^:]+:/,'');
var e = null;
if (typeof(svg.Element[className]) != 'undefined') {
e = new svg.Element[className](node);
@@ -2231,10 +2044,6 @@ if(!Array.indexOf){
// load from xml
svg.loadXml = function(ctx, xml) {
- svg.loadXmlDoc(ctx, svg.parseXml(xml));
- }
-
- svg.loadXmlDoc = function(ctx, dom) {
svg.init(ctx);
var mapXY = function(p) {
@@ -2261,24 +2070,19 @@ if(!Array.indexOf){
};
}
+ var dom = svg.parseXml(xml);
var e = svg.CreateElement(dom.documentElement);
- e.root = true;
// render loop
var isFirstRender = true;
var draw = function() {
- svg.ViewPort.Clear();
- if (ctx.canvas.parentNode) svg.ViewPort.SetCurrent(ctx.canvas.parentNode.clientWidth, ctx.canvas.parentNode.clientHeight);
-
if (svg.opts == null || svg.opts['ignoreDimensions'] != true) {
// set canvas size
if (e.style('width').hasValue()) {
- ctx.canvas.width = e.style('width').Length.toPixels('x');
- ctx.canvas.style.width = ctx.canvas.width + 'px';
+ ctx.canvas.width = e.style('width').Length.toPixels(ctx.canvas.parentNode.clientWidth);
}
if (e.style('height').hasValue()) {
- ctx.canvas.height = e.style('height').Length.toPixels('y');
- ctx.canvas.style.height = ctx.canvas.height + 'px';
+ ctx.canvas.height = e.style('height').Length.toPixels(ctx.canvas.parentNode.clientHeight);
}
}
svg.ViewPort.SetCurrent(ctx.canvas.clientWidth, ctx.canvas.clientHeight);
diff --git a/js/canvg/rgbcolor.js b/js/canvg/rgbcolor.js
new file mode 100644
index 0000000..0338a16
--- /dev/null
+++ b/js/canvg/rgbcolor.js
@@ -0,0 +1,288 @@
+/**
+ * A class to parse color values
+ * @author Stoyan Stefanov <sstoo at gmail.com>
+ * @link http://www.phpied.com/rgb-color-parser-in-javascript/
+ * @license Use it if you like it
+ */
+function RGBColor(color_string)
+{
+ this.ok = false;
+
+ // strip any leading #
+ if (color_string.charAt(0) == '#') { // remove # if any
+ color_string = color_string.substr(1,6);
+ }
+
+ color_string = color_string.replace(/ /g,'');
+ color_string = color_string.toLowerCase();
+
+ // before getting into regexps, try simple matches
+ // and overwrite the input
+ var simple_colors = {
+ aliceblue: 'f0f8ff',
+ antiquewhite: 'faebd7',
+ aqua: '00ffff',
+ aquamarine: '7fffd4',
+ azure: 'f0ffff',
+ beige: 'f5f5dc',
+ bisque: 'ffe4c4',
+ black: '000000',
+ blanchedalmond: 'ffebcd',
+ blue: '0000ff',
+ blueviolet: '8a2be2',
+ brown: 'a52a2a',
+ burlywood: 'deb887',
+ cadetblue: '5f9ea0',
+ chartreuse: '7fff00',
+ chocolate: 'd2691e',
+ coral: 'ff7f50',
+ cornflowerblue: '6495ed',
+ cornsilk: 'fff8dc',
+ crimson: 'dc143c',
+ cyan: '00ffff',
+ darkblue: '00008b',
+ darkcyan: '008b8b',
+ darkgoldenrod: 'b8860b',
+ darkgray: 'a9a9a9',
+ darkgreen: '006400',
+ darkkhaki: 'bdb76b',
+ darkmagenta: '8b008b',
+ darkolivegreen: '556b2f',
+ darkorange: 'ff8c00',
+ darkorchid: '9932cc',
+ darkred: '8b0000',
+ darksalmon: 'e9967a',
+ darkseagreen: '8fbc8f',
+ darkslateblue: '483d8b',
+ darkslategray: '2f4f4f',
+ darkturquoise: '00ced1',
+ darkviolet: '9400d3',
+ deeppink: 'ff1493',
+ deepskyblue: '00bfff',
+ dimgray: '696969',
+ dodgerblue: '1e90ff',
+ feldspar: 'd19275',
+ firebrick: 'b22222',
+ floralwhite: 'fffaf0',
+ forestgreen: '228b22',
+ fuchsia: 'ff00ff',
+ gainsboro: 'dcdcdc',
+ ghostwhite: 'f8f8ff',
+ gold: 'ffd700',
+ goldenrod: 'daa520',
+ gray: '808080',
+ green: '008000',
+ greenyellow: 'adff2f',
+ honeydew: 'f0fff0',
+ hotpink: 'ff69b4',
+ indianred : 'cd5c5c',
+ indigo : '4b0082',
+ ivory: 'fffff0',
+ khaki: 'f0e68c',
+ lavender: 'e6e6fa',
+ lavenderblush: 'fff0f5',
+ lawngreen: '7cfc00',
+ lemonchiffon: 'fffacd',
+ lightblue: 'add8e6',
+ lightcoral: 'f08080',
+ lightcyan: 'e0ffff',
+ lightgoldenrodyellow: 'fafad2',
+ lightgrey: 'd3d3d3',
+ lightgreen: '90ee90',
+ lightpink: 'ffb6c1',
+ lightsalmon: 'ffa07a',
+ lightseagreen: '20b2aa',
+ lightskyblue: '87cefa',
+ lightslateblue: '8470ff',
+ lightslategray: '778899',
+ lightsteelblue: 'b0c4de',
+ lightyellow: 'ffffe0',
+ lime: '00ff00',
+ limegreen: '32cd32',
+ linen: 'faf0e6',
+ magenta: 'ff00ff',
+ maroon: '800000',
+ mediumaquamarine: '66cdaa',
+ mediumblue: '0000cd',
+ mediumorchid: 'ba55d3',
+ mediumpurple: '9370d8',
+ mediumseagreen: '3cb371',
+ mediumslateblue: '7b68ee',
+ mediumspringgreen: '00fa9a',
+ mediumturquoise: '48d1cc',
+ mediumvioletred: 'c71585',
+ midnightblue: '191970',
+ mintcream: 'f5fffa',
+ mistyrose: 'ffe4e1',
+ moccasin: 'ffe4b5',
+ navajowhite: 'ffdead',
+ navy: '000080',
+ oldlace: 'fdf5e6',
+ olive: '808000',
+ olivedrab: '6b8e23',
+ orange: 'ffa500',
+ orangered: 'ff4500',
+ orchid: 'da70d6',
+ palegoldenrod: 'eee8aa',
+ palegreen: '98fb98',
+ paleturquoise: 'afeeee',
+ palevioletred: 'd87093',
+ papayawhip: 'ffefd5',
+ peachpuff: 'ffdab9',
+ peru: 'cd853f',
+ pink: 'ffc0cb',
+ plum: 'dda0dd',
+ powderblue: 'b0e0e6',
+ purple: '800080',
+ red: 'ff0000',
+ rosybrown: 'bc8f8f',
+ royalblue: '4169e1',
+ saddlebrown: '8b4513',
+ salmon: 'fa8072',
+ sandybrown: 'f4a460',
+ seagreen: '2e8b57',
+ seashell: 'fff5ee',
+ sienna: 'a0522d',
+ silver: 'c0c0c0',
+ skyblue: '87ceeb',
+ slateblue: '6a5acd',
+ slategray: '708090',
+ snow: 'fffafa',
+ springgreen: '00ff7f',
+ steelblue: '4682b4',
+ tan: 'd2b48c',
+ teal: '008080',
+ thistle: 'd8bfd8',
+ tomato: 'ff6347',
+ turquoise: '40e0d0',
+ violet: 'ee82ee',
+ violetred: 'd02090',
+ wheat: 'f5deb3',
+ white: 'ffffff',
+ whitesmoke: 'f5f5f5',
+ yellow: 'ffff00',
+ yellowgreen: '9acd32'
+ };
+ for (var key in simple_colors) {
+ if (color_string == key) {
+ color_string = simple_colors[key];
+ }
+ }
+ // emd of simple type-in colors
+
+ // array of color definition objects
+ var color_defs = [
+ {
+ re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
+ example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
+ process: function (bits){
+ return [
+ parseInt(bits[1]),
+ parseInt(bits[2]),
+ parseInt(bits[3])
+ ];
+ }
+ },
+ {
+ re: /^(\w{2})(\w{2})(\w{2})$/,
+ example: ['#00ff00', '336699'],
+ process: function (bits){
+ return [
+ parseInt(bits[1], 16),
+ parseInt(bits[2], 16),
+ parseInt(bits[3], 16)
+ ];
+ }
+ },
+ {
+ re: /^(\w{1})(\w{1})(\w{1})$/,
+ example: ['#fb0', 'f0f'],
+ process: function (bits){
+ return [
+ parseInt(bits[1] + bits[1], 16),
+ parseInt(bits[2] + bits[2], 16),
+ parseInt(bits[3] + bits[3], 16)
+ ];
+ }
+ }
+ ];
+
+ // search through the definitions to find a match
+ for (var i = 0; i < color_defs.length; i++) {
+ var re = color_defs[i].re;
+ var processor = color_defs[i].process;
+ var bits = re.exec(color_string);
+ if (bits) {
+ channels = processor(bits);
+ this.r = channels[0];
+ this.g = channels[1];
+ this.b = channels[2];
+ this.ok = true;
+ }
+
+ }
+
+ // validate/cleanup values
+ this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 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);
+
+ // some getters
+ this.toRGB = function () {
+ return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
+ }
+ this.toHex = function () {
+ var r = this.r.toString(16);
+ var g = this.g.toString(16);
+ var b = this.b.toString(16);
+ if (r.length == 1) r = '0' + r;
+ if (g.length == 1) g = '0' + g;
+ if (b.length == 1) b = '0' + b;
+ return '#' + r + g + b;
+ }
+
+ // help
+ this.getHelpXML = function () {
+
+ var examples = new Array();
+ // add regexps
+ for (var i = 0; i < color_defs.length; i++) {
+ var example = color_defs[i].example;
+ for (var j = 0; j < example.length; j++) {
+ examples[examples.length] = example[j];
+ }
+ }
+ // add type-in colors
+ for (var sc in simple_colors) {
+ examples[examples.length] = sc;
+ }
+
+ var xml = document.createElement('ul');
+ xml.setAttribute('id', 'rgbcolor-examples');
+ for (var i = 0; i < examples.length; i++) {
+ try {
+ var list_item = document.createElement('li');
+ var list_color = new RGBColor(examples[i]);
+ var example_div = document.createElement('div');
+ example_div.style.cssText =
+ 'margin: 3px; '
+ + 'border: 1px solid black; '
+ + 'background:' + list_color.toHex() + '; '
+ + 'color:' + list_color.toHex()
+ ;
+ example_div.appendChild(document.createTextNode('test'));
+ var list_item_value = document.createTextNode(
+ ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
+ );
+ list_item.appendChild(example_div);
+ list_item.appendChild(list_item_value);
+ xml.appendChild(list_item);
+
+ } catch(e){}
+ }
+ return xml;
+
+ }
+
+}
+
diff --git a/js/date.js b/js/date.js
new file mode 100644
index 0000000..9a92340
--- /dev/null
+++ b/js/date.js
@@ -0,0 +1,335 @@
+// ===================================================================
+// Author: Matt Kruse <matt at mattkruse.com>
+// WWW: http://www.mattkruse.com/
+//
+// NOTICE: You may use this code for any purpose, commercial or
+// private, without any further permission from the author. You may
+// remove this notice from your final code if you wish, however it is
+// appreciated by the author if at least my web site address is kept.
+//
+// You may *NOT* re-distribute this code in any way except through its
+// use. That means, you can include it in your product, or your web
+// site, or any other form where the code is actually being used. You
+// may not put the plain javascript up on your site for download or
+// include it in your javascript libraries for download.
+// If you wish to share this code with others, please just point them
+// to the URL instead.
+// Please DO NOT link directly to my .js files from your site. Copy
+// the files to your server and use them there. Thank you.
+// ===================================================================
+
+// HISTORY
+// ------------------------------------------------------------------
+// May 17, 2003: Fixed bug in parseDate() for dates <1970
+// March 11, 2003: Added parseDate() function
+// March 11, 2003: Added "NNN" formatting option. Doesn't match up
+// perfectly with SimpleDateFormat formats, but
+// backwards-compatability was required.
+
+// ------------------------------------------------------------------
+// These functions use the same 'format' strings as the
+// java.text.SimpleDateFormat class, with minor exceptions.
+// The format string consists of the following abbreviations:
+//
+// Field | Full Form | Short Form
+// -------------+--------------------+-----------------------
+// Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits)
+// Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
+// | NNN (abbr.) |
+// Day of Month | dd (2 digits) | d (1 or 2 digits)
+// Day of Week | EE (name) | E (abbr)
+// Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
+// Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
+// Hour (0-11) | KK (2 digits) | K (1 or 2 digits)
+// Hour (1-24) | kk (2 digits) | k (1 or 2 digits)
+// Minute | mm (2 digits) | m (1 or 2 digits)
+// Second | ss (2 digits) | s (1 or 2 digits)
+// AM/PM | a |
+//
+// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
+// Examples:
+// "MMM d, y" matches: January 01, 2000
+// Dec 1, 1900
+// Nov 20, 00
+// "M/d/yy" matches: 01/20/00
+// 9/2/00
+// "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
+// ------------------------------------------------------------------
+
+var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
+var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
+function LZ(x) {return(x<0||x>9?"":"0")+x}
+
+// ------------------------------------------------------------------
+// isDate ( date_string, format_string )
+// Returns true if date string matches format of format string and
+// is a valid date. Else returns false.
+// It is recommended that you trim whitespace around the value before
+// passing it to this function, as whitespace is NOT ignored!
+// ------------------------------------------------------------------
+function isDate(val,format) {
+ var date=getDateFromFormat(val,format);
+ if (date==0) { return false; }
+ return true;
+ }
+
+// -------------------------------------------------------------------
+// compareDates(date1,date1format,date2,date2format)
+// Compare two date strings to see which is greater.
+// Returns:
+// 1 if date1 is greater than date2
+// 0 if date2 is greater than date1 of if they are the same
+// -1 if either of the dates is in an invalid format
+// -------------------------------------------------------------------
+function compareDates(date1,dateformat1,date2,dateformat2) {
+ var d1=getDateFromFormat(date1,dateformat1);
+ var d2=getDateFromFormat(date2,dateformat2);
+ if (d1==0 || d2==0) {
+ return -1;
+ }
+ else if (d1 > d2) {
+ return 1;
+ }
+ return 0;
+ }
+
+// ------------------------------------------------------------------
+// formatDate (date_object, format)
+// Returns a date in the output format specified.
+// The format string uses the same abbreviations as in getDateFromFormat()
+// ------------------------------------------------------------------
+function formatDate(date,format) {
+ format=format+"";
+ var result="";
+ var i_format=0;
+ var c="";
+ var token="";
+ var y=date.getYear()+"";
+ var M=date.getMonth()+1;
+ var d=date.getDate();
+ var E=date.getDay();
+ var H=date.getHours();
+ var m=date.getMinutes();
+ var s=date.getSeconds();
+ var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
+ // Convert real date parts into formatted versions
+ var value=new Object();
+ if (y.length < 4) {y=""+(y-0+1900);}
+ value["y"]=""+y;
+ value["yyyy"]=y;
+ value["yy"]=y.substring(2,4);
+ value["M"]=M;
+ value["MM"]=LZ(M);
+ value["MMM"]=MONTH_NAMES[M-1];
+ value["NNN"]=MONTH_NAMES[M+11];
+ value["d"]=d;
+ value["dd"]=LZ(d);
+ value["E"]=DAY_NAMES[E+7];
+ value["EE"]=DAY_NAMES[E];
+ value["H"]=H;
+ value["HH"]=LZ(H);
+ if (H==0){value["h"]=12;}
+ else if (H>12){value["h"]=H-12;}
+ else {value["h"]=H;}
+ value["hh"]=LZ(value["h"]);
+ if (H>11){value["K"]=H-12;} else {value["K"]=H;}
+ value["k"]=H+1;
+ value["KK"]=LZ(value["K"]);
+ value["kk"]=LZ(value["k"]);
+ if (H > 11) { value["a"]="PM"; }
+ else { value["a"]="AM"; }
+ value["m"]=m;
+ value["mm"]=LZ(m);
+ value["s"]=s;
+ value["ss"]=LZ(s);
+ while (i_format < format.length) {
+ c=format.charAt(i_format);
+ token="";
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
+ token += format.charAt(i_format++);
+ }
+ if (value[token] != null) { result=result + value[token]; }
+ else { result=result + token; }
+ }
+ return result;
+ }
+
+// ------------------------------------------------------------------
+// Utility functions for parsing in getDateFromFormat()
+// ------------------------------------------------------------------
+function _isInteger(val) {
+ var digits="1234567890";
+ for (var i=0; i < val.length; i++) {
+ if (digits.indexOf(val.charAt(i))==-1) { return false; }
+ }
+ return true;
+ }
+function _getInt(str,i,minlength,maxlength) {
+ for (var x=maxlength; x>=minlength; x--) {
+ var token=str.substring(i,i+x);
+ if (token.length < minlength) { return null; }
+ if (_isInteger(token)) { return token; }
+ }
+ return null;
+ }
+
+// ------------------------------------------------------------------
+// getDateFromFormat( date_string , format_string )
+//
+// This function takes a date string and a format string. It matches
+// If the date string matches the format string, it returns the
+// getTime() of the date. If it does not match, it returns 0.
+// ------------------------------------------------------------------
+function getDateFromFormat(val,format) {
+ val=val+"";
+ format=format+"";
+ var i_val=0;
+ var i_format=0;
+ var c="";
+ var token="";
+ var token2="";
+ var x,y;
+ var now=new Date();
+ var year=now.getYear();
+ var month=now.getMonth()+1;
+ var date=1;
+ var hh=now.getHours();
+ var mm=now.getMinutes();
+ var ss=now.getSeconds();
+ var ampm="";
+
+ while (i_format < format.length) {
+ // Get next token from format string
+ c=format.charAt(i_format);
+ token="";
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
+ token += format.charAt(i_format++);
+ }
+ // Extract contents of value based on format token
+ if (token=="yyyy" || token=="yy" || token=="y") {
+ if (token=="yyyy") { x=4;y=4; }
+ if (token=="yy") { x=2;y=2; }
+ if (token=="y") { x=2;y=4; }
+ year=_getInt(val,i_val,x,y);
+ if (year==null) { return 0; }
+ i_val += year.length;
+ if (year.length==2) {
+ if (year > 70) { year=1900+(year-0); }
+ else { year=2000+(year-0); }
+ }
+ }
+ else if (token=="MMM"||token=="NNN"){
+ month=0;
+ for (var i=0; i<MONTH_NAMES.length; i++) {
+ var month_name=MONTH_NAMES[i];
+ if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
+ if (token=="MMM"||(token=="NNN"&&i>11)) {
+ month=i+1;
+ if (month>12) { month -= 12; }
+ i_val += month_name.length;
+ break;
+ }
+ }
+ }
+ if ((month < 1)||(month>12)){return 0;}
+ }
+ else if (token=="EE"||token=="E"){
+ for (var i=0; i<DAY_NAMES.length; i++) {
+ var day_name=DAY_NAMES[i];
+ if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
+ i_val += day_name.length;
+ break;
+ }
+ }
+ }
+ else if (token=="MM"||token=="M") {
+ month=_getInt(val,i_val,token.length,2);
+ if(month==null||(month<1)||(month>12)){return 0;}
+ i_val+=month.length;}
+ else if (token=="dd"||token=="d") {
+ date=_getInt(val,i_val,token.length,2);
+ if(date==null||(date<1)||(date>31)){return 0;}
+ i_val+=date.length;}
+ else if (token=="hh"||token=="h") {
+ hh=_getInt(val,i_val,token.length,2);
+ if(hh==null||(hh<1)||(hh>12)){return 0;}
+ i_val+=hh.length;}
+ else if (token=="HH"||token=="H") {
+ hh=_getInt(val,i_val,token.length,2);
+ if(hh==null||(hh<0)||(hh>23)){return 0;}
+ i_val+=hh.length;}
+ else if (token=="KK"||token=="K") {
+ hh=_getInt(val,i_val,token.length,2);
+ if(hh==null||(hh<0)||(hh>11)){return 0;}
+ i_val+=hh.length;}
+ else if (token=="kk"||token=="k") {
+ hh=_getInt(val,i_val,token.length,2);
+ if(hh==null||(hh<1)||(hh>24)){return 0;}
+ i_val+=hh.length;hh--;}
+ else if (token=="mm"||token=="m") {
+ mm=_getInt(val,i_val,token.length,2);
+ if(mm==null||(mm<0)||(mm>59)){return 0;}
+ i_val+=mm.length;}
+ else if (token=="ss"||token=="s") {
+ ss=_getInt(val,i_val,token.length,2);
+ if(ss==null||(ss<0)||(ss>59)){return 0;}
+ i_val+=ss.length;}
+ else if (token=="a") {
+ if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
+ else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
+ else {return 0;}
+ i_val+=2;}
+ else {
+ if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
+ else {i_val+=token.length;}
+ }
+ }
+ // If there are any trailing characters left in the value, it doesn't match
+ if (i_val != val.length) { return 0; }
+ // Is date valid for month?
+ if (month==2) {
+ // Check for leap year
+ if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
+ if (date > 29){ return 0; }
+ }
+ else { if (date > 28) { return 0; } }
+ }
+ if ((month==4)||(month==6)||(month==9)||(month==11)) {
+ if (date > 30) { return 0; }
+ }
+ // Correct hours value
+ if (hh<12 && ampm=="PM") { hh=hh-0+12; }
+ else if (hh>11 && ampm=="AM") { hh-=12; }
+ var newdate=new Date(year,month-1,date,hh,mm,ss);
+ return newdate.getTime();
+ }
+
+// ------------------------------------------------------------------
+// parseDate( date_string [, prefer_euro_format] )
+//
+// This function takes a date string and tries to match it to a
+// number of possible date formats to get the value. It will try to
+// match against the following international formats, in this order:
+// y-M-d MMM d, y MMM d,y y-MMM-d d-MMM-y MMM d
+// M/d/y M-d-y M.d.y MMM-d M/d M-d
+// d/M/y d-M-y d.M.y d-MMM d/M d-M
+// A second argument may be passed to instruct the method to search
+// for formats like d/M/y (european format) before M/d/y (American).
+// Returns a Date object or null if no patterns match.
+// ------------------------------------------------------------------
+function parseDate(val) {
+ var preferEuro=(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 checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
+ var d=null;
+ for (var i=0; i<checkList.length; i++) {
+ var l=window[checkList[i]];
+ for (var j=0; j<l.length; j++) {
+ d=getDateFromFormat(val,l[j]);
+ if (d!=0) { return new Date(d); }
+ }
+ }
+ return null;
+ }
diff --git a/js/messages.php b/js/messages.php
index 63fb182..b942a18 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -258,6 +258,12 @@ $js_messages['strSave'] = __('Save');
$js_messages['strHideSearchCriteria'] = __('Hide search criteria');
$js_messages['strShowSearchCriteria'] = __('Show search criteria');
+/* For tbl_zoom_plot.js */
+$js_messages['strZoomSearch'] = __('Zoom Search');
+$js_messages['strDisplayHelp'] = __('* Each point represents a data row.<br>* Hovering over a point will show its label.<br>* Drag and select an area in the plot to zoom into it.<br>* Click reset zoom link to come back to original state.<br>* Click a data point to view and possibly edit the data row.<br>* The plot can be resized by dragging it along the bottom right corner.<br>* Strings are converted into integer for plotting');
+$js_messages['strInputNull'] = __('<b>Select two columns</b>');
+$js_messages['strSameInputs'] = __('<b>Select two different columns</b>');
+
/* For tbl_change.js */
$js_messages['strIgnore'] = __('Ignore');
diff --git a/js/tbl_select.js b/js/tbl_select.js
index 3bc1137..af2242a 100644
--- a/js/tbl_select.js
+++ b/js/tbl_select.js
@@ -66,7 +66,7 @@ $(document).ready(function() {
if (typeof response == 'string') {
// found results
$("#sqlqueryresults").html(response);
- $("#sqlqueryresults").trigger('makegrid');
+ $("#sqlqueryresults").trigger('appendAnchor');
$('#tbl_search_form')
// work around for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
.slideToggle()
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
new file mode 100644
index 0000000..b9c0d75
--- /dev/null
+++ b/js/tbl_zoom_plot.js
@@ -0,0 +1,605 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ ** @fileoverview JavaScript functions used on tbl_select.php
+ **
+ ** @requires jQuery
+ ** @requires js/functions.js
+ **/
+
+
+/**
+ ** Display Help/Info
+ **/
+function displayHelp() {
+ var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000);
+ msgbox.click(function() {
+ PMA_ajaxRemoveMessage(msgbox);
+ });
+}
+
+/**
+ ** Extend the array object for max function
+ ** @param array
+ **/
+Array.max = function (array) {
+ return Math.max.apply( Math, array );
+}
+
+/**
+ ** Extend the array object for min function
+ ** @param array
+ **/
+Array.min = function (array) {
+ return Math.min.apply( Math, array );
+}
+
+/**
+ ** Checks if a string contains only numeric value
+ ** @param n: String (to be checked)
+ **/
+function isNumeric(n) {
+ return !isNaN(parseFloat(n)) && isFinite(n);
+}
+
+/**
+ ** Checks if an object is empty
+ ** @param n: Object (to be checked)
+ **/
+function isEmpty(obj) {
+ var name;
+ for (name in obj) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ ** Converts a timestamp into the format of its field type
+ ** @param val Integer Timestamp
+ ** @param type String Field type(datetime/timestamp/time/date)
+ **/
+function getDate(val,type) {
+ if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+ return Highcharts.dateFormat('%Y-%m-%e %H:%M:%S', val)
+ }
+ else if(type.toString().search(/time/i) != -1) {
+ return Highcharts.dateFormat('%H:%M:%S', val + 19800000)
+ }
+ else if (type.toString().search(/date/i) != -1) {
+ return Highcharts.dateFormat('%Y-%m-%e', val)
+ }
+}
+
+/**
+ ** Converts a date/time into timestamp
+ ** @param val String Date
+ ** @param type Sring Field type(datetime/timestamp/time/date)
+ **/
+function getTimeStamp(val,type) {
+ if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+ return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val)
+ }
+ else if(type.toString().search(/time/i) != -1) {
+ return getDateFromFormat('1970-01-01 ' + val,'yyyy-MM-dd HH:mm:ss')
+ }
+ else if (type.toString().search(/date/i) != -1) {
+ return getDateFromFormat(val,'yyyy-MM-dd')
+ }
+}
+
+/**
+ ** Classifies the field type into numeric,timeseries or text
+ ** @param field: field type (as in database structure)
+ **/
+function getType(field) {
+ if(field.toString().search(/int/i) != -1 || field.toString().search(/decimal/i) != -1 || field.toString().search(/year/i) != -1)
+ return 'numeric';
+ else if(field.toString().search(/time/i) != -1 || field.toString().search(/date/i) != -1)
+ return 'time';
+ else
+ return 'text';
+}
+/**
+ ** Converts a categorical array into numeric array
+ ** @param array categorical values array
+ **/
+function getCord(arr) {
+ var newCord = new Array();
+ var original = $.extend(true,[],arr);
+ var arr = jQuery.unique(arr).sort();
+ $.each(original, function(index,value) {
+ newCord.push(jQuery.inArray(value,arr));
+ });
+ return [newCord,arr,original];
+}
+
+/**
+ ** Scrolls the view to the display section
+ **/
+function scrollToChart() {
+ var x = $('#dataDisplay').offset().top - 100; // 100 provides buffer in viewport
+ $('html,body').animate({scrollTop: x}, 500);
+}
+
+$(document).ready(function() {
+
+ /**
+ ** Set a parameter for all Ajax queries made on this page. Don't let the
+ ** web server serve cached pages
+ **/
+ $.ajaxSetup({
+ cache: 'false'
+ });
+
+ var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer';
+ var currentChart = null;
+ var currentData = null;
+ var xLabel = $('#tableid_0').val();
+ var yLabel = $('#tableid_1').val();
+ var xType = $('#types_0').val();
+ var yType = $('#types_1').val();
+ var dataLabel = $('#dataLabel').val();
+
+ // Get query result
+ var data = jQuery.parseJSON($('#querydata').html());
+
+ /**
+ ** Input form submit on field change
+ **/
+ $('#tableid_0').change(function() {
+ $('#zoom_search_form').submit();
+ })
+
+ $('#tableid_1').change(function() {
+ $('#zoom_search_form').submit();
+ })
+
+ $('#tableid_2').change(function() {
+ $('#zoom_search_form').submit();
+ })
+
+ $('#tableid_3').change(function() {
+ $('#zoom_search_form').submit();
+ })
+
+ /**
+ * Input form validation
+ **/
+ $('#inputFormSubmitId').click(function() {
+ if ($('#tableid_0').get(0).selectedIndex == 0 || $('#tableid_1').get(0).selectedIndex == 0)
+ PMA_ajaxShowMessage(PMA_messages['strInputNull']);
+ else if (xLabel == yLabel)
+ PMA_ajaxShowMessage(PMA_messages['strSameInputs']);
+ });
+
+ /**
+ ** Prepare a div containing a link, otherwise it's incorrectly displayed
+ ** after a couple of clicks
+ **/
+ $('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>')
+ .insertAfter('#zoom_search_form')
+ // don't show it until we have results on-screen
+ .hide();
+
+ $('#togglesearchformlink')
+ .html(PMA_messages['strShowSearchCriteria'])
+ .bind('click', function() {
+ var $link = $(this);
+ $('#zoom_search_form').slideToggle();
+ if ($link.text() == PMA_messages['strHideSearchCriteria']) {
+ $link.text(PMA_messages['strShowSearchCriteria']);
+ } else {
+ $link.text(PMA_messages['strHideSearchCriteria']);
+ }
+ // avoid default click action
+ return false;
+ });
+
+ /**
+ ** Set dialog properties for the data display form
+ **/
+ $("#dataDisplay").dialog({
+ autoOpen: false,
+ title: 'Data point content',
+ modal: false, //false otherwise other dialogues like timepicker may not function properly
+ height: $('#dataDisplay').height() + 80,
+ width: $('#dataDisplay').width() + 80
+ });
+
+ /*
+ * Handle submit of zoom_display_form
+ */
+
+ $("#submitForm").click(function(event) {
+
+ //Prevent default submission of form
+ event.preventDefault();
+
+ //Find changed values by comparing form values with selectedRow Object
+ var newValues = new Array();//Stores the values changed from original
+ var it = 4;
+ var xChange = false;
+ var yChange = false;
+ for (key in selectedRow) {
+ if (key != 'where_clause'){
+ var oldVal = selectedRow[key];
+ var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val();
+ if (oldVal != newVal){
+ selectedRow[key] = newVal;
+ newValues[key] = newVal;
+ if(key == xLabel) {
+ xChange = true;
+ data[currentData][xLabel] = newVal;
+ }
+ else if(key == yLabel) {
+ yChange = true;
+ data[currentData][yLabel] = newVal;
+ }
+ }
+ }
+ it++
+ }//End data update
+
+ //Update the chart series and replot
+ if (xChange || yChange) {
+ var newSeries = new Array();
+ newSeries[0] = new Object();
+ newSeries[0].marker = {
+ symbol: 'circle'
+ };
+ //Logic similar to plot generation, replot only if xAxis changes or yAxis changes. Code includes a lot of checks so as to replot only when necessary
+ if(xChange) {
+ xCord[currentData] = selectedRow[xLabel];
+ if(xType == 'numeric') {
+ currentChart.series[0].data[currentData].update({ x : selectedRow[xLabel] });
+ currentChart.xAxis[0].setExtremes(Array.min(xCord) - 6,Array.max(xCord) + 6);
+ }
+ else if(xType == 'time') {
+ currentChart.series[0].data[currentData].update({ x : getTimeStamp(selectedRow[xLabel],$('#types_0').val())});
+ }
+ else {
+ var tempX = getCord(xCord);
+ var tempY = getCord(yCord);
+ var i = 0;
+ newSeries[0].data = new Array();
+ xCord = tempX[2];
+ yCord = tempY[2];
+
+ $.each(data,function(key,value) {
+ if(yType != 'text')
+ newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: value[yLabel], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+ else
+ newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+ i++;
+ });
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
+ }
+ }
+ currentSettings.series = newSeries;
+ currentChart = PMA_createChart(currentSettings);
+ }
+
+ }
+ if(yChange) {
+
+ yCord[currentData] = selectedRow[yLabel];
+ if(yType == 'numeric') {
+ currentChart.series[0].data[currentData].update({ y : selectedRow[yLabel] });
+ currentChart.yAxis[0].setExtremes(Array.min(yCord) - 6,Array.max(yCord) + 6);
+ }
+ else if(yType =='time') {
+ currentChart.series[0].data[currentData].update({ y : getTimeStamp(selectedRow[yLabel],$('#types_1').val())});
+ }
+ else {
+ var tempX = getCord(xCord);
+ var tempY = getCord(yCord);
+ var i = 0;
+ newSeries[0].data = new Array();
+ xCord = tempX[2];
+ yCord = tempY[2];
+
+ $.each(data,function(key,value) {
+ if(xType != 'text' )
+ newSeries[0].data.push({ name: value[dataLabel], x: value[xLabel], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+ else
+ newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+ i++;
+ });
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
+ }
+ }
+ currentSettings.series = newSeries;
+ currentChart = PMA_createChart(currentSettings);
+ }
+ }
+ currentChart.series[0].data[currentData].select();
+ }
+ //End plot update
+
+ //Generate SQL query for update
+ if (!isEmpty(newValues)) {
+ var sql_query = 'UPDATE `' + window.parent.table + '` SET ';
+ for (key in newValues) {
+ if(key != 'where_clause') {
+ sql_query += '`' + key + '`=' ;
+ var value = newValues[key];
+ if(!isNumeric(value) && value != null)
+ sql_query += '\'' + value + '\' ,';
+ else
+ sql_query += value + ' ,';
+ }
+ }
+ sql_query = sql_query.substring(0, sql_query.length - 1);
+ sql_query += ' WHERE ' + PMA_urldecode(data[currentData]['where_clause']);
+
+ //Post SQL query to sql.php
+ $.post('sql.php', {
+ 'token' : window.parent.token,
+ 'db' : window.parent.db,
+ 'ajax_request' : true,
+ 'sql_query' : sql_query,
+ 'inline_edit' : false
+ }, function(data) {
+ if(data.success == true) {
+ $('#sqlqueryresults').html(data.sql_query);
+ $("#sqlqueryresults").trigger('appendAnchor');
+ }
+ else
+ PMA_ajaxShowMessage(data.error);
+ })//End $.post
+ }//End database update
+ $("#dataDisplay").dialog("close");
+ });//End submit handler
+
+ /*
+ * Generate plot using Highcharts
+ */
+
+ if (data != null) {
+ $('#zoom_search_form')
+ .slideToggle()
+ .hide();
+ $('#togglesearchformlink')
+ .text(PMA_messages['strShowSearchCriteria'])
+ $('#togglesearchformdiv').show();
+ var selectedRow;
+ var columnNames = new Array();
+ var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF'];
+ var series = new Array();
+ var xCord = new Array();
+ var yCord = new Array();
+ var xCat = new Array();
+ var yCat = new Array();
+ var tempX, tempY;
+ var it = 0;
+
+ // Set the basic plot settings
+ var currentSettings = {
+ chart: {
+ renderTo: 'querychart',
+ type: 'scatter',
+ zoomType: 'xy',
+ width:$('#resizer').width() -3,
+ height:$('#resizer').height()-20
+ },
+ credits: {
+ enabled: false
+ },
+ exporting: { enabled: false },
+ label: { text: $('#dataLabel').val() },
+ plotOptions: {
+ series: {
+ allowPointSelect: true,
+ cursor: 'pointer',
+ showInLegend: false,
+ dataLabels: {
+ enabled: false,
+ },
+ point: {
+ events: {
+ click: function() {
+ var id = this.id;
+ var fid = 4;
+ currentData = id;
+ // Make AJAX request to tbl_zoom_select.php for getting the complete row info
+ var post_params = {
+ 'ajax_request' : true,
+ 'get_data_row' : true,
+ 'db' : window.parent.db,
+ 'table' : window.parent.table,
+ 'where_clause' : data[id]['where_clause'],
+ 'token' : window.parent.token,
+ }
+ $.post('tbl_zoom_select.php', post_params, function(data) {
+ // Row is contained in data.row_info, now fill the displayResultForm with row values
+ for ( key in data.row_info) {
+ if (data.row_info[key] == null)
+ $('#fields_null_id_' + fid).attr('checked', true);
+ else
+ $('#fieldID_' + fid).val(data.row_info[key]);
+ fid++;
+ }
+ selectedRow = new Object();
+ selectedRow = data.row_info;
+ });
+
+ $("#dataDisplay").dialog("open");
+ },
+ }
+ }
+ }
+ },
+ tooltip: {
+ formatter: function() {
+ return this.point.name;
+ }
+ },
+ title: { text: 'Query Results' },
+ xAxis: {
+ title: { text: $('#tableid_0').val() },
+ },
+ yAxis: {
+ min: null,
+ title: { text: $('#tableid_1').val() },
+ },
+ }
+
+ $('#resizer').resizable({
+ resize: function() {
+ currentChart.setSize(
+ this.offsetWidth -3,
+ this.offsetHeight -20,
+ false
+ );
+ }
+ });
+
+ // Classify types as either numeric,time,text
+ xType = getType(xType);
+ yType = getType(yType);
+
+ //Set the axis type based on the field
+ currentSettings.xAxis.type = (xType == 'time') ? 'datetime' : 'linear';
+ currentSettings.yAxis.type = (yType == 'time') ? 'datetime' : 'linear';
+
+ // Formulate series data for plot
+ series[0] = new Object();
+ series[0].data = new Array();
+ series[0].marker = {
+ symbol: 'circle'
+ };
+ if (xType != 'text' && yType != 'text') {
+ $.each(data,function(key,value) {
+ var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+ var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+ series[0].data.push({ name: value[dataLabel], x: xVal, y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ it++;
+ });
+ if(xType == 'numeric') {
+ currentSettings.xAxis.max = Array.max(xCord) + 6
+ currentSettings.xAxis.min = Array.min(xCord) - 6
+ }
+ else {
+ currentSettings.xAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_0').val());
+ }}
+ }
+ if(yType == 'numeric') {
+ currentSettings.yAxis.max = Array.max(yCord) + 6
+ currentSettings.yAxis.min = Array.min(yCord) - 6
+ }
+ else {
+ currentSettings.yAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_1').val());
+ }}
+ }
+
+ }
+
+ else if (xType =='text' && yType !='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+
+ tempX = getCord(xCord);
+ $.each(data,function(key,value) {
+ var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+ series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+ it++;
+ });
+
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
+ }
+ }
+ if(yType == 'numeric') {
+ currentSettings.yAxis.max = Array.max(yCord) + 6
+ currentSettings.yAxis.min = Array.min(yCord) - 6
+ }
+ else {
+ currentSettings.yAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_1').val());
+ }}
+ }
+ xCord = tempX[2];
+ }
+
+ else if (xType !='text' && yType =='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+ tempY = getCord(yCord);
+ $.each(data,function(key,value) {
+ var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+ series[0].data.push({ name: value[dataLabel], y: tempY[0][it], x: xVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+ it++;
+ });
+ if(xType == 'numeric') {
+ currentSettings.xAxis.max = Array.max(xCord) + 6
+ currentSettings.xAxis.min = Array.min(xCord) - 6
+ }
+ else {
+ currentSettings.xAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_0').val());
+ }}
+ }
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
+ }
+ }
+ yCord = tempY[2];
+ }
+
+ else if (xType =='text' && yType =='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+ tempX = getCord(xCord);
+ tempY = getCord(yCord);
+ $.each(data,function(key,value) {
+ series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: tempY[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } );
+ it++;
+ });
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
+ }
+ }
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
+ }
+ }
+ xCord = tempX[2];
+ yCord = tempY[2];
+
+ }
+
+ currentSettings.series = series;
+ currentChart = PMA_createChart(currentSettings);
+ scrollToChart();
+ }
+});
diff --git a/libraries/common.inc.php b/libraries/common.inc.php
index c806923..d40cd7b 100644
--- a/libraries/common.inc.php
+++ b/libraries/common.inc.php
@@ -413,6 +413,7 @@ $goto_whitelist = array(
'tbl_replace.php',
'tbl_row_action.php',
'tbl_select.php',
+ 'tbl_zoom_select.php',
//'themes.php',
'transformation_overview.php',
'transformation_wrapper.php',
diff --git a/libraries/config.default.php b/libraries/config.default.php
index efb0cbb..d8367e5 100644
--- a/libraries/config.default.php
+++ b/libraries/config.default.php
@@ -1137,7 +1137,6 @@ $cfg['DefaultTabDatabase'] = 'db_structure.php';
*/
$cfg['DefaultTabTable'] = 'sql.php';
-
/*******************************************************************************
* Export defaults
*/
@@ -1845,7 +1844,6 @@ $cfg['Export']['xml_export_contents'] = true;
*/
$cfg['Export']['yaml_structure_or_data'] = 'data';
-
/*******************************************************************************
* Import defaults
*/
@@ -2443,7 +2441,6 @@ $cfg['UserprefsDisallow'] = array();
*/
$cfg['UserprefsDeveloperTab'] = false;
-
/*******************************************************************************
* Window title settings
*/
@@ -2554,9 +2551,7 @@ $cfg['DefaultQueryDatabase'] = '';
/*******************************************************************************
* SQL Query box settings
* These are the links display in all of the SQL Query boxes
- */
-
-/**
+ *
* @global array $cfg['SQLQuery']
*/
$cfg['SQLQuery'] = array();
@@ -2628,7 +2623,7 @@ $cfg['SaveDir'] = '';
$cfg['TempDir'] = '';
-/*******************************************************************************
+/**
* Misc. settings
*/
@@ -2673,12 +2668,7 @@ $cfg['LinkLengthLimit'] = 1000;
*/
$cfg['DisableMultiTableMaintenance'] = false;
-
/*******************************************************************************
- * SQL Parser
- */
-
-/**
* SQL Parser Settings
*
* @global array $cfg['SQP']
@@ -2708,10 +2698,6 @@ $cfg['SQP']['fmtIndUnit'] = 'em';
/*******************************************************************************
- * SQL Validator
- */
-
-/**
* If you wish to use the SQL Validator service, you should be aware of the
* following:
* All SQL statements are stored anonymously for statistical purposes.
@@ -2746,10 +2732,6 @@ $cfg['SQLValidator']['password'] = '';
/*******************************************************************************
* Developers ONLY!
- */
-
-/**
- * Debugging settings
*
* @global array $cfg['DBG']
*/
@@ -2768,50 +2750,328 @@ $cfg['DBG']['sql'] = false;
*/
/**
- * Column types
- *
- * Fill in this array to overwrite data from data_*.inc.php files
+ * Column types;
+ * VARCHAR, TINYINT, TEXT and DATE are listed first, based on estimated popularity
*
* @global array $cfg['ColumnTypes']
*/
-$cfg['ColumnTypes'] = array();
+$cfg['ColumnTypes'] = array(
+ // most used
+ 'INT',
+ 'VARCHAR',
+ 'TEXT',
+ 'DATE',
+
+ // numeric
+ 'NUMERIC' => array(
+ 'TINYINT',
+ 'SMALLINT',
+ 'MEDIUMINT',
+ 'INT',
+ 'BIGINT',
+ '-',
+ 'DECIMAL',
+ 'FLOAT',
+ 'DOUBLE',
+ 'REAL',
+ '-',
+ 'BIT',
+ 'BOOLEAN',
+ 'SERIAL',
+ ),
+
+
+ // Date/Time
+ 'DATE and TIME' => array(
+ 'DATE',
+ 'DATETIME',
+ 'TIMESTAMP',
+ 'TIME',
+ 'YEAR',
+ ),
+
+ // Text
+ 'STRING' => array(
+ 'CHAR',
+ 'VARCHAR',
+ '-',
+ 'TINYTEXT',
+ 'TEXT',
+ 'MEDIUMTEXT',
+ 'LONGTEXT',
+ '-',
+ 'BINARY',
+ 'VARBINARY',
+ '-',
+ 'TINYBLOB',
+ 'MEDIUMBLOB',
+ 'BLOB',
+ 'LONGBLOB',
+ '-',
+ 'ENUM',
+ 'SET',
+ ),
+
+ 'SPATIAL' => array(
+ 'GEOMETRY',
+ 'POINT',
+ 'LINESTRING',
+ 'POLYGON',
+ 'MULTIPOINT',
+ 'MULTILINESTRING',
+ 'MULTIPOLYGON',
+ 'GEOMETRYCOLLECTION',
+ ),
+);
/**
* Attributes
*
- * Fill in this array to overwrite data from data_*.inc.php files
- *
* @global array $cfg['AttributeTypes']
*/
-$cfg['AttributeTypes'] = array();
+$cfg['AttributeTypes'] = array(
+ '',
+ 'BINARY',
+ 'UNSIGNED',
+ 'UNSIGNED ZEROFILL',
+ 'on update CURRENT_TIMESTAMP',
+);
+
if ($cfg['ShowFunctionFields']) {
/**
* Available functions
*
- * Fill in this array to overwrite data from data_*.inc.php files
- *
* @global array $cfg['Functions']
*/
- $cfg['Functions'] = array();
+ $cfg['Functions'] = array(
+ 'ABS',
+ 'ACOS',
+ 'ASCII',
+ 'ASIN',
+ 'ATAN',
+ 'BIN',
+ 'BIT_COUNT',
+ 'BIT_LENGTH',
+ 'CEILING',
+ 'CHAR',
+ 'CHAR_LENGTH',
+ 'COMPRESS',
+ 'COS',
+ 'COT',
+ 'CRC32',
+ 'CURDATE',
+ 'CURRENT_USER',
+ 'CURTIME',
+ 'DATE',
+ 'DAYNAME',
+ 'DEGREES',
+ 'DES_DECRYPT',
+ 'DES_ENCRYPT',
+ 'ENCRYPT',
+ 'EXP',
+ 'FLOOR',
+ 'FROM_DAYS',
+ 'FROM_UNIXTIME',
+ 'HEX',
+ 'INET_ATON',
+ 'INET_NTOA',
+ 'LENGTH',
+ 'LN',
+ 'LOG',
+ 'LOG10',
+ 'LOG2',
+ 'LOWER',
+ 'MD5',
+ 'NOW',
+ 'OCT',
+ 'OLD_PASSWORD',
+ 'ORD',
+ 'PASSWORD',
+ 'RADIANS',
+ 'RAND',
+ 'REVERSE',
+ 'ROUND',
+ 'SEC_TO_TIME',
+ 'SHA1',
+ 'SOUNDEX',
+ 'SPACE',
+ 'SQRT',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'TAN',
+ 'TIMESTAMP',
+ 'TIME_TO_SEC',
+ 'UNCOMPRESS',
+ 'UNHEX',
+ 'UNIX_TIMESTAMP',
+ 'UPPER',
+ 'USER',
+ 'UTC_DATE',
+ 'UTC_TIME',
+ 'UTC_TIMESTAMP',
+ 'UUID',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ 'YEAR',
+ );
/**
* Which column types will be mapped to which Group?
*
- * Fill in this array to overwrite data from data_*.inc.php files
- *
* @global array $cfg['RestrictColumnTypes']
*/
- $cfg['RestrictColumnTypes'] = array();
+ $cfg['RestrictColumnTypes'] = array(
+ 'TINYINT' => 'FUNC_NUMBER',
+ 'SMALLINT' => 'FUNC_NUMBER',
+ 'MEDIUMINT' => 'FUNC_NUMBER',
+ 'INT' => 'FUNC_NUMBER',
+ 'BIGINT' => 'FUNC_NUMBER',
+ 'DECIMAL' => 'FUNC_NUMBER',
+ 'FLOAT' => 'FUNC_NUMBER',
+ 'DOUBLE' => 'FUNC_NUMBER',
+ 'REAL' => 'FUNC_NUMBER',
+ 'BIT' => 'FUNC_NUMBER',
+ 'BOOLEAN' => 'FUNC_NUMBER',
+ 'SERIAL' => 'FUNC_NUMBER',
+
+ 'DATE' => 'FUNC_DATE',
+ 'DATETIME' => 'FUNC_DATE',
+ 'TIMESTAMP' => 'FUNC_DATE',
+ 'TIME' => 'FUNC_DATE',
+ 'YEAR' => 'FUNC_DATE',
+
+ 'CHAR' => 'FUNC_CHAR',
+ 'VARCHAR' => 'FUNC_CHAR',
+ 'TINYTEXT' => 'FUNC_CHAR',
+ 'TEXT' => 'FUNC_CHAR',
+ 'MEDIUMTEXT' => 'FUNC_CHAR',
+ 'LONGTEXT' => 'FUNC_CHAR',
+ 'BINARY' => 'FUNC_CHAR',
+ 'VARBINARY' => 'FUNC_CHAR',
+ 'TINYBLOB' => 'FUNC_CHAR',
+ 'MEDIUMBLOB' => 'FUNC_CHAR',
+ 'BLOB' => 'FUNC_CHAR',
+ 'LONGBLOB' => 'FUNC_CHAR',
+ 'ENUM' => '',
+ 'SET' => '',
+
+ 'GEOMETRY' => 'FUNC_SPATIAL',
+ 'POINT' => 'FUNC_SPATIAL',
+ 'LINESTRING' => 'FUNC_SPATIAL',
+ 'POLYGON' => 'FUNC_SPATIAL',
+ 'MULTIPOINT' => 'FUNC_SPATIAL',
+ 'MULTILINESTRING' => 'FUNC_SPATIAL',
+ 'MULTIPOLYGON' => 'FUNC_SPATIAL',
+ 'GEOMETRYCOLLECTION' => 'FUNC_SPATIAL',
+
+ );
/**
* Map above defined groups to any function
*
- * Fill in this array to overwrite data from data_*.inc.php files
- *
* @global array $cfg['RestrictFunctions']
*/
- $cfg['RestrictFunctions'] = array();
+ $cfg['RestrictFunctions'] = array(
+ 'FUNC_CHAR' => array(
+ 'BIN',
+ 'CHAR',
+ 'CURRENT_USER',
+ 'COMPRESS',
+ 'DAYNAME',
+ 'DES_DECRYPT',
+ 'DES_ENCRYPT',
+ 'ENCRYPT',
+ 'HEX',
+ 'INET_NTOA',
+ 'LOWER',
+ 'MD5',
+ 'OLD_PASSWORD',
+ 'PASSWORD',
+ 'REVERSE',
+ 'SHA1',
+ 'SOUNDEX',
+ 'SPACE',
+ 'UNCOMPRESS',
+ 'UNHEX',
+ 'UPPER',
+ 'USER',
+ 'UUID',
+ ),
+
+ 'FUNC_DATE' => array(
+ 'CURDATE',
+ 'CURTIME',
+ 'DATE',
+ 'FROM_DAYS',
+ 'FROM_UNIXTIME',
+ 'NOW',
+ 'SEC_TO_TIME',
+ 'TIMESTAMP',
+ 'UTC_DATE',
+ 'UTC_TIME',
+ 'UTC_TIMESTAMP',
+ 'YEAR',
+ ),
+
+ 'FUNC_NUMBER' => array(
+ 'ABS',
+ 'ACOS',
+ 'ASCII',
+ 'ASIN',
+ 'ATAN',
+ 'BIT_LENGTH',
+ 'BIT_COUNT',
+ 'CEILING',
+ 'CHAR_LENGTH',
+ 'COS',
+ 'COT',
+ 'CRC32',
+ 'DEGREES',
+ 'EXP',
+ 'FLOOR',
+ 'INET_ATON',
+ 'LENGTH',
+ 'LN',
+ 'LOG',
+ 'LOG2',
+ 'LOG10',
+ 'OCT',
+ 'ORD',
+ 'RADIANS',
+ 'RAND',
+ 'ROUND',
+ 'SQRT',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'TAN',
+ 'TIME_TO_SEC',
+ 'UNIX_TIMESTAMP',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ ),
+
+ 'FUNC_SPATIAL' => array(
+ 'GeomFromText',
+ 'GeomFromWKB',
+
+ 'GeomCollFromText',
+ 'LineFromText',
+ 'MLineFromText',
+ 'PointFromText',
+ 'MPointFromText',
+ 'PolyFromText',
+ 'MPolyFromText',
+
+ 'GeomCollFromWKB',
+ 'LineFromWKB',
+ 'MLineFromWKB',
+ 'PointFromWKB',
+ 'MPointFromWKB',
+ 'PolyFromWKB',
+ 'MPolyFromWKB',
+ ),
+ );
/**
* Default functions for above defined groups
@@ -2825,6 +3085,97 @@ if ($cfg['ShowFunctionFields']) {
'first_timestamp' => 'NOW',
'pk_char36' => 'UUID',
);
-}
+
+
+} // end if
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['NumOperators']
+ */
+$cfg['NumOperators'] = array(
+ '=',
+ '>',
+ '>=',
+ '<',
+ '<=',
+ '!=',
+ 'LIKE',
+ 'NOT LIKE',
+ 'IN (...)',
+ 'NOT IN (...)',
+ 'BETWEEN',
+ 'NOT BETWEEN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['TextOperators']
+ */
+$cfg['TextOperators'] = array(
+ 'LIKE',
+ 'LIKE %...%',
+ 'NOT LIKE',
+ '=',
+ '!=',
+ 'REGEXP',
+ 'REGEXP ^...$',
+ 'NOT REGEXP',
+ "= ''",
+ "!= ''",
+ 'IN (...)',
+ 'NOT IN (...)',
+ 'BETWEEN',
+ 'NOT BETWEEN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['EnumOperators']
+ */
+$cfg['EnumOperators'] = array(
+ '=',
+ '!=',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['SetOperators']
+ */
+$cfg['SetOperators'] = array(
+ 'IN',
+ 'NOT IN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['NullOperators']
+ */
+$cfg['NullOperators'] = array(
+ 'IS NULL',
+ 'IS NOT NULL',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['UnaryOperators']
+ */
+$cfg['UnaryOperators'] = array(
+ 'IS NULL' => 1,
+ 'IS NOT NULL' => 1,
+ "= ''" => 1,
+ "!= ''" => 1
+);
+
+/**
+ * Max rows retreived for zoom search
+ */
+$cfg['maxRowPlotLimit'] = 500;
?>
diff --git a/libraries/svg_plot/pma_scatter_plot.php b/libraries/svg_plot/pma_scatter_plot.php
new file mode 100644
index 0000000..10c0aea
--- /dev/null
+++ b/libraries/svg_plot/pma_scatter_plot.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Generates the SVG needed for the plot
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'pma_svg_data_point.php';
+
+class PMA_Scatter_Plot
+{
+ /**
+ * @var array Raw data for the plot
+ */
+ private $_data;
+
+ /**
+ * @var array Data points of the plot
+ */
+ private $_dataPoints;
+
+ /**
+ * @var array Set of default settigs values are here.
+ */
+ private $_settings = array(
+
+ // Array of colors to be used for plot.
+ 'colors' => array(
+ '#BCE02E',
+ '#E0642E',
+ '#E0D62E',
+ '#2E97E0',
+ '#B02EE0',
+ '#E02E75',
+ '#5CE02E',
+ '#E0B02E',
+ '#000000',
+ '#0022E0',
+ '#726CB1',
+ '#481A36',
+ '#BAC658',
+ '#127224',
+ '#825119',
+ '#238C74',
+ '#4C489B',
+ '#87C9BF',
+ ),
+ // Plot background color.
+ 'bgColor' => '#84AD83',
+
+ // The width of the plot.
+ 'width' => 520,
+
+ // The height of the plot.
+ 'height' => 325,
+
+ // Default X Axis label. If empty, label will be taken from the data.
+ 'xLabel' => '',
+
+ // Default Y Axis label. If empty, label will be taken from the data.
+ 'yLabel' => '',
+
+ // Data point label. If empty, label will be taken from the data.
+ 'dataLabel' => '',
+
+ );
+
+ /**
+ * @var array Options that the user has specified.
+ */
+ private $_userSpecifiedSettings = null;
+
+ /**
+ * Returns the settings array
+ *
+ * @return the settings array.
+ */
+ public function getSettings()
+ {
+ return $this->_settings;
+ }
+
+ /**
+ * Returns the data array
+ *
+ * @return the data array.
+ */
+ public function getData()
+ {
+ return $this->_data;
+ }
+
+ /**
+ * Constructor. Stores user specified options.
+ *
+ * @param array $data Data for the visualization
+ * @param array $options Users specified options
+ */
+ public function __construct($data, $options)
+ {
+ $this->_userSpecifiedSettings = $options;
+ $this->_data = $data;
+ }
+
+ /**
+ * All the variable initialization, options handling has to be done here.
+ */
+ protected function init()
+ {
+ $this->_handleOptions();
+ }
+
+ /**
+ * A function which handles passed parameters. Useful if desired
+ * chart needs to be a little bit different from the default one.
+ */
+ private function _handleOptions()
+ {
+ $this->_dataPoints = array();
+ if (! is_null($this->_userSpecifiedSettings)) {
+ foreach (array_keys($this->_userSpecifiedSettings) as $key){
+ $this->_settings[$key] = $this->_userSpecifiedSettings[$key];
+ }
+ }
+ if ($this->_settings['dataLabel'] == '') {
+ $labels = array_keys($this->_data[0]);
+ $this->_settings['dataLabel'] = $labels[0];
+ }
+ }
+
+ /**
+ * Generate the visualization in SVG format.
+ *
+ * @return the generated image resource
+ */
+ private function _svg()
+ {
+ $this->init();
+
+ $output = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+ $output .= '<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg"'
+ . ' xmlns="http://www.w3.org/2000/svg" width="' . $this->_settings['width'] . '"'
+ . ' height="' . $this->_settings['height'] . '">';
+ $output .= '<g id="groupPanel">';
+ $output .= '<defs>
+ <path id="myTextPath1"
+ d="M10,190 L10,50"/>
+ <path id="myTextPath2"
+ d="M250,10 L370,10"/>
+ </defs>';
+ $output .= '<text x="6" y="190" style="font-family: Arial; font-size : 54; stroke:none; fill:#000000;" >
+ <textPath xlink:href="#myTextPath1" >';
+ $output .= $this->_settings['yLabel'];
+ $output .= '</textPath>
+ </text>';
+
+ $output .= '<text x="250" y="10" style="font-family: Arial; font-size : 54; stroke:none; fill:#000000;" >
+ <textPath xlink:href="#myTextPath2" >';
+ $output .= $this->_settings['xLabel'];
+ $output .= '</textPath>
+ </text>';
+
+
+ $scale_data = $this->_scaleDataSet($this->_data, $this->_settings['xLabel'], $this->_settings['yLabel']);
+ $output .= $this->_prepareDataSet($this->_data, 0, $scale_data, $this->_settings['dataLabel']);
+
+ $output .= '</g>';
+ $output .= '</svg>';
+
+ return $output;
+ }
+
+ /**
+ * Get the visualization as a SVG.
+ *
+ * @return the visualization as a SVG
+ */
+ public function asSVG()
+ {
+ $output = $this->_svg();
+ return $output;
+ }
+
+ /**
+ * Calculates the scale, horizontal and vertical offset that should be used.
+ *
+ * @param array $data Row data
+ *
+ * @return an array containing the scale, x and y offsets
+ */
+ private function _scaleDataSet($data,$xField,$yField)
+ {
+
+ // Currently assuming only numeric fields are selected
+ $coordinates = array();
+ foreach ($data as $row) {
+ $coordinates[0][] = $row[$xField];
+ $coordinates[1][] = $row[$yField];
+ }
+ for ($i = 0 ; $i < 2 ; $i++) {
+
+ $maxC = ($i == 0) ? 500 : 320;
+
+ if( !is_numeric($coordinates[$i][0])) {
+ $uniqueC = array_unique($coordinates[$i]);
+ $countC = count(array_unique($coordinates[$i]));
+ $map = $tmp = array();
+ foreach ($uniqueC as $uc) {
+ $tmp[] = $uc;
+ }
+ for ($j = 0 ; $j < $countC ; $j++) {
+ $map[$tmp[$j]] = 20 + $j * $maxC / $countC;
+ }
+ for($j = 0 ; $j < count($coordinates[$i]) ; $j++) {
+ $coordinates[$i][$j] = $map[$coordinates[$i][$j]];
+ }
+
+ }
+ elseif (is_numeric($coordinates[$i][0])) {
+
+ $maxC = max($coordinates[$i]);
+ for($j = 0 ; $j < count($coordinates[$i]) ; $j++) {
+
+ if ($i == 0)
+ $coordinates[$i][$j] = 20 + 500 * $coordinates[$i][$j] / $maxC;
+ else
+ $coordinates[$i][$j] = 20 + 320 * (1 - $coordinates[$i][$j] / $maxC);
+ }
+ }
+ }
+ return $coordinates;
+ }
+
+ /**
+ * Prepares and return the dataset as needed by the visualization.
+ *
+ * @param array $data Raw data
+ * @param int $color_number Start index to the color array
+ * @param array $scale_data Data related to scaling
+ * @param string $label Label for the data points
+ * @param image $results Image object in the case of png
+ *
+ * @return the formatted array of data.
+ */
+ private function _prepareDataSet($data, $color_number, $scale_data, $label)
+ {
+ $result = '';
+ // loop through the rows
+ for($i = 0 ; $i < count($data) ; $i++) {
+
+ $index = $color_number % sizeof($this->_settings['colors']);
+
+ $data_element = new PMA_SVG_Data_Point($scale_data[0][$i],$scale_data[1][$i],$data[$i][$label],$data[$i]);
+
+ $options = array('color' => $this->_settings['colors'][$index], 'id' => $i);
+ $this->_dataPoints[] = $data_element;
+
+ $result .= $data_element->prepareRowAsSVG($options);
+ $color_number++;
+ }
+
+
+ return $result;
+ }
+}
+?>
+
diff --git a/libraries/svg_plot/pma_svg_data_element.php b/libraries/svg_plot/pma_svg_data_element.php
new file mode 100644
index 0000000..97f7734
--- /dev/null
+++ b/libraries/svg_plot/pma_svg_data_element.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Base class for the plot data type classes.
+ *
+ * @package phpMyAdmin
+ */
+abstract class PMA_SVG_Data_Element{
+
+ protected $label = '';
+
+ protected $dataRow = array();
+
+ /**
+ * Store user specified label and dataRow
+ * @param string $label users specified label
+ * @param array $dataRow A data row from the query result
+ */
+ function __construct($label,$dataRow)
+ {
+ $this->label = $label;
+ $this->dataRow = $dataRow;
+ }
+
+ /**
+ * Handles the generation of each Data Row/Element as a SVG element
+ * @return the code related to a row in the GIS dataset
+ */
+ public abstract function prepareRowAsSVG($options);
+
+ public function getLabel()
+ {
+ return $this->label;
+ }
+
+ public function setLabel($label)
+ {
+ $this->label = $label;
+ }
+
+ public function getDataRow()
+ {
+ return $this->dataRow;
+ }
+
+ public function setDataRow($dataRow)
+ {
+ $this->dataRow = $dataRow;
+ }
+}
+?>
diff --git a/libraries/svg_plot/pma_svg_data_point.php b/libraries/svg_plot/pma_svg_data_point.php
new file mode 100644
index 0000000..7d01b2b
--- /dev/null
+++ b/libraries/svg_plot/pma_svg_data_point.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Handles the visualization of Data Point objects.
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'pma_svg_data_element.php';
+
+class PMA_SVG_Data_Point extends PMA_SVG_Data_Element
+{
+ /*
+ * X-Coordinate of the point
+ */
+ private $cx;
+
+ /*
+ * Y-Coordinate of the point
+ */
+ private $cy;
+
+ /*
+ * A private constructor; prevents direct creation of object.
+ */
+ public function __construct($cx, $cy, $label, $dataRow)
+ {
+ parent::__construct($label,$dataRow);
+ $this->cx = $cx;
+ $this->cy = $cy;
+
+ }
+
+ public function prepareRowAsSVG($options)
+ {
+ return $this->prepareSvg($options);
+ }
+
+ /**
+ * Prepares and returns the code related to a row in the query result as SVG.
+ *
+ * @param array $options Array containing options related to properties of the point
+ *
+ * @return the code related to a row in the query result.
+ */
+
+ protected function prepareSvg($options)
+ {
+ $point_options = array(
+ 'name' => $this->label . '_' .$options['id'],
+ 'id' => $this->label . 'id' . '_' . $options['id'],
+ 'class' => 'point',
+ 'fill' => 'white',
+ 'stroke' => $options['color'],
+ 'stroke-width'=> 2,
+ );
+
+ $row = '<circle cx="' . $this->cx . '" cy="' . $this->cy . '" r=".1"';
+ foreach ($point_options as $option => $val) {
+ $row .= ' ' . $option . '="' . trim($val) . '"';
+ }
+ $row .= '/>';
+
+ return $row;
+ }
+
+ public function getCx()
+ {
+ return $this->cx;
+ }
+
+ public function setCx($cx)
+ {
+ $this->cx = $cx;
+ }
+
+ public function getCy()
+ {
+ return $this->cy;
+ }
+
+ public function setCy($cy)
+ {
+ $this->cy = $cy;
+ }
+}
+?>
diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php
new file mode 100644
index 0000000..6384f60
--- /dev/null
+++ b/libraries/tbl_select.lib.php
@@ -0,0 +1,390 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for the table-search page and zoom-search page
+ *
+ * Funtion PMA_tbl_getFields : Returns the fields of a table
+ * Funtion PMA_tbl_search_getWhereClause : Returns the where clause for query generation
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'url_generating.lib.php';
+
+ /**
+ * PMA_tbl_setTitle() sets the title for foreign keys display link
+ *
+ * @param $propertiesIconic Type of icon property
+ * @param $themeImage Icon Image
+ * @return string $str Value of the Title
+ *
+ */
+
+function PMA_tbl_setTitle($propertiesIconic,$pmaThemeImage){
+ if ($propertiesIconic == true) {
+ $str = '<img class="icon" width="16" height="16" src="' . $pmaThemeImage
+ .'b_browse.png" alt="' . __('Browse foreign values') . '" title="'
+ . __('Browse foreign values') . '" />';
+
+ if ($propertiesIconic === 'both') {
+ $str .= __('Browse foreign values');
+ return $str;
+ }
+ } else {
+ return __('Browse foreign values');
+ }
+}
+
+ /**
+ * PMA_tbl_getFields() gets all the fields of a table along with their types,collations and whether null or not.
+ *
+ * @uses PMA_DBI_query()
+ * @uses PMA_backquote()
+ * @uses PMA_DBI_num_rows()
+ * @uses PMA_DBI_fetch_assoc()
+ * @uses PMA_DBI_free_result()
+ * @uses preg_replace()
+ * @uses str_replace()
+ * @uses strncasecmp()
+ * @uses empty()
+ *
+ * @param $db Selected database
+ * @param $table Selected table
+ *
+ * @return array($fields_list,$fields_type,$fields_collation,$fields_null) Array containing the field list, field types, collations and null constatint
+ *
+ */
+
+function PMA_tbl_getFields($table,$db) {
+
+ // Gets the list and number of fields
+
+ $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
+ $fields_cnt = PMA_DBI_num_rows($result);
+ $fields_list = $fields_null = $fields_type = $fields_collation = array();
+ while ($row = PMA_DBI_fetch_assoc($result)) {
+ $fields_list[] = $row['Field'];
+ $type = $row['Type'];
+ // reformat mysql query output
+ if (strncasecmp($type, 'set', 3) == 0
+ || strncasecmp($type, 'enum', 4) == 0) {
+ $type = str_replace(',', ', ', $type);
+ } else {
+
+ // strip the "BINARY" attribute, except if we find "BINARY(" because
+ // this would be a BINARY or VARBINARY field type
+ if (!preg_match('@BINARY[\(]@i', $type)) {
+ $type = preg_replace('@BINARY at i', '', $type);
+ }
+ $type = preg_replace('@ZEROFILL at i', '', $type);
+ $type = preg_replace('@UNSIGNED at i', '', $type);
+
+ $type = strtolower($type);
+ }
+ if (empty($type)) {
+ $type = ' ';
+ }
+ $fields_null[] = $row['Null'];
+ $fields_type[] = $type;
+ $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL'
+ ? $row['Collation']
+ : '';
+ } // end while
+ PMA_DBI_free_result($result);
+ unset($result, $type);
+
+ return array($fields_list,$fields_type,$fields_collation,$fields_null);
+
+}
+
+/* PMA_tbl_setTableHeader() sets the table header for displaying a table in query-by-example format
+ *
+ * @return HTML content, the tags and content for table header
+ *
+ */
+
+function PMA_tbl_setTableHeader(){
+
+return '<thead>
+ <tr><th>' . __('Column') . '</th>
+ <th>' . __('Type') . '</th>
+ <th>' . __('Collation') . '</th>
+ <th>' . __('Operator') . '</th>
+ <th>' . __('Value') . '</th>
+ </tr>
+ </thead>';
+
+
+}
+
+/* PMA_tbl_getSubTabs() returns an array with necessary configrations to create sub-tabs(Table Search and Zoom Search) in the table_select page
+ *
+ * @return array $subtabs Array containing configuration (icon,text,link,id,args) of sub-tabs for Table Search and Zoom search
+ *
+ */
+
+function PMA_tbl_getSubTabs(){
+
+ $subtabs = array();
+
+ $subtabs['search']['icon'] = 'b_search.png';
+ $subtabs['search']['text'] = __('Table Search');
+ $subtabs['search']['link'] = 'tbl_select.php';
+ $subtabs['search']['id'] = 'tbl_search_id';
+ $subtabs['search']['args']['pos'] = 0;
+
+ $subtabs['zoom']['icon'] = 'b_props.png';
+ $subtabs['zoom']['link'] = 'tbl_zoom_select.php';
+ $subtabs['zoom']['text'] = __('Zoom Search');
+ $subtabs['zoom']['id'] = 'zoom_search_id';
+
+ return $subtabs;
+
+}
+
+
+/* PMA_tbl_getForeignFields_Values() creates the HTML content for: 1) Browsing foreign data for a field. 2) Creating elements for search criteria input on fields.
+ *
+ * @uses PMA_foreignDropdown
+ * @uses PMA_generate_common_url
+ * @uses isset()
+ * @uses is_array()
+ * @uses in_array()
+ * @uses urlencode()
+ * @uses str_replace()
+ * @uses stbstr()
+ *
+ * @param $foreigners Array of foreign keys
+ * @param $foreignData Foreign keys data
+ * @param $field Column name
+ * @param $tbl_fields_type Column type
+ * @param $i Column index
+ * @param $db Selected database
+ * @param $table Selected table
+ * @param $titles Selected title
+ * @param $foreignMaxLimit Max limit of displaying foreign elements
+ * @param $fields Array of search criteria inputs
+ *
+ * @return string $str HTML content for viewing foreing data and elements for search criteria input.
+ *
+ */
+
+function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table,$titles,$foreignMaxLimit, $fields){
+
+ $str = '';
+
+ if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) {
+ // f o r e i g n k e y s
+ $str .= ' <select name="fields[' . $i . ']" id="fieldID_' . $i .'">' . "\n";
+ // go back to first row
+ // here, the 4th parameter is empty because there is no current
+ // value of data for the dropdown (the search page initial values
+ // are displayed empty)
+ $str .= PMA_foreignDropdown($foreignData['disp_row'],
+ $foreignData['foreign_field'],
+ $foreignData['foreign_display'],
+ '', $foreignMaxLimit);
+ $str .= ' </select>' . "\n";
+ }
+ elseif ($foreignData['foreign_link'] == true) {
+ if(isset($fields[$i]) && is_string($fields[$i])){
+ $str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] " value="' . $fields[$i] . '"';
+ 'id="field_' . md5($field) . '[' . $i .']"
+ class="textfield"/>' ;
+ }
+ else{
+ $str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] "';
+ 'id="field_' . md5($field) . '[' . $i .']"
+ class="textfield" />' ;
+ }
+ ?>
+ <?php $str .= '<script type="text/javascript">';
+ // <![CDATA[
+ $str .= <<<EOT
+<a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php?
+EOT;
+ $str .= '' . PMA_generate_common_url($db, $table) . '&field=' . urlencode($field) . '&fieldkey=' . $i . '">' . str_replace("'", "\'", $titles['Browse']) . '</a>';
+ // ]]
+ $str .= '</script>';
+ }
+ elseif (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
+ // e n u m s
+ $enum_value=explode(', ', str_replace("'", '', substr($tbl_fields_type[$i], 5, -1)));
+ $cnt_enum_value = count($enum_value);
+ $str .= '<select name="fields[' . ($i) . '][]" id="fieldID_' . $i .'"'
+ .' multiple="multiple" size="' . min(3, $cnt_enum_value) . '">' . "\n";
+ for ($j = 0; $j < $cnt_enum_value; $j++) {
+ if(isset($fields[$i]) && is_array($fields[$i]) && in_array($enum_value[$j],$fields[$i])){
+ $str .= ' <option value="' . $enum_value[$j] . '" Selected>'
+ . $enum_value[$j] . '</option>';
+ }
+ else{
+ $str .= ' <option value="' . $enum_value[$j] . '">'
+ . $enum_value[$j] . '</option>';
+ }
+ } // end for
+ $str .= ' </select>' . "\n";
+ }
+ else {
+ // o t h e r c a s e s
+ $the_class = 'textfield';
+ $type = $tbl_fields_type[$i];
+ if ($type == 'date') {
+ $the_class .= ' datefield';
+ } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') {
+ $the_class .= ' datetimefield';
+ }
+ if(isset($fields[$i]) && is_string($fields[$i])){
+ $str .= ' <input type="text" name="fields[' . $i . ']" '
+ .' size="40" class="' . $the_class . '" id="fieldID_' . $i .'" value = "' . $fields[$i] . '"/>' . "\n";
+ }
+ else{
+ $str .= ' <input type="text" name="fields[' . $i . ']"'
+ .' size="40" class="' . $the_class . '" id="fieldID_' . $i .'" />' . "\n";
+ }
+ };
+ return $str;
+
+}
+
+
+/* PMA_tbl_search_getWhereClause() Return the where clause for query generation based on the inputs provided.
+ *
+ * @uses PMA_backquote
+ * @uses PMA_sqlAddslashes
+ * @uses preg_match
+ * @uses isset()
+ * @uses in_array()
+ * @uses str_replace()
+ * @uses strpos()
+ * @uses explode()
+ * @uses trim()
+ *
+ * @param $fields Search criteria input
+ * @param $names Name of the field(column) on which search criteria is submitted
+ * @param $types Type of the field
+ * @param $collations Field collation
+ * @param $func_type Search fucntion/operator
+ * @param $unaryFlag Whether operator unary or not
+ *
+ * @return string $str HTML content for viewing foreing data and elements for search criteria input.
+ *
+ */
+
+function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag){
+
+
+ $w = '';
+ if($unaryFlag){
+ $fields = '';
+ $w = PMA_backquote($names) . ' ' . $func_type;
+
+ } elseif (strncasecmp($types, 'enum', 4) == 0) {
+ if (!empty($fields)) {
+ if (! is_array($fields)) {
+ $fields = explode(',', $fields);
+ }
+ $enum_selected_count = count($fields);
+ if ($func_type == '=' && $enum_selected_count > 1) {
+ $func_type = 'IN';
+ $parens_open = '(';
+ $parens_close = ')';
+
+ } elseif ($func_type == '!=' && $enum_selected_count > 1) {
+ $func_type = 'NOT IN';
+ $parens_open = '(';
+ $parens_close = ')';
+
+ } else {
+ $parens_open = '';
+ $parens_close = '';
+ }
+ $enum_where = '\'' . PMA_sqlAddslashes($fields[0]) . '\'';
+ for ($e = 1; $e < $enum_selected_count; $e++) {
+ $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\'';
+ }
+
+ $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
+ }
+
+ } elseif ($fields != '') {
+ // For these types we quote the value. Even if it's another type (like INT),
+ // for a LIKE we always quote the value. MySQL converts strings to numbers
+ // and numbers to strings as necessary during the comparison
+ if (preg_match('@char|binary|blob|text|set|date|time|year at i', $types) || strpos(' ' . $func_type, 'LIKE')) {
+ $quot = '\'';
+ } else {
+ $quot = '';
+ }
+
+ // LIKE %...%
+ if ($func_type == 'LIKE %...%') {
+ $func_type = 'LIKE';
+ $fields = '%' . $fields . '%';
+ }
+ if ($func_type == 'REGEXP ^...$') {
+ $func_type = 'REGEXP';
+ $fields = '^' . $fields . '$';
+ }
+
+ if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
+ $func_type = str_replace(' (...)', '', $func_type);
+
+ // quote values one by one
+ $values = explode(',', $fields);
+ foreach ($values as &$value)
+ $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot;
+
+ if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
+ $w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
+ else
+ $w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
+ }
+ else {
+ $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;;
+ }
+
+ } // end if
+
+ return $w;
+}
+
+/**
+ * Formats a SVG plot for the query results.
+ *
+ * @param array $data Data for the status chart
+ * @param array &$settings Settings used to generate the chart
+ *
+ * @return string HTML and JS code for the SVG plot
+ */
+function PMA_SVG_scatter_plot($data, &$settings)
+{
+ require_once './libraries/svg_plot/pma_scatter_plot.php';
+
+ if (empty($data)) {
+ // empty data
+ return '';
+ } else {
+ $scatter_plot = new PMA_Scatter_Plot($data, $settings);
+
+ if ($settings != null) {
+ foreach ($scatter_plot->getSettings() as $setting => $val) {
+ if (! isset($settings[$setting])) {
+ $settings[$setting] = $val;
+ }
+ }
+ }
+ return $scatter_plot->asSVG();
+ }
+
+}
+
+
+
+
+
+
+
+
+
+?>
diff --git a/tbl_select.php b/tbl_select.php
index c6b0a35..e9b1eae 100644
--- a/tbl_select.php
+++ b/tbl_select.php
@@ -15,6 +15,7 @@
*/
require_once './libraries/common.inc.php';
require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/tbl_select.lib.php';
$GLOBALS['js_include'][] = 'makegrid.js';
$GLOBALS['js_include'][] = 'sql.js';
@@ -22,18 +23,8 @@ $GLOBALS['js_include'][] = 'tbl_select.js';
$GLOBALS['js_include'][] = 'tbl_change.js';
$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
$GLOBALS['js_include'][] = 'jquery/timepicker.js';
-if ($GLOBALS['cfg']['PropertiesIconic'] == true) {
- $titles['Browse'] =
- '<img class="icon" width="16" height="16" src="' . $pmaThemeImage
- .'b_browse.png" alt="' . __('Browse foreign values') . '" title="'
- . __('Browse foreign values') . '" />';
-
- if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') {
- $titles['Browse'] .= __('Browse foreign values');
- }
-} else {
- $titles['Browse'] = __('Browse foreign values');
-}
+
+$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage);
/**
* Not selection yet required -> displays the selection form
@@ -61,45 +52,26 @@ if (! isset($param) || $param[0] == '') {
$err_url = $goto . '?' . PMA_generate_common_url($db, $table);
// Gets the list and number of fields
- $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
- $fields_cnt = PMA_DBI_num_rows($result);
- $fields_list = $fields_null = $fields_type = $fields_collation = array();
- while ($row = PMA_DBI_fetch_assoc($result)) {
- $fields_list[] = $row['Field'];
- $type = $row['Type'];
- // reformat mysql query output
- if (strncasecmp($type, 'set', 3) == 0
- || strncasecmp($type, 'enum', 4) == 0) {
- $type = str_replace(',', ', ', $type);
- } else {
- // strip the "BINARY" attribute, except if we find "BINARY(" because
- // this would be a BINARY or VARBINARY field type
- if (!preg_match('@BINARY[\(]@i', $type)) {
- $type = preg_replace('@BINARY at i', '', $type);
- }
- $type = preg_replace('@ZEROFILL at i', '', $type);
- $type = preg_replace('@UNSIGNED at i', '', $type);
-
- $type = strtolower($type);
- }
- if (empty($type)) {
- $type = ' ';
- }
- $fields_null[] = $row['Null'];
- $fields_type[] = $type;
- $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL'
- ? $row['Collation']
- : '';
- } // end while
- PMA_DBI_free_result($result);
- unset($result, $type);
+ list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db);
+ $fields_cnt = count($fields_list);
// retrieve keys into foreign fields, if any
// check also foreigners even if relwork is FALSE (to get
// foreign keys from innodb)
$foreigners = PMA_getForeigners($db, $table);
?>
+
+<fieldset id="fieldset_subtab">
+<?php
+$url_params = array();
+$url_params['db'] = $db;
+$url_params['table'] = $table;
+
+echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
+
+?>
+
<form method="post" action="tbl_select.php" name="insertForm" id="tbl_search_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
<input type="hidden" name="goto" value="<?php echo $goto; ?>" />
@@ -110,14 +82,7 @@ if (! isset($param) || $param[0] == '') {
<fieldset id="fieldset_table_qbe">
<legend><?php echo __('Do a "query by example" (wildcard: "%")') ?></legend>
<table class="data">
- <thead>
- <tr><th><?php echo __('Column'); ?></th>
- <th><?php echo __('Type'); ?></th>
- <th><?php echo __('Collation'); ?></th>
- <th><?php echo __('Operator'); ?></th>
- <th><?php echo __('Value'); ?></th>
- </tr>
- </thead>
+ <?php echo PMA_tbl_setTableHeader(); ?>
<tbody>
<?php
$odd_row = true;
@@ -130,57 +95,31 @@ if (! isset($param) || $param[0] == '') {
<td><?php echo $fields_collation[$i]; ?></td>
<td><select name="func[]">
<?php
- // determine valid operators
if (strncasecmp($fields_type[$i], 'enum', 4) == 0) {
- // enum operators
- $operators = array(
- '=',
- '!=',
- );
+ foreach ($GLOBALS['cfg']['EnumOperators'] as $fc) {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
} elseif (preg_match('@char|blob|text|set at i', $fields_type[$i])) {
- // text operators
- $operators = array(
- 'LIKE',
- 'LIKE %...%',
- 'NOT LIKE',
- '=',
- '!=',
- 'REGEXP',
- 'REGEXP ^...$',
- 'NOT REGEXP',
- "= ''",
- "!= ''",
- 'IN (...)',
- 'NOT IN (...)',
- 'BETWEEN',
- 'NOT BETWEEN',
- );
+ foreach ($GLOBALS['cfg']['TextOperators'] as $fc) {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
} else {
- // numeric operators
- $operators = array(
- '=',
- '>',
- '>=',
- '<',
- '<=',
- '!=',
- 'LIKE',
- 'NOT LIKE',
- 'IN (...)',
- 'NOT IN (...)',
- 'BETWEEN',
- 'NOT BETWEEN',
- );
+ foreach ($GLOBALS['cfg']['NumOperators'] as $fc) {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
} // end if... else...
-
- // if field can be NULL, add IS NULL and IS NOT NULL
if ($fields_null[$i]) {
- $operators[] = 'IS NULL';
- $operators[] = 'IS NOT NULL';
- }
- foreach ($operators as $op) {
- echo "\n" . ' '
- . '<option value="' . htmlspecialchars($op) . '">' . htmlspecialchars($op) . '</option>';
+ foreach ($GLOBALS['cfg']['NullOperators'] as $fc) {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
}
?>
@@ -192,54 +131,9 @@ if (! isset($param) || $param[0] == '') {
$foreignData = PMA_getForeignData($foreigners, $field, false, '', '');
- if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) {
- // f o r e i g n k e y s
- echo ' <select name="fields[' . $i . ']">' . "\n";
- // go back to first row
-
- // here, the 4th parameter is empty because there is no current
- // value of data for the dropdown (the search page initial values
- // are displayed empty)
- echo PMA_foreignDropdown($foreignData['disp_row'],
- $foreignData['foreign_field'],
- $foreignData['foreign_display'],
- '', $GLOBALS['cfg']['ForeignKeyMaxLimit']);
- echo ' </select>' . "\n";
- } elseif ($foreignData['foreign_link'] == true) {
- ?>
- <input type="text" name="fields[<?php echo $i; ?>]"
- id="field_<?php echo md5($field); ?>[<?php echo $i; ?>]"
- class="textfield" />
- <script type="text/javascript">
- // <![CDATA[
- document.writeln('<a target="_blank" onclick="window.open(this.href, \'foreigners\', \'width=640,height=240,scrollbars=yes\'); return false" href="browse_foreigners.php?<?php echo PMA_generate_common_url($db, $table); ?>&field=<?php echo urlencode($field); ?>&fieldkey=<?php echo $i; ?>"><?php echo str_replace("'", "\'", $titles['Browse']); ?></a>');
- // ]]>
- </script>
- <?php
- } elseif (strncasecmp($fields_type[$i], 'enum', 4) == 0) {
- // e n u m s
- $enum_value=explode(', ', str_replace("'", '', substr($fields_type[$i], 5, -1)));
- $cnt_enum_value = count($enum_value);
- echo ' <select name="fields[' . $i . '][]"'
- .' multiple="multiple" size="' . min(3, $cnt_enum_value) . '">' . "\n";
- for ($j = 0; $j < $cnt_enum_value; $j++) {
- echo ' <option value="' . $enum_value[$j] . '">'
- . $enum_value[$j] . '</option>';
- } // end for
- echo ' </select>' . "\n";
- } else {
- // o t h e r c a s e s
- $the_class = 'textfield';
- $type = $fields_type[$i];
- if ($type == 'date') {
- $the_class .= ' datefield';
- } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') {
- $the_class .= ' datetimefield';
- }
- echo ' <input type="text" name="fields[' . $i . ']"'
- .' size="40" class="' . $the_class . '" id="field_' . $i . '" />' . "\n";
- };
- ?>
+ echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' );
+
+ ?>
<input type="hidden" name="names[<?php echo $i; ?>]"
value="<?php echo htmlspecialchars($fields_list[$i]); ?>" />
<input type="hidden" name="types[<?php echo $i; ?>]"
@@ -321,13 +215,20 @@ if (! isset($param) || $param[0] == '') {
<div id="sqlqueryresults"></div>
<?php
require './libraries/footer.inc.php';
+?>
+
+</fieldset>
+
+<?php
}
+
/**
* Selection criteria have been submitted -> do the work
*/
else {
+ echo "ZZ";
// Builds the query
$sql_query = 'SELECT ' . (isset($distinct) ? 'DISTINCT ' : '');
@@ -354,88 +255,18 @@ else {
$sql_query .= ' WHERE ' . $where;
} else {
$w = $charsets = array();
- $unary_operators = array(
- 'IS NULL' => 1,
- 'IS NOT NULL' => 1,
- "= ''" => 1,
- "!= ''" => 1
- );
$cnt_func = count($func);
reset($func);
while (list($i, $func_type) = each($func)) {
- list($charsets[$i]) = explode('_', $collations[$i]);
- if (isset($unary_operators[$func_type])) {
- $fields[$i] = '';
- $w[] = PMA_backquote($names[$i]) . ' ' . $func_type;
-
- } elseif (strncasecmp($types[$i], 'enum', 4) == 0) {
- if (!empty($fields[$i])) {
- if (! is_array($fields[$i])) {
- $fields[$i] = explode(',', $fields[$i]);
- }
- $enum_selected_count = count($fields[$i]);
- if ($func_type == '=' && $enum_selected_count > 1) {
- $func_type = $func[$i] = 'IN';
- $parens_open = '(';
- $parens_close = ')';
-
- } elseif ($func_type == '!=' && $enum_selected_count > 1) {
- $func_type = $func[$i] = 'NOT IN';
- $parens_open = '(';
- $parens_close = ')';
-
- } else {
- $parens_open = '';
- $parens_close = '';
- }
- $enum_where = '\'' . PMA_sqlAddSlashes($fields[$i][0]) . '\'';
- for ($e = 1; $e < $enum_selected_count; $e++) {
- $enum_where .= ', \'' . PMA_sqlAddSlashes($fields[$i][$e]) . '\'';
- }
-
- $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
- }
-
- } elseif ($fields[$i] != '') {
- // For these types we quote the value. Even if it's another type (like INT),
- // for a LIKE we always quote the value. MySQL converts strings to numbers
- // and numbers to strings as necessary during the comparison
- if (preg_match('@char|binary|blob|text|set|date|time|year at i', $types[$i]) || strpos(' ' . $func_type, 'LIKE')) {
- $quot = '\'';
- } else {
- $quot = '';
- }
-
- // LIKE %...%
- if ($func_type == 'LIKE %...%') {
- $func_type = 'LIKE';
- $fields[$i] = '%' . $fields[$i] . '%';
- }
- if ($func_type == 'REGEXP ^...$') {
- $func_type = 'REGEXP';
- $fields[$i] = '^' . $fields[$i] . '$';
- }
-
- if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
- $func_type = str_replace(' (...)', '', $func_type);
-
- // quote values one by one
- $values = explode(',', $fields[$i]);
- foreach ($values as &$value)
- $value = $quot . PMA_sqlAddSlashes(trim($value)) . $quot;
-
- if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
- $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : '');
- else
- $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
- }
- else {
- $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;;
- }
-
- } // end if
+
+ list($charsets[$i]) = explode('_', $collations[$i]);
+ $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false;
+ $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$names[$i], $types[$i], $collations[$i], $func_type, $unaryFlag);
+ if($whereClause)
+ $w[] = $whereClause;
+
} // end for
-
+ //print_r($w);
if ($w) {
$sql_query .= ' WHERE ' . implode(' AND ', $w);
}
@@ -444,7 +275,6 @@ else {
if ($orderField != '--nil--') {
$sql_query .= ' ORDER BY ' . PMA_backquote($orderField) . ' ' . $order;
} // end if
-
require './sql.php';
}
diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php
new file mode 100644
index 0000000..cdb784d
--- /dev/null
+++ b/tbl_zoom_select.php
@@ -0,0 +1,447 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles table zoom search tab
+ *
+ * display table zoom search form, create SQL queries from form data
+ *
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/tbl_select.lib.php';
+require_once './libraries/relation.lib.php';
+require_once './libraries/tbl_info.inc.php';
+
+$GLOBALS['js_include'][] = 'makegrid.js';
+$GLOBALS['js_include'][] = 'sql.js';
+$GLOBALS['js_include'][] = 'functions.js';
+$GLOBALS['js_include'][] = 'tbl_zoom_plot.js';
+$GLOBALS['js_include'][] = 'date.js';
+$GLOBALS['js_include'][] = 'highcharts/highcharts.js';
+/* Files required for chart exporting */
+$GLOBALS['js_include'][] = 'highcharts/exporting.js';
+$GLOBALS['js_include'][] = 'canvg/canvg.js';
+$GLOBALS['js_include'][] = 'canvg/rgbcolor.js';
+$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
+$GLOBALS['js_include'][] = 'jquery/timepicker.js';
+
+
+/**
+ * Handle AJAX request for data row on point select
+ * @var post_params Object containing parameters for the POST request
+ */
+
+if (isset($_REQUEST['get_data_row']) && $_REQUEST['get_data_row'] == true) {
+
+ $extra_data = array();
+ $row_info_query = 'SELECT * FROM `' . $_REQUEST['db'] . '`.`' . $_REQUEST['table'] . '` WHERE ' . $_REQUEST['where_clause'];
+ $result = PMA_DBI_query( $row_info_query . ";" , null, PMA_DBI_QUERY_STORE);
+ $fields_meta = PMA_DBI_get_fields_meta($result);
+ while ($row = PMA_DBI_fetch_assoc($result))
+ $extra_data['row_info'] = $row;
+
+ PMA_ajaxResponse(NULL, true, $extra_data);
+}
+
+$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage);
+/**
+ * Not selection yet required -> displays the selection form
+ */
+
+ // Gets some core libraries
+ require_once './libraries/tbl_common.php';
+ //$err_url = 'tbl_select.php' . $err_url;
+ $url_query .= '&goto=tbl_select.php&back=tbl_select.php';
+
+ /**
+ * Gets tables informations
+ */
+ require_once './libraries/tbl_info.inc.php';
+
+ /**
+ * Displays top menu links
+ */
+ require_once './libraries/tbl_links.inc.php';
+
+ if (! isset($goto)) {
+ $goto = $GLOBALS['cfg']['DefaultTabTable'];
+ }
+ // Defines the url to return to in case of error in the next sql statement
+ $err_url = $goto . '?' . PMA_generate_common_url($db, $table);
+
+ // Gets the list and number of fields
+
+ list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db);
+ $fields_cnt = count($fields_list);
+
+ // retrieve keys into foreign fields, if any
+ // check also foreigners even if relwork is FALSE (to get
+ // foreign keys from innodb)
+ $foreigners = PMA_getForeigners($db, $table);
+ $flag = 1;
+ $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array();
+ if(!isset($zoom_submit) && !isset($inputs))
+ $dataLabel = PMA_getDisplayField($db,$table);
+
+ ?>
+
+
+<div id="sqlqueryresults"></div>
+<fieldset id="fieldset_subtab">
+<?php
+$url_params = array();
+$url_params['db'] = $db;
+$url_params['table'] = $table;
+echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
+
+/**
+ * Set the field name,type,collation and whether null on select of a coulmn
+ */
+if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null')))
+{
+ $flag = 2;
+ for($i = 0 ; $i < 4 ; $i++)
+ {
+ if($inputs[$i] != __('pma_null'))
+ {
+ $key = array_search($inputs[$i],$fields_list);
+ $tbl_fields_type[$i] = $fields_type[$key];
+ $tbl_fields_collation[$i] = $fields_collation[$key];
+ $tbl_fields_null[$i] = $fields_null[$key];
+ }
+
+ }
+}
+
+
+?>
+
+<?php
+
+/*
+ * Form for input criteria
+ */
+
+?>
+<form method="post" action="tbl_zoom_select.php" name="zoomInputForm" id="zoom_search_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
+<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
+<input type="hidden" name="goto" value="<?php echo $goto; ?>" />
+<input type="hidden" name="back" value="tbl_zoom_select.php" />
+<input type="hidden" name="flag" id="id_flag" value=<?php echo $flag; ?> />
+
+
+
+
+<fieldset id="inputSection">
+
+<legend><?php echo __('Do a "query by example" (wildcard: "%") for two different columns') ?></legend>
+<table class="data">
+<?php echo PMA_tbl_setTableHeader();?>
+<tbody>
+<?php
+ $odd_row = true;
+
+for($i = 0 ; $i < 4 ; $i++){
+
+ if($i == 2){
+ echo "<tr><td>";
+ echo __("Additional search criteria");
+ echo "</td><tr>";
+ }
+
+?>
+ <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
+ <th><select name="inputs[]" id=<?php echo 'tableid_' . $i?> >
+ <option value= <?php echo __('pma_null')?>><?php echo __('None'); ?> </option>
+ <?php
+ for ($j = 0 ; $j < $fields_cnt ; $j++){
+ if(isset($inputs[$i]) && $inputs[$i] == htmlspecialchars($fields_list[$j])){?>
+ <option value=<?php echo htmlspecialchars($fields_list[$j]);?> Selected> <?php echo htmlspecialchars($fields_list[$j]);?></option>
+ <?php
+ }
+ else{ ?>
+ <option value=<?php echo htmlspecialchars($fields_list[$j]);?> > <?php echo htmlspecialchars($fields_list[$j]);?></option>
+ <?php
+ }
+ } ?>
+ </select></th>
+ <td><?php if(isset($tbl_fields_type[$i]))echo $tbl_fields_type[$i]; ?></td>
+ <td><?php if(isset($tbl_fields_collation[$i]))echo $tbl_fields_collation[$i]; ?></td>
+
+ <td>
+ <?php if(isset($inputs) && $inputs[$i] != __('pma_null')){ ?>
+ <select name="zoomFunc[]">
+ <?php
+
+ if (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
+ foreach ($GLOBALS['cfg']['EnumOperators'] as $fc) {
+ if(isset($zoomFunc[$i]) && $zoomFunc[$i] == htmlspecialchars($fc)){
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ else {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ }
+ } elseif (preg_match('@char|blob|text|set at i', $tbl_fields_type[$i])) {
+ foreach ($GLOBALS['cfg']['TextOperators'] as $fc) {
+ if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ else {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ }
+ } else {
+ foreach ($GLOBALS['cfg']['NumOperators'] as $fc) {
+ if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ else {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ }
+ } // end if... else...
+
+ if ($tbl_fields_null[$i]) {
+ foreach ($GLOBALS['cfg']['NullOperators'] as $fc) {
+ if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ else {
+ echo "\n" . ' '
+ . '<option value="' . htmlspecialchars($fc) . '">'
+ . htmlspecialchars($fc) . '</option>';
+ }
+ }
+ }
+ ?>
+ </select>
+ </td>
+ <td>
+ <?php
+ $field = $inputs[$i];
+
+ $foreignData = PMA_getForeignData($foreigners, $field, false, '', '');
+ if (isset($fields))
+ echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $fields);
+ else
+ echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], '');
+
+ }
+ else{ ?>
+
+ </td><td></td>
+
+ <?php } ?>
+
+ </td>
+ </tr>
+
+ <input type="hidden" name="types[<?php echo $i; ?>]" id="types_<?php echo $i; ?>"
+ value="<?php if(isset($tbl_fields_type[$i]))echo $tbl_fields_type[$i]; ?>" />
+ <input type="hidden" name="collations[<?php echo $i; ?>]"
+ value="<?php if(isset($tbl_fields_collation[$i]))echo $tbl_fields_collation[$i]; ?>" />
+
+
+
+<?php
+ }//end for
+?>
+ </table>
+
+ <?php
+ /*
+ * Other inputs like data label and mode go after selection of column criteria
+ */
+
+ //Set default datalabel if not selected
+ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null')) {
+ if ($dataLabel == '')
+ $dataLabel = PMA_getDisplayField($db,$table);
+ }
+ ?>
+ <table class="data">
+ <tr><td><label for="label"><?php echo __("Data Label"); ?></label>        </td>
+ <td><select name="dataLabel" id='dataLabel' >
+ <option value = ''> <?php echo __('None'); ?> </option>
+ <?php
+ for ($j = 0 ; $j < $fields_cnt ; $j++){
+ if(isset($dataLabel) && $dataLabel == htmlspecialchars($fields_list[$j])){?>
+ <option value=<?php echo htmlspecialchars($fields_list[$j]);?> Selected> <?php echo htmlspecialchars($fields_list[$j]);?></option>
+ <?php
+ }
+ else{ ?>
+ <option value=<?php echo htmlspecialchars($fields_list[$j]);?> > <?php echo htmlspecialchars($fields_list[$j]);?></option>
+ <?php
+ }
+ } ?>
+ </select>
+ </td></tr>
+ <tr><td><label for="label"><?php echo __("Maximum rows to plot"); ?></label></td>
+ <td>
+ <?php if(isset($maxPlotLimit)) { ?>
+ <input type="text" name="maxPlotLimit" value="<?php echo $maxPlotLimit; ?>" /></td></tr>
+ <?php
+ }
+ else { ?>
+ <input type="text" name="maxPlotLimit" value="<?php echo $GLOBALS['cfg']['maxRowPlotLimit']; ?>" /></td></tr>
+ <?php
+ } ?>
+ </table>
+
+</fieldset>
+<fieldset class="tblFooters">
+ <input type="hidden" name="max_number_of_fields"
+ value="<?php echo $fields_cnt; ?>" />
+ <input type="submit" name="zoom_submit" id="inputFormSubmitId" value="<?php echo __('Go'); ?>" />
+</fieldset>
+</form>
+
+<?php
+
+/*
+ * Handle the input criteria and gerate the query result
+ * Form for displaying query results
+ */
+if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null') && $inputs[0] != $inputs[1]) {
+
+ /*
+ * Query generation part
+ */
+ $w = $data = array();
+ $sql_query = 'SELECT *';
+
+ //Add the table
+
+ $sql_query .= ' FROM ' . PMA_backquote($table);
+ for($i = 0 ; $i < 4 ; $i++){
+ if($inputs[$i] == __('pma_null'))
+ continue;
+ $tmp = array();
+ // The where clause
+ $charsets = array();
+ $cnt_func = count($zoomFunc[$i]);
+ $func_type = $zoomFunc[$i];
+ list($charsets[$i]) = explode('_', $collations[$i]);
+ $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false;
+ $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag);
+ if($whereClause)
+ $w[] = $whereClause;
+
+ } // end for
+ if ($w) {
+ $sql_query .= ' WHERE ' . implode(' AND ', $w);
+ }
+ $sql_query .= ' LIMIT ' . $maxPlotLimit;
+
+ /*
+ * Query execution part
+ */
+ $result = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE);
+ $fields_meta = PMA_DBI_get_fields_meta($result);
+ while ($row = PMA_DBI_fetch_assoc($result)) {
+ //Need a row with indexes as 0,1,2 for the PMA_getUniqueCondition hence using a temporary array
+ $tmpRow = array();
+ foreach($row as $val)
+ $tmpRow[] = $val;
+ //Get unique conditon on each row (will be needed for row update)
+ $uniqueCondition = PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $tmpRow, true);
+
+ //Append it to row array as where_clause
+ $row['where_clause'] = $uniqueCondition[0];
+ if($dataLabel == $inputs[0] || $dataLabel == $inputs[1])
+ $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], 'where_clause' => $uniqueCondition[0]);
+ else
+ $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], $dataLabel => $row[$dataLabel], 'where_clause' => $uniqueCondition[0]);
+ }
+
+?>
+
+<?php
+ /*
+ * Form for displaying point data and also the scatter plot
+ */
+?>
+ <form method="post" action="tbl_zoom_select.php" name="displayResultForm" id="zoom_display_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
+ <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
+ <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
+ <input type="hidden" name="back" value="tbl_zoom_select.php" />
+
+ <fieldset id="displaySection">
+ <legend><?php echo __('Browse/Edit the points') ?></legend>
+ <center>
+ <?php
+ //JSON encode the data(query result)
+ if(isset($zoom_submit) && !empty($data)){ ?>
+ <div id='resizer' style="width:600px;height:400px">
+ <?php if (isset($data)) ?><center> <a href="#" onClick="displayHelp();"><?php echo __('How to use'); ?></a> </center>
+ <div id="querydata" style="display:none">
+ <?php if(isset($data)) echo json_encode($data); ?>
+ </div>
+ <div id="querychart" style="float:right"></div>
+ </div>
+ <?php
+ } ?>
+ </center>
+ <fieldset id='dataDisplay' style="display:none">
+ <fieldset>
+ <table class="data">
+ <thead>
+ <tr>
+ <th> <?php echo __('Column'); ?> </th>
+ <th> <?php echo __('Null'); ?> </th>
+ <th> <?php echo __('Value'); ?> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $odd_row = true;
+ for ($i = 4; $i < $fields_cnt + 4 ; $i++) {
+ $tbl_fields_type[$i] = $fields_type[$i - 4];
+ $fieldpopup = $fields_list[$i - 4];
+ $foreignData = PMA_getForeignData($foreigners, $fieldpopup, false, '', '');
+ ?>
+ <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
+ <th><?php echo htmlspecialchars($fields_list[$i - 4]); ?></th>
+ <th><?php echo '<input type="checkbox" class="checkbox_null" name="fields_null[ ' . $i . ' ]" id="fields_null_id_' . $i . '" />'; ?></th>
+ <th><?php echo PMA_getForeignFields_Values($foreigners, $foreignData, $fieldpopup, $tbl_fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' ); ?> </th>
+ </tr>
+ <?php
+ } ?>
+ </tbody>
+ </table>
+ </fieldset>
+ <fieldset class="tblFooters">
+ <input type="submit" id="submitForm" name="edit_point" value="<?php echo __('Submit'); ?>" />
+ </fieldset>
+ </fieldset>
+
+ </fieldset>
+ <input type="hidden" id="queryID" name="sql_query" />
+ </form>
+ </fieldset>
+ <?php
+}
+?>
+
+ <?php
+ require './libraries/footer.inc.php';
+?>
hooks/post-receive
--
phpMyAdmin
More information about the Git
mailing list