Changeset 3465484
- Timestamp:
- 02/20/2026 04:08:30 AM (5 weeks ago)
- Location:
- wp-featured-posts
- Files:
-
- 22 added
- 5 edited
-
tags/1.1.1 (added)
-
tags/1.1.1/assets (added)
-
tags/1.1.1/assets/css (added)
-
tags/1.1.1/assets/css/style.css (added)
-
tags/1.1.1/assets/css/style.min.css (added)
-
tags/1.1.1/assets/images (added)
-
tags/1.1.1/assets/images/btn-loading.gif (added)
-
tags/1.1.1/assets/js (added)
-
tags/1.1.1/assets/js/main.js (added)
-
tags/1.1.1/assets/js/main.min.js (added)
-
tags/1.1.1/assets/js/setting.js (added)
-
tags/1.1.1/assets/js/setting.min.js (added)
-
tags/1.1.1/inc (added)
-
tags/1.1.1/inc/wp-featured-posts-setting.php (added)
-
tags/1.1.1/inc/wp-featured-posts-wpml.php (added)
-
tags/1.1.1/index.php (added)
-
tags/1.1.1/languages (added)
-
tags/1.1.1/languages/wp-featured-posts.pot (added)
-
tags/1.1.1/readme.txt (added)
-
tags/1.1.1/templates (added)
-
tags/1.1.1/templates/featured-posts.php (added)
-
tags/1.1.1/wp-featured-posts.php (added)
-
trunk/assets/js/setting.js (modified) (1 diff)
-
trunk/assets/js/setting.min.js (modified) (1 diff)
-
trunk/inc/wp-featured-posts-setting.php (modified) (4 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/wp-featured-posts.php (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wp-featured-posts/trunk/assets/js/setting.js
r2382708 r3465484 1 1 (function($) { 2 2 3 $('.wpfp-toggle-expand').on('click', function (e) { 4 e.preventDefault(); 3 $(document).ready(function() { 5 4 6 var expand = $(this).data('expand'); 7 if ($(expand).length) { 8 $(expand).toggle(); 9 } 5 $('.wpfp-toggle-expand').on('click', function (e) { 6 e.preventDefault(); 10 7 11 if ($(this).hasClass('show')) { 12 $(this).addClass('hide'); 13 $(this).find('.hide').hide(); 14 $(this).find('.show').show(); 15 } else { 16 $(this).addClass('show'); 17 $(this).find('.hide').show(); 18 $(this).find('.show').hide(); 19 } 8 var expand = $(this).data('expand'); 9 if ($(expand).length) { 10 $(expand).toggle(); 11 } 12 13 if ($(this).hasClass('show')) { 14 $(this).addClass('hide'); 15 $(this).find('.hide').hide(); 16 $(this).find('.show').show(); 17 } else { 18 $(this).addClass('show'); 19 $(this).find('.hide').show(); 20 $(this).find('.show').hide(); 21 } 22 }); 23 24 // Media Uploader for Pin Image 25 var wpfpMediaUploader; 26 27 $(document).on('click', '.wpfp-upload-pin-image', function(e) { 28 e.preventDefault(); 29 30 // If the uploader already exists, reopen it 31 if (wpfpMediaUploader) { 32 wpfpMediaUploader.open(); 33 return; 34 } 35 36 // Create a new media uploader 37 wpfpMediaUploader = wp.media({ 38 title: 'Select Pin Icon Image', 39 button: { 40 text: 'Use this image' 41 }, 42 multiple: false 43 }); 44 45 // When an image is selected in the media uploader 46 wpfpMediaUploader.on('select', function() { 47 var attachment = wpfpMediaUploader.state().get('selection').first().toJSON(); 48 $('#wp-featured-posts-pin-image').val(attachment.url); 49 $('.wpfp-pin-preview img').attr('src', attachment.url); 50 $('.wpfp-pin-preview').show(); 51 $('.wpfp-remove-pin-image').show(); 52 }); 53 54 // Open the uploader 55 wpfpMediaUploader.open(); 56 }); 57 58 // Remove pin image 59 $(document).on('click', '.wpfp-remove-pin-image', function(e) { 60 e.preventDefault(); 61 $('#wp-featured-posts-pin-image').val(''); 62 $('.wpfp-pin-preview').hide(); 63 $(this).hide(); 64 }); 20 65 21 66 22 });23 24 67 })(jQuery); -
wp-featured-posts/trunk/assets/js/setting.min.js
r2382708 r3465484 1 !function( h){h(".wpfp-toggle-expand").on("click",function(s){s.preventDefault();var i=h(this).data("expand");h(i).length&&h(i).toggle(),h(this).hasClass("show")?(h(this).addClass("hide"),h(this).find(".hide").hide(),h(this).find(".show").show()):(h(this).addClass("show"),h(this).find(".hide").show(),h(this).find(".show").hide())})}(jQuery);1 !function(a){a(document).ready(function(){a(".wpfp-toggle-expand").on("click",function(b){b.preventDefault();var c=a(this).data("expand");a(c).length&&a(c).toggle(),a(this).hasClass("show")?(a(this).addClass("hide"),a(this).find(".hide").hide(),a(this).find(".show").show()):(a(this).addClass("show"),a(this).find(".hide").show(),a(this).find(".show").hide())});var b;a(document).on("click",".wpfp-upload-pin-image",function(c){c.preventDefault(),b?b.open():(b=wp.media({title:"Select Pin Icon Image",button:{text:"Use this image"},multiple:!1}),b.on("select",function(){var c=b.state().get("selection").first().toJSON();a("#wp-featured-posts-pin-image").val(c.url),a(".wpfp-pin-preview img").attr("src",c.url),a(".wpfp-pin-preview").show(),a(".wpfp-remove-pin-image").show()}),b.open())}),a(document).on("click",".wpfp-remove-pin-image",function(b){b.preventDefault(),a("#wp-featured-posts-pin-image").val(""),a(".wpfp-pin-preview").hide(),a(this).hide()})})}(jQuery); -
wp-featured-posts/trunk/inc/wp-featured-posts-setting.php
r3465479 r3465484 33 33 { 34 34 if ($hook === 'toplevel_page_wp-featured-posts-settings-page') { 35 wp_enqueue_media(); 35 36 wp_enqueue_script('admin-featured-sorting-setting', WPFP_PLUGIN_URL . '/assets/js/setting.min.js', ['jquery'], WPFP_VERSION, true); 36 37 } … … 125 126 126 127 add_settings_section( 128 'wp_featured_pin_icon_settings_section', // ID 129 __('Pin Icon Settings', 'wp-featured-posts'), // Title 130 [$this, 'wp_featured_pin_icon_settings_section'], // Callback 131 'wp-featured-posts-settings-page' // Page 132 ); 133 134 add_settings_field( 135 'wp-featured-posts-pin-enable', // ID 136 __('Enable Pin Icon', 'wp-featured-posts'), // Title 137 [$this, 'pin_enable_field'], // Callback 138 'wp-featured-posts-settings-page', // Page 139 'wp_featured_pin_icon_settings_section' 140 ); 141 142 add_settings_field( 143 'wp-featured-posts-pin-size', // ID 144 __('Pin Icon Size', 'wp-featured-posts'), // Title 145 [$this, 'pin_size_field'], // Callback 146 'wp-featured-posts-settings-page', // Page 147 'wp_featured_pin_icon_settings_section' 148 ); 149 150 add_settings_field( 151 'wp-featured-posts-pin-image', // ID 152 __('Custom Pin Image', 'wp-featured-posts'), // Title 153 [$this, 'pin_image_field'], // Callback 154 'wp-featured-posts-settings-page', // Page 155 'wp_featured_pin_icon_settings_section' 156 ); 157 158 add_settings_section( 127 159 'wp_featured_sticky_posts_settings_section', // ID 128 160 '', // Title … … 145 177 'post_types' => [], 146 178 'sticky_post_type' => [], 179 'pin_enable' => 0, 180 'pin_size' => 16, 181 'pin_image' => '', 147 182 ]; 148 183 149 184 $sanitized_input = array_merge($sanitized_input, $input); 185 186 // Sanitize pin size 187 if (isset($sanitized_input['pin_size'])) { 188 $sanitized_input['pin_size'] = absint($sanitized_input['pin_size']); 189 if ($sanitized_input['pin_size'] < 10) { 190 $sanitized_input['pin_size'] = 10; 191 } 192 if ($sanitized_input['pin_size'] > 50) { 193 $sanitized_input['pin_size'] = 50; 194 } 195 } 196 197 // Sanitize pin image URL 198 if (isset($sanitized_input['pin_image'])) { 199 $sanitized_input['pin_image'] = esc_url_raw($sanitized_input['pin_image']); 200 } 150 201 151 202 return $sanitized_input; … … 212 263 } 213 264 265 266 public function wp_featured_pin_icon_settings_section() 267 { 268 echo '<p>' . __('Configure the pin icon that appears next to featured post titles.', 'wp-featured-posts') . '</p>'; 269 } 270 271 public function pin_enable_field() 272 { 273 $pin_enable = isset($this->options['pin_enable']) ? $this->options['pin_enable'] : 0; 274 echo '<label for="wp-featured-posts-pin-enable"><input type="checkbox" id="wp-featured-posts-pin-enable" name="wp_featured_posts_settings[pin_enable]" value="1" ' . checked($pin_enable, 1, false) . ' > ' . __('Show pin icon next to featured post titles', 'wp-featured-posts') . '</label>'; 275 } 276 277 public function pin_size_field() 278 { 279 $pin_size = isset($this->options['pin_size']) ? $this->options['pin_size'] : 16; 280 echo '<input type="number" id="wp-featured-posts-pin-size" name="wp_featured_posts_settings[pin_size]" value="' . esc_attr($pin_size) . '" min="10" max="50" step="1" style="width: 80px;"> <span class="description">' . __('px (10-50)', 'wp-featured-posts') . '</span>'; 281 } 282 283 public function pin_image_field() 284 { 285 $pin_image = isset($this->options['pin_image']) ? $this->options['pin_image'] : ''; 286 ?> 287 <div class="wpfp-pin-image-upload"> 288 <input type="hidden" id="wp-featured-posts-pin-image" name="wp_featured_posts_settings[pin_image]" value="<?php echo esc_attr($pin_image); ?>"> 289 <button type="button" class="button wpfp-upload-pin-image"><?php _e('Upload Image', 'wp-featured-posts'); ?></button> 290 <button type="button" class="button wpfp-remove-pin-image" style="<?php echo empty($pin_image) ? 'display:none;' : ''; ?>"><?php _e('Remove Image', 'wp-featured-posts'); ?></button> 291 <div class="wpfp-pin-preview" style="margin-top: 10px;<?php echo empty($pin_image) ? 'display:none;' : ''; ?>"> 292 <img src="<?php echo esc_url($pin_image); ?>" style="max-width: 100px; height: auto;"> 293 </div> 294 <p class="description"><?php _e('Leave empty to use default pin icon (📌). Recommended size: 32x32px or larger.', 'wp-featured-posts'); ?></p> 295 </div> 296 <?php 297 } 214 298 215 299 public function wp_featured_sticky_posts_settings_section() -
wp-featured-posts/trunk/readme.txt
r3465479 r3465484 5 5 Requires at least: 4.7 6 6 Tested up to: 6.9 7 Stable tag: 1.1. 07 Stable tag: 1.1.1 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 48 48 == Changelog == 49 49 50 = 1.1.1 = 51 * Fix: Resolved media uploader not working for custom pin image upload 52 * Fix: Improved JavaScript initialization with proper DOM ready handling 53 * Fix: Enhanced event delegation for better compatibility 54 50 55 = 1.1.0 = 51 56 * Security: Added ABSPATH checks to prevent direct file access … … 54 59 * Enhancement: Fixed wp_send_json_* function usage (removed incorrect echo statements) 55 60 * Enhancement: Modernized code to comply with WordPress coding standards 61 * Enhancement: Fixed deprecated FILTER_SANITIZE_STRING for PHP 8.1+ compatibility 62 * Enhancement: Fixed undefined variable $q in sticky posts logic 63 * Feature: Added pin icon display for featured posts with customizable settings 64 * Feature: Pin icon can be enabled/disabled per configuration 65 * Feature: Adjustable pin icon size (10-50px) 66 * Feature: Support for custom pin image upload 67 * Feature: Pin icon position can be filtered (before/after title) 68 * Fix: Featured posts now work correctly on category, tag, author, and date archive pages 56 69 * Compatibility: Tested up to WordPress 6.9 57 70 -
wp-featured-posts/trunk/wp-featured-posts.php
r3465479 r3465484 4 4 * Plugin URI: https://wordpress.org/plugins/wp-featured-posts/ 5 5 * Description: Set featured posts, sortable and sticky custom post type. Compatible with WPML. 6 * Version: 1.1. 06 * Version: 1.1.1 7 7 * Requires at least: 4.7 8 8 * Requires PHP: 7.4 … … 24 24 define('WPFP_BASENAME', plugin_basename(__FILE__)); 25 25 define('WPFP_PLUGIN_URL', plugin_dir_url(__FILE__)); 26 define('WPFP_VERSION', '1.1. 0');26 define('WPFP_VERSION', '1.1.1'); 27 27 28 28 /** … … 74 74 'post_types' => [], 75 75 'sticky_post_type' => [], 76 'pin_enable' => 0, 77 'pin_size' => 16, 78 'pin_image' => '', 76 79 ]; 77 80 … … 83 86 84 87 add_filter('plugin_action_links_' . WPFP_BASENAME, [$this, 'add_plugin_donate_link']); 88 89 // Pin icon functionality 90 if ($this->options['enable'] && $this->options['pin_enable']) { 91 add_filter('the_title', [$this, 'add_pin_icon_to_title'], 10, 2); 92 add_action('wp_head', [$this, 'add_pin_icon_styles']); 93 } 85 94 } 86 95 … … 255 264 check_ajax_referer('save-featured-sorting'); 256 265 257 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_ STRING);266 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS); 258 267 259 268 $data['_redirect'] = $data['_wp_http_referer']; … … 327 336 check_ajax_referer('delete-featured-sorting'); 328 337 329 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_ STRING);338 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS); 330 339 331 340 if ($data['post_type'] == 'post') { … … 402 411 check_ajax_referer('order-featured-sorting'); 403 412 404 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_ STRING);413 $data = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS); 405 414 406 415 $post_ids = $data['post_id']; … … 524 533 foreach ($this->options['sticky_post_type'] as $sticky_post_type) { 525 534 526 if ($wp_query->is_home() && $sticky_post_type == 'post' || $wp_query->get('post_type') == $sticky_post_type) { 535 $is_post_archive = ($wp_query->is_home() || $wp_query->is_category() || $wp_query->is_tag() || $wp_query->is_author() || $wp_query->is_date()) && $sticky_post_type == 'post'; 536 $is_custom_post_type = $wp_query->get('post_type') == $sticky_post_type; 537 538 if ($is_post_archive || $is_custom_post_type) { 527 539 528 540 // Get original meta query … … 568 580 { 569 581 $post_type = $wp_query->query_vars['post_type']; 582 583 // Handle standard post archives (category, tag, etc.) where post_type is empty 584 if (empty($post_type) && ($wp_query->is_home() || $wp_query->is_category() || $wp_query->is_tag() || $wp_query->is_author() || $wp_query->is_date())) { 585 $post_type = 'post'; 586 } 587 570 588 if (!is_admin() && $wp_query->is_main_query() && $this->options['enable'] && in_array($post_type, $this->options['sticky_post_type'])) { 571 589 … … 605 623 606 624 // If any posts have been excluded specifically, Ignore those that are sticky. 607 if (!empty($sticky_posts) && !empty($ q['post__not_in'])) {608 $sticky_posts = array_diff($sticky_posts, $ q['post__not_in']);625 if (!empty($sticky_posts) && !empty($wp_query->query_vars['post__not_in'])) { 626 $sticky_posts = array_diff($sticky_posts, $wp_query->query_vars['post__not_in']); 609 627 } 610 628 … … 652 670 $set_default_options = true; 653 671 } 672 if (!isset($this->options['pin_enable'])) { 673 $this->options['pin_enable'] = 0; 674 $set_default_options = true; 675 } 676 if (!isset($this->options['pin_size'])) { 677 $this->options['pin_size'] = 16; 678 $set_default_options = true; 679 } 680 if (!isset($this->options['pin_image'])) { 681 $this->options['pin_image'] = ''; 682 $set_default_options = true; 683 } 654 684 655 685 if ($set_default_options) { … … 658 688 } 659 689 690 /** 691 * Add pin icon to featured post titles 692 * 693 * @param string $title 694 * @param int $post_id 695 * @return string 696 */ 697 public function add_pin_icon_to_title($title, $post_id) 698 { 699 // Only add pin icon on frontend, not in admin or feeds 700 if (is_admin() || is_feed()) { 701 return $title; 702 } 703 704 // Get post type 705 $post_type = get_post_type($post_id); 706 707 // Check if this post type has pin icon enabled 708 if (!in_array($post_type, $this->options['post_types'])) { 709 return $title; 710 } 711 712 // Check if this post is featured 713 $featured_key = "{$post_type}_featured"; 714 $is_featured = get_post_meta($post_id, $featured_key, true); 715 716 if ($is_featured != '1') { 717 return $title; 718 } 719 720 // Build pin icon HTML 721 $pin_html = $this->get_pin_icon_html(); 722 723 // Allow filtering of pin position (before or after title) 724 $position = apply_filters('wpfp_pin_icon_position', 'before', $post_id); 725 726 if ($position === 'after') { 727 return $title . ' ' . $pin_html; 728 } 729 730 return $pin_html . ' ' . $title; 731 } 732 733 /** 734 * Get pin icon HTML 735 * 736 * @return string 737 */ 738 private function get_pin_icon_html() 739 { 740 $pin_size = isset($this->options['pin_size']) ? absint($this->options['pin_size']) : 16; 741 $pin_image = isset($this->options['pin_image']) ? $this->options['pin_image'] : ''; 742 743 if (!empty($pin_image)) { 744 // Use custom image 745 return sprintf( 746 '<span class="wpfp-pin-icon wpfp-pin-custom"><img src="%s" alt="%s" width="%d" height="%d"></span>', 747 esc_url($pin_image), 748 esc_attr__('Featured', 'wp-featured-posts'), 749 $pin_size, 750 $pin_size 751 ); 752 } 753 754 // Use default emoji pin 755 return sprintf( 756 '<span class="wpfp-pin-icon wpfp-pin-default" style="font-size:%dpx;">📌</span>', 757 $pin_size 758 ); 759 } 760 761 /** 762 * Add pin icon styles to frontend 763 */ 764 public function add_pin_icon_styles() 765 { 766 ?> 767 <style type="text/css"> 768 .wpfp-pin-icon { 769 display: inline-block; 770 vertical-align: middle; 771 line-height: 1; 772 } 773 .wpfp-pin-icon.wpfp-pin-custom img { 774 display: inline-block; 775 vertical-align: middle; 776 } 777 .wpfp-pin-icon.wpfp-pin-default { 778 margin-right: 4px; 779 } 780 </style> 781 <?php 782 } 660 783 661 784 /** … … 667 790 public function add_plugin_donate_link($links) 668 791 { 669 $links[] = '<a href="https://www.buymeacoffee.com/nutttaro" target="_blank">' . __('Donate', ' video-player-for-wpbakery') . '</a>';792 $links[] = '<a href="https://www.buymeacoffee.com/nutttaro" target="_blank">' . __('Donate', 'wp-featured-posts') . '</a>'; 670 793 return $links; 671 794 }
Note: See TracChangeset
for help on using the changeset viewer.