class-redux-background.php (19085B)
1 <?php 2 /** 3 * Background Field. 4 * 5 * @package ReduxFramework/Fields 6 * @author Dovy Paukstys & Kevin Provance (kprovance) 7 * @version 4.0.0 8 */ 9 10 defined( 'ABSPATH' ) || exit; 11 12 // Don't duplicate me! 13 if ( ! class_exists( 'Redux_Background', false ) ) { 14 15 /** 16 * Main Redux_background class 17 * 18 * @since 3.1.5 19 */ 20 class Redux_Background extends Redux_Field { 21 22 /** 23 * Set field and value defaults. 24 */ 25 public function set_defaults() { 26 $defaults = array( 27 'background-color' => true, 28 'background-repeat' => true, 29 'background-attachment' => true, 30 'background-position' => true, 31 'background-image' => true, 32 'background-gradient' => false, 33 'background-clip' => false, 34 'background-origin' => false, 35 'background-size' => true, 36 'preview_media' => false, 37 'preview' => true, 38 'preview_height' => '200px', 39 'transparent' => true, 40 ); 41 42 $this->field = wp_parse_args( $this->field, $defaults ); 43 44 // No errors please. 45 $defaults = array( 46 'background-color' => '', 47 'background-repeat' => '', 48 'background-attachment' => '', 49 'background-position' => '', 50 'background-image' => '', 51 'background-clip' => '', 52 'background-origin' => '', 53 'background-size' => '', 54 'media' => array(), 55 ); 56 57 $this->value = wp_parse_args( $this->value, $defaults ); 58 59 $defaults = array( 60 'id' => '', 61 'width' => '', 62 'height' => '', 63 'thumbnail' => '', 64 ); 65 66 $this->value['media'] = wp_parse_args( $this->value['media'], $defaults ); 67 } 68 69 /** 70 * Field Render Function. 71 * Takes the vars and outputs the HTML for the field in the settings 72 * 73 * @since 1.0.0 74 * @access public 75 * @return void 76 */ 77 public function render() { 78 $this->select2_config['allowClear'] = true; 79 80 if ( isset( $this->field['select2'] ) ) { 81 $this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config ); 82 } else { 83 $this->field['select2'] = $this->select2_config; 84 } 85 86 $this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] ); 87 88 $select2_data = Redux_Functions::create_data_string( $this->field['select2'] ); 89 90 if ( true === $this->field['background-color'] ) { 91 if ( isset( $this->value['color'] ) && empty( $this->value['background-color'] ) ) { 92 $this->value['background-color'] = $this->value['color']; 93 } 94 95 $def_bg_color = $this->field['default']['background-color'] ?? ''; 96 97 echo '<input '; 98 echo 'data-id="' . esc_attr( $this->field['id'] ) . '"'; 99 echo 'name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-color]"'; 100 echo 'id="' . esc_attr( $this->field['id'] ) . '-color"'; 101 echo 'class="color-picker redux-color redux-background-input redux-color-init ' . esc_attr( $this->field['class'] ) . '"'; 102 echo 'type="text" value="' . esc_attr( $this->value['background-color'] ) . '"'; 103 echo 'data-default-color="' . esc_attr( $def_bg_color ) . '"'; 104 105 $data = array( 106 'field' => $this->field, 107 'index' => 'color', 108 ); 109 110 echo Redux_Functions_Ex::output_alpha_data( $data); 111 112 echo '>'; 113 114 echo '<input type="hidden" class="redux-saved-color" id="' . esc_attr( $this->field['id'] ) . '-saved-color" value="">'; 115 116 if ( ! isset( $this->field['transparent'] ) || false !== $this->field['transparent'] ) { 117 $is_checked = ''; 118 if ( 'transparent' === $this->value['background-color'] ) { 119 $is_checked = ' checked="checked"'; 120 } 121 echo '<label for="' . esc_attr( $this->field['id'] ) . '-transparency" class="color-transparency-check"><input type="checkbox" class="checkbox color-transparency redux-background-input ' . esc_attr( $this->field['class'] ) . '" id="' . esc_attr( $this->field['id'] ) . '-transparency" data-id="' . esc_attr( $this->field['id'] ) . '-color" value="1" ' . esc_html( $is_checked ) . '> ' . esc_html__( 'Transparent', 'redux-framework' ) . '</label>'; 122 } 123 124 if ( true === $this->field['background-repeat'] || true === $this->field['background-position'] || true === $this->field['background-attachment'] ) { 125 echo '<br />'; 126 } 127 } 128 129 if ( $this->field['background-image'] ) { 130 if ( true === $this->field['background-repeat'] ) { 131 $array = array( 132 'no-repeat' => esc_html__( 'No Repeat', 'redux-framework' ), 133 'repeat' => esc_html__( 'Repeat All', 'redux-framework' ), 134 'repeat-x' => esc_html__( 'Repeat Horizontally', 'redux-framework' ), 135 'repeat-y' => esc_html__( 'Repeat Vertically', 'redux-framework' ), 136 'inherit' => esc_html__( 'Inherit', 'redux-framework' ), 137 ); 138 139 echo '<select id="' . esc_attr( $this->field['id'] ) . '-repeat-select" data-placeholder="' . esc_html__( 'Background Repeat', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-repeat]" class="redux-select-item redux-background-input redux-background-repeat ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 140 echo '<option></option>'; 141 142 foreach ( $array as $k => $v ) { 143 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-repeat'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 144 } 145 146 echo '</select>'; 147 } 148 149 if ( true === $this->field['background-clip'] ) { 150 $array = array( 151 'inherit' => esc_html__( 'Inherit', 'redux-framework' ), 152 'border-box' => esc_html__( 'Border Box', 'redux-framework' ), 153 'content-box' => esc_html__( 'Content Box', 'redux-framework' ), 154 'padding-box' => esc_html__( 'Padding Box', 'redux-framework' ), 155 ); 156 157 echo '<select id="' . esc_attr( $this->field['id'] ) . '-clip-select" data-placeholder="' . esc_html__( 'Background Clip', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-clip]" class="redux-select-item redux-background-input redux-background-clip ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 158 echo '<option></option>'; 159 160 foreach ( $array as $k => $v ) { 161 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-clip'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 162 } 163 164 echo '</select>'; 165 } 166 167 if ( true === $this->field['background-origin'] ) { 168 $array = array( 169 'inherit' => esc_html__( 'Inherit', 'redux-framework' ), 170 'border-box' => esc_html__( 'Border Box', 'redux-framework' ), 171 'content-box' => esc_html__( 'Content Box', 'redux-framework' ), 172 'padding-box' => esc_html__( 'Padding Box', 'redux-framework' ), 173 ); 174 175 echo '<select id="' . esc_attr( $this->field['id'] ) . '-origin-select" data-placeholder="' . esc_html__( 'Background Origin', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-origin]" class="redux-select-item redux-background-input redux-background-origin ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 176 echo '<option></option>'; 177 178 foreach ( $array as $k => $v ) { 179 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-origin'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 180 } 181 182 echo '</select>'; 183 } 184 185 if ( true === $this->field['background-size'] ) { 186 $array = array( 187 'inherit' => esc_html__( 'Inherit', 'redux-framework' ), 188 'cover' => esc_html__( 'Cover', 'redux-framework' ), 189 'contain' => esc_html__( 'Contain', 'redux-framework' ), 190 ); 191 192 echo '<select id="' . esc_attr( $this->field['id'] ) . '-size-select" data-placeholder="' . esc_html__( 'Background Size', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-size]" class="redux-select-item redux-background-input redux-background-size ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 193 echo '<option></option>'; 194 195 foreach ( $array as $k => $v ) { 196 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-size'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 197 } 198 199 echo '</select>'; 200 } 201 202 if ( true === $this->field['background-attachment'] ) { 203 $array = array( 204 'fixed' => esc_html__( 'Fixed', 'redux-framework' ), 205 'scroll' => esc_html__( 'Scroll', 'redux-framework' ), 206 'inherit' => esc_html__( 'Inherit', 'redux-framework' ), 207 ); 208 209 echo '<select id="' . esc_attr( $this->field['id'] ) . '-attachment-select" data-placeholder="' . esc_html__( 'Background Attachment', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-attachment]" class="redux-select-item redux-background-input redux-background-attachment ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 210 echo '<option></option>'; 211 212 foreach ( $array as $k => $v ) { 213 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-attachment'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 214 } 215 216 echo '</select>'; 217 } 218 219 if ( true === $this->field['background-position'] ) { 220 $array = array( 221 'left top' => esc_html__( 'Left Top', 'redux-framework' ), 222 'left center' => esc_html__( 'Left center', 'redux-framework' ), 223 'left bottom' => esc_html__( 'Left Bottom', 'redux-framework' ), 224 'center top' => esc_html__( 'Center Top', 'redux-framework' ), 225 'center center' => esc_html__( 'Center Center', 'redux-framework' ), 226 'center bottom' => esc_html__( 'Center Bottom', 'redux-framework' ), 227 'right top' => esc_html__( 'Right Top', 'redux-framework' ), 228 'right center' => esc_html__( 'Right center', 'redux-framework' ), 229 'right bottom' => esc_html__( 'Right Bottom', 'redux-framework' ), 230 ); 231 232 echo '<select id="' . esc_attr( $this->field['id'] ) . '-position-select" data-placeholder="' . esc_html__( 'Background Position', 'redux-framework' ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-position]" class="redux-select-item redux-background-input redux-background-position ' . esc_attr( $this->field['class'] ) . '"' . esc_attr( $select2_data ) . '>'; 233 echo '<option></option>'; 234 235 foreach ( $array as $k => $v ) { 236 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $this->value['background-position'], $k, false ) . '>' . esc_html( $v ) . '</option>'; 237 } 238 239 echo '</select>'; 240 } 241 } 242 243 if ( $this->field['background-image'] ) { 244 echo '<br />'; 245 246 if ( empty( $this->value ) && ! empty( $this->field['default'] ) ) { 247 if ( is_array( $this->field['default'] ) ) { 248 if ( ! empty( $this->field['default']['media']['id'] ) ) { 249 $this->value['media']['id'] = $this->field['default']['media']['id']; 250 } elseif ( ! empty( $this->field['default']['id'] ) ) { 251 $this->value['media']['id'] = $this->field['default']['id']; 252 } 253 254 if ( ! empty( $this->field['default']['url'] ) ) { 255 $this->value['background-image'] = $this->field['default']['url']; 256 } elseif ( ! empty( $this->field['default']['media']['url'] ) ) { 257 $this->value['background-image'] = $this->field['default']['media']['url']; 258 } elseif ( ! empty( $this->field['default']['background-image'] ) ) { 259 $this->value['background-image'] = $this->field['default']['background-image']; 260 } 261 } else { 262 if ( is_numeric( $this->field['default'] ) ) { // Check if it's an attachment ID. 263 $this->value['media']['id'] = $this->field['default']; 264 } else { // Must be a URL. 265 $this->value['background-image'] = $this->field['default']; 266 } 267 } 268 } 269 270 if ( empty( $this->value['background-image'] ) && ! empty( $this->value['media']['id'] ) ) { 271 $img = wp_get_attachment_image_src( $this->value['media']['id'], 'full' ); 272 $this->value['background-image'] = $img[0]; 273 $this->value['media']['width'] = $img[1]; 274 $this->value['media']['height'] = $img[2]; 275 } 276 277 $hide = 'hide '; 278 279 if ( ( isset( $this->field['preview_media'] ) && false === $this->field['preview_media'] ) ) { 280 $this->field['class'] .= ' noPreview'; 281 } 282 283 if ( ( ! empty( $this->field['background-image'] ) && true === $this->field['background-image'] ) || isset( $this->field['preview'] ) && false === $this->field['preview'] ) { 284 $hide = ''; 285 } 286 287 $placeholder = $this->field['placeholder'] ?? esc_html__( 'No media selected', 'redux-framework' ); 288 289 echo '<input placeholder="' . esc_html( $placeholder ) . '" type="text" class="redux-background-input ' . esc_attr( $hide ) . 'upload ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[background-image]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][background-image]" value="' . esc_url( $this->value['background-image'] ) . '" />'; 290 echo '<input type="hidden" class="upload-id ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][id]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][id]" value="' . esc_attr( $this->value['media']['id'] ) . '" />'; 291 echo '<input type="hidden" class="upload-height" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][height]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][height]" value="' . esc_attr( $this->value['media']['height'] ) . '" />'; 292 echo '<input type="hidden" class="upload-width" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][width]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][width]" value="' . esc_attr( $this->value['media']['width'] ) . '" />'; 293 echo '<input type="hidden" class="upload-thumbnail" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[media][thumbnail]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][media][thumbnail]" value="' . esc_url( $this->value['media']['thumbnail'] ) . '" />'; 294 295 // Preview. 296 $hide = ''; 297 298 if ( ( isset( $this->field['preview_media'] ) && false === $this->field['preview_media'] ) || empty( $this->value['background-image'] ) ) { 299 $hide = 'hide '; 300 } 301 302 if ( empty( $this->value['media']['thumbnail'] ) && ! empty( $this->value['background-image'] ) ) { // Just in case. 303 if ( ! empty( $this->value['media']['id'] ) ) { 304 $image = wp_get_attachment_image_src( 305 $this->value['media']['id'], 306 array( 307 150, 308 150, 309 ) 310 ); 311 312 $this->value['media']['thumbnail'] = $image[0]; 313 } else { 314 $this->value['media']['thumbnail'] = $this->value['background-image']; 315 } 316 } 317 318 echo '<div class="' . esc_attr( $hide ) . 'screenshot">'; 319 echo '<a class="of-uploaded-image" href="' . esc_url( $this->value['background-image'] ) . '" target="_blank">'; 320 321 $alt = wp_prepare_attachment_for_js( $this->value['media']['id'] ); 322 $alt = $alt['alt'] ?? ''; 323 324 echo '<img class="redux-option-image" id="image_' . esc_attr( $this->value['media']['id'] ) . '" src="' . esc_url( $this->value['media']['thumbnail'] ) . '" alt="' . esc_attr( $alt ) . '" target="_blank" rel="external" />'; 325 echo '</a>'; 326 echo '</div>'; 327 328 // Upload controls DIV. 329 echo '<div class="upload_button_div">'; 330 331 // If the user has WP3.5+ show upload/remove button. 332 echo '<span class="button redux-background-upload" id="' . esc_attr( $this->field['id'] ) . '-media">' . esc_html__( 'Upload', 'redux-framework' ) . '</span>'; 333 334 $hide = ''; 335 if ( empty( $this->value['background-image'] ) || '' === $this->value['background-image'] ) { 336 $hide = ' hide'; 337 } 338 339 echo '<span class="button removeCSS redux-remove-background' . esc_attr( $hide ) . '" id="reset_' . esc_attr( $this->field['id'] ) . '" rel="' . esc_attr( $this->field['id'] ) . '">' . esc_html__( 'Remove', 'redux-framework' ) . '</span>'; 340 341 echo '</div>'; 342 } 343 344 /** 345 * Preview 346 * */ 347 if ( ! isset( $this->field['preview'] ) || false !== $this->field['preview'] ) { 348 $css = $this->css_style( $this->value ); 349 350 $is_bg = strpos( $css, 'background-image' ); 351 352 if ( empty( $css ) || ! $is_bg ) { 353 $css = 'display:none;'; 354 } 355 356 $css .= 'height: ' . esc_attr( $this->field['preview_height'] ) . ';'; 357 echo '<p class="clear ' . esc_attr( $this->field['id'] ) . '_previewer background-preview" style="' . esc_attr( $css ) . '"> </p>'; 358 } 359 } 360 361 /** 362 * Enqueue Function. 363 * If this field requires any scripts, or css define this function and register/enqueue the scripts/css 364 * 365 * @since 1.0.0 366 * @access public 367 * @return void 368 */ 369 public function enqueue() { 370 if ( function_exists( 'wp_enqueue_media' ) ) { 371 wp_enqueue_media(); 372 } else { 373 if ( ! wp_script_is( 'media-upload' ) ) { 374 wp_enqueue_script( 'media-upload' ); 375 } 376 } 377 378 if ( ! wp_style_is( 'select2-css' ) ) { 379 wp_enqueue_style( 'select2-css' ); 380 } 381 382 if ( ! wp_style_is( 'wp-color-picker' ) ) { 383 wp_enqueue_style( 'wp-color-picker' ); 384 } 385 386 $dep_array = array( 'jquery', 'wp-color-picker', 'select2-js', 'redux-js' ); 387 388 wp_enqueue_script( 389 'redux-field-background-js', 390 Redux_Core::$url . 'inc/fields/background/redux-background' . Redux_Functions::is_min() . '.js', 391 $dep_array, 392 $this->timestamp, 393 true 394 ); 395 396 if ( $this->parent->args['dev_mode'] ) { 397 wp_enqueue_style( 398 'redux-field-background-css', 399 Redux_Core::$url . 'inc/fields/background/redux-background.css', 400 array(), 401 $this->timestamp 402 ); 403 404 wp_enqueue_style( 'redux-color-picker-css' ); 405 } 406 } 407 408 /** 409 * Output CSS styling. 410 * 411 * @param array $data Value array. 412 * 413 * @return string 414 */ 415 public function css_style( $data = array() ): string { 416 $css = ''; 417 418 if ( ! empty( $data ) && is_array( $data ) ) { 419 foreach ( $data as $key => $val ) { 420 if ( ! empty( $val ) && 'media' !== $key ) { 421 if ( 'background-image' === $key ) { 422 $css .= $key . ":url('" . esc_url( $val ) . "');"; 423 } else { 424 $css .= $key . ':' . esc_attr( $val ) . ';'; 425 } 426 } 427 } 428 } 429 430 return $css; 431 } 432 433 /** 434 * Enable output_variables to be generated. 435 * 436 * @since 4.0.3 437 * @return void 438 */ 439 public function output_variables() { 440 // No code needed, just defining the method is enough. 441 } 442 } 443 } 444 445 class_alias( 'Redux_Background', 'ReduxFramework_Background' );