| @@ -211,15 +211,8 @@ | ||
| 211 | 211 | 'ajaxUrl' => admin_url('admin-ajax.php'), |
| 212 | 212 | 'adminUrl' => admin_url(), |
| 213 | 213 | 'sourceNonce' => wp_create_nonce('source_nonce_embedpress'), |
| 214 | 214 | 'canUploadMedia' => current_user_can('upload_files'), |
| 215 | - // Google Reviews: the saved-places library is a SINGLE SITE-WIDE | |
| 216 | - // store, so both verbs of /google-reviews/places are gated on | |
| 217 | - // manage_options (see GoogleReviewsRestController's authz notes). | |
| 218 | - // The picker needs to know that BEFORE it offers to add a place — | |
| 219 | - // without this flag a non-admin gets a working search, a dead | |
| 220 | - // "+ Select", and a 403 with nothing on screen to explain it. | |
| 221 | - 'canManageGoogleReviewPlaces' => current_user_can('manage_options'), | |
| 222 | 215 | 'pdfGalleryNonce' => wp_create_nonce('ep_pdf_gallery_nonce'), |
| 223 | 216 | 'assetsUrl' => $assets_url, |
| 224 | 217 | 'staticUrl' => $static_url, |
| 225 | 218 | // Use underscore naming for consistency with block attributes |
| @@ -563,19 +556,9 @@ | ||
| 563 | 556 | * @return string |
| 564 | 557 | */ |
| 565 | 558 | private static function get_analytics_session_id() |
| 566 | 559 | { |
| 567 | - // Read-only. The analytics tracker (assets/js/analytics-tracker.js) | |
| 568 | - // owns this cookie and mints it client-side via getOrCreateSessionId(). | |
| 569 | - // | |
| 570 | - // Setting it here server-side put a Set-Cookie header on every anonymous | |
| 571 | - // HTML response, which Cloudflare and every other CDN treat as a signal | |
| 572 | - // that the response is personalised — they return cf-cache-status: BYPASS | |
| 573 | - // and the site loses its entire edge cache. See #286. | |
| 574 | - // | |
| 575 | - // Reading a cookie is cache-safe; only setting one is not. So we surface | |
| 576 | - // the id when the browser already has one and return '' otherwise, rather | |
| 577 | - // than minting a value that nothing consumes. | |
| 560 | + // Prefer cookie-based session IDs to avoid server PHP session configuration issues | |
| 578 | 561 | if (isset($_COOKIE['ep_session_id'])) { |
| 579 | 562 | $cookie = $_COOKIE['ep_session_id']; |
| 580 | 563 | // Allow only safe characters and a minimum length |
| 581 | 564 | if (is_string($cookie) && preg_match('/^[A-Za-z0-9._:-]{8,}$/', $cookie)) { |
| @@ -582,9 +565,36 @@ | ||
| 582 | 565 | return sanitize_text_field($cookie); |
| 583 | 566 | } |
| 584 | 567 | } |
| 585 | 568 | |
| 586 | - return ''; | |
| 569 | + // Generate a new ephemeral session ID | |
| 570 | + $id = 'ep-sess-' . time() . '-' . wp_generate_password(8, false); | |
| 571 | + | |
| 572 | + // Set a session cookie (expires when the browser closes). | |
| 573 | + // Build the Set-Cookie header manually so we can add SameSite=Lax while | |
| 574 | + // staying compatible with PHP 5.6+ (the options-array form of setcookie() | |
| 575 | + // requires PHP 7.3). HttpOnly is intentionally omitted: the analytics | |
| 576 | + // tracker reads ep_session_id via document.cookie to deduplicate views | |
| 577 | + // within a session, so the cookie must be JS-readable. | |
| 578 | + if (!headers_sent()) { | |
| 579 | + $path = defined('COOKIEPATH') ? COOKIEPATH : '/'; | |
| 580 | + $domain = (defined('COOKIE_DOMAIN') && COOKIE_DOMAIN) ? COOKIE_DOMAIN : ''; | |
| 581 | + $secure = is_ssl(); | |
| 582 | + | |
| 583 | + $cookie = 'ep_session_id=' . rawurlencode($id) | |
| 584 | + . '; path=' . ($path ? $path : '/') | |
| 585 | + . '; SameSite=Lax'; | |
| 586 | + if ($domain) { | |
| 587 | + $cookie .= '; domain=' . $domain; | |
| 588 | + } | |
| 589 | + if ($secure) { | |
| 590 | + $cookie .= '; Secure'; | |
| 591 | + } | |
| 592 | + | |
| 593 | + header('Set-Cookie: ' . $cookie, false); | |
| 594 | + } | |
| 595 | + | |
| 596 | + return $id; | |
| 587 | 597 | } |
| 588 | 598 | |
| 589 | 599 | /** |
| 590 | 600 | * Get URL schemes for preview script |