From 9baa46beaf1cccbec986b5434b453c14dddd624a Mon Sep 17 00:00:00 2001 From: Alessio Torrisi Date: Wed, 20 Nov 2024 13:10:28 +0100 Subject: [PATCH] Added API to handle change option --- components/cacheSettings/index.js | 290 +++++++++++++----------- components/performance/index.js | 83 +++---- includes/Performance.php | 24 +- includes/Permissions.php | 52 +++++ includes/RestApi/RestApi.php | 39 ++++ includes/RestApi/SettingsController.php | 117 ++++++++++ package.json | 3 +- 7 files changed, 435 insertions(+), 173 deletions(-) create mode 100644 includes/Permissions.php create mode 100644 includes/RestApi/RestApi.php create mode 100644 includes/RestApi/SettingsController.php diff --git a/components/cacheSettings/index.js b/components/cacheSettings/index.js index 2be0778..f77812d 100644 --- a/components/cacheSettings/index.js +++ b/components/cacheSettings/index.js @@ -1,144 +1,174 @@ -import { Checkbox, Container, RadioGroup } from "@newfold/ui-component-library"; +// WordPress +import apiFetch from '@wordpress/api-fetch'; -const CacheSettings = ({ methods, constants, Components }) => { - const [ cacheLevel, setCacheLevel ] = methods.useState(constants.store.cacheLevel); - const [ skip404, setSkip404 ] = methods.useState(constants.store.skip404); +// Newfold +import { Checkbox, Container, RadioGroup } from '@newfold/ui-component-library'; +import { NewfoldRuntime } from '@newfold-labs/wp-module-runtime'; - const cacheOptions = [ - { - label: constants.text.cacheLevel0Label, - description: constants.text.cacheLevel0Description + constants.text.cacheLevel0Recommendation, - value: 0, - notice: constants.text.cacheLevel0NoticeText, - }, - { - label: constants.text.cacheLevel1Label, - description: constants.text.cacheLevel1Description + constants.text.cacheLevel1Recommendation, - value: 1, - notice: constants.text.cacheLevel1NoticeText, - }, - { - label: constants.text.cacheLevel2Label, - description: constants.text.cacheLevel2Description + constants.text.cacheLevel2Recommendation, - value: 2, - notice: constants.text.cacheLevel2NoticeText, - }, - { - label: constants.text.cacheLevel3Label, - description: constants.text.cacheLevel3Description + constants.text.cacheLevel3Recommendation, - value: 3, - notice: constants.text.cacheLevel3NoticeText, - }, - ]; +const CacheSettings = ( { methods, constants, Components } ) => { + const [ cacheLevel, setCacheLevel ] = methods.useState( + constants.store.cacheLevel + ); + const [ skip404, setSkip404 ] = methods.useState( + NewfoldRuntime.sdk.skip404 + ); - const getCacheLevelNoticeTitle = () => { - return constants.text.cacheLevelNoticeTitle; - }; + const cacheOptions = [ + { + label: constants.text.cacheLevel0Label, + description: + constants.text.cacheLevel0Description + + constants.text.cacheLevel0Recommendation, + value: 0, + notice: constants.text.cacheLevel0NoticeText, + }, + { + label: constants.text.cacheLevel1Label, + description: + constants.text.cacheLevel1Description + + constants.text.cacheLevel1Recommendation, + value: 1, + notice: constants.text.cacheLevel1NoticeText, + }, + { + label: constants.text.cacheLevel2Label, + description: + constants.text.cacheLevel2Description + + constants.text.cacheLevel2Recommendation, + value: 2, + notice: constants.text.cacheLevel2NoticeText, + }, + { + label: constants.text.cacheLevel3Label, + description: + constants.text.cacheLevel3Description + + constants.text.cacheLevel3Recommendation, + value: 3, + notice: constants.text.cacheLevel3NoticeText, + }, + ]; - const getCacheLevelNoticeText = () => { - return cacheOptions[cacheLevel].notice; - }; + const getCacheLevelNoticeTitle = () => { + return constants.text.cacheLevelNoticeTitle; + }; + const getCacheLevelNoticeText = () => { + return cacheOptions[ cacheLevel ].notice; + }; - const getSkip404NoticeTitle = () => { - return constants.text.skip404NoticeTitle; - }; + const getSkip404NoticeTitle = () => { + return constants.text.skip404NoticeTitle; + }; - const handleCacheLevelChange = (e) => { - methods.newfoldSettingsApiFetch( - { cacheLevel: parseInt(e.target.value) }, - methods.setError, (response) => { - setCacheLevel(parseInt(e.target.value)); - } - ); - }; + const handleCacheLevelChange = ( e ) => { + methods.newfoldSettingsApiFetch( + { cacheLevel: parseInt( e.target.value ) }, + methods.setError, + () => { + setCacheLevel( parseInt( e.target.value ) ); + } + ); + }; - const handleSkip404Change = (e) => { - methods.newfoldSettingsApiFetch( - { skip404: ! skip404 }, - methods.setError, (response) => { - setSkip404( ! skip404 ); - } - ); - }; + const handleSkip404Change = () => { + const value = ! skip404; - methods.useUpdateEffect(() => { - methods.setStore({ - ...constants.store, - cacheLevel, - }); + apiFetch( { + path: 'newfold-performance/v1/settings', + method: 'POST', + data: { + field: { + id: 'skip404', + value, + }, + }, + } ) + .then( () => { + setSkip404( value ); - methods.makeNotice( - "cache-level-change-notice", - getCacheLevelNoticeTitle(), - getCacheLevelNoticeText(), - "success", - 5000 - ); - }, [cacheLevel]); + methods.makeNotice( + 'skip-404-change-notice', + getSkip404NoticeTitle(), + '', + 'success', + 5000 + ); + } ) + .catch( () => { + methods.makeNotice( + 'skip-404-change-notice', + constants.text.optionNotSet, + '', + 'error', + 5000 + ); + } ); + }; + methods.useUpdateEffect( () => { + methods.setStore( { + ...constants.store, + cacheLevel, + } ); - methods.useUpdateEffect(() => { - methods.setStore({ - ...constants.store, - skip404, - }); + methods.makeNotice( + 'cache-level-change-notice', + getCacheLevelNoticeTitle(), + getCacheLevelNoticeText(), + 'success', + 5000 + ); + }, [ cacheLevel ] ); - methods.makeNotice( - "skip-404-change-notice", - getSkip404NoticeTitle(), - '', - "success", - 5000 - ); - }, [skip404]); + return ( + <> + + + { cacheOptions.map( ( option ) => { + return ( + + +
+ { option.description } +
+
+ ); + } ) } +
+
+ + + + + ); +}; - return ( - <> - - - {cacheOptions.map((option) => { - return ( - - -
- {option.description} -
-
- ); - })} -
-
- - - - - - ); -} - -export default CacheSettings; \ No newline at end of file +export default CacheSettings; diff --git a/components/performance/index.js b/components/performance/index.js index e6d7483..0070001 100644 --- a/components/performance/index.js +++ b/components/performance/index.js @@ -6,54 +6,55 @@ import { default as defaultText } from './defaultText'; /** * Performance Module * For use in brand plugin apps to display performance page and settings - * - * @param {*} props - * @returns + * + * @param {*} props + * @return */ -const Performance = ({methods, constants, Components, ...props}) => { - const { store, setStore } = methods.useContext(methods.AppStore); - const [ isError, setError ] = methods.useState(false); +const Performance = ( { methods, constants, Components, ...props } ) => { + const { store, setStore } = methods.useContext( methods.AppStore ); + const [ isError, setError ] = methods.useState( false ); - let notify = methods.useNotification(); + const notify = methods.useNotification(); // set default text if not provided - constants.text = Object.assign(defaultText, constants.text); + constants.text = Object.assign( defaultText, constants.text ); - const makeNotice = (id, title, description, variant="success", duration=false) => { - notify.push(`performance-notice-${id}`, { - title, - description: ( - - {description} - - ), - variant, - autoDismiss: duration, - }); - }; - constants.store = store; - methods.makeNotice = makeNotice; - methods.setStore = setStore; - methods.setError = setError; + const makeNotice = ( + id, + title, + description, + variant = 'success', + duration = false + ) => { + notify.push( `performance-notice-${ id }`, { + title, + description: { description }, + variant, + autoDismiss: duration, + } ); + }; + constants.store = store; + methods.makeNotice = makeNotice; + methods.setStore = setStore; + methods.setError = setError; return ( - <> - - - - - - - + <> + + + + + + + ); - }; -export default Performance; \ No newline at end of file +export default Performance; diff --git a/includes/Performance.php b/includes/Performance.php index ac50c2f..5492c1f 100644 --- a/includes/Performance.php +++ b/includes/Performance.php @@ -2,9 +2,11 @@ namespace NewfoldLabs\WP\Module\Performance; +use NewfoldLabs\WP\Module\Performance\RestApi\RestApi; use NewfoldLabs\WP\Module\Performance\CacheTypes\Browser; use NewfoldLabs\WP\Module\Performance\CacheTypes\File; use NewfoldLabs\WP\Module\Performance\CacheTypes\Skip404; +use NewfoldLabs\WP\Module\Performance\Permissions; use NewfoldLabs\WP\ModuleLoader\Container; /** @@ -80,6 +82,12 @@ public function __construct( Container $container ) { $container->set( 'cachePurger', $cachePurger ); $container->set( 'hasMustUsePlugin', file_exists( WPMU_PLUGIN_DIR . '/endurance-page-cache.php' ) ); + + if ( Permissions::is_authorized_admin() || Permissions::rest_is_authorized_admin() ) { + new RestAPI(); + } + + add_filter( 'newfold-runtime', array( $this, 'add_to_runtime' ), 10 ); } /** @@ -287,9 +295,23 @@ public function adminBarMenu( \WP_Admin_Bar $wp_admin_bar ) { 'id' => 'nfd_purge_menu-cache_settings', 'title' => __( 'Cache Settings', 'newfold-module-performance' ), 'parent' => 'nfd_purge_menu', - 'href' => admin_url( 'options-general.php#' . Performance::SETTINGS_ID ), + 'href' => admin_url( 'options-general.php#' . self::SETTINGS_ID ), ) ); } } + + + /** + * Add to Newfold SDK runtime. + * + * @param array $sdk SDK data. + * @return array SDK data. + */ + public function add_to_runtime( $sdk ) { + $values = array( + 'skip404' => (bool) get_option( 'newfold_skip_404_handling', false ), + ); + return array_merge( $sdk, array( 'performance' => $values ) ); + } } diff --git a/includes/Permissions.php b/includes/Permissions.php new file mode 100644 index 0000000..1b5bf86 --- /dev/null +++ b/includes/Permissions.php @@ -0,0 +1,52 @@ +controllers as $controller ) { + /** + * Get an instance of the WP_REST_Controller. + * + * @var $instance WP_REST_Controller + */ + $instance = new $controller(); + $instance->register_routes(); + } + } +} diff --git a/includes/RestApi/SettingsController.php b/includes/RestApi/SettingsController.php new file mode 100644 index 0000000..8d25082 --- /dev/null +++ b/includes/RestApi/SettingsController.php @@ -0,0 +1,117 @@ +namespace, + $this->rest_base, + array( + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'set_options' ), + 'permission_callback' => function () { + return current_user_can( 'manage_options' ); + }, + ), + ) + ); + } + + /** + * Set Jetpack options. + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response + */ + public function set_options( $request ) { + try { + $params = $request->get_params(); + + if ( ! isset( $params['field'] ) || ! is_array( $params['field'] ) ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'error' => __( "The parameter 'field' is missing or invalid.", 'newfold-performance-module' ), + ), + 400 + ); + } + + $field = $params['field']; + + if ( ! isset( $field['id'], $field['value'] ) ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'error' => __( "The fields 'id' and 'value' are required.", 'newfold-performance-module' ), + ), + 400 + ); + } + + switch ( $field['id'] ) { + case 'skip404': + $result = update_option( 'newfold_skip_404_handling', $field['value'] ); + break; + + default: + break; + } + + if ( false === $result ) { + return new \WP_REST_Response( + array( + 'success' => false, + 'error' => __( 'An error occurred while updating the option.', 'newfold-performance-module' ), + ), + 500 + ); + } + + // Success response. + return new \WP_REST_Response( + array( + 'success' => true, + 'updated_option' => $field['id'], + 'updated_value' => $field['value'], + ), + 200 + ); + } catch ( \Exception $e ) { + // Exceptions handling. + return new \WP_REST_Response( + array( + 'success' => false, + 'error' => __( 'An error occurred while updating the option.', 'newfold-performance-module' ) . $e->getMessage(), + ), + 500 + ); + } + } +} diff --git a/package.json b/package.json index 6388cb6..e57c793 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ ], "dependencies": { "@heroicons/react": "^2.0.18", - "@newfold/ui-component-library": "^1.0.1" + "@newfold/ui-component-library": "^1.0.1", + "@newfold-labs/wp-module-runtime": "^1.0.12" }, "devDependencies": { "@testing-library/cypress": "^9.0.0",