Skip to content

Instantly share code, notes, and snippets.

@craigrodway
Last active October 27, 2025 17:58
Show Gist options
  • Select an option

  • Save craigrodway/708766029682d2c6c02cea7e188b36b6 to your computer and use it in GitHub Desktop.

Select an option

Save craigrodway/708766029682d2c6c02cea7e188b36b6 to your computer and use it in GitHub Desktop.
SqlFormatterPlugin
<?php
namespace AdminNeo;
use AdminNeo\Plugin;
/**
* Add a 'Format SQL' button to query textarea.
*
* @uses SQL Formatter, https://www.npmjs.com/package/sql-formatter
* @author Craig Rodway
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class SqlFormatterPlugin extends Plugin
{
/** @access protected */
private $script;
/** @access protected */
private $options;
/** @access protected */
private $icon;
function __construct($script = 'sql-formatter.min.js', $options = [])
{
// https://unpkg.com/browse/sql-formatter@15.3.1/dist/sql-formatter.min.js
$this->script = $script;
$defaults = [
// 'tabWidth' => 4,
];
$this->options = array_merge($defaults, $options);
$this->icon = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHMSURBVDjLlZLBSyJhGMa/UxTUIWJ0ZVmlwxLLEiEhurCoKeqCOtZN7J4ZRZdd9rSG6NFbSOegDp5aqWWI3UGm6KBUxsq2LLj+CzV9jDOH8NlvJtqLjuXhBy/z8Xvel4chAMhTKGfOMeVsbqXf2wBp3s5Yf5hno8rp24YxS9PTVHq18mTAgzj3k4mCIs0cqZeLUCTHJ1q13VKRSz0v4PRNVr1KQfu9Aa31BZ2LKKg42aHfJ8ZNA9i5L9hWUZFeQ73kof3N42SPR6OyjFZ1FZ36AuQfo5CPyc7gDiRHttNYwsl+Apqmodvt4uJrCur1GmSB/GI4TAOo9JKjVasQi8VQr9ehqiqazSaqu1Fofz5C/kYow9M3gJVkp+JUJZFIIJ1Oo1gsolwu42hngcmfdfmecS4fki3TC3ieN2SPx4NAIIB4PA7lPIo70YY7YQJyhdhNS3yU3W43/H4/LBaLvnWbbbxnvGNyQz4gmb4ByWQShULBkH0+HziOg/6die+ZKOjzzQEZYXzoCYhEIsjn8z3yI0wKmf7KwWAQuVwOLpcLXq+3Rx4EyWQyaLfbcDqdCIVCQ8n/A2q1GkqlklHYMLIREA6HN/WzrVbr0LLOP1AMs7UPAa92AAAAAElFTkSuQmCC';
}
private function styles()
{
$css = <<<EOS
<style>
.fmt-sql-btn {
padding: 3px 7px;
font-size: 12px;
font-family: inherit;
}
.fmt-sql-btn img {
vertical-align: -15%;
margin-right: 4px;
}
</style>
EOS;
return $css;
}
public function js()
{
$json_options = json_encode($this->options ?? [], JSON_NUMERIC_CHECK);
$js = <<<EOS
(function(document) {
const sqlFmtOpts = {$json_options};
document.addEventListener("DOMContentLoaded", init, false);
function init() {
addBtn();
}
function doFormatSql() {
const sqlArea = qs('textarea.sqlarea');
var fmtd = window.sqlFormatter.format(sqlArea.value, getOptions(sqlArea));
setSqlAreaValue(fmtd);
}
function getOptions(sqlArea) {
// @todo detect language in use by AdminNeo and override?
var opts = sqlFmtOpts;
return opts;
}
function addBtn() {
const sqlArea = qs('textarea.sqlarea');
var actionsEl = sqlArea.parentNode.nextSibling;
var parentEl = sqlArea.parentNode.parentNode;
var formatBtn = document.createElement('button');
formatBtn.type = 'button';
formatBtn.className = 'button';
formatBtn.addEventListener('click', function(e) {
e.preventDefault();
doFormatSql();
}, false);
var lblEl = document.createTextNode('Format SQL');
var iconEl = document.createElement('img');
iconEl.src = "data:image/png;base64,{$this->icon}";
iconEl.alt = '';
iconEl.style = 'margin-right:4px';
formatBtn.appendChild(iconEl);
formatBtn.appendChild(lblEl);
var formatP = document.createElement('p');
formatP.appendChild(formatBtn);
parentEl.insertBefore(formatP, actionsEl);
}
function setSqlAreaValue(value) {
const sqlArea = qs('textarea.sqlarea');
sqlArea.value = value;
var preEl = qs('pre.sqlarea');
var tmtdEl = document.createTextNode(value);
preEl.textContent = value;
// trigger event for jush to update formatting/styles
preEl.oninput && preEl.oninput(null);
}
})(document);
EOS;
return $js;
}
public function printToHead()
{
echo script_src($this->script);
echo $this->styles();
echo script($this->js());
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment