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() { } /** * Cache the REST response. * * @since 1.0 * * @param string $url * @param array $response * @param float|int $timeout */ protected function setCache( $url, $response, $timeout = DAY_IN_SECONDS ) { set_transient( $this->cacheKey( $url ), $response, $timeout ); } /** * Get cached REST response. * * @since 1.0 * * @param string $url * * @return array|false */ protected function getCache( $url ) { if ( is_array( $response = get_transient( $this->cacheKey( $url ) ) ) ) { return $response; } return FALSE; } /** * Clear cache. * * @since 1.0 * * @param string $url */ public function clearCache( $url ){ delete_transient( $this->cacheKey( $url ) ); } /** * Create cache key based on URL. * * @since 1.0 * * @param string $url * * @return string */ protected function cacheKey( $url ) { return md5( preg_replace( '(^https?://)', '', $url ) ); } /** * 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, 'cache_timeout' => DAY_IN_SECONDS, ); $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 ); } if ( 0 >= $atts['cache_timeout'] ) { $this->clearCache( $url ); } if ( FALSE === $response = $this->getCache( $url ) ) { $response = wp_safe_remote_get( $url ); if ( ! is_wp_error( $response ) && 0 < $atts['cache_timeout'] ) { /* * NOTE: cache will be saved during Gutenberg autosaves via the REST API. */ $this->setCache( $url, $response, $atts['cache_timeout'] ); } } if ( is_wp_error( $response ) ) { return $response; } $posts = json_decode( wp_remote_retrieve_body( $response ) ); 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', 'cache_timeout' => DAY_IN_SECONDS, ); } /** * 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'] ); $atts['cache_timeout'] = absint( $atts['cache_timeout'] ); 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 '