class-redux-media.php (10968B)
1 <?php 2 /** 3 * Media Picker 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_Media', false ) ) { 14 15 /** 16 * Main Redux_media class 17 * 18 * @since 1.0.0 19 */ 20 class Redux_Media extends Redux_Field { 21 22 /** 23 * Flag to filter file types. 24 * 25 * @var bool $filters_enabled . 26 */ 27 private $filters_enabled = false; 28 29 /** 30 * Set field and value defaults. 31 */ 32 public function set_defaults() { 33 // No errors please. 34 $defaults = array( 35 'id' => '', 36 'url' => '', 37 'width' => '', 38 'height' => '', 39 'thumbnail' => '', 40 'filter' => array( 41 'grayscale' => array( 42 'checked' => false, 43 'value' => 0, 44 ), 45 'blur' => array( 46 'checked' => false, 47 'value' => 0, 48 ), 49 'sepia' => array( 50 'checked' => false, 51 'value' => 0, 52 ), 53 'saturate' => array( 54 'checked' => false, 55 'value' => 1, 56 ), 57 'opacity' => array( 58 'checked' => false, 59 'value' => 1, 60 ), 61 'brightness' => array( 62 'checked' => false, 63 'value' => 100, 64 ), 65 'contrast' => array( 66 'checked' => false, 67 'value' => 100, 68 ), 69 'hue-rotate' => array( 70 'checked' => false, 71 'value' => 0, 72 ), 73 'invert' => array( 74 'checked' => false, 75 'value' => 0, 76 ), 77 ), 78 ); 79 80 // Since value subarrays do not get parsed in wp_parse_args! 81 $this->value = Redux_Functions::parse_args( $this->value, $defaults ); 82 83 $defaults = array( 84 'mode' => 'image', 85 'preview' => true, 86 'preview_size' => 'thumbnail', 87 'url' => true, 88 'alt' => '', 89 'placeholder' => esc_html__( 'No media selected', 'redux-framework' ), 90 'readonly' => true, 91 'class' => '', 92 'filter' => array( 93 'grayscale' => false, 94 'blur' => false, 95 'sepia' => false, 96 'saturate' => false, 97 'opacity' => false, 98 'brightness' => false, 99 'contrast' => false, 100 'hue-rotate' => false, 101 'invert' => false, 102 ), 103 ); 104 105 $this->field = Redux_Functions::parse_args( $this->field, $defaults ); 106 107 if ( false === $this->field['mode'] ) { 108 $this->field['mode'] = 0; 109 } 110 111 include_once Redux_Core::$dir . 'inc/lib/image-filters/class-redux-image-filters.php'; 112 if ( in_array( true, $this->field['filter'], true ) ) { 113 $this->filters_enabled = true; 114 include_once Redux_Core::$dir . 'inc/lib/image-filters/class-redux-image-filters.php'; 115 } 116 } 117 118 /** 119 * Field Render Function. 120 * Takes the vars and outputs the HTML for the field in the settings 121 * 122 * @since 1.0.0 123 * @access public 124 * @return void 125 */ 126 public function render() { 127 if ( ! isset( $this->field['library_filter'] ) ) { 128 $lib_filter = ''; 129 } else { 130 if ( ! is_array( $this->field['library_filter'] ) ) { 131 $this->field['library_filter'] = array( $this->field['library_filter'] ); 132 } 133 134 $mime_types = get_allowed_mime_types(); 135 136 $lib_array = $this->field['library_filter']; 137 138 $json_arr = array(); 139 140 // Enum mime types. 141 foreach ( $mime_types as $ext => $type ) { 142 if ( strpos( $ext, '|' ) ) { 143 $ex_arr = explode( '|', $ext ); 144 145 foreach ( $ex_arr as $ext ) { 146 if ( in_array( $ext, $lib_array, true ) ) { 147 $json_arr[ $ext ] = $type; 148 } 149 } 150 } elseif ( in_array( $ext, $lib_array, true ) ) { 151 $json_arr[ $ext ] = $type; 152 } 153 } 154 155 $lib_filter = rawurlencode( wp_json_encode( $json_arr ) ); 156 } 157 158 if ( empty( $this->value ) && ! empty( $this->field['default'] ) ) { // If there are standard values and value is empty. 159 if ( is_array( $this->field['default'] ) ) { 160 if ( ! empty( $this->field['default']['id'] ) ) { 161 $this->value['id'] = $this->field['default']['id']; 162 } 163 164 if ( ! empty( $this->field['default']['url'] ) ) { 165 $this->value['url'] = $this->field['default']['url']; 166 } 167 } else { 168 if ( is_numeric( $this->field['default'] ) ) { // Check if it's an attachment ID. 169 $this->value['id'] = $this->field['default']; 170 } else { // Must be a URL. 171 $this->value['url'] = $this->field['default']; 172 } 173 } 174 } 175 176 if ( empty( $this->value['url'] ) && ! empty( $this->value['id'] ) ) { 177 $img = wp_get_attachment_image_src( $this->value['id'], 'full' ); 178 $this->value['url'] = $img[0]; 179 $this->value['width'] = $img[1]; 180 $this->value['height'] = $img[2]; 181 } 182 183 $hide = 'hide '; 184 185 if ( false === $this->field['preview'] ) { 186 $this->field['class'] .= ' noPreview'; 187 } 188 189 if ( ( ! empty( $this->field['url'] ) && true === $this->field['url'] ) || false === $this->field['preview'] ) { 190 $hide = ''; 191 } 192 193 $read_only = ''; 194 if ( $this->field['readonly'] ) { 195 $read_only = ' readonly="readonly"'; 196 } 197 198 echo '<input placeholder="' . esc_attr( $this->field['placeholder'] ) . '" type="text" class="' . esc_attr( $hide ) . 'upload large-text ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[url]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][url]" value="' . esc_attr( $this->value['url'] ) . '"' . esc_html( $read_only ) . '/>'; 199 echo '<input type="hidden" class="data" data-preview-size="' . esc_attr( $this->field['preview_size'] ) . '" data-mode="' . esc_attr( $this->field['mode'] ) . '" />'; 200 echo '<input type="hidden" class="library-filter" data-lib-filter="' . $lib_filter . '" />'; // phpcs:ignore WordPress.Security.EscapeOutput 201 echo '<input type="hidden" class="upload-id ' . esc_attr( $this->field['class'] ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[id]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][id]" value="' . esc_attr( $this->value['id'] ) . '" />'; 202 echo '<input type="hidden" class="upload-height" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[height]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][height]" value="' . esc_attr( $this->value['height'] ) . '" />'; 203 echo '<input type="hidden" class="upload-width" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[width]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][width]" value="' . esc_attr( $this->value['width'] ) . '" />'; 204 echo '<input type="hidden" class="upload-thumbnail" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[thumbnail]" id="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][thumbnail]" value="' . esc_attr( $this->value['thumbnail'] ) . '" />'; 205 206 // Preview. 207 $hide = ''; 208 209 if ( ( false === $this->field['preview'] ) || empty( $this->value['url'] ) ) { 210 $hide .= 'display:none;'; 211 } 212 213 if ( empty( $this->value['thumbnail'] ) && ! empty( $this->value['url'] ) ) { // Just in case. 214 if ( ! empty( $this->value['id'] ) ) { 215 $image = wp_get_attachment_image_src( $this->value['id'], array( 150, 150 ) ); 216 217 if ( empty( $image[0] ) || '' === $image[0] ) { 218 $this->value['thumbnail'] = $this->value['url']; 219 } else { 220 $this->value['thumbnail'] = $image[0]; 221 } 222 } else { 223 $this->value['thumbnail'] = $this->value['url']; 224 } 225 } 226 227 $css = ''; 228 229 $css = $this->get_filter_css( $this->value['filter'] ); 230 231 $alt = wp_prepare_attachment_for_js( $this->value['id'] ); 232 $alt = $alt['alt'] ?? ''; 233 234 echo '<div class="screenshot" style="' . esc_attr( $hide ) . '">'; 235 echo '<a class="of-uploaded-image" href="' . esc_url( $this->value['url'] ) . '" target="_blank">'; 236 echo '<img class="redux-option-image" id="image_' . esc_attr( $this->field['id'] ) . '" src="' . esc_url( $this->value['thumbnail'] ) . '" alt="' . esc_attr( $alt ) . '" target="_blank" rel="external" style="' . $css . '" />'; // phpcs:ignore WordPress.Security.EscapeOutput 237 echo '</a>'; 238 echo '</div>'; 239 240 // Upload controls DIV. 241 echo '<div class="upload_button_div">'; 242 243 // If the user has WP3.5+ show upload/remove button. 244 echo '<span class="button media_upload_button" id="' . esc_attr( $this->field['id'] ) . '-media">' . esc_html__( 'Upload', 'redux-framework' ) . '</span>'; 245 246 $hide = ''; 247 if ( empty( $this->value['url'] ) || '' === $this->value['url'] ) { 248 $hide = ' hide'; 249 } 250 251 echo '<span class="button remove-image' . esc_attr( $hide ) . '" id="reset_' . esc_attr( $this->field['id'] ) . '" rel="' . esc_attr( $this->field['id'] ) . '">' . esc_html__( 'Remove', 'redux-framework' ) . '</span>'; 252 echo '</div>'; 253 254 if ( $this->filters_enabled ) { 255 $data = array( 256 'parent' => $this->parent, 257 'field' => $this->field, 258 'value' => $this->value, 259 'mode' => 'media', 260 ); 261 262 echo Redux_Image_Filters::render( $data ); 263 } 264 } 265 266 /** 267 * Enqueue Function. 268 * If this field requires any scripts, or CSS define this function and register/enqueue the scripts/css 269 * 270 * @since 1.0.0 271 * @access public 272 * @return void 273 */ 274 public function enqueue() { 275 if ( function_exists( 'wp_enqueue_media' ) ) { 276 wp_enqueue_media(); 277 } else { 278 wp_enqueue_script( 'media-upload' ); 279 } 280 281 if ( $this->filters_enabled ) { 282 Redux_Image_Filters::enqueue( $this->field, $this->filters_enabled ); 283 } 284 285 wp_enqueue_script( 286 'redux-field-media-js', 287 Redux_Core::$url . 'assets/js/media/media' . Redux_Functions::is_min() . '.js', 288 array( 'jquery', 'redux-js' ), 289 $this->timestamp, 290 true 291 ); 292 293 if ( $this->parent->args['dev_mode'] ) { 294 wp_enqueue_style( 'redux-field-media-css' ); 295 } 296 } 297 298 /** 299 * Compile CSS styles for output. 300 * 301 * @param string $data CSS data. 302 * 303 * @return string|null 304 */ 305 public function css_style( $data ): string { 306 if ( isset( $data['filter'] ) ) { 307 return $this->get_filter_css( $data['filter'] ); 308 } 309 310 return ''; 311 } 312 313 /** 314 * Get filter CSS. 315 * 316 * @param array $data Data. 317 * 318 * @return string 319 */ 320 private function get_filter_css( array $data ): string { 321 $css = ''; 322 323 foreach ( $data as $filter => $values ) { 324 $checked = filter_var( $values['checked'], FILTER_VALIDATE_BOOLEAN ); 325 326 if ( true === $checked ) { 327 $unit = Redux_Image_Filters::get_filter_unit( $filter ); 328 329 if ( '°' === $unit ) { 330 $unit = 'deg'; 331 } 332 333 $css .= ' ' . $filter . '(' . $values['value'] . $unit . ')'; 334 } 335 } 336 337 if ( '' !== $css ) { 338 return 'filter:' . $css . ';-webkit-filter:' . $css . ';'; 339 } 340 341 return ''; 342 } 343 344 } 345 } 346 347 class_alias( 'Redux_Media', 'ReduxFramework_Media' );