WordPress.org

Making WordPress.org

Changeset 9990


Ignore:
Timestamp:
07/01/2020 07:42:15 PM (17 months ago)
Author:
coffee2code
Message:

Handbook plugin: Split root file classes out into separate include files.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook/handbook.php

    r9845 r9990  
    33 * Plugin Name: Handbook
    44 * Description: Features for a handbook, complete with glossary and table of contents
    5  * Author: Nacin
     5 * Author:      WordPress.org
     6 * Author URI:  https://wordpress.org/
     7 * License:     GPLv2 or later
     8 * Text Domain: wporg
    69 */
    710
    811const WPORG_HANDBOOK_PLUGIN_FILE = __FILE__;
    912
     13require_once __DIR__ . '/inc/init.php';
     14require_once __DIR__ . '/inc/handbook.php';
    1015require_once __DIR__ . '/inc/admin-notices.php';
    1116require_once __DIR__ . '/inc/callout-boxes.php';
     
    2025require_once __DIR__ . '/inc/blocks.php';
    2126
    22 /**
    23  * Initialize our handbooks
    24  *
    25  */
    26 class WPorg_Handbook_Init {
    27 
    28     public static function get_post_types() {
    29         return (array) apply_filters( 'handbook_post_types', array( 'handbook' ) );
    30     }
    31 
    32     static function init() {
    33 
    34         $post_types = self::get_post_types();
    35 
    36         new WPorg_Handbook_TOC( $post_types );
    37 
    38         foreach ( $post_types as $type ) {
    39             new WPorg_Handbook( $type );
    40         }
    41 
    42         WPorg_Handbook_Glossary::init();
    43 
    44         add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_styles' ) );
    45         add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
    46     }
    47 
    48     static public function enqueue_styles() {
    49         wp_enqueue_style( 'wporg-handbook-css', plugins_url( '/stylesheets/callout-boxes.css', __FILE__ ), array(), '20200121' );
    50     }
    51 
    52     static public function enqueue_scripts() {
    53         wp_enqueue_script( 'wporg-handbook', plugins_url( '/scripts/handbook.js', __FILE__ ), array( 'jquery' ), '20150930' );
    54     }
    55 
    56 }
    57 
    58 add_action( 'after_setup_theme', array( 'WPorg_Handbook_Init', 'init' ) );
    59 
    60 class WPorg_Handbook {
    61 
    62     public $post_type = '';
    63     public $setting_name = '';
    64 
    65     protected $label = '';
    66 
    67     static function caps() {
    68         return array(
    69             'edit_handbook_pages', 'edit_others_handbook_pages',
    70             'edit_published_handbook_pages',
    71         );
    72     }
    73 
    74     static function editor_caps() {
    75         return array(
    76             'publish_handbook_pages',
    77             'delete_handbook_pages', 'delete_others_handbook_pages',
    78             'delete_published_handbook_pages', 'delete_private_handbook_pages',
    79             'edit_private_handbook_pages', 'read_private_handbook_pages',
    80         );
    81     }
    82 
    83     /**
    84      * Returns the handbook name.
    85      *
    86      * If one isn't set via settings, one is generated.
    87      *
    88      * @param  string $post_type Optional. Handbook post type.
    89      * @param  bool   $raw       Optional. Return only explicitly set name without attempting to generate default name?
    90      * @return string
    91      */
    92     static function get_name( $post_type = 'handbook', $raw = false ) {
    93         // Prefer explicitly configured handbook name.
    94         $name = get_option( $post_type . '_name' );
    95 
    96         // If handbook name isn't set, try root relative site path.
    97         if ( ! $raw && empty( $name ) ) {
    98             if ( is_multisite() ) {
    99                 $name = trim( get_blog_details()->path, '/' );
    100             } else {
    101                 $name = trim( parse_url( get_option( 'home' ), PHP_URL_PATH ), '/' );
    102             }
    103 
    104             // If no name defined yet, try handbook post type if not standard.
    105             if ( empty( $name ) && ( 'handbook' != $post_type ) ) {
    106                 $name = ucfirst( substr( $post_type, 0, -9 ) );
    107             }
    108 
    109             $name .= ' Handbook';
    110         }
    111 
    112         return trim( $name );
    113     }
    114 
    115     function __construct( $type ) {
    116         if ( 'handbook' != $type ) {
    117             $this->post_type = $type . '-handbook';
    118         } else {
    119             $this->post_type = $type;
    120         }
    121 
    122         $this->label = ucwords( str_replace( array( '-', '_' ), ' ', $this->post_type ) );
    123         $this->label = apply_filters( 'handbook_label', $this->label, $this->post_type );
    124 
    125         $this->setting_name = $this->post_type . '_name';
    126 
    127         add_filter( 'user_has_cap',                       array( $this, 'grant_handbook_caps' ) );
    128         add_action( 'widgets_init',                       array( $this, 'register_post_type' ) );
    129         add_filter( 'post_type_link',                     array( $this, 'post_type_link' ), 10, 2 );
    130         add_action( 'template_redirect',                  array( $this, 'redirect_handbook_root_page' ) );
    131         add_filter( 'template_include',                   array( $this, 'template_include' ) );
    132         add_filter( 'pre_get_posts',                      array( $this, 'pre_get_posts' ) );
    133         add_action( 'widgets_init',                       array( $this, 'handbook_sidebar' ), 11 ); // After P2
    134         add_action( 'wporg_email_changes_for_post_types', array( $this, 'wporg_email_changes_for_post_types' ) );
    135         add_action( 'p2_action_links',                    array( $this, 'disable_p2_resolved_posts_action_links' ) );
    136         add_action( 'admin_init',                         array( $this, 'add_name_setting' ) );
    137         add_filter( 'body_class',                         array( $this, 'add_body_class' ) );
    138         add_filter( 'post_class',                         array( $this, 'add_post_class' ) );
    139         add_filter( 'o2_process_the_content',             array( $this, 'disable_o2_processing' ) );
    140         add_filter( 'o2_application_container',           array( $this, 'o2_application_container' ) );
    141         add_filter( 'o2_view_type',                       array( $this, 'o2_view_type' ) );
    142         add_filter( 'o2_post_fragment',                   array( $this, 'o2_post_fragment' ) );
    143         add_filter( 'comments_open',                      array( $this, 'comments_open' ), 10, 2 );
    144         add_filter( 'wp_nav_menu_objects',                array( $this, 'highlight_menu_handbook_link' ) );
    145         add_filter( 'display_post_states',                array( $this, 'display_post_states' ), 10, 2 );
    146     }
    147 
    148     /**
    149      * Adds 'Handbook Front Page' post state indicator for handbook landing pages.
    150      *
    151      * @param string[] $post_states An array of post display states.
    152      * @param WP_Post  $post        The current post object.
    153      * @return string[]
    154      */
    155     function display_post_states( $post_states, $post ) {
    156         if ( $this->post_is_landing_page( $post ) ) {
    157             $post_states[] = __( 'Handbook Front Page', 'wporg' );
    158         }
    159         return $post_states;
    160     }
    161 
    162     /**
    163      * Adds custom handbook-related classes to body tag.
    164      *
    165      * * Adds 'single-handbook' class for any handbook page.
    166      * * Adds 'handbook-landing-page' class for page acting as a handbook landing
    167      *   page.
    168      *
    169      * @param array $classes Array of body classes.
    170      * @return array
    171      */
    172     function add_body_class( $classes ) {
    173         if ( is_singular() && wporg_is_handbook( $this->post_type ) ) {
    174             $classes[] = 'single-handbook';
    175         }
    176 
    177         if ( wporg_is_handbook_landing_page() ) {
    178             $classes[] = 'handbook-landing-page';
    179         }
    180 
    181         return $classes;
    182     }
    183 
    184     /**
    185      * Adds 'type-handbook' class to the list of post classes to a handbook post
    186      * when appropriate.
    187      *
    188      * @param array $classes Array of post classes.
    189      * @return array
    190      */
    191     function add_post_class( $classes ) {
    192         if ( $this->post_type === get_post_type() ) {
    193             $classes[] = 'type-handbook';
    194         }
    195 
    196         return $classes;
    197     }
    198 
    199     function add_name_setting() {
    200         register_setting( 'general', $this->setting_name, 'esc_attr' );
    201 
    202         $label = ( 'handbook' == $this->post_type ) ?
    203             __( 'Handbook name', 'wporg' ) :
    204             sprintf( __( 'Handbook name (%s)', 'wporg' ), substr( $this->post_type, 0, -9 ) );
    205 
    206         add_settings_field(
    207             $this->setting_name,
    208             '<label for="' . esc_attr( $this->setting_name ) . '">' . $label . '</label>',
    209             array( $this, 'name_setting_html' ),
    210             'general'
    211         );
    212     }
    213 
    214     function name_setting_html() {
    215         $value = get_option( $this->setting_name, '' );
    216         echo '<input type="text" id="' . esc_attr( $this->setting_name ) . '" name="' . esc_attr( $this->setting_name ) . '" value="' . esc_attr( $value ) . '" class="regular-text ltr" />';
    217     }
    218 
    219     function grant_handbook_caps( $caps ) {
    220         if ( ! is_user_member_of_blog() ) {
    221             return $caps;
    222         }
    223 
    224         foreach ( self::caps() as $cap ) {
    225             $caps[ $cap ] = true;
    226         }
    227 
    228         if ( ! empty( $caps['edit_pages'] ) ) {
    229             foreach ( self::editor_caps() as $cap ) {
    230                 $caps[ $cap ] = true;
    231             }
    232         }
    233 
    234         return $caps;
    235     }
    236 
    237     function register_post_type() {
    238         if ( 'handbook' != $this->post_type ) {
    239             $slug = substr( $this->post_type, 0, -9 );
    240         } else {
    241             $slug = 'handbook';
    242         }
    243 
    244         $default_config = array(
    245             'labels' => array(
    246                 'name'          => $this->label,
    247                 'singular_name' => sprintf( __( '%s Page', 'wporg' ), $this->label ),
    248                 'menu_name'     => $this->label,
    249                 'all_items'     => sprintf( __( '%s Pages', 'wporg' ), $this->label ),
    250             ),
    251             'public'            => true,
    252             'show_ui'           => true,
    253             'show_in_rest'      => true,
    254             'capability_type'   => 'handbook_page',
    255             'map_meta_cap'      => true,
    256             'has_archive'       => true,
    257             'hierarchical'      => true,
    258             'menu_icon'         => 'dashicons-book',
    259             'menu_position'     => 11,
    260             'rewrite' => array(
    261                 'feeds'         => false,
    262                 'slug'          => $slug,
    263                 'with_front'    => false,
    264             ),
    265             'delete_with_user'  => false,
    266             'supports'          => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'revisions', 'wpcom-markdown' ),
    267         );
    268         // Allow customization of the default post type configuration via filter.
    269         $config = apply_filters( 'handbook_post_type_defaults', $default_config, $slug );
    270 
    271         $this->label = $config['labels']['name'];
    272 
    273         register_post_type( $this->post_type, $config );
    274     }
    275 
    276     /**
    277      * Determines if the given values correspond to a post that acts as the
    278      * landing page for this handbook.
    279      *
    280      * @param int|WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
    281      * @return bool True if the given information would make such a post the
    282      *              handbook's landing page.
    283      */
    284     protected function post_is_landing_page( $post = null ) {
    285         $is_landing_page = false;
    286 
    287         $post_type = get_post_type( $post );
    288         $slug      = get_post_field( 'post_name', $post );
    289 
    290         if (
    291             $post_type === $this->post_type
    292         &&
    293             (
    294                 $post_type === $slug
    295             ||
    296                 $post_type === "{$slug}-handbook"
    297             ||
    298                 'handbook' === $slug
    299             ||
    300                 'welcome'  === $slug
    301             )
    302         &&
    303             ! wp_get_post_parent_id( $post )
    304         ) {
    305             $is_landing_page = true;
    306         }
    307 
    308         return $is_landing_page;
    309     }
    310 
    311     /**
    312      * For a handbook page acting as the root page for the handbook, change its
    313      * permalink to be the equivalent of the post type archive link.
    314      *
    315      * @param string  $post_link The post's permalink.
    316      * @param WP_Post $post      The post in question.
    317      */
    318     function post_type_link( $post_link, $post ) {
    319         $post_type = get_post_type( $post );
    320 
    321         // Only change links for this handbook's post type.
    322         if ( $this->post_is_landing_page( $post ) ) {
    323             $post_link = get_post_type_archive_link( $post_type );
    324         }
    325 
    326         return $post_link;
    327     }
    328 
    329     /**
    330      * For a handbook page acting as the root page for the handbook, redirect to the
    331      * post type archive link for the handbook.
    332      */
    333     function redirect_handbook_root_page() {
    334         global $wp_query;
    335 
    336         if ( is_singular( $this->post_type )
    337             &&
    338             ! is_preview()
    339             &&
    340             ! $wp_query->is_handbook_root
    341             &&
    342             $this->post_is_landing_page( get_queried_object_id() )
    343         ) {
    344             wp_safe_redirect( get_post_type_archive_link( $this->post_type ), 301 );
    345             exit;
    346         }
    347     }
    348 
    349     /**
    350      * Use 'single-handbook.php' as the fallback template for handbooks.
    351      *
    352      * Applies to handbooks using a post type other than 'handbook', as well as
    353      * the handbook root page.
    354      *
    355      * @param string $template The path of the template to include.
    356      * @return string
    357      */
    358     function template_include( $template ) {
    359         global $wp_query;
    360 
    361         // Don't override Embeds
    362         if ( is_embed() ) {
    363             return $template;
    364         }
    365 
    366         $handbook_templates = array();
    367 
    368         // For singular handbook pages not of the 'handbook' post type.
    369         if ( is_singular( $this->post_type ) && 'handbook' !== $this->post_type ) {
    370             $handbook_templates = array( "single-{$this->post_type}.php", 'single-handbook.php' );
    371         }
    372         // For handbook landing page.
    373         elseif ( $wp_query->is_handbook_root && get_query_var( 'handbook' ) === $this->post_type ) {
    374             if ( 'handbook' !== $this->post_type ) {
    375                 $handbook_templates[] = "single-{$this->post_type}.php";
    376             }
    377             $handbook_templates[] = 'single-handbook.php';
    378         }
    379 
    380         if ( $handbook_templates ) {
    381             if ( $handbook_template = locate_template( $handbook_templates ) ) {
    382                 $template = $handbook_template;
    383             }
    384         }
    385 
    386         return $template;
    387     }
    388 
    389     function pre_get_posts( $query ) {
    390         // Bail early if query is not for this handbook's post type.
    391         if ( get_query_var( 'post_type' ) !== $this->post_type ) {
    392             // Request is obviously not for a handbook root page. (Though if the request is
    393             // for some other handbook's root page will be determined by that handbook.)
    394             if ( empty( get_query_var( 'handbook' ) ) ) {
    395                 $query->is_handbook_root = false;
    396             }
    397             return;
    398         }
    399 
    400         $query->is_handbook_root = false;
    401 
    402         if ( $query->is_main_query() && ! $query->is_admin && ! $query->is_search && $query->is_post_type_archive( $this->post_type ) ) {
    403             // If the post type has a page to act as an archive index page, get that.
    404             $page = get_page_by_path( $this->post_type, OBJECT, $this->post_type );
    405             if ( ! $page ) {
    406                 $slug = substr( $this->post_type, 0, -9 );
    407                 $page = get_page_by_path( $slug, OBJECT, $this->post_type );
    408             }
    409             if ( ! $page ) {
    410                 $page = get_page_by_path( 'handbook', OBJECT, $this->post_type );
    411             }
    412             if ( ! $page ) {
    413                 $page = get_page_by_path( 'welcome', OBJECT, $this->post_type );
    414             }
    415             if ( $page ) {
    416                 $query->set( 'p', $page->ID );
    417                 $query->is_handbook_root     = true;
    418 
    419                 $query->is_archive           = false;
    420                 $query->is_post_type_archive = false;
    421                 $query->is_single            = true;
    422                 $query->is_singular          = true;
    423             }
    424             $query->set( 'handbook', $this->post_type );
    425         }
    426     }
    427 
    428     function handbook_sidebar() {
    429         $sidebar_args = array(
    430             'id'          => $this->post_type,
    431             'name'        => sprintf( __( '%s Sidebar', 'wporg' ), $this->label ),
    432             'description' => sprintf( __( 'Used on %s pages', 'wporg' ), $this->label ),
    433             'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    434             'after_widget'  => '</aside>',
    435             'before_title'  => '<h2 class="widget-title">',
    436             'after_title'   => '</h2>',
    437         );
    438 
    439         $sidebar_args = apply_filters( 'wporg_handbook_sidebar_args', $sidebar_args, $this );
    440 
    441         register_sidebar( $sidebar_args );
    442 
    443         require_once __DIR__ . '/inc/widgets.php';
    444         register_widget( 'WPorg_Handbook_Pages_Widget' );
    445     }
    446 
    447     function wporg_email_changes_for_post_types( $post_types ) {
    448         if ( ! in_array( $this->post_type, $post_types ) ) {
    449             $post_types[] = $this->post_type;
    450         }
    451 
    452         return $post_types;
    453     }
    454 
    455     /**
    456      * Disable the P2 Resolved Posts plugin's action links (e.g. "Flag Unresolved"),
    457      * if that plugin is active.
    458      */
    459     function disable_p2_resolved_posts_action_links() {
    460         if ( ( $this->post_type == get_post_type() ) && class_exists( 'P2_Resolved_Posts' ) && isset( $GLOBALS['p2_resolved_posts'] ) && is_object( $GLOBALS['p2_resolved_posts'] ) ) {
    461             remove_filter( 'p2_action_links', array( P2_Resolved_Posts::instance(), 'p2_action_links' ), 100 );
    462         }
    463     }
    464 
    465     /**
    466      * Disables handbook post content processing by the o2 plugin.
    467      *
    468      * @param bool $process_with_o2 Is o2 about to process the post content?
    469      * @return bool
    470      */
    471     function disable_o2_processing( $process_with_o2 ) {
    472         return ( is_singular() && $this->post_type === get_post_type() ) ? false : $process_with_o2;
    473     }
    474 
    475     /**
    476      * Use the correct ID for the content container element.
    477      *
    478      * @param string $container The container element ID.
    479      * @return string
    480      */
    481     function o2_application_container( $container ) {
    482         return ( is_singular() && $this->post_type === get_post_type() ) ? '#primary' : $container;
    483     }
    484 
    485     /**
    486      * Tell o2 to use the 'single' view type for handbook pages. This removes a lot of the meta
    487      * cruft around the content.
    488      *
    489      * @param string $view_type The o2 view type.
    490      * @return string
    491      */
    492     function o2_view_type( $view_type ) {
    493         return ( is_singular() && $this->post_type === get_post_type() ) ? 'single' : $view_type;
    494     }
    495 
    496     /**
    497      * Tell o2 to treat the handbook page the same as it would a normal page.
    498      *
    499      * @param array $post_fragment The o2 post fragment
    500      * @return array
    501      */
    502     function o2_post_fragment( $post_fragment ) {
    503         $post = get_post( $post_fragment['id'] );
    504         if ( ! $post ) {
    505             return $post_fragment;
    506         }
    507 
    508         if ( $post->post_type === $this->post_type ) {
    509             $post_fragment['isPage'] = true;
    510         }
    511 
    512         return $post_fragment;
    513     }
    514 
    515     /**
    516      * Don't show the comment form on handbook pages.
    517      *
    518      * @param bool $open Whether the comments are open or not.
    519      * @param WP_Post|int $post_id The current post.
    520      * @return bool
    521      */
    522     function comments_open( $open, $post_id ) {
    523         $post = get_post( $post_id );
    524         if ( ! $post ) {
    525             return $open;
    526         }
    527 
    528         if ( $post->post_type === $this->post_type ) {
    529             return false;
    530         }
    531 
    532         return $open;
    533     }
    534 
    535     /**
    536      * Highlights a menu link to the handbook home page when on any constituent
    537      * handbook page.
    538      *
    539      * Assuming the handbook page isn't already directly linked in the menu,
    540      * preference is given to highlight a link to the front page of the current
    541      * handbook. Barring the presence of such a link, it will check to see if
    542      * there is a link to a 'handbook' or 'handbooks' page, which could be the
    543      * case for multi-handbook sites.
    544      *
    545      * @param array $menu_items Array of sorted menu items.
    546      * @return array
    547      */
    548     function highlight_menu_handbook_link( $menu_items ) {
    549         // Must be on a handbook page that isn't the handbook landing page (which will already be handled).
    550         if ( ! is_page( array( 'handbook', 'handbooks' ) ) && ( ! wporg_is_handbook() || wporg_is_handbook_landing_page() ) ) {
    551             return $menu_items;
    552         }
    553 
    554         // Menu must not have an item that is already noted as being current.
    555         $current_menu_item = wp_filter_object_list( $menu_items, array( 'current' => true ) );
    556         if ( $current_menu_item ) {
    557             return $menu_items;
    558         }
    559 
    560         // Menu must have an item that links to handbook home page.
    561         $root_handbook_menu_item = wp_filter_object_list( $menu_items, array( 'url' => wporg_get_current_handbook_home_url() ) );
    562         if ( ! $root_handbook_menu_item ) {
    563             // Or it must have an item that links to a 'handbook' or 'handbooks' page.
    564             $page_slug = is_page( 'handbooks' ) ? 'handbooks' : 'handbook';
    565             $page = get_page_by_path( $page_slug );
    566             if ( $page ) {
    567                 $root_handbook_menu_item = wp_filter_object_list( $menu_items, array( 'object_id' => $page->ID ) );
    568             }
    569         }
    570         if ( ! $root_handbook_menu_item ) {
    571             return $menu_items;
    572         }
    573 
    574         // Add current-menu-item class to the handbook menu item.
    575         reset( $root_handbook_menu_item );
    576         $handbook_item_index = key( $root_handbook_menu_item );
    577         $menu_items[ $handbook_item_index ]->classes[] = 'current-menu-item';
    578 
    579         return $menu_items;
    580     }
    581 
    582 }
Note: See TracChangeset for help on using the changeset viewer.