PluginProbe
TablePress – Tables in WordPress made easy / 2.4.4
TablePress – Tables in WordPress made easy v2.4.4
3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 2.4.4 All 44 releases
tablepress / models / model-options.php

model-options.php in TablePress – Tables in WordPress made easy 2.4.4, at models/model-options.php

394 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Options Model
4 *
5 * @package TablePress
6 * @subpackage Models
7 * @author Tobias Bäthge
8 * @since 1.0.0
9 */
10
11 // Prohibit direct script loading.
12 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13
14 /**
15 * Options Model class
16 *
17 * @package TablePress
18 * @subpackage Models
19 * @author Tobias Bäthge
20 * @since 1.0.0
21 */
22 class TablePress_Options_Model extends TablePress_Model {
23
24 /**
25 * Default Plugin Options.
26 *
27 * @since 1.0.0
28 * @since 2.0.0 Added the "modules" option.
29 * @var array<string, mixed>
30 */
31 protected $default_plugin_options = array(
32 'plugin_options_db_version' => 0,
33 'table_scheme_db_version' => 0,
34 'prev_tablepress_version' => '0',
35 'tablepress_version' => TablePress::version,
36 'first_activation' => 0,
37 'message_plugin_update' => false,
38 'message_donation_nag' => true,
39 'use_custom_css' => true,
40 'use_custom_css_file' => true,
41 'custom_css' => '',
42 'custom_css_minified' => '',
43 'custom_css_version' => 0,
44 'modules' => false,
45 );
46
47 /**
48 * Default User Options.
49 *
50 * @since 1.0.0
51 * @var array<string, mixed>>
52 */
53 protected $default_user_options = array(
54 'user_options_db_version' => TablePress::db_version, // To prevent saving on first load.
55 'admin_menu_parent_page' => 'middle',
56 'message_first_visit' => true,
57 'message_superseded_extensions' => true,
58 'table_editor_column_width' => '170', // Default column width of 170px of the table editor on the "Edit" screen.
59 'table_editor_line_clamp' => '5', // Maximum number of lines per cell in the table editor on the "Edit" screen.
60 );
61
62 /**
63 * Instance of WP_Option class for Plugin Options.
64 *
65 * @since 1.0.0
66 * @var TablePress_WP_Option
67 */
68 protected $plugin_options;
69
70 /**
71 * Instance of WP_User_Option class for User Options.
72 *
73 * @since 1.0.0
74 * @var TablePress_WP_User_Option
75 */
76 protected $user_options;
77
78 /**
79 * Init Options Model by creating the object instances for the Plugin and User Options.
80 *
81 * @since 1.0.0
82 */
83 public function __construct() {
84 parent::__construct();
85
86 $params = array(
87 'option_name' => 'tablepress_plugin_options',
88 'default_value' => $this->default_plugin_options,
89 );
90 $this->plugin_options = TablePress::load_class( 'TablePress_WP_Option', 'class-wp_option.php', 'classes', $params );
91
92 $params = array(
93 'option_name' => 'tablepress_user_options',
94 'default_value' => $this->default_user_options,
95 );
96 $this->user_options = TablePress::load_class( 'TablePress_WP_User_Option', 'class-wp_user_option.php', 'classes', $params );
97
98 // Filter to map Meta capabilities to Primitive Capabilities.
99 add_filter( 'map_meta_cap', array( $this, 'map_tablepress_meta_caps' ), 10, 4 );
100 }
101
102 /**
103 * Update a single option or an array of options with new values.
104 *
105 * @since 1.0.0
106 *
107 * @param array<string, mixed>|string $new_options Array of new options (name => value) or name of a single option.
108 * @param mixed $single_value Optional. New value for a single option (only if $new_options is not an array).
109 */
110 public function update( /* array|string */ $new_options, /* string|bool|int|float|null */ $single_value = null ): void {
111 // Allow saving of single options that are not in an array.
112 if ( ! is_array( $new_options ) ) {
113 $new_options = array( $new_options => $single_value );
114 }
115
116 $plugin_options = $this->plugin_options->get();
117 $user_options = $this->user_options->get();
118 foreach ( $new_options as $name => $value ) {
119 if ( isset( $this->default_plugin_options[ $name ] ) ) {
120 $plugin_options[ $name ] = $value;
121 } elseif ( isset( $this->default_user_options[ $name ] ) ) {
122 $user_options[ $name ] = $value;
123 } else { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedElse
124 // No valid Plugin or User Option -> discard the name/value pair.
125 }
126 }
127
128 $this->plugin_options->update( $plugin_options );
129 $this->user_options->update( $user_options );
130 }
131
132 /**
133 * Get the value of a single option, or an array with all options.
134 *
135 * @since 1.0.0
136 *
137 * @param string|false $name Optional. Name of a single option to get, or false for all options.
138 * @param mixed $default_value Optional. Default value, if the option $name does not exist.
139 * @return mixed Value of the retrieved option $name, or $default_value if it does not exist, or array of all options.
140 */
141 public function get( /* string|false */ $name = false, /* string|bool|int|float|null */ $default_value = null ) /* : string|bool|int|float|array|null */ {
142 if ( false === $name ) {
143 return array_merge( $this->plugin_options->get(), $this->user_options->get() );
144 }
145
146 // Single Option wanted.
147 if ( $this->plugin_options->is_set( $name ) ) {
148 return $this->plugin_options->get( $name );
149 } elseif ( $this->user_options->is_set( $name ) ) {
150 return $this->user_options->get( $name );
151 } else {
152 // No valid Plugin or User Option.
153 return $default_value;
154 }
155 }
156
157 /**
158 * Get all Plugin Options (only used in Debug).
159 *
160 * @since 1.0.0
161 *
162 * @return array<string, mixed> Array of all Plugin Options.
163 */
164 public function _debug_get_plugin_options(): array {
165 return $this->plugin_options->get();
166 }
167
168 /**
169 * Get all User Options (only used in Debug).
170 *
171 * @since 1.0.0
172 *
173 * @return array<string, mixed> Array of all User Options.
174 */
175 public function _debug_get_user_options(): array {
176 return $this->user_options->get();
177 }
178
179 /**
180 * Merge existing Plugin Options with default Plugin Options,
181 * remove (no longer) existing options, e.g. after a plugin update.
182 *
183 * @since 1.0.0
184 */
185 public function merge_plugin_options_defaults(): void {
186 $plugin_options = $this->plugin_options->get();
187 // Remove old (i.e. no longer existing) Plugin Options.
188 $plugin_options = array_intersect_key( $plugin_options, $this->default_plugin_options );
189 // Merge current into new Plugin Options.
190 $plugin_options = array_merge( $this->default_plugin_options, $plugin_options );
191
192 $this->plugin_options->update( $plugin_options );
193 }
194
195 /**
196 * Merge existing User Options with default User Options,
197 * remove (no longer) existing options, e.g. after a plugin update.
198 *
199 * @since 1.0.0
200 */
201 public function merge_user_options_defaults(): void {
202 $user_options = $this->user_options->get();
203 // Remove old (i.e. no longer existing) User Options.
204 $user_options = array_intersect_key( $user_options, $this->default_user_options );
205 // Merge current into new User Options.
206 $user_options = array_merge( $this->default_user_options, $user_options );
207
208 $this->user_options->update( $user_options );
209 }
210
211 /**
212 * Adds the TablePress default capabilities to the "Administrator", "Editor", and "Author" user roles.
213 *
214 * @since 1.0.0
215 */
216 public function add_access_capabilities(): void {
217 // Capabilities for all roles.
218 $roles = array( 'administrator', 'editor', 'author' );
219 foreach ( $roles as $role ) {
220 $role = get_role( $role );
221 if ( empty( $role ) ) {
222 continue;
223 }
224
225 // From get_post_type_capabilities().
226 $role->add_cap( 'tablepress_edit_tables' );
227 // $role->add_cap( 'tablepress_edit_others_tables' );
228 $role->add_cap( 'tablepress_delete_tables' );
229 // $role->add_cap( 'tablepress_delete_others_tables' );
230
231 // Custom capabilities.
232 $role->add_cap( 'tablepress_list_tables' );
233 $role->add_cap( 'tablepress_add_tables' );
234 $role->add_cap( 'tablepress_copy_tables' );
235 $role->add_cap( 'tablepress_import_tables' );
236 $role->add_cap( 'tablepress_export_tables' );
237 $role->add_cap( 'tablepress_access_options_screen' );
238 $role->add_cap( 'tablepress_access_about_screen' );
239 }
240
241 // Capabilities for single roles.
242 $role = get_role( 'administrator' );
243 if ( ! empty( $role ) ) {
244 $role->add_cap( 'tablepress_edit_options' );
245 $role->add_cap( 'tablepress_import_tables_url' );
246 }
247 $role = get_role( 'editor' );
248 if ( ! empty( $role ) ) {
249 $role->add_cap( 'tablepress_import_tables_url' );
250 }
251
252 // Refresh current set of capabilities of the user, to be able to directly use the new caps.
253 $user = wp_get_current_user();
254 $user->get_role_caps();
255 }
256
257 /**
258 * Adds a custom "Import from URL" access capability to the "Editor" and "Administrator" user roles.
259 *
260 * @since 2.3.2
261 */
262 public function add_access_capabilities_tp232(): void {
263 $roles = array( 'administrator', 'editor' );
264 foreach ( $roles as $role ) {
265 $role = get_role( $role );
266 if ( ! empty( $role ) ) {
267 $role->add_cap( 'tablepress_import_tables_url' );
268 }
269 }
270
271 // Refresh current set of capabilities of the user, to be able to directly use the new caps.
272 $user = wp_get_current_user();
273 $user->get_role_caps();
274 }
275
276 /**
277 * Remove all TablePress capabilities from all roles.
278 *
279 * @since 1.1.0
280 *
281 * @global WP_Roles $wp_roles WordPress User Roles abstraction object.
282 * @see add_access_capabilities()
283 */
284 public function remove_access_capabilities(): void {
285 global $wp_roles;
286
287 if ( ! isset( $wp_roles ) ) {
288 $wp_roles = new WP_Roles(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
289 }
290
291 foreach ( $wp_roles->roles as $role => $details ) {
292 $role = $wp_roles->get_role( $role );
293 if ( empty( $role ) ) {
294 continue;
295 }
296
297 $role->remove_cap( 'tablepress_edit_tables' );
298 $role->remove_cap( 'tablepress_delete_tables' );
299 $role->remove_cap( 'tablepress_list_tables' );
300 $role->remove_cap( 'tablepress_add_tables' );
301 $role->remove_cap( 'tablepress_copy_tables' );
302 $role->remove_cap( 'tablepress_import_tables' );
303 $role->remove_cap( 'tablepress_export_tables' );
304 $role->remove_cap( 'tablepress_access_options_screen' );
305 $role->remove_cap( 'tablepress_access_about_screen' );
306 $role->remove_cap( 'tablepress_import_tables_wptr' ); // No longer used since 1.10, but might still be in the database.
307 $role->remove_cap( 'tablepress_edit_options' );
308 }
309
310 // Refresh current set of capabilities of the user, to be able to directly use the new caps.
311 $user = wp_get_current_user();
312 $user->get_role_caps();
313 }
314
315 /**
316 * Map TablePress meta capabilities to primitive capabilities.
317 *
318 * @since 1.0.0
319 *
320 * @param string[] $caps Current set of primitive caps.
321 * @param string $cap Meta cap that is to be checked/mapped.
322 * @param int $user_id User ID for which meta cap is to be checked.
323 * @param mixed[] $args Arguments for the check, here e.g. the table ID.
324 * @return string[] Modified set of primitive caps.
325 */
326 public function map_tablepress_meta_caps( array $caps, /* string */ $cap, int $user_id, array $args ): array {
327 // Don't use a type hint for the `$cap` argument as many WordPress plugins seem to be passing `null` to capability check or admin menu functions.
328
329 // Protect against other plugins not supplying a string for the `$cap` argument.
330 if ( ! is_string( $cap ) ) {
331 return $caps;
332 }
333
334 if ( ! in_array( $cap, array( 'tablepress_edit_table', 'tablepress_edit_table_id', 'tablepress_copy_table', 'tablepress_delete_table', 'tablepress_export_table', 'tablepress_preview_table' ), true ) ) {
335 return $caps;
336 }
337
338 // $table_id = ( ! empty( $args ) ) ? $args[0] : false;
339
340 // Reset current set of primitive caps.
341 $caps = array();
342
343 switch ( $cap ) {
344 case 'tablepress_edit_table':
345 $caps[] = 'tablepress_edit_tables';
346 break;
347 case 'tablepress_edit_table_id':
348 $caps[] = 'tablepress_edit_tables';
349 break;
350 case 'tablepress_copy_table':
351 $caps[] = 'tablepress_copy_tables';
352 break;
353 case 'tablepress_delete_table':
354 $caps[] = 'tablepress_delete_tables';
355 break;
356 case 'tablepress_export_table':
357 $caps[] = 'tablepress_export_tables';
358 break;
359 case 'tablepress_preview_table':
360 $caps[] = 'tablepress_edit_tables';
361 break;
362 default:
363 // Something went wrong, deny access to be on the safe side.
364 $caps[] = 'do_not_allow';
365 break;
366 }
367
368 /**
369 * Filters a user's TablePress capabilities.
370 *
371 * @since 1.0.0
372 *
373 * @see map_meta_cap()
374 *
375 * @param string[] $caps The user's current TablePress capabilities.
376 * @param string $cap Capability name.
377 * @param int $user_id The user ID.
378 * @param mixed[] $args Adds the context to the cap, typically the table ID.
379 */
380 return apply_filters( 'tablepress_map_meta_caps', $caps, $cap, $user_id, $args );
381 }
382
383 /**
384 * Delete the WP_Option and the user option of the model.
385 *
386 * @since 1.0.0
387 */
388 public function destroy(): void {
389 $this->plugin_options->delete();
390 $this->user_options->delete_for_all_users();
391 }
392
393 } // class TablePress_Options_Model
394