wp-revisions-control.php 6.4 KB
Newer Older
Erick Hitter's avatar
Erick Hitter committed
1
2
3
<?php
/*
Plugin Name: WP Revisions Control
Erick Hitter's avatar
Erick Hitter committed
4
Plugin URI: http://www.ethitter.com/plugins/wp-revisions-control/
Erick Hitter's avatar
Erick Hitter committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Description: Control how many revisions are stored for each post type
Author: Erick Hitter
Version: 0.1
Author URI: http://www.ethitter.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
*/

class WP_Revisions_Control {
	/**
	 * Singleton
	 */
	private static $__instance = null;

	/**
	 * Class variables
	 */
34
	private static $post_types = array();
Erick Hitter's avatar
Erick Hitter committed
35

36
37
38
	private $settings_page = 'writing';
	private $settings_section = 'wp_revisions_control';

Erick Hitter's avatar
Erick Hitter committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
	/**
	 * Silence is golden!
	 */
	private function __construct() {}

	/**
	 * Singleton implementation
	 *
	 * @uses self::setup
	 * @return object
	 */
	public static function get_instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;

			self::$__instance->setup();
		}

		return self::$__instance;
	}

	/**
	 * Register actions and filters
	 *
	 * @uses add_action
	 * @uses add_filter
	 * @return null
	 */
	private function setup() {
68
		add_action( 'admin_init', array( $this, 'action_admin_init' ) );
Erick Hitter's avatar
Erick Hitter committed
69
70

		add_filter( 'wp_revisions_to_keep', array( $this, 'filter_wp_revisions_to_keep' ), 10, 2 );
71
72
73
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
74
	 * Register plugin's settings fields
75
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
76
77
78
79
80
81
82
	 * @uses register_setting
	 * @uses add_settings_section
	 * @uses __
	 * @uses this::get_post_types
	 * @uses add_settings_field
	 * @action admin_init
	 * @return null
83
84
	 */
	public function action_admin_init() {
Erick Hitter's avatar
Erick Hitter committed
85
		register_setting( $this->settings_page, $this->settings_section, array( $this, 'sanitize_options' ) );
86

87
		add_settings_section( $this->settings_section, 'WP Revisions Control', array( $this, 'settings_section_intro' ), $this->settings_page );
88
89
90
91
92
93

		foreach ( $this->get_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 ) );
		}
	}

94
	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
95
	 * Display assistive text in settings section
96
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
97
98
	 * @uses _e
	 * @return string
99
100
101
102
103
104
105
106
	 */
	public function settings_section_intro() {
		?>
		<p><?php _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 _e( "If a post type isn't listed, revisions are not enabled for that post type.", 'wp_revisions_control' ); ?></p>
		<?php
	}

107
	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
108
	 * Render field for each post type
109
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
110
111
112
113
	 * @param array $args
	 * @uses this::get_revisions_to_keep
	 * @uses esc_attr
	 * @return string
114
115
	 */
	public function field_post_type( $args ) {
Erick Hitter's avatar
Erick Hitter committed
116
117
		$revisions_to_keep = $this->get_revisions_to_keep( $args['post_type'], true );
		?>
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
118
		<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
119
		<?php
120
121
122
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
123
	 * Sanitize plugin settings
124
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
125
126
	 * @param array $options
	 * @return array
127
128
	 */
	public function sanitize_options( $options ) {
Erick Hitter's avatar
Erick Hitter committed
129
130
131
132
		$options_sanitized = array();

		if ( is_array( $options ) ) {
			foreach ( $options as $post_type => $to_keep ) {
133
				if ( 0 === strlen( $to_keep ) )
Erick Hitter's avatar
Erick Hitter committed
134
135
136
					$to_keep = -1;
				else
					$to_keep = intval( $to_keep );
137

138
139
140
141
				// Lowest possible value is -1, used to indicate infinite revisions are stored
				if ( -1 > $to_keep )
					$to_keep = -1;

Erick Hitter's avatar
Erick Hitter committed
142
143
144
145
146
147
148
149
				$options_sanitized[ $post_type ] = $to_keep;
			}
		}

		return $options_sanitized;
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
150
	 * Override number of revisions to keep using plugin's settings
Erick Hitter's avatar
Erick Hitter committed
151
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
152
153
154
155
	 * @uses get_post_type
	 * @uses this::get_settings
	 * @filter wp_revisions_to_keep
	 * @return mixed
Erick Hitter's avatar
Erick Hitter committed
156
157
158
159
160
161
162
163
164
165
166
167
	 */
	public function filter_wp_revisions_to_keep( $qty, $post ) {
		$post_type = get_post_type( $post ) ? get_post_type( $post ) : $post->post_type;
		$settings = $this->get_settings();

		if ( array_key_exists( $post_type, $settings ) )
			return $settings[ $post_type ];

		return $qty;
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
168
	 * Retrieve plugin settings
Erick Hitter's avatar
Erick Hitter committed
169
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
170
171
172
	 * @uses this::get_post_types
	 * @uses get_option
	 * @return array
Erick Hitter's avatar
Erick Hitter committed
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
	 */
	private function get_settings() {
		$post_types = $this->get_post_types();

		$settings = get_option( $this->settings_section, array() );

		$merged_settings = array();

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

		return $merged_settings;
189
190
191
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
192
	 * Retrieve array of supported post types and their labels
193
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
194
195
196
197
	 * @uses get_post_types
	 * @uses post_type_supports
	 * @uses get_post_type_object
	 * @return array
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	 */
	private function get_post_types() {
		if ( empty( self::$post_types ) ) {
			$types = get_post_types();

			foreach ( $types as $type ) {
				if ( post_type_supports( $type, 'revisions' ) ) {
					$object = get_post_type_object( $type );

					if ( property_exists( $object, 'labels' ) && property_exists( $object->labels, 'name' ) )
						$name = $object->labels->name;
					else
						$name = $object->name;

					self::$post_types[ $type ] = $name;
				}
			}

			self::$post_types = array_unique( self::$post_types );
		}
Erick Hitter's avatar
Erick Hitter committed
218

219
		return self::$post_types;
Erick Hitter's avatar
Erick Hitter committed
220
	}
Erick Hitter's avatar
Erick Hitter committed
221
222

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
223
	 * Retrieve number of revisions to keep for a given post type
Erick Hitter's avatar
Erick Hitter committed
224
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
225
226
227
	 * @uses WP_Post
	 * @uses wp_revisions_to_keep
	 * @return mixed
Erick Hitter's avatar
Erick Hitter committed
228
229
230
231
232
233
234
235
236
237
238
239
	 */
	private function get_revisions_to_keep( $post_type, $blank_for_all = false ) {
		// wp_revisions_to_keep() accepts a post object, not just the post type
		// 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.
		$_post = new WP_Post( (object) array( 'post_type' => $post_type ) );
		$to_keep = wp_revisions_to_keep( $_post );

		if ( $blank_for_all && -1 == $to_keep )
			return '';
		else
			return (int) $to_keep;
	}
Erick Hitter's avatar
Erick Hitter committed
240
241
}
WP_Revisions_Control::get_instance();