Skip to content

Commit

Permalink
Standardize REST Error messages (#413)
Browse files Browse the repository at this point in the history
  • Loading branch information
akirk authored Dec 13, 2024
1 parent 2879032 commit e152be2
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 110 deletions.
19 changes: 14 additions & 5 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ public function send_friend_request( $rest_url, $user_login, $user_url, $display
$json = json_decode( wp_remote_retrieve_body( $response ) );
if ( $json && isset( $json->code ) && isset( $json->message ) ) {
// translators: %s is the message from the other server.
return new \WP_Error( $json->code, sprintf( __( 'The other side responded: %s', 'friends' ), $json->message ), $json->data );
return new \WP_Error( $json->code, sprintf( __( 'The other side responded: %s', 'friends' ), Rest::translate_error_message( $json->message ) ), $json->data );
}

if ( ! $json || ! is_object( $json ) ) {
Expand Down Expand Up @@ -1094,11 +1094,12 @@ public function process_admin_edit_friend() {
if ( ! is_wp_error( $rest_url ) ) {
$response = $this->send_friend_request( $rest_url, $friend->user_login, $friend->user_url, $friend->display_name );
} else {
// pass on the error to below.
$response = $rest_url;
}

if ( is_wp_error( $response ) ) {
$arg = 'error';
$arg_value = $response->get_error_message();
} elseif ( $response instanceof User ) {
if ( $response->has_cap( 'pending_friend_request' ) ) {
$arg = 'sent-request';
Expand Down Expand Up @@ -1146,9 +1147,9 @@ public function process_admin_edit_friend() {
do_action( 'friends_edit_friend_after_form_submit', $friend );

if ( isset( $_GET['_wp_http_referer'] ) ) {
wp_safe_redirect( add_query_arg( $arg, $arg_value, wp_get_referer() ) );
wp_safe_redirect( add_query_arg( $arg, rawurlencode( $arg_value ), wp_get_referer() ) );
} else {
wp_safe_redirect( add_query_arg( $arg, $arg_value, remove_query_arg( array( '_wp_http_referer', '_wpnonce' ) ) ) );
wp_safe_redirect( add_query_arg( $arg, rawurlencode( $arg_value ), remove_query_arg( array( '_wp_http_referer', '_wpnonce' ) ) ) );
}
exit;
}
Expand Down Expand Up @@ -1205,7 +1206,15 @@ public function render_admin_edit_friend() {
<?php
} elseif ( isset( $_GET['error'] ) ) {
?>
<div id="message" class="updated error is-dismissible"><p><?php esc_html_e( 'An error occurred.', 'friends' ); ?></p></div>
<div id="message" class="updated error is-dismissible"><p>
<?php
if ( 1 === intval( $_GET['error'] ) ) {
esc_html_e( 'An error occurred.', 'friends' );
} else {
echo esc_html( Rest::translate_error_message( sanitize_text_field( wp_unslash( $_GET['error'] ) ) ) );
}
?>
</p></div>
<?php
} elseif ( isset( $_GET['sent-request'] ) ) {
?>
Expand Down
193 changes: 94 additions & 99 deletions includes/class-rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,85 @@ public function add_rest_routes() {
);
}

/**
* Translate a REST error message
*
* @param string $message The message to translate.
* @return string The translated message.
*/
public static function translate_error_message( $message ) {
$messages = self::get_error_messages( true );
if ( isset( $messages[ $message ] ) ) {
return $messages[ $message ];
}
return $message;
}

/**
* Get the error messages for REST
*
* @return array The error messages.
*/
public static function get_error_messages() {
$english = function () {
return 'en_US';
};

// In the first pass never translate these messages.
add_filter( 'locale', $english );

$messages = array(
'friends_invalid_parameters' => __( 'Not all necessary parameters were provided.', 'friends' ),
'friends_invalid_url' => __( 'An invalid URL was provided.', 'friends' ),
'friends_no_request' => __( 'No request was found.', 'friends' ),
'friends_unsupported_protocol_version' => __( 'Incompatible Friends protocol version.', 'friends' ),
'friends_invalid_codeword' => __( 'An invalid codeword was provided.', 'friends' ),
'friends_invalid_site' => __( 'An invalid site was provided.', 'friends' ),
'friends_disabled_friendship' => __( 'This site doesn\'t accept friend requests.', 'friends' ),
'friends_not_requested' => __( 'No friendship request was made.', 'friends' ),
'friends_request_failed' => __( 'Could not respond to the request.', 'friends' ),
'unknown' => __( 'An unknown error occurred.', 'friends' ),
);

remove_filter( 'locale', $english );

// Add mapping for English text to translations.
foreach ( $messages as $key => $message ) {
$messages[ $message ] = __( $message, 'friends' ); // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
}

return $messages;
}

/**
* Standardize the error message texts
*
* @param string $code The error code.
* @param string $message The message to return, if not provided the default message will be used.
* @param int $status The status code to return.
*
* @return \WP_Error The error object.
*/
public static function error( $code, $message = '', $status = 403 ) {
if ( ! $message ) {
// Return English error messages.
$messages = self::get_error_messages();
if ( isset( $messages[ $code ] ) ) {
$message = $messages[ $code ];
} else {
$message = $messages['unknown'];
}
}

return new \WP_Error(
$code,
$message,
array(
'status' => $status,
)
);
}

public function permssion_check_accept_friend_request( \WP_REST_Request $request ) {
$url = $request->get_param( 'url' );

Expand All @@ -213,13 +292,7 @@ public function permssion_check_accept_friend_request( \WP_REST_Request $request
}

if ( ! $friend_user ) {
return new \WP_Error(
'friends_invalid_parameters',
'Not all necessary parameters were provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_parameters' );
}
}

Expand All @@ -230,13 +303,7 @@ public function permssion_check_accept_friend_request( \WP_REST_Request $request
$friend_user->get_user_option( 'friends_out_token' ) !== $our_key
|| $friend_user->get_user_option( 'friends_in_token' ) !== $their_key
) {
return new \WP_Error(
'friends_invalid_parameters',
'Not all necessary parameters were provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_parameters' );
}
return true;
}
Expand Down Expand Up @@ -271,13 +338,7 @@ public function rest_accept_friend_request( \WP_REST_Request $request ) {
}

if ( ! $friend_user ) {
return new \WP_Error(
'friends_invalid_parameters',
'Not all necessary parameters were provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_parameters' );
}
}

Expand All @@ -288,13 +349,7 @@ public function rest_accept_friend_request( \WP_REST_Request $request ) {
$friend_user->get_user_option( 'friends_out_token' ) !== $our_key
|| $friend_user->get_user_option( 'friends_in_token' ) !== $their_key
) {
return new \WP_Error(
'friends_invalid_parameters',
'Not all necessary parameters were provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_parameters' );
}

$friend_user->make_friend();
Expand Down Expand Up @@ -368,13 +423,7 @@ public function rest_friendship_requested( \WP_REST_Request $request ) {
$url = $request->get_param( 'url' );

if ( ! Friends::check_url( $url ) ) {
return new \WP_Error(
'friends_invalid_url',
'An invalid URL was provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_url' );
}

$pending_friend_requests = User_Query::all_pending_friend_requests();
Expand All @@ -386,67 +435,31 @@ public function rest_friendship_requested( \WP_REST_Request $request ) {
}
}

return new \WP_Error(
'friends_no_request',
'No request was found.',
array(
'status' => 404,
)
);
return self::error( 'friends_no_request' );
}

public function permission_check_friend_request( \WP_REST_Request $request ) {
$version = $request->get_param( 'version' );
if ( 3 !== intval( $version ) ) {
return new \WP_Error(
'friends_unsupported_protocol_version',
'Incompatible Friends protocol version.',
array(
'status' => 403,
)
);
return self::error( 'friends_unsupported_protocol_version' );
}

$codeword = $request->get_param( 'codeword' );
if ( get_option( 'friends_require_codeword' ) && get_option( 'friends_codeword', 'friends' ) !== $codeword ) {
return new \WP_Error(
'friends_invalid_codeword',
get_option( 'friends_wrong_codeword_message', 'An invalid codeword was provided.' ),
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_codeword', get_option( 'friends_wrong_codeword_message' ) );
}

$url = trim( $request->get_param( 'url' ) );
if ( ! is_string( $url ) || ! Friends::check_url( $url ) || 0 === strcasecmp( home_url(), $url ) ) {
return new \WP_Error(
'friends_invalid_site',
'An invalid site was provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_invalid_site' );
}

if ( ! get_option( 'friends_enable_wp_friendships' ) ) {
return new \WP_Error(
'friends_invalid_site',
'An invalid site was provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_disabled_friendship' );
}

if ( ! $this->check_remote_did_send_request( $url ) ) {
return new \WP_Error(
'friends_invalid_site',
'An invalid site was provided.',
array(
'status' => 403,
)
);
return self::error( 'friends_not_requested' );
}

return true;
Expand Down Expand Up @@ -490,24 +503,12 @@ public function permission_check_friends_only( \WP_REST_Request $request ) {
$tokens = explode( '-', $request->get_param( 'auth' ) );
$user_id = $this->friends->access_control->verify_token( $tokens[0], isset( $tokens[1] ) ? $tokens[1] : null, isset( $tokens[2] ) ? $tokens[2] : null );
if ( ! $user_id ) {
return new \WP_Error(
'friends_request_failed',
__( 'Could not respond to the request.', 'friends' ),
array(
'status' => 403,
)
);
return self::error( 'friends_request_failed' );
}

$friend_user = new User( $user_id );
if ( ! $friend_user->has_cap( 'friend' ) ) {
return new \WP_Error(
'friends_request_failed',
__( 'Could not respond to the request.', 'friends' ),
array(
'status' => 403,
)
);
return self::error( 'friends_request_failed' );
}

return true;
Expand Down Expand Up @@ -554,13 +555,7 @@ public function rest_friend_post_deleted( $request ) {
$tokens = explode( '-', $request->get_param( 'auth' ) );
$user_id = $this->friends->access_control->verify_token( $tokens[0], isset( $tokens[1] ) ? $tokens[1] : null, isset( $tokens[2] ) ? $tokens[2] : null );
if ( ! $user_id ) {
return new \WP_Error(
'friends_request_failed',
__( 'Could not respond to the request.', 'friends' ),
array(
'status' => 403,
)
);
return self::error( 'friends_request_failed' );
}
$friend_user = new User( $user_id );
$remote_post_id = $request->get_param( 'post_id' );
Expand Down Expand Up @@ -686,7 +681,7 @@ public function get_friends_rest_url( $feeds ) {
*/
public function discover_rest_url( $url ) {
if ( ! is_string( $url ) || ! Friends::check_url( $url ) ) {
return new \WP_Error( 'invalid-url-given', 'An invalid URL was given.' );
return self::error( 'friends_invalid_url' );
}

$response = wp_safe_remote_get(
Expand Down
2 changes: 1 addition & 1 deletion includes/class-user-feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ public static function get_by_url( $url ) {
*
* @param bool $ignore_due_date Whether to get also undue feeds.
*
* @return object|\WP_Error A User_Feed object.
* @return array An array of User_Feed objects.
*/
public static function get_all_due( $ignore_due_date = false ) {
$term_query = new \WP_Term_Query(
Expand Down
6 changes: 5 additions & 1 deletion includes/class-user.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,12 @@ public static function create( $user_login, $role, $url, $display_name = null, $
}
}

$friend_user = self::get_user( $user_login );
$friend_user = self::get_by_username( $user_login );
if ( $friend_user && ! is_wp_error( $friend_user ) ) {
if ( $friend_user instanceof Subscription ) {
$friend_user = Subscription::convert_to_user( $friend_user );
}

foreach ( $role_rank as $_role => $rank ) {
if ( $rank > $role_rank[ $role ] ) {
break;
Expand Down
8 changes: 4 additions & 4 deletions templates/admin/edit-friend.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,25 @@
</p>
<?php elseif ( $args['friend']->has_cap( 'pending_friend_request' ) ) : ?>
<p class="description">
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'add-friend-' . $args['friend']->user_login, 'add-friend' ) ); ?>"><?php esc_html_e( 'Resend Friend Request', 'friends' ); ?></a>
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', rawurlencode( remove_query_arg( '_wp_http_referer' ) ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'add-friend-' . $args['friend']->user_login, 'add-friend' ) ); ?>"><?php esc_html_e( 'Resend Friend Request', 'friends' ); ?></a>
</p>
<?php elseif ( $args['friend']->has_cap( 'subscription' ) ) : ?>
<p class="description">
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'add-friend-' . $args['friend']->user_login, 'add-friend' ) ); ?>"><?php esc_html_e( 'Send Friend Request', 'friends' ); ?></a>
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', rawurlencode( remove_query_arg( '_wp_http_referer' ) ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'add-friend-' . $args['friend']->user_login, 'add-friend' ) ); ?>"><?php esc_html_e( 'Send Friend Request', 'friends' ); ?></a>
</p>
<?php elseif ( $args['friend']->has_cap( 'acquaintance' ) ) : ?>
<p class="description">
<?php
// translators: %s is a friend role.
echo wp_kses( sprintf( __( 'Change to %s.', 'friends' ), '<a href="' . esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'change-to-friend-' . $args['friend']->user_login, 'change-to-friend' ) ) . '">' . __( 'Friend', 'friends' ) . '</a>' ), array( 'a' => array( 'href' => array() ) ) );
echo wp_kses( sprintf( __( 'Change to %s.', 'friends' ), '<a href="' . esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', rawurlencode( remove_query_arg( '_wp_http_referer' ) ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'change-to-friend-' . $args['friend']->user_login, 'change-to-friend' ) ) . '">' . __( 'Friend', 'friends' ) . '</a>' ), array( 'a' => array( 'href' => array() ) ) );
?>
<?php esc_html_e( 'An Acquaintance has friend status but cannot read private posts.', 'friends' ); ?>
</p>
<?php elseif ( $args['friend']->has_cap( 'friend' ) ) : ?>
<p class="description">
<?php
// translators: %s is a friend role.
echo wp_kses( sprintf( __( 'Change to %s.', 'friends' ), '<a href="' . esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'change-to-restricted-friend-' . $args['friend']->user_login, 'change-to-restricted-friend' ) ) . '">' . __( 'Acquaintance', 'friends' ) . '</a>' ), array( 'a' => array( 'href' => array() ) ) );
echo wp_kses( sprintf( __( 'Change to %s.', 'friends' ), '<a href="' . esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', rawurlencode( remove_query_arg( '_wp_http_referer' ) ), self_admin_url( 'admin.php?page=edit-friend&user=' . $args['friend']->user_login ) ), 'change-to-restricted-friend-' . $args['friend']->user_login, 'change-to-restricted-friend' ) ) . '">' . __( 'Acquaintance', 'friends' ) . '</a>' ), array( 'a' => array( 'href' => array() ) ) );
?>
<?php esc_html_e( 'An Acquaintance has friend status but cannot read private posts.', 'friends' ); ?>
</p>
Expand Down
Loading

0 comments on commit e152be2

Please sign in to comment.