Skip to content
Snippets Groups Projects

v0.3

Merged Erick Hitter requested to merge fix/phpcs into master
Files
10
+ 268
0
<?php
/**
* Plugin functionality.
*
* @package ETH_Redirect_To_Latest_Post
*/
/**
* Class ETH_Redirect_To_Latest_Post.
*/
class ETH_Redirect_To_Latest_Post {
/**
* PLUGIN SETUP
*/
/**
* Singleton.
*
* @var self
*/
private static $instance;
/**
* Instantiate singleton.
*/
public static function get_instance() {
if ( ! is_a( self::$instance, __CLASS__ ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Dummy magic method.
*/
public function __clone() {
_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; uh?', 'eth_redirect_to_latest_post' ), '0.1' );
}
/**
* Dummy magic method.
*/
public function __wakeup() {
_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; uh?', 'eth_redirect_to_latest_post' ), '0.1' );
}
/**
* Dummy magic method.
*
* @param string $name Method name.
* @param array $args Method arguments.
* @return null
*/
public function __call( $name = '', $args = array() ) {
return null;
}
/**
* Plugin's option name.
*
* @var string
*/
private $plugin_option_name = 'eth-redirect-to-latest';
/**
* Plugin's slug.
*
* @var string
*/
private $slug = '';
/**
* Plugin's fallback slug.
*
* @var string
*/
private $default_slug = '';
/**
* Register plugin's setup action.
*/
private function __construct() {
add_action( 'init', array( $this, 'action_init' ) );
add_action( 'parse_request', array( $this, 'action_parse_request' ) );
add_action( 'admin_init', array( $this, 'action_admin_init' ) );
}
/**
* Translate plugin slug.
*/
public function action_init() {
$this->default_slug = __( 'latest', 'eth_redirect_to_latest_post' );
$_slug = get_option( $this->plugin_option_name, $this->default_slug );
if ( is_string( $_slug ) && ! empty( $_slug ) ) {
$this->slug = $_slug;
}
if ( empty( $this->slug ) ) {
$this->slug = $this->default_slug;
}
}
/**
* Redirect to the latest post any requests made to plugin's slug.
*
* @param WP $r WP object.
*/
public function action_parse_request( $r ) {
// Nothing to do if permalinks aren't enabled.
if ( ! $r->did_permalink ) {
return;
}
$redirect = $this->get_redirect_for_request( $r );
if ( null === $redirect ) {
return;
}
header( 'x-redirect: eth-redirect-to-latest-post' );
// Not validating in case other plugins redirect elsewhere.
// phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
wp_redirect( $redirect->destination, $redirect->status_code );
exit;
}
/**
* Parse the request to determine its redirect, if any.
*
* @param WP $r WP object.
* @return \stdClass|null
*/
public function get_redirect_for_request( $r ) {
/**
* Check if request is for our slug.
*
* The first condition catches hierarchical permastructs, while
* the second catches non-hierarchical permastructs.
*/
if ( isset( $r->query_vars['pagename'] ) && $this->slug === $r->query_vars['pagename'] ) {
$should_intercept = true;
} elseif ( isset( $r->query_vars['name'] ) && $this->slug === $r->query_vars['name'] ) {
$should_intercept = true;
} else {
$should_intercept = false;
}
if ( ! $should_intercept ) {
return null;
}
$redirect = array(
'destination' => '',
'status_code' => 302,
);
$query_args = array(
'posts_per_page' => 1,
'post_type' => 'post',
'orderby' => 'date',
'order' => 'desc',
'suppress_filters' => false,
'no_found_rows' => true,
);
/**
* Filters the query arguments that determine
* the latest post.
*
* @param array $query_args WP_Query arguments.
* @param WP $r WP Object.
* @return array
*/
$query_args = apply_filters( 'eth_redirect_to_latest_post_query_args', $query_args, $r );
$latest = get_posts( $query_args );
if ( is_array( $latest ) && ! empty( $latest ) ) {
$latest = array_shift( $latest );
$redirect['destination'] = get_permalink( $latest->ID );
}
if ( empty( $redirect['destination'] ) ) {
$redirect['destination'] = user_trailingslashit( home_url() );
}
/**
* Filters the redirection data.
*
* @param array $redirect Array of redirect destination and status code.
* @param array|WP_Post $latest Post object or empty array if no posts found.
* @param WP $r WP object.
* @return array|null
*/
$redirect = apply_filters( 'eth_redirect_to_latest_post_redirection', $redirect, $latest, $r );
if ( null === $redirect ) {
return null;
}
return (object) $redirect;
}
/**
* ADMIN OPTIONS
*/
/**
* Save plugin settings and register settings field
*
* Permalinks screen is a snowflake, hence the custom saving handler.
*/
public function action_admin_init() {
// Make sure user has necessary permissions first.
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Save custom option, permalinks screen is a snowflake and doesn't fully use the Settings API.
global $pagenow;
if ( 'options-permalink.php' === $pagenow && isset( $_POST[ $this->plugin_option_name ] ) ) {
check_admin_referer( 'update-permalink' );
$_slug = sanitize_text_field( $_POST[ $this->plugin_option_name ] );
if ( empty( $_slug ) ) {
$_slug = $this->default_slug;
}
update_option( $this->plugin_option_name, $_slug );
}
// Add custom input field to permalinks screen.
add_settings_field( $this->plugin_option_name, __( '&quot;Latest post&quot; slug', 'eth_redirect_to_latest_post' ), array( $this, 'settings_field' ), 'permalink', 'optional' );
}
/**
* Render settings field.
*/
public function settings_field() {
?>
<input type="text" name="<?php echo esc_attr( $this->plugin_option_name ); ?>" value="<?php echo esc_attr( $this->slug ); ?>" class="regular-text" />
<p class="description">
<?php
printf(
/* translators: 1. Default slug, wrapped in a <code> tag. */
esc_html__(
'Set the slug that will redirect to the latest published post. The default value is %s.',
'eth_redirect_to_latest_post'
),
'<code style="font-style: normal;">' . esc_html( $this->default_slug ) . '</code>'
);
?>
</p>
<?php
}
}
/**
* One instance to rule them all.
*/
ETH_Redirect_To_Latest_Post::get_instance();
Loading