PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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.63.2.1 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()`.