PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / 22.7.0
WPSSO Core – Complete Schema Markup and Meta Tags v22.7.0
22.7.0 22.6.1 22.6.0 22.5.3 22.5.2 22.5.1 22.4.0 22.3.0 22.2.1 22.2.0 22.1.3 22.1.2 22.1.1 22.1.0 22.0.0 21.13.3 21.13.2 trunk 21.13.1
wpsso / lib / pinterest.php

pinterest.php in WPSSO Core – Complete Schema Markup and Meta Tags 22.7.0, at lib/pinterest.php

324 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * License: GPLv3
4 * License URI: https://www.gnu.org/licenses/gpl.txt
5 * Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/)
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9
10 die( 'These aren\'t the droids you\'re looking for.' );
11 }
12
13 if ( ! defined( 'WPSSO_PLUGINDIR' ) ) {
14
15 die( 'Do. Or do not. There is no try.' );
16 }
17
18 if ( ! class_exists( 'WpssoPinterest' ) ) {
19
20 class WpssoPinterest {
21
22 private $p; // Wpsso class object.
23
24 /*
25 * Note that options from the WPSSO Core setting pages and Document SSO metabox use a "p" option prefix.
26 */
27 public function __construct( &$plugin ) {
28
29 $this->p =& $plugin;
30
31 if ( $this->p->debug->enabled ) {
32
33 $this->p->debug->mark();
34 }
35
36 add_action( 'init', array( $this, 'allow_img_data_attributes' ) );
37
38 add_filter( 'wp_get_attachment_image_attributes', array( $this, 'add_attachment_image_attributes' ), 10, 2 );
39 add_filter( 'get_header_image_tag', array( $this, 'get_header_image_tag' ), 10, 3 );
40 add_filter( 'get_avatar', array( $this, 'get_avatar_image_tag' ), 10, 6 );
41 add_filter( 'get_image_tag', array( $this, 'get_image_tag' ), 10, 6 );
42
43 if ( empty( $this->p->options[ 'pin_add_img_html' ] ) ) {
44
45 if ( $this->p->debug->enabled ) {
46
47 $this->p->debug->log( 'pinterest hidden image is disabled' );
48 }
49
50 } else {
51
52 if ( $this->p->debug->enabled ) {
53
54 $this->p->debug->log( 'pinterest hidden image is enabled' );
55 }
56
57 $this->p->util->add_plugin_filters( $this, array(
58 'plugin_image_sizes' => 1,
59 ) );
60
61 /*
62 * Filters the post content.
63 *
64 * See https://developer.wordpress.org/reference/hooks/the_content/.
65 */
66 add_filter( 'the_content', array( $this, 'prepend_image_html' ), PHP_INT_MAX );
67
68 /*
69 * Filters the author description, post type archive description, and the term description.
70 *
71 * See https://developer.wordpress.org/reference/functions/get_the_archive_description/.
72 */
73 add_filter( 'get_the_archive_description', array( $this, 'prepend_image_html' ), PHP_INT_MAX );
74 }
75 }
76
77 public function allow_img_data_attributes() {
78
79 global $allowedposttags;
80
81 if ( ! empty( $this->p->options[ 'pin_add_nopin_media_img_tag' ] ) ) {
82
83 $allowedposttags[ 'img' ][ 'data-pin-nopin' ] = true;
84 }
85 }
86
87 /*
88 * $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment );
89 */
90 public function add_attachment_image_attributes( $attr, $attach ) {
91
92 if ( ! empty( $this->p->options[ 'pin_add_nopin_media_img_tag' ] ) ) {
93
94 $attr[ 'data-pin-nopin' ] = 'nopin';
95 }
96
97 return $attr;
98 }
99
100 /*
101 * $html = apply_filters( 'get_header_image_tag', $html, $header, $attr );
102 */
103 public function get_header_image_tag( $html, $header, $attr ) {
104
105 if ( ! empty( $this->p->options[ 'pin_add_nopin_header_img_tag' ] ) ) {
106
107 $html = SucomUtil::insert_html_tag_attributes( $html, array( 'data-pin-nopin' => 'nopin' ) );
108 }
109
110 return $html;
111 }
112
113 /*
114 * $html = apply_filters( 'get_avatar', $html, $id_or_email, $size_px, $default_type, $alt, $data_args );
115 */
116 public function get_avatar_image_tag( $html, $id_or_email, $size_px, $default_type, $alt, $data_args ) {
117
118 if ( ! empty( $this->p->options[ 'pin_add_nopin_header_img_tag' ] ) ) {
119
120 $html = SucomUtil::insert_html_tag_attributes( $html, array( 'data-pin-nopin' => 'nopin' ) );
121 }
122
123 return $html;
124 }
125
126 /*
127 * $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size );
128 */
129 public function get_image_tag( $html, $id, $alt, $title, $align, $size ) {
130
131 if ( ! empty( $this->p->options[ 'pin_add_nopin_media_img_tag' ] ) ) {
132
133 $html = SucomUtil::insert_html_tag_attributes( $html, array( 'data-pin-nopin' => 'nopin' ) );
134 }
135
136 return $html;
137 }
138
139 public function filter_plugin_image_sizes( array $sizes ) {
140
141 if ( ! empty( $this->p->options[ 'pin_add_img_html' ] ) ) { // Just in case.
142
143 $sizes[ 'pin' ] = array( // Option prefix.
144 'name' => 'pinterest',
145 'label_transl' => _x( 'Pinterest Pin It', 'option label', 'wpsso' ),
146 );
147 }
148
149 return $sizes;
150 }
151
152 /*
153 * Hooked to the 'woocommerce_archive_description' action.
154 */
155 public function show_image_html() {
156
157 echo $this->prepend_image_html();
158 }
159
160 /*
161 * Hooked to 'the_content' and 'get_the_archive_description' filters.
162 */
163 public function prepend_image_html( $content = '' ) {
164
165 if ( $this->p->debug->enabled ) {
166
167 $this->p->debug->mark();
168 }
169
170 /*
171 * Do not add a Pinterest image if the current webpage is amp, an rss feed, we're in the loop, or WPSSO is
172 * applying the content filter to create a Schema or meta tag description value.
173 */
174 if ( SucomUtilWP::is_amp() ) {
175
176 if ( $this->p->debug->enabled ) {
177
178 $this->p->debug->log( 'exiting early: is amp' );
179 }
180
181 return $content; // Stop here.
182
183 } elseif ( is_feed() ) {
184
185 if ( $this->p->debug->enabled ) {
186
187 $this->p->debug->log( 'exiting early: is feed' );
188 }
189
190 return $content; // Stop here.
191
192 /*
193 * Do not add a Pinterest image for individual posts within an archive page.
194 *
195 * Note that in_the_loop() can be true in both archive and singular pages.
196 */
197 } elseif ( is_archive() && in_the_loop() ) {
198
199 if ( $this->p->debug->enabled ) {
200
201 $this->p->debug->log( 'exiting early: archive page and in the loop' );
202 }
203
204 return $content; // Stop here.
205
206 } elseif ( ! empty( $GLOBALS[ 'wpsso_doing_filter_the_content' ] ) ) {
207
208 if ( $this->p->debug->enabled ) {
209
210 $this->p->debug->log( 'exiting early: doing the content filter' );
211 }
212
213 return $content; // Stop here.
214 }
215
216 if ( $this->p->debug->enabled ) {
217
218 $this->p->debug->log( 'required call to WpssoPage->get_mod()' );
219 }
220
221 /*
222 * Note that in_the_loop() can be true in both archive and singular pages.
223 */
224 $use_post = apply_filters( 'wpsso_use_post', in_the_loop() ? true : false );
225
226 $mod = $this->p->page->get_mod( $use_post ); // $use_post is true by default.
227
228 $image_html = $this->get_mod_image_html( $mod );
229
230 return $image_html . $content;
231 }
232
233 /*
234 * See WpssoPinterest->prepend_image_html().
235 */
236 public function get_mod_image_html( array $mod ) {
237
238 if ( $this->p->debug->enabled ) {
239
240 $this->p->debug->mark();
241 }
242
243 $image_html = '';
244
245 if ( empty( $mod[ 'name' ] ) || empty( $mod[ 'id' ] ) ) {
246
247 if ( $this->p->debug->enabled ) {
248
249 $this->p->debug->log( 'exiting early: mod name or id is empty' );
250 }
251
252 return $image_html; // Stop here.
253 }
254
255 /*
256 * Note that the sort order, page number, locale, amp and embed checks are provided by
257 * WpssoHead->get_head_cache_index() and not SucomUtil::get_mod_salt().
258 */
259 $cache_salt = SucomUtil::get_mod_salt( $mod );
260
261 static $do_once = array(); // Just in case - prevent recursion and duplicate CSS IDs in the webpage.
262
263 if ( ! empty( $do_once[ $cache_salt ] ) ) {
264
265 if ( $this->p->debug->enabled ) {
266
267 $this->p->debug->log( 'exiting early: already added for ' . $cache_salt );
268 }
269
270 return $image_html; // Stop here.
271 }
272
273 $do_once[ $cache_salt ] = true; // Set early to prevent recursion.
274
275 $size_name = 'wpsso-pinterest';
276 $mt_images = $this->p->media->get_all_images( $num = 1, $size_name, $mod, $md_pre = array( 'pin', 'schema', 'og' ) );
277 $image_url = SucomUtil::get_first_mt_media_url( $mt_images );
278 $css_id = 'pin-it-' . SucomUtil::sanitize_css_id( $cache_salt );
279
280 /*
281 * Avoid newline characters and HTML comments as they can be wrapped in paragraph tags by some WordPress filters.
282 */
283 $image_html = '<div class="wpsso-pinterest-image" id="' . $css_id . '" style="width:0;height:0;display:none !important;">';
284
285 if ( empty( $image_url ) ) {
286
287 if ( $this->p->debug->enabled ) {
288
289 $this->p->debug->log( 'image URL for pinterest is empty' );
290 }
291
292 } else {
293
294 if ( $this->p->debug->enabled ) {
295
296 $this->p->debug->log( 'adding image URL for pinterest = ' . $image_url );
297 }
298
299 $data_pin_desc = $this->p->page->get_description( $mod, $md_key = 'pin_img_desc', $max_len = 'pin_img_desc', $num_hashtags = true );
300
301 if ( $this->p->debug->enabled ) {
302
303 $this->p->debug->log( 'pinterest data pin description = ' . $data_pin_desc );
304 }
305
306 /*
307 * Note that an empty alt attribute is required for W3C validation.
308 *
309 * Adding a 'loading="lazy"' attribute breaks the Pinterest Save button.
310 *
311 * The 'skip-lazy' class is used by WP Rocket to skip the lazy loading of an image.
312 */
313 $image_html .= '<img src="' . SucomUtil::esc_url_encode( $image_url ) . '" ' .
314 'width="0" height="0" class="skip-lazy" style="width:0;height:0;" alt="" ' .
315 'data-pin-description="' . esc_attr( $data_pin_desc ) . '" />';
316 }
317
318 $image_html .= '</div>';
319
320 return $image_html;
321 }
322 }
323 }
324