[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Twenty Fourteen Featured Content 4 * 5 * This module allows you to define a subset of posts to be displayed 6 * in the theme's Featured Content area. 7 * 8 * For maximum compatibility with different methods of posting users 9 * will designate a featured post tag to associate posts with. Since 10 * this tag now has special meaning beyond that of a normal tags, users 11 * will have the ability to hide it from the front-end of their site. 12 */ 13 class Featured_Content { 14 15 /** 16 * The maximum number of posts a Featured Content area can contain. 17 * 18 * We define a default value here but themes can override 19 * this by defining a "max_posts" entry in the second parameter 20 * passed in the call to add_theme_support( 'featured-content' ). 21 * 22 * @see Featured_Content::init() 23 * 24 * @since Twenty Fourteen 1.0 25 * 26 * @static 27 * @access public 28 * @var int 29 */ 30 public static $max_posts = 15; 31 32 /** 33 * Instantiate. 34 * 35 * All custom functionality will be hooked into the "init" action. 36 * 37 * @static 38 * @access public 39 * @since Twenty Fourteen 1.0 40 */ 41 public static function setup() { 42 add_action( 'init', array( __CLASS__, 'init' ), 30 ); 43 } 44 45 /** 46 * Conditionally hook into WordPress. 47 * 48 * Theme must declare that they support this module by adding 49 * add_theme_support( 'featured-content' ); during after_setup_theme. 50 * 51 * If no theme support is found there is no need to hook into WordPress. 52 * We'll just return early instead. 53 * 54 * @static 55 * @access public 56 * @since Twenty Fourteen 1.0 57 */ 58 public static function init() { 59 $theme_support = get_theme_support( 'featured-content' ); 60 61 // Return early if theme does not support Featured Content. 62 if ( ! $theme_support ) { 63 return; 64 } 65 66 /* 67 * An array of named arguments must be passed as the second parameter 68 * of add_theme_support(). 69 */ 70 if ( ! isset( $theme_support[0] ) ) { 71 return; 72 } 73 74 // Return early if "featured_content_filter" has not been defined. 75 if ( ! isset( $theme_support[0]['featured_content_filter'] ) ) { 76 return; 77 } 78 79 $filter = $theme_support[0]['featured_content_filter']; 80 81 // Theme can override the number of max posts. 82 if ( isset( $theme_support[0]['max_posts'] ) ) { 83 self::$max_posts = absint( $theme_support[0]['max_posts'] ); 84 } 85 86 add_filter( $filter, array( __CLASS__, 'get_featured_posts' ) ); 87 add_action( 'customize_register', array( __CLASS__, 'customize_register' ), 9 ); 88 add_action( 'admin_init', array( __CLASS__, 'register_setting' ) ); 89 add_action( 'save_post', array( __CLASS__, 'delete_transient' ) ); 90 add_action( 'delete_post_tag', array( __CLASS__, 'delete_post_tag' ) ); 91 add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); 92 add_action( 'pre_get_posts', array( __CLASS__, 'pre_get_posts' ) ); 93 add_action( 'wp_loaded', array( __CLASS__, 'wp_loaded' ) ); 94 } 95 96 /** 97 * Hide "featured" tag from the front-end. 98 * 99 * Has to run on wp_loaded so that the preview filters of the customizer 100 * have a chance to alter the value. 101 * 102 * @static 103 * @access public 104 * @since Twenty Fourteen 1.0 105 */ 106 public static function wp_loaded() { 107 if ( self::get_setting( 'hide-tag' ) ) { 108 add_filter( 'get_terms', array( __CLASS__, 'hide_featured_term' ), 10, 2 ); 109 add_filter( 'get_the_terms', array( __CLASS__, 'hide_the_featured_term' ), 10, 3 ); 110 } 111 } 112 113 /** 114 * Get featured posts. 115 * 116 * @static 117 * @access public 118 * @since Twenty Fourteen 1.0 119 * 120 * @return array Array of featured posts. 121 */ 122 public static function get_featured_posts() { 123 $post_ids = self::get_featured_post_ids(); 124 125 // No need to query if there is are no featured posts. 126 if ( empty( $post_ids ) ) { 127 return array(); 128 } 129 130 $featured_posts = get_posts( array( 131 'include' => $post_ids, 132 'posts_per_page' => count( $post_ids ), 133 ) ); 134 135 return $featured_posts; 136 } 137 138 /** 139 * Get featured post IDs 140 * 141 * This function will return the an array containing the 142 * post IDs of all featured posts. 143 * 144 * Sets the "featured_content_ids" transient. 145 * 146 * @static 147 * @access public 148 * @since Twenty Fourteen 1.0 149 * 150 * @return array Array of post IDs. 151 */ 152 public static function get_featured_post_ids() { 153 // Return array of cached results if they exist. 154 $featured_ids = get_transient( 'featured_content_ids' ); 155 if ( ! empty( $featured_ids ) ) { 156 return array_map( 'absint', (array) $featured_ids ); 157 } 158 159 $settings = self::get_setting(); 160 161 // Return sticky post ids if no tag name is set. 162 $term = get_term_by( 'name', $settings['tag-name'], 'post_tag' ); 163 if ( $term ) { 164 $tag = $term->term_id; 165 } else { 166 return self::get_sticky_posts(); 167 } 168 169 // Query for featured posts. 170 $featured = get_posts( array( 171 'numberposts' => $settings['quantity'], 172 'tax_query' => array( 173 array( 174 'field' => 'term_id', 175 'taxonomy' => 'post_tag', 176 'terms' => $tag, 177 ), 178 ), 179 ) ); 180 181 // Return array with sticky posts if no Featured Content exists. 182 if ( ! $featured ) { 183 return self::get_sticky_posts(); 184 } 185 186 // Ensure correct format before save/return. 187 $featured_ids = wp_list_pluck( (array) $featured, 'ID' ); 188 $featured_ids = array_map( 'absint', $featured_ids ); 189 190 set_transient( 'featured_content_ids', $featured_ids ); 191 192 return $featured_ids; 193 } 194 195 /** 196 * Return an array with IDs of posts maked as sticky. 197 * 198 * @static 199 * @access public 200 * @since Twenty Fourteen 1.0 201 * 202 * @return array Array of sticky posts. 203 */ 204 public static function get_sticky_posts() { 205 $settings = self::get_setting(); 206 return array_slice( get_option( 'sticky_posts', array() ), 0, $settings['quantity'] ); 207 } 208 209 /** 210 * Delete featured content ids transient. 211 * 212 * Hooks in the "save_post" action. 213 * 214 * @see Featured_Content::validate_settings(). 215 * 216 * @static 217 * @access public 218 * @since Twenty Fourteen 1.0 219 */ 220 public static function delete_transient() { 221 delete_transient( 'featured_content_ids' ); 222 } 223 224 /** 225 * Exclude featured posts from the home page blog query. 226 * 227 * Filter the home page posts, and remove any featured post ID's from it. 228 * Hooked onto the 'pre_get_posts' action, this changes the parameters of 229 * the query before it gets any posts. 230 * 231 * @static 232 * @access public 233 * @since Twenty Fourteen 1.0 234 * 235 * @param WP_Query $query WP_Query object. 236 * @return WP_Query Possibly-modified WP_Query. 237 */ 238 public static function pre_get_posts( $query ) { 239 240 // Bail if not home or not main query. 241 if ( ! $query->is_home() || ! $query->is_main_query() ) { 242 return; 243 } 244 245 $page_on_front = get_option( 'page_on_front' ); 246 247 // Bail if the blog page is not the front page. 248 if ( ! empty( $page_on_front ) ) { 249 return; 250 } 251 252 $featured = self::get_featured_post_ids(); 253 254 // Bail if no featured posts. 255 if ( ! $featured ) { 256 return; 257 } 258 259 // We need to respect post ids already in the blacklist. 260 $post__not_in = $query->get( 'post__not_in' ); 261 262 if ( ! empty( $post__not_in ) ) { 263 $featured = array_merge( (array) $post__not_in, $featured ); 264 $featured = array_unique( $featured ); 265 } 266 267 $query->set( 'post__not_in', $featured ); 268 } 269 270 /** 271 * Reset tag option when the saved tag is deleted. 272 * 273 * It's important to mention that the transient needs to be deleted, 274 * too. While it may not be obvious by looking at the function alone, 275 * the transient is deleted by Featured_Content::validate_settings(). 276 * 277 * Hooks in the "delete_post_tag" action. 278 * 279 * @see Featured_Content::validate_settings(). 280 * 281 * @static 282 * @access public 283 * @since Twenty Fourteen 1.0 284 * 285 * @param int $tag_id The term_id of the tag that has been deleted. 286 * @return void 287 */ 288 public static function delete_post_tag( $tag_id ) { 289 $settings = self::get_setting(); 290 291 if ( empty( $settings['tag-id'] ) || $tag_id != $settings['tag-id'] ) { 292 return; 293 } 294 295 $settings['tag-id'] = 0; 296 $settings = self::validate_settings( $settings ); 297 update_option( 'featured-content', $settings ); 298 } 299 300 /** 301 * Hide featured tag from displaying when global terms are queried from the front-end. 302 * 303 * Hooks into the "get_terms" filter. 304 * 305 * @static 306 * @access public 307 * @since Twenty Fourteen 1.0 308 * 309 * @param array $terms List of term objects. This is the return value of get_terms(). 310 * @param array $taxonomies An array of taxonomy slugs. 311 * @return array A filtered array of terms. 312 * 313 * @uses Featured_Content::get_setting() 314 */ 315 public static function hide_featured_term( $terms, $taxonomies ) { 316 317 // This filter is only appropriate on the front-end. 318 if ( is_admin() ) { 319 return $terms; 320 } 321 322 // We only want to hide the featured tag. 323 if ( ! in_array( 'post_tag', $taxonomies ) ) { 324 return $terms; 325 } 326 327 // Bail if no terms were returned. 328 if ( empty( $terms ) ) { 329 return $terms; 330 } 331 332 foreach( $terms as $order => $term ) { 333 if ( self::get_setting( 'tag-id' ) == $term->term_id && 'post_tag' == $term->taxonomy ) { 334 unset( $terms[ $order ] ); 335 } 336 } 337 338 return $terms; 339 } 340 341 /** 342 * Hide featured tag from display when terms associated with a post object 343 * are queried from the front-end. 344 * 345 * Hooks into the "get_the_terms" filter. 346 * 347 * @static 348 * @access public 349 * @since Twenty Fourteen 1.0 350 * 351 * @param array $terms A list of term objects. This is the return value of get_the_terms(). 352 * @param int $id The ID field for the post object that terms are associated with. 353 * @param array $taxonomy An array of taxonomy slugs. 354 * @return array Filtered array of terms. 355 * 356 * @uses Featured_Content::get_setting() 357 */ 358 public static function hide_the_featured_term( $terms, $id, $taxonomy ) { 359 360 // This filter is only appropriate on the front-end. 361 if ( is_admin() ) { 362 return $terms; 363 } 364 365 // Make sure we are in the correct taxonomy. 366 if ( 'post_tag' != $taxonomy ) { 367 return $terms; 368 } 369 370 // No terms? Return early! 371 if ( empty( $terms ) ) { 372 return $terms; 373 } 374 375 foreach( $terms as $order => $term ) { 376 if ( self::get_setting( 'tag-id' ) == $term->term_id ) { 377 unset( $terms[ $term->term_id ] ); 378 } 379 } 380 381 return $terms; 382 } 383 384 /** 385 * Register custom setting on the Settings -> Reading screen. 386 * 387 * @static 388 * @access public 389 * @since Twenty Fourteen 1.0 390 * 391 * @return void 392 */ 393 public static function register_setting() { 394 register_setting( 'featured-content', 'featured-content', array( __CLASS__, 'validate_settings' ) ); 395 } 396 397 /** 398 * Add settings to the Customizer. 399 * 400 * @static 401 * @access public 402 * @since Twenty Fourteen 1.0 403 * 404 * @param WP_Customize_Manager $wp_customize Theme Customizer object. 405 */ 406 public static function customize_register( $wp_customize ) { 407 $wp_customize->add_section( 'featured_content', array( 408 'title' => __( 'Featured Content', 'twentyfourteen' ), 409 'description' => sprintf( __( 'Use the <a href="%1$s">"featured" tag</a> to feature your posts. You can change this to a tag of your choice; if no posts match the tag, <a href="%2$s">sticky posts</a> will be displayed instead.', 'twentyfourteen' ), admin_url( '/edit.php?tag=featured' ), admin_url( '/edit.php?show_sticky=1' ) ), 410 'priority' => 130, 411 'theme_supports' => 'featured-content', 412 ) ); 413 414 // Add Featured Content settings. 415 $wp_customize->add_setting( 'featured-content[tag-name]', array( 416 'default' => 'featured', 417 'type' => 'option', 418 'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ), 419 ) ); 420 $wp_customize->add_setting( 'featured-content[hide-tag]', array( 421 'default' => true, 422 'type' => 'option', 423 'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ), 424 ) ); 425 426 // Add Featured Content controls. 427 $wp_customize->add_control( 'featured-content[tag-name]', array( 428 'label' => __( 'Tag Name', 'twentyfourteen' ), 429 'section' => 'featured_content', 430 'priority' => 20, 431 ) ); 432 $wp_customize->add_control( 'featured-content[hide-tag]', array( 433 'label' => __( 'Don’t display tag on front end.', 'twentyfourteen' ), 434 'section' => 'featured_content', 435 'type' => 'checkbox', 436 'priority' => 30, 437 ) ); 438 } 439 440 /** 441 * Enqueue the tag suggestion script. 442 * 443 * @static 444 * @access public 445 * @since Twenty Fourteen 1.0 446 */ 447 public static function enqueue_scripts() { 448 wp_enqueue_script( 'featured-content-suggest', get_template_directory_uri() . '/js/featured-content-admin.js', array( 'jquery', 'suggest' ), '20131022', true ); 449 } 450 451 /** 452 * Get featured content settings. 453 * 454 * Get all settings recognized by this module. This function 455 * will return all settings whether or not they have been stored 456 * in the database yet. This ensures that all keys are available 457 * at all times. 458 * 459 * In the event that you only require one setting, you may pass 460 * its name as the first parameter to the function and only that 461 * value will be returned. 462 * 463 * @static 464 * @access public 465 * @since Twenty Fourteen 1.0 466 * 467 * @param string $key The key of a recognized setting. 468 * @return mixed Array of all settings by default. A single value if passed as first parameter. 469 */ 470 public static function get_setting( $key = 'all' ) { 471 $saved = (array) get_option( 'featured-content' ); 472 473 $defaults = array( 474 'hide-tag' => 1, 475 'quantity' => 6, 476 'tag-id' => 0, 477 'tag-name' => 'featured', 478 ); 479 480 $options = wp_parse_args( $saved, $defaults ); 481 $options = array_intersect_key( $options, $defaults ); 482 $options['quantity'] = self::sanitize_quantity( $options['quantity'] ); 483 484 if ( 'all' != $key ) { 485 return isset( $options[ $key ] ) ? $options[ $key ] : false; 486 } 487 488 return $options; 489 } 490 491 /** 492 * Validate featured content settings. 493 * 494 * Make sure that all user supplied content is in an expected 495 * format before saving to the database. This function will also 496 * delete the transient set in Featured_Content::get_featured_content(). 497 * 498 * @static 499 * @access public 500 * @since Twenty Fourteen 1.0 501 * 502 * @param array $input Array of settings input. 503 * @return array Validated settings output. 504 */ 505 public static function validate_settings( $input ) { 506 $output = array(); 507 508 if ( empty( $input['tag-name'] ) ) { 509 $output['tag-id'] = 0; 510 } else { 511 $term = get_term_by( 'name', $input['tag-name'], 'post_tag' ); 512 513 if ( $term ) { 514 $output['tag-id'] = $term->term_id; 515 } else { 516 $new_tag = wp_create_tag( $input['tag-name'] ); 517 518 if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) ) { 519 $output['tag-id'] = $new_tag['term_id']; 520 } 521 } 522 523 $output['tag-name'] = $input['tag-name']; 524 } 525 526 if ( isset( $input['quantity'] ) ) { 527 $output['quantity'] = self::sanitize_quantity( $input['quantity'] ); 528 } 529 530 $output['hide-tag'] = isset( $input['hide-tag'] ) && $input['hide-tag'] ? 1 : 0; 531 532 // Delete the featured post ids transient. 533 self::delete_transient(); 534 535 return $output; 536 } 537 538 /** 539 * Sanitize quantity of featured posts. 540 * 541 * @static 542 * @access public 543 * @since Twenty Fourteen 1.0 544 * 545 * @param int $input The value to sanitize. 546 * @return int A number between 1 and FeaturedContent::$max_posts. 547 */ 548 public static function sanitize_quantity( $input ) { 549 $quantity = absint( $input ); 550 551 if ( $quantity > self::$max_posts ) { 552 $quantity = self::$max_posts; 553 } else if ( 1 > $quantity ) { 554 $quantity = 1; 555 } 556 557 return $quantity; 558 } 559 560 } // Featured_Content 561 562 Featured_Content::setup();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |