challenge
1 year ago
css
6 days ago
img
1 year ago
js
1 month ago
menu
1 month ago
partials
1 week ago
rest-api
6 days ago
scss
1 year ago
settings
6 days ago
uninstall
1 year ago
wpchill
1 month ago
admin-notices.php
5 months ago
admin.php
1 month ago
class-strong-testimonials-addons.php
1 month ago
class-strong-testimonials-admin-category-list.php
1 year ago
class-strong-testimonials-admin-list.php
1 year ago
class-strong-testimonials-admin-scripts.php
1 month ago
class-strong-testimonials-admin.php
1 month ago
class-strong-testimonials-debug.php
5 months ago
class-strong-testimonials-exporter.php
1 year ago
class-strong-testimonials-help.php
1 year ago
class-strong-testimonials-helper.php
1 month ago
class-strong-testimonials-list-table.php
1 year ago
class-strong-testimonials-lite-vs-pro-page.php
1 month ago
class-strong-testimonials-post-editor.php
7 months ago
class-strong-testimonials-review.php
1 year ago
class-strong-testimonials-updater.php
1 month ago
class-strong-testimonials-upsell.php
6 days ago
class-strong-views-list-table.php
1 month ago
class-walker-strong-category-checklist.php
1 year ago
class-walker-strong-form-category-checklist.php
1 year ago
class-wpmtst-onboarding.php
1 year ago
compat.php
1 year ago
custom-fields-ajax.php
1 year ago
custom-fields.php
6 days ago
form-preview.php
1 year ago
view-list-order.php
1 year ago
views-ajax.php
1 month ago
views-validate.php
1 year ago
views.php
1 month ago
class-strong-testimonials-post-editor.php
413 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Class Strong_Testimonials_Post_Editor |
| 5 | * |
| 6 | * @since 2.28.0 |
| 7 | */ |
| 8 | class Strong_Testimonials_Post_Editor { |
| 9 | |
| 10 | /** |
| 11 | * Strong_Testimonials_Post_Editor constructor. |
| 12 | */ |
| 13 | public function __construct() { |
| 14 | } |
| 15 | |
| 16 | /** |
| 17 | * Initialize. |
| 18 | */ |
| 19 | public static function init() { |
| 20 | self::add_actions(); |
| 21 | } |
| 22 | |
| 23 | /** |
| 24 | * Add actions and filters. |
| 25 | */ |
| 26 | public static function add_actions() { |
| 27 | add_action( 'add_meta_boxes_wpm-testimonial', array( __CLASS__, 'add_meta_boxes' ) ); |
| 28 | add_action( 'save_post_wpm-testimonial', array( __CLASS__, 'save_details' ) ); |
| 29 | add_action( 'wp_ajax_wpmtst_edit_rating', array( __CLASS__, 'edit_rating' ) ); |
| 30 | add_filter( 'wp_insert_post_data', array( __CLASS__, 'prevent_shortcode' ), 10, 2 ); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * Add meta box to the post editor screen. |
| 35 | */ |
| 36 | public static function add_meta_boxes() { |
| 37 | add_meta_box( |
| 38 | 'details', |
| 39 | esc_html_x( 'Client Details', 'post editor', 'strong-testimonials' ), |
| 40 | array( __CLASS__, 'meta_options' ), |
| 41 | 'wpm-testimonial', |
| 42 | 'normal', |
| 43 | 'high' |
| 44 | ); |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * Add custom fields to the testimonial editor. |
| 49 | */ |
| 50 | public static function meta_options() { |
| 51 | global $post, $pagenow; |
| 52 | $post = wpmtst_get_post( $post ); |
| 53 | $fields = wpmtst_get_custom_fields(); |
| 54 | $is_new = ( 'post-new.php' === $pagenow ); |
| 55 | wp_nonce_field( plugin_basename( __FILE__ ), 'wpmtst_metabox_nonce' ); |
| 56 | ?> |
| 57 | <?php do_action( 'wpmtst_before_client_fields_table' ); ?> |
| 58 | <table class="options"> |
| 59 | <tr> |
| 60 | <td colspan="2"> |
| 61 | <p><?php echo esc_html_x( 'To add a photo or logo, use the Featured Image option.', 'post editor', 'strong-testimonials' ); ?></p> |
| 62 | </td> |
| 63 | </tr> |
| 64 | <?php |
| 65 | do_action( 'wpmtst_before_client_fields' ); |
| 66 | foreach ( $fields as $key => $field ) { |
| 67 | // TODO Use field property to bypass instead |
| 68 | // short-circuit |
| 69 | if ( 'category' === strtok( $field['input_type'], '-' ) ) { |
| 70 | continue; |
| 71 | } |
| 72 | ?> |
| 73 | <tr> |
| 74 | <th> |
| 75 | <label for="<?php echo esc_attr( $field['name'] ); ?>"> |
| 76 | <?php echo wp_kses_post( apply_filters( 'wpmtst_l10n', $field['label'], 'strong-testimonials-form-fields', $field['name'] . ' : label' ) ); ?> |
| 77 | </label> |
| 78 | </th> |
| 79 | <td> |
| 80 | <div class="<?php echo esc_attr( $field['input_type'] ); ?>"> |
| 81 | <?php self::meta_option( $field, $post, $is_new ); ?> |
| 82 | </div> |
| 83 | </td> |
| 84 | </tr> |
| 85 | <?php |
| 86 | } |
| 87 | do_action( 'wpmtst_after_client_fields' ); |
| 88 | ?> |
| 89 | </table> |
| 90 | <?php |
| 91 | do_action( 'wpmtst_after_client_fields_table' ); |
| 92 | } |
| 93 | |
| 94 | /** |
| 95 | * Input type for a single custom field. |
| 96 | * |
| 97 | * @since 2.23.0 |
| 98 | * |
| 99 | * @param $field |
| 100 | * @param $post |
| 101 | * @param $is_new |
| 102 | */ |
| 103 | public static function meta_option( $field, $post, $is_new ) { |
| 104 | // Check for callback first. |
| 105 | if ( isset( $field['action_input'] ) && $field['action_input'] ) { |
| 106 | self::meta_option__action( $field, $post, $is_new ); |
| 107 | } else { |
| 108 | switch ( $field['input_type'] ) { |
| 109 | case 'rating': |
| 110 | self::meta_option__rating( $field, $post, $is_new ); |
| 111 | break; |
| 112 | case 'url': |
| 113 | self::meta_option__url( $field, $post, $is_new ); |
| 114 | break; |
| 115 | case 'checkbox': |
| 116 | self::meta_option__checkbox( $field, $post, $is_new ); |
| 117 | break; |
| 118 | case 'shortcode': |
| 119 | self::meta_option__shortcode( $field, $post, $is_new ); |
| 120 | break; |
| 121 | case 'textarea': |
| 122 | self::meta_option__textarea( $field, $post, $is_new ); |
| 123 | break; |
| 124 | default: |
| 125 | self::meta_option__text( $field, $post, $is_new ); |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * Custom action callback. |
| 132 | * |
| 133 | * @param $field |
| 134 | * @param $post |
| 135 | * @param $is_new |
| 136 | */ |
| 137 | private static function meta_option__action( $field, $post, $is_new ) { |
| 138 | if ( isset( $field['action_input'] ) && $field['action_input'] ) { |
| 139 | do_action( $field['action_input'], $field, $post->{$field['name']} ); |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * Text input. |
| 145 | * |
| 146 | * @param $field |
| 147 | * @param $post |
| 148 | * @param $is_new |
| 149 | */ |
| 150 | private static function meta_option__text( $field, $post, $is_new ) { |
| 151 | printf( '<input id="%2$s" type="%1$s" class="custom-input" name="custom[%2$s]" value="%3$s">', esc_attr( $field['input_type'] ), esc_attr( $field['name'] ), esc_attr( $post->{$field['name']} ) ); |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Textarea. |
| 156 | * |
| 157 | * @param $field |
| 158 | * @param $post |
| 159 | * @param $is_new |
| 160 | */ |
| 161 | private static function meta_option__textarea( $field, $post, $is_new ) { |
| 162 | printf( |
| 163 | '<textarea id="%1$s" name="custom[%1$s]" class="custom-input">%2$s</textarea>', |
| 164 | esc_attr( $field['name'] ), |
| 165 | wp_kses_post( $post->{$field['name']} ) |
| 166 | ); |
| 167 | } |
| 168 | |
| 169 | /** |
| 170 | * URL input. |
| 171 | * |
| 172 | * @param $field |
| 173 | * @param $post |
| 174 | * @param $is_new |
| 175 | */ |
| 176 | private static function meta_option__url( $field, $post, $is_new ) { |
| 177 | ?> |
| 178 | <div class="input-url"> |
| 179 | <?php printf( '<input id="%2$s" type="%1$s" class="custom-input" name="custom[%2$s]" value="%3$s" size="">', esc_attr( $field['input_type'] ), esc_html( $field['name'] ), esc_attr( $post->{$field['name']} ) ); ?> |
| 180 | </div> |
| 181 | <div class="input-links"> |
| 182 | <div class="input-nofollow"> |
| 183 | <label for="custom_nofollow"><code>rel="nofollow"</code></label> |
| 184 | <select id="custom_nofollow" name="custom[nofollow]"> |
| 185 | <option value="default" <?php selected( $post->nofollow, 'default' ); ?>><?php esc_html_e( 'default', 'strong-testimonials' ); ?></option> |
| 186 | <option value="yes" <?php selected( $post->nofollow, 'yes' ); ?>><?php esc_html_e( 'yes', 'strong-testimonials' ); ?></option> |
| 187 | <option value="no" <?php selected( $post->nofollow, 'no' ); ?>><?php esc_html_e( 'no', 'strong-testimonials' ); ?></option> |
| 188 | </select> |
| 189 | </div> |
| 190 | <div class="input-noopener"> |
| 191 | <label for="custom_noopener"><code>rel="noopener"</code></label> |
| 192 | <select id="custom_noopener" name="custom[noopener]"> |
| 193 | <option value="default" <?php selected( $post->noopener, 'default' ); ?>><?php esc_html_e( 'default', 'strong-testimonials' ); ?></option> |
| 194 | <option value="yes" <?php selected( $post->noopener, 'yes' ); ?>><?php esc_html_e( 'yes', 'strong-testimonials' ); ?></option> |
| 195 | <option value="no" <?php selected( $post->noopener, 'no' ); ?>><?php esc_html_e( 'no', 'strong-testimonials' ); ?></option> |
| 196 | </select> |
| 197 | </div> |
| 198 | <div class="input-noreferrer"> |
| 199 | <label for="custom_noreferrer"><code>rel="noreferrer"</code></label> |
| 200 | <select id="custom_noopener" name="custom[noreferrer]"> |
| 201 | <option value="default" <?php selected( $post->noreferrer, 'default' ); ?>><?php esc_html_e( 'default', 'strong-testimonials' ); ?></option> |
| 202 | <option value="yes" <?php selected( $post->noreferrer, 'yes' ); ?>><?php esc_html_e( 'yes', 'strong-testimonials' ); ?></option> |
| 203 | <option value="no" <?php selected( $post->noreferrer, 'no' ); ?>><?php esc_html_e( 'no', 'strong-testimonials' ); ?></option> |
| 204 | </select> |
| 205 | </div> |
| 206 | <?php |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Checkbox input. |
| 211 | * |
| 212 | * @param $field |
| 213 | * @param $post |
| 214 | * @param $is_new |
| 215 | */ |
| 216 | private static function meta_option__checkbox( $field, $post, $is_new ) { |
| 217 | printf( '<input id="%2$s" type="%1$s" class="custom-input" name="custom[%2$s]" value="%3$s" %4$s>', esc_attr( $field['input_type'] ), esc_attr( $field['name'] ), 1, checked( $post->{$field['name']}, 1, false ) ); |
| 218 | } |
| 219 | |
| 220 | /** |
| 221 | * Rating input. |
| 222 | * |
| 223 | * @param $field |
| 224 | * @param $post |
| 225 | * @param $is_new |
| 226 | */ |
| 227 | private static function meta_option__rating( $field, $post, $is_new ) { |
| 228 | $rating = get_post_meta( $post->ID, $field['name'], true ); |
| 229 | if ( ! $rating || $is_new ) { |
| 230 | $rating = 0; |
| 231 | } |
| 232 | ?> |
| 233 | <div class="edit-rating-box hide-if-no-js" data-field="<?php echo esc_attr( $field['name'] ); ?>"> |
| 234 | |
| 235 | <?php wp_nonce_field( 'editrating', "edit-{$field['name']}-nonce", false ); ?> |
| 236 | <input type="hidden" class="current-rating" value="<?php echo esc_attr( $rating ); ?>"> |
| 237 | |
| 238 | <!-- form --> |
| 239 | <div class="rating-form" style="<?php echo ( $is_new ) ? 'display: inline-block;' : 'display: none;'; ?>"> |
| 240 | <span class="inner"> |
| 241 | <?php wpmtst_star_rating_form( $field, $rating, 'in-metabox', true, 'custom' ); ?> |
| 242 | </span> |
| 243 | <?php if ( ! $is_new ) : ?> |
| 244 | <span class="edit-rating-buttons-2"> |
| 245 | <button type="button" class="zero button-link"><?php esc_html_e( 'Zero', 'strong-testimonials' ); ?></button> |
| 246 | <button type="button" class="save button button-small"><?php esc_html_e( 'OK', 'strong-testimonials' ); ?></button> |
| 247 | <button type="button" class="cancel button-link"><?php esc_html_e( 'Cancel', 'strong-testimonials' ); ?></button> |
| 248 | </span> |
| 249 | <?php endif; ?> |
| 250 | </div> |
| 251 | |
| 252 | <!-- display --> |
| 253 | <div class="rating-display" style="<?php echo $is_new ? 'display: none;' : 'display: inline-block;'; ?>"> |
| 254 | <span class="inner"> |
| 255 | <?php wpmtst_star_rating_display( $rating, 'in-metabox' ); ?> |
| 256 | </span> |
| 257 | |
| 258 | <?php if ( ! $is_new ) : ?> |
| 259 | <span class="edit-rating-buttons-1"> |
| 260 | <button type="button" id="" class="edit-rating button button-small hide-if-no-js" aria-label="Edit rating"><?php esc_html_e( 'Edit', 'strong-testimonials' ); ?></button> |
| 261 | </span> |
| 262 | <?php endif; ?> |
| 263 | </div> |
| 264 | |
| 265 | <span class="edit-rating-success"></span> |
| 266 | |
| 267 | </div> |
| 268 | <?php |
| 269 | } |
| 270 | |
| 271 | /** |
| 272 | * Shortcode for custom input. |
| 273 | * |
| 274 | * @param $field |
| 275 | * @param $post |
| 276 | * @param $is_new |
| 277 | */ |
| 278 | public static function meta_option__shortcode( $field, $post, $is_new ) { |
| 279 | $shortcode = str_replace( array( '[', ']' ), array( '', '' ), $field['shortcode_on_display'] ); |
| 280 | if ( shortcode_exists( $shortcode ) ) { |
| 281 | echo do_shortcode( $field['shortcode_on_display'] ); |
| 282 | } else { |
| 283 | // translators: %s is the shortcode that was not found. |
| 284 | echo '<div class="custom-input not-found">' . sprintf( esc_html__( 'shortcode %s not found', 'strong-testimonials' ), '<code>' . esc_html( $field['shortcode_on_display'] ) . '</code>' ) . '</div>'; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * Save custom fields. |
| 290 | * |
| 291 | * @since 2.23.2 Delete meta record when rating is zero to allow default display value. |
| 292 | */ |
| 293 | public static function save_details() { |
| 294 | if ( ! isset( $_POST['custom'] ) || ! isset( $_POST['post_ID'] ) || ! wp_verify_nonce( $_POST['wpmtst_metabox_nonce'], plugin_basename( __FILE__ ) ) ) { |
| 295 | return; |
| 296 | } |
| 297 | |
| 298 | $post_id = absint( $_POST['post_ID'] ); |
| 299 | $custom = $_POST['custom']; // phpcs:ignore sanitization is done underneath ( Data Sanitizationva ) |
| 300 | |
| 301 | $custom_fields = wpmtst_get_custom_fields(); |
| 302 | |
| 303 | // Construct array of checkbox empty values because blank checkboxes are not POSTed. |
| 304 | $checkboxes = array(); |
| 305 | foreach ( $custom_fields as $key => $field ) { |
| 306 | if ( 'checkbox' === $field['input_type'] ) { |
| 307 | $checkboxes[ $key ] = 0; |
| 308 | } |
| 309 | } |
| 310 | if ( $checkboxes ) { |
| 311 | $custom = array_merge( $checkboxes, $custom ); |
| 312 | } |
| 313 | |
| 314 | // Determine whether to update or delete. |
| 315 | // Similar to wpmtst_ajax_edit_rating() in admin-ajax.php. |
| 316 | $custom_fields['nofollow']['input_type'] = ''; |
| 317 | $custom_fields['noopener']['input_type'] = ''; |
| 318 | $custom_fields['noreferrer']['input_type'] = ''; |
| 319 | |
| 320 | foreach ( $custom as $key => $value ) { |
| 321 | $action = 'update'; |
| 322 | $sanitized_value = ''; |
| 323 | |
| 324 | if ( isset( $custom_fields[ $key ] ) ) { |
| 325 | if ( 'rating' === $custom_fields[ $key ]['input_type'] && ! $value ) { |
| 326 | $action = 'delete'; |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | // Data Sanitizationva |
| 331 | if ( isset( $custom_fields[ $key ]['input_type'] ) && 'text' === $custom_fields[ $key ]['input_type'] ) { |
| 332 | // Define the allowed HTML tags and their attributes |
| 333 | $allowed_html = array( |
| 334 | 'p' => array( 'style' => array() ), |
| 335 | 'strong' => array( 'style' => array() ), |
| 336 | 'span' => array( 'style' => array() ), |
| 337 | ); |
| 338 | $sanitized_value = wp_kses( $value, $allowed_html ); |
| 339 | } elseif ( isset( $custom_fields[ $key ]['input_type'] ) && 'email' === $custom_fields[ $key ]['input_type'] ) { |
| 340 | $sanitized_value = sanitize_email( $value ); |
| 341 | } elseif ( isset( $custom_fields[ $key ]['input_type'] ) && 'url' === $custom_fields[ $key ]['input_type'] ) { |
| 342 | $sanitized_value = esc_url_raw( $value ); |
| 343 | } else { |
| 344 | $sanitized_value = sanitize_text_field( $value ); |
| 345 | } |
| 346 | |
| 347 | if ( 'update' === $action ) { |
| 348 | // empty values replace existing values |
| 349 | update_post_meta( $post_id, $key, $sanitized_value ); |
| 350 | } else { |
| 351 | // delete value; e.g. zero rating |
| 352 | delete_post_meta( $post_id, $key ); |
| 353 | } |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | /** |
| 358 | * Prevent use of this plugin's shortcode in a testimonial. |
| 359 | * |
| 360 | * @since 2.32.2 |
| 361 | * @param $data |
| 362 | * @param $postarr |
| 363 | * |
| 364 | * @return mixed |
| 365 | */ |
| 366 | public static function prevent_shortcode( $data, $postarr ) { |
| 367 | if ( 'wpm-testimonial' === $data['post_type'] ) { |
| 368 | $data['post_content'] = preg_replace( '/\[testimonial_view (.*)\]/', '', $data['post_content'] ); |
| 369 | } |
| 370 | |
| 371 | return $data; |
| 372 | } |
| 373 | |
| 374 | /** |
| 375 | * Ajax handler to edit a rating. |
| 376 | * |
| 377 | * @since 2.12.0 |
| 378 | */ |
| 379 | public static function edit_rating() { |
| 380 | |
| 381 | $message = ''; |
| 382 | $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; |
| 383 | $rating = isset( $_POST['rating'] ) ? absint( $_POST['rating'] ) : 0; |
| 384 | $name = isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : 'rating'; |
| 385 | |
| 386 | check_ajax_referer( 'editrating', 'editratingnonce' ); |
| 387 | |
| 388 | if ( ! current_user_can( 'edit_post', $post_id ) ) { |
| 389 | wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to edit this testimonial.', 'strong-testimonials' ) ) ); |
| 390 | return; |
| 391 | } |
| 392 | |
| 393 | if ( $post_id ) { |
| 394 | if ( $rating ) { |
| 395 | update_post_meta( $post_id, $name, $rating ); |
| 396 | } else { |
| 397 | delete_post_meta( $post_id, $name ); |
| 398 | } |
| 399 | $message = 'New rating saved'; |
| 400 | } |
| 401 | |
| 402 | $display = wpmtst_star_rating_display( $rating, 'in-metabox', false ); |
| 403 | $response = array( |
| 404 | 'display' => $display, |
| 405 | 'message' => $message, |
| 406 | ); |
| 407 | echo json_encode( $response ); |
| 408 | wp_die(); |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | Strong_Testimonials_Post_Editor::init(); |
| 413 |