WP_Widget to let wordpress know about it.
function __construct() {
$language_codes = explode( '_', get_locale() );
switch ( $language_codes[ 0 ] ) {
case 'ar':
$widget_name = 'آخر المقالات مع الصوّر المصغّرة';
$widget_desc = 'قائمة موقعك المشاركات الأخيرة، مع عنوان نقر والصور المصغرة';
break;
case 'fa':
$widget_name = 'نوشته های اخیر با تصویر بندانگشتی';
$widget_desc = 'فهرست سایت شما ارسال جدید، با عنوان قابل کلیک و عکسها';
break;
case 'de':
$widget_name = 'Neueste Beiträge mit Vorschaubildern';
$widget_desc = 'Liste deiner aktuellsten Beiträge, mit klickbaren Überschriften und Vorschaubildern.';
break;
case 'pl':
$widget_name = 'Ostatnie posty z miniaturami';
$widget_desc = 'Lista ostatnich wpisów twojej strony z klikalnymi tytułami i miniaturami.';
break;
case 'ru':
$widget_name = 'Последние записи с эскизами';
$widget_desc = 'Список последних сообщений вашего сайта, с заголовком интерактивными и иконками.';
break;
case 'tr':
$widget_name = 'Küçük Resimlerle Son Yazılar';
$widget_desc = 'Başlık ve küçük resimleri tıklanabilir olan sitenizin en son yazıların listesi.';
break;
case 'ja':
$widget_name = 'Recent Posts With Thumbnails';
$widget_desc = 'サイトの最新の投稿を、クリック可能なタイトルとサムネイル付きで一覧表示します。';
break;
case 'ca':
$widget_name = 'Publicacions recents amb miniatures';
$widget_desc = 'Llista de les publicacions més recents del vostre lloc, amb títol i miniatures que es poden fer clic.';
break;
default:
$widget_name = 'Recent Posts With Thumbnails';
$widget_desc = 'List of your site’s most recent posts, with clickable title and thumbnails.';
}
$this->defaults[ 'author_label' ] = __( 'By', 'recent-posts-widget-with-thumbnails' );
$this->defaults[ 'category_ids' ] = array( 0 ); // selected categories
$this->defaults[ 'category_label' ] = _x( 'In', 'In {categories}', 'recent-posts-widget-with-thumbnails' ); // label for category list
$this->defaults[ 'css_file_path' ] = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'public.css'; // path of the public css file
$this->defaults[ 'excerpt_length' ] = absint( apply_filters( 'rpwwt_excerpt_length', 55 ) ); // default length: 55 characters
$this->defaults[ 'excerpt_more' ] = apply_filters( 'rpwwt_excerpt_more', ' ' . '[…]' ); // set ellipses as default 'more'
$this->defaults[ 'is_nav_widget' ] = current_theme_supports( 'html5', 'navigation-widgets' ); // available support of navigation in widgets (NAV element for more accessibility), since WP 5.5
$this->defaults[ 'nav_label' ] = __( 'Recent Posts With Thumbnails', 'recent-posts-widget-with-thumbnails' ); // ARIA label of the navigation list
$this->defaults[ 'number_posts' ] = 5; // number of posts to show in the widget
$this->defaults[ 'orderby' ] = 'date'; // default order value
$this->defaults[ 'order' ] = 'desc'; // default sort value
$this->defaults[ 'plugin_slug' ] = 'recent-posts-widget-with-thumbnails'; // identifier of this plugin for WP
$this->defaults[ 'plugin_version' ] = '7.1.1'; // current plugin version
$this->defaults[ 'post_title_length' ] = 1000; // default length: 1000 characters
$this->defaults[ 'thumb_alt' ] = '';
$this->defaults[ 'thumb_dimensions' ] = 'custom'; // dimensions of the thumbnail
$this->defaults[ 'thumb_height' ] = absint( round( get_option( 'thumbnail_size_h', 110 ) / 2 ) ); // custom height of the thumbnail
$this->defaults[ 'thumb_url' ] = plugins_url( 'default_thumb.gif', __FILE__ ); // URL of the default thumbnail
$this->defaults[ 'thumb_width' ] = absint( round( get_option( 'thumbnail_size_w', 110 ) / 2 ) ); // custom width of the thumbnail
$this->defaults[ 'widget_title' ] = ''; // title of the widget
// Domain name and protocol of WP site
$parsed_url = parse_url( home_url() );
$this->defaults[ 'site_protocol' ] = $parsed_url[ 'host' ];
$this->defaults[ 'site_url' ] = $parsed_url[ 'scheme' ];
unset( $parsed_url );
// other vars
$this->bools_false = array( 'hide_current_post', 'only_sticky_posts', 'hide_sticky_posts', 'hide_title', 'keep_aspect_ratio', 'keep_sticky', 'only_1st_img', 'random_order', 'show_author', 'show_categories', 'show_comments_number', 'show_date', 'show_excerpt', 'ignore_excerpt', 'ignore_post_content_excerpt', 'set_more_as_link', 'try_1st_img', 'use_default', 'use_default_only', 'open_new_window', 'print_post_categories', 'set_cats_as_links', 'use_inline_css', 'use_no_css', 'hide_alt_texts' );
$this->bools_true = array( 'show_thumb' );
$this->ints = array( 'excerpt_length', 'number_posts', 'post_title_length', 'thumb_height', 'thumb_width' );
$this->valid_excerpt_sources = array( 'post_content', 'excerpt_field' );
$this->optional_text_fields = array( 'author_label', 'excerpt_more', 'category_label', 'thumb_alt' );
$widget_ops = array( 'classname' => $this->defaults[ 'plugin_slug' ], 'description' => $widget_desc );
parent::__construct( $this->defaults[ 'plugin_slug' ], $widget_name, $widget_ops );
add_action( 'save_post', array( $this, 'flush_widget_cache' ) );
add_action( 'deleted_post', array( $this, 'flush_widget_cache' ) );
add_action( 'switch_theme', array( $this, 'flush_widget_cache' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_public_style' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_style' ) );
// not in use, just for the po-editor to display the translation on the plugins overview list
$widget_name = __( 'Recent Posts With Thumbnails', 'recent-posts-widget-with-thumbnails' );
$widget_desc = __( 'List of your site’s most recent posts, with clickable title and thumbnails.', 'recent-posts-widget-with-thumbnails' );
}
// display the widget on the front end.
function widget( $args, $instance ) {
global $post;
if ( ! isset( $args[ 'widget_id' ] ) ) {
$args[ 'widget_id' ] = $this->id;
}
// get and sanitize values
$title = ( ! empty( $instance[ 'title' ] ) ) ? $instance[ 'title' ] : $this->defaults[ 'widget_title' ];
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
$category_ids = ( ! empty( $instance[ 'category_ids' ] ) ) ? array_map( 'absint', $instance[ 'category_ids' ] ) : $this->defaults[ 'category_ids' ];
$default_url = ( ! empty( $instance[ 'default_url' ] ) ) ? $instance[ 'default_url' ] : $this->defaults[ 'thumb_url' ];
$thumb_dimensions = ( ! empty( $instance[ 'thumb_dimensions' ] ) ) ? $instance[ 'thumb_dimensions' ] : $this->defaults[ 'thumb_dimensions' ];
$orderby = ( ! empty( $instance[ 'orderby' ] ) ) ? $instance[ 'orderby' ] : $this->defaults[ 'orderby' ];
$order = ( ! empty( $instance[ 'order' ] ) && 'rand' != $orderby ) ? $instance[ 'order' ] : $this->defaults[ 'order' ];
// initialize integer variables
$ints = array();
foreach ( $this->ints as $key ) {
$ints[ $key ] = ( ! empty( $instance[ $key ] ) ) ? absint( $instance[ $key ] ) : $this->defaults[ $key ];
}
// initialize bool variables
$bools = array();
foreach ( $this->bools_false as $key ) {
$bools[ $key ] = ( isset( $instance[ $key ] ) ) ? (bool) $instance[ $key ] : false;
}
foreach ( $this->bools_true as $key ) {
$bools[ $key ] = ( isset( $instance[ $key ] ) ) ? (bool) $instance[ $key ] : false;
}
// special case: class wide setting
$this->use_inline_css = $bools[ 'use_inline_css' ];
$this->use_no_css = $bools[ 'use_no_css' ];
// if 'all categories' was selected ignore other selections of categories
if ( in_array( 0, $category_ids ) ) {
$category_ids = $this->defaults[ 'category_ids' ];
}
// if no URL take default URL
if ( '' == esc_url_raw( $default_url ) ) {
$default_url = $this->defaults[ 'thumb_url' ];
}
// ToDo: add option to filter custom post types as well
// standard params
$query_args = array(
'posts_per_page' => $ints[ 'number_posts' ],
'no_found_rows' => true,
'post_status' => 'publish',
'orderby' => $orderby
);
if( 'rand' != $orderby ) {
$query_args[ 'order' ] = $order;
}
// make downward compatible from version 7.1 and up
// deprecated $bools[ 'random_order' ]
if( $bools['random_order'] ) {
$this->ints[ 'orderby' ] = 'rand';
}
// set order of posts in widget
//$query_args[ 'orderby' ] = ( $bools[ 'random_order' ] ) ? 'rand' : 'menu_order, post_date';
// add categories param only if 'all categories' was not selected
if ( ! in_array( 0, $category_ids ) ) {
$query_args[ 'category__in' ] = $category_ids;
}
// exclude current displayed post
if ( $bools[ 'hide_current_post' ] ) {
if ( isset( $post->ID ) and is_singular() ) {
$query_args[ 'post__not_in' ] = array( $post->ID );
}
}
// ignore sticky posts if desired, else show them on top
$query_args[ 'ignore_sticky_posts' ] = ( $bools[ 'keep_sticky' ] ) ? false : true;
// exclude sticky posts
if ( $bools[ 'only_sticky_posts' ] ) {
// set the filter with IDs of sticky posts
$query_args[ 'post__in' ] = get_option( 'sticky_posts', array() );
// The next line appears illogical in comparison with the
// previous line, but is necessary to display the correct
// number of posts if the number of sticky posts is greater
// than the number of posts to be displayed.
$query_args[ 'ignore_sticky_posts' ] = true;
} elseif ( $bools[ 'hide_sticky_posts' ] ) {
// get IDs of sticky posts
$post_ids = get_option( 'sticky_posts', array() );
// if there are sticky posts
if ( $post_ids ) {
// if argument 'post__not_in' is defined
if ( isset( $query_args[ 'post__not_in' ] ) ) {
// merge argument arrays
$tmp1 = array_merge( $query_args[ 'post__not_in' ], $post_ids );
// make post IDs in array unique by using a faster way than array_unique()
$tmp2 = array();
foreach( $tmp1 as $key => $val ) {
$tmp2[ $val ] = true;
}
// set argument with cleaned array
$query_args[ 'post__not_in' ] = array_keys( $tmp2 );
// delete temporary variables
unset( $tmp1, $tmp2 );
} else {
// set argument with array of post IDs
$query_args[ 'post__not_in' ] = $post_ids;
}
}
// delete temporary variable
unset( $post_ids );
}
// apply correction function if query includes sticky posts and categories filter
if ( isset( $query_args[ 'category__in' ] ) and $bools[ 'keep_sticky' ] ) {
add_filter( 'the_posts', array( $this, 'get_stickies_on_top' ) );
}
// run the query: get the latest posts
$r = new WP_Query( apply_filters( 'rpwwt_widget_posts_args', $query_args ) );
// remove correction function if query includes sticky posts and categories filter
if ( isset( $query_args[ 'category__in' ] ) and $bools[ 'keep_sticky' ] ) {
remove_filter( 'the_posts', array( $this, 'get_stickies_on_top' ) );
}
if ( $r->have_posts() ) :
// translate repeately used texts once (for more performance)
$text = ', ';
$this->defaults[ 'comma' ] = __( $text );
$text = '…';
$this->defaults[ 'ellipses' ] = __( $text );
$text = '(no title)';
$this->defaults[ 'no_title' ] = __( $text );
$text = 'Post';
$this->defaults[ 'Post' ] = _x( $text, 'post type singular name' );
// get current post ID
$queried_object_id = get_queried_object_id();
// set the desired image dimensions
if ( 'custom' == $thumb_dimensions ) {
// set dimensions with specified size array
$this->customs[ 'thumb_dimensions' ] = array( $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] );
} else {
// overwrite thumb_width and thumb_height with closest size
list( $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] ) = $this->get_image_dimensions( $thumb_dimensions );
// set dimensions with specified size name
$this->customs[ 'thumb_dimensions' ] = $thumb_dimensions;
}
// for some text fields: let there be an empty fields if desired
foreach ( $this->optional_text_fields as $field ) {
if ( isset( $instance[ $field ] ) ) {
if ( '' === $instance[ $field ] ) {
$this->customs[ $field ] = '';
} else {
$this->customs[ $field ] = $instance[ $field ];
}
} else {
$this->customs[ $field ] = $this->defaults[ $field ];
}
}
// set other global vars
$this->customs[ 'ignore_excerpt' ] = $bools[ 'ignore_excerpt' ]; // whether to ignore post excerpt field or not
$this->customs[ 'ignore_post_content_excerpt' ] = $bools[ 'ignore_post_content_excerpt' ]; // whether to ignore post content or not
$this->customs[ 'set_more_as_link' ] = $bools[ 'set_more_as_link' ]; // whether to set 'more' signs as link or not
$this->customs[ 'set_cats_as_links' ] = $bools[ 'set_cats_as_links' ]; // whether to set category names as links or not
$this->customs[ 'excerpt_length' ] = $ints[ 'excerpt_length' ]; // number of characters of excerpt
$this->customs[ 'post_title_length' ] = $ints[ 'post_title_length' ]; // maximum number of characters of post title
// set default image code
$default_attr = array(
'src' => esc_url( $default_url ),
'class' => sprintf( "attachment-%dx%d", $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] ),
'alt' => $bools[ 'hide_alt_texts' ] ? '' : esc_attr( $this->customs[ 'thumb_alt' ] ),
'loading' => 'lazy',
);
$default_img = '
$value ) {
$default_img .= ' ' . $name . '="' . $value . '"';
}
$default_img .= ' />';
// set link target
if ( $bools[ 'open_new_window' ] ) {
$this->customs[ 'link_target' ] = ' target="_blank"';
} else {
$this->customs[ 'link_target' ] = '';
}
//set image attributes
$attr = '';
if ( $bools[ 'hide_alt_texts' ] ) {
$attr = array( 'alt' => '' );
}
// print list
include 'includes/widget.php';
// Reset the global $the_post as this query will have stomped on it
wp_reset_postdata();
endif;
}
// The widget form in the admin area.
function update( $new_widget_settings, $old_widget_settings ) {
$instance = $old_widget_settings;
// sanitize user input before update
$instance[ 'title' ] = ( isset( $new_widget_settings[ 'title' ] ) ) ? strip_tags( $new_widget_settings[ 'title' ] ) : $this->defaults[ 'widget_title' ];
$instance[ 'default_url' ] = ( isset( $new_widget_settings[ 'default_url' ] ) ) ? esc_url_raw( $new_widget_settings[ 'default_url' ] ) : $this->defaults[ 'thumb_url' ];
$instance[ 'thumb_dimensions' ] = ( isset( $new_widget_settings[ 'thumb_dimensions' ] ) ) ? strip_tags( $new_widget_settings[ 'thumb_dimensions' ] ) : $this->defaults[ 'thumb_dimensions' ];
$instance[ 'category_ids' ] = ( isset( $new_widget_settings[ 'category_ids' ] ) ) ? array_map( 'absint', $new_widget_settings[ 'category_ids' ] ) : $this->defaults[ 'category_ids' ];
$instance[ 'orderby' ] = ( isset( $new_widget_settings[ 'orderby' ] ) ) ? $new_widget_settings[ 'orderby' ] : $this->defaults[ 'orderby' ];
$instance[ 'order' ] = ( isset( $new_widget_settings[ 'order' ] ) ) ? $new_widget_settings[ 'order' ] : $this->defaults[ 'order' ];
// initialize integer variables
foreach ( $this->ints as $key ) {
$instance[ $key ] = ( isset( $new_widget_settings[ $key ] ) ) ? absint( $new_widget_settings[ $key ] ) : $this->defaults[ $key ];
}
// initialize bool variables
foreach ( $this->bools_false as $key ) {
$instance[ $key ] = isset( $new_widget_settings[ $key ] ) && $new_widget_settings[ $key ];
}
foreach ( $this->bools_true as $key ) {
$instance[ $key ] = isset( $new_widget_settings[ $key ]) && $new_widget_settings[ $key ];
}
// for some text fields: let there be an empty fields if desired
foreach ( $this->optional_text_fields as $field ) {
if ( isset( $new_widget_settings[ $field ] ) ) {
if ( '' == $new_widget_settings[ $field ] ) {
$instance[ $field ] = '';
} else {
$instance[ $field ] = $new_widget_settings[ $field ];
}
} else {
$instance[ $field ] = $this->defaults[ $field ];
}
}
// if 'all categories' was selected ignore other selections of categories
if ( in_array( 0, $instance[ 'category_ids' ] ) ) {
$instance[ 'category_ids' ] = $this->defaults[ 'category_ids' ];
}
// empty widget cache
$this->flush_widget_cache();
$alloptions = wp_cache_get( 'alloptions', 'options' );
if ( isset( $alloptions[ $this->defaults[ 'plugin_slug' ] ] ) ) {
delete_option( $this->defaults[ 'plugin_slug' ] );
}
// delete current css file to let make new one via $this->enqueue_public_style()
if ( file_exists( $this->defaults[ 'css_file_path' ] ) ) {
// remove the file
unlink( $this->defaults[ 'css_file_path' ] );
}
// return sanitized current widget settings
return $instance;
}
function flush_widget_cache() {
wp_cache_delete( $this->defaults[ 'plugin_slug' ], 'widget' );
}
// Saves the data, called via AJAX. But the saving logic comes here.
function form( $instance ) {
// get and sanitize values
$title = ( isset( $instance[ 'title' ] ) ) ? $instance[ 'title' ] : $this->defaults[ 'widget_title' ];
$thumb_dimensions = ( isset( $instance[ 'thumb_dimensions' ] ) ) ? $instance[ 'thumb_dimensions' ] : $this->defaults[ 'thumb_dimensions' ];
$default_url = ( isset( $instance[ 'default_url' ] ) ) ? $instance[ 'default_url' ] : $this->defaults[ 'thumb_url' ];
$category_ids = ( isset( $instance[ 'category_ids' ] ) ) ? $instance[ 'category_ids' ] : $this->defaults[ 'category_ids' ];
// initialize integer variables
$ints = array();
foreach ( $this->ints as $key ) {
$ints[ $key ] = ( isset( $instance[ $key ] ) ) ? absint( $instance[ $key ] ) : $this->defaults[ $key ];
}
// initialize bool variables
$bools = array();
foreach ( $this->bools_false as $key ) {
$bools[ $key ] = ( isset( $instance[ $key ] ) ) ? (bool) $instance[ $key ] : false;
}
foreach ( $this->bools_true as $key ) {
$bools[ $key ] = ( isset( $instance[ $key ] ) ) ? (bool) $instance[ $key ] : true;
}
// for some text fields: let there be an empty fields if desired
foreach ( $this->optional_text_fields as $field ) {
if ( isset( $instance[ $field ] ) ) {
if ( '' == $instance[ $field ] ) {
$optional_texts[ $field ] = '';
} else {
$optional_texts[ $field ] = $instance[ $field ];
}
} else {
$optional_texts[ $field ] = $this->defaults[ $field ];
}
}
// if 'all categories' was selected ignore other selections of categories
if ( in_array( 0, $category_ids ) ) {
$category_ids = $this->defaults[ 'category_ids' ];
}
// if no URL take default URL
if ( '' == esc_url_raw( $default_url ) ) {
$default_url = $this->defaults[ 'thumb_url' ];
}
// compute ids only once to improve performance
$field_ids = array();
$field_ids[ 'author_label' ] = $this->get_field_id( 'author_label' );
$field_ids[ 'category_ids' ] = $this->get_field_id( 'category_ids' );
$field_ids[ 'category_label' ] = $this->get_field_id( 'category_label' );
$field_ids[ 'default_url' ] = $this->get_field_id( 'default_url' );
$field_ids[ 'excerpt_more' ] = $this->get_field_id( 'excerpt_more' );
$field_ids[ 'thumb_alt' ] = $this->get_field_id( 'thumb_alt' );
$field_ids[ 'thumb_dimensions' ]= $this->get_field_id( 'thumb_dimensions' );
$field_ids[ 'title' ] = $this->get_field_id( 'title' );
$field_ids[ 'orderby' ] = $this->get_field_id( 'orderby' );
$field_ids[ 'order' ] = $this->get_field_id( 'order' );
foreach ( array_merge( $this->ints, $this->bools_false, $this->bools_true ) as $key ) {
$field_ids[ $key ] = $this->get_field_id( $key );
}
// get texts and values for image sizes dropdown
global $_wp_additional_image_sizes;
$wp_standard_image_size_labels = array();
$label = 'Full Size'; $wp_standard_image_size_labels[ 'full' ] = __( $label );
$label = 'Large'; $wp_standard_image_size_labels[ 'large' ] = __( $label );
$label = 'Medium'; $wp_standard_image_size_labels[ 'medium' ] = __( $label );
$label = 'Thumbnail'; $wp_standard_image_size_labels[ 'thumbnail' ] = __( $label );
$wp_standard_image_size_names = array_keys( $wp_standard_image_size_labels );
$size_options = array();
foreach ( get_intermediate_image_sizes() as $size_name ) {
// Don't take numeric sizes that appear
if( is_integer( $size_name ) ) {
continue;
}
$option_values = array();
// Set technical name
$option_values[ 'size_name' ] = $size_name;
// Set name
$option_values[ 'name' ] = in_array( $size_name, $wp_standard_image_size_names ) ? $wp_standard_image_size_labels[$size_name] : $size_name;
// Set width
$option_values[ 'width' ] = isset( $_wp_additional_image_sizes[$size_name]['width'] ) ? $_wp_additional_image_sizes[$size_name]['width'] : get_option( "{$size_name}_size_w" );
// Set height
$option_values[ 'height' ] = isset( $_wp_additional_image_sizes[$size_name]['height'] ) ? $_wp_additional_image_sizes[$size_name]['height'] : get_option( "{$size_name}_size_h" );
// add option to options list
$size_options[] = $option_values;
}
// create text to Media Settings page
$text = 'Settings'; $label_settings = __( $text );
$text = 'Media'; $label_media = _x( $text, 'post type general name' );
$label = sprintf( '%s › %s', $label_settings, $label_media );
$media_trail = ( current_user_can( 'manage_options' ) ) ? sprintf( '%s', esc_url( admin_url( 'options-media.php' ) ), esc_html( $label ) ) : sprintf( '%s', esc_html( $label ) );
// oder settings
$option_values[ 'orderby' ] = ( isset( $instance[ 'orderby' ] ) ) ? $instance[ 'orderby' ] : $this->defaults[ 'orderby' ];
// make downward compatible from version 7.1 and up
// deprecated $bools[ 'random_order' ]
if( true == $bools[ 'random_order' ] ) {
$option_values[ 'orderby' ] = 'rand';
}
$option_values[ 'order' ] = ( isset( $instance[ 'order' ] ) && 'rand' != $option_values[ 'orderby' ] ) ? $instance[ 'order' ] : $this->defaults[ 'order' ];
// get texts and values for categories dropdown
$all_text = __( 'All Categories', 'recent-posts-widget-with-thumbnails' );
$label_all_cats = $all_text;
// get categories
$categories = get_categories( array( 'hide_empty' => 0, 'hierarchical' => 1 ) );
$number_of_cats = count( $categories );
// get size (number of rows to display) of selection box: not more than 10
$number_of_rows = ( 10 > $number_of_cats ) ? $number_of_cats + 1 : 10;
// start selection box
$selection_element = sprintf(
'\n";
// print form in widgets page
include 'includes/form.php';
}
/**
* Return the array index of a given ID
*
* @since 4.1
*/
private function get_cat_parent_index( $arr, $id ) {
$len = count( $arr );
if ( 0 == $len ) {
return false;
}
$id = absint( $id );
for ( $i = 0; $i < $len; $i++ ) {
if ( $id == $arr[ $i ][ 'id' ] ) {
return $i;
}
}
return false;
}
/**
* Load the widget's CSS in the HEAD section of the frontend
*
* @since 2.3
*/
public function enqueue_public_style () {
$is_file = false;
$css_code = '';
// make sure the CSS file exists; if not available: generate it
if ( file_exists( $this->defaults[ 'css_file_path' ] ) ) {
$is_file = true;
} else {
// get stored settings
$all_settings = $this->get_settings();
// quit if at least 1 widget was set for no CSS at all
foreach ( $all_settings as $id => $settings ) {
if ( isset( $settings[ 'use_no_css' ] ) and $settings[ 'use_no_css' ] ) {
return;
}
} // foreach ( $all_settings as $id => $settings )
// get the CSS code
list( $css_code, $use_inline_css ) = $this->generate_css_code( $all_settings );
// if not to print the CSS as inline code in the HTML document
if ( ! $use_inline_css ) {
// write file safely
if ( @file_put_contents( $this->defaults[ 'css_file_path' ], $css_code ) ) {
// file writing was successfull, so change file permissions
chmod( $this->defaults[ 'css_file_path' ], 0644 );
$is_file = true;
} // if CSS file successfully created
} // if no inline CSS
} // if CSS file exists
// if there is a CSS file
if ( $is_file ) {
// enqueue the CSS file
wp_enqueue_style(
$this->defaults[ 'plugin_slug' ] . '-public-style',
plugin_dir_url( __FILE__ ) . 'public.css',
array(),
$this->defaults[ 'plugin_version' ],
'all'
);
} else {
// print inline CSS
print "\n\n";
printf( "\n", $css_code );
} // if $is_file
}
/**
* Load the widget's CSS in the HEAD section of the backend
*
* @since 4.0
*/
public function enqueue_admin_style () {
// load CSS file on Widgets page only
$screen = get_current_screen();
if ( 'widgets' == $screen->id ) {
// enqueue the style
wp_enqueue_style(
$this->defaults[ 'plugin_slug' ] . '-admin-style',
plugin_dir_url( __FILE__ ) . 'admin.css',
array(),
$this->defaults[ 'plugin_version' ],
'all'
);
}
}
/**
* Returns the id of the first image in the content, else 0
*
* @access private
* @since 2.0
*
* @return integer the post id of the first content image
*/
private function get_first_content_image_id () {
// set variables
global $wpdb;
$post = get_post();
if ( $post and isset( $post->post_content ) ) {
// look for images in HTML code
preg_match_all( '/
]+>/i', $post->post_content, $all_img_tags );
if ( $all_img_tags ) {
foreach ( $all_img_tags[ 0 ] as $img_tag ) {
// find class attribute and catch its value
preg_match( '/]*>/i', $img_tag, $img_class );
if ( $img_class ) {
// Look for the WP image id
preg_match( '/wp-image-([\d]+)/i', $img_class[ 1 ], $thumb_id );
// if first image id found: check whether is image
if ( $thumb_id ) {
$img_id = absint( $thumb_id[ 1 ] );
// if is image: return its id
if ( wp_attachment_is_image( $img_id ) ) {
return $img_id;
}
} // if(thumb_id)
} // if(img_class)
// else: try to catch image id by its url as stored in the database
// find src attribute and catch its value
preg_match( '/]*>/i', $img_tag, $img_src );
if ( $img_src ) {
// delete optional query string in img src
$url = preg_replace( '/([^?]+).*/', '\1', $img_src[ 1 ] );
// delete image dimensions data in img file name, just take base name and extension
$url = preg_replace( '/(.+)-\d+x\d+\.(\w+)/', '\1.\2', $url );
// if path is protocol relative then set it absolute
if ( 0 === strpos( $url, '//' ) ) {
$url = $this->defaults[ 'site_protocol' ] . ':' . $url;
// if path is domain relative then set it absolute
} elseif ( 0 === strpos( $url, '/' ) ) {
$url = $this->defaults[ 'site_url' ] . $url;
}
// look up its id in the db
$thumb_id = $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM $wpdb->posts WHERE `guid` = '%s'", $url ) );
// if id is available: return it
if ( $thumb_id ) {
return absint( $thumb_id );
} // if(thumb_id)
} // if(img_src)
} // foreach(img_tag)
} // if(all_img_tags)
} // if (post content)
// if nothing found: return 0
return 0;
}
/**
* Returns the thumbnail of first post's image or empty string on failure
*
* @access private
* @since 2.0
*
* @return bool success on finding an image
*/
private function the_first_post_image ( $attr ) {
// look for first image
$thumb_id = $this->get_first_content_image_id();
// if there is first image then show first image
if ( $thumb_id ) :
return wp_get_attachment_image( $thumb_id, $this->customs[ 'thumb_dimensions' ], $attr );
else :
return '';
endif; // thumb_id
}
/**
* Returns the assigned categories of a post in a string
*
* @access private
* @since 4.6
*
*/
private function get_the_categories ( $id ) {
$terms = get_the_terms( $id, 'category' );
if ( is_wp_error( $terms ) ) {
return __( 'Error on listing categories', 'recent-posts-widget-with-thumbnails' );
}
if ( empty( $terms ) ) {
$text = 'No categories';
return __( $text );
}
$categories = array();
if ( $this->customs[ 'set_cats_as_links' ] ) {
foreach ( $terms as $term ) {
// get link to category
$categories[] = sprintf(
'%s',
get_category_link( $term->term_id ),
esc_html( $term->name )
);
}
} else {
foreach ( $terms as $term ) {
// get sanitized category name
$categories[] = esc_html( $term->name );
}
}
/*foreach ( $terms as $term ) {
$categories[] = $term->name;
}*/
$string = '';
if ( $this->customs[ 'category_label' ] ) {
$string = $this->customs[ 'category_label' ] . ' ';
}
$string .= join( $this->defaults[ 'comma' ], $categories );
return apply_filters( 'rpwwt_categories', $string );
}
/**
* Returns the assigned author of a post in a string
*
* @access private
* @since 4.8
*
*/
private function get_the_author () {
$author = get_the_author();
if ( empty( $author ) ) {
return '';
} else {
$string = '';
if ( $this->customs[ 'author_label' ] ) {
$string = $this->customs[ 'author_label' ] . ' ';
}
return $string . $author;
//return sprintf( $this->defaults[ 'author_label' ], $author );
}
}
/**
* Generate the css code with stored settings
*
* @since 2.3
*/
private function generate_css_code ( $all_instances ) {
$set_default = true;
$ints = array();
$use_inline_css = false;
// generate CSS
$css_code = ".rpwwt-widget ul { list-style: outside none none; margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }\n";
$css_code .= ".rpwwt-widget ul li { overflow: hidden; margin: 0 0 1.5em; }\n";
$css_code .= ".rpwwt-widget ul li:last-child { margin: 0; }\n";
$css_code .= ".rpwwt-widget .screen-reader-text {border: 0; clip: rect(1px, 1px, 1px, 1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute !important; width: 1px; word-wrap: normal !important; word-break: normal; }\n";
$css_code .= ".rpwwt-widget .screen-reader-text:focus {background-color: #f1f1f1; border-radius: 3px; box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); clip: auto !important; -webkit-clip-path: none; clip-path: none; color: #21759b; display: block; font-size: 0.875rem; font-weight: 700; height: auto; right: 5px; line-height: normal; padding: 15px 23px 14px; text-decoration: none; top: 5px; width: auto; z-index: 100000; }\n";
if ( is_rtl() ) {
$css_code .= ".rpwwt-widget ul li img { display: inline; float: right; margin: .3em 0 .75em .75em; }\n";
} else {
$css_code .= ".rpwwt-widget ul li img { display: inline; float: left; margin: .3em .75em .75em 0; }\n";
}
foreach ( $all_instances as $number => $settings ) {
// set width and height
$ints[ 'thumb_width' ] = $this->defaults[ 'thumb_width' ];
$ints[ 'thumb_height' ] = $this->defaults[ 'thumb_height' ];
$thumb_dimensions = isset( $settings[ 'thumb_dimensions' ] ) ? $settings[ 'thumb_dimensions' ] : $this->defaults[ 'thumb_dimensions' ];
if ( 'custom' == $thumb_dimensions ) {
if ( isset( $settings[ 'thumb_width' ] ) ) {
$ints[ 'thumb_width' ] = absint( $settings[ 'thumb_width' ] );
}
if ( isset( $settings[ 'thumb_height' ] ) ) {
$ints[ 'thumb_height' ] = absint( $settings[ 'thumb_height' ] );
}
} else {
list( $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] ) = $this->get_image_dimensions( $thumb_dimensions );
} // $settings[ 'thumb_dimensions' ]
// get aspect ratio option
$bools[ 'keep_aspect_ratio' ] = false;
if ( isset( $settings[ 'keep_aspect_ratio' ] ) ) {
$bools[ 'keep_aspect_ratio' ] = (bool) $settings[ 'keep_aspect_ratio' ];
// set CSS code
if ( $bools[ 'keep_aspect_ratio' ] ) {
$css_code .= sprintf( '#rpwwt-%s-%d img { max-width: %dpx; width: 100%%; height: auto; }', $this->defaults[ 'plugin_slug' ], $number, $ints[ 'thumb_width' ] );
$css_code .= "\n";
} else {
$css_code .= sprintf( '#rpwwt-%s-%d img { width: %dpx; height: %dpx; }', $this->defaults[ 'plugin_slug' ], $number, $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] );
$css_code .= "\n";
}
} else {
$css_code .= sprintf( '#rpwwt-%s-%d img { width: %dpx; height: %dpx; }', $this->defaults[ 'plugin_slug' ], $number, $ints[ 'thumb_width' ], $ints[ 'thumb_height' ] );
$css_code .= "\n";
}
// override default code
$set_default = false;
// inline CSS if at least 1 widget was set for that
if ( isset( $settings[ 'use_inline_css' ] ) ) {
$bools[ 'use_inline_css' ] = (bool) $settings[ 'use_inline_css' ];
if ( $bools[ 'use_inline_css' ] ) {
$use_inline_css = true;
}
}
} // foreach ( $all_instances as $number => $settings )
// set at least this statement if no settings are stored
if ( $set_default ) {
$css_code .= sprintf( '.rpwwt-widget ul li img { width: %dpx; height: %dpx; }', $this->defaults[ 'thumb_width' ], $this->defaults[ 'thumb_height' ] );
$css_code .= "\n";
}
return array( $css_code, $use_inline_css );
}
/**
* Returns the shortened excerpt, must use in a loop.
*
* @since 3.0
*/
private function get_the_trimmed_excerpt () {
$post = get_post();
if ( empty( $post ) ) {
return '';
}
$excerpt = '';
if ( post_password_required( $post ) ) {
$excerpt = 'There is no excerpt because this is a protected post.';
return esc_html__( $excerpt );
}
// get excerpt from text field if desired
if ( ! $this->customs[ 'ignore_excerpt' ] ) {
$excerpt = apply_filters( 'rpwwt_the_excerpt', $post->post_excerpt, $post );
}
// text processings if no manual excerpt is available
if ( empty( $excerpt ) and ! $this->customs[ 'ignore_post_content_excerpt' ] ) {
// get excerpt from post content
$excerpt = strip_shortcodes( get_the_content( '' ) );
$excerpt = apply_filters( 'the_excerpt', $excerpt );
$excerpt = str_replace( ']]>', ']]>', $excerpt );
$excerpt = wp_trim_words( $excerpt, $this->customs[ 'excerpt_length' ], $this->customs[ 'excerpt_more' ] );
// if excerpt is longer than desired
if ( mb_strlen( $excerpt ) > $this->customs[ 'excerpt_length' ] ) {
// get excerpt in desired length
$sub_excerpt = mb_substr( $excerpt, 0, $this->customs[ 'excerpt_length' ] );
// get array of shortened excerpt words
$excerpt_words = explode( ' ', $sub_excerpt );
// get the length of the last word in the shortened excerpt
$excerpt_cut = - ( mb_strlen( $excerpt_words[ count( $excerpt_words ) - 1 ] ) );
// if there is no empty string
if ( $excerpt_cut < 0 ) {
// get the shorter excerpt until the last word
$excerpt = mb_substr( $sub_excerpt, 0, $excerpt_cut );
} else {
// get the shortened excerpt
$excerpt = $sub_excerpt;
} // if ( $excerpt_cut < 0 )
} // if ( mb_strlen( $excerpt ) > $this->customs[ 'excerpt_length' ] )
} // if ( empty( $excerpt ) )
if ( $excerpt ) {
// append 'more' text, set 'more' signs as link if desired
if ( $this->customs[ 'set_more_as_link' ] ) {
$excerpt .= sprintf( '%s', get_the_permalink( $post ), $this->customs[ 'link_target' ], $this->customs[ 'excerpt_more' ] );
} else {
$excerpt .= '' . $this->customs[ 'excerpt_more' ] . '';
}
}
// return text
return $excerpt;
}
/**
* Returns the shortened post title, must use in a loop.
*
* @since 4.5
*/
private function get_the_trimmed_post_title () {
// get current post's post_title
$post_title = get_the_title();
// if post_title is longer than desired
if ( mb_strlen( $post_title ) > $this->customs[ 'post_title_length' ] ) {
// get post_title in desired length
$post_title = mb_substr( $post_title, 0, $this->customs[ 'post_title_length' ] );
// append ellipses
$post_title .= $this->defaults[ 'ellipses' ];
}
// return text
return $post_title;
}
/**
* Returns width and height of a image size name, else default sizes
*
* @since 4.0
*/
private function get_image_dimensions ( $size = 'thumbnail' ) {
$width = 0;
$height = 0;
// check if selected size is in registered images sizes
if ( in_array( $size, get_intermediate_image_sizes() ) ) {
// if in WordPress standard image sizes
if ( in_array( $size, array( 'thumbnail', 'medium', 'large' ) ) ) {
$width = get_option( $size . '_size_w' );
$height = get_option( $size . '_size_h' );
} else {
// custom image sizes, formerly added via add_image_size()
global $_wp_additional_image_sizes;
$width = $_wp_additional_image_sizes[ $size ][ 'width' ];
$height = $_wp_additional_image_sizes[ $size ][ 'height' ];
}
}
// check if vars have true values, else use default size
if ( ! $width ) $width = $this->defaults[ 'thumb_width' ];
if ( ! $height ) $height = $this->defaults[ 'thumb_height' ];
// return sizes
return array( $width, $height );
}
/**
* Shows sticky posts on top of categories list
*
* @since 6.2.1
*/
public function get_stickies_on_top( $posts ) {
// get sticky post IDs
$sticky_posts = get_option( 'sticky_posts' );
// initialize variables for the correct number of posts in the result list
$num_posts = count( $posts );
$sticky_offset = 0;
// loop over posts and relocate stickies to the front
for( $i = 0; $i < $num_posts; $i++ ) {
// if sticky post
if ( in_array( $posts[ $i ]->ID, $sticky_posts ) ) {
$sticky_post = $posts[ $i ];
// remove sticky post from current position
array_splice( $posts, $i, 1 );
// move to front, after other stickies
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
// increment the sticky offset. the next sticky will be placed at this offset.
$sticky_offset++;
// remove post from sticky posts array
//$offset = array_search( $sticky_post->ID, $sticky_posts );
//unset( $sticky_posts[ $offset ] );
} // if ( in_array( $posts[ $i ]->ID, $sticky_posts ) )
} // for()
// return new list
return $posts;
}
/**
* Returns the ARIA label for the NAV element
*
* @since 6.7.1
*/
private function get_aria_nav_label( $title ) {
// the title may be filtered: Strip out HTML
$title = trim( strip_tags( $title ) );
// and make sure the aria-label is never empty
return $title ? $title : $this->defaults[ 'nav_label' ];
}
}
/**
* Register widget on init
*
* @since 1.0
*/
function register_recent_posts_widget_with_thumbnails () {
register_widget( 'Recent_Posts_Widget_With_Thumbnails' );
}
add_action( 'widgets_init', 'register_recent_posts_widget_with_thumbnails', 1 );