Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 6
CRAP
n/a
0 / 0
wpme_dec2sixtwo
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
wpme_get_shortlink
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
342
wpme_get_shortlink_handler
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wpme_rest_register_shortlinks
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
wpme_rest_get_shortlink
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
wpme_set_extension_available
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Module Name: WP.me Shortlinks
4 * Module Description: Share short, easy-to-remember links to your posts and pages.
5 * Sort Order: 8
6 * First Introduced: 1.1
7 * Requires Connection: Yes
8 * Auto Activate: No
9 * Module Tags: Social
10 * Feature: Writing
11 * Additional Search Queries: shortlinks, wp.me
12 *
13 * @package automattic/jetpack
14 */
15
16if ( ! defined( 'ABSPATH' ) ) {
17    exit( 0 );
18}
19
20add_filter( 'pre_get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
21
22if ( ! function_exists( 'wpme_dec2sixtwo' ) ) {
23    /**
24     * Converts number to base 62.
25     *
26     * @param int $num Number.
27     *
28     * @return string Value in base 62.
29     */
30    function wpme_dec2sixtwo( $num ) {
31        $index = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
32        $out   = '';
33
34        if ( $num < 0 ) {
35            $out = '-';
36            $num = abs( $num );
37        }
38
39        for ( $t = floor( log10( $num ) / log10( 62 ) ); $t >= 0; $t-- ) {
40            $a   = (int) floor( $num / pow( 62, $t ) );
41            $out = $out . substr( $index, $a, 1 );
42            $num = $num - ( $a * pow( 62, $t ) );
43        }
44
45        return $out;
46    }
47}
48
49/**
50 * Returns the WP.me shortlink.
51 *
52 * @param int    $id Post ID, or 0 for the current post.
53 * @param string $context The context for the link. One of 'post' or 'query'.
54 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
55 *
56 * @return string
57 */
58function wpme_get_shortlink( $id = 0, $context = 'post', $allow_slugs = true ) {
59    global $wp_query;
60
61    $blog_id = Jetpack_Options::get_option( 'id' );
62
63    if ( 'query' === $context ) {
64        if ( is_singular() ) {
65            $id      = $wp_query->get_queried_object_id();
66            $context = 'post';
67        } elseif ( is_front_page() ) {
68            $context = 'blog';
69        } else {
70            return '';
71        }
72    }
73
74    if ( 'blog' === $context ) {
75        if ( empty( $id ) ) {
76            $id = $blog_id;
77        }
78
79        return 'https://wp.me/' . wpme_dec2sixtwo( $id );
80    }
81
82    $post = get_post( $id );
83
84    if ( empty( $post ) ) {
85            return '';
86    }
87
88    $post_id = $post->ID;
89    $type    = '';
90
91    if ( $allow_slugs && 'publish' === $post->post_status && 'post' === $post->post_type && strlen( $post->post_name ) <= 8 && ! str_contains( $post->post_name, '%' )
92        && ! str_contains( $post->post_name, '-' ) ) {
93        $id   = $post->post_name;
94        $type = 's';
95    } else {
96        $id = wpme_dec2sixtwo( $post_id );
97        if ( 'page' === $post->post_type ) {
98            $type = 'P';
99        } elseif ( 'post' === $post->post_type || post_type_supports( $post->post_type, 'shortlinks' ) ) {
100            $type = 'p';
101        } elseif ( 'attachment' === $post->post_type ) {
102            $type = 'a';
103        }
104    }
105
106    if ( empty( $type ) ) {
107        return '';
108    }
109
110    return 'https://wp.me/' . $type . wpme_dec2sixtwo( $blog_id ) . '-' . $id;
111}
112
113/**
114 * Get the shortlink handler.
115 *
116 * Used with the Core pre_get_shortlink hook.
117 *
118 * @param string $shortlink Shortlink value from the action. Ignored.
119 * @param int    $id Post ID (0 for the current post).
120 * @param string $context The context for the link. One of 'post' or 'query'.
121 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
122 *
123 * @return string
124 */
125function wpme_get_shortlink_handler( $shortlink, $id, $context, $allow_slugs ) {
126    return wpme_get_shortlink( $id, $context, $allow_slugs );
127}
128
129/**
130 * Add Shortlinks to the REST API responses.
131 *
132 * @since 6.9.0
133 *
134 * @action rest_api_init
135 * @uses register_rest_field, wpme_rest_get_shortlink
136 */
137function wpme_rest_register_shortlinks() {
138    // Post types that support shortlinks by default.
139    $supported_post_types = array(
140        'attachment',
141        'page',
142        'post',
143    );
144
145    // Add any CPT that may have declared support for shortlinks.
146    foreach ( get_post_types() as $post_type ) {
147        if (
148            post_type_supports( $post_type, 'shortlinks' )
149            && post_type_supports( $post_type, 'editor' )
150        ) {
151            $supported_post_types[] = $post_type;
152        }
153    }
154
155    register_rest_field(
156        $supported_post_types,
157        'jetpack_shortlink',
158        array(
159            'get_callback'    => 'wpme_rest_get_shortlink',
160            'update_callback' => null,
161            'schema'          => null,
162        )
163    );
164}
165
166/**
167 * Get the shortlink of a post.
168 *
169 * @since 6.9.0
170 *
171 * @param array $object Details of current post.
172 *
173 * @uses wpme_get_shortlink
174 *
175 * @return string
176 */
177function wpme_rest_get_shortlink( $object ) {
178    $object_id = $object['id'] ?? 0;
179    return wpme_get_shortlink( $object_id, array() );
180}
181
182// Add shortlinks to the REST API Post response.
183add_action( 'rest_api_init', 'wpme_rest_register_shortlinks' );
184
185/**
186 * Set the Shortlink Gutenberg extension as available.
187 */
188function wpme_set_extension_available() {
189    Jetpack_Gutenberg::set_extension_available( 'shortlinks' );
190}
191
192add_action( 'init', 'wpme_set_extension_available' );