Last active
October 27, 2025 17:58
-
-
Save craigrodway/708766029682d2c6c02cea7e188b36b6 to your computer and use it in GitHub Desktop.
SqlFormatterPlugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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