WordPress 4.1
[autoinstalls/wordpress.git] / wp-admin / custom-background.php
1 <?php
2 /**
3  * The custom background script.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * The custom background class.
11  *
12  * @since 3.0.0
13  * @package WordPress
14  * @subpackage Administration
15  */
16 class Custom_Background {
17
18         /**
19          * Callback for administration header.
20          *
21          * @var callback
22          * @since 3.0.0
23          * @access private
24          */
25         private $admin_header_callback;
26
27         /**
28          * Callback for header div.
29          *
30          * @var callback
31          * @since 3.0.0
32          * @access private
33          */
34         private $admin_image_div_callback;
35
36         /**
37          * Holds the page menu hook.
38          *
39          * @var string
40          * @since 3.0.0
41          * @access private
42          */
43         private $page = '';
44
45         /**
46          * @var bool
47          */
48         private $updated;
49
50         /**
51          * Constructor - Register administration header callback.
52          *
53          * @since 3.0.0
54          * @param callback $admin_header_callback
55          * @param callback $admin_image_div_callback Optional custom image div output callback.
56          * @return Custom_Background
57          */
58         public function __construct($admin_header_callback = '', $admin_image_div_callback = '') {
59                 $this->admin_header_callback = $admin_header_callback;
60                 $this->admin_image_div_callback = $admin_image_div_callback;
61
62                 add_action( 'admin_menu', array( $this, 'init' ) );
63
64                 add_action( 'wp_ajax_custom-background-add', array( $this, 'ajax_background_add' ) );
65
66                 // Unused since 3.5.0.
67                 add_action( 'wp_ajax_set-background-image', array( $this, 'wp_set_background_image' ) );
68         }
69
70         /**
71          * Make private properties readable for backwards compatibility.
72          *
73          * @since 4.0.0
74          * @access public
75          *
76          * @param string $name Property name.
77          * @return mixed Property.
78          */
79         public function __get( $name ) {
80                 return $this->$name;
81         }
82
83         /**
84          * Make private properties settable for backwards compatibility.
85          *
86          * @since 4.0.0
87          * @access public
88          *
89          * @param string $name  Property to set.
90          * @param mixed  $value Property value.
91          * @return mixed Newly-set property.
92          */
93         public function __set( $name, $value ) {
94                 return $this->$name = $value;
95         }
96
97         /**
98          * Make private properties checkable for backwards compatibility.
99          *
100          * @since 4.0.0
101          * @access public
102          *
103          * @param string $name Property to check if set.
104          * @return bool Whether the property is set.
105          */
106         public function __isset( $name ) {
107                 return isset( $this->$name );
108         }
109
110         /**
111          * Make private properties un-settable for backwards compatibility.
112          *
113          * @since 4.0.0
114          * @access public
115          *
116          * @param string $name Property to unset.
117          */
118         public function __unset( $name ) {
119                 unset( $this->$name );
120         }
121
122         /**
123          * Set up the hooks for the Custom Background admin page.
124          *
125          * @since 3.0.0
126          */
127         public function init() {
128                 if ( ! current_user_can('edit_theme_options') )
129                         return;
130
131                 $this->page = $page = add_theme_page(__('Background'), __('Background'), 'edit_theme_options', 'custom-background', array($this, 'admin_page'));
132
133                 add_action("load-$page", array($this, 'admin_load'));
134                 add_action("load-$page", array($this, 'take_action'), 49);
135                 add_action("load-$page", array($this, 'handle_upload'), 49);
136
137                 if ( $this->admin_header_callback )
138                         add_action("admin_head-$page", $this->admin_header_callback, 51);
139         }
140
141         /**
142          * Set up the enqueue for the CSS & JavaScript files.
143          *
144          * @since 3.0.0
145          */
146         public function admin_load() {
147                 get_current_screen()->add_help_tab( array(
148                         'id'      => 'overview',
149                         'title'   => __('Overview'),
150                         'content' =>
151                                 '<p>' . __( 'You can customize the look of your site without touching any of your theme&#8217;s code by using a custom background. Your background can be an image or a color.' ) . '</p>' .
152                                 '<p>' . __( 'To use a background image, simply upload it or choose an image that has already been uploaded to your Media Library by clicking the &#8220;Choose Image&#8221; button. You can display a single instance of your image, or tile it to fill the screen. You can have your background fixed in place, so your site content moves on top of it, or you can have it scroll with your site.' ) . '</p>' .
153                                 '<p>' . __( 'You can also choose a background color by clicking the Select Color button and either typing in a legitimate HTML hex value, e.g. &#8220;#ff0000&#8221; for red, or by choosing a color using the color picker.' ) . '</p>' .
154                                 '<p>' . __( 'Don&#8217;t forget to click on the Save Changes button when you are finished.' ) . '</p>'
155                 ) );
156
157                 get_current_screen()->set_help_sidebar(
158                         '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
159                         '<p>' . __( '<a href="http://codex.wordpress.org/Appearance_Background_Screen" target="_blank">Documentation on Custom Background</a>' ) . '</p>' .
160                         '<p>' . __( '<a href="https://wordpress.org/support/" target="_blank">Support Forums</a>' ) . '</p>'
161                 );
162
163                 wp_enqueue_media();
164                 wp_enqueue_script('custom-background');
165                 wp_enqueue_style('wp-color-picker');
166         }
167
168         /**
169          * Execute custom background modification.
170          *
171          * @since 3.0.0
172          */
173         public function take_action() {
174
175                 if ( empty($_POST) )
176                         return;
177
178                 if ( isset($_POST['reset-background']) ) {
179                         check_admin_referer('custom-background-reset', '_wpnonce-custom-background-reset');
180                         remove_theme_mod('background_image');
181                         remove_theme_mod('background_image_thumb');
182                         $this->updated = true;
183                         return;
184                 }
185
186                 if ( isset($_POST['remove-background']) ) {
187                         // @TODO: Uploaded files are not removed here.
188                         check_admin_referer('custom-background-remove', '_wpnonce-custom-background-remove');
189                         set_theme_mod('background_image', '');
190                         set_theme_mod('background_image_thumb', '');
191                         $this->updated = true;
192                         wp_safe_redirect( $_POST['_wp_http_referer'] );
193                         return;
194                 }
195
196                 if ( isset($_POST['background-repeat']) ) {
197                         check_admin_referer('custom-background');
198                         if ( in_array($_POST['background-repeat'], array('repeat', 'no-repeat', 'repeat-x', 'repeat-y')) )
199                                 $repeat = $_POST['background-repeat'];
200                         else
201                                 $repeat = 'repeat';
202                         set_theme_mod('background_repeat', $repeat);
203                 }
204
205                 if ( isset($_POST['background-position-x']) ) {
206                         check_admin_referer('custom-background');
207                         if ( in_array($_POST['background-position-x'], array('center', 'right', 'left')) )
208                                 $position = $_POST['background-position-x'];
209                         else
210                                 $position = 'left';
211                         set_theme_mod('background_position_x', $position);
212                 }
213
214                 if ( isset($_POST['background-attachment']) ) {
215                         check_admin_referer('custom-background');
216                         if ( in_array($_POST['background-attachment'], array('fixed', 'scroll')) )
217                                 $attachment = $_POST['background-attachment'];
218                         else
219                                 $attachment = 'fixed';
220                         set_theme_mod('background_attachment', $attachment);
221                 }
222
223                 if ( isset($_POST['background-color']) ) {
224                         check_admin_referer('custom-background');
225                         $color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['background-color']);
226                         if ( strlen($color) == 6 || strlen($color) == 3 )
227                                 set_theme_mod('background_color', $color);
228                         else
229                                 set_theme_mod('background_color', '');
230                 }
231
232                 $this->updated = true;
233         }
234
235         /**
236          * Display the custom background page.
237          *
238          * @since 3.0.0
239          */
240         public function admin_page() {
241 ?>
242 <div class="wrap" id="custom-background">
243 <h2><?php _e( 'Custom Background' ); ?></h2>
244
245 <?php if ( current_user_can( 'customize' ) ) { ?>
246 <div class="notice notice-info hide-if-no-customize">
247         <p>
248                 <?php
249                 printf(
250                         __( 'You can now manage and live-preview Custom Backgrounds in the <a href="%1$s">Customizer</a>.' ),
251                         admin_url( 'customize.php?autofocus[control]=background_image' )
252                 );
253                 ?>
254         </p>
255 </div>
256 <?php } ?>
257
258 <?php if ( ! empty( $this->updated ) ) { ?>
259 <div id="message" class="updated">
260 <p><?php printf( __( 'Background updated. <a href="%s">Visit your site</a> to see how it looks.' ), home_url( '/' ) ); ?></p>
261 </div>
262 <?php } ?>
263
264 <h3><?php _e( 'Background Image' ); ?></h3>
265
266 <table class="form-table">
267 <tbody>
268 <tr>
269 <th scope="row"><?php _e( 'Preview' ); ?></th>
270 <td>
271         <?php
272         if ( $this->admin_image_div_callback ) {
273                 call_user_func( $this->admin_image_div_callback );
274         } else {
275                 $background_styles = '';
276                 if ( $bgcolor = get_background_color() )
277                         $background_styles .= 'background-color: #' . $bgcolor . ';';
278
279                 if ( get_background_image() ) {
280                         $background_image_thumb = esc_url( set_url_scheme( get_theme_mod( 'background_image_thumb', str_replace( '%', '%%', get_background_image() ) ) ) );
281
282                         // Background-image URL must be single quote, see below.
283                         $background_styles .= ' background-image: url(\'' . $background_image_thumb . '\');'
284                                 . ' background-repeat: ' . get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) . ';'
285                                 . ' background-position: top ' . get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) );
286                 }
287         ?>
288         <div id="custom-background-image" style="<?php echo $background_styles; ?>"><?php // must be double quote, see above ?>
289                 <?php if ( get_background_image() ) { ?>
290                 <img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" /><br />
291                 <img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" />
292                 <?php } ?>
293         </div>
294         <?php } ?>
295 </td>
296 </tr>
297
298 <?php if ( get_background_image() ) : ?>
299 <tr>
300 <th scope="row"><?php _e('Remove Image'); ?></th>
301 <td>
302 <form method="post" action="">
303 <?php wp_nonce_field('custom-background-remove', '_wpnonce-custom-background-remove'); ?>
304 <?php submit_button( __( 'Remove Background Image' ), 'button', 'remove-background', false ); ?><br/>
305 <?php _e('This will remove the background image. You will not be able to restore any customizations.') ?>
306 </form>
307 </td>
308 </tr>
309 <?php endif; ?>
310
311 <?php $default_image = get_theme_support( 'custom-background', 'default-image' ); ?>
312 <?php if ( $default_image && get_background_image() != $default_image ) : ?>
313 <tr>
314 <th scope="row"><?php _e('Restore Original Image'); ?></th>
315 <td>
316 <form method="post" action="">
317 <?php wp_nonce_field('custom-background-reset', '_wpnonce-custom-background-reset'); ?>
318 <?php submit_button( __( 'Restore Original Image' ), 'button', 'reset-background', false ); ?><br/>
319 <?php _e('This will restore the original background image. You will not be able to restore any customizations.') ?>
320 </form>
321 </td>
322 </tr>
323 <?php endif; ?>
324
325 <tr>
326 <th scope="row"><?php _e('Select Image'); ?></th>
327 <td><form enctype="multipart/form-data" id="upload-form" class="wp-upload-form" method="post" action="">
328         <p>
329                 <label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br />
330                 <input type="file" id="upload" name="import" />
331                 <input type="hidden" name="action" value="save" />
332                 <?php wp_nonce_field( 'custom-background-upload', '_wpnonce-custom-background-upload' ); ?>
333                 <?php submit_button( __( 'Upload' ), 'button', 'submit', false ); ?>
334         </p>
335         <p>
336                 <label for="choose-from-library-link"><?php _e( 'Or choose an image from your media library:' ); ?></label><br />
337                 <button id="choose-from-library-link" class="button"
338                         data-choose="<?php esc_attr_e( 'Choose a Background Image' ); ?>"
339                         data-update="<?php esc_attr_e( 'Set as background' ); ?>"><?php _e( 'Choose Image' ); ?></button>
340         </p>
341         </form>
342 </td>
343 </tr>
344 </tbody>
345 </table>
346
347 <h3><?php _e('Display Options') ?></h3>
348 <form method="post" action="">
349 <table class="form-table">
350 <tbody>
351 <?php if ( get_background_image() ) : ?>
352 <tr>
353 <th scope="row"><?php _e( 'Position' ); ?></th>
354 <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Position' ); ?></span></legend>
355 <label>
356 <input name="background-position-x" type="radio" value="left"<?php checked( 'left', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
357 <?php _e('Left') ?>
358 </label>
359 <label>
360 <input name="background-position-x" type="radio" value="center"<?php checked( 'center', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
361 <?php _e('Center') ?>
362 </label>
363 <label>
364 <input name="background-position-x" type="radio" value="right"<?php checked( 'right', get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ) ); ?> />
365 <?php _e('Right') ?>
366 </label>
367 </fieldset></td>
368 </tr>
369
370 <tr>
371 <th scope="row"><?php _e( 'Repeat' ); ?></th>
372 <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Repeat' ); ?></span></legend>
373 <label><input type="radio" name="background-repeat" value="no-repeat"<?php checked( 'no-repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('No Repeat'); ?></label>
374         <label><input type="radio" name="background-repeat" value="repeat"<?php checked( 'repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile'); ?></label>
375         <label><input type="radio" name="background-repeat" value="repeat-x"<?php checked( 'repeat-x', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile Horizontally'); ?></label>
376         <label><input type="radio" name="background-repeat" value="repeat-y"<?php checked( 'repeat-y', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?> /> <?php _e('Tile Vertically'); ?></label>
377 </fieldset></td>
378 </tr>
379
380 <tr>
381 <th scope="row"><?php _ex( 'Attachment', 'Background Attachment' ); ?></th>
382 <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Attachment' ); ?></span></legend>
383 <label>
384 <input name="background-attachment" type="radio" value="scroll" <?php checked( 'scroll', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?> />
385 <?php _e( 'Scroll' ); ?>
386 </label>
387 <label>
388 <input name="background-attachment" type="radio" value="fixed" <?php checked( 'fixed', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?> />
389 <?php _e( 'Fixed' ); ?>
390 </label>
391 </fieldset></td>
392 </tr>
393 <?php endif; // get_background_image() ?>
394 <tr>
395 <th scope="row"><?php _e( 'Background Color' ); ?></th>
396 <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Color' ); ?></span></legend>
397 <?php
398 $default_color = '';
399 if ( current_theme_supports( 'custom-background', 'default-color' ) )
400         $default_color = ' data-default-color="#' . esc_attr( get_theme_support( 'custom-background', 'default-color' ) ) . '"';
401 ?>
402 <input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php echo $default_color ?> />
403 </fieldset></td>
404 </tr>
405 </tbody>
406 </table>
407
408 <?php wp_nonce_field('custom-background'); ?>
409 <?php submit_button( null, 'primary', 'save-background-options' ); ?>
410 </form>
411
412 </div>
413 <?php
414         }
415
416         /**
417          * Handle an Image upload for the background image.
418          *
419          * @since 3.0.0
420          */
421         public function handle_upload() {
422
423                 if ( empty($_FILES) )
424                         return;
425
426                 check_admin_referer('custom-background-upload', '_wpnonce-custom-background-upload');
427                 $overrides = array('test_form' => false);
428
429                 $uploaded_file = $_FILES['import'];
430                 $wp_filetype = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'], false );
431                 if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) )
432                         wp_die( __( 'The uploaded file is not a valid image. Please try again.' ) );
433
434                 $file = wp_handle_upload($uploaded_file, $overrides);
435
436                 if ( isset($file['error']) )
437                         wp_die( $file['error'] );
438
439                 $url = $file['url'];
440                 $type = $file['type'];
441                 $file = $file['file'];
442                 $filename = basename($file);
443
444                 // Construct the object array
445                 $object = array(
446                         'post_title' => $filename,
447                         'post_content' => $url,
448                         'post_mime_type' => $type,
449                         'guid' => $url,
450                         'context' => 'custom-background'
451                 );
452
453                 // Save the data
454                 $id = wp_insert_attachment($object, $file);
455
456                 // Add the meta-data
457                 wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
458                 update_post_meta( $id, '_wp_attachment_is_custom_background', get_option('stylesheet' ) );
459
460                 set_theme_mod('background_image', esc_url_raw($url));
461
462                 $thumbnail = wp_get_attachment_image_src( $id, 'thumbnail' );
463                 set_theme_mod('background_image_thumb', esc_url_raw( $thumbnail[0] ) );
464
465                 /** This action is documented in wp-admin/custom-header.php */
466                 do_action( 'wp_create_file_in_uploads', $file, $id ); // For replication
467                 $this->updated = true;
468         }
469
470         /**
471          * AJAX handler for adding custom background context to an attachment.
472          *
473          * Triggered when the user adds a new background image from the
474          * Media Manager.
475          *
476          * @since 4.1.0
477          */
478         public function ajax_background_add() {
479                 check_ajax_referer( 'background-add', 'nonce' );
480
481                 if ( ! current_user_can( 'edit_theme_options' ) ) {
482                         wp_send_json_error();
483                 }
484
485                 $attachment_id = absint( $_POST['attachment_id'] );
486                 if ( $attachment_id < 1 ) {
487                         wp_send_json_error();
488                 }
489
490                 update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', get_stylesheet() );
491
492                 wp_send_json_success();
493         }
494
495         /**
496          *
497          * @since 3.4.0
498          * @deprecated 3.5.0
499          */
500         public function attachment_fields_to_edit( $form_fields ) {
501                 return $form_fields;
502         }
503
504         /**
505          *
506          * @since 3.4.0
507          * @deprecated 3.5.0
508          */
509         public function filter_upload_tabs( $tabs ) {
510                 return $tabs;
511         }
512
513         /**
514          *
515          * @since 3.4.0
516          * @deprecated 3.5.0
517          */
518         public function wp_set_background_image() {
519                 if ( ! current_user_can('edit_theme_options') || ! isset( $_POST['attachment_id'] ) ) exit;
520                 $attachment_id = absint($_POST['attachment_id']);
521                 /** This filter is documented in wp-admin/includes/media.php */
522                 $sizes = array_keys(apply_filters( 'image_size_names_choose', array('thumbnail' => __('Thumbnail'), 'medium' => __('Medium'), 'large' => __('Large'), 'full' => __('Full Size')) ));
523                 $size = 'thumbnail';
524                 if ( in_array( $_POST['size'], $sizes ) )
525                         $size = esc_attr( $_POST['size'] );
526
527                 update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', get_option('stylesheet' ) );
528                 $url = wp_get_attachment_image_src( $attachment_id, $size );
529                 $thumbnail = wp_get_attachment_image_src( $attachment_id, 'thumbnail' );
530                 set_theme_mod( 'background_image', esc_url_raw( $url[0] ) );
531                 set_theme_mod( 'background_image_thumb', esc_url_raw( $thumbnail[0] ) );
532                 exit;
533         }
534 }