PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta
16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-publicize / src / social-image-generator / class-setup.php
jetpack / jetpack_vendor / automattic / jetpack-publicize / src / social-image-generator Last commit date
class-post-settings.php 1 month ago class-rest-settings-controller.php 2 months ago class-rest-token-controller.php 2 months ago class-settings.php 3 months ago class-setup.php 3 weeks ago class-templates.php 3 years ago utilities.php 8 months ago
class-setup.php
209 lines
1 <?php
2 /**
3 * Setup class.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8 namespace Automattic\Jetpack\Publicize\Social_Image_Generator;
9
10 use Automattic\Jetpack\Publicize\Jetpack_Social_Settings\Settings;
11 use Automattic\Jetpack\Publicize\Publicize;
12
13 /**
14 * Class for setting up Social Image Generator-related functionality.
15 */
16 class Setup {
17 /**
18 * Initialise SIG-related functionality.
19 */
20 public function init() {
21 if ( ! ( new Settings() )->is_sig_available() ) {
22 return;
23 }
24
25 // Be wary of any code that you add to this file, since this function is called on plugin load.
26 // We're using the `wp_after_insert_post` hook because we need access to the updated post meta. By using the default priority
27 // of 10 we make sure that our code runs before Sync processes the post.
28 add_action( 'wp_after_insert_post', array( $this, 'generate_token_on_save' ), 10, 3 );
29 add_action( 'jetpack_social_sig_warm_image', array( $this, 'warm_social_image' ) );
30 add_action( 'rest_api_init', array( REST_Token_Controller::class, 'register' ) );
31
32 // Flagged to be removed after deprecation.
33 // @deprecated 0.38.3
34 add_action( 'rest_api_init', array( REST_Settings_Controller::class, 'register' ) );
35 }
36
37 /**
38 * Get a token from WPCOM to generate the social image for the post, and save it locally.
39 *
40 * @param Post_Settings $post_settings A Post_Settings object that can be used to save the generated token.
41 */
42 public function generate_token( $post_settings ) {
43 if ( ! $post_settings->is_enabled() ) {
44 return;
45 }
46
47 $token = fetch_token(
48 $post_settings->get_custom_text(),
49 $post_settings->get_image_url(),
50 $post_settings->get_template(),
51 $post_settings->get_font()
52 );
53
54 if ( is_wp_error( $token ) ) {
55 return;
56 }
57
58 $post_settings->update_setting( 'token', sanitize_text_field( $token ) );
59
60 $this->sync_attached_media( $post_settings->post_id );
61 }
62
63 /**
64 * Point the shared attachment at the post's current generated image.
65 *
66 * When the post shares the generated image as an attachment, attached_media holds a
67 * plain URL instead of being derived from the token at render time like the OG tag is.
68 * It therefore goes stale whenever the token changes — most visibly after a template
69 * edit, which shares the previous template's image. This runs alongside the
70 * authoritative token write so the two can't drift, including when the editor closes
71 * before its debounced preview ever produced a token.
72 *
73 * @param int $post_id Post whose attachment should follow the generated image.
74 */
75 private function sync_attached_media( $post_id ) {
76 $options = get_post_meta( $post_id, Publicize::POST_JETPACK_SOCIAL_OPTIONS, true );
77
78 if ( ! is_array( $options ) || ( $options['media_source'] ?? '' ) !== 'sig' ) {
79 return;
80 }
81
82 // A non-empty id means real library media, which must not be replaced.
83 if ( ! isset( $options['attached_media'][0] ) || ! empty( $options['attached_media'][0]['id'] ) ) {
84 return;
85 }
86
87 $url = get_image_url( $post_id );
88
89 if ( empty( $url ) || ( $options['attached_media'][0]['url'] ?? '' ) === $url ) {
90 return;
91 }
92
93 $options['attached_media'][0] = array(
94 'id' => 0,
95 'url' => $url,
96 'type' => 'image/png',
97 );
98
99 update_post_meta( $post_id, Publicize::POST_JETPACK_SOCIAL_OPTIONS, $options );
100 }
101
102 /**
103 * Trigger token generation for a post if SIG is enabled.
104 *
105 * @param int $post_id Post ID.
106 * @param \WP_Post $post The post object being saved.
107 * @param bool $update Whether this is an update to a post.
108 */
109 public function generate_token_on_save( $post_id, $post, $update ) {
110 if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
111 return;
112 }
113
114 // If we're not using the block editor for this post, do not continue.
115 if ( ! use_block_editor_for_post( $post ) ) {
116 return;
117 }
118
119 global $publicize;
120
121 if ( ! $publicize->post_type_is_publicizeable( $post->post_type ) ) {
122 return;
123 }
124
125 $settings = new Settings();
126
127 if ( ! $settings->is_sig_available() ) {
128 return;
129 }
130
131 if ( wp_is_post_autosave( $post ) || wp_is_post_revision( $post_id ) ) {
132 return;
133 }
134
135 // Set SIG to be enabled by default for new posts if the toggle is on.
136 $post_settings = new Post_Settings( $post_id );
137 if (
138 ! $update &&
139 'auto-draft' === $post->post_status &&
140 ! empty( $settings->get_settings()['socialImageGeneratorSettings']['enabled'] ) &&
141 empty( $post_settings->get_settings( true ) ) &&
142 'jetpack-social-note' !== $post->post_type
143 ) {
144 $post_settings->update_setting( 'enabled', true );
145 return;
146 }
147
148 if ( $post->post_status === 'auto-draft' ) {
149 return;
150 }
151
152 if ( ! $post_settings->is_enabled() ) {
153 return;
154 }
155
156 $this->generate_token( $post_settings );
157
158 // Prime the Social Image Generator cache out-of-band right after publish.
159 // SIG renders the preview image on the first request to its URL, so a post
160 // shared immediately after publishing can race that cold render and end up
161 // with no preview image (notably on X, which does not retry). Warming the
162 // URL here means the image is already rendered and edge-cached before any
163 // crawler fetches it. Scheduled rather than inline so it never delays the
164 // publish request itself.
165 if (
166 'publish' === $post->post_status &&
167 ! wp_next_scheduled( 'jetpack_social_sig_warm_image', array( $post_id ) )
168 ) {
169 wp_schedule_single_event( time(), 'jetpack_social_sig_warm_image', array( $post_id ) );
170 }
171 }
172
173 /**
174 * Warm the edge cache for a post's generated social image.
175 *
176 * Runs from a scheduled single event (see generate_token_on_save) so it never
177 * blocks the publish request. Issues one blocking request to the same URL the
178 * Open Graph tags expose, which forces the on-demand render and lets the full
179 * response populate the edge cache before a crawler fetches it.
180 *
181 * @param int $post_id Post ID whose social image should be primed.
182 */
183 public function warm_social_image( $post_id ) {
184 $post_settings = new Post_Settings( $post_id );
185
186 if ( ! $post_settings->is_enabled() ) {
187 return;
188 }
189
190 $image_url = get_image_url( $post_id );
191
192 if ( empty( $image_url ) ) {
193 return;
194 }
195
196 // Blocking so the rendered response travels back through the edge cache and
197 // is stored; redirection is followed to the final image URL the crawler hits.
198 wp_remote_get(
199 $image_url,
200 array(
201 'timeout' => 15,
202 'redirection' => 5,
203 'blocking' => true,
204 'user-agent' => 'WordPress.com Social Image Generator cache warmer',
205 )
206 );
207 }
208 }
209