PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.2.2
Jetpack – WP Security, Backup, Speed, & Growth v14.2.2
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 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 / modules / theme-tools / site-logo / inc / class-site-logo.php
jetpack / modules / theme-tools / site-logo / inc Last commit date
class-site-logo.php 2 years ago compat.php 5 years ago functions.php 2 years ago
class-site-logo.php
420 lines
1 <?php
2 /**
3 * Site Logo class main class file.
4 *
5 * @package automattic/jetpack
6 */
7
8 /**
9 * Site Logo class for managing a theme-agnostic logo through the Customizer.
10 */
11 class Site_Logo {
12 /**
13 * Stores our single instance.
14 *
15 * @var Site_Logo
16 */
17 private static $instance;
18
19 /**
20 * Stores the attachment ID of the site logo.
21 *
22 * @var int
23 */
24 public $logo;
25
26 /**
27 * Return our instance, creating a new one if necessary.
28 *
29 * @uses Site_Logo::$instance
30 * @return object Site_Logo
31 */
32 public static function instance() {
33 if ( ! isset( self::$instance ) ) {
34 self::$instance = new Site_Logo();
35 self::$instance->register_hooks();
36 }
37
38 return self::$instance;
39 }
40
41 /**
42 * Get our current logo settings stored in options.
43 *
44 * @uses get_option()
45 */
46 private function __construct() {
47 $this->logo = (int) get_option( 'site_logo', null );
48 }
49
50 /**
51 * Register our actions and filters.
52 *
53 * @uses Site_Logo::head_text_styles()
54 * @uses Site_Logo::customize_register()
55 * @uses Site_Logo::preview_enqueue()
56 * @uses Site_Logo::body_classes()
57 * @uses Site_Logo::media_manager_image_sizes()
58 * @uses add_action
59 * @uses add_filter
60 */
61 public function register_hooks() {
62 // This would only happen if a theme supports BOTH site-logo and custom-logo for some reason
63 if ( current_theme_supports( 'custom-logo' ) ) {
64 return;
65 }
66
67 add_action( 'wp_head', array( $this, 'head_text_styles' ) );
68 add_action( 'customize_register', array( $this, 'customize_register' ) );
69 add_action( 'customize_preview_init', array( $this, 'preview_enqueue' ) );
70 add_action( 'delete_attachment', array( $this, 'reset_on_attachment_delete' ) );
71 add_filter( 'body_class', array( $this, 'body_classes' ) );
72 add_filter( 'image_size_names_choose', array( $this, 'media_manager_image_sizes' ) );
73 add_filter( 'display_media_states', array( $this, 'add_media_state' ) );
74 }
75
76 /**
77 * Add our logo uploader to the Customizer.
78 *
79 * @param object $wp_customize Customizer object.
80 * @uses current_theme_supports()
81 * @uses current_theme_supports()
82 * @uses WP_Customize_Manager::add_setting()
83 * @uses WP_Customize_Manager::add_control()
84 * @uses Site_Logo::sanitize_checkbox()
85 */
86 public function customize_register( $wp_customize ) {
87 // Add a setting to hide header text if the theme isn't supporting the feature itself
88 if ( ! current_theme_supports( 'custom-header' ) ) {
89 $wp_customize->add_setting(
90 'site_logo_header_text',
91 array(
92 'default' => 1,
93 'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
94 'transport' => 'postMessage',
95 )
96 );
97
98 $wp_customize->add_control(
99 new WP_Customize_Control(
100 $wp_customize,
101 'site_logo_header_text',
102 array(
103 'label' => __( 'Display Header Text', 'jetpack' ),
104 'section' => 'title_tagline',
105 'settings' => 'site_logo_header_text',
106 'type' => 'checkbox',
107 )
108 )
109 );
110 }
111
112 // Add the setting for our logo value.
113 $wp_customize->add_setting(
114 'site_logo',
115 array(
116 'capability' => 'manage_options',
117 'default' => 0,
118 'sanitize_callback' => array( $this, 'sanitize_logo_setting' ),
119 'transport' => 'postMessage',
120 'type' => 'option',
121 )
122 );
123
124 // By default, not setting width and height will suggest a square crop.
125 $width = null;
126 $height = null;
127 $logo_size = jetpack_get_site_logo_dimensions();
128
129 // Only suggested a different crop if the theme declares both dimensions.
130 if ( false !== $logo_size && $logo_size['width'] && $logo_size['height'] ) {
131 $width = $logo_size['width'];
132 $height = $logo_size['height'];
133 }
134
135 // Add our image uploader.
136 $wp_customize->add_control(
137 new WP_Customize_Cropped_Image_Control(
138 $wp_customize,
139 'site_logo',
140 array(
141 'label' => __( 'Logo', 'jetpack' ),
142 'section' => 'title_tagline',
143 'settings' => 'site_logo',
144 'width' => $width,
145 'height' => $height,
146 'flex_width' => true,
147 'flex_height' => true,
148 'button_labels' => array(
149 'select' => __( 'Add logo', 'jetpack' ),
150 'change' => __( 'Change logo', 'jetpack' ),
151 'remove' => __( 'Remove logo', 'jetpack' ),
152 'placeholder' => __( 'No logo set', 'jetpack' ),
153 'frame_title' => __( 'Set as logo', 'jetpack' ),
154 'frame_button' => __( 'Choose logo', 'jetpack' ),
155 ),
156 )
157 )
158 );
159
160 $wp_customize->selective_refresh->add_partial(
161 'site_logo',
162 array(
163 'settings' => 'site_logo',
164 'selector' => '.site-logo-link',
165 'render_callback' => array( $this, 'customizer_preview' ),
166 'container_inclusive' => true,
167 )
168 );
169 }
170
171 /**
172 * Enqueue scripts for the Customizer live preview.
173 *
174 * @uses wp_enqueue_script()
175 * @uses plugins_url()
176 * @uses current_theme_supports()
177 * @uses Site_Logo::header_text_classes()
178 * @uses wp_localize_script()
179 */
180 public function preview_enqueue() {
181 // Don't bother passing in header text classes if the theme supports custom headers.
182 if ( ! current_theme_supports( 'custom-header' ) ) {
183 $classes = jetpack_sanitize_header_text_classes( $this->header_text_classes() );
184 wp_enqueue_script(
185 'site-logo-header-text',
186 plugins_url( '../js/site-logo-header-text.js', __FILE__ ),
187 array( 'jquery', 'media-views' ),
188 JETPACK__VERSION,
189 true
190 );
191 wp_localize_script( 'site-logo-header-text', 'site_logo_header_classes', array( 'classes' => $classes ) );
192 }
193 }
194
195 /**
196 * Get header text classes. If not defined in add_theme_support(), defaults from Underscores will be used.
197 *
198 * @uses get_theme_support
199 * @return string String of classes to hide
200 */
201 public function header_text_classes() {
202 $args = get_theme_support( 'site-logo' );
203
204 if ( isset( $args[0]['header-text'] ) ) {
205 // Use any classes defined in add_theme_support().
206 $classes = $args[0]['header-text'];
207 } else {
208 // Otherwise, use these defaults, which will work with any Underscores-based theme.
209 $classes = array(
210 'site-title',
211 'site-description',
212 );
213 }
214
215 // If we've got an array, reduce them to a string for output
216 if ( is_array( $classes ) ) {
217 $classes = (string) '.' . implode( ', .', $classes );
218 } else {
219 $classes = (string) '.' . $classes;
220 }
221
222 return $classes;
223 }
224
225 /**
226 * Hide header text on front-end if necessary.
227 *
228 * @uses current_theme_supports()
229 * @uses get_theme_mod()
230 * @uses Site_Logo::header_text_classes()
231 * @uses esc_html()
232 */
233 public function head_text_styles() {
234 // Bail if our theme supports custom headers.
235 if ( current_theme_supports( 'custom-header' ) ) {
236 return;
237 }
238
239 // Is Display Header Text unchecked? If so, we need to hide our header text.
240 if ( ! get_theme_mod( 'site_logo_header_text', 1 ) ) {
241 $classes = $this->header_text_classes();
242 ?>
243 <!-- Site Logo: hide header text -->
244 <style type="text/css">
245 <?php echo jetpack_sanitize_header_text_classes( $classes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> {
246 position: absolute;
247 clip: rect(1px, 1px, 1px, 1px);
248 }
249 </style>
250 <?php
251 }
252 }
253
254 /**
255 * Determine image size to use for the logo.
256 *
257 * @uses get_theme_support()
258 * @return string Size specified in add_theme_support declaration, or 'thumbnail' default
259 */
260 public function theme_size() {
261 $args = get_theme_support( 'site-logo' );
262 $valid_sizes = get_intermediate_image_sizes();
263
264 // Add 'full' to the list of accepted values.
265 $valid_sizes[] = 'full';
266
267 // If the size declared in add_theme_support is valid, use it; otherwise, just go with 'thumbnail'.
268 $size = ( isset( $args[0]['size'] ) && in_array( $args[0]['size'], $valid_sizes, true ) ) ? $args[0]['size'] : 'thumbnail';
269
270 return $size;
271 }
272
273 /**
274 * Make custom image sizes available to the media manager.
275 *
276 * @param array $sizes List of image sizes.
277 * @uses get_intermediate_image_sizes()
278 * @return array All default and registered custom image sizes.
279 */
280 public function media_manager_image_sizes( $sizes ) {
281 // Get an array of all registered image sizes.
282 $intermediate = get_intermediate_image_sizes();
283
284 // Have we got anything fun to work with?
285 if ( is_array( $intermediate ) && ! empty( $intermediate ) ) {
286 foreach ( $intermediate as $size ) {
287 // If the size isn't already in the $sizes array, add it.
288 if ( ! array_key_exists( $size, $sizes ) ) {
289 $sizes[ $size ] = $size;
290 }
291 }
292 }
293
294 return $sizes;
295 }
296
297 /**
298 * Add site logos to media states in the Media Manager.
299 *
300 * @param array $media_states An array of media states.
301 *
302 * @return array The current attachment's media states.
303 */
304 public function add_media_state( $media_states ) {
305 // Only bother testing if we have a site logo set.
306 if ( $this->has_site_logo() ) {
307 global $post;
308
309 // If our attachment ID and the site logo ID match, this image is the site logo.
310 if ( $post && $post->ID === $this->logo ) {
311 $media_states[] = __( 'Site Logo', 'jetpack' );
312 }
313 }
314
315 return $media_states;
316 }
317
318 /**
319 * Reset the site logo if the current logo is deleted in the media manager.
320 *
321 * @param int $post_id Attachment ID.
322 * @uses Site_Logo::remove_site_logo()
323 */
324 public function reset_on_attachment_delete( $post_id ) {
325 if ( $this->logo === $post_id ) {
326 $this->remove_site_logo();
327 }
328 }
329
330 /**
331 * Determine if a site logo is assigned or not.
332 *
333 * @uses Site_Logo::$logo
334 * @return boolean True if there is an active logo, false otherwise
335 */
336 public function has_site_logo() {
337 return (bool) $this->logo;
338 }
339
340 /**
341 * Reset the site logo option to zero (empty).
342 *
343 * @uses update_option()
344 */
345 public function remove_site_logo() {
346 update_option( 'site_logo', null );
347 }
348
349 /**
350 * Adds custom classes to the array of body classes.
351 *
352 * @uses Site_Logo::has_site_logo()
353 * @param array $classes Classes for the body element.
354 * @return array Array of <body> classes
355 */
356 public function body_classes( $classes ) {
357 // Add a class if a Site Logo is active
358 if ( $this->has_site_logo() ) {
359 $classes[] = 'has-site-logo';
360 }
361
362 return $classes;
363 }
364
365 /**
366 * Sanitize our header text Customizer setting.
367 *
368 * @param mixed $input The input value to sanitize.
369 * @return bool|string 1 if checked, empty string if not checked.
370 */
371 public function sanitize_checkbox( $input ) {
372 return ( 1 === (int) $input ) ? 1 : '';
373 }
374
375 /**
376 * Validate and sanitize a new site logo setting.
377 *
378 * @param mixed $input Logo setting value to sanitize.
379 * @return int Attachment post ID, or 0 if invalid.
380 */
381 public function sanitize_logo_setting( $input ) {
382 $input = absint( $input );
383
384 // If the new setting doesn't point to a valid attachment, just reset the whole thing.
385 if ( false === wp_get_attachment_image_src( $input ) ) {
386 $input = 0;
387 }
388
389 return $input;
390 }
391
392 /**
393 * This function returns the updated HTML in the Customizer preview when the logo is added, updated, or removed.
394 *
395 * @return string
396 */
397 public function customizer_preview() {
398 ob_start();
399 jetpack_the_site_logo();
400 return ob_get_clean();
401 }
402 }
403
404 // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move these functions to some other file.
405
406 /**
407 * Allow themes and plugins to access Site_Logo methods and properties.
408 *
409 * @uses Site_Logo::instance()
410 * @return object Site_Logo
411 */
412 function site_logo() {
413 return Site_Logo::instance();
414 }
415
416 /**
417 * One site logo, please.
418 */
419 site_logo();
420