Forked from microneer/gist:abe764ae031e88c5b0919b661a0c8ff9
Last active
June 6, 2020 21:32
-
-
Save MaximeCulea/996f8948b1dc06b85b7a666805c96248 to your computer and use it in GitHub Desktop.
Make post excerpt as mandatory field with capability to set the lenght, if needed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// put this in functions.php or in your custom plugin or theme code. | |
$m = new Mandatory_Excerpt(); | |
$m->add('post', 20 ); // will require all 'post' post types to have an excerpt at least 20 characters long | |
/** | |
* Helper class which removes specified metaboxes from specified pages. It manages setting up the hooks | |
* and calling them. | |
* | |
* @author: Michael Fielding | |
* | |
* Usage: | |
* $me = new Mandatory_Excerpt(); | |
* $me->add('post', 20 ) | |
* ->add('my_custom_post', 44); // repeat as needed | |
*/ | |
class Mandatory_Excerpt { | |
private $min_lengths = []; | |
// set up the hooks we'll need | |
public function __construct() { | |
add_filter('wp_insert_post_data', [$this,'do_mandatory_excerpt']); | |
add_action('admin_notices', [$this,'do_admin_notice']); | |
} | |
public function add( $post_type, $minimum_excerpt_length = 0 ){ | |
$this->min_lengths[$post_type] = $minimum_excerpt_length; | |
return $this; | |
} | |
// handler for wp_insert_post_data hook | |
public function do_mandatory_excerpt( $data ) { | |
$post_type = $data['post_type']; | |
// if there's a minimum excerpt length set for this post type, check it | |
if ( isset($this->min_lengths[$post_type]) ) { | |
$min_length = $this->min_lengths[$post_type]; | |
$excerpt = $data['post_excerpt']; | |
if ( empty($excerpt) || strlen($excerpt)<$min_length ) { | |
// if user was trying to publish the post, show a warning | |
if ($data['post_status'] === 'publish') { | |
// add a filter to intercept the post-save redirect and show a message | |
add_filter('redirect_post_location', [$this,'do_error_message_redirect'], 10, 2); | |
} | |
// ensure it's not published | |
if ('deleted' !== $data['post_status'] && 'trash' !== $data['post_status']) { | |
$data['post_status'] = 'draft'; | |
} | |
} | |
} | |
return $data; | |
} | |
// intercept the after-save redirect and ensure a message will be shown on the following page | |
public function do_error_message_redirect($location,$post_id) { | |
remove_filter('redirect_post_location', [$this,'do_error_message_redirect'], 10, 2); | |
$post_type = get_post_type( $post_id ); | |
if ( isset($this->min_lengths[$post_type]) ) { | |
$min_length = $this->min_lengths[$post_type]; | |
// add a query variable to display our admin notice | |
$location = add_query_arg('excerpt_not_long_enough', $min_length, $location); | |
// remove the post saved message | |
$location = remove_query_arg( 'message', $location ); | |
} | |
return $location; | |
} | |
/** | |
* Show a warning or error that the excerpt is required, if it is not manually defined for something where it's required. | |
*/ | |
public function do_admin_notice() { | |
// show a warning or error if there is no custom excerpt on a type where there should be | |
$screen = get_current_screen(); | |
if ( $screen != NULL && $screen->base == 'post' && isset($this->min_lengths[$screen->post_type]) ) { | |
$min_length = $this->min_lengths[$screen->post_type]; | |
$post_id = $_GET['post']; | |
if ( !has_excerpt($post_id) || strlen(get_the_excerpt($post_id)) < $min_length ) { | |
$this->echo_admin_notice(['Cannot publish this until a hand-written Excerpt of at least ',$min_length,' characters is provided.'], 'warning'); | |
} | |
// check if the excerpt not long enough message was requested by being put in the query string | |
if (isset($_GET['excerpt_not_long_enough'])) { | |
$this->echo_admin_notice(['Publication failed because the Excerpt wasn\'t ',$min_length,' characters or more.']); | |
} | |
} | |
} | |
/** | |
* Show an admin message. Should be called in an admin_notices hook. | |
* @param string|array(string) $text The notice to show. This is passed through _e() for translation. | |
* Can be an array, in which case each string is concatenated after passing thru _e(), which allows | |
* parameters to be embedded. | |
* @param string $class error|warning|success|info | |
* @param boolean $is_dismissable If true, then the notice has an X to dismiss it. | |
*/ | |
private function echo_admin_notice( $text, $class = 'error', $is_dismissable = true ) { | |
$dismissable = $is_dismissable ? 'is-dismissable' : ''; | |
echo "<div class=\"notice notice-$class $dismissable\"><p>"; | |
foreach( (array)$text as $t ) { | |
_e($t); | |
} | |
echo( "</p></div>" ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment