Jake Vanderwerf
2026-02-10 ad052f72a6c994dfb2fe0aa11970c9d110564004
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
namespace JVBase\managers\SEO\schemas\resolvers;
 
use JVBase\managers\SEO\schemas\SchemaDefinition;
use JVBase\meta\Meta;
 
if (!defined('ABSPATH')) {
    exit;
}
 
/**
 * Resolver for FAQPage schema.
 *
 * Handles two contexts:
 * - Single post: transforms question/answer into mainEntity Question structure
 * - Archive/term: delegates to CollectionPageResolver for mainEntity from posts
 */
class FAQPageResolver extends BaseResolver
{
    private CollectionPageResolver $collectionResolver;
 
    public function __construct()
    {
        $this->collectionResolver = new CollectionPageResolver();
    }
 
    public function resolve(SchemaDefinition $definition, ?Meta $meta = null): ?array
    {
        // Single FAQ post: restructure question/answer into mainEntity
        if ($definition->objectType === 'post') {
            $this->transformQuestionAnswer($definition);
        }
 
        return parent::resolve($definition, $meta);
    }
 
    public function getAutoFields(SchemaDefinition $definition): array
    {
        // Archive/term context: delegate to CollectionPageResolver
        if (in_array($definition->objectType, ['archive', 'term'])) {
            return $this->collectionResolver->getAutoFields($definition);
        }
 
        return [];
    }
 
    /**
     * Transform question/answer into proper mainEntity structure.
     *
     * Schema.org requires FAQPage Q&A nested as:
     *   mainEntity: [{ @type: Question, name: ..., acceptedAnswer: { @type: Answer, text: ... } }]
     */
    private function transformQuestionAnswer(SchemaDefinition $definition): void
    {
        $question = $definition->config['question'] ?? null;
        $answer   = $definition->config['answer'] ?? null;
 
        if (!$question && !$answer) {
            return;
        }
 
        unset($definition->config['question'], $definition->config['answer']);
 
        $questionEntity = ['@type' => 'Question', 'name' => $question ?? ''];
 
        if ($answer) {
            $questionEntity['acceptedAnswer'] = [
                '@type' => 'Answer',
                'text'  => $answer,
            ];
        }
 
        $definition->config['mainEntity'] = [$questionEntity];
    }
}