AjaxShortcodes.php
87 lines
| 1 | <?php |
| 2 | namespace NitroPack\Feature; |
| 3 | |
| 4 | class AjaxShortcodes { |
| 5 | const STAGE = "very_early"; |
| 6 | |
| 7 | private $shortcodes = array(); |
| 8 | private $nitroScLoader = <<<'SCRIPT' |
| 9 | (() => { |
| 10 | document.addEventListener("DOMContentLoaded", () => { |
| 11 | let ajaxElements = document.querySelectorAll(".nitro-sc-load"); |
| 12 | let reqData = new Set(); |
| 13 | ajaxElements.forEach((el) => { |
| 14 | reqData.add(el.getAttribute("data-sc-meta")); |
| 15 | }); |
| 16 | jQuery.ajax({ |
| 17 | type: "post", |
| 18 | url: `${window.location.origin}/wp-admin/admin-ajax.php`, |
| 19 | data: { |
| 20 | action: "nitro_shortcode_ajax", |
| 21 | data: Array.from(reqData), |
| 22 | }, |
| 23 | complete: function (response) { |
| 24 | let scData = JSON.parse(response.responseText).data |
| 25 | for (let key in scData) { |
| 26 | document.querySelectorAll(`.nitro-sc-load[data-sc-meta='${key}']`).forEach( el => { el.outerHTML = scData[key]; }); |
| 27 | console.log(key, scData[key]); |
| 28 | } |
| 29 | }, |
| 30 | }); |
| 31 | }); |
| 32 | })() |
| 33 | SCRIPT; |
| 34 | |
| 35 | public function init($stage) { |
| 36 | if (!defined("NITROPACK_AJAX_SHORTCODES")) { |
| 37 | // This init method can be run at any stage. This gives the opportunity to define the constant at a later point |
| 38 | // For example in a MU plugin |
| 39 | return true; |
| 40 | } |
| 41 | |
| 42 | $this->shortcodes = array_map("trim", explode(",", NITROPACK_AJAX_SHORTCODES)); |
| 43 | |
| 44 | add_action('wp_ajax_nitro_shortcode_ajax', array($this, 'shortcodeAjax')); |
| 45 | add_action('wp_ajax_nopriv_nitro_shortcode_ajax', array($this, 'shortcodeAjax')); |
| 46 | |
| 47 | add_action('wp_enqueue_scripts', function() { |
| 48 | wp_add_inline_script('jquery', $this->nitroScLoader); |
| 49 | }); |
| 50 | |
| 51 | add_filter('pre_do_shortcode_tag', function($out, $tag, $attr) { |
| 52 | if (defined("NITRO_DOING_AJAX_SHORTCODES") && NITRO_DOING_AJAX_SHORTCODES) return $out; |
| 53 | |
| 54 | if (in_array($tag, $this->shortcodes)) { |
| 55 | return '<span class="nitro-sc-load" data-sc-meta="' . base64_encode(json_encode(["tag" => $tag, "attr" => $attr])) . '"></span>'; |
| 56 | } |
| 57 | return $out; |
| 58 | }, 10, 3); |
| 59 | } |
| 60 | |
| 61 | public function shortcodeAjax() { |
| 62 | if (!defined("NITRO_DOING_AJAX_SHORTCODES")) define("NITRO_DOING_AJAX_SHORTCODES", true); |
| 63 | $this->runShortcodes(); |
| 64 | |
| 65 | // In case a later hook is needed, we can and an option for it and use something like this |
| 66 | //if (did_action('plugins_loaded')) { |
| 67 | // $this->runShortcodes(); |
| 68 | //} else { |
| 69 | // add_action('plugins_loaded', [$this, 'runShortcodes']); |
| 70 | //} |
| 71 | } |
| 72 | |
| 73 | public function runShortcodes() { |
| 74 | $shortcodes = $_POST["data"]; |
| 75 | if (empty($shortcodes)) wp_send_json_error(["message" => "Invalid shortcode input"], 400); |
| 76 | |
| 77 | $resp = []; |
| 78 | foreach ($shortcodes as $shortcode) { |
| 79 | $sc = json_decode(base64_decode($shortcode), true); |
| 80 | $attrFlat = is_array($sc["attr"]) ? array_map(function($k, $v) { return "$k=$v"; }, array_keys($sc["attr"]), array_values($sc["attr"])) : []; |
| 81 | $resp[$shortcode] = do_shortcode("[{$sc['tag']} " . implode(" ", $attrFlat) . "]"); |
| 82 | } |
| 83 | |
| 84 | wp_send_json_success($resp); |
| 85 | } |
| 86 | } |
| 87 |