Skip to content

Commit b881385

Browse files
committed
Homepage publish logic
1 parent 47e5a44 commit b881385

File tree

8 files changed

+236
-25
lines changed

8 files changed

+236
-25
lines changed

includes/RestApi/AppController.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use NewfoldLabs\WP\Module\Onboarding\Permissions;
66
use NewfoldLabs\WP\Module\Onboarding\Services\AppService;
7-
use NewfoldLabs\WP\Module\Onboarding\Data\Config;
87

98
class AppController {
109

@@ -70,11 +69,21 @@ public function start(): \WP_REST_Response {
7069
/**
7170
* Complete onboarding backend process.
7271
*
72+
* @param \WP_REST_Request $request The request object.
7373
* @return \WP_REST_Response The response object.
7474
*/
75-
public function complete(): \WP_REST_Response {
75+
public function complete( \WP_REST_Request $request ): \WP_REST_Response {
76+
$data = json_decode( $request->get_body(), true );
77+
$selected_sitegen_homepage = $data['selected_sitegen_homepage'];
78+
if ( ! $selected_sitegen_homepage ) {
79+
return new \WP_REST_Response(
80+
array( 'error' => 'Selected sitegen homepage is required.' ),
81+
400
82+
);
83+
}
84+
7685
try {
77-
( new AppService() )->complete();
86+
( new AppService() )->complete( $selected_sitegen_homepage );
7887
return new \WP_REST_Response( array(), 200 );
7988
} catch ( \Exception $e ) {
8089
return new \WP_REST_Response(

includes/Services/AppService.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
namespace NewfoldLabs\WP\Module\Onboarding\Services;
44

5+
use NewfoldLabs\WP\Module\Onboarding\Data\Events;
56
use NewfoldLabs\WP\Module\Onboarding\Data\Options;
7+
use NewfoldLabs\WP\Module\Onboarding\Data\Services\PreviewsService;
8+
use NewfoldLabs\WP\Module\Onboarding\Data\Services\SiteGenService as LegacySiteGenService;
9+
10+
11+
use function NewfoldLabs\WP\ModuleLoader\container;
612

713
class AppService {
814

@@ -31,11 +37,35 @@ public function start(): void {
3137
}
3238
}
3339

34-
public function complete(): void {
35-
// Publish the header.
36-
// Publish the footer.
40+
/**
41+
* Complete onboarding.
42+
*
43+
* @param string $selected_sitegen_homepage The selected sitegen homepage to publish.
44+
* @return void
45+
* @throws \Exception
46+
*/
47+
public function complete( string $selected_sitegen_homepage ): void {
3748
// Publish selected homepage.
38-
// Set the color palette.
39-
// Trash preview posts.
49+
$result = ( new SiteGenService() )->publish_homepage( $selected_sitegen_homepage );
50+
if ( \is_wp_error( $result ) ) {
51+
throw new \Exception( $result->get_error_message() );
52+
}
53+
// Trash sample page and preview posts.
54+
LegacySiteGenService::trash_sample_page();
55+
PreviewsService::trash_preview_pages();
56+
57+
// Purge all caches.
58+
container()->get( 'cachePurger' )->purge_all();
59+
60+
// Create a survey to collect feedback.
61+
container()->get( 'survey' )->create_toast_survey(
62+
Events::get_category()[0] . '_sitegen_pulse',
63+
'customer_satisfaction_survey',
64+
array(
65+
'label_key' => 'value',
66+
),
67+
__( 'Help us improve', 'wp-module-onboarding-data' ),
68+
__( 'How satisfied were you with the ease of creating your website?', 'wp-module-onboarding-data' ),
69+
);
4070
}
4171
}

includes/Services/GlobalStylesService.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function set_color_palette( array $color_palette ): array|\WP_Error {
5555

5656
return $color_palette;
5757
} catch ( \Exception $e ) {
58-
return new \WP_Error( 'global_styles_error', $e->getMessage() );
58+
return new \WP_Error( 'set_color_palette_error', $e->getMessage() );
5959
}
6060
}
6161

@@ -107,13 +107,13 @@ protected function update_active_global_styles( ?array $post_content = null, ?in
107107
$post_id = $post_id ?? $this->global_styles_id;
108108
$post_content = $post_content ?? $this->global_styles;
109109

110-
$result = wp_update_post(
111-
array(
112-
'ID' => $post_id,
113-
'post_content' => wp_json_encode( $post_content ),
114-
),
115-
true
116-
);
110+
$result = wp_update_post( [
111+
'ID' => $post_id,
112+
'post_content' => wp_json_encode( $post_content ),
113+
], true );
114+
if ( is_wp_error( $result ) ) {
115+
return $result;
116+
}
117117

118118
wp_clean_theme_json_cache();
119119

includes/Services/SiteGenService.php

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?php
2+
3+
namespace NewfoldLabs\WP\Module\Onboarding\Services;
4+
5+
use NewfoldLabs\WP\Module\Onboarding\Data\Options;
6+
use NewfoldLabs\WP\Module\Onboarding\Data\Services\SitePagesService;
7+
use NewfoldLabs\WP\Module\Onboarding\Data\Services\SiteGenService as LegacySiteGenService;
8+
9+
class SiteGenService {
10+
11+
/**
12+
* The Redux input object.
13+
*
14+
* @var array|null
15+
*/
16+
private ?array $input_data = null;
17+
18+
/**
19+
* The Redux sitegen object.
20+
*
21+
* @var array|null
22+
*/
23+
private ?array $sitegen_data = null;
24+
25+
public function __construct() {
26+
$this->input_data = ReduxStateService::get( 'input' );
27+
$this->sitegen_data = ReduxStateService::get( 'sitegen' );
28+
}
29+
30+
/**
31+
* Publish the selected sitegen homepage.
32+
*
33+
* @param string $selected_sitegen_homepage The selected sitegen homepage to publish.
34+
* @return int|\WP_Error
35+
*/
36+
public function publish_homepage( string $selected_sitegen_homepage ): int | \WP_Error {
37+
// Validate we have the selected homepage.
38+
if (
39+
! $this->sitegen_data ||
40+
! is_array( $this->sitegen_data['homepages'] ) ||
41+
! isset( $this->sitegen_data['homepages'][ $selected_sitegen_homepage ] )
42+
) {
43+
return new \WP_Error(
44+
'sitegen_homepage_publish_validation_error',
45+
'Error validating selected homepage.',
46+
);
47+
}
48+
49+
$selected_homepage = $this->sitegen_data['homepages'][ $selected_sitegen_homepage ];
50+
// Always set the default homepage to a page.
51+
$show_pages_on_front = \get_option( Options::get_option_name( 'show_on_front', false ) );
52+
if ( 'posts' === $show_pages_on_front ) {
53+
\update_option( Options::get_option_name( 'show_on_front', false ), 'page' );
54+
}
55+
56+
$content = $selected_homepage['content'];
57+
$title = __( 'Home', 'wp-module-onboarding' );
58+
59+
$post_id = SitePagesService::publish_page(
60+
$title,
61+
$content,
62+
true,
63+
array(
64+
'nf_dc_page' => 'home',
65+
)
66+
);
67+
if ( 0 === $post_id || is_wp_error( $post_id ) ) {
68+
return new \WP_Error(
69+
'sitegen_homepage_publish_error',
70+
'Error publishing homepage.',
71+
);
72+
}
73+
74+
// Add the homepage to the site navigation.
75+
$this->add_page_to_navigation( $post_id, $title, get_permalink( $post_id ) );
76+
77+
// Set the homepage as the front page.
78+
\update_option( Options::get_option_name( 'page_on_front', false ), $post_id );
79+
80+
return $post_id;
81+
}
82+
83+
/**
84+
* Get AI generated page title for a given slug (if found in sitemap).
85+
*
86+
* @param string $slug The slug of the page to get the title for.
87+
* @return string|false The page title, or false if not found.
88+
*/
89+
public function get_sitemap_page_title( string $slug ): string|false {
90+
$prompt = $this->get_prompt();
91+
$locale = $this->get_locale();
92+
if ( ! $prompt || ! $locale ) {
93+
return false;
94+
}
95+
96+
$sitemap = LegacySiteGenService::instantiate_site_meta( $prompt, 'sitemap', $locale );
97+
if ( ! is_wp_error( $sitemap ) ) {
98+
foreach ( $sitemap as $page ) {
99+
if ( $slug === $page['slug'] ) {
100+
$title = $page['title'];
101+
return $title;
102+
}
103+
}
104+
}
105+
106+
return false;
107+
}
108+
109+
/**
110+
* Add a page to the site navigation.
111+
*
112+
* @param int $post_id The ID of the page to add to the navigation.
113+
* @param string $page_title The title of the page.
114+
* @param string $permalink The permalink of the page.
115+
*/
116+
public function add_page_to_navigation( int $post_id, string $page_title, string $permalink ): void {
117+
$id = $post_id;
118+
$label = $page_title;
119+
$url = $permalink;
120+
121+
$nav_link_grammar = "<!-- wp:navigation-link {\"label\":\"$label\",\"type\":\"page\",\"id\":$id,\"url\":\"$url\",\"kind\":\"post-type\"} /-->";
122+
123+
$navigation = new \WP_Query(
124+
array(
125+
'name' => 'navigation',
126+
'post_type' => 'wp_navigation',
127+
)
128+
);
129+
if ( ! empty( $navigation->posts ) ) {
130+
wp_update_post(
131+
array(
132+
'ID' => $navigation->posts[0]->ID,
133+
'post_content' => $nav_link_grammar . $navigation->posts[0]->post_content,
134+
)
135+
);
136+
}
137+
}
138+
139+
/**
140+
* Get the prompt entered during Onboarding.
141+
*
142+
* @return string|false
143+
*/
144+
public function get_prompt(): string|false {
145+
return ! empty( $this->input_data['prompt'] ) ? $this->input_data['prompt'] : false;
146+
}
147+
148+
/**
149+
* Get the locale entered during Onboarding.
150+
*
151+
* @return string
152+
*/
153+
public function get_locale(): string {
154+
return ! empty( $this->input_data['locale'] ) ? $this->input_data['locale'] : 'en_US';
155+
}
156+
}

src/app/data/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const wpAdminPage = addQueryArgs(
1616
window.nfdOnboarding.runtime.currentBrand?.dashboardRedirectParams
1717
);
1818
export const wpEditorPage = `${ wpAdminUrl }site-editor.php?canvas=edit`;
19+
export const wpEditorDesignStudio = `${ wpAdminUrl }site-editor.php?referrer=nfd-onboarding&canvas=edit`;
1920
export const pluginDashboardPage =
2021
addQueryArgs(
2122
window.nfdOnboarding.runtime.currentBrand?.pluginDashboardPage,

src/app/steps/Canvas/HeaderActions.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import { RectangleStackIcon as RectangleStackIconSolid } from '@heroicons/react/
55
import { InteractionBlockingOverlay } from '@/components';
66
import { nfdOnboardingStore } from '@/data/store';
77
import { usePublishSite } from '@/utils/hooks';
8-
import { OnboardingEvent, trackOnboardingEvent } from '@/utils/analytics/hiive';
9-
import { ACTION_CANVAS_CUSTOMIZE_SELECTED, ACTION_CANVAS_PUBLISH_SELECTED } from '@/utils/analytics/hiive/constants';
8+
import { OnboardingEvent, sendOnboardingEvent } from '@/utils/analytics/hiive';
9+
import { ACTION_ONBOARDING_COMPLETE } from '@/utils/analytics/hiive/constants';
10+
import { pluginDashboardPage, wpEditorDesignStudio } from '@/data/constants';
1011

1112
const HeaderActions = () => {
1213
const [ isPublishing, setIsPublishing ] = useState( false );
@@ -34,23 +35,33 @@ const HeaderActions = () => {
3435
const handleSelectAndCustomize = async () => {
3536
await handlePublishSite();
3637

37-
trackOnboardingEvent(
38-
new OnboardingEvent( ACTION_CANVAS_CUSTOMIZE_SELECTED )
38+
sendOnboardingEvent(
39+
new OnboardingEvent( ACTION_ONBOARDING_COMPLETE, 'select_and_customize', {
40+
source: 'quickstart',
41+
} )
3942
);
43+
44+
// Send to the Design Studio.
45+
window.location.replace( wpEditorDesignStudio );
4046
};
4147

4248
const handleSaveAndPublish = async () => {
4349
await handlePublishSite();
4450

45-
trackOnboardingEvent(
46-
new OnboardingEvent( ACTION_CANVAS_PUBLISH_SELECTED )
51+
sendOnboardingEvent(
52+
new OnboardingEvent( ACTION_ONBOARDING_COMPLETE, 'save_and_publish', {
53+
source: 'quickstart',
54+
} )
4755
);
56+
57+
// Send to the Plugin Dashboard.
58+
window.location.replace( pluginDashboardPage );
4859
};
4960

5061
return (
5162
<div className="nfd-onboarding-canvas-header-actions nfd-flex nfd-gap-4">
5263
{ isPublishing && (
53-
<InteractionBlockingOverlay
64+
<InteractionBlockingOverlay
5465
hasLoadingSpinner={ true }
5566
hasBackground={ isPublishing }
5667
/>

src/app/utils/api/onboarding.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ export const startOnboarding = async ( data = {} ) => {
4545
);
4646
};
4747

48-
export const completeOnboarding = async ( data = {} ) => {
48+
export const completeOnboarding = async ( selectedSitegenHomepage ) => {
4949
return await resolve(
5050
apiFetch( {
5151
url: onboardingRestURL( 'app/complete' ),
5252
method: 'POST',
53-
body: JSON.stringify( data ),
53+
body: JSON.stringify( {
54+
selected_sitegen_homepage: selectedSitegenHomepage,
55+
} ),
5456
} ).then()
5557
);
5658
};

src/app/utils/hooks/usePublishSite.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useCallback } from '@wordpress/element';
22
import { useSelect } from '@wordpress/data';
33
import { nfdOnboardingStore } from '@/data/store';
4+
import { completeOnboarding } from '@/utils/api';
45
import { useTemplateParts, useGlobalStyles } from '.';
56

67
const usePublishSite = () => {
@@ -36,6 +37,7 @@ const usePublishSite = () => {
3637
updateHeader( homepages[ selectedHomepage ].header ),
3738
updateFooter( homepages[ selectedHomepage ].footer ),
3839
setColorPalette( selectedColorPalette ),
40+
completeOnboarding( selectedHomepage ),
3941
] );
4042

4143
return true;

0 commit comments

Comments
 (0)