Skip to content
Snippets Groups Projects
class-wp-revisions-control.php 19 KiB
Newer Older
Erick Hitter's avatar
Erick Hitter committed
<?php
/**
 * Main plugin functionality.
 *
 * @package WP_Revisions_Control
 */
/**
 * Class WP_Revisions_Control.
 */
Erick Hitter's avatar
Erick Hitter committed
class WP_Revisions_Control {
	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Singleton.
	 *
	 * @var static
Erick Hitter's avatar
Erick Hitter committed
	 */
Erick Hitter's avatar
Erick Hitter committed
	private static $__instance;
Erick Hitter's avatar
Erick Hitter committed
	 * Filter priority.
	 *
	 * @see $this->filter_priority()
	 *
	 * @var int
	 */
	private static $priority = null;

	/**
	 * Default filter priority.
	 *
	 * @var int
Erick Hitter's avatar
Erick Hitter committed
	 */
Erick Hitter's avatar
Erick Hitter committed
	/**
	 * Supported post types.
	 *
	 * @see $this->get_post_types()
	 *
	 * @var array
	 */
	private static $post_types = array();

	/**
	 * Plugin settings.
	 *
	 * @see $this->get_settings()
	 *
	 * @var array
	 */
	private static $settings = array();
Erick Hitter's avatar
Erick Hitter committed
	/**
	 * WordPress options page to display settings on.
	 *
	 * @var string
	 */
	private $settings_page = 'writing';
Erick Hitter's avatar
Erick Hitter committed

	/**
	 * Name of custom settings sections.
	 *
	 * @var string
	 */
	private $settings_section = 'wp_revisions_control';

Erick Hitter's avatar
Erick Hitter committed
	/**
	 * Meta key holding post's revisions limit.
	 *
	 * @var string
	 */
	private $meta_key_limit = '_wp_rev_ctl_limit';

	/**
	 * Name of action used to clean up post's revisions via cron.
	 *
	 * @var string
	 */
	private $cron_action = 'wp_revisions_control_cron_purge';

Erick Hitter's avatar
Erick Hitter committed
	/**
	 * Silence is golden!
	 */
	private function __construct() {}

	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Singleton implementation.
Erick Hitter's avatar
Erick Hitter committed
	 *
Erick Hitter's avatar
Erick Hitter committed
	 * @return static
Erick Hitter's avatar
Erick Hitter committed
	 */
	public static function get_instance() {
Erick Hitter's avatar
Erick Hitter committed
		if ( ! is_a( static::$__instance, __CLASS__ ) ) {
			static::$__instance = new self();
Erick Hitter's avatar
Erick Hitter committed
			static::$__instance->setup();
Erick Hitter's avatar
Erick Hitter committed
		return static::$__instance;
Erick Hitter's avatar
Erick Hitter committed
	 * Register actions and filters at `init` so others can interact, if desired.
		add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
		add_action( 'init', array( $this, 'action_init' ) );
	}

Erick Hitter's avatar
Erick Hitter committed
	 * Load plugin translations.
	 */
	public function action_plugins_loaded() {
		load_plugin_textdomain(
			'wp_revisions_control',
			false,
			dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
		);
Erick Hitter's avatar
Erick Hitter committed
	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Register actions and filters.
Erick Hitter's avatar
Erick Hitter committed
	 */
		add_action( 'admin_init', array( $this, 'action_admin_init' ) );
Erick Hitter's avatar
Erick Hitter committed

		add_filter( 'wp_revisions_to_keep', array( $this, 'filter_wp_revisions_to_keep' ), $this->plugin_priority(), 2 );
Erick Hitter's avatar
Erick Hitter committed
		add_action( 'rest_api_init', array( $this, 'action_rest_api_init' ) );
		add_filter( 'is_protected_meta', array( $this, 'filter_is_protected_meta' ), 10, 2 );
		add_action( 'enqueue_block_editor_assets', array( $this, 'action_enqueue_block_editor_assets' ) );
		add_action( $this->cron_action, array( $this, 'do_purge_excess' ) );
Erick Hitter's avatar
Erick Hitter committed
	 * Register plugin's admin-specific elements.
	 */
	public function action_admin_init() {
Erick Hitter's avatar
Erick Hitter committed
		$post_types = $this->get_post_types();

Erick Hitter's avatar
Erick Hitter committed
		// Plugin setting section.
Erick Hitter's avatar
Erick Hitter committed
		register_setting( $this->settings_page, $this->settings_section, array( $this, 'sanitize_options' ) );
		add_settings_section( $this->settings_section, 'WP Revisions Control', array( $this, 'settings_section_intro' ), $this->settings_page );
Erick Hitter's avatar
Erick Hitter committed
		foreach ( $post_types as $post_type => $name ) {
			add_settings_field( $this->settings_section . '-' . $post_type, $name, array( $this, 'field_post_type' ), $this->settings_page, $this->settings_section, array( 'post_type' => $post_type ) );
		}
Erick Hitter's avatar
Erick Hitter committed
		// Post-level functionality.
		add_action( 'add_meta_boxes', array( $this, 'action_add_meta_boxes' ), 10, 2 );
		add_action( 'wp_ajax_' . $this->settings_section . '_purge', array( $this, 'ajax_purge' ) );
		add_action( 'save_post', array( $this, 'action_save_post' ) );
Erick Hitter's avatar
Erick Hitter committed

		// Bulk actions.
		WP_Revisions_Control_Bulk_Actions::get_instance( $post_types );
Erick Hitter's avatar
Erick Hitter committed
	 * PLUGIN SETTINGS SECTION
	 * FOUND UNDER SETTINGS > WRITING
	 */
Erick Hitter's avatar
Erick Hitter committed
	 * Display assistive text in settings section.
	 */
	public function settings_section_intro() {
		?>
Erick Hitter's avatar
Erick Hitter committed
		<p><?php esc_html_e( 'Set the number of revisions to save for each post type listed. To retain all revisions for a given post type, leave the field empty.', 'wp_revisions_control' ); ?></p>
		<p><?php esc_html_e( 'If a post type isn\'t listed, revisions are not enabled for that post type.', 'wp_revisions_control' ); ?></p>

		// Display a note if the plugin priority is other than the default.
		// Will be useful when debugging issues later.
Erick Hitter's avatar
Erick Hitter committed
		if ( $this->plugin_priority() !== $this->priority_default ) :
			?>
			<p>
				<?php
				printf(
					/* translators: 1. Filter tag. */
					esc_html__(
						'A local change is causing this plugin\'s functionality to run at a priority other than the default. If you experience difficulties with the plugin, please unhook any functions from the %1$s filter.',
						'wp_revisions_control'
					),
					'<code>wp_revisions_control_priority</code>'
				);
				?>
			</p>
			<?php
		endif;
Erick Hitter's avatar
Erick Hitter committed
	 * Render field for each post type.
Erick Hitter's avatar
Erick Hitter committed
	 * @param array $args Field arguments.
	 */
	public function field_post_type( $args ) {
Erick Hitter's avatar
Erick Hitter committed
		$revisions_to_keep = $this->get_revisions_to_keep( $args['post_type'], true );
		?>
Erick Hitter's avatar
Erick Hitter committed
		<input type="text" name="<?php echo esc_attr( $this->settings_section . '[' . $args['post_type'] . ']' ); ?>" value="<?php echo esc_attr( $revisions_to_keep ); ?>" class="small-text" />
Erick Hitter's avatar
Erick Hitter committed
		<?php
Erick Hitter's avatar
Erick Hitter committed
	 * Sanitize plugin settings.
Erick Hitter's avatar
Erick Hitter committed
	 * @param array $options Unsanitized settings.
Erick Hitter's avatar
Erick Hitter committed
	 * @return array
	 */
	public function sanitize_options( $options ) {
Erick Hitter's avatar
Erick Hitter committed
		$options_sanitized = array();

		if ( is_array( $options ) ) {
			foreach ( $options as $post_type => $to_keep ) {
Erick Hitter's avatar
Erick Hitter committed
				$type_length = strlen( $to_keep );

				if ( 0 === $type_length ) {
Erick Hitter's avatar
Erick Hitter committed
					$to_keep = -1;
Erick Hitter's avatar
Erick Hitter committed
				} else {
					$to_keep = (int) $to_keep;
				}
Erick Hitter's avatar
Erick Hitter committed
				// Lowest possible value is -1, used to indicate infinite revisions are stored.
				if ( -1 > $to_keep ) {
Erick Hitter's avatar
Erick Hitter committed
				}
Erick Hitter's avatar
Erick Hitter committed
				$options_sanitized[ $post_type ] = $to_keep;
			}
		}

		return $options_sanitized;
	}

Erick Hitter's avatar
Erick Hitter committed
	 * REVISIONS QUANTITY OVERRIDES.
	 */
	/**
	 * Allow others to change the priority this plugin's functionality runs at
	 *
	 * @uses apply_filters
	 * @return int
	 */
	private function plugin_priority() {
		if ( is_null( self::$priority ) ) {
			$plugin_priority = apply_filters( 'wp_revisions_control_priority', $this->priority_default );

			self::$priority = is_numeric( $plugin_priority ) ? (int) $plugin_priority : $this->priority_default;
		}

		return self::$priority;
	}

Erick Hitter's avatar
Erick Hitter committed
	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Override number of revisions to keep using plugin's settings.
Erick Hitter's avatar
Erick Hitter committed
	 *
Erick Hitter's avatar
Erick Hitter committed
	 * Can either be post-specific or universal.
Erick Hitter's avatar
Erick Hitter committed
	 * @param int     $qty  Number of revisions to keep.
	 * @param WP_Post $post Post object.
	 * @return int
Erick Hitter's avatar
Erick Hitter committed
	 */
	public function filter_wp_revisions_to_keep( $qty, $post ) {
		$post_limit = get_post_meta( $post->ID, $this->meta_key_limit, true );

		if ( 0 < strlen( $post_limit ) ) {
			$qty = $post_limit;
		} else {
			$post_type = get_post_type( $post ) ? get_post_type( $post ) : $post->post_type;
Erick Hitter's avatar
Erick Hitter committed
			$settings  = $this->get_settings();
Erick Hitter's avatar
Erick Hitter committed

Erick Hitter's avatar
Erick Hitter committed
			if ( array_key_exists( $post_type, $settings ) ) {
				$qty = $settings[ $post_type ];
Erick Hitter's avatar
Erick Hitter committed
			}
Erick Hitter's avatar
Erick Hitter committed

		return $qty;
	}

Erick Hitter's avatar
Erick Hitter committed
	 * POST-LEVEL FUNCTIONALITY.
	 */
Erick Hitter's avatar
Erick Hitter committed
	 * Override Core's revisions metabox.
	 * @param string  $post_type Post type.
	 * @param WP_Post $post      Post object.
	 */
	public function action_add_meta_boxes( $post_type, $post ) {
Erick Hitter's avatar
Erick Hitter committed
			(
				function_exists( 'use_block_editor_for_post' )
				&& use_block_editor_for_post( $post )
			)
			|| ! post_type_supports( $post_type, 'revisions' )
			|| 'auto-draft' === get_post_status()
			|| count( wp_get_post_revisions( $post ) ) < 1
		) {
			return;

		// Replace the metabox.
		remove_meta_box( 'revisionsdiv', null, 'normal' );
		add_meta_box(
			'revisionsdiv-wp-rev-ctl',
			__(
				'Revisions',
				'wp_revisions_control'
			),
			array(
				$this,
				'revisions_meta_box',
			),
			null,
			'normal',
			'core'
		);

		// A bit of JS for us.
		$handle = 'wp-revisions-control-post';
Erick Hitter's avatar
Erick Hitter committed
		wp_enqueue_script(
			$handle,
			plugins_url(
				'dist/js/classic-editor.js',
				__DIR__
			),
			array(
				'jquery',
Erick Hitter's avatar
Erick Hitter committed
			),
Erick Hitter's avatar
Erick Hitter committed
			2013120501,
			true
		);
		wp_localize_script(
			$handle,
			$this->settings_section,
			array(
				'namespace'       => $this->settings_section,
				'action_base'     => $this->settings_section,
				'processing_text' => __( 'Processing&hellip;', 'wp_revisions_control' ),
				'ays'             => __( 'Are you sure you want to remove revisions from this post?', 'wp_revisions_control' ),
				'autosave'        => __( 'Autosave', 'wp_revisions_control' ),
				'nothing_text'    => wpautop( __( 'There are no revisions to remove.', 'wp_revisions_control' ) ),
				'error'           => __( 'An error occurred. Please refresh the page and try again.', 'wp_revisions_control' ),
			)
		);

		// Add some styling to our metabox additions.
		add_action( 'admin_head', array( $this, 'action_admin_head' ), 999 );
	 * Render Revisions metabox with plugin's additions
Erick Hitter's avatar
Erick Hitter committed
	 * @param WP_Post $post Post object.
	 */
	public function revisions_meta_box( $post ) {
		post_revisions_meta_box( $post );

		?>
		<div id="<?php echo esc_attr( $this->settings_section ); ?>">
			<h4>WP Revisions Control</h4>
			<p class="button purge" data-postid="<?php the_ID(); ?>" data-nonce="<?php echo esc_attr( wp_create_nonce( $this->settings_section . '_purge' ) ); ?>"><?php _e( 'Purge these revisions', 'wp_revisions_control' ); ?></p>

			<p>
Erick Hitter's avatar
Erick Hitter committed
				<?php
				printf(
					/* translators: 1. Text input field. */
					esc_html__(
						'Limit this post to %1$s revisions. Leave this field blank for default behavior.',
						'wp_revisions_control'
					),
					'<input type="text" name="' . esc_attr( $this->settings_section ) . '_qty" value="' . esc_attr( $this->get_post_revisions_to_keep( $post->ID ) ) . '" id="' . esc_attr( $this->settings_section ) . '_qty" size="2" />'
Erick Hitter's avatar
Erick Hitter committed
				);
				?>

				<?php wp_nonce_field( $this->settings_section . '_limit', $this->settings_section . '_limit_nonce', false ); ?>
			</p>
		</div><!-- #<?php echo esc_attr( $this->settings_section ); ?> -->
		<?php
	}

Erick Hitter's avatar
Erick Hitter committed
	 * Process a post-specific request to purge revisions.
	 */
	public function ajax_purge() {
		$post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : false;

Erick Hitter's avatar
Erick Hitter committed
		// Hold the current state of this Ajax request.
Erick Hitter's avatar
Erick Hitter committed
		// Check for necessary data and capabilities.
		if ( ! $post_id ) {
			$response['error'] = __( 'No post ID was provided. Please refresh the page and try again.', 'wp_revisions_control' );
Erick Hitter's avatar
Erick Hitter committed
		} elseif ( ! check_ajax_referer( $this->settings_section . '_purge', 'nonce', false ) ) {
			$response['error'] = __( 'Invalid request. Please refresh the page and try again.', 'wp_revisions_control' );
Erick Hitter's avatar
Erick Hitter committed
		} elseif ( ! current_user_can( 'edit_post', $post_id ) ) {
			$response['error'] = __( 'You are not allowed to edit this post.', 'wp_revisions_control' );
Erick Hitter's avatar
Erick Hitter committed
		}
Erick Hitter's avatar
Erick Hitter committed
		// Request is valid if $response is still empty, as no errors arose above.
			$response = $this->do_purge_all( $post_id );
		}
		// Pass the response back to JS.
		echo json_encode( $response );
		exit;
	}
	/**
	 * Remove all revisions from a given post ID.
	 *
	 * @param int $post_id Post ID to purge of revisions.
	 * @return array
	 */
	public function do_purge_all( $post_id ) {
		$response = array();
		$revisions = wp_get_post_revisions( $post_id );

		$count = count( $revisions );
Erick Hitter's avatar
Erick Hitter committed

		foreach ( $revisions as $revision ) {
			wp_delete_post_revision( $revision->ID );
		$response['success'] = sprintf(
			/* translators: 1. Number of removed revisions, already formatted for locale. */
			esc_html__(
				'Removed %1$s revisions associated with this post.',
				'wp_revisions_control'
			),
			number_format_i18n( $count, 0 )
		);

		$response['count'] = $count;

		return $response;
	/**
	 * Remove any revisions in excess of a post's limit.
	 *
	 * @param int $post_id Post ID to purge of excess revisions.
	 * @return array
	 */
	public function do_purge_excess( $post_id ) {
		$response = array(
			'count' => 0,
		);

		$to_keep = wp_revisions_to_keep( get_post( $post_id ) );

		if ( $to_keep < 0 ) {
			$response['success'] = __(
				'No revisions to remove.',
				'wp_revisions_control'
			);

			return $response;
		}

		$revisions      = wp_get_post_revisions( $post_id );
		$starting_count = count( $revisions );

		if ( $starting_count <= $to_keep ) {
			$response['success'] = __(
				'No revisions to remove.',
				'wp_revisions_control'
			);

			return $response;
		}

		$to_remove         = array_slice( $revisions, $to_keep, null, true );
		$response['count'] = count( $to_remove );

		foreach ( $to_remove as $revision ) {
			wp_delete_post_revision( $revision->ID );
		}

		return $response;
	}

Erick Hitter's avatar
Erick Hitter committed
	 * Sanitize and store post-specifiy revisions quantity.
Erick Hitter's avatar
Erick Hitter committed
	 * @param int $post_id Post ID.
	 */
	public function action_save_post( $post_id ) {
Erick Hitter's avatar
Erick Hitter committed
		$nonce = $this->settings_section . '_limit_nonce';
		$qty   = $this->settings_section . '_qty';

		if ( isset( $_POST[ $nonce ], $_POST[ $qty ] ) && wp_verify_nonce( sanitize_text_field( $_POST[ $nonce ] ), $this->settings_section . '_limit' ) ) {
			$limit = (int) $_POST[ $qty ];
Erick Hitter's avatar
Erick Hitter committed
			if ( -1 === $limit || empty( $limit ) ) {
				delete_post_meta( $post_id, $this->meta_key_limit );
Erick Hitter's avatar
Erick Hitter committed
			} else {
				update_post_meta( $post_id, $this->meta_key_limit, absint( $limit ) );
Erick Hitter's avatar
Erick Hitter committed
			}
Erick Hitter's avatar
Erick Hitter committed
	 * Add a border between the regular revisions list and this plugin's additions.
	 */
	public function action_admin_head() {
Erick Hitter's avatar
Erick Hitter committed
		?>
		<style type="text/css">
			#revisionsdiv-wp-rev-ctl #<?php echo esc_attr( $this->settings_section ); ?> {
Erick Hitter's avatar
Erick Hitter committed
				border-top: 1px solid #dfdfdf;
				padding-top: 0;
				margin-top: 20px;
			}

			#revisionsdiv-wp-rev-ctl #<?php echo esc_attr( $this->settings_section ); ?> h4 {
				border-top: 1px solid #fff;
				padding-top: 1.33em;
				margin-top: 0;
			}
		</style>
Erick Hitter's avatar
Erick Hitter committed
		<?php
Erick Hitter's avatar
Erick Hitter committed
	/**
	 * GUTENBERG SUPPORT.
	 */

	/**
	 * Register REST API components for Gutenberg UI.
Erick Hitter's avatar
Erick Hitter committed
	 */
	public function action_rest_api_init() {
		foreach ( array_keys( $this->get_post_types() ) as $post_type ) {
			register_meta(
				'post',
				$this->meta_key_limit,
				array(
					'object_subtype' => $post_type,
					'type'           => 'string', // Can be empty, so must be string.
					'default'        => '',
					'single'         => true,
					'show_in_rest'   => true,
					'description'    => __(
						'Number of revisions to retain.',
						'wp_revisions_control'
					),
				)
			);
		}

		register_rest_route(
			'wp-revisions-control/v1',
			'schedule/(?P<id>[\d]+)',
			array(
Erick Hitter's avatar
Erick Hitter committed
				'methods'             => 'PUT',
				'callback'            => array( $this, 'rest_api_schedule_purge' ),
				'permission_callback' => array( $this, 'rest_api_permission_callback' ),
				'args'                => array(
					'id' => array(
						'required'          => true,
						'type'              => 'integer',
						'validate_callback' => array( $this, 'rest_api_validate_id' ),
					),
				),
Erick Hitter's avatar
Erick Hitter committed
				'show_in_index'       => false,
			)
		);
	}

	/**
	 * Permissions callback for REST endpoint.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return bool
	 */
	public function rest_api_permission_callback( $request ) {
		return current_user_can(
			'edit_post',
			$request->get_param( 'id' )
		);
	}

	/**
	 * Validate post ID.
	 *
	 * @param int $input Post ID.
	 * @return bool
	 */
	public function rest_api_validate_id( $input ) {
		return is_numeric( $input );
	}

	/**
	 * Schedule cleanup of post's excess revisions.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function rest_api_schedule_purge( $request ) {
		$result = wp_schedule_single_event(
			time() + 3,
			$this->cron_action,
Erick Hitter's avatar
Erick Hitter committed
			array(
				$request->get_param( 'id' ),
Erick Hitter's avatar
Erick Hitter committed
			)
		);

		return rest_ensure_response( $result );
Erick Hitter's avatar
Erick Hitter committed
	}

	/**
	 * Allow our meta to be edited from Gutenberg.
	 *
	 * @param bool   $protected If meta is protected.
	 * @param string $meta_key  Meta key being checked.
	 * @return false
	 */
	public function filter_is_protected_meta( $protected, $meta_key ) {
		if ( $meta_key === $this->meta_key_limit ) {
			return false;
		}

		return $protected;
	}

	/**
	 * Register Gutenberg script.
	 */
	public function action_enqueue_block_editor_assets() {
		wp_enqueue_script(
			$this->settings_section,
			plugins_url(
				'dist/js/gutenberg.js',
				__DIR__
			),
			array(
				'wp-components',
				'wp-compose',
				'wp-data',
				'wp-edit-post',
				'wp-i18n',
				'wp-plugins',
			),
			2021032701
		);
	}

Erick Hitter's avatar
Erick Hitter committed
	 * PLUGIN UTILITIES.
	 */
Erick Hitter's avatar
Erick Hitter committed
	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Retrieve plugin settings.
Erick Hitter's avatar
Erick Hitter committed
	 *
Erick Hitter's avatar
Erick Hitter committed
	 * @return array
Erick Hitter's avatar
Erick Hitter committed
	 */
	private function get_settings() {
		static $hash = null;

		$settings = get_option( $this->settings_section, array() );
Erick Hitter's avatar
Erick Hitter committed

		if ( empty( self::$settings ) || $hash !== $this->hash_settings( $settings ) ) {
			$post_types = $this->get_post_types();
Erick Hitter's avatar
Erick Hitter committed

Erick Hitter's avatar
Erick Hitter committed
			if ( ! is_array( $settings ) ) {
				$settings = array();
			}

			$merged_settings = array();
Erick Hitter's avatar
Erick Hitter committed

			foreach ( $post_types as $post_type => $name ) {
Erick Hitter's avatar
Erick Hitter committed
				if ( array_key_exists( $post_type, $settings ) ) {
					$merged_settings[ $post_type ] = (int) $settings[ $post_type ];
Erick Hitter's avatar
Erick Hitter committed
				} else {
					$merged_settings[ $post_type ] = - 1;
				}
			}

			self::$settings = $merged_settings;
			$hash           = $this->hash_settings( self::$settings );
	/**
	 * Hash settings to limit re-parsing.
	 *
	 * @param array $settings Settings array.
	 * @return string
	 */
	private function hash_settings( $settings ) {
		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
		return md5( serialize( $settings ) );
	}

Erick Hitter's avatar
Erick Hitter committed
	 * Retrieve array of supported post types and their labels.
Erick Hitter's avatar
Erick Hitter committed
	 * @return array
	 */
	private function get_post_types() {
		if ( empty( self::$post_types ) ) {
Erick Hitter's avatar
Erick Hitter committed
			foreach ( get_post_types() as $type ) {
				if ( post_type_supports( $type, 'revisions' ) ) {
					$object = get_post_type_object( $type );

Erick Hitter's avatar
Erick Hitter committed
					if ( null === $object ) {
						continue;
					}

					if ( property_exists( $object, 'labels' ) && property_exists( $object->labels, 'name' ) ) {
						$name = $object->labels->name;
Erick Hitter's avatar
Erick Hitter committed
					} else {
Erick Hitter's avatar
Erick Hitter committed
					}

					self::$post_types[ $type ] = $name;
				}
			}
		}
		return self::$post_types;
Erick Hitter's avatar
Erick Hitter committed
	}
Erick Hitter's avatar
Erick Hitter committed

	/**
Erick Hitter's avatar
Erick Hitter committed
	 * Retrieve number of revisions to keep for a given post type.
Erick Hitter's avatar
Erick Hitter committed
	 *
Erick Hitter's avatar
Erick Hitter committed
	 * @param string $post_type     Post type.
	 * @param bool   $blank_for_all Should blank value be used to indicate all are kept.
	 * @return int|string
Erick Hitter's avatar
Erick Hitter committed
	 */
	private function get_revisions_to_keep( $post_type, $blank_for_all = false ) {
Erick Hitter's avatar
Erick Hitter committed
		// wp_revisions_to_keep() accepts a post object, not just the post type.
Erick Hitter's avatar
Erick Hitter committed
		// We construct a new WP_Post object to ensure anything hooked to the wp_revisions_to_keep filter has the same basic data WP provides.
Erick Hitter's avatar
Erick Hitter committed
		$_post   = new WP_Post( (object) array( 'post_type' => $post_type ) );
Erick Hitter's avatar
Erick Hitter committed
		$to_keep = wp_revisions_to_keep( $_post );

		if ( $blank_for_all && ( -1 === $to_keep || '-1' === $to_keep ) ) {
Erick Hitter's avatar
Erick Hitter committed
			return '';
Erick Hitter's avatar
Erick Hitter committed
		} else {
Erick Hitter's avatar
Erick Hitter committed
			return (int) $to_keep;
Erick Hitter's avatar
Erick Hitter committed
		}
Erick Hitter's avatar
Erick Hitter committed
	}
Erick Hitter's avatar
Erick Hitter committed
	 * Retrieve number of revisions to keep for a give post.
Erick Hitter's avatar
Erick Hitter committed
	 * @param int $post_id Post ID.
	 * @return int|string
	 */
	private function get_post_revisions_to_keep( $post_id ) {
		$to_keep = get_post_meta( $post_id, $this->meta_key_limit, true );

		if ( empty( $to_keep ) || -1 === $to_keep || '-1' === $to_keep ) {
Erick Hitter's avatar
Erick Hitter committed
		} else {
			$to_keep = (int) $to_keep;
Erick Hitter's avatar
Erick Hitter committed
		}
Erick Hitter's avatar
Erick Hitter committed
}
Erick Hitter's avatar
Erick Hitter committed

Erick Hitter's avatar
Erick Hitter committed
WP_Revisions_Control::get_instance();