diff --git a/js/blocks/components/edit.js b/js/blocks/components/edit.js index 10ae6761b..9d09c7f55 100644 --- a/js/blocks/components/edit.js +++ b/js/blocks/components/edit.js @@ -38,6 +38,7 @@ const Edit = ( { blockProps, block } ) => { block={ `genesis-custom-blocks/${ block.name }` } attributes={ attributes } className="genesis-custom-blocks-editor__ssr" + httpMethod="POST" /> ) } diff --git a/package-lock.json b/package-lock.json index e4f2ad580..fc1777127 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4008,12 +4008,45 @@ "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", "dev": true }, + "@types/react": { + "version": "16.9.52", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.52.tgz", + "integrity": "sha512-EHRjmnxiNivwhGdMh9sz1Yw9AUxTSZFxKqdBWAAzyZx3sufWwx6ogqHYh/WB1m/I4ZpjkoZLExF5QTy2ekVi/Q==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz", + "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==", + "dev": true + } + } + }, + "@types/react-dom": { + "version": "16.9.8", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", + "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -6766,20 +6799,20 @@ } }, "@wordpress/server-side-render": { - "version": "1.16.5", - "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.16.5.tgz", - "integrity": "sha512-5QcyKIO1GCPVzqopwhTN+zIlpAO28G4LSgr0AXQ5f8FNtBxcpdfXzSnhveoSrLXVkXaEj+/qjS7Yb8FIkWeC6A==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "@wordpress/api-fetch": "^3.18.0", - "@wordpress/components": "^10.0.5", - "@wordpress/data": "^4.22.3", - "@wordpress/deprecated": "^2.9.0", - "@wordpress/element": "^2.16.0", - "@wordpress/i18n": "^3.14.0", - "@wordpress/url": "^2.17.0", - "lodash": "^4.17.15" + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.18.0.tgz", + "integrity": "sha512-1LFeKjTBml4daW8CavMasxOXHgit9ZDwrSi8Xs/cND7s0dShrGyS8Nxt/D8Urb9PsRgOFWAOfBlCSb74d+tTjg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/api-fetch": "^3.20.0", + "@wordpress/components": "^11.0.0", + "@wordpress/data": "^4.24.0", + "@wordpress/deprecated": "^2.10.0", + "@wordpress/element": "^2.18.0", + "@wordpress/i18n": "^3.16.0", + "@wordpress/url": "^2.19.0", + "lodash": "^4.17.19" }, "dependencies": { "@babel/runtime": { @@ -6791,6 +6824,298 @@ "regenerator-runtime": "^0.13.4" } }, + "@wordpress/a11y": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.13.0.tgz", + "integrity": "sha512-hZm5O8piFe5TQxzc1ti3zcLgCRRYNZz8FiGSTFvF1LlMPxbt4usOD4op+MLRPCyYhMQ+1hdodFBUsa40NfzXwg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/dom-ready": "^2.11.0", + "@wordpress/i18n": "^3.16.0" + } + }, + "@wordpress/api-fetch": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.20.0.tgz", + "integrity": "sha512-VQtdH8QH7pUlYoc2k7GQsT5KXp/ouyQp/hDGZKW4ir9fhGV1QZd/B9ptEitqeXdvXzY6lsEBzHXAJipz3WJ8ng==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/i18n": "^3.16.0", + "@wordpress/url": "^2.19.0" + } + }, + "@wordpress/components": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-11.0.0.tgz", + "integrity": "sha512-DAtGJoV0FcfdbO/POmbtbBpMpnvt4j8ffxPmaKD/XiO0A9FfyVKy3h2lrJ/g6/P2kyzaaS+LJbCyy186+PNQoA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@emotion/core": "^10.0.22", + "@emotion/css": "^10.0.22", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.13.0", + "@wordpress/compose": "^3.21.0", + "@wordpress/date": "^3.12.0", + "@wordpress/deprecated": "^2.10.0", + "@wordpress/dom": "^2.15.0", + "@wordpress/element": "^2.18.0", + "@wordpress/hooks": "^2.10.0", + "@wordpress/i18n": "^3.16.0", + "@wordpress/icons": "^2.7.0", + "@wordpress/is-shallow-equal": "^2.3.0", + "@wordpress/keycodes": "^2.16.0", + "@wordpress/primitives": "^1.9.0", + "@wordpress/rich-text": "^3.22.0", + "@wordpress/warning": "^1.3.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^5.4.0", + "gradient-parser": "^0.1.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-merge-refs": "^1.0.0", + "react-resize-aware": "^3.0.1", + "react-spring": "^8.0.20", + "react-use-gesture": "^7.0.15", + "reakit": "^1.1.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^7.0.2" + } + }, + "@wordpress/compose": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.21.0.tgz", + "integrity": "sha512-GoFe2jwVdo6fU6MuDgI59cXwp8DyH1IpLNKSYGqeaDm69ky1cnMQXKV9mFQ8USZbYRn1f5LYV1Dg4IRsqSGqCw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/element": "^2.18.0", + "@wordpress/is-shallow-equal": "^2.3.0", + "@wordpress/priority-queue": "^1.9.0", + "clipboard": "^2.0.1", + "lodash": "^4.17.19", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.0.1" + } + }, + "@wordpress/data": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.24.0.tgz", + "integrity": "sha512-QlM+dmHLJJROCYIve5sCARt9BDL6eP6VF2IWnYYjJ5yHMlTf6lKp5fyWdGcInY0HmPigLduSTcfgbLUIG3b//Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/compose": "^3.21.0", + "@wordpress/deprecated": "^2.10.0", + "@wordpress/element": "^2.18.0", + "@wordpress/is-shallow-equal": "^2.3.0", + "@wordpress/priority-queue": "^1.9.0", + "@wordpress/redux-routine": "^3.12.0", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/date": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.12.0.tgz", + "integrity": "sha512-sVLSWS3ViLTz4JVM9mmWXKcIrtzkkd+hqDoVyLGZRIBZAK1Fp5c/uDmTCUf7arYW856g8vftWy35r9GC+f6D+A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/deprecated": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.10.0.tgz", + "integrity": "sha512-eyHZMRtq7XItAep7vpeqaLQbF5Guud49UiO0ib5UBT97hrORtd6hM+rlqlFOB3ENvs42XPDCV9jR+jwYJPU9DQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/hooks": "^2.10.0" + } + }, + "@wordpress/dom": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.15.0.tgz", + "integrity": "sha512-eoNfM7QnrZJfdJr1DMaIi1oWlaFJ0BtHBy/0IjGhDYeZIzKRhGzCkz4vhRMwxeTPCGbG0PZg4uwPvys4Vugp9Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "lodash": "^4.17.19" + } + }, + "@wordpress/dom-ready": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-2.11.0.tgz", + "integrity": "sha512-q9MZqYPHUtioT/2tgzyAtnEFXRgUJ6eMxLDQaOprBQkGoD2Ue/V+wEX6cJGy+x8AafFataPC2i2jPsnYqE9+zQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/element": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.18.0.tgz", + "integrity": "sha512-aR1gOXFxIDcrLCSANe5PwOwYH40n29LzjqBascNkFo6f0LBekCZPbI3Bqq4EtoH/zjq2RKAO9PVPlQRDoQUlmA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^1.10.0", + "lodash": "^4.17.19", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "@wordpress/escape-html": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.10.0.tgz", + "integrity": "sha512-peG+Ypnw8L3YiUWSe/3Nmyzlaoqqbn5JaBaLpL0o6pBxFvGwKr00fFJoi+Yq2yZ3LEFDrHBHlVYAB6A2aYIbew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/hooks": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.10.0.tgz", + "integrity": "sha512-DOHahghdZD74feOa36pE1t4E1NpaftAnYP3n41s7YlT2hUKQLCQyo7XQyI38ZsoZwuVCM5b4e9rG4kaNQE6BzA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/i18n": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.16.0.tgz", + "integrity": "sha512-ZyRWplETgD90caVaBuGBFcnYVpcogji1g9Ctbb5AO2bGFeHpmPpjvWm0NE64iQTtLFEJoaCiq6oqUvAOPIQJpw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + } + }, + "@wordpress/icons": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-2.7.0.tgz", + "integrity": "sha512-UnFoieW6dZjYOpQTU+cIdoDTU2NNMiBQ5nUFP1RnNcNcwEiXVrhLqJS9ZXsy+mECeR0K1wT3UUUN7rTiMtITGw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/element": "^2.18.0", + "@wordpress/primitives": "^1.9.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-2.3.0.tgz", + "integrity": "sha512-BUVCYZNDoT5fRJGoam/nI2Sn8QELu5z/pFe7UL+szFqQqNnMibdWqN/KoW/YO7WLJqqqTRhAs/Fa51g4oXRyHQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/keycodes": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.16.0.tgz", + "integrity": "sha512-8CfxB+9f08FXMUsaO625abmbx2ZinFUz6upzXbe0Da8W3oy7+/TZz6EWsMVBEWz+alSR3Z2FUZ7xUuopHZFcow==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/i18n": "^3.16.0", + "lodash": "^4.17.19" + } + }, + "@wordpress/primitives": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-1.9.0.tgz", + "integrity": "sha512-dbYivYpHunYMTXBlY5Mxy/YSBY2RbMV+Z3/MgdkZJMkGL1k+C5/JFAsHSt8Y1UyvWR3lZnWpH+MeF+oq04TWYg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/element": "^2.18.0", + "classnames": "^2.2.5" + } + }, + "@wordpress/priority-queue": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.9.0.tgz", + "integrity": "sha512-Kfk89IF5giemrgMyQ3avkEdEyYqOgSrC2S/vdYUidoGqg3xhDTeSknIRJy82C8/hwSGAB/hLaAkTjK5/T2OYTg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/redux-routine": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.12.0.tgz", + "integrity": "sha512-YJanhB9jHF8089gMzsvI4HNWePC4FL0CKQ+qGacp8rr4AgQ05VkmCmnSO/Y5dAxgXIHAtluz8NlXYgN65l5hAg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "rungen": "^0.3.2" + } + }, + "@wordpress/rich-text": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.22.0.tgz", + "integrity": "sha512-Bch6yyE3EckctjUZ5oS/X5VjmHP2JqO4tzrcgD1abHET7LeZIVUg7cXFnz+4byOVvkrgFtuQl+Tk6CINyLpKMQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@wordpress/compose": "^3.21.0", + "@wordpress/data": "^4.24.0", + "@wordpress/deprecated": "^2.10.0", + "@wordpress/element": "^2.18.0", + "@wordpress/escape-html": "^1.10.0", + "@wordpress/is-shallow-equal": "^2.3.0", + "@wordpress/keycodes": "^2.16.0", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "rememo": "^3.0.0" + } + }, + "@wordpress/url": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.19.0.tgz", + "integrity": "sha512-RizWbBxYmWBlNd+q89r3N6Y2XO8eCG3VncnXDgbGnhV4e+2z9fjzp1/9C/SORftEn+ix/qBKbqygmkmBqb+wuw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "lodash": "^4.17.19", + "qs": "^6.5.2", + "react-native-url-polyfill": "^1.1.2" + } + }, + "@wordpress/warning": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-1.3.0.tgz", + "integrity": "sha512-xwvgwqugc3zQawSPMMA09knAgap7IGgp0PxTXpFqizGFRIohoXFWERnPBZT0VsSCovqYS0ADcH+ZZgQ+BKAzLA==", + "dev": true + }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", @@ -15203,6 +15528,12 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -22148,6 +22479,12 @@ "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", "dev": true }, + "react-merge-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", + "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==", + "dev": true + }, "react-moment-proptypes": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/react-moment-proptypes/-/react-moment-proptypes-1.7.0.tgz", diff --git a/package.json b/package.json index 0b5615dc5..4ed5a4fe7 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@wordpress/keycodes": "2.14.0", "@wordpress/postcss-plugins-preset": "1.3.1", "@wordpress/scripts": "12.1.1", - "@wordpress/server-side-render": "1.16.5", + "@wordpress/server-side-render": "1.18.0", "@wordpress/url": "2.17.0", "autoprefixer": "9.8.6", "babel-core": "6.26.3", diff --git a/php/Blocks/Loader.php b/php/Blocks/Loader.php index 919350994..f257fc879 100644 --- a/php/Blocks/Loader.php +++ b/php/Blocks/Loader.php @@ -7,6 +7,7 @@ namespace Genesis\CustomBlocks\Blocks; +use WP_REST_Server; use WP_Query; use Genesis\CustomBlocks\ComponentAbstract; @@ -62,25 +63,11 @@ public function init() { * Register all the hooks. */ public function register_hooks() { - /** - * Gutenberg JS block loading. - */ - add_action( 'enqueue_block_editor_assets', $this->get_callback( 'editor_assets' ) ); - - /** - * Gutenberg custom categories. - */ - add_filter( 'block_categories', $this->get_callback( 'register_categories' ) ); - - /** - * Block retrieval, must run before dynamic_block_loader(). - */ - add_action( 'init', $this->get_callback( 'retrieve_blocks' ) ); - - /** - * PHP block loading. - */ - add_action( 'init', $this->get_callback( 'dynamic_block_loader' ) ); + add_action( 'enqueue_block_editor_assets', [ $this, 'editor_assets' ] ); + add_filter( 'block_categories', [ $this, 'register_categories' ] ); + add_action( 'init', [ $this, 'retrieve_blocks' ] ); + add_action( 'init', [ $this, 'dynamic_block_loader' ] ); + add_filter( 'rest_endpoints', [ $this, 'add_rest_method' ] ); } /** @@ -112,25 +99,10 @@ public function get_data( $key ) { return apply_filters( "genesis_custom_blocks_data_{$key}", $data ); } - /** - * Gets the callback for an action or filter. - * - * Enables keeping these methods protected, - * while allowing actions and filters to call them. - * - * @param string $method_name The name of the method to get the callback for. - * @return callable An enclosure that calls the function. - */ - protected function get_callback( $method_name ) { - return function( $arg ) use ( $method_name ) { - return call_user_func( [ $this, $method_name ], $arg ); - }; - } - /** * Launch the blocks inside Gutenberg. */ - protected function editor_assets() { + public function editor_assets() { $js_config = require $this->plugin->get_path( 'js/editor.blocks.asset.php' ); $css_config = require $this->plugin->get_path( 'css/blocks.editor.asset.php' ); @@ -189,7 +161,7 @@ protected function editor_assets() { /** * Loads dynamic blocks via render_callback for each block. */ - protected function dynamic_block_loader() { + public function dynamic_block_loader() { if ( ! function_exists( 'register_block_type' ) ) { return; } @@ -237,7 +209,7 @@ protected function register_block( $block_name, $block ) { * * @return array */ - protected function register_categories( $categories ) { + public function register_categories( $categories ) { foreach ( $this->blocks as $block_config ) { if ( ! isset( $block_config['category'] ) ) { continue; @@ -519,7 +491,7 @@ protected function block_template( $name, $type = 'block' ) { /** * Load all the published blocks and blocks/block.json files. */ - protected function retrieve_blocks() { + public function retrieve_blocks() { /** * Retrieve blocks from blocks.json. * Reverse to preserve order of preference when using array_merge. @@ -610,4 +582,30 @@ public function add_field( $block_name, $field_config ) { $this->blocks[ "genesis-custom-blocks/{$block_name}" ]['fields'][ $field_config['name'] ] = $field_config; } + + /** + * Adds 'POST' to the allowed REST methods for GCB blocks. + * + * The uses the httpMethod of 'POST' to handle a larger attributes object. + * That is already added in WP 5.6+, so no need to add it there. + * + * @todo: Delete when this plugin's 'Requires at least' is bumped to 5.6. + * @see https://core.trac.wordpress.org/ticket/49680#comment:15 + * + * @param array $endpoints The REST API endpoints, an associative array of $route => $handlers. + * @return array The filtered endpoints, with the GCB endpoints allowing POST requests. + */ + public function add_rest_method( $endpoints ) { + if ( is_wp_version_compatible( '5.6' ) ) { + return $endpoints; + } + + foreach ( $endpoints as $route => $handler ) { + if ( 0 === strpos( $route, '/wp/v2/block-renderer/(?Pgenesis-custom-blocks/' ) && isset( $endpoints[ $route ][0] ) ) { + $endpoints[ $route ][0]['methods'] = [ WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ]; + } + } + + return $endpoints; + } } diff --git a/tests/php/Unit/Blocks/TestLoader.php b/tests/php/Unit/Blocks/TestLoader.php index c39867df7..8454c93ea 100644 --- a/tests/php/Unit/Blocks/TestLoader.php +++ b/tests/php/Unit/Blocks/TestLoader.php @@ -26,7 +26,7 @@ class TestLoader extends AbstractTemplate { * * @var array */ - public $block_config_without_name = [ + private $block_config_without_name = [ 'foo' => 'Example Value', ]; @@ -35,12 +35,40 @@ class TestLoader extends AbstractTemplate { * * @var array */ - public $block_config_with_name = [ + private $block_config_with_name = [ 'name' => 'Example Block', ]; /** - * Teardown. + * The REST API route for blocks. + * + * @var string + */ + private $rest_api_route = '/wp/v2/block-renderer/'; + + /** + * A mock REST API handler. + * + * @var array + */ + private $mock_handler = [ + 0 => [ + 'methods' => [ 'GET' ], + 'callback' => [ 'example_callback' ], + ], + ]; + + /** + * The WP version with the correct 'block-renderer' endpoint. + * + * @see https://core.trac.wordpress.org/ticket/49680#comment:15 + * + * @var string + */ + private $wp_version_with_correct_endpoint = '5.6'; + + /** + * Tear down after each test. * * @inheritdoc */ @@ -70,18 +98,13 @@ public function test_init() { * @covers \Genesis\CustomBlocks\Blocks\Loader::register_hooks() */ public function test_register_hooks() { - global $wp_filter; - $this->instance->register_hooks(); - $expected_filters = [ - 'enqueue_block_editor_assets', - 'block_categories', - 'init', - ]; - foreach ( $expected_filters as $filter ) { - $this->assertNotEmpty( $wp_filter[ $filter ]->callbacks[10] ); - } + $this->assertEquals( 10, has_action( 'enqueue_block_editor_assets', [ $this->instance, 'editor_assets' ] ) ); + $this->assertEquals( 10, has_filter( 'block_categories', [ $this->instance, 'register_categories' ] ) ); + $this->assertEquals( 10, has_action( 'init', [ $this->instance, 'retrieve_blocks' ] ) ); + $this->assertEquals( 10, has_action( 'init', [ $this->instance, 'dynamic_block_loader' ] ) ); + $this->assertEquals( 10, has_filter( 'rest_endpoints', [ $this->instance, 'add_rest_method' ] ) ); } /** @@ -142,7 +165,7 @@ public function test_editor_assets() { $style_handle = 'genesis-custom-blocks-editor-css'; $this->instance->init(); - $this->invoke_protected_method( 'editor_assets' ); + $this->instance->editor_assets(); $this->assertTrue( wp_script_is( $script_handle ) ); $this->assertContains( @@ -436,6 +459,60 @@ public function test_add_field() { ); } + /** + * Test add_rest_method when there is no GCB block. + * + * @covers \Genesis\CustomBlocks\Blocks\Loader::add_rest_method() + */ + public function test_add_rest_method_no_gcb_block() { + $initial_methods = [ 'GET' ]; + $non_gcb_block_route = $this->rest_api_route . '(?Pdifferent-block-namespace/main-hero)'; + $actual = $this->instance->add_rest_method( + [ + $non_gcb_block_route => [ + 0 => [ + 'methods' => $initial_methods, + 'callback' => '__return_false', + ], + ], + ] + ); + + $this->assertEquals( + [ + 'methods' => $initial_methods, + 'callback' => '__return_false', + ], + $actual[ $non_gcb_block_route ][0] + ); + } + + /** + * Test add_rest_method when there is a GCB block. + * + * @covers \Genesis\CustomBlocks\Blocks\Loader::add_rest_method() + */ + public function test_add_rest_method_with_gcb_block() { + $expected_methods = [ 'GET', 'POST' ]; + $gcb_block_route = $this->rest_api_route . '(?Pgenesis-custom-blocks/main-hero)'; + $initial_routes = [ + $gcb_block_route => $this->mock_handler, + ]; + + if ( is_wp_version_compatible( $this->wp_version_with_correct_endpoint ) ) { + $initial_routes[ $gcb_block_route ]['methods'] = $expected_methods; + } + + $actual = $this->instance->add_rest_method( $initial_routes ); + $this->assertEquals( + [ + 'methods' => $expected_methods, + 'callback' => $this->mock_handler[0]['callback'], + ], + $actual[ $gcb_block_route ][0] + ); + } + /** * Gets the full paths of the template CSS files, in order of reverse priority. *