wecobble/Subtitles

View on GitHub
admin/class-subtitles-admin.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php
/**
* @package Subtitles
*/
 
/**
* Do not load this file directly
*
* @since 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
die( '-1' );
}
 
/**
* Checks for the existence of Subtitles_Admin before defining it.
*
* @link http://www.php.net//manual/en/function.class-exists.php
*
* @since 1.0.0
*/
if ( ! class_exists( 'Subtitles_Admin' ) ) {
/**
* Define Subtitles_Admin class.
*
* Within classes constants and variables are called properties.
* Within classes functions are called methods.
*
* @link http://php.net/manual/en/language.oop5.php
*
* @since 1.0.0
*/
class Subtitles_Admin extends Subtitles {
/**
* Hold the singleton instance of Subtitles_Admin.
*
* @since 1.0.3
*/
private static $instance = null;
 
public static function getinstance() {
if ( ! self::$instance ) {
self::$instance = new Subtitles_Admin;
}
 
return self::$instance;
} // end method getinstance()
 
protected function __clone() {}
 
public function __wakeup() {
throw new Exception( 'This Singleton cannot be unserialized.' );
}
 
/**
* Declare constructor methods for the class Subtitles.
*
* Classes which have a constructor method call this method on each newly-created object,
* so it is suitable for any initialization that the object may need before it is used.
*
* Access is set to protected to prevent outside access to the method for anything other than
* the class or a child class. Otherwise `new` could be used to kick off this constructor if
* it were public.
*
* @access protected
*
* @since 1.0.0
*/
protected function __construct() {
/**
* Build the subtitle input field.
*
* To find out the number and name of arguments for any action in WordPress,
* search Core for the matching do_action call. For example, searching for
* "do_action( 'save_post'" reveals that two arguments, $post_id and $post are used.
*
* add_action accepts:
*
* - $tag The name of the action to which the $function_to_add is hooked.
* - callback function The name of the function you wish to be called.
* - int $priority optional. Used to specify the order in which the functions
* associated with a particular action are executed (default: 10).
* Lower numbers correspond with earlier execution, and functions with the
* same priority are executed in the order in which they were added to the action.
* - int $accepted_args optional. The number of arguments the function accept (default: 1).
*
* @see add_action()
* @link http://codex.wordpress.org/Function_Reference/add_action
*
* @since 1.0.0
*/
if ( version_compare( $GLOBALS['wp_version'], '4.1-alpha', '<' ) ) {
add_action( 'edit_form_after_title', array( &$this, 'build_subtitle_input' ) );
} else {
add_action( 'edit_form_before_permalink', array( &$this, 'build_subtitle_input' ) );
}
 
/**
* Validate and update the subtitle input field.
*
* @see add_action()
* @link http://codex.wordpress.org/Function_Reference/add_action
* @link http://codex.wordpress.org/Data_Validation
*
* @since 1.0.0
*/
add_action( 'save_post', array( &$this, 'update_subtitle_data' ), 10, 3 );
 
/**
* Enqueue backend scripts and styles.
*
* @see add_action()
* @link http://codex.wordpress.org/Function_Reference/add_action
*
* @since 1.0.0
*/
add_action( 'admin_enqueue_scripts', array( &$this, 'subtitle_admin_scripts' ) );
 
/**
* Add subtitles into post, page, and custom post type columns in the Dashboard.
*
* @since 2.1.0
*/
add_action( 'manage_posts_columns', array( &$this, 'build_subtitles_column_head' ), 10, 2 );
add_action( 'manage_posts_custom_column', array( &$this, 'build_subtitles_column_content' ), 10, 2 );
add_action( 'manage_pages_columns', array( &$this, 'build_subtitles_column_head' ) );
add_action( 'manage_pages_custom_column', array( &$this, 'build_subtitles_column_content' ), 10, 2 );
} // end method __construct()
 
/**
* Build the subtitle input field.
*
* @access public
*
* @since 1.0.0
*/
public function build_subtitle_input( $post ) {
/**
* Bail if we're not on an admin screen
*
* @since 1.0.0
*/
if ( ! is_admin() ) {
return;
}
 
/**
* Bail if the current post type doesn't support subtitles.
*
* By default both posts and pages automatically support subtitles.
*
* Support for subtitles is kicked off in Subtitles->add_subtitles_support();
*
* @since 1.0.0
*/
$screen = (object) get_current_screen();
$post_type_support = post_type_supports( $screen->post_type, self::SUBTITLE_FEATURE_SUPPORT );
 
if ( ! $post_type_support ) {
return;
}
 
$post_id = (int) absint( $post->ID ); // post ID should always be a non-negative integer
 
/**
* get_post_meta() takes the following arguments:
* - $post_id for the ID of the post
* - $key for the meta key to retrieve
* - $single for whether or not to return a single value
* (in effect either choosing an array or a single value to be returned)
*/
$subtitle = (string) get_post_meta( $post_id, self::SUBTITLE_META_KEY, true );
 
// nonces ("number used once") are used to protect the custom meta box forms from being misused.
wp_nonce_field(
basename( __FILE__ ), // $action, Action name
self::SUBTITLE_NONCE_NAME // $name, Nonce name
); ?>
 
<div id="subtitlediv">
<div id="subtitlewrap">
<label class="screen-reader-text" id="subtitle-prompt-text" for="<?php echo esc_attr( self::SUBTITLE_META_KEY ); ?>">
<?php echo esc_html( apply_filters( 'enter_subtitle_here', __( 'Enter subtitle here', 'subtitles' ), $post ) ); ?>
</label><!-- #subtitle-prompt-text -->
<input type="text" name="<?php echo esc_attr( self::SUBTITLE_META_KEY ); ?>" size="30" value="<?php echo esc_attr( $subtitle ); ?>" id="subtitle" autocomplete="off" />
</div><!-- #subtitlewrap -->
</div><!-- #subtitlediv --><?php
 
do_action( 'edit_form_after_subtitle', $post );
} // end build_subtitle_input()
 
/**
* Validate and save custom metadata associated with Subtitles.
*
* @link http://codex.wordpress.org/Data_Validation
* @access public
*
* @since 1.0.0
*/
Method `update_subtitle_data` has 48 lines of code (exceeds 25 allowed). Consider refactoring.
Function `update_subtitle_data` has a Cognitive Complexity of 15 (exceeds 5 allowed). Consider refactoring.
public function update_subtitle_data( $post_id, $post, $update ) {
/**
* Check current save status of post
*/
$is_post_autosave = (bool) wp_is_post_autosave( $post_id ); // Autosave, found in wp-includes/revisison.php
$is_post_revision = (bool) wp_is_post_revision( $post_id ); // Revision, found in wp-includes/revision.php
 
/**
* Check current subtitle nonce status of post
*/
$is_nonce_set = (bool) isset( $_POST[ self::SUBTITLE_NONCE_NAME ] );
/**
* If the nonce is set then check if it's verified.
* This gets rid of undefined index notices for _subtitle_data_nonce.
*/
if ( $is_nonce_set ) {
$nonce = sanitize_key( $_POST[ self::SUBTITLE_NONCE_NAME ] );
$is_verified_nonce = (bool) wp_verify_nonce( $nonce, basename( __FILE__ ) );
} else {
$is_verified_nonce = null;
}
 
/**
* Bail if the save status or nonce status of the post isn't correct
*/
if ( $is_post_autosave || $is_post_revision || ! $is_verified_nonce || ! $is_nonce_set ) {
return;
}
 
/**
* Bail if the current user doesn't have permission to edit the current post type
*/
$post_type_object = (object) get_post_type_object( $post->post_type );
$can_edit_post_type = (bool) current_user_can( $post_type_object->cap->edit_post, $post_id );
 
if ( ! $can_edit_post_type ) {
return;
}
 
/**
* Data validation and sanitization before inputting it into the database.
*
* Always remember to validate on both input and output. We're using wp_kses
* here, and only allowing users to input italicized and bold text in their
* subtitles.
*
* @link http://codex.wordpress.org/Function_Reference/wp_kses
* @since 1.0.0
*
* @since 2.1.0 We have added in a way for developers to allow more tags in subtitles input.
*/
$subtitles_allowed_tags = array(
'i' => array(), // italicized text
'em' => array(), // emphasized text
'strong' => array(), // strong text
);
/**
* @since 2.1.0 We have added in a way for developers to allow more tags in subtitles input.
*/
$subtitles_allowed_tags = apply_filters( 'subtitles_allowed_tags', $subtitles_allowed_tags );
// grab the subtitles meta key
$subtitle_meta_key = (string) self::SUBTITLE_META_KEY;
// If a new subtitle has been posted, then use it; otherwise assign an empty value to the subtitle
$new_subtitle = (string) isset( $_POST[ $subtitle_meta_key ] ) ? wp_kses( $_POST[ $subtitle_meta_key ], $subtitles_allowed_tags ) : null;
// Get the current subtitle assigned to the post
$current_subtitle = (string) wp_kses( get_post_meta( $post_id, $subtitle_meta_key, true ), $subtitles_allowed_tags );
 
/**
* Add meta when key is new or empty for post
*
* If the current subtitle is empty (hasn't been entered yet) then set it
*/
if ( $current_subtitle && '' === $current_subtitle ) {
add_post_meta(
$post_id, // $post_id the post ID
$subtitle_meta_key, // $meta_key the metadata name
$new_subtitle, // $meta_value the metadata value
false // $unique, if this is set to true then the key cannot be re-used
);
}
 
/**
* If the current meta value and the newly entered meta value are different,
* then update the post meta
*/
if ( ( $new_subtitle && $new_subtitle !== $current_subtitle ) ) {
update_post_meta(
$post_id, // $post_id the post ID
$subtitle_meta_key, // $meta_key the metadata name
$new_subtitle // $meta_value the metadata value
);
}
 
/**
* If the new subtitle entered is blank
*/
if ( '' === $new_subtitle && $current_subtitle ) {
delete_post_meta(
$post_id, // $post_id the post ID
$subtitle_meta_key, // $meta_key the metadata name
$new_subtitle // $meta_value the metadata value
);
}
} // end update_subtitle_data()
 
/**
* Enqueue admin scripts and styles.
*
* @since 1.0.0
* @access public
*/
public function subtitle_admin_scripts( $hook ) {
/**
* Bail on these scripts and styles if we're not on a post edit screen
* or an add new post screen.
*
* @since 1.0.0
*/
if ( 'post-new.php' != $hook && 'post.php' != $hook ) {
return;
}
 
/**
* Load in main Subtitles admin stylesheet
*
* wp_enqueue_style accepts
* - $handle Name of the stylesheet.
* - $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
* - $deps An array of registered style handles this stylesheet depends on. Default empty array.
* - $ver String specifying the stylesheet version number, if it has one. This parameter is used
* to ensure that the correct version is sent to the client regardless of caching, and so
* should be included if a version number is available and makes sense for the stylesheet.
* - $media Optional. The media for which this stylesheet has been defined.
* Default 'all'. Accepts 'all', 'aural', 'braille', 'handheld', 'projection', 'print',
* 'screen', 'tty', or 'tv'.
*
* @link http://codex.wordpress.org/Function_Reference/wp_enqueue_style
* @since 1.0.0
*/
wp_enqueue_style( self::PLUGIN_SLUG . '-admin-style', plugins_url( 'assets/css/subtitles.css' , __FILE__ ), array(), self::VERSION );
 
/**
* Load in main Subtitles scripts
*
* wp_enqueue_script accepts
* - $handle Name of the script.
* - $src Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
* - $deps An array of registered handles this script depends on. Default empty array.
* - $ver Optional. String specifying the script version number, if it has one. This parameter
* is used to ensure that the correct version is sent to the client regardless of caching,
* and so should be included if a version number is available and makes sense for the script.
* - $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
* Default 'false'. Accepts 'false' or 'true'.
*
* @link http://codex.wordpress.org/Function_Reference/wp_enqueue_script
* @since 1.0.0
*/
wp_enqueue_script( self::PLUGIN_SLUG . '-admin-scripts', plugins_url( 'assets/js/subtitles.js' , __FILE__ ), array( 'jquery' ), self::VERSION, true );
} // end subtitle_admin_scripts()
 
/**
* Build Subtitle column headers for post, pages, and custom post types.
*
* @see function esc_html__
* @see function is_admin
* @see function post_type_supports
* @since 2.1.0
* @access public
*/
public function build_subtitles_column_head( $posts_columns, $post_type = 'page' ) {
if ( ! is_admin() ) {
return;
}
 
$post_type_support = post_type_supports( $post_type, self::SUBTITLE_FEATURE_SUPPORT );
if ( $post_type_support ) {
$posts_columns['subtitle'] = esc_html__( 'Subtitle', 'subtitles' );
}
 
return $posts_columns;
} // end function build_subtitles_column_head
 
/**
* Build Subtitle column content for post, pages, and custom post types.
*
* @see function is_admin
* @see function get_the_subtitle
* @since 2.1.0
* @access public
*/
public function build_subtitles_column_content( $column_name, $post_id ) {
if ( ! is_admin() || 'subtitle' !== $column_name ) {
return;
}
 
$subtitle = get_the_subtitle( $post_id );
 
if ( ! empty( $subtitle ) ) {
echo $subtitle; // WPCS: XSS OK
}
} // end function build_subtitles_column_content
} // end class Subtitles_Admin
} // End if().