From a16fb52d5eebd35e1c1081b5d7fa6f6dbab8129f Mon Sep 17 00:00:00 2001 From: Erick Hitter <git-contrib@ethitter.com> Date: Sun, 12 May 2019 14:00:05 -0700 Subject: [PATCH] PHPCS --- .phpcs.xml.dist | 2 +- eth-simple-shortlinks.php | 33 +++ inc/class-eth-simple-shortlinks.php | 322 ++++++++++++++++++++-------- 3 files changed, 265 insertions(+), 92 deletions(-) create mode 100644 eth-simple-shortlinks.php diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 7dfcb69..6555ad3 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -26,7 +26,7 @@ <!-- Rules: 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 --> - <config name="minimum_supported_wp_version" value="3.2.1"/> + <config name="minimum_supported_wp_version" value="4.4"/> <rule ref="WordPress" /> <rule ref="WordPressVIPMinimum" /> <rule ref="WordPress-VIP-Go" /> diff --git a/eth-simple-shortlinks.php b/eth-simple-shortlinks.php new file mode 100644 index 0000000..e0894c5 --- /dev/null +++ b/eth-simple-shortlinks.php @@ -0,0 +1,33 @@ +<?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'; diff --git a/inc/class-eth-simple-shortlinks.php b/inc/class-eth-simple-shortlinks.php index 381f07d..8549853 100644 --- a/inc/class-eth-simple-shortlinks.php +++ b/inc/class-eth-simple-shortlinks.php @@ -1,29 +1,13 @@ <?php -/* -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 -*/ +/** + * Plugin functionality. + * + * @package ETH_Simple_Shortlinks + */ +/** + * Class ETH_Simple_Shortlinks. + */ class ETH_Simple_Shortlinks { /** * PLUGIN SETUP @@ -31,6 +15,8 @@ class ETH_Simple_Shortlinks { /** * Singleton + * + * @var self */ private static $instance = null; @@ -39,115 +25,204 @@ class ETH_Simple_Shortlinks { */ public static function get_instance() { if ( ! is_a( self::$instance, __CLASS__ ) ) { - self::$instance = new self; + self::$instance = new self(); } return self::$instance; } /** - * Dummy magic methods + * Dummy magic method */ - public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ uh?', 'eth_simple_shortlinks' ), '0.1' ); } - public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ uh?', 'eth_simple_shortlinks' ), '0.1' ); } - public function __call( $name = '', $args = array() ) { unset( $name, $args ); return null; } + public function __clone() { + _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ uh?', 'eth_simple_shortlinks' ), '0.1' ); + } /** - * Class properties + * Dummy magic method */ - private $name = 'ETH Simple Shortlinks'; - private $slug = 'p'; - private $rewrite_rule = null; - private $rewrite_match = null; - private $qv = 'eth-shortlink'; + public function __wakeup() { + _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ uh?', 'eth_simple_shortlinks' ), '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 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 $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(); /** - * Register plugin's setup action + * Register plugin's setup action. */ 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_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( 'init', array( $this, 'action_init' ) ); } /** - * Load plugin translations + * Load plugin translations. */ 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() { 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 ) ) { add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) ); - } else { - $this->plugin_supported = true; + return; + } - // Admin notices - add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) ); + $this->plugin_supported = true; - // Register rewrite rule - add_rewrite_rule( $this->rewrite_rule, $this->rewrite_match, 'top' ); + // Admin notices. + add_action( 'admin_notices', array( $this, 'action_add_admin_notices' ) ); - // Request handling - add_action( 'wp_loaded', array( $this, 'filter_support' ) ); - add_filter( 'query_vars', array( $this, 'filter_query_vars' ) ); - add_action( 'parse_request', array( $this, 'action_parse_request' ) ); + // Register rewrite rule. + add_rewrite_rule( $this->rewrite_rule, $this->rewrite_match, 'top' ); - // 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 ); - } + // Request handling. + add_action( 'wp_loaded', array( $this, 'filter_support' ) ); + add_filter( 'query_vars', array( $this, 'filter_query_vars' ) ); + add_action( 'parse_request', array( $this, 'action_parse_request' ) ); + + // 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() { - // 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' ) ) { + // 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' ) ) { return; } - // Build notices + // Build notices. $message = ''; 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. $rewrites = get_option( 'rewrite_rules' ); 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 { - $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 ) ) { - $message = sprintf( __( '<strong>%1$s</strong>: %2$s', 'eth_simple_shortlinks' ), $this->name, $message ); - - ?><div class="error"> - <p><?php echo $message; ?></p> - </div><?php + $message = sprintf( + /* translators: 1: Plugin name, 2: Notice text. */ + __( + '<strong>%1$s</strong>: %2$s', + '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 { */ /** - * Allow filtering of supported statuses and types + * Allow filtering of supported statuses and types. */ 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_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 ) { $qv[] = $this->qv; @@ -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 ) { if ( isset( $request->query_vars[ $this->qv ] ) ) { - $dest = get_permalink( $request->query_vars[ 'p' ] ); + $dest = get_permalink( $request->query_vars['p'] ); 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; } } } /** - * 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 ) { if ( empty( $id ) ) { @@ -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() { global $typenow; @@ -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 ) { 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 { } /** - * 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 ) { - 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 ) { - 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 ) { - // 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 ) { return wp_get_shortlink( $post_id ); } @@ -286,11 +413,24 @@ class ETH_Simple_Shortlinks { 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 ) { 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; } -- GitLab