2022-06-16 14:01:47 +02:00
< ? php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2023-04-26 17:39:43 +02:00
// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
2022-06-16 14:01:47 +02:00
add_action ( 'widgets_init' , 'jetpack_goodreads_widget_init' );
2019-11-15 23:26:29 +01:00
/**
* Register the widget for use in Appearance -> Widgets
*/
function jetpack_goodreads_widget_init () {
register_widget ( 'WPCOM_Widget_Goodreads' );
}
/**
* Goodreads widget class
* Display a user ' s Goodreads shelf .
* Customize user_id , title , and shelf
*/
class WPCOM_Widget_Goodreads extends WP_Widget {
2022-06-16 14:01:47 +02:00
/**
* Widget ID based on Goodreads user ID and shelf .
*
* @ var int
*/
2019-11-15 23:26:29 +01:00
private $goodreads_widget_id = 0 ;
2022-06-16 14:01:47 +02:00
/**
* WPCOM_Widget_Goodreads constructor .
*/
public function __construct () {
2019-11-15 23:26:29 +01:00
parent :: __construct (
'wpcom-goodreads' ,
/** This filter is documented in modules/widgets/facebook-likebox.php */
apply_filters ( 'jetpack_widget_name' , __ ( 'Goodreads' , 'jetpack' ) ),
array (
'classname' => 'widget_goodreads' ,
'description' => __ ( 'Display your books from Goodreads' , 'jetpack' ),
'customize_selective_refresh' => true ,
2024-04-17 11:32:24 +02:00
'show_instance_in_rest' => true ,
2019-11-15 23:26:29 +01:00
)
);
2022-06-16 14:01:47 +02:00
// For user input sanitization and display.
2019-11-15 23:26:29 +01:00
$this -> shelves = array (
'read' => _x ( 'Read' , 'past participle: books I have read' , 'jetpack' ),
'currently-reading' => __ ( 'Currently Reading' , 'jetpack' ),
'to-read' => _x ( 'To Read' , 'my list of books to read' , 'jetpack' ),
);
2024-04-17 11:32:24 +02:00
add_filter ( 'widget_types_to_hide_from_legacy_widget_block' , array ( $this , 'hide_widget_in_block_editor' ) );
}
/**
* Remove the " Goodreads " widget from the Legacy Widget block
*
* @ param array $widget_types List of widgets that are currently removed from the Legacy Widget block .
* @ return array $widget_types New list of widgets that will be removed .
*/
public function hide_widget_in_block_editor ( $widget_types ) {
$widget_types [] = 'wpcom-goodreads' ;
return $widget_types ;
2019-11-15 23:26:29 +01:00
}
2022-06-16 14:01:47 +02:00
/**
* Enqueue widget styles .
*/
public function enqueue_style () {
wp_enqueue_style (
'goodreads-widget' ,
plugins_url ( 'goodreads/css/goodreads.css' , __FILE__ ),
array (),
JETPACK__VERSION
);
2019-11-15 23:26:29 +01:00
wp_style_add_data ( 'goodreads-widget' , 'rtl' , 'replace' );
}
2022-06-16 14:01:47 +02:00
/**
* Display the widget .
*
* @ param array $args Display arguments including before_title , after_title , before_widget , and after_widget .
* @ param array $instance The settings for the particular instance of the widget .
*/
public function widget ( $args , $instance ) {
2019-11-15 23:26:29 +01:00
/** This action is documented in modules/widgets/gravatar-profile.php */
do_action ( 'jetpack_stats_extra' , 'widget_view' , 'goodreads' );
/** This filter is documented in core/src/wp-includes/default-widgets.php */
$title = apply_filters ( 'widget_title' , isset ( $instance [ 'title' ] ) ? $instance [ 'title' ] : '' );
if ( empty ( $instance [ 'user_id' ] ) || 'invalid' === $instance [ 'user_id' ] ) {
if ( current_user_can ( 'edit_theme_options' ) ) {
2022-06-16 14:01:47 +02:00
echo $args [ 'before_widget' ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2019-11-15 23:26:29 +01:00
echo '<p>' . sprintf (
2022-06-16 14:01:47 +02:00
wp_kses (
/* translators: %1$s: link to the widget settings page. %2$s: support article URL for Goodreads widget. */
__ ( 'You need to enter your numeric user ID for the <a href="%1$s">Goodreads Widget</a> to work correctly. <a href="%2$s" target="_blank">Full instructions</a>.' , 'jetpack' ),
array (
'a' => array (
'href' => array (),
'target' => array (),
),
)
),
2019-11-15 23:26:29 +01:00
esc_url ( admin_url ( 'widgets.php' ) ),
2022-06-16 14:01:47 +02:00
'https://wordpress.com/support/widgets/goodreads-widget/#set-up-the-widget'
2019-11-15 23:26:29 +01:00
) . '</p>' ;
2022-06-16 14:01:47 +02:00
echo $args [ 'after_widget' ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2019-11-15 23:26:29 +01:00
}
return ;
}
if ( ! array_key_exists ( $instance [ 'shelf' ], $this -> shelves ) ) {
return ;
}
2025-02-28 08:42:11 +01:00
// Enqueue front end assets.
$this -> enqueue_style ();
2019-11-15 23:26:29 +01:00
$instance [ 'user_id' ] = absint ( $instance [ 'user_id' ] );
// Set widget ID based on shelf.
$this -> goodreads_widget_id = $instance [ 'user_id' ] . '_' . $instance [ 'shelf' ];
2023-04-26 17:39:43 +02:00
$this -> goodreads_widget_id = str_replace ( '-' , '_' , $this -> goodreads_widget_id ); // Goodreads' custom widget does not like dashes.
2019-11-15 23:26:29 +01:00
if ( empty ( $title ) ) {
$title = esc_html__ ( 'Goodreads' , 'jetpack' );
}
2022-06-16 14:01:47 +02:00
echo $args [ 'before_widget' ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2022-04-02 10:26:41 +02:00
echo $args [ 'before_title' ] . $title . $args [ 'after_title' ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2019-11-15 23:26:29 +01:00
2022-06-16 14:01:47 +02:00
$goodreads_url = 'https://www.goodreads.com/review/custom_widget/' . rawurlencode ( $instance [ 'user_id' ] ) . '.' . rawurlencode ( $instance [ 'title' ] ) . ':%20' . rawurlencode ( $instance [ 'shelf' ] ) . '?cover_position=&cover_size=small&num_books=5&order=d&shelf=' . rawurlencode ( $instance [ 'shelf' ] ) . '&sort=date_added&widget_bg_transparent=&widget_id=' . rawurlencode ( $this -> goodreads_widget_id );
2019-11-15 23:26:29 +01:00
2024-04-17 11:32:24 +02:00
echo '<div class="jetpack-goodreads-legacy-widget gr_custom_widget" id="gr_custom_widget_' . esc_attr ( $this -> goodreads_widget_id ) . '"></div>' . " \n " ;
2022-06-16 14:01:47 +02:00
echo '<script src="' . esc_url ( $goodreads_url ) . '"></script>' . " \n " ; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
2019-11-15 23:26:29 +01:00
2022-06-16 14:01:47 +02:00
echo $args [ 'after_widget' ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2019-11-15 23:26:29 +01:00
}
2022-06-16 14:01:47 +02:00
/**
* Check if given Goodreads user ID exists .
*
* @ param string $user_id User ID .
*/
public function goodreads_user_id_exists ( $user_id ) {
2019-11-15 23:26:29 +01:00
$url = " https://www.goodreads.com/user/show/ $user_id / " ;
$response = wp_remote_head (
2022-06-16 14:01:47 +02:00
$url ,
array (
2019-11-15 23:26:29 +01:00
'httpversion' => '1.1' ,
'timeout' => 10 ,
'redirection' => 2 ,
)
);
if ( 200 === wp_remote_retrieve_response_code ( $response ) ) {
return true ;
} else {
return false ;
}
}
2022-06-16 14:01:47 +02:00
/**
* Update widget .
*
* @ see WP_Widget :: update ()
*
* @ param array $new_instance New widget instance data .
* @ param array $old_instance Old widget instance data .
*/
public function update ( $new_instance , $old_instance ) {
2019-11-15 23:26:29 +01:00
$instance = $old_instance ;
$instance [ 'user_id' ] = trim ( wp_kses ( stripslashes ( $new_instance [ 'user_id' ] ), array () ) );
if ( ! empty ( $instance [ 'user_id' ] ) && ( ! isset ( $old_instance [ 'user_id' ] ) || $instance [ 'user_id' ] !== $old_instance [ 'user_id' ] ) ) {
if ( ! $this -> goodreads_user_id_exists ( $instance [ 'user_id' ] ) ) {
$instance [ 'user_id' ] = 'invalid' ;
}
}
$instance [ 'title' ] = wp_kses ( stripslashes ( $new_instance [ 'title' ] ), array () );
$shelf = wp_kses ( stripslashes ( $new_instance [ 'shelf' ] ), array () );
if ( array_key_exists ( $shelf , $this -> shelves ) ) {
$instance [ 'shelf' ] = $shelf ;
}
return $instance ;
}
2022-06-16 14:01:47 +02:00
/**
* Outputs the widget settings form .
*
* @ param array $instance Current settings .
2025-06-09 09:58:01 +02:00
* @ return string | void
2022-06-16 14:01:47 +02:00
*/
public function form ( $instance ) {
// Defaults.
2019-11-15 23:26:29 +01:00
$instance = wp_parse_args (
2022-06-16 14:01:47 +02:00
( array ) $instance ,
array (
2019-11-15 23:26:29 +01:00
'user_id' => '' ,
'title' => 'Goodreads' ,
'shelf' => 'read' ,
)
);
echo '<p><label for="' . esc_attr ( $this -> get_field_id ( 'title' ) ) . '">' . esc_html__ ( 'Title:' , 'jetpack' ) . '
< input class = " widefat " id = " ' . esc_attr( $this->get_field_id ( 'title' ) ) . ' " name = " ' . esc_attr( $this->get_field_name ( 'title' ) ) . ' " type = " text " value = " ' . esc_attr( $instance['title'] ) . ' " />
</ label ></ p >
< p >< label for = " ' . esc_attr( $this->get_field_id ( 'user_id' ) ) . ' " > ' ;
2022-06-16 14:01:47 +02:00
printf (
wp_kses (
/* translators: %s: support article URL for Goodreads widget. */
__ ( 'Goodreads numeric user ID <a href="%s" target="_blank">(instructions)</a>:' , 'jetpack' ),
array (
'a' => array (
'href' => array (),
'target' => array (),
),
)
),
'https://wordpress.com/support/widgets/goodreads-widget/#set-up-the-widget'
);
2019-11-15 23:26:29 +01:00
if ( 'invalid' === $instance [ 'user_id' ] ) {
2022-06-16 14:01:47 +02:00
printf ( '<br /><small class="error">%s</small> ' , esc_html ( __ ( 'Invalid User ID, please verify and re-enter your Goodreads numeric user ID.' , 'jetpack' ) ) );
2019-11-15 23:26:29 +01:00
$instance [ 'user_id' ] = '' ;
}
echo '<input class="widefat" id="' . esc_attr ( $this -> get_field_id ( 'user_id' ) ) . '" name="' . esc_attr ( $this -> get_field_name ( 'user_id' ) ) . '" type="text" value="' . esc_attr ( $instance [ 'user_id' ] ) . ' " />
</ label ></ p >
< p >< label for = " ' . esc_attr( $this->get_field_id ( 'shelf' ) ) . ' " > ' . esc_html__( ' Shelf : ', ' jetpack ' ) . '
< select class = " widefat " id = " ' . esc_attr( $this->get_field_id ( 'shelf' ) ) . ' " name = " ' . esc_attr( $this->get_field_name ( 'shelf' ) ) . ' " > ' ;
foreach ( $this -> shelves as $_shelf_value => $_shelf_display ) {
2022-06-16 14:01:47 +02:00
echo " \t <option value=' " . esc_attr ( $_shelf_value ) . " ' " . selected ( $_shelf_value , $instance [ 'shelf' ], false ) . '>' . $_shelf_display . " </option> \n " ; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
2019-11-15 23:26:29 +01:00
}
echo ' </ select >
</ label ></ p >
' ;
}
}