wp-revisions-control.php 6.46 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
Description: Control how many revisions are stored for each post type
Author: Erick Hitter
Erick Hitter's avatar
Erick Hitter committed
7
Version: 1.0
Erick Hitter's avatar
Erick Hitter committed
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
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();
35
	private static $settings = array();
Erick Hitter's avatar
Erick Hitter committed
36

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

Erick Hitter's avatar
Erick Hitter committed
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
68
	/**
	 * 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() {
69
		add_action( 'admin_init', array( $this, 'action_admin_init' ) );
Erick Hitter's avatar
Erick Hitter committed
70
71

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

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

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

		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 ) );
		}
	}

95
	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
96
	 * Display assistive text in settings section
97
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
98
99
	 * @uses _e
	 * @return string
100
101
102
103
104
105
106
107
	 */
	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
	}

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

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

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

139
140
141
142
				// 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
143
144
145
146
147
148
149
150
				$options_sanitized[ $post_type ] = $to_keep;
			}
		}

		return $options_sanitized;
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
151
	 * Override number of revisions to keep using plugin's settings
Erick Hitter's avatar
Erick Hitter committed
152
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
153
154
155
156
	 * @uses get_post_type
	 * @uses this::get_settings
	 * @filter wp_revisions_to_keep
	 * @return mixed
Erick Hitter's avatar
Erick Hitter committed
157
158
159
160
161
162
163
164
165
166
167
168
	 */
	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
169
	 * Retrieve plugin settings
Erick Hitter's avatar
Erick Hitter committed
170
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
171
172
173
	 * @uses this::get_post_types
	 * @uses get_option
	 * @return array
Erick Hitter's avatar
Erick Hitter committed
174
175
	 */
	private function get_settings() {
176
177
		if ( empty( self::$settings ) ) {
			$post_types = $this->get_post_types();
Erick Hitter's avatar
Erick Hitter committed
178

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

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

183
184
185
186
187
188
189
190
			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;
			}

			self::$settings = $merged_settings;
Erick Hitter's avatar
Erick Hitter committed
191
192
		}

193
		return self::$settings;
194
195
196
	}

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
197
	 * Retrieve array of supported post types and their labels
198
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
199
200
201
202
	 * @uses get_post_types
	 * @uses post_type_supports
	 * @uses get_post_type_object
	 * @return array
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	 */
	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;
				}
			}
		}
Erick Hitter's avatar
Erick Hitter committed
221

222
		return self::$post_types;
Erick Hitter's avatar
Erick Hitter committed
223
	}
Erick Hitter's avatar
Erick Hitter committed
224
225

	/**
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
226
	 * Retrieve number of revisions to keep for a given post type
Erick Hitter's avatar
Erick Hitter committed
227
	 *
Erick Hitter's avatar
PHPDoc  
Erick Hitter committed
228
229
230
	 * @uses WP_Post
	 * @uses wp_revisions_to_keep
	 * @return mixed
Erick Hitter's avatar
Erick Hitter committed
231
232
233
234
235
236
237
238
239
240
241
242
	 */
	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
243
244
}
WP_Revisions_Control::get_instance();