log-oscon /
post-glue
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Plugin Name: Post Glue |
||
| 4 | * Plugin URI: https://github.com/log-oscon/post-glue/ |
||
| 5 | * Description: Sticky posts for WordPress, improved. |
||
| 6 | * Version: 1.0.0 |
||
| 7 | * Author: log.OSCON, Lda. |
||
| 8 | * Author URI: https://log.pt/ |
||
| 9 | * License: GPL-2.0+ |
||
| 10 | * License URI: http://www.gnu.org/licenses/gpl-2.0.txt |
||
| 11 | * Text Domain: post-glue |
||
| 12 | * Domain Path: /languages |
||
| 13 | * GitHub Plugin URI: https://github.com/log-oscon/post-glue |
||
| 14 | * GitHub Branch: master |
||
| 15 | */ |
||
| 16 | |||
| 17 | if ( ! defined( 'WPINC' ) ) { |
||
| 18 | die; |
||
| 19 | } |
||
| 20 | |||
| 21 | /** |
||
| 22 | * Implements plugin functionality. |
||
| 23 | */ |
||
| 24 | class Post_Glue { |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Set sticky meta values on plugin activation. |
||
| 28 | */ |
||
| 29 | 1 | public static function activation() { |
|
| 30 | 1 | self::stick_posts( get_option( 'sticky_posts', array() ) ); |
|
| 31 | 1 | } |
|
| 32 | |||
| 33 | /** |
||
| 34 | * Initialize the plugin. |
||
| 35 | */ |
||
| 36 | 1 | public static function plugins_loaded() { |
|
| 37 | 1 | $plugin_basename = plugin_basename( dirname( __FILE__ ) ); |
|
| 38 | |||
| 39 | 1 | load_plugin_textdomain( 'post-glue', false, $plugin_basename . '/languages' ); |
|
| 40 | |||
| 41 | 1 | add_action( 'admin_init', array( __CLASS__, 'admin_init' ) ); |
|
| 42 | 1 | add_action( 'update_option_sticky_posts', array( __CLASS__, 'update_option_sticky_posts' ), 10, 3 ); |
|
| 43 | 1 | add_action( 'pre_get_posts', array( __CLASS__, 'pre_get_posts' ) ); |
|
| 44 | 1 | add_filter( 'post_class', array( __CLASS__, 'post_class' ), 10, 3 ); |
|
| 45 | 1 | } |
|
| 46 | |||
| 47 | /** |
||
| 48 | * Initialize the admin-specific parts of the plugin. |
||
| 49 | * |
||
| 50 | * Registers a Sticky metabox for every non-hierarchical post type and |
||
| 51 | * adds a view filter to the post edit screen. |
||
| 52 | */ |
||
| 53 | 2 | public static function admin_init() { |
|
| 54 | |||
| 55 | // Get all public, non-hierarchical post types: |
||
| 56 | 2 | $post_types = get_post_types( array( 'hierarchical' => false, 'public' => true ) ); |
|
| 57 | |||
| 58 | // Bypass the core post type: |
||
| 59 | 2 | $post_types = array_diff( $post_types, array( 'post' ) ); |
|
| 60 | |||
| 61 | /** |
||
| 62 | * Filter the list of post types that support stickiness. |
||
| 63 | * |
||
| 64 | * Defaults to the list of public, non-hierarchical post types. |
||
| 65 | * |
||
| 66 | * @param array $post_types Post types that support stickiness. |
||
| 67 | */ |
||
| 68 | 2 | $post_types = apply_filters( 'post_glue_post_types', $post_types ); |
|
| 69 | |||
| 70 | 2 | add_meta_box( |
|
| 71 | 2 | 'post_glue_meta', |
|
| 72 | 2 | __( 'Post Glue', 'post-glue' ), |
|
| 73 | 2 | array( __CLASS__, 'admin_meta_box' ), |
|
| 74 | 2 | $post_types, |
|
| 75 | 2 | 'side', |
|
| 76 | 'high' |
||
| 77 | 2 | ); |
|
| 78 | |||
| 79 | 2 | foreach( $post_types as $post_type ) { |
|
| 80 | 2 | add_filter( 'views_edit-' . $post_type, array( __CLASS__, 'views_edit' ) ); |
|
| 81 | 2 | } |
|
| 82 | 2 | } |
|
| 83 | |||
| 84 | /** |
||
| 85 | * Render the sticky meta box. |
||
| 86 | */ |
||
| 87 | 1 | public static function admin_meta_box() { |
|
| 88 | ?> |
||
| 89 | <label for="post-glue-sticky" class="selectit"> |
||
| 90 | <input id="post-glue-sticky" name="sticky" type="checkbox" |
||
| 91 | value="sticky" <?php checked( is_sticky() ) ?>> |
||
| 92 | <?php _e( 'Make this post sticky', 'post-glue' ) ?> |
||
| 93 | </label> |
||
| 94 | <?php |
||
| 95 | 1 | } |
|
| 96 | |||
| 97 | /** |
||
| 98 | * Add sticky post view to the post edit page in the admin. |
||
| 99 | * |
||
| 100 | * @param array $views Admin post edit views. |
||
| 101 | * @return array Filtered admin post edit views. |
||
| 102 | */ |
||
| 103 | 1 | public static function views_edit( $views ) { |
|
| 104 | 1 | global $wp_query; |
|
|
0 ignored issues
–
show
|
|||
| 105 | |||
| 106 | 1 | $post_type = $wp_query->get( 'post_type' ); |
|
| 107 | 1 | $sticky_posts = array(); |
|
| 108 | |||
| 109 | 1 | foreach( get_option( 'sticky_posts', array() ) as $post_id ) { |
|
| 110 | 1 | if ( get_post_type( $post_id ) === $post_type ) { |
|
| 111 | 1 | $sticky_posts[] = $post_id; |
|
| 112 | 1 | } |
|
| 113 | 1 | } |
|
| 114 | |||
| 115 | 1 | $sticky_posts_count = count( $sticky_posts ); |
|
| 116 | |||
| 117 | 1 | if ( ! $sticky_posts_count ) { |
|
| 118 | 1 | return $views; |
|
| 119 | } |
||
| 120 | |||
| 121 | 1 | $sticky_inner_html = sprintf( |
|
| 122 | 1 | _nx( |
|
| 123 | 1 | 'Sticky <span class="count">(%s)</span>', |
|
| 124 | 1 | 'Sticky <span class="count">(%s)</span>', |
|
| 125 | 1 | $sticky_posts_count, |
|
| 126 | 1 | 'sticky view link', |
|
| 127 | 'post-glue' |
||
| 128 | 1 | ), |
|
| 129 | 1 | number_format_i18n( $sticky_posts_count ) |
|
| 130 | 1 | ); |
|
| 131 | |||
| 132 | 1 | $views['sticky'] = sprintf( |
|
| 133 | 1 | '<a href="%sedit.php?post_type=%s&show_sticky=1">%s</a>', |
|
| 134 | 1 | get_admin_url(), |
|
| 135 | 1 | $post_type, |
|
| 136 | $sticky_inner_html |
||
| 137 | 1 | ); |
|
| 138 | |||
| 139 | 1 | return $views; |
|
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * Saves post stickiness to the `_sticky` post meta key. |
||
| 144 | * |
||
| 145 | * @param mixed $old_value Previous option value. |
||
| 146 | * @param mixed $value New option value. |
||
| 147 | * @param string $option Option name. |
||
| 148 | */ |
||
| 149 | 1 | public static function update_option_sticky_posts( $old_value, $value, $option ) { |
|
| 150 | 1 | $added = array_diff( $value, $old_value ); |
|
| 151 | 1 | $removed = array_diff( $old_value, $value ); |
|
| 152 | |||
| 153 | 1 | self::stick_posts( $added ); |
|
| 154 | 1 | self::unstick_posts( $removed ); |
|
| 155 | 1 | } |
|
| 156 | |||
| 157 | /** |
||
| 158 | * Sort posts by stickiness. |
||
| 159 | * |
||
| 160 | * Changes queries to include sticky posts on the default sort order. |
||
| 161 | * Honours the `ignore_sticky_posts` query argument. |
||
| 162 | * |
||
| 163 | * The meta query added by this action translates to a `LEFT JOIN` where the |
||
| 164 | * `_sticky` meta key is checked for both existence and non-existence. The |
||
| 165 | * point is to force the WordPress SQL builder to perform a `CAST(meta_value |
||
| 166 | * AS SIGNED)` in the `ORDER BY` clause as a sort of poor man's `COALESCE()`. |
||
| 167 | * |
||
| 168 | * @param WP_Query $query The current query instance, passed by reference. |
||
| 169 | */ |
||
| 170 | 2 | public static function pre_get_posts( $query ) { |
|
| 171 | |||
| 172 | // Don't alter admin queries: |
||
| 173 | 2 | if ( is_admin() ) { |
|
| 174 | 1 | return; |
|
| 175 | } |
||
| 176 | |||
| 177 | // Ignore sticky posts: |
||
| 178 | 1 | if ( $query->get( 'ignore_sticky_posts' ) ) { |
|
| 179 | 1 | return; |
|
| 180 | } |
||
| 181 | |||
| 182 | // Don't show stickies outside of home, post type or taxonomy archives: |
||
| 183 | 1 | if ( ! $query->is_home() && ! $query->is_post_type_archive() && ! $query->is_tax() ) { |
|
| 184 | 1 | return; |
|
| 185 | } |
||
| 186 | |||
| 187 | // Ignore when querying specific posts: |
||
| 188 | 1 | if ( $query->get( 'post__in' ) ) { |
|
| 189 | 1 | return; |
|
| 190 | } |
||
| 191 | |||
| 192 | // Ignore queries that already provide an order: |
||
| 193 | 1 | if ( $query->get( 'orderby' ) ) { |
|
| 194 | 1 | return; |
|
| 195 | } |
||
| 196 | |||
| 197 | // Ignore queries that already provide a meta query: |
||
| 198 | 1 | if ( $query->get( 'meta_query' ) ) { |
|
| 199 | 1 | return; |
|
| 200 | } |
||
| 201 | |||
| 202 | // Ignore core stickies now: |
||
| 203 | 1 | $query->set( 'ignore_sticky_posts', 1 ); |
|
| 204 | |||
| 205 | 1 | $query->set( 'meta_query', array( |
|
| 206 | array( |
||
| 207 | 1 | 'relation' => 'OR', |
|
| 208 | array( |
||
| 209 | 1 | 'key' => '_sticky', |
|
| 210 | 1 | 'type' => 'BINARY', |
|
| 211 | 1 | 'compare' => 'EXISTS', |
|
| 212 | 1 | ), |
|
| 213 | 'sticky_clause' => array( |
||
| 214 | 1 | 'key' => '_sticky', |
|
| 215 | 1 | 'type' => 'BINARY', |
|
| 216 | 1 | 'compare' => 'NOT EXISTS', |
|
| 217 | 1 | ), |
|
| 218 | 1 | ), |
|
| 219 | 1 | ) ); |
|
| 220 | |||
| 221 | 1 | $query->set( 'orderby', array( |
|
| 222 | 1 | 'sticky_clause' => 'DESC', |
|
| 223 | 1 | 'date' => 'DESC', |
|
| 224 | 1 | ) ); |
|
| 225 | 1 | } |
|
| 226 | |||
| 227 | /** |
||
| 228 | * Add a `sticky` HTML class to posts. |
||
| 229 | * |
||
| 230 | * @param array $classes An array of post classes. |
||
| 231 | * @param array $class An array of additional classes added to the post. |
||
| 232 | * @param int $post_id The post ID. |
||
| 233 | * @return array Filtered class list. |
||
| 234 | */ |
||
| 235 | 1 | public static function post_class( $classes, $class, $post_id ) { |
|
| 236 | 1 | if ( is_sticky( $post_id ) ) { |
|
| 237 | 1 | if ( is_home() || is_post_type_archive() || is_tax() ) { |
|
| 238 | 1 | $classes[] = 'sticky'; |
|
| 239 | 1 | } |
|
| 240 | 1 | } |
|
| 241 | |||
| 242 | 1 | return $classes; |
|
| 243 | } |
||
| 244 | |||
| 245 | /** |
||
| 246 | * Bulk update _sticky meta values for a group of post IDs. |
||
| 247 | * |
||
| 248 | * @param array $posts List of post IDs. |
||
| 249 | */ |
||
| 250 | 1 | private static function stick_posts( $posts ) { |
|
| 251 | 1 | foreach ( $posts as $post_id ) { |
|
| 252 | 1 | update_post_meta( $post_id, '_sticky', 1 ); |
|
| 253 | 1 | } |
|
| 254 | 1 | } |
|
| 255 | |||
| 256 | /** |
||
| 257 | * Bulk delete _sticky meta values for a group of post IDs. |
||
| 258 | * |
||
| 259 | * @param array $posts List of post IDs. |
||
| 260 | */ |
||
| 261 | 1 | private static function unstick_posts( $posts ) { |
|
| 262 | 1 | foreach ( $posts as $post_id ) { |
|
| 263 | 1 | delete_post_meta( $post_id, '_sticky' ); |
|
| 264 | 1 | } |
|
| 265 | 1 | } |
|
| 266 | |||
| 267 | } |
||
| 268 | |||
| 269 | register_activation_hook( __FILE__, array( 'Post_Glue', 'activation' ) ); |
||
| 270 | |||
| 271 | add_action( 'plugins_loaded', array( 'Post_Glue', 'plugins_loaded' ) ); |
||
| 272 |
Instead of relying on
globalstate, we recommend one of these alternatives:1. Pass all data via parameters
2. Create a class that maintains your state