PluginProbe
Extendify / trunk
Extendify vtrunk
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
← All changes | app/AdminPageRouter.php +75 -45 3.0.5 → trunk View file →
@@ -193,9 +193,10 @@
193 193 $useAgentOnboarding = PartnerData::setting('useAgentOnboarding') ||
194 194 Config::preview('agent-onboarding') ||
195 195 constant('EXTENDIFY_DEVMODE');
196 196 $page = $useAgentOnboarding ? 'extendify-auto-launch' : 'extendify-launch';
197 - \wp_safe_redirect(\admin_url('admin.php?page=' . $page));
197 + $query_params = $this->presentLaunchParams(['page' => $page]);
198 + \wp_safe_redirect(\add_query_arg($query_params, \admin_url('admin.php')));
198 199 exit;
199 200 }
200 201
201 202 // If they have the Agent onboarding enabled, redirect to home.
@@ -214,8 +215,10 @@
214 215
215 216 /**
216 217 * Redirect once to Launch, only once (at least once) when
217 218 * the email matches the entry in WP Admin > Settings > General.
219 + * Requests carrying a build-id keep redirecting until onboarding
220 + * completes.
218 221 *
219 222 * @return void
220 223 */
221 224 public function redirectOnce()
@@ -227,12 +230,21 @@
227 230 if (defined('EXTENDIFY_IS_THEME_EXTENDABLE') && !EXTENDIFY_IS_THEME_EXTENDABLE) {
228 231 return;
229 232 }
230 233
231 - if (\get_option('extendify_launch_loaded', false) || !Config::$showLaunch) {
234 + // Partner preview links must work on every admin visit, not just the first.
235 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
236 + $buildIdRedirect = !empty(sanitize_text_field(wp_unslash($_GET['build-id'] ?? '')))
237 + && !Config::$launchCompleted;
238 +
239 + if (!$buildIdRedirect && \get_option('extendify_launch_loaded', false)) {
232 240 return;
233 241 }
234 242
243 + if (!Config::$showLaunch) {
244 + return;
245 + }
246 +
235 247 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
236 248 if (isset($_GET['page']) && $_GET['page'] === 'extendify-auto-launch') {
237 249 return;
238 250 }
@@ -243,19 +255,27 @@
243 255 $agentOnboarding = PartnerData::setting('useAgentOnboarding') ||
244 256 Config::preview('agent-onboarding') ||
245 257 constant('EXTENDIFY_DEVMODE');
246 258 if ($agentOnboarding) {
247 - // If they landed on launch but have the Agent onboarding enabled, redirect to auto-launch.
248 - $redirect_url = \add_query_arg(
249 - ['page' => 'extendify-auto-launch'],
250 - \admin_url('admin.php')
251 - );
252 - \wp_safe_redirect($redirect_url);
259 + // If they landed on launch but have the Agent onboarding enabled, redirect to
260 + // auto-launch — carrying their deep-link params, which a bare page-only redirect drops.
261 + $query_params = $this->presentLaunchParams(['page' => 'extendify-auto-launch']);
262 + \wp_safe_redirect(\add_query_arg($query_params, \admin_url('admin.php')));
253 263 exit;
254 264 }
255 265 return;
256 266 }
257 267
268 + if ($buildIdRedirect) {
269 + \update_option('permalink_structure', '/%postname%/');
270 + \update_option('extendify_needs_rewrite_flush', true);
271 +
272 + // Only AutoLaunch consumes build-id.
273 + $query_params = $this->presentLaunchParams(['page' => 'extendify-auto-launch']);
274 + \wp_safe_redirect(\add_query_arg($query_params, \admin_url('admin.php')));
275 + exit;
276 + }
277 +
258 278 $user = \wp_get_current_user();
259 279 if (
260 280 $user
261 281 // Check the main admin email, and they have an admin role.
@@ -274,52 +294,62 @@
274 294 // Update permalink structure to postname when auto-redirecting to Launch
275 295 \update_option('permalink_structure', '/%postname%/');
276 296 \update_option('extendify_needs_rewrite_flush', true);
277 297
278 - $allowed_launch_params = [
279 - 'objective',
280 - 'title',
281 - 'description',
282 - 'structure',
283 - 'tone',
284 - 'skip',
285 - // new for autolaunch (some duplicated)
286 - 'type',
287 - 'title',
288 - 'description',
289 - 'objective',
290 - 'category',
291 - 'structure',
292 - 'tone',
293 - 'products',
294 - 'appointments',
295 - 'events',
296 - 'donations',
297 - 'multilingual',
298 - 'contact',
299 - 'address',
300 - 'blog',
301 - 'landing-page',
302 - 'cta-link',
303 - 'build-id',
304 - 'go',
305 - ];
306 298 // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
307 299 $autoLaunch = isset($_GET['auto-launch']) && filter_var($_GET['auto-launch'], FILTER_VALIDATE_BOOLEAN);
308 - $query_params = ['page' => $autoLaunch ? 'extendify-auto-launch' : 'extendify-launch'];
300 + $query_params = $this->presentLaunchParams([
301 + 'page' => $autoLaunch ? 'extendify-auto-launch' : 'extendify-launch',
302 + ]);
309 303
310 - foreach ($allowed_launch_params as $param) {
311 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
312 - $value = sanitize_text_field(wp_unslash($_GET[$param] ?? ''));
313 - if (!empty($value)) {
314 - $query_params[$param] = $value;
315 - }
316 - }
317 -
318 304 $redirect_url = \add_query_arg($query_params, \admin_url('admin.php'));
319 305 \wp_safe_redirect($redirect_url);
320 306 exit;
321 307 }
308 + }
309 +
310 + /**
311 + * Merges the allowlisted launch deep-link params present in the request onto
312 + * $base, so a redirect into Launch/AutoLaunch carries the partner's params
313 + * through instead of dropping them.
314 + *
315 + * @param array $base Seed query args (typically the destination `page`).
316 + * @return array
317 + */
318 + private function presentLaunchParams(array $base)
319 + {
320 + $allowed = [
321 + 'objective',
322 + 'title',
323 + 'description',
324 + 'structure',
325 + 'tone',
326 + 'skip',
327 + 'type',
328 + 'category',
329 + 'products',
330 + 'appointments',
331 + 'events',
332 + 'donations',
333 + 'multilingual',
334 + 'contact',
335 + 'address',
336 + 'blog',
337 + 'landing-page',
338 + 'cta-link',
339 + 'build-id',
340 + 'go',
341 + ];
342 +
343 + foreach ($allowed as $param) {
344 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
345 + $value = sanitize_text_field(wp_unslash($_GET[$param] ?? ''));
346 + if (!empty($value)) {
347 + $base[$param] = $value;
348 + }
349 + }
350 +
351 + return $base;
322 352 }
323 353
324 354 /**
325 355 * Flushes WordPress rewrite rules if previously scheduled by `redirectOnce()`.