Files
Bookshelf/goodreads-widget.php
2026-10-18 19:01:01 -07:00

136 lines
7.2 KiB
PHP

<?php
// Copyright 2026 Umbra Tools (umbratools.com)
// SPDX-License-Identifier: Apache-2.0
/**
* Custom Widgets
*
* @package BD_Murphy
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Goodreads Author Widget
*/
class BD_Goodreads_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'bd_goodreads_widget',
__('Goodreads Books', 'bd-murphy'),
array('description' => __('Display B.D. Murphy books from Goodreads with ratings', 'bd-murphy'))
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
$author_id = !empty($instance['author_id']) ? $instance['author_id'] : '30469651';
$author_name = !empty($instance['author_name']) ? $instance['author_name'] : 'B.D. Murphy';
$num_books = !empty($instance['num_books']) ? intval($instance['num_books']) : 5;
$author_slug = str_replace(' ', '_', $author_name);
?>
<div class="goodreads-widget">
<a href="https://www.goodreads.com/author/show/<?php echo esc_attr($author_id); ?>.<?php echo esc_attr($author_slug); ?>" target="_blank" rel="noopener">
<?php echo esc_html($author_name); ?>'s books on Goodreads
</a>
<div class="gr_container">
<?php
$books = $this->get_goodreads_books($author_id, $num_books);
foreach ($books as $book) :
?>
<div class="gr_book_container">
<a title="<?php echo esc_attr($book['title']); ?>" class="gr_book_image" rel="nofollow" href="https://www.goodreads.com/book/show/<?php echo esc_attr($book['id']); ?>" target="_blank" rel="noopener">
<img alt="<?php echo esc_attr($book['title']); ?>" border="0" src="<?php echo esc_attr($book['image']); ?>" />
</a>
<div class="gr_book_details">
<a class="gr_book_title" rel="nofollow" href="https://www.goodreads.com/book/show/<?php echo esc_attr($book['id']); ?>" target="_blank" rel="noopener">
<?php echo esc_html($book['title']); ?>
</a>
<div class="gr_review_stats">
<?php echo esc_html($book['reviews']); ?> reviews, <?php echo esc_html($book['ratings']); ?> ratings (avg <?php echo esc_html($book['avg_rating']); ?>)
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
echo $args['after_widget'];
}
private function get_goodreads_books($author_id, $num_books = 5) {
$transient_key = 'bd_goodreads_books_' . $author_id . '_' . $num_books;
$cached = get_transient($transient_key);
if ($cached !== false) {
return $cached;
}
$default_books = $this->get_default_books();
$books = array_slice($default_books, 0, $num_books);
set_transient($transient_key, $books, HOUR_IN_SECONDS);
return $books;
}
private function get_default_books() {
return array(
array('id' => '228023870', 'image' => 'https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1759515027l/228023870._SY75_.jpg', 'title' => 'Pandemic Hacker', 'reviews' => '3', 'ratings' => '29', 'avg_rating' => '4.38'),
array('id' => '245700909', 'image' => 'https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1766512882l/245700909._SY75_.jpg', 'title' => 'The Last Dwarf', 'reviews' => '12', 'ratings' => '14', 'avg_rating' => '3.64'),
array('id' => '197739353', 'image' => 'https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1763291540l/197739353._SY75_.jpg', 'title' => 'Deal Hunter', 'reviews' => '1', 'ratings' => '5', 'avg_rating' => '5.00'),
array('id' => '240199272', 'image' => 'https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1756046864l/240199272._SY75_.jpg', 'title' => 'Pandemic Hacker 2: Time to Hunt', 'reviews' => '5', 'ratings' => '9', 'avg_rating' => '4.89'),
array('id' => '227879386', 'image' => 'https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1739259148l/227879386._SY75_.jpg', 'title' => 'Sidney and Watson: Time Detectives', 'reviews' => '2', 'ratings' => '5', 'avg_rating' => '5.00'),
);
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : __('Goodreads', 'bd-murphy');
$author_id = !empty($instance['author_id']) ? $instance['author_id'] : '30469651';
$author_name = !empty($instance['author_name']) ? $instance['author_name'] : 'B.D. Murphy';
$num_books = !empty($instance['num_books']) ? $instance['num_books'] : 5;
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'bd-murphy'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('author_id'); ?>"><?php _e('Author ID:', 'bd-murphy'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('author_id'); ?>" name="<?php echo $this->get_field_name('author_id'); ?>" type="text" value="<?php echo esc_attr($author_id); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('author_name'); ?>"><?php _e('Author Name:', 'bd-murphy'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('author_name'); ?>" name="<?php echo $this->get_field_name('author_name'); ?>" type="text" value="<?php echo esc_attr($author_name); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('num_books'); ?>"><?php _e('Number of Books:', 'bd-murphy'); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id('num_books'); ?>" name="<?php echo $this->get_field_name('num_books'); ?>" type="number" min="1" max="10" value="<?php echo esc_attr($num_books); ?>">
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
$instance['author_id'] = (!empty($new_instance['author_id'])) ? strip_tags($new_instance['author_id']) : '30469651';
$instance['author_name'] = (!empty($new_instance['author_name'])) ? strip_tags($new_instance['author_name']) : 'B.D. Murphy';
$instance['num_books'] = (!empty($new_instance['num_books'])) ? intval($new_instance['num_books']) : 5;
return $instance;
}
}
function register_bd_widgets() {
register_widget('BD_Goodreads_Widget');
}
add_action('widgets_init', 'register_bd_widgets');