mirror of
https://github.com/10h30/Display-Posts-Shortcode-Remote.git
synced 2026-06-05 15:07:31 +09:00
Initial commit.
This commit is contained in:
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Display Posts Shortcode - Remote
|
||||
* @category Extension
|
||||
* @author Steven A. Zahm
|
||||
* @license GPL-2.0+
|
||||
* @link https://connections-pro.com
|
||||
* @copyright 2018 Steven A. Zahm
|
||||
*
|
||||
* @wordpress-plugin
|
||||
* Plugin Name: Display Posts Shortcode - Remote
|
||||
* Plugin URI: https://connections-pro.com/
|
||||
* Description: An extension for the Display Posts Shortcode plugin which adds a shortcode for displaying posts from a remote WordPress site.
|
||||
* Version: 1.0
|
||||
* Author: Steven A. Zahm
|
||||
* Author URI: https://connections-pro.com
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
* Text Domain: display-posts-shortcode-remote
|
||||
* Domain Path: /languages
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'Display_Posts_Remote' ) ) {
|
||||
|
||||
final class Display_Posts_Remote {
|
||||
|
||||
const VERSION = '1.0';
|
||||
|
||||
/**
|
||||
* @var Display_Posts_Remote Stores the instance of this class.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @var string The absolute path this this file.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private $file = '';
|
||||
|
||||
/**
|
||||
* @var string The URL to the plugin's folder.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private $url = '';
|
||||
|
||||
/**
|
||||
* @var string The absolute path to this plugin's folder.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private $path = '';
|
||||
|
||||
/**
|
||||
* @var string The basename of the plugin.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private $basename = '';
|
||||
|
||||
/**
|
||||
* A dummy constructor to prevent the class from being loaded more than once.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function __construct() { /* Do nothing here */ }
|
||||
|
||||
/**
|
||||
* The main Connection Form plugin instance.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function instance() {
|
||||
|
||||
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {
|
||||
|
||||
self::$instance = $self = new self;
|
||||
|
||||
$self->file = __FILE__;
|
||||
$self->url = plugin_dir_url( $self->file );
|
||||
$self->path = plugin_dir_path( $self->file );
|
||||
$self->basename = plugin_basename( $self->file );
|
||||
|
||||
$self->includes();
|
||||
$self->hooks();
|
||||
//$self->registerJavaScripts();
|
||||
//$self->registerCSS();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include the dependencies.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private function includes() {
|
||||
|
||||
require_once( 'includes/class.wp-rest-post.php');
|
||||
require_once( 'includes/class.wp-rest-add-featured-image.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the plugins actions/filters.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
add_shortcode( 'display-posts-remote', array( __CLASS__, 'shortcode' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin's bas URL.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function getURL() {
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the plugin's JavaScript.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private function registerJavaScripts() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the plugin's JavaScript.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function enqueueJS() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the plugin's CSS.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private function registerCSS() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the plugin's JavaScript.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function enqueueCSS() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a remote site's posts.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $untrusted
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function getPosts( $untrusted ) {
|
||||
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'category_id' => 0,
|
||||
);
|
||||
|
||||
$atts = shortcode_atts( $defaults, $untrusted );
|
||||
|
||||
$atts['url'] = esc_url( filter_var( $atts['url'], FILTER_SANITIZE_URL ) );
|
||||
|
||||
if ( 0 >= strlen( $atts['url'] ) ) {
|
||||
|
||||
return new WP_Error(
|
||||
'invalid_url',
|
||||
__( 'Remote site URL must be provided.', 'display-posts-shortcode-remote' ),
|
||||
$atts['url']
|
||||
);
|
||||
}
|
||||
|
||||
$url = trailingslashit( $atts['url'] ) . 'wp-json/wp/v2/posts';
|
||||
$url = add_query_arg( '_embed' , '', $url );
|
||||
|
||||
if ( ! empty( $atts['category_id'] ) ) {
|
||||
|
||||
$url = add_query_arg( 'categories', $atts['category_id'], $url );
|
||||
}
|
||||
|
||||
$request = wp_safe_remote_get( $url );
|
||||
|
||||
if ( is_wp_error( $request ) ) {
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
$posts = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
|
||||
if ( JSON_ERROR_NONE !== json_last_error() ) {
|
||||
|
||||
return new WP_Error(
|
||||
'invalid_response',
|
||||
json_last_error_msg(),
|
||||
$posts
|
||||
);
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* The shortcode default options/values.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaults() {
|
||||
|
||||
return array(
|
||||
'category_id' => 0,
|
||||
'content_class' => 'content',
|
||||
'date_format' => '(n/j/Y)',
|
||||
'include_content' => FALSE,
|
||||
'include_date' => FALSE,
|
||||
'include_date_modified' => FALSE,
|
||||
'include_link' => TRUE,
|
||||
'include_title' => TRUE,
|
||||
'image_size' => 'thumbnail',
|
||||
'url' => '',
|
||||
'wrapper' => 'ul',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and sanitize the user supplied shortcode values.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $untrusted The user defined shortcode attributes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parseShortcodeAtts( $untrusted ) {
|
||||
|
||||
$defaults = Display_Posts_Remote()->getDefaults();
|
||||
$atts = shortcode_atts( $defaults, $untrusted, 'display-posts-remote' );
|
||||
|
||||
$atts['category_id'] = absint( $atts['category_id'] );
|
||||
$atts['content_class'] = array_map( 'sanitize_html_class', ( explode( ' ', $atts['content_class'] ) ) );
|
||||
$atts['date_format'] = sanitize_text_field( $atts['date_format'] );
|
||||
$atts['include_content'] = self::toBoolean( $atts['include_content'] );
|
||||
$atts['include_date'] = self::toBoolean( $atts['include_date'] );
|
||||
$atts['include_date_modified'] = self::toBoolean( $atts['include_date_modified'] );
|
||||
$atts['include_link'] = self::toBoolean( $atts['include_link'] );
|
||||
$atts['include_title'] = self::toBoolean( $atts['include_title'] );
|
||||
$atts['image_size'] = sanitize_key( $atts['image_size'] );
|
||||
$atts['url'] = filter_var( $atts['url'], FILTER_SANITIZE_URL );
|
||||
$atts['wrapper'] = sanitize_text_field( $atts['wrapper'] );
|
||||
|
||||
return $atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the `display-posts-remote` shortcode.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $untrusted
|
||||
* @param string $content
|
||||
* @param string $tag
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function shortcode( $untrusted, $content, $tag = 'display-posts-remote' ) {
|
||||
|
||||
$self = Display_Posts_Remote();
|
||||
|
||||
$html = '';
|
||||
$atts = $self->parseShortcodeAtts( $untrusted );
|
||||
|
||||
$result = $self->getPosts( $atts );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
|
||||
return '<div>' . $result->get_error_message() . '</div>';
|
||||
}
|
||||
|
||||
if ( empty( $result ) || ! is_array( $result ) ) {
|
||||
|
||||
return '<div>' . __( 'No posts to display.', 'display-posts-shortcode-remote' ) . '</div>';
|
||||
}
|
||||
|
||||
// Set up html elements used to wrap the posts.
|
||||
// Default is ul/li, but can also be ol/li and div/div.
|
||||
if ( ! in_array( $atts['wrapper'], array( 'ul', 'ol', 'div' ) ) ) {
|
||||
|
||||
$atts['wrapper'] = 'ul';
|
||||
}
|
||||
|
||||
$itemElement = 'div' === $atts['wrapper'] ? 'div' : 'li';
|
||||
|
||||
foreach ( $result as $data ) {
|
||||
|
||||
$image = $date = $postContent = '';
|
||||
|
||||
$post = new Display_Posts_Remote_Post( $data );
|
||||
|
||||
if ( $atts['include_title'] && $atts['include_link'] ) {
|
||||
|
||||
$title = '<span class="title"><a href="' . esc_url( $post->get_permalink() ) . '">' . esc_attr( strip_tags( $post->get_the_title() ) ) . '</a></span>';
|
||||
|
||||
} elseif ( $atts['include_title'] ) {
|
||||
|
||||
$title = '<span class="title">' . esc_attr( strip_tags( $post->get_the_title() ) ) . '</span>';
|
||||
|
||||
} else {
|
||||
|
||||
$title = '';
|
||||
}
|
||||
|
||||
$imageAttributes = $self->getImageAttributes( $atts );
|
||||
|
||||
if ( $atts['image_size'] && $post->has_post_thumbnail() && $atts['include_link'] ) {
|
||||
|
||||
$image = '<a class="image" href="' . esc_url( $post->get_permalink() ) . '">' . $post->get_the_post_thumbnail( $atts['image_size'], $imageAttributes ) . '</a> ';
|
||||
|
||||
} elseif ( $atts['image_size'] && $post->has_post_thumbnail() ) {
|
||||
|
||||
$image = '<span class="image">' . $post->get_the_post_thumbnail( $atts['image_size'], $imageAttributes ) . '</span> ';
|
||||
|
||||
} elseif ( $post->has_featured_media() && $atts['include_link'] ) {
|
||||
|
||||
$image = '<a class="image" href="' . esc_url( $post->get_permalink() ) . '">' . $post->get_the_post_thumbnail( 'full', $imageAttributes ) . '</a> ';
|
||||
|
||||
} elseif ( $post->has_featured_media() ) {
|
||||
|
||||
$image = '<span class="image">' . $post->get_the_post_thumbnail( 'full', $imageAttributes ) . '</span> ';
|
||||
|
||||
}
|
||||
|
||||
if ( $atts['include_date'] ) {
|
||||
|
||||
$date = ' <span class="date">' . $post->get_the_date( $atts['date_format'] ) . '</span>';
|
||||
|
||||
} elseif ( $atts['include_date_modified'] ) {
|
||||
|
||||
$date = ' <span class="date">' . $post->get_the_modified_date( $atts['date_format'] ) . '</span>';
|
||||
}
|
||||
|
||||
if ( $atts['include_content'] ) {
|
||||
|
||||
$postContent = '<div class="' . implode( ' ', $atts['content_class'] ) . '">' . $post->get_the_content() . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the HTML markup for output via the shortcode.
|
||||
*
|
||||
* Use the same filter name and pass the same values so existing filters work on DPS Remote.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $html The shortcode's HTML output.
|
||||
* @param array $original_atts Original attributes passed to the shortcode.
|
||||
* @param string $image HTML markup for the post's featured image element.
|
||||
* @param string $title HTML markup for the post's title element.
|
||||
* @param string $date HTML markup for the post's date element.
|
||||
* @param string $excerpt HTML markup for the post's excerpt element.
|
||||
* @param string $inner_wrapper Type of container to use for the post's inner wrapper element.
|
||||
* @param string $content The post's content.
|
||||
* @param string $class Space-separated list of post classes to supply to the $inner_wrapper element.
|
||||
* @param string $author HTML markup for the post's author.
|
||||
* @param string $category_display_text
|
||||
*/
|
||||
$html .= apply_filters(
|
||||
'display_posts_shortcode_output',
|
||||
"<{$itemElement} class=\"listing-item\">{$image}{$title}{$date}{$postContent}</{$itemElement}>" . PHP_EOL,
|
||||
array(), // $original_atts
|
||||
$image,
|
||||
$title,
|
||||
$date,
|
||||
'', // $excerpt
|
||||
$itemElement, // $inner_wrapper
|
||||
$postContent, // $content
|
||||
array( 'listing-item' ), // $class
|
||||
'', // $author
|
||||
'' // $category_display_text
|
||||
);
|
||||
}
|
||||
|
||||
$open = "<{$atts['wrapper']} class=\"display-posts-listing\">" . PHP_EOL;
|
||||
$close = "</{$atts['wrapper']}>" . PHP_EOL;
|
||||
|
||||
return $open . $html . $close;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image attributes that should be applied ti the image tags.
|
||||
*
|
||||
* This is primarily to support DPS Pinch Zoomer add on.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $atts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getImageAttributes( $atts = array() ) {
|
||||
|
||||
$attributes = array();
|
||||
|
||||
/*
|
||||
* Support DPS Pinch Zoomer.
|
||||
*/
|
||||
if ( function_exists( 'Display_Posts_Pinch_Zoomer' ) ) {
|
||||
|
||||
$options = Display_Posts_Pinch_Zoomer()->shortcodeAtts( $atts );
|
||||
$attributes = Display_Posts_Pinch_Zoomer()->postImageAttributes( $options );
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the following strings: yes/no; true/false and 0/1 to boolean values.
|
||||
* If the supplied string does not match one of those values the method will return NULL.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string|int|bool $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function toBoolean( &$value ) {
|
||||
|
||||
// Already a bool, return it.
|
||||
if ( is_bool( $value ) ) return $value;
|
||||
|
||||
$value = filter_var( strtolower( $value ), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
|
||||
|
||||
if ( is_null( $value ) ) {
|
||||
|
||||
$value = FALSE;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.0
|
||||
*
|
||||
* @return Display_Posts_Remote
|
||||
*/
|
||||
function Display_Posts_Remote() {
|
||||
|
||||
return Display_Posts_Remote::instance();
|
||||
}
|
||||
|
||||
Display_Posts_Remote();
|
||||
}
|
||||
Reference in New Issue
Block a user