Commit a16fb52d authored by Erick Hitter's avatar Erick Hitter

PHPCS

parent 6ef259b4
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<!-- Rules: WordPress Coding Standards --> <!-- Rules: WordPress Coding Standards -->
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards --> <!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards -->
<!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties --> <!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties -->
<config name="minimum_supported_wp_version" value="3.2.1"/> <config name="minimum_supported_wp_version" value="4.4"/>
<rule ref="WordPress" /> <rule ref="WordPress" />
<rule ref="WordPressVIPMinimum" /> <rule ref="WordPressVIPMinimum" />
<rule ref="WordPress-VIP-Go" /> <rule ref="WordPress-VIP-Go" />
......
<?php
/**
* Load ETH Simple Shortlinks.
*
* @package ETH_Simple_Shortlinks
*/
/**
* Plugin Name: ETH Simple Shortlinks
* Plugin URI: https://ethitter.com/plugins/
* Description: Simple non-GET shortlinks using post IDs
* Author: Erick Hitter
* Version: 0.5
* Author URI: https://ethitter.com/
* Text Domain: eth_simple_shortlinks
* Domain Path: /languages/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
require_once __DIR__ . '/inc/class-eth-simple-shortlinks.php';
<?php <?php
/* /**
Plugin Name: ETH Simple Shortlinks * Plugin functionality.
Plugin URI: https://ethitter.com/plugins/ *
Description: Simple non-GET shortlinks using post IDs * @package ETH_Simple_Shortlinks
Author: Erick Hitter */
Version: 0.5
Author URI: https://ethitter.com/
Text Domain: eth_simple_shortlinks
Domain Path: /languages/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Class ETH_Simple_Shortlinks.
*/
class ETH_Simple_Shortlinks { class ETH_Simple_Shortlinks {
/** /**
* PLUGIN SETUP * PLUGIN SETUP
...@@ -31,6 +15,8 @@ class ETH_Simple_Shortlinks { ...@@ -31,6 +15,8 @@ class ETH_Simple_Shortlinks {
/** /**
* Singleton * Singleton
*
* @var self
*/ */
private static $instance = null; private static $instance = null;
...@@ -39,115 +25,204 @@ class ETH_Simple_Shortlinks { ...@@ -39,115 +25,204 @@ class ETH_Simple_Shortlinks {
*/ */
public static function get_instance() { public static function get_instance() {
if ( ! is_a( self::$instance, __CLASS__ ) ) { if ( ! is_a( self::$instance, __CLASS__ ) ) {
self::$instance = new self; self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
/** /**
* Dummy magic methods * Dummy magic method
*/ */
public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; uh?', 'eth_simple_shortlinks' ), '0.1' ); } public function __clone() {
public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; uh?', 'eth_simple_shortlinks' ), '0.1' ); } _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; uh?', 'eth_simple_shortlinks' ), '0.1' );
public function __call( $name = '', $args = array() ) { unset( $name, $args ); return null; } }
/** /**
* Class properties * Dummy magic method
*/ */
private $name = 'ETH Simple Shortlinks'; public function __wakeup() {
private $slug = 'p'; _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; uh?', 'eth_simple_shortlinks' ), '0.1' );
private $rewrite_rule = null; }
private $rewrite_match = null;
private $qv = 'eth-shortlink';
/**
* Dummy magic method
*
* @param string $name Method name.
* @param array $args Method arguments.
* @return null
*/
public function __call( $name = '', $args = array() ) {
return null;
}
/**
* Plugin name.
*
* @var string
*/
private $name = 'ETH Simple Shortlinks';
/**
* Rewrite slug.
*
* @var string
*/
private $slug = 'p';
/**
* Rewrite rule.
*
* @var string
*/
private $rewrite_rule;
/**
* Rewrite rule match.
*
* @var string
*/
private $rewrite_match;
/**
* Query variable.
*
* @var string
*/
private $qv = 'eth-shortlink';
/**
* Is environment ready?
*
* @var bool
*/
private $plugin_supported = false; private $plugin_supported = false;
private $supported_post_types = array(); /**
* Post types supported by the plugin.
*
* @var array
*/
private $supported_post_types = array();
/**
* Post statuses allowed to redirect to.
*
* @var array
*/
private $supported_post_statuses = array(); private $supported_post_statuses = array();
/** /**
* Register plugin's setup action * Register plugin's setup action.
*/ */
private function __construct() { private function __construct() {
// Build rewrite parts using other class properties // Build rewrite parts using other class properties.
$this->rewrite_rule = '^' . $this->slug . '/([\d]+)/?$'; $this->rewrite_rule = '^' . $this->slug . '/([\d]+)/?$';
$this->rewrite_match = 'index.php?p=$matches[1]&' . $this->qv . '=1'; $this->rewrite_match = 'index.php?p=$matches[1]&' . $this->qv . '=1';
// Basic plugin actions // Basic plugin actions.
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) ); add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
add_action( 'init', array( $this, 'action_init' ) ); add_action( 'init', array( $this, 'action_init' ) );
} }
/** /**
* Load plugin translations * Load plugin translations.
*/ */
public function action_plugins_loaded() { public function action_plugins_loaded() {
load_plugin_textdomain( 'eth_simple_shortlinks', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); load_plugin_textdomain(
'eth_simple_shortlinks',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages/'
);
} }
/** /**
* Verify plugin is supported, then register its functionality * Verify plugin is supported, then register its functionality.
*/ */
public function action_init() { public function action_init() {
global $wp_rewrite; global $wp_rewrite;
// Plugin won't work if site doesn't use pretty permalinks // Plugin won't work if site doesn't use pretty permalinks.
if ( empty( $wp_rewrite->permalink_structure ) ) { if ( empty( $wp_rewrite->permalink_structure ) ) {
add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) ); add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) );
} else { return;
$this->plugin_supported = true; }
// Admin notices $this->plugin_supported = true;
add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) );
// Register rewrite rule // Admin notices.
add_rewrite_rule( $this->rewrite_rule, $this->rewrite_match, 'top' ); add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) );
// Request handling // Register rewrite rule.
add_action( 'wp_loaded', array( $this, 'filter_support' ) ); add_rewrite_rule( $this->rewrite_rule, $this->rewrite_match, 'top' );
add_filter( 'query_vars', array( $this, 'filter_query_vars' ) );
add_action( 'parse_request', array( $this, 'action_parse_request' ) );
// Shortlink overrides // Request handling.
add_filter( 'get_shortlink', array( $this, 'filter_get_shortlink' ), 10, 2 ); add_action( 'wp_loaded', array( $this, 'filter_support' ) );
add_action( 'admin_head-edit.php', array( $this, 'add_admin_header_assets' ) ); add_filter( 'query_vars', array( $this, 'filter_query_vars' ) );
add_filter( 'post_row_actions', array( $this, 'filter_row_actions' ), 10, 2 ); add_action( 'parse_request', array( $this, 'action_parse_request' ) );
add_filter( 'page_row_actions', array( $this, 'filter_row_actions' ), 10, 2 );
} // Shortlink overrides.
add_filter( 'get_shortlink', array( $this, 'filter_get_shortlink' ), 10, 2 );
add_action( 'admin_head-edit.php', array( $this, 'add_admin_header_assets' ) );
add_filter( 'post_row_actions', array( $this, 'filter_row_actions' ), 10, 2 );
add_filter( 'page_row_actions', array( $this, 'filter_row_actions' ), 10, 2 );
} }
/** /**
* Display admin notices if plugin's requirements aren't met * Display admin notices if plugin's requirements aren't met.
*/ */
public function action_add_admin_notices() { public function action_add_admin_notices() {
// Notices are only relevant if current user can get to the Permalinks and Plugins options screens // Notices are only relevant if current user can get to the Permalinks and Plugins options screens.
if ( ! current_user_can( 'manage_options') || ! current_user_can( 'activate_plugins' ) ) { if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'activate_plugins' ) ) {
return; return;
} }
// Build notices // Build notices.
$message = ''; $message = '';
if ( $this->plugin_supported ) { if ( $this->plugin_supported ) {
// Check option for the plugin's rule // Check option for the plugin's rule.
// The `$wp_rewrite` global will include it in `extra_rules_top` even though it hasn't been saved to the DB, and therefore isn't really active. // The `$wp_rewrite` global will include it in `extra_rules_top` even though it hasn't been saved to the DB, and therefore isn't really active.
$rewrites = get_option( 'rewrite_rules' ); $rewrites = get_option( 'rewrite_rules' );
if ( is_array( $rewrites ) && ! array_key_exists( $this->rewrite_rule, $rewrites ) ) { if ( is_array( $rewrites ) && ! array_key_exists( $this->rewrite_rule, $rewrites ) ) {
$message = sprintf( __( 'Please visit the <a href="%1$s">Permalinks</a> settings page to refresh your permalinks. Doing so will add the rules this plugin requires.', 'eth_simple_shortlinks' ), admin_url( 'options-permalink.php' ) ); $message = sprintf(
/* translators: 1: URL of permalink options page. */
__(
'Please visit the <a href="%1$s">Permalinks</a> settings page to refresh your permalinks. Doing so will add the rules this plugin requires.',
'eth_simple_shortlinks'
),
admin_url( 'options-permalink.php' )
);
} }
} else { } else {
$message = sprintf( __( 'Please enable <a href="%1$s">pretty permalinks</a>, otherwise disable this plugin as it is not compatible with "Plain" permalinks.', 'eth_simple_shortlinks' ), admin_url( 'options-permalink.php' ) ); $message = sprintf(
/* translators: 1: URL of permalink options page. */
__(
'Please enable <a href="%1$s">pretty permalinks</a>, otherwise disable this plugin as it is not compatible with "Plain" permalinks.',
'eth_simple_shortlinks'
),
admin_url( 'options-permalink.php' )
);
} }
// Display a notice if one exists // Display a notice if one exists.
if ( ! empty( $message ) ) { if ( ! empty( $message ) ) {
$message = sprintf( __( '<strong>%1$s</strong>: %2$s', 'eth_simple_shortlinks' ), $this->name, $message ); $message = sprintf(
/* translators: 1: Plugin name, 2: Notice text. */
?><div class="error"> __(
<p><?php echo $message; ?></p> '<strong>%1$s</strong>: %2$s',
</div><?php 'eth_simple_shortlinks'
),
$this->name,
$message
);
?>
<div class="error">
<p><?php echo wp_kses_post( $message ); ?></p>
</div>
<?php
} }
} }
...@@ -156,15 +231,29 @@ class ETH_Simple_Shortlinks { ...@@ -156,15 +231,29 @@ class ETH_Simple_Shortlinks {
*/ */
/** /**
* Allow filtering of supported statuses and types * Allow filtering of supported statuses and types.
*/ */
public function filter_support() { public function filter_support() {
/**
* Filters supported post statuses.
*
* @param array $statuses Supported statuses.
*/
$this->supported_post_statuses = apply_filters( 'eth_simple_shortlinks_allowed_post_statuses', array( 'publish', 'future' ) ); $this->supported_post_statuses = apply_filters( 'eth_simple_shortlinks_allowed_post_statuses', array( 'publish', 'future' ) );
$this->supported_post_types = apply_filters( 'eth_simple_shortlinks_allowed_post_types', array( 'post', 'page' ) );
/**
* Filters supported post types.
*
* @param array $types Post types.
*/
$this->supported_post_types = apply_filters( 'eth_simple_shortlinks_allowed_post_types', array( 'post', 'page' ) );
} }
/** /**
* Add custom query var to those permitted, so it can be detected at `parse_request` * Add custom query var to those permitted, so it can be detected at `parse_request`.
*
* @param array $qv Registered query vars.
* @return array
*/ */
public function filter_query_vars( $qv ) { public function filter_query_vars( $qv ) {
$qv[] = $this->qv; $qv[] = $this->qv;
...@@ -173,25 +262,50 @@ class ETH_Simple_Shortlinks { ...@@ -173,25 +262,50 @@ class ETH_Simple_Shortlinks {
} }
/** /**
* Catch this plugin's requests and issue redirects, otherwise WP will serve content at duplicate URLs * Catch this plugin's requests and issue redirects, otherwise WP
* will serve content at duplicate URLs.
* *
* Allows invalid post IDs fall through to WP's 404 handler, or anything else that might intercede * Allows invalid post IDs fall through to WP's 404 handler, or
* anything else that might intercede.
* *
* URLs aren't validated in case plugins filter permalinks to point to external URLs * @param WP $request WP object.
*/ */
public function action_parse_request( $request ) { public function action_parse_request( $request ) {
if ( isset( $request->query_vars[ $this->qv ] ) ) { if ( isset( $request->query_vars[ $this->qv ] ) ) {
$dest = get_permalink( $request->query_vars[ 'p' ] ); $dest = get_permalink( $request->query_vars['p'] );
if ( $dest ) { if ( $dest ) {
wp_redirect( $dest, 301 ); /**
* Filters the redirect URL.
*
* @param string $dest Redirect destination.
* @param WP $request WP object.
*/
$dest = apply_filters( 'eth_simple_shortlinks_redirect_url', $dest, $request );
/**
* Filters the redirect status code.
*
* @param int $status_code Redirect status code.
* @param string $dest Redirect destination.
* @param WP $request WP object.
*/
$status_code = (int) apply_filters( 'eth_simple_shortlinks_redirect_status', 301, $dest, $request );
// URLs aren't validated in case plugins filter permalinks to point to external URLs.
// phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
wp_redirect( $dest, $status_code );
exit; exit;
} }
} }
} }
/** /**
* Override shortlinks with this plugin's format * Override shortlinks with this plugin's format.
*
* @param string $shortlink Short URL.
* @param int $id Post ID.
* @return string
*/ */
public function filter_get_shortlink( $shortlink, $id ) { public function filter_get_shortlink( $shortlink, $id ) {
if ( empty( $id ) ) { if ( empty( $id ) ) {
...@@ -218,7 +332,7 @@ class ETH_Simple_Shortlinks { ...@@ -218,7 +332,7 @@ class ETH_Simple_Shortlinks {
} }
/** /**
* Header assets for shortlink in row actions * Header assets for shortlink in row actions.
*/ */
public function add_admin_header_assets() { public function add_admin_header_assets() {
global $typenow; global $typenow;
...@@ -241,7 +355,11 @@ class ETH_Simple_Shortlinks { ...@@ -241,7 +355,11 @@ class ETH_Simple_Shortlinks {
} }
/** /**
* Provide the shortlink in row actions for easy access * Provide the shortlink in row actions for easy access.
*
* @param array $actions Row actions.
* @param WP_Post $post Post object.
* @return array
*/ */
public function filter_row_actions( $actions, $post ) { public function filter_row_actions( $actions, $post ) {
if ( ! $this->is_supported_post_type( get_post_type( $post ) ) || ! $this->is_supported_post_status( get_post_status( $post ) ) ) { if ( ! $this->is_supported_post_type( get_post_type( $post ) ) || ! $this->is_supported_post_status( get_post_status( $post ) ) ) {
...@@ -254,24 +372,33 @@ class ETH_Simple_Shortlinks { ...@@ -254,24 +372,33 @@ class ETH_Simple_Shortlinks {
} }
/** /**
* Check if given post type is supported * Check if given post type is supported.
*
* @param string $type Post type.
* @return bool
*/ */
private function is_supported_post_type( $type ) { private function is_supported_post_type( $type ) {
return in_array( $type, $this->supported_post_types ); return in_array( $type, $this->supported_post_types, true );
} }
/** /**
* Check if given post status is supported * Check if given post status is supported.
*
* @param string $status Post status.
* @return bool
*/ */
private function is_supported_post_status( $status ) { private function is_supported_post_status( $status ) {
return in_array( $status, $this->supported_post_statuses ); return in_array( $status, $this->supported_post_statuses, true );
} }
/** /**
* Utility method for building permlink * Utility method for building permalink.
*
* @param int $post_id Post ID.
* @return string
*/ */
public function get_shortlink( $post_id ) { public function get_shortlink( $post_id ) {
// Use Core's default when this plugin can't build a link // Use Core's default when this plugin can't build a link.
if ( ! $this->plugin_supported ) { if ( ! $this->plugin_supported ) {
return wp_get_shortlink( $post_id ); return wp_get_shortlink( $post_id );
} }
...@@ -286,11 +413,24 @@ class ETH_Simple_Shortlinks { ...@@ -286,11 +413,24 @@ class ETH_Simple_Shortlinks {
ETH_Simple_Shortlinks::get_instance(); ETH_Simple_Shortlinks::get_instance();
/** /**
* Shortcut for using the shortlink outside of this plugin's considerations * Shortcut for using the shortlink outside of this plugin's considerations.
*
* @param int $post_id Post ID.
* @return string
*/ */
function eth_simple_shortlinks_get( $post_id ) { function eth_simple_shortlinks_get( $post_id ) {
if ( ! did_action( 'wp_loaded' ) ) { if ( ! did_action( 'wp_loaded' ) ) {
_doing_it_wrong( __FUNCTION__, __( 'Shortlinks cannot be generated until after <code>wp_loaded</code>; this ensures that all post types are registered.', 'eth_simple_shortlinks' ), '0.3' ); _doing_it_wrong(
__FUNCTION__,
wp_kses_post(
__(
'Shortlinks cannot be generated until after <code>wp_loaded</code>; this ensures that all post types are registered.',
'eth_simple_shortlinks'
)
),
'0.3'
);
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment