| @@ -1,10 +1,10 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace FilterEverything\Filter; |
| 4 | 4 | |
| 5 | -if ( ! defined('WPINC') ) { | |
| 6 | - wp_die(); | |
| 5 | +if ( ! defined('ABSPATH') ) { | |
| 6 | + exit; | |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | abstract class BaseSettings implements TabInterface{ |
| 10 | 10 | |
| @@ -18,19 +18,25 @@ | ||
| 18 | 18 | |
| 19 | 19 | protected function registerSettings($settings, $page, $optionName) |
| 20 | 20 | { |
| 21 | 21 | $callbacks = array( |
| 22 | - 'checkbox' => array($this, 'checkboxCallback'), | |
| 23 | - 'text' => array($this, 'inputCallback'), | |
| 24 | - 'textarea' => array($this, 'textareaCallback'), | |
| 25 | - 'editor' => array($this, 'textEditorCallback'), | |
| 26 | - 'select' => array($this, 'selectCallback'), | |
| 27 | - 'hidden' => array($this, 'hiddenCallback') | |
| 22 | + 'checkbox' => array($this, 'checkboxCallback'), | |
| 23 | + 'text' => array($this, 'inputCallback'), | |
| 24 | + 'license' => array($this, 'licenseCallback'), | |
| 25 | + 'textarea' => array($this, 'textareaCallback'), | |
| 26 | + 'editor' => array($this, 'textEditorCallback'), | |
| 27 | + 'select' => array($this, 'selectCallback'), | |
| 28 | + 'hidden' => array($this, 'hiddenCallback'), | |
| 29 | + 'file' => array($this, 'fileCallback'), | |
| 30 | + 'number' => array($this, 'numberCallback'), | |
| 31 | + 'inProButton' => array($this, 'inProButtonCallback'), | |
| 32 | + 'html' => array($this, 'htmlCallback'), | |
| 28 | 33 | ); |
| 29 | 34 | |
| 30 | 35 | foreach ($settings as $sectionId => $section) { |
| 31 | 36 | $callback = isset($section['callback']) ? $section['callback'] : null; |
| 32 | - add_settings_section($sectionId, $section['label'], $callback, $page); | |
| 37 | + $args = isset($section['args']) ? $section['args'] : array(); | |
| 38 | + add_settings_section($sectionId, $section['label'], $callback, $page, $args ); | |
| 33 | 39 | |
| 34 | 40 | if( isset( $section['fields'] ) ){ |
| 35 | 41 | foreach ( $section['fields'] as $fieldId => $field) { |
| 36 | 42 | $title = isset($field['title']) ? $field['title'] : ''; |
| @@ -45,16 +51,25 @@ | ||
| 45 | 51 | } |
| 46 | 52 | |
| 47 | 53 | public function checkBoxCallback($args) |
| 48 | 54 | { |
| 49 | - $checkbox = '<label><input type="checkbox" name="%s[%s]" %s id="%s">%s</label>'; | |
| 55 | + | |
| 56 | + $args = wp_parse_args( $args, array( | |
| 57 | + 'checked' => false, | |
| 58 | + 'disabled' => false, | |
| 59 | + 'label' => '', | |
| 60 | + ) ); | |
| 61 | + | |
| 62 | + $checkbox = '<label><input type="checkbox" name="%s[%s]" %s id="%s" %s>%s</label>'; | |
| 50 | 63 | $checkbox = apply_filters( 'wpc_settings_field_checkbox', $checkbox, $args ); |
| 51 | 64 | $checked = $this->getOption($args['label_for']); |
| 52 | 65 | |
| 53 | - if ($checked == '1') { | |
| 66 | + if ( $checked == '1' || $args['checked'] === true ) { | |
| 54 | 67 | $checked = 'on'; |
| 55 | 68 | } |
| 56 | 69 | |
| 70 | + $disabled = ( $args['disabled'] === true ) ? 'disabled' : ''; | |
| 71 | + | |
| 57 | 72 | printf( |
| 58 | 73 | $checkbox, |
| 59 | 74 | esc_attr($args['option_name']), |
| 60 | 75 | esc_attr($args['label_for']), |
| @@ -59,8 +74,9 @@ | ||
| 59 | 74 | esc_attr($args['option_name']), |
| 60 | 75 | esc_attr($args['label_for']), |
| 61 | 76 | checked('on', $checked, false), |
| 62 | 77 | esc_attr($args['id']), |
| 78 | + esc_attr($disabled), | |
| 63 | 79 | esc_html($args['label']) |
| 64 | 80 | ); |
| 65 | 81 | |
| 66 | 82 | if( isset( $args['description'] ) ){ |
| @@ -67,8 +83,9 @@ | ||
| 67 | 83 | printf( '<p class="description">%s</p>', esc_html( $args['description'] ) ); |
| 68 | 84 | } |
| 69 | 85 | } |
| 70 | 86 | |
| 87 | + | |
| 71 | 88 | public function inputCallback($args) |
| 72 | 89 | { |
| 73 | 90 | $input = '<input class="%s" type="text" name="%s[%s]" value="%s" placeholder="%s" id="%s">'; |
| 74 | 91 | $class = isset( $args['class'] ) ? $args['class'] : 'regular-text'; |
| @@ -77,9 +94,11 @@ | ||
| 77 | 94 | }else{ |
| 78 | 95 | $value = $this->getOption($args['label_for']); |
| 79 | 96 | } |
| 80 | 97 | |
| 81 | - $value = trim($value); | |
| 98 | + if (!is_null($value)) { | |
| 99 | + $value = trim($value); | |
| 100 | + } | |
| 82 | 101 | |
| 83 | 102 | printf( |
| 84 | 103 | $input, |
| 85 | 104 | esc_attr($class), |
| @@ -89,12 +108,53 @@ | ||
| 89 | 108 | esc_attr($args['placeholder']), |
| 90 | 109 | esc_attr($args['id']) |
| 91 | 110 | ); |
| 92 | 111 | |
| 112 | + if(!empty($args['additional_link'])){ | |
| 113 | + echo '<a id="wpc-choose-selector-button" href="' . esc_url($args['additional_link']['url']) . '" class="button">' . esc_html($args['additional_link']['label']) . '</a>'; | |
| 114 | + } | |
| 115 | + | |
| 93 | 116 | if( isset($args['id']) && $args['id'] === 'posts_container' ){ |
| 117 | + if( flrt_get_option('enable_ajax') === 'on' && ! $value ){ | |
| 118 | + printf( '<p class="wpc-warning">%s</p>', esc_html__( 'You must specify the Results container, otherwise AJAX will not work properly', 'filter-everything' ) ); | |
| 119 | + } | |
| 94 | 120 | |
| 121 | + } | |
| 122 | + | |
| 123 | + if( isset( $args['description'] ) ){ | |
| 124 | + printf( '<p class="description">%s</p>', esc_html( $args['description'] ) ); | |
| 125 | + } | |
| 126 | + | |
| 127 | + } | |
| 128 | + | |
| 129 | + public function numberCallback($args) | |
| 130 | + { | |
| 131 | + $input = '<input class="%s" type="number" name="%s[%s]" value="%s" placeholder="%s" id="%s">'; | |
| 132 | + $class = isset( $args['class'] ) ? $args['class'] : 'regular-text'; | |
| 133 | + if( isset( $args['default'] ) ){ | |
| 134 | + $value = $this->getOption($args['label_for']) ? $this->getOption($args['label_for']) : $args['default']; | |
| 135 | + }else{ | |
| 136 | + $value = $this->getOption($args['label_for']); | |
| 137 | + } | |
| 138 | + | |
| 139 | + if (!is_null($value)) { | |
| 140 | + $value = trim($value); | |
| 141 | + } | |
| 142 | + | |
| 143 | + printf( | |
| 144 | + $input, | |
| 145 | + esc_attr($class), | |
| 146 | + esc_attr($this->optionName), | |
| 147 | + esc_attr($args['label_for']), | |
| 148 | + esc_attr($value), | |
| 149 | + esc_attr($args['placeholder']), | |
| 150 | + esc_attr($args['id']) | |
| 151 | + ); | |
| 152 | + | |
| 153 | + if( isset($args['id']) && $args['id'] === 'posts_container' ){ | |
| 154 | + | |
| 95 | 155 | if( flrt_get_option('enable_ajax') === 'on' && ! $value ){ |
| 96 | - printf( '<p class="wpc-warning">%s</p>', esc_html__( 'You must specify Posts Container, otherwise AJAX will not work properly', 'filter-everything' ) ); | |
| 156 | + printf( '<p class="wpc-warning">%s</p>', esc_html__( 'You must specify the Results container, otherwise AJAX will not work properly', 'filter-everything' ) ); | |
| 97 | 157 | } |
| 98 | 158 | } |
| 99 | 159 | |
| 100 | 160 | if( isset( $args['description'] ) ){ |
| @@ -102,8 +162,32 @@ | ||
| 102 | 162 | } |
| 103 | 163 | |
| 104 | 164 | } |
| 105 | 165 | |
| 166 | + public function licenseCallback( $args ) | |
| 167 | + { | |
| 168 | + $input = '<input class="%s" type="text" readonly="readonly" name="%s[%s]" value="%s" placeholder="%s" id="%s">'; | |
| 169 | + $class = isset( $args['class'] ) ? $args['class'] : 'regular-text'; | |
| 170 | + | |
| 171 | + $value = str_repeat( '*', 80 ); | |
| 172 | + $value = trim($value); | |
| 173 | + | |
| 174 | + printf( | |
| 175 | + $input, | |
| 176 | + esc_attr($class), | |
| 177 | + esc_attr($this->optionName), | |
| 178 | + esc_attr($args['label_for']), | |
| 179 | + esc_attr($value), | |
| 180 | + esc_attr($args['placeholder']), | |
| 181 | + esc_attr($args['id']) | |
| 182 | + ); | |
| 183 | + | |
| 184 | + if( isset( $args['description'] ) ){ | |
| 185 | + printf( '<p class="description">%s</p>', esc_html( $args['description'] ) ); | |
| 186 | + } | |
| 187 | + | |
| 188 | + } | |
| 189 | + | |
| 106 | 190 | public function hiddenCallback( $args ) |
| 107 | 191 | { |
| 108 | 192 | $input = '<input class="%s" type="hidden" name="%s[%s]" value="%s" placeholder="%s" id="%s">'; |
| 109 | 193 | $class = isset( $args['class'] ) ? $args['class'] : 'regular-text'; |
| @@ -117,11 +201,29 @@ | ||
| 117 | 201 | esc_attr($args['id']) |
| 118 | 202 | ); |
| 119 | 203 | } |
| 120 | 204 | |
| 121 | - public function selectCallback($args) | |
| 205 | + public function fileCallback( $args ) | |
| 122 | 206 | { |
| 207 | + $input = '<label for="%s" class="flrt-file-upload"><input class="%s" type="file" name="%s[%s]" value="%s" placeholder="%s" id="%s" %s></label>'; | |
| 208 | + $class = isset( $args['class'] ) ? $args['class'] : 'regular-text'; | |
| 209 | + printf( | |
| 210 | + $input, | |
| 211 | + esc_attr($args['id']), | |
| 212 | + esc_attr($class), | |
| 213 | + esc_attr($this->optionName), | |
| 214 | + esc_attr($args['label_for']), | |
| 215 | + esc_attr($this->getOption($args['label_for'])), | |
| 216 | + esc_attr($args['placeholder']), | |
| 217 | + esc_attr($args['id']), | |
| 218 | + esc_attr($args['required']) | |
| 219 | + ); | |
| 220 | + } | |
| 221 | + | |
| 222 | + public function selectCallback( $args ) | |
| 223 | + { | |
| 123 | 224 | $options = isset($args['options']) ? $args['options'] : []; |
| 225 | + $disabled = isset($args['disabled']) ? $args['disabled'] : []; | |
| 124 | 226 | $class = isset( $args['class'] ) ? $args['class'] : 'filter-settings-select'; |
| 125 | 227 | $value = $this->getOption($args['label_for']); |
| 126 | 228 | |
| 127 | 229 | $multiple = ! empty($args['multiple']) ? 'multiple' : null; |
| @@ -148,10 +250,14 @@ | ||
| 148 | 250 | } |
| 149 | 251 | } else { |
| 150 | 252 | $selected = ''; |
| 151 | 253 | } |
| 254 | + $disabled_option = ''; | |
| 255 | + if( in_array($key, $disabled) ){ | |
| 256 | + $disabled_option = 'disabled'; | |
| 257 | + } | |
| 152 | 258 | |
| 153 | - printf('<option value="%s" %s>%s</option>', esc_attr($key), $selected, esc_html($option)); | |
| 259 | + printf('<option value="%s" %s%s>%s</option>', esc_attr($key), $selected, $disabled_option, esc_html($option)); | |
| 154 | 260 | } |
| 155 | 261 | |
| 156 | 262 | print('</select>'); |
| 157 | 263 | |
| @@ -168,8 +274,13 @@ | ||
| 168 | 274 | public function textareaCallback($args) |
| 169 | 275 | { |
| 170 | 276 | $textarea = '<textarea class="filter-settings-input large-text code" name="%s[%s]" placeholder="%s" cols="30" rows="10" id="%s">%s</textarea>'; |
| 171 | 277 | |
| 278 | + $textarea_text = $this->getOption($args['label_for']); | |
| 279 | + if(empty($textarea_text)){ | |
| 280 | + $textarea_text = ''; | |
| 281 | + } | |
| 282 | + | |
| 172 | 283 | printf( |
| 173 | 284 | $textarea, |
| 174 | 285 | esc_attr($this->optionName), |
| 175 | 286 | esc_attr($args['label_for']), |
| @@ -174,9 +285,9 @@ | ||
| 174 | 285 | esc_attr($this->optionName), |
| 175 | 286 | esc_attr($args['label_for']), |
| 176 | 287 | esc_attr($args['placeholder']), |
| 177 | 288 | esc_attr($args['id']), |
| 178 | - esc_textarea( $this->getOption($args['label_for']) ) | |
| 289 | + esc_textarea( $textarea_text ) | |
| 179 | 290 | ); |
| 180 | 291 | |
| 181 | 292 | } |
| 182 | 293 | |
| @@ -203,9 +314,12 @@ | ||
| 203 | 314 | $this->doSettingsSections($this->page); |
| 204 | 315 | |
| 205 | 316 | do_action('wpc_after_sections_settings_fields', $this->page ); |
| 206 | 317 | |
| 207 | - submit_button(); | |
| 318 | + if( apply_filters('wpc_settings_submit_button', true ) ){ | |
| 319 | + submit_button(); | |
| 320 | + } | |
| 321 | + | |
| 208 | 322 | print('</form>'); |
| 209 | 323 | } |
| 210 | 324 | |
| 211 | 325 | public function doSettingsSections( $page ) { |
| @@ -238,8 +352,9 @@ | ||
| 238 | 352 | echo '<table class="wpc-form-table form-table'.esc_attr($sortable).'" role="presentation">'; |
| 239 | 353 | $this->doSettingsFields( $page, $section['id'] ); |
| 240 | 354 | echo '</table>'; |
| 241 | 355 | } |
| 356 | + do_action('wpc_after_settings_fields', $page ); | |
| 242 | 357 | } |
| 243 | 358 | |
| 244 | 359 | public function doSettingsFields( $page, $section ) { |
| 245 | 360 | global $wp_settings_fields; |
| @@ -246,8 +361,9 @@ | ||
| 246 | 361 | |
| 247 | 362 | if ( ! isset( $wp_settings_fields[ $page ][ $section ] ) ) { |
| 248 | 363 | return; |
| 249 | 364 | } |
| 365 | + | |
| 250 | 366 | $i = 1; |
| 251 | 367 | |
| 252 | 368 | foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) { |
| 253 | 369 | $class = ''; |
| @@ -252,20 +368,29 @@ | ||
| 252 | 368 | foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) { |
| 253 | 369 | $class = ''; |
| 254 | 370 | |
| 255 | 371 | if( $field['id'] === 'bottom_widget_compatibility' ){ |
| 256 | - if( flrt_get_option('show_bottom_widget') === 'on' ){ | |
| 372 | + if( flrt_get_option('mobile_filter_settings') === 'show_bottom_widget' ){ | |
| 257 | 373 | $field['args']['class'] .= ' wpc-opened'; |
| 258 | 374 | } |
| 259 | 375 | } |
| 260 | 376 | |
| 377 | + if( $field['id'] === 'color_swatches_taxonomies' || $field['id'] === 'rounded_swatches' ) { | |
| 378 | + if( flrt_get_experimental_option('use_color_swatches') === 'on' ) { | |
| 379 | + $field['args']['class'] .= ' wpc-opened'; | |
| 380 | + } | |
| 381 | + } | |
| 382 | + | |
| 261 | 383 | if ( ! empty( $field['args']['class'] ) ) { |
| 262 | 384 | $class = ' class="' . esc_attr( $field['args']['class'] ) . '"'; |
| 263 | 385 | } |
| 264 | 386 | |
| 387 | + do_action('wpc_before_settings_field', $field ); | |
| 388 | + | |
| 265 | 389 | echo "<tr{$class}>"; |
| 266 | 390 | |
| 267 | 391 | $sortable = isset( $field['args']['sortable'] ) ? $i : ''; |
| 392 | + | |
| 268 | 393 | if( $sortable ){ |
| 269 | 394 | echo '<td class="wpc-order-td">'.esc_html($sortable).'</td>'; |
| 270 | 395 | } |
| 271 | 396 | |
| @@ -273,16 +398,24 @@ | ||
| 273 | 398 | $tooltip = wp_kses( |
| 274 | 399 | $tooltip, |
| 275 | 400 | array( |
| 276 | 401 | 'strong' => array(), |
| 277 | - 'br' => array(), | |
| 402 | + 'br' => array(), | |
| 278 | 403 | 'a' => array( 'href'=>true, 'title'=>true, 'class'=>true ), |
| 279 | 404 | 'span' => array( 'class'=>true, 'data-tip'=>true) |
| 280 | 405 | ) |
| 281 | 406 | ); |
| 282 | 407 | |
| 408 | + | |
| 409 | + $enabled_in_pro_string = ''; | |
| 410 | + $enabled_in_pro_class = ''; | |
| 411 | + if( !empty($field['args']['pro_label']) ){ | |
| 412 | + $enabled_in_pro_string = $field['args']['pro_label']; | |
| 413 | + $enabled_in_pro_class = 'class="wpc-row-pro-only wpc-pro-badge-text"'; | |
| 414 | + } | |
| 415 | + | |
| 283 | 416 | if ( ! empty( $field['args']['label_for'] ) ) { |
| 284 | - echo '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . esc_html($field['title']) . '</label> ' .$tooltip. '</th>'; // $tooltip already escaped | |
| 417 | + echo '<th scope="row" ' . $enabled_in_pro_class. '><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . esc_html($field['title']) . '</label> ' .$tooltip. $enabled_in_pro_string . '</th>'; // $tooltip already escaped | |
| 285 | 418 | } else { |
| 286 | 419 | echo '<th scope="row">'. esc_html($field['title'] ) . ' ' .$tooltip. '</th>'; // $tooltip already escaped |
| 287 | 420 | } |
| 288 | 421 | |
| @@ -290,13 +423,16 @@ | ||
| 290 | 423 | call_user_func( $field['callback'], $field['args'] ); |
| 291 | 424 | echo '</td>'; |
| 292 | 425 | |
| 293 | 426 | if( $sortable ){ |
| 294 | - $title = ( ! defined( 'FLRT_FILTERS_PRO' ) ) ? __( 'Editing the order of URL prefixes is available in PRO version', 'filter-everything' ) : ''; | |
| 427 | + $title = ( ! defined( 'FLRT_FILTERS_PRO' ) ) ? __( 'Editing the order of URL prefixes is available in the PRO version', 'filter-everything' ) : ''; | |
| 295 | 428 | echo '<td class="wpc-order-sortable-handle-icon"><span class="dashicons dashicons-menu wpc-field-sortable-handle" title="'.esc_attr( $title ).'"> </span></td>'; |
| 296 | 429 | } |
| 297 | 430 | |
| 298 | 431 | echo '</tr>'; |
| 432 | + | |
| 433 | + do_action('wpc_after_settings_field', $field ); | |
| 434 | + | |
| 299 | 435 | $i++; |
| 300 | 436 | } |
| 301 | 437 | } |
| 302 | 438 | |
| @@ -306,6 +442,32 @@ | ||
| 306 | 442 | $this->options = get_option($this->optionName); |
| 307 | 443 | } |
| 308 | 444 | |
| 309 | 445 | return isset($this->options[$key]) ? $this->options[$key] : $default; |
| 446 | + } | |
| 447 | + | |
| 448 | + public function inProButtonCallback($args) | |
| 449 | + { | |
| 450 | + echo flrt_unlock_in_pro(); | |
| 451 | + | |
| 452 | + if( isset( $args['description'] ) ){ | |
| 453 | + printf( '<p class="description">%s</p>', esc_html( $args['description'] ) ); | |
| 454 | + } | |
| 455 | + } | |
| 456 | + | |
| 457 | + /** | |
| 458 | + * Read-only field: delegates the cell markup to $args['render'] (callable | |
| 459 | + * receiving $args) or echoes pre-escaped $args['html']. Nothing is saved — | |
| 460 | + * for generated previews, hints and code blocks inside a settings table. | |
| 461 | + */ | |
| 462 | + public function htmlCallback($args) | |
| 463 | + { | |
| 464 | + if ( isset( $args['render'] ) && is_callable( $args['render'] ) ) { | |
| 465 | + call_user_func( $args['render'], $args ); | |
| 466 | + return; | |
| 467 | + } | |
| 468 | + | |
| 469 | + if ( isset( $args['html'] ) ) { | |
| 470 | + echo wp_kses_post( $args['html'] ); | |
| 471 | + } | |
| 310 | 472 | } |
| 311 | 473 | } |