diff --git a/includes/Services/PluginUninstaller.php b/includes/Services/PluginUninstaller.php index 9b5c4406e..08d668376 100644 --- a/includes/Services/PluginUninstaller.php +++ b/includes/Services/PluginUninstaller.php @@ -13,13 +13,6 @@ class PluginUninstaller { public static function uninstall( $plugin ) { - $position_in_queue = PluginInstallTaskManager::status( $plugin ); - if ( $position_in_queue !== false && $position_in_queue !== 0 ) { - PluginInstallTaskManager::remove_from_queue( - $plugin, - ); - } - $plugin_list = Plugins::get_squashed(); // Gets the specified path for the Plugin from the predefined list $plugin_path = $plugin_list[ $plugin ]['path']; diff --git a/includes/TaskManagers/PluginUninstallTaskManager.php b/includes/TaskManagers/PluginUninstallTaskManager.php index 74ea563fd..fc7409284 100644 --- a/includes/TaskManagers/PluginUninstallTaskManager.php +++ b/includes/TaskManagers/PluginUninstallTaskManager.php @@ -1,9 +1,11 @@ get_slug() ); + if ( $position_in_queue !== false && $position_in_queue !== 0 ) { + PluginInstallTaskManager::remove_from_queue( + $plugin_uninstall_task->get_slug(), + ); + + return true; + } + + $plugin_list = Plugins::get_squashed(); + // Gets the specified path for the Plugin from the predefined list + $plugin_path = $plugin_list[ $plugin_uninstall_task->get_slug() ]['path']; + + if (!PluginUninstaller::is_plugin_installed($plugin_path)) + return true; + $queue = new PriorityQueue(); foreach ( $plugins as $queued_plugin ) { diff --git a/src/OnboardingSPA/pages/Steps/Complete/index.js b/src/OnboardingSPA/pages/Steps/Complete/index.js index 35b016bf3..3de550af1 100644 --- a/src/OnboardingSPA/pages/Steps/Complete/index.js +++ b/src/OnboardingSPA/pages/Steps/Complete/index.js @@ -3,10 +3,11 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { useEffect, useState } from '@wordpress/element'; import { useNavigate } from 'react-router-dom'; -import { StepLoader } from '../../../components/Loaders'; +import getContents from './contents'; import { completeFlow } from '../../../utils/api/flow'; +import { StepLoader } from '../../../components/Loaders'; +import { setSiteFeatures } from '../../../utils/api/plugins'; import { StepErrorState } from '../../../components/ErrorState'; -import getContents from './contents'; import { DesignStateHandler } from '../../../components/StateHandlers'; const StepComplete = () => { @@ -16,24 +17,54 @@ const StepComplete = () => { const navigate = useNavigate(); const [ isError, setIsError ] = useState( false ); - const { nextStep, brandName } = useSelect( ( select ) => { - return { - nextStep: select( nfdOnboardingStore ).getNextStep(), - brandName: select( nfdOnboardingStore ).getNewfoldBrandName(), - }; - }, [] ); + const { nextStep, brandName, currentData, pluginInstallHash } = useSelect( + ( select ) => { + return { + nextStep: select( nfdOnboardingStore ).getNextStep(), + brandName: select( nfdOnboardingStore ).getNewfoldBrandName(), + currentData: + select( nfdOnboardingStore ).getCurrentOnboardingData(), + pluginInstallHash: + select( nfdOnboardingStore ).getPluginInstallHash(), + }; + }, + [] + ); const contents = getContents( brandName ); const checkFlowComplete = async () => { - const flowCompletionResponse = await completeFlow(); - if ( flowCompletionResponse?.error ) { - setIsHeaderNavigationEnabled( true ); - return setIsError( true ); - } + await Promise.all( [ completeFlowRequest(), setSiteFeaturesRequest() ] ).then( + ( values ) => + values.forEach( ( value ) => { + // If any Request returns False then Show Error + if ( ! value ) { + setIsHeaderNavigationEnabled( true ); + return setIsError( true ); + } + } ) + ); + navigate( nextStep.path ); }; + async function completeFlowRequest() { + const flowCompletionResponse = await completeFlow(); + if ( flowCompletionResponse?.error ) return false; + return true; + } + + async function setSiteFeaturesRequest() { + if ( Array.isArray( currentData?.data?.siteFeatures ) ) return true; + + const siteFeaturesResponse = await setSiteFeatures( pluginInstallHash, { + plugins: currentData?.data?.siteFeatures, + } ); + if ( siteFeaturesResponse?.error ) return false; + + return true; + } + useEffect( () => { setIsHeaderNavigationEnabled( false ); setIsDrawerSuppressed( true ); diff --git a/src/OnboardingSPA/store/selectors.js b/src/OnboardingSPA/store/selectors.js index b3c5c9ad4..f8480e8aa 100644 --- a/src/OnboardingSPA/store/selectors.js +++ b/src/OnboardingSPA/store/selectors.js @@ -262,3 +262,13 @@ export function getStepPreviewData( state ) { export function getHeaderMenuData( state ) { return state.header.menu; } + +/** + * Gets the Plugin Install Hash for security + * + * @param {*} state + * @return string + */ +export function getPluginInstallHash( state ) { + return state.runtime.pluginInstallHash; +} diff --git a/src/OnboardingSPA/utils/api/plugins.js b/src/OnboardingSPA/utils/api/plugins.js index 7716ad275..5b36def29 100644 --- a/src/OnboardingSPA/utils/api/plugins.js +++ b/src/OnboardingSPA/utils/api/plugins.js @@ -38,3 +38,16 @@ export const getSiteFeatures = async () => { } ) ); }; + +export const setSiteFeatures = async ( pluginInstallHash, data ) => { + return await resolve( + apiFetch( { + url: onboardingRestURL( 'plugins/site-features' ), + method: 'POST', + headers: { + 'X-NFD-ONBOARDING': pluginInstallHash, + }, + data, + } ) + ); +};