Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
Schema_Node_Ids
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
6 / 6
6
100.00% covered (success)
100.00%
1 / 1
 organization
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 website
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 person
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 profile_page
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 site_anchor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 author_anchor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Stable Schema.org node `@id` helpers.
4 *
5 * Site-level nodes (Organization, WebSite, …) and page nodes (Article) live
6 * together in one `@graph` and cross-reference each other by `@id`. Those `@id`s
7 * must be stable URIs — the same across every page of the site — so references
8 * resolve and search engines can de-duplicate the entities. Centralizing them
9 * here keeps every node builder agreeing on the exact same strings.
10 *
11 * @package automattic/jetpack-seo-package
12 */
13
14namespace Automattic\Jetpack\SEO;
15
16/**
17 * Builds the canonical `@id` URIs used across the schema graph.
18 */
19class Schema_Node_Ids {
20
21    /**
22     * `@id` for the site-level Organization node.
23     *
24     * Anchored to the site root with a stable fragment, e.g.
25     * `https://example.com/#organization`, so the Article `publisher`
26     * reference resolves to the same entity on every page.
27     *
28     * @return string
29     */
30    public static function organization() {
31        return self::site_anchor( 'organization' );
32    }
33
34    /**
35     * `@id` for the site-level WebSite node.
36     *
37     * @return string
38     */
39    public static function website() {
40        return self::site_anchor( 'website' );
41    }
42
43    /**
44     * `@id` for an author's Person node.
45     *
46     * @param int    $user_id       User ID.
47     * @param string $user_nicename User nicename.
48     * @return string
49     */
50    public static function person( $user_id, $user_nicename ) {
51        return self::author_anchor( $user_id, $user_nicename, 'person' );
52    }
53
54    /**
55     * `@id` for an author's ProfilePage node.
56     *
57     * @param int    $user_id       User ID.
58     * @param string $user_nicename User nicename.
59     * @return string
60     */
61    public static function profile_page( $user_id, $user_nicename ) {
62        return self::author_anchor( $user_id, $user_nicename, 'profilepage' );
63    }
64
65    /**
66     * Build a stable site-root `@id` from a fragment name.
67     *
68     * @param string $fragment Fragment identifier (without the leading `#`).
69     * @return string
70     */
71    private static function site_anchor( $fragment ) {
72        // home_url( '/' ) is the canonical site root and already carries a trailing
73        // slash, giving fragments like `https://example.com/#organization`.
74        return home_url( '/' ) . '#' . $fragment;
75    }
76
77    /**
78     * Build a stable author-archive `@id` from a fragment name.
79     *
80     * @param int    $user_id       User ID.
81     * @param string $user_nicename User nicename.
82     * @param string $fragment      Fragment identifier (without the leading `#`).
83     * @return string
84     */
85    private static function author_anchor( $user_id, $user_nicename, $fragment ) {
86        return get_author_posts_url( (int) $user_id, $user_nicename ) . '#' . $fragment;
87    }
88}