WordPress.org

Making WordPress.org


Ignore:
File:
1 edited

Legend:

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

    r10356 r10837  
    88class WPorg_Handbook {
    99
     10    /**
     11     * The handbook post type.
     12     *
     13     * @var string
     14     */
    1015    public $post_type = '';
     16
     17    /**
     18     * The handbook's settings.
     19     *
     20     * @var array
     21     */
     22    public $settings = [];
     23
     24    /**
     25     * The name of the setting for the handbook's name.
     26     *
     27     * @var string
     28     */
    1129    public $setting_name = '';
    1230
     31    /**
     32     * The memoized and filtered label text for the handbook.
     33     *
     34     * @var string
     35     */
    1336    protected $label = '';
    1437
    15     static function caps() {
    16         return array(
    17             'edit_handbook_pages', 'edit_others_handbook_pages',
     38    /**
     39     * The associated importer object, if warranted.
     40     */
     41    protected $importer;
     42
     43    /**
     44     * Returns the custom handbook-related capabilities granted to site users.
     45     *
     46     * @return array
     47     */
     48    public static function caps() {
     49        return [
     50            'edit_handbook_pages',
     51            'edit_others_handbook_pages',
    1852            'edit_published_handbook_pages',
    19         );
    20     }
    21 
    22     static function editor_caps() {
    23         return array(
     53        ];
     54    }
     55
     56    /**
     57     * Returns the custom capabilities granted to handbook editors.
     58     *
     59     * @return array
     60     */
     61    public static function editor_caps() {
     62        return [
    2463            'publish_handbook_pages',
    25             'delete_handbook_pages', 'delete_others_handbook_pages',
    26             'delete_published_handbook_pages', 'delete_private_handbook_pages',
    27             'edit_private_handbook_pages', 'read_private_handbook_pages',
    28         );
     64            'delete_handbook_pages',
     65            'delete_others_handbook_pages',
     66            'delete_published_handbook_pages',
     67            'delete_private_handbook_pages',
     68            'edit_private_handbook_pages',
     69            'read_private_handbook_pages',
     70        ];
     71    }
     72
     73    /**
     74     * Returns handbook default config.
     75     *
     76     * @return array
     77     */
     78    public static function get_default_handbook_config() {
     79        /**
     80         * Filters default handbook configuration array.
     81         *
     82         * @param array $config {
     83         *     Associative array of handbook configuration.
     84         *
     85         *     @type string $cron_interval The cron interval for which an imported handbook gets
     86         *                                 imported, e.g. 'hourly', 'daily'. If defined as an
     87         *                                 unrecognized interval, 'hourly' will be used.
     88         *                                 Default '15_minutes'.
     89         *     @type string $label The label for the handbook. Default is the
     90         *                         post type slug converted to titlecase (e.g.
     91         *                         plugin-handbok => "Plugin Handbook").
     92         *     @type string manifest       The URL to the manifest JSON file for an imported
     93         *                                 handbook.
     94         *     @type string $slug  The slug for the post type. Default is the
     95         *                         post type.
     96         * }
     97         */
     98        return (array) apply_filters( 'handbook_default_handbook_config', [
     99            'cron_interval' => '15_minutes',
     100            'label'         => '',
     101            'manifest'      => '',
     102            'slug'          => '',
     103        ] );
    29104    }
    30105
     
    38113     * @return string
    39114     */
    40     static function get_name( $post_type = 'handbook', $raw = false ) {
     115    public static function get_name( $post_type = 'handbook', $raw = false ) {
    41116        // Prefer explicitly configured handbook name.
    42117        $name = get_option( $post_type . '_name' );
    43118
     119        // If handbook name isn't set, try configured label.
     120        if ( ! $raw && ! $name ) {
     121            $config = WPorg_Handbook_Init::get_handbooks_config( $post_type );
     122            if ( ! empty( $config['label'] ) ) {
     123                $name = $config['label'];
     124            }
     125        }
     126
    44127        // If handbook name isn't set, try root relative site path.
    45         if ( ! $raw && empty( $name ) ) {
     128        if ( ! $raw && ! $name ) {
    46129            if ( is_multisite() ) {
    47130                $name = trim( get_blog_details()->path, '/' );
     
    51134
    52135            // If no name defined yet, try handbook post type if not standard.
    53             if ( empty( $name ) && ( 'handbook' != $post_type ) ) {
    54                 $name = ucfirst( substr( $post_type, 0, -9 ) );
     136            if ( ! $name && ( 'handbook' !== $post_type ) ) {
     137                $name = str_replace( '-handbook', '', $post_type );
    55138            }
    56139
    57140            $name .= ' Handbook';
     141            $name = ucfirst( $name );
    58142        }
    59143
     
    61145    }
    62146
    63     function __construct( $type ) {
    64         if ( 'handbook' != $type ) {
    65             $this->post_type = $type . '-handbook';
    66         } else {
    67             $this->post_type = $type;
    68         }
    69 
    70         $this->label = ucwords( str_replace( array( '-', '_' ), ' ', $this->post_type ) );
    71         $this->label = apply_filters( 'handbook_label', $this->label, $this->post_type );
     147    /**
     148     * Constructor
     149     *
     150     * @param string $type   The post type for the handbook.
     151     * @param array  $config The config array for the handbook.
     152     */
     153    public function __construct( $type, $config = [] ) {
     154        $this->post_type = sanitize_title( $type );
     155
     156        $config = $this->config = wp_parse_args( $config, self::get_default_handbook_config() );
     157
     158        $this->label = apply_filters(
     159            'handbook_label',
     160            $config['label'] ?: ucwords( str_replace( [ '-', '_' ], ' ', $this->post_type ) ),
     161            $this->post_type
     162        );
    72163
    73164        $this->setting_name = $this->post_type . '_name';
    74165
    75         add_filter( 'user_has_cap',                       array( $this, 'grant_handbook_caps' ) );
    76         add_action( 'widgets_init',                       array( $this, 'register_post_type' ) );
    77         add_filter( 'post_type_link',                     array( $this, 'post_type_link' ), 10, 2 );
    78         add_action( 'template_redirect',                  array( $this, 'redirect_handbook_root_page' ) );
    79         add_filter( 'template_include',                   array( $this, 'template_include' ) );
    80         add_filter( 'pre_get_posts',                      array( $this, 'pre_get_posts' ) );
    81         add_action( 'widgets_init',                       array( $this, 'handbook_sidebar' ), 11 ); // After P2
    82         add_action( 'wporg_email_changes_for_post_types', array( $this, 'wporg_email_changes_for_post_types' ) );
    83         add_action( 'p2_action_links',                    array( $this, 'disable_p2_resolved_posts_action_links' ) );
    84         add_action( 'admin_init',                         array( $this, 'add_name_setting' ) );
    85         add_filter( 'body_class',                         array( $this, 'add_body_class' ) );
    86         add_filter( 'post_class',                         array( $this, 'add_post_class' ) );
    87         add_filter( 'o2_process_the_content',             array( $this, 'disable_o2_processing' ) );
    88         add_filter( 'o2_application_container',           array( $this, 'o2_application_container' ) );
    89         add_filter( 'o2_view_type',                       array( $this, 'o2_view_type' ) );
    90         add_filter( 'o2_post_fragment',                   array( $this, 'o2_post_fragment' ) );
    91         add_filter( 'comments_open',                      array( $this, 'comments_open' ), 10, 2 );
    92         add_filter( 'wp_nav_menu_objects',                array( $this, 'highlight_menu_handbook_link' ) );
    93         add_filter( 'display_post_states',                array( $this, 'display_post_states' ), 10, 2 );
     166        add_action( 'after_handbooks_init',               [ $this, 'init_importer' ] );
     167        add_filter( 'user_has_cap',                       [ $this, 'grant_handbook_caps' ] );
     168        add_action( 'widgets_init',                       [ $this, 'register_post_type' ] );
     169        add_filter( 'post_type_link',                     [ $this, 'post_type_link' ], 10, 2 );
     170        add_action( 'template_redirect',                  [ $this, 'redirect_handbook_root_page' ] );
     171        add_filter( 'template_include',                   [ $this, 'template_include' ] );
     172        add_filter( 'pre_get_posts',                      [ $this, 'pre_get_posts' ] );
     173        add_filter( 'posts_pre_query',                    [ $this, 'posts_pre_query' ], 10, 2 );
     174        add_action( 'widgets_init',                       [ $this, 'handbook_sidebar' ], 11 ); // After P2
     175        add_action( 'wporg_email_changes_for_post_types', [ $this, 'wporg_email_changes_for_post_types' ] );
     176        add_action( 'p2_action_links',                    [ $this, 'disable_p2_resolved_posts_action_links' ] );
     177        add_action( 'admin_init',                         [ $this, 'add_name_setting' ] );
     178        add_filter( 'body_class',                         [ $this, 'add_body_class' ] );
     179        add_filter( 'post_class',                         [ $this, 'add_post_class' ] );
     180        add_filter( 'o2_process_the_content',             [ $this, 'disable_o2_processing' ] );
     181        add_filter( 'o2_application_container',           [ $this, 'o2_application_container' ] );
     182        add_filter( 'o2_view_type',                       [ $this, 'o2_view_type' ] );
     183        add_filter( 'o2_post_fragment',                   [ $this, 'o2_post_fragment' ] );
     184        add_filter( 'comments_open',                      [ $this, 'comments_open' ], 10, 2 );
     185        add_filter( 'wp_nav_menu_objects',                [ $this, 'highlight_menu_handbook_link' ] );
     186        add_filter( 'display_post_states',                [ $this, 'display_post_states' ], 10, 2 );
     187    }
     188
     189    /**
     190     * Returns the configuration array for handbooks.
     191     *
     192     * @return array
     193     */
     194    public function get_config() {
     195        return $this->config;
     196    }
     197
     198    /**
     199     * Returns the handbook's importer object, if applicable.
     200     *
     201     * @return WPorg_Handbook_Importer|null
     202     */
     203    public function get_importer() {
     204        return $this->importer;
     205    }
     206
     207    /**
     208     * Initializes the importer, if applicable.
     209     */
     210    public function init_importer() {
     211        $config = $this->get_config();
     212
     213        if ( class_exists( 'WPorg_Handbook_Importer' ) ) {
     214            if ( WPorg_Handbook_Importer::is_handbook_imported( $this->post_type ) ) {
     215                $this->importer = new WPorg_Handbook_Importer( $this );
     216            }
     217        } elseif ( is_admin() && ( $config['manifest'] ?: false ) ) {
     218            add_action( 'admin_notices', function () {
     219                echo '<div class="notice notice-error"><p>' . __( 'Error: The <strong>WPORG Markdown Importer</strong> plugin needs to be activated in order to allow importing of handbooks.', 'wporg' ) . '</p></div>';
     220            } );
     221        }
    94222    }
    95223
     
    101229     * @return string[]
    102230     */
    103     function display_post_states( $post_states, $post ) {
     231    public function display_post_states( $post_states, $post ) {
    104232        if ( $this->post_is_landing_page( $post ) ) {
    105233            $post_states[] = __( 'Handbook Front Page', 'wporg' );
     
    119247     * @return array
    120248     */
    121     function add_body_class( $classes ) {
     249    public function add_body_class( $classes ) {
    122250        if ( is_singular() && wporg_is_handbook( $this->post_type ) ) {
    123251            $classes[] = 'single-handbook';
     
    142270     * @return array
    143271     */
    144     function add_post_class( $classes ) {
     272    public function add_post_class( $classes ) {
    145273        if ( $this->post_type === get_post_type() ) {
    146274            $classes[] = 'type-handbook';
     
    150278    }
    151279
    152     function add_name_setting() {
     280    /**
     281     * Adds the setting for the handbook's name.
     282     */
     283    public function add_name_setting() {
    153284        register_setting( 'general', $this->setting_name, 'esc_attr' );
    154285
    155         $label = ( 'handbook' == $this->post_type ) ?
     286        $label = ( 'handbook' === $this->post_type ) ?
    156287            __( 'Handbook name', 'wporg' ) :
    157             sprintf( __( 'Handbook name (%s)', 'wporg' ), substr( $this->post_type, 0, -9 ) );
     288            sprintf( __( 'Handbook name (%s)', 'wporg' ), str_replace( '-handbook', '', $this->post_type ) );
    158289
    159290        add_settings_field(
    160291            $this->setting_name,
    161292            '<label for="' . esc_attr( $this->setting_name ) . '">' . $label . '</label>',
    162             array( $this, 'name_setting_html' ),
     293            [ $this, 'name_setting_html' ],
    163294            'general'
    164295        );
    165296    }
    166297
    167     function name_setting_html() {
     298    /**
     299     * Outputs the HTML for the input field for the handbook's name.
     300     */
     301    public function name_setting_html() {
    168302        $value = get_option( $this->setting_name, '' );
    169303        echo '<input type="text" id="' . esc_attr( $this->setting_name ) . '" name="' . esc_attr( $this->setting_name ) . '" value="' . esc_attr( $value ) . '" class="regular-text ltr" />';
    170304    }
    171305
    172     function grant_handbook_caps( $caps ) {
     306    /**
     307     * Grants handbook caps to the current user.
     308     *
     309     * @return array
     310     */
     311    public function grant_handbook_caps( $caps ) {
    173312        if ( ! is_user_member_of_blog() ) {
    174313            return $caps;
     
    188327    }
    189328
    190     function register_post_type() {
    191         if ( 'handbook' != $this->post_type ) {
    192             $slug = substr( $this->post_type, 0, -9 );
     329    /**
     330     * Registers handbook post types.
     331     */
     332    public function register_post_type() {
     333        $config = $this->get_config();
     334
     335        if ( ! empty( $config['slug'] ) ) {
     336            $slug = $config['slug'];
     337        } elseif ( 'handbook' !== $this->post_type ) {
     338            $slug = str_replace( '-handbook', '', $this->post_type );
    193339        } else {
    194340            $slug = 'handbook';
    195341        }
    196342
    197         $default_config = array(
    198             'labels' => array(
     343        $default_config = [
     344            'labels' => [
    199345                'name'          => $this->label,
    200346                'singular_name' => sprintf( __( '%s Page', 'wporg' ), $this->label ),
    201347                'menu_name'     => $this->label,
    202348                'all_items'     => sprintf( __( '%s Pages', 'wporg' ), $this->label ),
    203             ),
     349            ],
    204350            'public'            => true,
    205351            'show_ui'           => true,
     
    211357            'menu_icon'         => 'dashicons-book',
    212358            'menu_position'     => 11,
    213             'rewrite' => array(
     359            'rewrite' => [
    214360                'feeds'         => false,
    215361                'slug'          => $slug,
    216362                'with_front'    => false,
    217             ),
     363            ],
    218364            'delete_with_user'  => false,
    219             'supports'          => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'revisions', 'wpcom-markdown' ),
    220         );
     365            'supports'          => [ 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'revisions', 'wpcom-markdown' ],
     366        ];
    221367        // Allow customization of the default post type configuration via filter.
    222         $config = apply_filters( 'handbook_post_type_defaults', $default_config, $slug );
    223 
    224         $this->label = $config['labels']['name'];
     368        $config = (array) apply_filters( 'handbook_post_type_defaults', $default_config, $slug );
     369
     370        // Override the presumed label with a potentially customized value.
     371        if ( ! empty( $config['labels']['name'] ) ) {
     372            $this->label = $config['labels']['name'];
     373        }
    225374
    226375        register_post_type( $this->post_type, $config );
     
    235384     *              handbook's landing page.
    236385     */
    237     protected function post_is_landing_page( $post = null ) {
     386    public function post_is_landing_page( $post = null ) {
    238387        $is_landing_page = false;
    239388
     
    269418     * @param WP_Post $post      The post in question.
    270419     */
    271     function post_type_link( $post_link, $post ) {
     420    public function post_type_link( $post_link, $post ) {
    272421        $post_type = get_post_type( $post );
    273422
     
    284433     * post type archive link for the handbook.
    285434     */
    286     function redirect_handbook_root_page() {
     435    public function redirect_handbook_root_page() {
    287436        global $wp_query;
    288437
     
    309458     * @return string
    310459     */
    311     function template_include( $template ) {
     460    public function template_include( $template ) {
    312461        global $wp_query;
    313462
     
    317466        }
    318467
    319         $handbook_templates = array();
     468        $handbook_templates = [];
    320469
    321470        // For singular handbook pages not of the 'handbook' post type.
    322471        if ( is_singular( $this->post_type ) && 'handbook' !== $this->post_type ) {
    323             $handbook_templates = array( "single-{$this->post_type}.php", 'single-handbook.php' );
     472            $handbook_templates = [ "single-{$this->post_type}.php", 'single-handbook.php' ];
    324473        }
    325474        // For handbook landing page.
     
    340489    }
    341490
    342     function pre_get_posts( $query ) {
     491    /**
     492     * Pre-emptively sets the query posts to the handbook landing page when
     493     * appropriate.
     494     *
     495     * @param array $posts    Posts.
     496     * @param WP_Query $query Query object.
     497     * @return array
     498     */
     499    public function posts_pre_query( $posts, $query ) {
     500        if ( $query->is_main_query() && ! $query->is_admin && ! $query->is_search && $query->is_handbook_root ) {
     501            $posts = [ $query->is_handbook_root ];
     502        }
     503
     504        return $posts;
     505    }
     506
     507    /**
     508     * Performs query object adjustments for handbook requests prior to querying
     509     * for posts.
     510     */
     511    public function pre_get_posts( $query ) {
    343512        // Bail early if query is not for this handbook's post type.
    344513        if ( get_query_var( 'post_type' ) !== $this->post_type ) {
     
    357526            $page = get_page_by_path( $this->post_type, OBJECT, $this->post_type );
    358527            if ( ! $page ) {
    359                 $slug = substr( $this->post_type, 0, -9 );
    360                 $page = get_page_by_path( $slug, OBJECT, $this->post_type );
    361             }
    362             if ( ! $page ) {
     528                $slug = str_replace( '-handbook', '', $this->post_type );
     529                if ( $slug !== $this->post_type ) {
     530                    $page = get_page_by_path( $slug, OBJECT, $this->post_type );
     531                }
     532            }
     533            if ( ! $page && 'handbook' !== $this->post_type ) {
    363534                $page = get_page_by_path( 'handbook', OBJECT, $this->post_type );
    364535            }
    365             if ( ! $page ) {
     536            if ( ! $page && 'welcome' !== $this->post_type ) {
    366537                $page = get_page_by_path( 'welcome', OBJECT, $this->post_type );
    367538            }
    368539            if ( $page ) {
    369540                $query->set( 'page_id', $page->ID );
    370                 $query->is_handbook_root     = true;
     541                $query->is_handbook_root     = $page;
    371542
    372543                $query->is_archive           = false;
     
    379550    }
    380551
    381     function handbook_sidebar() {
    382         $sidebar_args = array(
    383             'id'          => $this->post_type,
    384             'name'        => sprintf( __( '%s Sidebar', 'wporg' ), $this->label ),
    385             'description' => sprintf( __( 'Used on %s pages', 'wporg' ), $this->label ),
     552    /**
     553     * Registers sidebar and widgets for handbook pages.
     554     */
     555    public function handbook_sidebar() {
     556        $sidebar_args = [
     557            'id'            => $this->post_type,
     558            'name'          => sprintf( __( '%s Sidebar', 'wporg' ), $this->label ),
     559            'description'   => sprintf( __( 'Used on %s pages', 'wporg' ), $this->label ),
    386560            'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    387561            'after_widget'  => '</aside>',
    388562            'before_title'  => '<h2 class="widget-title">',
    389563            'after_title'   => '</h2>',
    390         );
     564        ];
    391565
    392566        $sidebar_args = apply_filters( 'wporg_handbook_sidebar_args', $sidebar_args, $this );
     
    398572    }
    399573
    400     function wporg_email_changes_for_post_types( $post_types ) {
     574    /**
     575     * Amends list of post types for which users can opt into receiving emails
     576     * about changes.
     577     *
     578     * @param array $post_types Post types.
     579     * @return array
     580     */
     581    public function wporg_email_changes_for_post_types( $post_types ) {
    401582        if ( ! in_array( $this->post_type, $post_types ) ) {
    402583            $post_types[] = $this->post_type;
     
    410591     * if that plugin is active.
    411592     */
    412     function disable_p2_resolved_posts_action_links() {
    413         if ( ( $this->post_type == get_post_type() ) && class_exists( 'P2_Resolved_Posts' ) && isset( $GLOBALS['p2_resolved_posts'] ) && is_object( $GLOBALS['p2_resolved_posts'] ) ) {
    414             remove_filter( 'p2_action_links', array( P2_Resolved_Posts::instance(), 'p2_action_links' ), 100 );
     593    public function disable_p2_resolved_posts_action_links() {
     594        if ( ( $this->post_type === get_post_type() ) && class_exists( 'P2_Resolved_Posts' ) && isset( $GLOBALS['p2_resolved_posts'] ) && is_object( $GLOBALS['p2_resolved_posts'] ) ) {
     595            remove_filter( 'p2_action_links', [ P2_Resolved_Posts::instance(), 'p2_action_links' ], 100 );
    415596        }
    416597    }
     
    422603     * @return bool
    423604     */
    424     function disable_o2_processing( $process_with_o2 ) {
     605    public function disable_o2_processing( $process_with_o2 ) {
    425606        return ( is_singular() && $this->post_type === get_post_type() ) ? false : $process_with_o2;
    426607    }
     
    432613     * @return string
    433614     */
    434     function o2_application_container( $container ) {
     615    public function o2_application_container( $container ) {
    435616        return ( is_singular() && $this->post_type === get_post_type() ) ? '#primary' : $container;
    436617    }
     
    443624     * @return string
    444625     */
    445     function o2_view_type( $view_type ) {
     626    public function o2_view_type( $view_type ) {
    446627        return ( is_singular() && $this->post_type === get_post_type() ) ? 'single' : $view_type;
    447628    }
     
    453634     * @return array
    454635     */
    455     function o2_post_fragment( $post_fragment ) {
     636    public function o2_post_fragment( $post_fragment ) {
     637        if ( empty( $post_fragment['id'] ) ) {
     638            return $post_fragment;
     639        }
     640
    456641        $post = get_post( $post_fragment['id'] );
    457642        if ( ! $post ) {
     
    473658     * @return bool
    474659     */
    475     function comments_open( $open, $post_id ) {
     660    public function comments_open( $open, $post_id ) {
    476661        $post = get_post( $post_id );
    477662        if ( ! $post ) {
     
    499684     * @return array
    500685     */
    501     function highlight_menu_handbook_link( $menu_items ) {
     686    public function highlight_menu_handbook_link( $menu_items ) {
    502687        // Must be on a handbook page that isn't the handbook landing page (which will already be handled).
    503         if ( ! is_page( array( 'handbook', 'handbooks' ) ) && ( ! wporg_is_handbook() || wporg_is_handbook_landing_page() ) ) {
     688        if ( ! is_page( [ 'handbook', 'handbooks' ] ) && ( ! wporg_is_handbook() || wporg_is_handbook_landing_page() ) ) {
    504689            return $menu_items;
    505690        }
    506691
    507692        // Menu must not have an item that is already noted as being current.
    508         $current_menu_item = wp_filter_object_list( $menu_items, array( 'current' => true ) );
     693        $current_menu_item = wp_filter_object_list( $menu_items, [ 'current' => true ] );
    509694        if ( $current_menu_item ) {
    510695            return $menu_items;
     
    512697
    513698        // Menu must have an item that links to handbook home page.
    514         $root_handbook_menu_item = wp_filter_object_list( $menu_items, array( 'url' => wporg_get_current_handbook_home_url() ) );
     699        $root_handbook_menu_item = wp_filter_object_list( $menu_items, [ 'url' => wporg_get_current_handbook_home_url() ] );
    515700        if ( ! $root_handbook_menu_item ) {
    516701            // Or it must have an item that links to a 'handbook' or 'handbooks' page.
     
    518703            $page = get_page_by_path( $page_slug );
    519704            if ( $page ) {
    520                 $root_handbook_menu_item = wp_filter_object_list( $menu_items, array( 'object_id' => $page->ID ) );
     705                $root_handbook_menu_item = wp_filter_object_list( $menu_items, [ 'object_id' => $page->ID ] );
    521706            }
    522707        }
Note: See TracChangeset for help on using the changeset viewer.