diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1eeee56cefb802a3d77bdab5e9a75936dc251bcd..c86fd79bd0a16a215eb60fd58c4115ad7a5d5052 100755
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,9 +25,9 @@ before_script:
   - composer global require phpcompatibility/phpcompatibility-wp
   - phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs,$HOME/.composer/vendor/automattic/vipwpcs,$HOME/.composer/vendor/phpcompatibility/php-compatibility,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-paragonie,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-wp
 
-PHPunit:PHP7.3:MySQL:
+PHP5.3:
   stage: test
-  image: containers.ethitter.com:443/docker/images/php:7.3
+  image: containers.ethitter.com:443/docker/images/php:5.3
   services:
     - mysql:5.6
   script:
@@ -36,6 +36,56 @@ PHPunit:PHP7.3:MySQL:
     - phpunit
   allow_failure: true
 
+PHP5.6:
+  stage: test
+  image: containers.ethitter.com:443/docker/images/php:5.6
+  services:
+    - mysql:5.6
+  script:
+    - find . -type "f" -iname "*.php" | xargs -L "1" php -l
+    - phpcs -n
+    - phpunit
+
+PHP7.0:
+  stage: test
+  image: containers.ethitter.com:443/docker/images/php:7.0
+  services:
+    - mysql:5.6
+  script:
+    - find . -type "f" -iname "*.php" | xargs -L "1" php -l
+    - phpcs -n
+    - phpunit
+
+PHP7.1:
+  stage: test
+  image: containers.ethitter.com:443/docker/images/php:7.1
+  services:
+    - mysql:5.6
+  script:
+    - find . -type "f" -iname "*.php" | xargs -L "1" php -l
+    - phpcs -n
+    - phpunit
+
+PHP7.2:
+  stage: test
+  image: containers.ethitter.com:443/docker/images/php:7.2
+  services:
+    - mysql:5.6
+  script:
+    - find . -type "f" -iname "*.php" | xargs -L "1" php -l
+    - phpcs -n
+    - phpunit
+
+PHP7.3:
+  stage: test
+  image: containers.ethitter.com:443/docker/images/php:7.3
+  services:
+    - mysql:5.6
+  script:
+    - find . -type "f" -iname "*.php" | xargs -L "1" php -l
+    - phpcs -n
+    - phpunit
+
 PluginSVN:
   stage: deploy
   image: containers.ethitter.com:443/docker/images/php:7.3
diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist
index 019e0278089de965f41e45e73445ffedad58b0a2..f1a344055722f890bd8269aafa470e9070755c09 100644
--- a/.phpcs.xml.dist
+++ b/.phpcs.xml.dist
@@ -19,7 +19,7 @@
 
 	<!-- Rules: Check PHP version compatibility -->
 	<!-- https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions -->
-	<config name="testVersion" value="5.6-"/>
+	<config name="testVersion" value="5.2-"/>
 	<!-- https://github.com/PHPCompatibility/PHPCompatibilityWP -->
 	<rule ref="PHPCompatibilityWP"/>
 
@@ -27,19 +27,21 @@
 	<!-- 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.0"/>
-	<rule ref="WordPress" />
+	<rule ref="WordPress">
+		<exclude name="WordPress.Files.FileName.InvalidClassFileName" />
+	</rule>
 	<rule ref="WordPressVIPMinimum" />
 	<rule ref="WordPress-VIP-Go" />
 	<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
 		<properties>
 			<!-- Value: replace the function, class, and variable prefixes used. Separate multiple prefixes with a comma. -->
-			<property name="prefixes" type="array" value="external_permalinks_redux"/>
+			<property name="prefixes" type="array" value="external_permalinks_redux, epr_"/>
 		</properties>
 	</rule>
 	<rule ref="WordPress.WP.I18n">
 		<properties>
 			<!-- Value: replace the text domain used. -->
-			<property name="text_domain" type="array" value="external_permalinks_redux"/>
+			<property name="text_domain" type="array" value="external-permalinks-redux"/>
 		</properties>
 	</rule>
 	<rule ref="WordPress.WhiteSpace.ControlStructureSpacing">
diff --git a/external-permalinks-redux.php b/external-permalinks-redux.php
index 8295052ce52063811b7f80a99681b71d97a0a300..70571546a2f81848d44b2f30849b32b43c168397 100644
--- a/external-permalinks-redux.php
+++ b/external-permalinks-redux.php
@@ -1,58 +1,80 @@
 <?php
-/*
-Plugin Name: External Permalinks Redux
-Plugin URI: http://www.thinkoomph.com/plugins-modules/external-permalinks-redux/
-Description: Allows users to point WordPress objects (posts, pages, custom post types) to a URL of your choosing. Inspired by and backwards-compatible with <a href="http://txfx.net/wordpress-plugins/page-links-to/">Page Links To</a> by Mark Jaquith. Written for use on WordPress.com VIP.
-Version: 1.1
-Author: Erick Hitter & Oomph, Inc.
-Author URI: http://www.thinkoomph.com/
-
-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 Name: External Permalinks Redux
+ * Plugin URI: http://www.thinkoomph.com/plugins-modules/external-permalinks-redux/
+ * Description: Allows users to point WordPress objects (posts, pages, custom post types) to a URL of your choosing. Inspired by and backwards-compatible with <a href="http://txfx.net/wordpress-plugins/page-links-to/">Page Links To</a> by Mark Jaquith. Written for use on WordPress.com VIP.
+ * Version: 1.1
+ * Author: Erick Hitter & Oomph, Inc.
+ * Author URI: http://www.thinkoomph.com/
+ *
+ * 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
+ *
+ * @package External_Permalinks_Redux
+ */
 
+/**
+ * Class external_permalinks_redux.
+ */
+// phpcs:ignore PEAR.NamingConventions.ValidClassName, Squiz.Commenting.ClassComment.Missing
 class external_permalinks_redux {
 	/**
-	 * Class variables
+	 * Singleton!
+	 *
+	 * @var self
 	 */
 	protected static $instance;
 
-	var $meta_key_target = '_links_to';
-	var $meta_key_type = '_links_to_type';
-	var $status_codes;
+	/**
+	 * Redirect URL meta key.
+	 *
+	 * @var string
+	 */
+	public $meta_key_target = '_links_to';
 
 	/**
-	 * Instantiate class as a singleton
+	 * Redirect type meta key.
+	 *
+	 * @var string
+	 */
+	public $meta_key_type = '_links_to_type';
+
+	/**
+	 * Supported redirect codes.
+	 *
+	 * @var array
+	 */
+	public $status_codes;
+
+	/**
+	 * Instantiate class as a singleton.
 	 *
 	 * @return object
 	 */
-	static function get_instance() {
-		if ( ! isset( self::$instance ) )
-			self::$instance = new self;
+	public static function get_instance() {
+		if ( ! isset( self::$instance ) ) {
+			self::$instance = new self();
+		}
 
 		return self::$instance;
 	}
 
 	/**
-	 * Register actions and filters
-	 *
-	 * @uses add_action
-	 * @uses add_filter
-	 * @return null
+	 * Register actions and filters.
 	 */
 	private function __construct() {
-		add_action( 'init', array( $this, 'action_init' ), 0 ); // other init actions may rely on permalinks so filter early
+		add_action( 'init', array( $this, 'action_init' ), 0 ); // Other init actions may rely on permalinks so filter early.
 		add_action( 'admin_init', array( $this, 'action_admin_init' ) );
 		add_action( 'save_post', array( $this, 'action_save_post' ) );
 
@@ -63,17 +85,15 @@ class external_permalinks_redux {
 	}
 
 	/**
-	 * Register plugin keys and status codes
+	 * Register plugin keys and status codes.
 	 *
-	 * @uses apply_filters
 	 * @action init
-	 * @return null
 	 */
-	function action_init() {
+	public function action_init() {
 		$this->meta_key_target = apply_filters( 'epr_meta_key_target', $this->meta_key_target );
-		$this->meta_key_type = apply_filters( 'epr_meta_key_type', $this->meta_key_type );
+		$this->meta_key_type   = apply_filters( 'epr_meta_key_type', $this->meta_key_type );
 
-		$status_codes = array(
+		$status_codes       = array(
 			302 => __( 'Temporary (302)', 'external-permalinks-redux' ),
 			301 => __( 'Permanent (301)', 'external-permalinks-redux' ),
 		);
@@ -81,25 +101,21 @@ class external_permalinks_redux {
 	}
 
 	/**
-	 * Add meta box
-	 *
-	 * @uses apply_filters
-	 * @uses __
-	 * @uses add_meta_box
-	 * @action admin_init
-	 * @return null
+	 * Add meta box.
 	 */
-	function action_admin_init() {
+	public function action_admin_init() {
 		$post_types = apply_filters( 'epr_post_types', array( 'post', 'page' ) );
 
-		if ( ! is_array( $post_types ) )
+		if ( ! is_array( $post_types ) ) {
 			return;
+		}
 
-		foreach( $post_types as $post_type ) {
-			$title  = apply_filters( 'epr_metabox_title', '', $post_type );
+		foreach ( $post_types as $post_type ) {
+			$title = apply_filters( 'epr_metabox_title', '', $post_type );
 
-			if ( ! $title )
+			if ( ! $title ) {
 				$title = __( 'External Permalinks Redux', 'external-permalinks-redux' );
+			}
 
 			add_meta_box( 'external-permalinks-redux', $title, array( $this, 'meta_box' ), $post_type, 'normal' );
 
@@ -109,146 +125,139 @@ class external_permalinks_redux {
 
 
 	/**
-	 * Render meta box
+	 * Render meta box.
 	 *
-	 * @param object $post
-	 * @uses get_post_meta
-	 * @uses _e
-	 * @uses esc_attr
-	 * @uses esc_url
-	 * @uses selected
-	 * @uses wp_nonce_field
-	 * @return string
+	 * @param object $post Post object.
 	 */
-	function meta_box( $post ) {
+	public function meta_box( $post ) {
 		$type = get_post_meta( $post->ID, $this->meta_key_type, true );
-	?>
+		?>
 		<p class="epr-destination">
-			<label for="epr-url"><?php _e( 'Destination Address:', 'external-permalinks-redux' ); ?></label><br />
+			<label for="epr-url"><?php esc_html_e( 'Destination Address:', 'external-permalinks-redux' ); ?></label><br />
 			<input name="<?php echo esc_attr( $this->meta_key_target ); ?>_url" class="large-text code" id="epr-url" type="text" value="<?php echo esc_url( get_post_meta( $post->ID, $this->meta_key_target, true ) ); ?>" />
 		</p>
 
-		<p class="description"><?php _e( 'To restore the original permalink, remove the link entered above.', 'external-permalinks-redux' ); ?></p>
+		<p class="description"><?php esc_html_e( 'To restore the original permalink, remove the link entered above.', 'external-permalinks-redux' ); ?></p>
 
 		<p class="epr-separator">&nbsp;</p>
 
 		<p class="epr-redirect-type">
-			<label for="epr-type"><?php _e( 'Redirect Type:', 'external-permalinks-redux' ); ?></label>
+			<label for="epr-type"><?php esc_html_e( 'Redirect Type:', 'external-permalinks-redux' ); ?></label>
 			<select name="<?php echo esc_attr( $this->meta_key_target ); ?>_type" id="epr-type">
-				<option value=""><?php _e( '-- Select --', 'external-permalinks-redux' ); ?></option>
-				<?php foreach ( $this->status_codes as $status_code => $explanation ) {
+				<option value=""><?php esc_html_e( '-- Select --', 'external-permalinks-redux' ); ?></option>
+				<?php
+				foreach ( $this->status_codes as $status_code => $explanation ) {
 					echo '<option value="' . esc_attr( $status_code ) . '"';
-					selected( $status_code, intval( $type ) );
+					selected( $status_code, (int) $type );
 					echo '>' . esc_attr( $explanation ) . '</option>';
-				} ?>
+				}
+				?>
 			</select>
 		</p>
 
-	<?php
+		<?php
 		wp_nonce_field( 'external-permalinks-redux', $this->meta_key_target . '_nonce', false );
 	}
 
 	/**
-	 * Save meta box input
+	 * Save meta box input.
 	 *
-	 * @param int $post_id
-	 * @uses wp_verify_nonce
-	 * @uses esc_url_raw
-	 * @uses update_post_meta
-	 * @uses delete_post_meta
-	 * @action save_post
-	 * @return null
+	 * @param int $post_id Post ID.
 	 */
-	function action_save_post( $post_id ) {
-		if ( isset( $_POST[ $this->meta_key_target . '_nonce' ] ) && wp_verify_nonce( $_POST[ $this->meta_key_target . '_nonce' ], 'external-permalinks-redux' ) ) {
-			//Target
-			$url = esc_url_raw( $_POST[ $this->meta_key_target . '_url' ] );
+	public function action_save_post( $post_id ) {
+		if ( isset( $_POST[ $this->meta_key_target . '_nonce' ] ) && wp_verify_nonce( sanitize_text_field( $_POST[ $this->meta_key_target . '_nonce' ] ), 'external-permalinks-redux' ) ) {
+			// Target.
+			$url = isset( $_POST[ $this->meta_key_target . '_url' ] ) ? esc_url_raw( $_POST[ $this->meta_key_target . '_url' ] ) : '';
 
-			if ( ! empty( $url ) )
+			if ( ! empty( $url ) ) {
 				update_post_meta( $post_id, $this->meta_key_target, $url );
-			else
+			} else {
 				delete_post_meta( $post_id, $this->meta_key_target, $url );
+			}
 
-			//Redirect type
-			$type = intval( $_POST[ $this->meta_key_target . '_type' ] );
+			// Redirect type.
+			$type = isset( $_POST[ $this->meta_key_target . '_type' ] ) ? (int) $_POST[ $this->meta_key_target . '_type' ] : '';
 
-			if ( ! empty( $url ) && array_key_exists( $type, $this->status_codes ) )
+			if ( ! empty( $url ) && array_key_exists( $type, $this->status_codes ) ) {
 				update_post_meta( $post_id, $this->meta_key_type, $type );
-			else
+			} else {
 				delete_post_meta( $post_id, $this->meta_key_type );
+			}
 		}
 	}
 
 	/**
-	 * Filter post and custom post type permalinks
+	 * Filter post and custom post type permalinks.
 	 *
-	 * @param string $permalink
-	 * @param object $post
-	 * @uses get_post_meta
-	 * @filter post_link
-	 * @uses post_type_link
+	 * @param string $permalink Post permalinks.
+	 * @param object $post Post object.
 	 * @return string
 	 */
-	function filter_post_permalink( $permalink, $post ) {
-		if ( $external_link = get_post_meta( $post->ID, $this->meta_key_target, true ) )
+	public function filter_post_permalink( $permalink, $post ) {
+		$external_link = get_post_meta( $post->ID, $this->meta_key_target, true );
+
+		if ( ! empty( $external_link ) ) {
 			$permalink = $external_link;
+		}
 
 		return $permalink;
 	}
 
 	/**
-	 * Filter page permalinks
+	 * Filter page permalinks.
 	 *
-	 * @param string $link
-	 * @param int $id
-	 * @uses get_post_meta
-	 * @filter page_link
+	 * @param string $link Page permalink.
+	 * @param int    $id Post ID.
 	 * @return string
 	 */
-	function filter_page_link( $link, $id ) {
-		if ( $external_link = get_post_meta( $id, $this->meta_key_target, true ) )
+	public function filter_page_link( $link, $id ) {
+		$external_link = get_post_meta( $id, $this->meta_key_target, true );
+
+		if ( ! empty( $external_link ) ) {
 			$link = $external_link;
+		}
 
 		return $link;
 	}
 
 	/**
 	 * Redirect to external link if object requested directly.
-	 *
-	 * @global $post
-	 * @uses is_singular
-	 * @uses get_post_meta
-	 * @uses apply_filters
-	 * @uses wp_redirect
-	 * @action wp
-	 * @return null
 	 */
-	function action_wp() {
+	public function action_wp() {
 		global $post;
 
-		if ( is_singular() && ( $link = get_post_meta( $post->ID, $this->meta_key_target, true ) ) ) {
-			$type = intval( get_post_meta( $post->ID, $this->meta_key_type, true ) );
+		if ( ! is_singular() ) {
+			return;
+		}
+
+		$link = get_post_meta( $post->ID, $this->meta_key_target, true );
+
+		if ( ! empty( $link ) ) {
+			$type = (int) get_post_meta( $post->ID, $this->meta_key_type, true );
 			$type = apply_filters( 'epr_status_code', $type, $link, $post );
 
-			if ( ! $type )
+			if ( ! $type ) {
 				$type = 302;
+			}
 
+			// Unreasonable to validate redirect destination.
+			// phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect
 			wp_redirect( $link, $type );
 			exit;
 		}
 	}
 }
 
-// Initialize the plugin if it hasn't already
+// Initialize the plugin if it hasn't already.
 external_permalinks_redux::get_instance();
 
 /**
- * Wrapper for meta box function
- * Can be used as an alternative to the epr_post_types filter found in the plugin classes's action_admin_init function.
+ * Wrapper for meta box function.
+ *
+ * Can be used as an alternative to the `epr_post_types` filter
+ * found in the plugin class's `action_admin_init` function.
  *
- * @param object $post
- * @uses external_permalinks_redux
- * @return string
+ * @param object $post Post object.
  */
 function external_permalinks_redux_meta_box( $post ) {
 	external_permalinks_redux::get_instance()->meta_box( $post );