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