Making WordPress.org

Changeset 12007


Ignore:
Timestamp:
08/03/2022 03:43:07 AM (3 years ago)
Author:
dd32
Message:

Learn: Sync with git WordPress/learn@74fb550537cf709a1b73ce39ebe66f7ce5906256

File:
1 edited

Legend:

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

    r11997 r12007  
    1212defined( 'WPINC' ) || die();
    1313
    14 add_action( 'rest_api_init', function() {
    15     // Important: only expose raw post content for specific post types
    16     register_raw_content_for_post_type( 'lesson-plan' );
    17     register_raw_content_for_post_type( 'wporg_workshop' );
     14add_filter( 'wporg_export_context_post_types', function( $post_types ) {
     15    return array_merge( $post_types, array(
     16        'lesson-plan',
     17        'wporg_workshop',
     18    ) );
    1819} );
    1920
    20 /**
    21  * Register a `wporg_export` context for a given post type.
    22  *
    23  * @param string $post_type Post type to allow for export.
    24  */
    25 function register_raw_content_for_post_type( $post_type ) {
    26 
    27     register_rest_field(
    28         $post_type,
    29         'content_raw',
    30         array(
    31             'get_callback' => __NAMESPACE__ . '\show_post_content_raw',
    32             'schema'       => array(
    33                 'type' => 'string',
    34                 'context' => array( 'wporg_export' ),
    35             ),
    36         )
    37     );
    38 
    39     add_filter( "rest_{$post_type}_item_schema", __NAMESPACE__ . '\add_export_context_to_schema' );
    40 }
    41 
    42 /**
    43  * Filter a CPT item schema and make it so that every item with 'view' context also has 'export' context.
    44  *
    45  * @param array $schema The schema object.
    46  */
    47 function add_export_context_to_schema( $schema ) {
    48     update_schema_array_recursive( $schema );
    49 
    50     return $schema;
    51 }
    52 
    53 /**
    54  * Find every item in the schema that has a 'view' context, and add an 'export' context to it.
    55  * Had to use a recursive function because array_walk_recursive only walks leaf nodes.
    56  *
    57  * @param array $schema The schema object.
    58  */
    59 function update_schema_array_recursive( &$schema ) {
    60     foreach ( $schema as $key => &$value ) {
    61         // Head recursion
    62         if ( is_array( $value ) ) {
    63             update_schema_array_recursive( $value );
    64         }
    65         if ( 'context' === $key && in_array( 'view', $value ) ) {
    66             $value[] = 'wporg_export';
    67         }
    68     }
    69 }
    70 
    71 /**
    72  * Given an array of blocks, return an array of just the names of those blocks.
    73  *
    74  * @param array $blocks An array of blocks.
    75  * @return array An array of block names.
    76  */
    77 function get_all_block_names( $blocks ) {
    78     $block_names = array();
    79     if ( ! $blocks ) {
    80         return array();
    81     }
    82     foreach ( $blocks as $block ) {
    83         if ( null !== $block['blockName'] ) {
    84             $block_names[] = $block['blockName'];
    85             if ( $block['innerBlocks'] ) {
    86                 // Recursive call to get inner blocks
    87                 $block_names = array_merge( $block_names, get_all_block_names( $block['innerBlocks'] ) );
    88             }
    89         }
    90     }
    91 
    92     return array_unique( $block_names );
    93 }
    94 
    95 /**
    96  * Callback: If a post contains only allowed blocks, then return the raw block markup for the post.
    97  *
    98  * @param array  $object The post object relating to the REST request.
    99  * @param string $field_name The field name.
    100  * @param array  $request The request object.
    101  *
    102  * @return string The raw post content, if it contains only allowed blocks; a placeholder string otherwise.
    103  */
    104 function show_post_content_raw( $object, $field_name, $request ) {
    105 
    106     /**
    107      * Filter: Modify the list of blocks permitted in posts available via the 'export' context.
    108      * Posts containing any other blocks will not be exported.
    109      *
    110      * @param array $allowed_blocks An array of allowed block names. Simple wildcards are permitted, like 'core/*'.
    111      */
    112     $allowed_blocks = apply_filters( 'allow_raw_block_export', array(
    113         'core/*',
    114         'wporg/*',
    115         // other allowed blocks:
    116         'jetpack/image-compare',
    117         'jetpack/tiled-gallery',
    118         'syntaxhighlighter/code',
    119     ) );
    120 
    121     if ( ! empty( $object['id'] ) ) {
    122         $post = get_post( $object['id'] );
    123     } else {
    124         $post = get_post();
    125     }
    126 
    127     // Exit early if the post contains any blocks that are not explicitly allowed.
    128     if ( $post && has_blocks( $post->post_content ) || true ) {
    129 
    130         $regexes = array();
    131         foreach ( $allowed_blocks as $allowed_block_name ) {
    132             $regexes[] = strtr( preg_quote( $allowed_block_name, '#' ), array( '\*' => '.*' ) );
    133         }
    134 
    135         $regex = '#^(' . implode( '|', $regexes ) . ')$#';
    136 
    137         $blocks = parse_blocks( $post->post_content );
    138         $block_names = get_all_block_names( $blocks );
    139 
    140         foreach ( $block_names as $block_name ) {
    141             // If it contains a disallowed block, then return no content.
    142             // Better to raise an error instead?
    143             if ( ! preg_match( $regex, $block_name ) ) {
    144                 return '<p>Post contains a disallowed block ' . esc_html( $block_name ) . '</p>';
    145             }
    146         }
    147     }
    148 
    149     return $post->post_content;
    150 }
Note: See TracChangeset for help on using the changeset viewer.