Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b791272247
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
288
js/canvg/rgbcolor.js
Normal file
288
js/canvg/rgbcolor.js
Normal file
@ -0,0 +1,288 @@
|
||||
/**
|
||||
* A class to parse color values
|
||||
* @author Stoyan Stefanov <sstoo@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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
335
js/date.js
Normal file
335
js/date.js
Normal file
@ -0,0 +1,335 @@
|
||||
// ===================================================================
|
||||
// Author: Matt Kruse <matt@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;
|
||||
}
|
||||
@ -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');
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
605
js/tbl_zoom_plot.js
Normal file
605
js/tbl_zoom_plot.js
Normal file
@ -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();
|
||||
}
|
||||
});
|
||||
@ -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',
|
||||
|
||||
@ -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;
|
||||
|
||||
?>
|
||||
|
||||
267
libraries/svg_plot/pma_scatter_plot.php
Normal file
267
libraries/svg_plot/pma_scatter_plot.php
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
50
libraries/svg_plot/pma_svg_data_element.php
Normal file
50
libraries/svg_plot/pma_svg_data_element.php
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
86
libraries/svg_plot/pma_svg_data_point.php
Normal file
86
libraries/svg_plot/pma_svg_data_point.php
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
390
libraries/tbl_select.lib.php
Normal file
390
libraries/tbl_select.lib.php
Normal file
@ -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@i', '', $type);
|
||||
}
|
||||
$type = preg_replace('@ZEROFILL@i', '', $type);
|
||||
$type = preg_replace('@UNSIGNED@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@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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
282
tbl_select.php
282
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@i', '', $type);
|
||||
}
|
||||
$type = preg_replace('@ZEROFILL@i', '', $type);
|
||||
$type = preg_replace('@UNSIGNED@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@i', $fields_type[$i])) {
|
||||
// text operators
|
||||
$operators = array(
|
||||
'LIKE',
|
||||
'LIKE %...%',
|
||||
'NOT LIKE',
|
||||
'=',
|
||||
'!=',
|
||||
'REGEXP',
|
||||
'REGEXP ^...$',
|
||||
'NOT REGEXP',
|
||||
"= ''",
|
||||
"!= ''",
|
||||
'IN (...)',
|
||||
'NOT IN (...)',
|
||||
'BETWEEN',
|
||||
'NOT BETWEEN',
|
||||
);
|
||||
} else {
|
||||
// numeric operators
|
||||
$operators = array(
|
||||
'=',
|
||||
'>',
|
||||
'>=',
|
||||
'<',
|
||||
'<=',
|
||||
'!=',
|
||||
'LIKE',
|
||||
'NOT LIKE',
|
||||
'IN (...)',
|
||||
'NOT IN (...)',
|
||||
'BETWEEN',
|
||||
'NOT BETWEEN',
|
||||
);
|
||||
} // 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) {
|
||||
foreach ($GLOBALS['cfg']['TextOperators'] as $fc) {
|
||||
echo "\n" . ' '
|
||||
. '<option value="' . htmlspecialchars($op) . '">' . htmlspecialchars($op) . '</option>';
|
||||
. '<option value="' . htmlspecialchars($fc) . '">'
|
||||
. htmlspecialchars($fc) . '</option>';
|
||||
}
|
||||
} else {
|
||||
foreach ($GLOBALS['cfg']['NumOperators'] as $fc) {
|
||||
echo "\n" . ' '
|
||||
. '<option value="' . htmlspecialchars($fc) . '">'
|
||||
. htmlspecialchars($fc) . '</option>';
|
||||
}
|
||||
} // end if... else...
|
||||
if ($fields_null[$i]) {
|
||||
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@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';
|
||||
}
|
||||
|
||||
|
||||
447
tbl_zoom_select.php
Normal file
447
tbl_zoom_select.php
Normal file
@ -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@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';
|
||||
?>
|
||||
Loading…
Reference in New Issue
Block a user