class-wp-revisions-control-bulk-actions.php 5.33 KB
Newer Older
Erick Hitter's avatar
Erick Hitter committed
1 2 3 4 5 6 7 8 9 10 11
<?php
/**
 * Bulk actions.
 *
 * @package WP_Revisions_Control
 */

/**
 * Class WP_Revisions_Control_Bulk_Actions.
 */
class WP_Revisions_Control_Bulk_Actions {
12 13 14 15 16 17 18
	/**
	 * Singleton.
	 *
	 * @var static
	 */
	private static $__instance;

Erick Hitter's avatar
Erick Hitter committed
19 20 21 22 23 24 25
	/**
	 * Supported post types.
	 *
	 * @var array
	 */
	protected $post_types;

26 27 28 29 30 31 32
	/**
	 * Base for bulk action names.
	 *
	 * @var string
	 */
	protected $action_base = 'wp_rev_ctl_bulk_';

Erick Hitter's avatar
Erick Hitter committed
33 34 35 36 37 38 39 40
	/**
	 * Custom bulk actions.
	 *
	 * @var array
	 */
	protected $actions;

	/**
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	 * Silence is golden!
	 */
	private function __construct() {}

	/**
	 * Singleton implementation.
	 *
	 * @param array $post_types Supported post types, used only on instantiation.
	 * @return static
	 */
	public static function get_instance( $post_types = array() ) {
		if ( ! is_a( static::$__instance, __CLASS__ ) ) {
			static::$__instance = new self();

			static::$__instance->setup( $post_types );
		}

		return static::$__instance;
	}

	/**
	 * One-time actions.
Erick Hitter's avatar
Erick Hitter committed
63 64 65
	 *
	 * @param array $post_types Supported post types.
	 */
66
	public function setup( $post_types ) {
Erick Hitter's avatar
Erick Hitter committed
67 68 69 70 71 72 73
		if ( empty( $post_types ) || ! is_array( $post_types ) ) {
			return;
		}

		$this->post_types = $post_types;
		$this->register_actions();

74
		add_action( 'load-edit.php', array( $this, 'register_admin_hooks' ) );
Erick Hitter's avatar
Erick Hitter committed
75
		add_filter( 'removable_query_args', array( $this, 'remove_message_query_args' ) );
Erick Hitter's avatar
Erick Hitter committed
76 77 78 79 80 81
	}

	/**
	 * Register custom actions.
	 */
	protected function register_actions() {
82
		$actions = array();
Erick Hitter's avatar
Erick Hitter committed
83

84 85
		$actions[ $this->action_base . 'purge_excess' ] = __( 'Purge excess revisions', 'wp_revisions_control' );
		$actions[ $this->action_base . 'purge_all' ]    = __( 'Purge ALL revisions', 'wp_revisions_control' );
Erick Hitter's avatar
Erick Hitter committed
86 87 88 89 90 91 92

		$this->actions = $actions;
	}

	/**
	 * Register various hooks.
	 */
93
	public function register_admin_hooks() {
Erick Hitter's avatar
Erick Hitter committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
		$screen = get_current_screen();

		if ( null === $screen ) {
			return;
		}

		$post_types = array_keys( $this->post_types );

		if ( ! in_array( $screen->post_type, $post_types, true ) ) {
			return;
		}

		if ( 'edit' !== $screen->base ) {
			return;
		}

		add_filter( 'bulk_actions-' . $screen->id, array( $this, 'add_actions' ) );
		add_filter( 'handle_bulk_actions-' . $screen->id, array( $this, 'handle_action' ), 10, 3 );
Erick Hitter's avatar
Erick Hitter committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
		add_action( 'admin_notices', array( $this, 'admin_notices' ) );
	}

	/**
	 * Remove message query arguments to prevent re-display.
	 *
	 * @param array $args Array of query variables to remove from URL.
	 * @return array
	 */
	public function remove_message_query_args( $args ) {
		return array_merge( $args, $this->get_message_query_args() );
	}

	/**
	 * Return array of supported query args that trigger admin notices.
	 *
	 * @return array
	 */
	protected function get_message_query_args() {
		$args   = array_keys( $this->actions );
		$args[] = $this->action_base . 'missing';

		return $args;
Erick Hitter's avatar
Erick Hitter committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
	}

	/**
	 * Add our actions.
	 *
	 * @param string[] $actions Array of available actions.
	 * @return array
	 */
	public function add_actions( $actions ) {
		return array_merge( $actions, $this->actions );
	}

	/**
	 * Handle our bulk actions.
	 *
	 * @param string $redirect_to Redirect URL.
	 * @param string $action      Bulk action being taken.
	 * @param array  $ids         Object IDs to manipulate.
	 * @return string
	 */
	public function handle_action( $redirect_to, $action, $ids ) {
		if ( ! array_key_exists( $action, $this->actions ) ) {
			return $redirect_to;
		}

160
		$response = array_fill_keys( $this->get_message_query_args(), 0 );
161

Erick Hitter's avatar
Erick Hitter committed
162
		switch ( str_replace( $this->action_base, '', $action ) ) {
163 164
			case 'purge_all':
				$this->purge_all( $ids );
165
				$response[ $action ] = 1;
166 167 168 169
				break;

			case 'purge_excess':
				$this->purge_excess( $ids );
170
				$response[ $action ] = 1;
171 172 173
				break;

			default:
174
				$response[ $this->action_base . 'missing' ] = 1;
175 176 177
				break;
		}

Erick Hitter's avatar
Erick Hitter committed
178 179 180 181
		if ( is_array( $response ) ) {
			$redirect_to = add_query_arg( $response, $redirect_to );
		}

Erick Hitter's avatar
Erick Hitter committed
182 183
		return $redirect_to;
	}
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205

	/**
	 * Remove all revisions from the given IDs.
	 *
	 * @param array $ids Object IDs.
	 */
	protected function purge_all( $ids ) {
		foreach ( $ids as $id ) {
			WP_Revisions_Control::get_instance()->do_purge_all( $id );
		}
	}

	/**
	 * Remove excess revisions from the given IDs.
	 *
	 * @param array $ids Object IDs.
	 */
	protected function purge_excess( $ids ) {
		foreach ( $ids as $id ) {
			WP_Revisions_Control::get_instance()->do_purge_excess( $id );
		}
	}
Erick Hitter's avatar
Erick Hitter committed
206 207 208 209 210 211 212 213 214

	/**
	 * Render admin notices.
	 */
	public function admin_notices() {
		$message = null;

		foreach ( $this->get_message_query_args() as $arg ) {
			// phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
215
			if ( isset( $_GET[ $arg ] ) && 1 === (int) $_GET[ $arg ] ) {
Erick Hitter's avatar
Erick Hitter committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
				$message = $arg;
				break;
			}
		}

		if ( null === $message ) {
			return;
		}

		$type = 'updated';

		switch ( str_replace( $this->action_base, '', $message ) ) {
			case 'purge_all':
				$message = __(
					'Purged all revisions.',
					'wp_revisions_control'
				);
				break;

			case 'purge_excess':
				$message = __(
					'Purged excess revisions.',
					'wp_revisions_control'
				);
				break;

			default:
			case 'missing':
				$message = __(
					'WP Revisions Control encountered an unspecified error.',
					'wp_revisions_control'
				);
				$type    = 'error';
				break;
		}

		?>
		<div class="notice is-dismissible <?php echo esc_attr( $type ); ?>">
			<p><?php echo esc_html( $message ); ?></p>
		</div>
		<?php
	}
Erick Hitter's avatar
Erick Hitter committed
258
}