Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for comments #871

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7ec60e4
Make add `get_dom` method to AMP_DOM_Utils
DavidCramer Jan 17, 2018
eed214f
add amp_form_sanitizer
DavidCramer Jan 17, 2018
4067b59
add form sanitisation on output buuffer
DavidCramer Jan 17, 2018
a8d2ad3
merge develop in
DavidCramer Jan 18, 2018
98874ba
Merge develop
DavidCramer Jan 19, 2018
4f6dcd6
add comments REST endpoints
DavidCramer Jan 19, 2018
317f90f
Add AMP Comments Walker
DavidCramer Jan 19, 2018
451db91
Add comments template overrides and methods
DavidCramer Jan 19, 2018
0541686
add comment sanitizer
DavidCramer Jan 19, 2018
2c8575e
Make walker add the HTML to reduce load in the sanitiser.
DavidCramer Jan 19, 2018
ac0cc53
its a filter, not an action.
DavidCramer Jan 19, 2018
2741fdf
Merge develop
DavidCramer Jan 22, 2018
ebffaae
add form sanitisation changes
DavidCramer Jan 22, 2018
9790be3
make action setting more sane
DavidCramer Jan 22, 2018
b425b19
Add sanitisation and component_type method
DavidCramer Jan 22, 2018
b7c5963
optimize comments endpoint
DavidCramer Jan 23, 2018
94aee02
wp_unslash request_uri for action attribute.
DavidCramer Jan 23, 2018
d0fc6c5
cleaner comments template generation
DavidCramer Jan 23, 2018
6b660b3
merge develop
DavidCramer Jan 23, 2018
69d1342
cleanup formatting
DavidCramer Jan 24, 2018
4200d9e
output comment template on same comments pass
DavidCramer Jan 24, 2018
366bef3
cleanup comments sanitiser and add url template string filtering
DavidCramer Jan 24, 2018
7b63836
add comment template url string filters
DavidCramer Jan 24, 2018
8b289c1
remove unnecessary duplicated `wp_list_comments` pass
DavidCramer Jan 24, 2018
15d327d
Hook into AMP xhr-submissions to handle headers and JSON responses.
DavidCramer Jan 24, 2018
561189b
add amp-list fallback for comments.
DavidCramer Jan 24, 2018
a1bf8d3
add comment form success and error handlers and wrapper code.
DavidCramer Jan 24, 2018
b40e932
lowercase `post` k, thanks.
DavidCramer Jan 24, 2018
dc1f9c3
Merge develop
DavidCramer Jan 24, 2018
187e136
fix formatting fail.
DavidCramer Jan 24, 2018
82e8021
if no template, move on.
DavidCramer Jan 25, 2018
d4fd8bc
No need to check for the `amp_comments` tag anymore.
DavidCramer Jan 25, 2018
bbabbd7
add tests for form and comment sanitisation.
DavidCramer Jan 25, 2018
0fd1ab5
add docs to tests
DavidCramer Jan 25, 2018
9f99abe
No need to get images again.
DavidCramer Jan 25, 2018
9216e4e
check has images before converting urls
DavidCramer Jan 25, 2018
fafa679
fix phpdoc
DavidCramer Jan 25, 2018
9536794
Merge branch 'develop' of https://github.com/Automattic/amp-wp into a…
westonruter Jan 25, 2018
74ae3b5
Prevent saveHTML from munging amp-mustache curly braces via URL-encoding
westonruter Jan 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions amp.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function amp_after_setup_theme() {
}

add_action( 'init', 'amp_init' );
add_action( 'rest_api_init', 'amp_rest_init' );
add_action( 'widgets_init', 'AMP_Theme_Support::register_widgets' );
add_action( 'admin_init', 'AMP_Options_Manager::register_settings' );
add_filter( 'amp_post_template_analytics', 'amp_add_custom_analytics' );
Expand Down Expand Up @@ -125,6 +126,18 @@ function amp_init() {
if ( class_exists( 'Jetpack' ) && ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
require_once( AMP__DIR__ . '/jetpack-helper.php' );
}

amp_hook_comments_maybe();
}

/**
* Init AMP Rest endpoints.
*
* @since 0.1
*/
function amp_rest_init() {
require_once AMP__DIR__ . '/includes/amp-rest-functions.php';
amp_register_endpoints();
}

// Make sure the `amp` query var has an explicit value.
Expand Down Expand Up @@ -361,3 +374,64 @@ function amp_redirect_old_slug_to_new_url( $link ) {

return $link;
}

/**
* Hook into a comment submission if an AMP xhr post request.
*/
function amp_hook_comments_maybe() {

$method = filter_input( INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING );
$is_amp_submit = filter_input( INPUT_GET, '__amp_source_origin', FILTER_VALIDATE_URL );

if ( 'post' !== strtolower( $method ) || is_null( $is_amp_submit ) ) {
return;
}

// Add amp comment hooks.
add_filter( 'comment_post_redirect', 'amp_comment_post_redirect', PHP_INT_MAX, 2 );
add_filter( 'wp_die_handler', 'amp_set_comment_submit_die_handler' );

// Send amp header.
header( 'AMP-Access-Control-Allow-Source-Origin: ' . $is_amp_submit, true );

}

/**
* Set the die handler on comment submit to output the error in json and send AMP headers.
*/
function amp_set_comment_submit_die_handler() {
return 'amp_send_error_json';
}

/**
* Send error creating message.
*
* @param string $message The error message to send.
*/
function amp_send_error_json( $message ) {
header( 'HTTP/1.1 400 BAD REQUEST' );
wp_send_json( array( 'error' => strip_tags( $message, 'strong' ) ) );
}

/**
* Redirect after comment submission.
*
* @param string $location The location to redirect to.
* @param WP_Comment $comment The comment that was posted.
* @return string The location URL or void if send json.
*/
function amp_comment_post_redirect( $location, $comment ) {
$is_amp_submit = filter_input( INPUT_GET, '__amp_source_origin', FILTER_VALIDATE_URL );
if ( is_null( $is_amp_submit ) ) {
return $location;
}

// AMP-Redirect only works if https. If not, we simply render the success.
if ( is_ssl() ) {
$location = strtok( $location, '#' );
header( 'AMP-Redirect-To: ' . $location );
header( 'Access-Control-Expose-Headers: AMP-Redirect-To', false );
}
$comment->comment_link = get_comment_link( $comment->comment_ID );
wp_send_json( $comment );
}
2 changes: 2 additions & 0 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ function amp_get_content_sanitizers( $post = null ) {
'AMP_Video_Sanitizer' => array(),
'AMP_Audio_Sanitizer' => array(),
'AMP_Playbuzz_Sanitizer' => array(),
'AMP_Form_Sanitizer' => array(),
'AMP_Comments_Sanitizer' => array(),
'AMP_Iframe_Sanitizer' => array(
'add_placeholder' => true,
),
Expand Down
71 changes: 71 additions & 0 deletions includes/amp-rest-functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* AMP Rest Functions
*
* @package AMP
*/

/**
* Register the comments REST endpoint.
*
* @since 0.7
*/
function amp_register_endpoints() {

register_rest_route( 'amp/v1', '/comments/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'amp_get_comments',
) );

}

/**
* Get comments for the Post and Parent
*
* @since 0.7
* @param WP_REST_Request $request The REST request.
*
* @return array The array of comments.
*/
function amp_get_comments( $request ) {

$id = $request->get_param( 'id' );
$comments = get_comments( array(
'post_ID' => $id,
'order' => 'ASC',
) );
$return = array(
'items' => array(
'comment' => amp_get_comments_recursive( 0, $comments ),
),
);

return $return;
}

/**
* Recursively get comments for the Post and Parent
*
* @since 0.7
* @param int $parent The comment parent.
* @param array $comments The list of comments.
*
* @return array The array of comments.
*/
function amp_get_comments_recursive( $parent, $comments ) {

$return = array();
foreach ( $comments as $comment ) {
if ( (int) $parent !== (int) $comment->comment_parent ) {
continue;
}
$GLOBALS['comment'] = $comment; // WPCS: override ok.
$comment->comment_date = get_comment_date();
$comment->comment_time = get_comment_time();
$comment->comment_avatar_url = get_avatar_url( $comment->comment_author_email );
$comment->comment = amp_get_comments_recursive( $comment->comment_ID, $comments );
$return[] = $comment;
}

return $return;
}
3 changes: 3 additions & 0 deletions includes/class-amp-autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AMP_Autoloader {
*/
private static $_classmap = array(
'AMP_Theme_Support' => 'includes/class-amp-theme-support',
'AMP_Comment_Walker' => 'includes/class-amp-comment-walker',
'AMP_WP_Styles' => 'includes/class-amp-wp-styles',
'AMP_Template_Customizer' => 'includes/admin/class-amp-customizer',
'AMP_Post_Meta_Box' => 'includes/admin/class-amp-post-meta-box',
Expand Down Expand Up @@ -65,6 +66,8 @@ class AMP_Autoloader {
'AMP_Blacklist_Sanitizer' => 'includes/sanitizers/class-amp-blacklist-sanitizer',
'AMP_Iframe_Sanitizer' => 'includes/sanitizers/class-amp-iframe-sanitizer',
'AMP_Img_Sanitizer' => 'includes/sanitizers/class-amp-img-sanitizer',
'AMP_Form_Sanitizer' => 'includes/sanitizers/class-amp-form-sanitizer',
'AMP_Comments_Sanitizer' => 'includes/sanitizers/class-amp-comments-sanitizer',
'AMP_Playbuzz_Sanitizer' => 'includes/sanitizers/class-amp-playbuzz-sanitizer',
'AMP_Style_Sanitizer' => 'includes/sanitizers/class-amp-style-sanitizer',
'AMP_Tag_And_Attribute_Sanitizer' => 'includes/sanitizers/class-amp-tag-and-attribute-sanitizer',
Expand Down
105 changes: 105 additions & 0 deletions includes/class-amp-comment-walker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
/**
* Class AMP_Comment_Walker
*
* @package AMP
*/

/**
* Class AMP_Comment_Walker
*
* Walker to wrap comments in mustache tags for amp-template.
*/
class AMP_Comment_Walker extends Walker_Comment {

/**
* The original comments arguments.
*
* @since 0.7
* @var array
*/
public $args;

/**
* Starts the element output.
*
* @since 2.7.0
*
* @see Walker::start_el()
* @see wp_list_comments()
* @global int $comment_depth
* @global WP_Comment $comment
*
* @param string $output Used to append additional content. Passed by reference.
* @param WP_Comment $comment Comment data object.
* @param int $depth Optional. Depth of the current comment in reference to parents. Default 0.
* @param array $args Optional. An array of arguments. Default empty array.
* @param int $id Optional. ID of the current comment. Default 0 (unused).
*/
public function start_el( &$output, $comment, $depth = 0, $args = array(), $id = 0 ) {
$output .= '{{#comment}}';
parent::start_el( $output, $comment, $depth, $args, $id );
}
/**
* Ends the element output, if needed.
*
* @since 2.7.0
*
* @see Walker::end_el()
* @see wp_list_comments()
*
* @param string $output Used to append additional content. Passed by reference.
* @param WP_Comment $comment The current comment object. Default current comment.
* @param int $depth Optional. Depth of the current comment. Default 0.
* @param array $args Optional. An array of arguments. Default empty array.
*/
public function end_el( &$output, $comment, $depth = 0, $args = array() ) {
if ( ! empty( $args['end-callback'] ) ) {
ob_start();
call_user_func( $args['end-callback'], $comment, $args, $depth );
$output .= ob_get_clean();
} else {
if ( 'div' === $args['style'] ) {
$output .= "</div><!-- #comment-## -->\n";
} else {
$output .= "</li><!-- #comment-## -->\n";
}
}
$output .= '{{/comment}}';
}

/**
* Output amp-list template code and place holder for comments.
*
* @see Walker::paged_walk()
* @param array $elements List of comment Elements.
* @param int $max_depth The maximum hierarchical depth.
* @param int $page_num The specific page number, beginning with 1.
* @param int $per_page Per page counter.
*
* @return string XHTML of the specified page of elements.
*/
public function paged_walk( $elements, $max_depth, $page_num, $per_page ) {
if ( empty( $elements ) || $max_depth < - 1 ) {
return '';
}

$args = array_slice( func_get_args(), 4 );

$url = get_rest_url( get_current_blog_id(), 'amp/v1/comments/' . get_the_ID() );
if ( strpos( $url, 'http:' ) === 0 ) {
$url = substr( $url, 5 );
}
// @todo Identify arguments and make filterable/settable.
$output = '<amp-list src="' . esc_attr( $url ) . '" height="200" width="auto" single-item="true" layout="flex-item">';
$output .= '<template type="amp-mustache"></template>';
$output .= '<div overflow role="button" aria-label="' . esc_attr__( 'Show more', 'amp' ) . '" class="list-overflow ampstart-btn caps">' . esc_html__( 'Show more', 'amp' ) . '</div>';
$output .= '<div fallback class="amp-fallback amp-comments-notice amp-error"><p>' . esc_html__( 'Could not load comments.', 'amp' ) . '</p></div>';
$output .= '</amp-list>';
$output .= '<comment-template>';
$output .= parent::paged_walk( $elements, $max_depth, $page_num, $per_page, $args[0] );
$output .= '</comment-template>';

return $output;
}
}
Loading