| @@ -369,8 +369,27 @@ | ||
| 369 | 369 | return is_string($template) && $template !== '' ? $template : $fallback; |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | /** |
| 373 | + * Whether the post's content is behind a password for this request. | |
| 374 | + * | |
| 375 | + * The same test SEO_Manager uses for the Global SEO path (#363), guarded | |
| 376 | + * because this class is also exercised outside a front-end request. | |
| 377 | + * | |
| 378 | + * @since 2.15.0 | |
| 379 | + * | |
| 380 | + * @param \WP_Post $post Post. | |
| 381 | + * @return bool | |
| 382 | + */ | |
| 383 | + private static function is_password_required(\WP_Post $post): bool { | |
| 384 | + if ('' === (string) $post->post_password) { | |
| 385 | + return false; | |
| 386 | + } | |
| 387 | + | |
| 388 | + return !function_exists('post_password_required') || post_password_required($post); | |
| 389 | + } | |
| 390 | + | |
| 391 | + /** | |
| 373 | 392 | * Build placeholder values for an explicit post (no loop dependency). |
| 374 | 393 | * |
| 375 | 394 | * @param int $post_id Post ID. |
| 376 | 395 | * @return array<string,string> Placeholder map. |
| @@ -377,13 +396,21 @@ | ||
| 377 | 396 | */ |
| 378 | 397 | private static function placeholders_for(int $post_id): array { |
| 379 | 398 | $post = get_post($post_id); |
| 380 | 399 | |
| 400 | + // An authored excerpt is written for public consumption, so it stays. | |
| 401 | + // The body is not: deriving %excerpt% from a protected post's body put | |
| 402 | + // the gated text into the title, meta, og/twitter tags and JSON-LD of | |
| 403 | + // the page that asks for the password. The Global SEO path closed this | |
| 404 | + // in #363; the per-post templates resolve here, so the same rule | |
| 405 | + // applies here too (#973). | |
| 381 | 406 | $excerpt = ''; |
| 382 | 407 | if ($post) { |
| 383 | - $excerpt = !empty($post->post_excerpt) | |
| 384 | - ? $post->post_excerpt | |
| 385 | - : self::derive_excerpt(Builder_Content::visible_content($post)); | |
| 408 | + if (!empty($post->post_excerpt)) { | |
| 409 | + $excerpt = $post->post_excerpt; | |
| 410 | + } elseif (!self::is_password_required($post)) { | |
| 411 | + $excerpt = self::derive_excerpt(Builder_Content::visible_content($post)); | |
| 412 | + } | |
| 386 | 413 | } |
| 387 | 414 | |
| 388 | 415 | $author_id = (int) get_post_field('post_author', $post_id); |
| 389 | 416 | |
| @@ -576,9 +603,9 @@ | ||
| 576 | 603 | $value |
| 577 | 604 | ); |
| 578 | 605 | |
| 579 | 606 | // Strip leading/trailing separators and whitespace. |
| 580 | - return trim($value, " \t\n\r\0\x0B" . $separator); | |
| 607 | + return \ThinkRank\Core\Seo_Text::trim_separator($value, $separator); | |
| 581 | 608 | } |
| 582 | 609 | |
| 583 | 610 | /** |
| 584 | 611 | * Remove any token the placeholder map did not resolve. |