Camel case data hinting, replacement refactor, showsource instead of sourcepreview option

This commit is contained in:
Conner Harkness 2025-09-25 09:08:33 -06:00
parent 11501e240b
commit a4aab45046
2 changed files with 137 additions and 88 deletions

View File

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

View File

@ -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; ?>