Skip to content

Commit

Permalink
Complete flow for WooCommerce install failure
Browse files Browse the repository at this point in the history
  • Loading branch information
aulisius committed Aug 12, 2022
1 parent f6e558f commit 14d5178
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 65 deletions.
1 change: 1 addition & 0 deletions includes/Data/Plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static function get_slug_map( $plugin ) {
'yith_wcas_panel' => array( 'https://downloads.wordpress.org/plugin/yith-woocommerce-ajax-search.1.21.0.zip', 'yith-woocommerce-ajax-search/init.php' ),
'yith_shippo_shipping_for_woocommerce' => array( 'https://hiive.cloud/workers/plugin-downloads/yith-shippo-shippings-for-woocommerce', 'yith-shippo-shippings-for-woocommerce-extended/init.php' ),
'yith_paypal_payments' => array( 'https://hiive.cloud/workers/plugin-downloads/yith-paypal-payments-for-woocommerce', 'yith-paypal-payments-for-woocommerce-extended/init.php' ),
'woocommerce' => array( 'ignore', 'woocommerce/woocommerce.php'),
);
if ( in_array( $plugin, array_keys( $map ) ) ) {
$plugin = $map[ $plugin ];
Expand Down
23 changes: 8 additions & 15 deletions includes/RestApi/PluginsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,6 @@ public function register_routes() {
),
)
);
\register_rest_route(
$this->namespace,
$this->rest_base . '/verification',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array( Permissions::class, 'rest_get_plugin_install_hash' ),
'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ),
),
)
);
}

/**
Expand All @@ -56,6 +45,7 @@ public function register_routes() {
*/
public function get_plugins_status() {
$plugins = array(
'woocommerce',
'yith_wcmap_panel',
'yith_woocommerce_gift_cards_panel',
'yith_wcwl_panel',
Expand All @@ -70,16 +60,19 @@ public function get_plugins_status() {
if ( file_exists( WP_PLUGIN_DIR . '/' . $map[1] ) ) {
$active = is_plugin_active( $map[1] );
if ( $active ) {
$result[ $plugin ] = 'Active';
$status[ $plugin ] = 'Active';
} else {
$result[ $plugin ] = 'Inactive';
$status[ $plugin ] = 'Inactive';
}
} else {
$result[ $plugin ] = 'Not Installed';
$status[ $plugin ] = 'Not Installed';
}
}
return new \WP_REST_Response(
$result,
array(
'status' => $status,
'token' => Permissions::rest_get_plugin_install_hash()
),
200
);
}
Expand Down
23 changes: 9 additions & 14 deletions src/components/AdvancedFeatures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import useSWR from "swr";
import { ReactComponent as Booking } from "../icons/booking.svg";
import { ReactComponent as CustomizeAccount } from "../icons/customize-account.svg";
import { ReactComponent as Filter } from "../icons/filter.svg";
Expand Down Expand Up @@ -81,17 +80,13 @@ const SuggestedPlugins = [
},
];

export function AdvancedFeatures(props) {
export function AdvancedFeatures({ plugins }) {
let [inprogressInstalls, setInstalls] = useState([]);
let {
data: pluginsOnSite,
error,
mutate: refreshPlugins,
} = useSWR("/newfold-ecommerce/v1/plugins/status");
if (!pluginsOnSite) {

if (plugins.status === undefined) {
return (
<div style={{ height: "100%", display: "grid", placeContent: "center" }}>
{error ? (
{plugins.errors ? (
<h2>
{__(
"There was an error while loading this information",
Expand All @@ -105,10 +100,10 @@ export function AdvancedFeatures(props) {
);
}
let installedPlugins = SuggestedPlugins.filter(
(pluginDef) => pluginsOnSite[pluginDef.slug] === "Active"
(pluginDef) => plugins.status?.[pluginDef.slug] === "Active"
);
let unavailablePlugins = SuggestedPlugins.filter(
(pluginDef) => pluginsOnSite[pluginDef.slug] !== "Active"
(pluginDef) => plugins.status?.[pluginDef.slug] !== "Active"
);
return (
<>
Expand All @@ -132,7 +127,7 @@ export function AdvancedFeatures(props) {
title={plugin.title}
action={__("Enable", "wp-module-ecommerce")}
status={
inprogressInstalls.includes(plugin.slug) || props.token === undefined
inprogressInstalls.includes(plugin.slug)
? "inprogress"
: "ready"
}
Expand All @@ -142,9 +137,9 @@ export function AdvancedFeatures(props) {
if (plugin.sync === true) {
await syncPluginInstall(plugin.name);
} else {
await queuePluginInstall(plugin.name, props.token);
await queuePluginInstall(plugin.name, plugins.token);
}
await refreshPlugins();
await plugins.refresh();
setInstalls(
inprogressInstalls.filter((_) => _ !== plugin.slug)
);
Expand Down
13 changes: 6 additions & 7 deletions src/components/CustomizeStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ReactComponent as Account } from "../icons/account.svg";
import { ReactComponent as Contact } from "../icons/contactpage.svg";
import { ReactComponent as Home } from "../icons/homepage.svg";
import { ReactComponent as StoreLayout } from "../icons/storelayout.svg";
import { queuePluginInstall } from "../services";
import { Endpoints, queuePluginInstall } from "../services";
import { Card } from "./Card";
import { DashboardContent } from "./DashboardContent";

Expand All @@ -23,9 +23,8 @@ const CustomizeList = [
},
];

export function CustomizeStore(props) {
let { data: pluginsOnSite } = useSWR("/newfold-ecommerce/v1/plugins/status");
let { data: status } = useSWR("/newfold-ecommerce/v1/user/page-status");
export function CustomizeStore({ plugins }) {
let { data: status } = useSWR(Endpoints.PAGE_STATUS);
let { pages, theme } = status ?? {};
let pagesByName = Object.fromEntries(
pages?.map((_) => [_["meta_value"], _["ID"]]) ?? []
Expand Down Expand Up @@ -78,12 +77,12 @@ export function CustomizeStore(props) {
title={__("Customer Account Page", "wp-module-ecommerce")}
action={__("Setup", "wp-module-ecommerce")}
data-action-gutter={"s"}
status={pluginsOnSite ? "ready" : "inprogress"}
status={plugins.status !== undefined ? "ready" : "inprogress"}
onClick={async () => {
if (pluginsOnSite.yith_wcmap_panel !== "Active") {
if (plugins.status?.yith_wcmap_panel !== "Active") {
await queuePluginInstall(
"nfd_slug_yith_woocommerce_customize_myaccount_page",
props.token
plugins.token
);
}
window.location.href = "admin.php?page=yith_wcmap_panel";
Expand Down
9 changes: 4 additions & 5 deletions src/components/Dashboard.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { __ } from "@wordpress/i18n";
import useSWR from "swr";
import { AdvancedFeatures } from "./AdvancedFeatures";
import { CustomizeStore } from "./CustomizeStore";
import { GeneralSettings } from "./GeneralSettings";
Expand Down Expand Up @@ -38,10 +37,10 @@ const guideSteps = [
export function Dashboard(props) {
let { key, StepContent } =
guideSteps.find((step) => step.key === props.section) ?? guideSteps[0];
let { data: token } = useSWR("/newfold-ecommerce/v1/plugins/verification");
useSetupYITHWonderTheme();
let isCleanUpInProgress = useOnboardingCleanup(props.token);
let className = `nfd-ecommerce-dashboard ${props.state.wp?.isWooActive !== 1 ? 'disableDashboardContent' : ''}` ;
let isCleanUpInProgress = useOnboardingCleanup(props.plugins.token?.hash);
let addCurtain = props.plugins?.status?.woocommerce !== 'Active';
let className = `nfd-ecommerce-dashboard ${addCurtain ? 'disableDashboardContent' : ''}` ;
return (
<div className={className}>
<nav
Expand All @@ -66,7 +65,7 @@ export function Dashboard(props) {
<div className="bwa-loader" />
</div>
) : (
<StepContent token={token} {...props} />
<StepContent {...props} />
)}
</div>
</div>
Expand Down
20 changes: 12 additions & 8 deletions src/components/WooCommerceUnavailable.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { __ } from "@wordpress/i18n";
import { useState } from "@wordpress/element";
import { ReactComponent as WCUnAvailableIllustaration } from "../icons/wc-unavailable-illustration.svg";
import { syncPluginInstall } from "../services";
import { queuePluginInstall, syncPluginInstall } from "../services";

export function WooCommerceUnavailable({ wpModules }) {
export function WooCommerceUnavailable({ wpModules, plugins }) {
let { Modal } = wpModules;
let [installationFailed, setInstallationFailed] = useState(false);
let [isInstalling, setIsInstalling] = useState(false);

async function installWooCommerce() {
setIsInstalling(true);
let resposne = await syncPluginInstall("woocommerce");
let response =
plugins.status?.woocommerce === 'Inactive'
? await queuePluginInstall('woocommerce', plugins.token)
: await syncPluginInstall('woocommerce');
setIsInstalling(false);
if (resposne == "Failed") {
if (response === 'failed') {
setInstallationFailed(true);
} else {
await plugins.refresh();
window.location.reload();
}
}
Expand All @@ -31,11 +35,11 @@ export function WooCommerceUnavailable({ wpModules }) {
<h1>{__(" We hit a snag...", "wp-module-ecommerce")}</h1>
<span style={{ marginTop: "48px" }}>
{__(
"We'are sorry, but there was an error installing WooCommerce, please try again.",
"We're sorry, but there was an error installing WooCommerce, please try again.",
"wp-module-ecommerce"
)}
</span>
<button onClick={installWooCommerce}>
<button disabled={plugins.token === undefined} onClick={installWooCommerce}>
{__("Try again", "wp-module-ecommerce")}
</button>
<span style={{ marginTop: "32px" }}>
Expand Down Expand Up @@ -63,8 +67,8 @@ export function WooCommerceUnavailable({ wpModules }) {
"wp-module-ecommerce"
)}
</div>
<button onClick={installWooCommerce}>
{isInstalling ? "Installing WooCommerce..." : "Install Woocommerce"}
<button disabled={isInstalling} onClick={installWooCommerce}>
{isInstalling ? "Installing WooCommerce..." : "Install WooCommerce"}
</button>
<a href="https://www.bluehost.com/contact" target="_blank">
{__("Contact Support", "wp-module-ecommerce")}
Expand Down
19 changes: 10 additions & 9 deletions src/components/useOnboardingCleanup.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ const isEmpty = (object) => Object.keys(object).length === 0;

const HighProductVolumes = ['11-100', '101-1000', '1000+'];

export function useOnboardingCleanup(token) {
export function useOnboardingCleanup(hash) {
let [cleanupStatus, setCleanupStatus] = useState(false);
let { data: flow, error: flowError } = useSWR('/newfold-onboarding/v1/flow');
let { data: settings, error: settingsError } = useSWR(Endpoints.WP_SETTINGS);
useEffect(async () => {
if (flow && settings && token) {
if (flow && settings && hash) {
setCleanupStatus(true);
let flowCheckpoint = flow.updatedAt ?? flow.createdAt;
let previousCheckpoint = Number(
Expand All @@ -40,32 +40,33 @@ export function useOnboardingCleanup(token) {
if (HighProductVolumes.includes(productInfo.product_count)) {
await queuePluginInstall(
'nfd_slug_yith_woocommerce_ajax_product_filter',
token
{ hash }
);
await syncPluginInstall('yith-woocommerce-ajax-search');
}
for (const product_type of productInfo.product_types) {
if (product_type === 'physical') {
await queuePluginInstall(
'nfd_slug_yith_shippo_shippings_for_woocommerce',
token
{ hash }
);
}
if (product_type === 'bookings') {
await queuePluginInstall(
'nfd_slug_yith_woocommerce_booking',
token
);
await queuePluginInstall('nfd_slug_yith_woocommerce_booking', {
hash,
});
}
}
await updateWPSettings({
'nfd-ecommerce-onboarding-check': String(flowCheckpoint),
});
} else {
setCleanupStatus(false);
}
}
if (flowError || settingsError) {
setCleanupStatus(false);
}
}, [flow, settings, token]);
}, [flow, settings, hash]);
return cleanupStatus;
}
38 changes: 33 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
import apiFetch from "@wordpress/api-fetch";
import { SWRConfig } from "swr";
import useSWR, { SWRConfig } from "swr";
import { Banner } from "./components/Banner";
import { Dashboard } from "./components/Dashboard";
import { WooCommerceUnavailable } from "./components/WooCommerceUnavailable";

const fetcher = (path) => apiFetch({ path });

window.NewfoldECommerce = function NewfoldECommerce(props) {
let {
data,
error,
mutate: refreshPlugins,
} = useSWR("/newfold-ecommerce/v1/plugins/status", fetcher, {
revalidateOnReconnect: false,
});
let plugins = {
errors: error,
...(data ?? {}),
refresh: refreshPlugins,
};
let Hero =
props.state.wp?.isWooActive === 1 ? Banner : WooCommerceUnavailable;
plugins.status?.woocommerce === "Active" ? Banner : WooCommerceUnavailable;
return (
<SWRConfig value={{ fetcher, revalidateOnReconnect: false }}>
<SWRConfig
value={{
fetcher,
revalidateOnReconnect: false,
isPaused: () => plugins.status?.woocommerce !== "Active",
}}
>
<div className="nfd-ecommerce-atoms nfd-ecommerce-setup">
<Hero {...props} />
<Dashboard {...props} />
{data === undefined ? (
<div
style={{ height: "100%", display: "grid", placeContent: "center" }}
>
<div className="bwa-loader" />
</div>
) : (
<>
<Hero plugins={plugins} {...props} />
<Dashboard plugins={plugins} {...props} />
</>
)}
</div>
</SWRConfig>
);
Expand Down
4 changes: 2 additions & 2 deletions src/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export async function syncPluginInstall(slug) {
path: Endpoints.PLUGIN_SYNC_INSTALL,
method: 'POST',
data: { slug, status: 'active' },
}).catch((error) => {return 'Failed'});
}).catch((error) => 'failed');
}

export async function queuePluginInstall(plugin, token) {
Expand All @@ -39,5 +39,5 @@ export async function queuePluginInstall(plugin, token) {
method: 'POST',
headers: { 'X-NFD-ONBOARDING': token.hash },
data: { plugin, activate: true, queue: true },
}).catch((error) => {});
}).catch((error) => 'failed');
}

0 comments on commit 14d5178

Please sign in to comment.