Camel case data hinting, replacement refactor, showsource instead of sourcepreview option
This commit is contained in:
parent
11501e240b
commit
a4aab45046
14
README.md
14
README.md
@ -78,3 +78,17 @@ declare @Fruit varchar(100) = ?; -- Options: Apple=0,Orange=1,Banana=2
|
|||||||
```
|
```
|
||||||
|
|
||||||
The above will still allow a user to select a fruit's name from the dropdown, but only one of the corresponding values 0, 1, or 2 will be sent to the query as a `varchar(100)`.
|
The above will still allow a user to select a fruit's name from the dropdown, but only one of the corresponding values 0, 1, or 2 will be sent to the query as a `varchar(100)`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SQL Row and Column Hinting
|
||||||
|
|
||||||
|
All data with column names starting with an underscore `_` will be hidden from the output. To have finer control of how a row or cell of data appears, you can select and position special columns to control how the output appears.
|
||||||
|
|
||||||
|
* `__NextCellClass` — Apply this HTML class to the very next data cell
|
||||||
|
|
||||||
|
**Note:** To apply more than one `__NextCellClass` hint, additional identifiers must be used, e.g. `__NextCellClass0` or `__NextCellClassXYZ`.
|
||||||
|
|
||||||
|
* `__RowClass` — Apply this HTML class to the entire row and all data cells.
|
||||||
|
|
||||||
|
* `__Section` — Use to categorize similar and subsequent rows under a section with this name.
|
||||||
|
|||||||
211
pages/run.php
211
pages/run.php
@ -4,9 +4,6 @@
|
|||||||
global $varRows;
|
global $varRows;
|
||||||
|
|
||||||
$strQueryDir = "files/sql";
|
$strQueryDir = "files/sql";
|
||||||
|
|
||||||
// $varFiles = is_dir($strQueryDir)? scandir($strQueryDir) : [];
|
|
||||||
// $varFiles = array_diff($varFiles, [".", ".."]);
|
|
||||||
|
|
||||||
function removeQueryDir(&$strInput)
|
function removeQueryDir(&$strInput)
|
||||||
{
|
{
|
||||||
@ -39,88 +36,75 @@
|
|||||||
$strFileDataSource = file_get_contents("{$strQueryDir}/{$strSelection}");
|
$strFileDataSource = file_get_contents("{$strQueryDir}/{$strSelection}");
|
||||||
$strFileData = $strFileDataSource;
|
$strFileData = $strFileDataSource;
|
||||||
|
|
||||||
// Translate occurrences of {{ Date: next monday }} into yyyy-MM-dd format:
|
$fncReplaceDate = function($strInput)
|
||||||
// Can be used in string literals or default values in comments!
|
|
||||||
preg_match_all(
|
|
||||||
"/\{\{\s*?Date\:\s*?(.*)\s*?\}\}/i",
|
|
||||||
$strFileData,
|
|
||||||
$varDateReplacements);
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($varDateReplacements[0]); $i++)
|
|
||||||
{
|
{
|
||||||
try
|
return
|
||||||
{
|
date_create($strInput)
|
||||||
$strMatch = $varDateReplacements[0][$i];
|
->format("Y-m-d");
|
||||||
$strMatchSafe = preg_quote($strMatch);
|
};
|
||||||
$strDateString = $varDateReplacements[1][$i];
|
|
||||||
$strFileData = preg_replace(
|
|
||||||
"/{$strMatchSafe}/i",
|
|
||||||
date_create($strDateString)->format("Y-m-d"),
|
|
||||||
$strFileData);
|
|
||||||
}
|
|
||||||
catch (Exception $x) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING: Can be abused.
|
$fncReplaceSQL = function($strSQL)
|
||||||
// Translate occurrences of {{ SQL: select 'test' }} into the string value of the first cell of the first row:
|
|
||||||
// Can be used in string literals or default values in comments!
|
|
||||||
preg_match_all(
|
|
||||||
"/\{\{\s*SQL\:\s*(.*)\s+?\}\}/i",
|
|
||||||
$strFileData,
|
|
||||||
$varSQLReplacements);
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($varSQLReplacements[0]); $i++)
|
|
||||||
{
|
{
|
||||||
try
|
global $c;
|
||||||
{
|
$varRows = $c->query($strSQL);
|
||||||
$strMatch = $varSQLReplacements[0][$i];
|
|
||||||
$strMatchSafe = preg_quote($strMatch);
|
|
||||||
$strSQLString = $varSQLReplacements[1][$i];
|
|
||||||
$varTempRows = $c->query($strSQLString);
|
|
||||||
|
|
||||||
//Respond::json($varTempRows);
|
if (count($varRows) > 0)
|
||||||
|
foreach ($varRows[0] as $k => $v)
|
||||||
|
return $varRows[0][$k];
|
||||||
|
};
|
||||||
|
|
||||||
$strFirstCell = "";
|
$fncReplaceServer = function($strInput)
|
||||||
if (count($varTempRows) > 0)
|
|
||||||
foreach ($varTempRows[0] as $k => $v)
|
|
||||||
{
|
|
||||||
$strFirstCell = $varTempRows[0][$k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$strFileData = preg_replace(
|
|
||||||
"/{$strMatchSafe}/i",
|
|
||||||
$strFirstCell,
|
|
||||||
$strFileData);
|
|
||||||
}
|
|
||||||
catch (Exception $x) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// $_SERVER Key replacements:
|
|
||||||
preg_match_all(
|
|
||||||
"/\{\{\s*([A-Z_]{1,})\s*\}\}/i",
|
|
||||||
$strFileData,
|
|
||||||
$varServerKeyReplacements);
|
|
||||||
|
|
||||||
//Respond::json($_SERVER);
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($varServerKeyReplacements[0]); $i++)
|
|
||||||
{
|
{
|
||||||
try
|
// Take no chances on possible SQL injection:
|
||||||
{
|
$strValue = $_SERVER[$strInput];
|
||||||
$strMatch = $varServerKeyReplacements[0][$i];
|
$strValue = preg_replace("/\'/i", "", $strValue);
|
||||||
$strMatchSafe = preg_quote($strMatch);
|
|
||||||
$strKey = $varServerKeyReplacements[1][$i];
|
|
||||||
|
|
||||||
if (array_key_exists($strKey, $_SERVER))
|
return
|
||||||
|
$strValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
$varReplaceMap = [
|
||||||
|
["SQL", $fncReplaceSQL],
|
||||||
|
["Date", $fncReplaceDate],
|
||||||
|
["Server", $fncReplaceServer]
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($varReplaceMap as $varReplace)
|
||||||
|
{
|
||||||
|
$strKey = $varReplace[0];
|
||||||
|
$fncReplace = $varReplace[1];
|
||||||
|
|
||||||
|
preg_match_all(
|
||||||
|
"/\{\{\s+{$strKey}\:\s+(.+?)\s+\}\}/i",
|
||||||
|
$strFileData,
|
||||||
|
$varMatches);
|
||||||
|
|
||||||
|
//if ($varReplace[0] == "Server")
|
||||||
|
// Respond::json($varMatches);
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($varMatches[0]); $i++)
|
||||||
|
{
|
||||||
|
$strMatch = $varMatches[0][$i];
|
||||||
|
$strMatchSafe = preg_quote($strMatch);
|
||||||
|
$strInput = $varMatches[1][$i];
|
||||||
|
$strOutput = $fncReplace($strInput);
|
||||||
|
|
||||||
|
while (preg_match("/{$strMatchSafe}/i", $strFileData))
|
||||||
|
{
|
||||||
$strFileData = preg_replace(
|
$strFileData = preg_replace(
|
||||||
"/{$strMatchSafe}/i",
|
"/{$strMatchSafe}/i",
|
||||||
$_SERVER[$strKey],
|
$strOutput,
|
||||||
$strFileData);
|
$strFileData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $x) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ob_clean();
|
||||||
|
//header("Content-Type: text/plain");
|
||||||
|
//echo $strFileData;
|
||||||
|
//ob_end_flush();
|
||||||
|
//exit;
|
||||||
|
|
||||||
// Get the inputs:
|
// Get the inputs:
|
||||||
preg_match_all(
|
preg_match_all(
|
||||||
"/declare\s+\@([A-Za-z0-9]{1,})\s+(.+)\s+=\s+\?;(\s+-- ([A-Za-z0-9]{1,})\:\s(.*))?/i",
|
"/declare\s+\@([A-Za-z0-9]{1,})\s+(.+)\s+=\s+\?;(\s+-- ([A-Za-z0-9]{1,})\:\s(.*))?/i",
|
||||||
@ -200,12 +184,12 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$varRows = $c->query($strQueryPath, $varPosted);
|
$varRows = $c->query($strFileData, $varPosted);
|
||||||
$strQueryView = "{$strQueryPath}.php";
|
$strQueryView = "{$strQueryPath}.php";
|
||||||
|
|
||||||
if (count($varRows) > 0)
|
if (count($varRows) > 0)
|
||||||
{
|
{
|
||||||
if (array_key_exists("_section", $varRows[0]))
|
if (array_key_exists("__Section", $varRows[0]))
|
||||||
{
|
{
|
||||||
$intSectioned = 1;
|
$intSectioned = 1;
|
||||||
$intSortable = 0;
|
$intSortable = 0;
|
||||||
@ -575,7 +559,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<?php if ($strSelection !== null && strlen($strSelection) > 0): ?>
|
<?php if ($strSelection !== null && strlen($strSelection) > 0): ?>
|
||||||
<?php if (array_key_exists("sourcepreview", $varOptions)): ?>
|
<?php if (array_key_exists("showsource", $varOptions)): ?>
|
||||||
<style>
|
<style>
|
||||||
#source-preview {
|
#source-preview {
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
@ -646,10 +630,10 @@
|
|||||||
<div class="row my-3">
|
<div class="row my-3">
|
||||||
<?php foreach ($varRows as $r): ?>
|
<?php foreach ($varRows as $r): ?>
|
||||||
<?php
|
<?php
|
||||||
// Allow SQL data to control row classes with _row_class column:
|
// Allow SQL data to control row classes with __RowClass column:
|
||||||
$strRowClass = "";
|
$strRowClass = "";
|
||||||
if (array_key_exists("_row_class", $r))
|
if (array_key_exists("__RowClass", $r))
|
||||||
$strRowClass = $r["_row_class"];
|
$strRowClass = $r["__RowClass"];
|
||||||
|
|
||||||
$strNextCellClass = "";
|
$strNextCellClass = "";
|
||||||
?>
|
?>
|
||||||
@ -678,8 +662,8 @@
|
|||||||
if (strlen($strNextCellClass) > 0)
|
if (strlen($strNextCellClass) > 0)
|
||||||
$strCellClass = $strNextCellClass;
|
$strCellClass = $strNextCellClass;
|
||||||
|
|
||||||
// Allow SQL data to controll next cell class with _next_cell_class column:
|
// Allow SQL data to controll next cell class with __NextCellClass column:
|
||||||
if (preg_match("/^_next_cell_class/i", $col))
|
if (preg_match("/^__NextCellClass/i", $col))
|
||||||
$strNextCellClass = $r[$col];
|
$strNextCellClass = $r[$col];
|
||||||
|
|
||||||
// Hide columns that begin with underscore:
|
// Hide columns that begin with underscore:
|
||||||
@ -738,20 +722,20 @@
|
|||||||
?>
|
?>
|
||||||
<?php foreach ($varRows as $r): ?>
|
<?php foreach ($varRows as $r): ?>
|
||||||
<?php
|
<?php
|
||||||
// Allow SQL data to control row classes with _row_class column:
|
// Allow SQL data to control row classes with __RowClass column:
|
||||||
$strRowClass = "";
|
$strRowClass = "";
|
||||||
if (array_key_exists("_row_class", $r))
|
if (array_key_exists("__RowClass", $r))
|
||||||
$strRowClass = $r["_row_class"];
|
$strRowClass = $r["__RowClass"];
|
||||||
|
|
||||||
$strNextCellClass = "";
|
$strNextCellClass = "";
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?php if ($intSectioned && $strLastSection !== $r["_section"]): ?>
|
<?php if ($intSectioned && $strLastSection !== $r["__Section"]): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="<?= $strSectionClass; ?>" colspan="<?= $intVisibleColumnCount; ?>"><?= $r["_section"]; ?></td>
|
<td class="<?= $strSectionClass; ?>" colspan="<?= $intVisibleColumnCount; ?>"><?= $r["__Section"]; ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
$strLastSection = $r["_section"];
|
$strLastSection = $r["__Section"];
|
||||||
?>
|
?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
@ -766,8 +750,8 @@
|
|||||||
if (strlen($strNextCellClass) > 0)
|
if (strlen($strNextCellClass) > 0)
|
||||||
$strCellClass = $strNextCellClass;
|
$strCellClass = $strNextCellClass;
|
||||||
|
|
||||||
// Allow SQL data to controll next cell class with _next_cell_class column:
|
// Allow SQL data to controll next cell class with __NextCellClass column:
|
||||||
if (preg_match("/^_next_cell_class/i", $col))
|
if (preg_match("/^__NextCellClass/i", $col))
|
||||||
$strNextCellClass = $r[$col];
|
$strNextCellClass = $r[$col];
|
||||||
|
|
||||||
// Hide columns that begin with underscore:
|
// Hide columns that begin with underscore:
|
||||||
@ -775,6 +759,7 @@
|
|||||||
continue;
|
continue;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
<td class="<?= $strCellClass; ?>" data-column-name="<?= $col; ?>"><?= $r[$col]; ?></td>
|
<td class="<?= $strCellClass; ?>" data-column-name="<?= $col; ?>"><?= $r[$col]; ?></td>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@ -973,3 +958,53 @@
|
|||||||
<meta http-equiv="refresh" content="<?= $varOptions["autorefresh"]; ?>">
|
<meta http-equiv="refresh" content="<?= $varOptions["autorefresh"]; ?>">
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (array_key_exists("saveto", $varOptions)): ?>
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
var saveTo = "<?= $varOptions["saveto"]; ?>";
|
||||||
|
var saveColumns = "<?= $varOptions["savecolumns"]; ?>";
|
||||||
|
saveColumns = saveColumns.split(",");
|
||||||
|
|
||||||
|
saveColumnsArray.forEach(function(item, index) {
|
||||||
|
$(`td[data-column-name="${item}"]`).each(function(i, x) {
|
||||||
|
x = $(x);
|
||||||
|
|
||||||
|
var cellText = x.text().trim();
|
||||||
|
x.html("");
|
||||||
|
|
||||||
|
var inputElement = $("<input type='text' />");
|
||||||
|
|
||||||
|
x.append(inputElement);
|
||||||
|
|
||||||
|
inputElement.val(cellText);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#table tr input[type='text']").on("input", function() {
|
||||||
|
var parentTr = $(this).parents("tr").first();
|
||||||
|
|
||||||
|
parentTr.attr("data-save-row", 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
fnSave = function()
|
||||||
|
{
|
||||||
|
$("tr[data-save-row]").each(function(i, x) {
|
||||||
|
x = $(x);
|
||||||
|
|
||||||
|
var o = {};
|
||||||
|
|
||||||
|
x.find("input").each(function(i2, x2) {
|
||||||
|
x2 = $(x2);
|
||||||
|
|
||||||
|
var cell = x2.parents("td").first();
|
||||||
|
var columnName = cell.attr("data-column-name");
|
||||||
|
|
||||||
|
o[columnName] = x2.val();
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(o);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php endif; ?>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user