PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.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 All 45 releases
← All changes | models/model-post.php +65 -78 1.9.2 → 3.4 View file →
@@ -7,13 +7,16 @@
7 7 * @author Tobias Bäthge
8 8 * @since 1.0.0
9 9 */
10 10
11 +declare(strict_types=1);
12 +
11 13 // Prohibit direct script loading.
12 14 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13 15
14 16 /**
15 17 * Post Model class
18 + *
16 19 * @package TablePress
17 20 * @subpackage Models
18 21 * @author Tobias Bäthge
19 22 * @since 1.0.0
@@ -23,34 +26,34 @@
23 26 /**
24 27 * Name of the "Custom Post Type" for the tables.
25 28 *
26 29 * @since 1.0.0
27 - * @var string
30 + * @var lowercase-string&non-empty-string
28 31 */
29 - protected $post_type = 'tablepress_table';
32 + protected string $post_type = 'tablepress_table';
30 33
31 34 /**
32 - * Init the model by registering the Custom Post Type.
35 + * Inits the model by registering the Custom Post Type.
33 36 *
34 37 * @since 1.0.0
35 38 */
36 39 public function __construct() {
37 40 parent::__construct();
38 - $this->_register_post_type(); // we are on WP "init" hook already
41 + $this->_register_post_type(); // We are on WP "init" hook already.
39 42 }
40 43
41 44 /**
42 - * Register the Custom Post Type which the tables use.
45 + * Registers the Custom Post Type which the tables use.
43 46 *
44 47 * @since 1.0.0
45 48 */
46 - protected function _register_post_type() {
49 + protected function _register_post_type(): void {
47 50 /**
48 - * Filter the "Custom Post Type" that TablePress uses for storing tables in the database.
51 + * Filters the "Custom Post Type" that TablePress uses for storing tables in the database.
49 52 *
50 53 * @since 1.0.0
51 54 *
52 - * @param string $post_type The "Custom Post Type" that TablePress uses.
55 + * @param lowercase-string&non-empty-string $post_type The "Custom Post Type" that TablePress uses.
53 56 */
54 57 $this->post_type = apply_filters( 'tablepress_post_type', $this->post_type );
55 58 $post_type_args = array(
56 59 'labels' => array(
@@ -65,13 +68,13 @@
65 68 'supports' => array( 'title', 'editor', 'excerpt', 'revisions' ),
66 69 'can_export' => true,
67 70 );
68 71 /**
69 - * Filter the arguments for the registration of the "Custom Post Type" that TablePress uses.
72 + * Filters the arguments for the registration of the "Custom Post Type" that TablePress uses.
70 73 *
71 74 * @since 1.0.0
72 75 *
73 - * @param array $post_type_args Arguments for the registration of the TablePress "Custom Post Type".
76 + * @param array<string, mixed> $post_type_args Arguments for the registration of the TablePress "Custom Post Type".
74 77 */
75 78 $post_type_args = apply_filters( 'tablepress_post_type_args', $post_type_args );
76 79 register_post_type( $this->post_type, $post_type_args );
77 80 }
@@ -76,18 +79,18 @@
76 79 register_post_type( $this->post_type, $post_type_args );
77 80 }
78 81
79 82 /**
80 - * Insert a post with the correct Custom Post Type and default values in the the wp_posts table in the database.
83 + * Inserts a post with the correct Custom Post Type and default values in the wp_posts table in the database.
81 84 *
82 85 * @since 1.0.0
83 86 *
84 - * @param array $post Post to insert.
87 + * @param array<string, mixed> $post Post to insert.
85 88 * @return int|WP_Error Post ID of the inserted post on success, WP_Error on error.
86 89 */
87 - public function insert( array $post ) {
90 + public function insert( array $post ) /* : int|WP_Error */ {
88 91 $default_post = array(
89 - 'ID' => false, // false on new insert, but existing post ID on update
92 + 'ID' => false, // false on new insert, but existing post ID on update.
90 93 'comment_status' => 'closed',
91 94 'ping_status' => 'closed',
92 95 'post_category' => false,
93 96 'post_content' => '',
@@ -106,8 +109,9 @@
106 109
107 110 // Remove balanceTags() from sanitize_post(), as it can destroy the JSON when messing with HTML.
108 111 remove_filter( 'content_save_pre', 'balanceTags', 50 );
109 112 remove_filter( 'excerpt_save_pre', 'balanceTags', 50 );
113 +
110 114 /*
111 115 * Remove possible KSES filtering, as it can destroy the JSON when messing with HTML.
112 116 * KSES filtering is done to table cells individually, when saving.
113 117 */
@@ -114,13 +118,8 @@
114 118 $has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
115 119 if ( $has_kses ) {
116 120 kses_remove_filters();
117 121 }
118 - // Remove filter that adds `rel="noopener noreferrer" to <a> HTML tags, but destroys JSON code. See https://core.trac.wordpress.org/ticket/46316.
119 - $has_targeted_link_rel_filters = ( false !== has_filter( 'content_save_pre', 'wp_targeted_link_rel' ) );
120 - if ( $has_targeted_link_rel_filters ) {
121 - wp_remove_targeted_link_rel_filters();
122 - }
123 122
124 123 $post_id = wp_insert_post( $post, true );
125 124
126 125 // Restore removed content filters.
@@ -128,10 +127,12 @@
128 127 add_filter( 'excerpt_save_pre', 'balanceTags', 50 );
129 128 if ( $has_kses ) {
130 129 kses_init_filters();
131 130 }
132 - if ( $has_targeted_link_rel_filters ) {
133 - wp_init_targeted_link_rel_filters();
131 +
132 + // In rare cases, `wp_insert_post()` returns 0 as the post ID, when an error happens, so it's converted to a WP_Error here.
133 + if ( 0 === $post_id ) { // @phpstan-ignore identical.alwaysFalse (False-positive in the PHPStan WordPress stubs.)
134 + return new WP_Error( 'post_insert', '' );
134 135 }
135 136
136 137 return $post_id;
137 138 }
@@ -136,18 +137,18 @@
136 137 return $post_id;
137 138 }
138 139
139 140 /**
140 - * Update an existing post with the correct Custom Post Type and default values in the the wp_posts table in the database.
141 + * Updates an existing post with the correct Custom Post Type and default values in the wp_posts table in the database.
141 142 *
142 143 * @since 1.0.0
143 144 *
144 - * @param array $post Post.
145 + * @param array<string, mixed> $post Post.
145 146 * @return int|WP_Error Post ID of the updated post on success, WP_Error on error.
146 147 */
147 - public function update( array $post ) {
148 + public function update( array $post ) /* : int|WP_Error */ {
148 149 $default_post = array(
149 - 'ID' => false, // false on new insert, but existing post ID on update
150 + 'ID' => false, // false on new insert, but existing post ID on update.
150 151 'comment_status' => 'closed',
151 152 'ping_status' => 'closed',
152 153 'post_category' => false,
153 154 'post_content' => '',
@@ -163,11 +164,12 @@
163 164 $post = array_merge( $default_post, $post );
164 165 // WP expects everything to be slashed.
165 166 $post = wp_slash( $post );
166 167
167 - // Remove balanceTags() from sanitize_post(), as it can destroy the JSON when messing with HTML
168 + // Remove balanceTags() from sanitize_post(), as it can destroy the JSON when messing with HTML.
168 169 remove_filter( 'content_save_pre', 'balanceTags', 50 );
169 170 remove_filter( 'excerpt_save_pre', 'balanceTags', 50 );
171 +
170 172 /*
171 173 * Remove possible KSES filtering, as it can destroy the JSON when messing with HTML.
172 174 * KSES filtering is done to table cells individually, when saving.
173 175 */
@@ -174,13 +176,8 @@
174 176 $has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
175 177 if ( $has_kses ) {
176 178 kses_remove_filters();
177 179 }
178 - // Remove filter that adds `rel="noopener noreferrer" to <a> HTML tags, but destroys JSON code. See https://core.trac.wordpress.org/ticket/46316.
179 - $has_targeted_link_rel_filters = ( false !== has_filter( 'content_save_pre', 'wp_targeted_link_rel' ) );
180 - if ( $has_targeted_link_rel_filters ) {
181 - wp_remove_targeted_link_rel_filters();
182 - }
183 180
184 181 $post_id = wp_update_post( $post, true );
185 182
186 183 // Restore removed content filters.
@@ -188,24 +185,21 @@
188 185 add_filter( 'excerpt_save_pre', 'balanceTags', 50 );
189 186 if ( $has_kses ) {
190 187 kses_init_filters();
191 188 }
192 - if ( $has_targeted_link_rel_filters ) {
193 - wp_init_targeted_link_rel_filters();
194 - }
195 189
196 190 return $post_id;
197 191 }
198 192
199 193 /**
200 - * Get a post from the wp_posts table in the database.
194 + * Gets a post from the wp_posts table in the database.
201 195 *
202 196 * @since 1.0.0
203 197 *
204 198 * @param int $post_id Post ID.
205 - * @return WP_Post|bool Post on success, false on error.
199 + * @return WP_Post|false Post on success, false on error.
206 200 */
207 - public function get( $post_id ) {
201 + public function get( int $post_id ) /* : WP_Post|false */ {
208 202 $post = get_post( $post_id );
209 203 if ( is_null( $post ) ) {
210 204 return false;
211 205 }
@@ -212,47 +206,47 @@
212 206 return $post;
213 207 }
214 208
215 209 /**
216 - * Delete a post (and all revisions) from the wp_posts table in the database.
210 + * Deletes a post (and all revisions) from the wp_posts table in the database.
217 211 *
218 212 * @since 1.0.0
219 213 *
220 214 * @param int $post_id Post ID.
221 - * @return mixed|bool Post on success, false on error.
215 + * @return WP_Post|false|null Post data on success, false or null on failure.
222 216 */
223 - public function delete( $post_id ) {
224 - return wp_delete_post( $post_id, true ); // true means force delete, although for CPTs this is automatic in this function
217 + public function delete( int $post_id ) /* : WP_Post|false|null */ {
218 + return wp_delete_post( $post_id, true ); // true means force delete, although for CPTs this is automatic in this function.
225 219 }
226 220
227 221 /**
228 - * Move a post to the trash (if trash is globally enabled), instead of directly deleting the post.
222 + * Moves a post to the trash (if trash is globally enabled), instead of directly deleting the post.
229 223 * (yet unused)
230 224 *
231 225 * @since 1.0.0
232 226 *
233 227 * @param int $post_id Post ID.
234 - * @return mixed|bool Post on success, false on error.
228 + * @return WP_Post|false|null Post data on success, false or null on failure.
235 229 */
236 - public function trash( $post_id ) {
230 + public function trash( int $post_id ) /* : WP_Post|false|null */ {
237 231 return wp_trash_post( $post_id );
238 232 }
239 233
240 234 /**
241 - * Restore a post from the trash.
235 + * Restores a post from the trash.
242 236 * (yet unused)
243 237 *
244 238 * @since 1.0.0
245 239 *
246 240 * @param int $post_id Post ID.
247 - * @return array|bool Post on success, false on error.
241 + * @return WP_Post|false|null Post on success, false or null on error.
248 242 */
249 - public function untrash( $post_id ) {
243 + public function untrash( int $post_id ) /* : WP_Post|false */ {
250 244 return wp_untrash_post( $post_id );
251 245 }
252 246
253 247 /**
254 - * Load all posts with one query, to prime the cache.
248 + * Loads all posts with one query, to prime the cache.
255 249 *
256 250 * @since 1.0.0
257 251 *
258 252 * @global wpdb $wpdb WordPress database abstraction object.
@@ -257,25 +251,23 @@
257 251 *
258 252 * @global wpdb $wpdb WordPress database abstraction object.
259 253 * @see get_post()
260 254 *
261 - * @param array $all_post_ids List of Post IDs.
255 + * @param int[] $all_post_ids List of Post IDs.
262 256 * @param bool $update_meta_cache Optional. Whether to update the Post Meta Cache (for table options and visibility).
263 257 */
264 - public function load_posts( array $all_post_ids, $update_meta_cache = true ) {
258 + public function load_posts( array $all_post_ids, bool $update_meta_cache = true ): void {
265 259 global $wpdb;
266 260
267 261 // Split post loading, to save memory.
268 - $offset = 0;
269 - $length = 100; // 100 posts at a time
270 - $number_of_posts = count( $all_post_ids );
271 - while ( $offset < $number_of_posts ) {
272 - $post_ids = array_slice( $all_post_ids, $offset, $length );
262 + while ( ! empty( $all_post_ids ) ) {
263 + $post_ids = array_splice( $all_post_ids, 0, 100 ); // Extract 100 posts at a time.
273 264 // Don't load posts that are in the cache already.
274 265 $post_ids = _get_non_cached_ids( $post_ids, 'posts' );
275 266 if ( ! empty( $post_ids ) ) {
276 267 $post_ids_list = implode( ',', $post_ids );
277 - $posts = $wpdb->get_results( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID IN ({$post_ids_list})" );
268 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
269 + $posts = $wpdb->get_results( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID IN ({$post_ids_list})" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
278 270 update_post_cache( $posts );
279 271 if ( $update_meta_cache ) {
280 272 // Get all post meta data for all table posts, @see get_post_meta().
281 273 update_meta_cache( 'post', $post_ids );
@@ -280,14 +272,13 @@
280 272 // Get all post meta data for all table posts, @see get_post_meta().
281 273 update_meta_cache( 'post', $post_ids );
282 274 }
283 275 }
284 - $offset += $length; // next array_slice() $offset
285 276 }
286 277 }
287 278
288 279 /**
289 - * Count the number of posts with the model's CPT in the wp_posts table in the database.
280 + * Counts the number of posts with the model's CPT in the wp_posts table in the database.
290 281 * (currently for debug only)
291 282 *
292 283 * @since 1.0.0
293 284 *
@@ -292,14 +283,14 @@
292 283 * @since 1.0.0
293 284 *
294 285 * @return int Number of posts.
295 286 */
296 - public function count_posts() {
297 - return array_sum( (array) wp_count_posts( $this->post_type ) ); // original return value is object with the counts for each post_status
287 + public function count_posts(): int {
288 + return array_sum( (array) wp_count_posts( $this->post_type ) ); // Original return value is object with the counts for each post_status.
298 289 }
299 290
300 291 /**
301 - * Add a post meta field to a post.
292 + * Adds a post meta field to a post.
302 293 *
303 294 * @since 1.0.0
304 295 *
305 296 * @param int $post_id ID of the post for which the field shall be added.
@@ -306,12 +297,10 @@
306 297 * @param string $field Name of the post meta field.
307 298 * @param string $value Value of the post meta field (not slashed).
308 299 * @return bool True on success, false on error.
309 300 */
310 - public function add_meta_field( $post_id, $field, $value ) {
311 - // WP expects a slashed value.
312 - $value = wp_slash( $value );
313 - $success = add_post_meta( $post_id, $field, $value, true ); // true means unique
301 + public function add_meta_field( int $post_id, string $field, string $value ): bool {
302 + $success = add_post_meta( $post_id, wp_slash( $field ), wp_slash( $value ), true ); // WP expects slashed values, `true` means unique.
314 303 // Make sure that $success is a boolean, as add_post_meta() returns an ID or false.
315 304 $success = ( false === $success ) ? false : true;
316 305 return $success;
317 306 }
@@ -316,9 +305,9 @@
316 305 return $success;
317 306 }
318 307
319 308 /**
320 - * Update the value of a post meta field of a post.
309 + * Updatse the value of a post meta field of a post.
321 310 *
322 311 * If the field does not yet exist, it is added.
323 312 *
324 313 * @since 1.0.0
@@ -327,9 +316,9 @@
327 316 * @param string $field Name of the post meta field.
328 317 * @param string $value Value of the post meta field (not slashed).
329 318 * @return bool True on success, false on error.
330 319 */
331 - public function update_meta_field( $post_id, $field, $value ) {
320 + public function update_meta_field( int $post_id, string $field, string $value ): bool {
332 321 $prev_value = (string) get_post_meta( $post_id, $field, true );
333 322 // No need to update, if values are equal (also, update_post_meta() would return false for this).
334 323 if ( $prev_value === $value ) {
335 324 return true;
@@ -334,15 +323,13 @@
334 323 if ( $prev_value === $value ) {
335 324 return true;
336 325 }
337 326
338 - // WP expects a slashed value.
339 - $value = wp_slash( $value );
340 - return update_post_meta( $post_id, $field, $value, $prev_value );
327 + return (bool) update_post_meta( $post_id, wp_slash( $field ), wp_slash( $value ), $prev_value ); // WP expects slashed values.
341 328 }
342 329
343 330 /**
344 - * Get the value of a post meta field of a post.
331 + * Gets the value of a post meta field of a post.
345 332 *
346 333 * @since 1.0.0
347 334 *
348 335 * @param int $post_id ID of the post for which the field shall be retrieved.
@@ -348,14 +335,14 @@
348 335 * @param int $post_id ID of the post for which the field shall be retrieved.
349 336 * @param string $field Name of the post meta field.
350 337 * @return string Value of the meta field.
351 338 */
352 - public function get_meta_field( $post_id, $field ) {
353 - return get_post_meta( $post_id, $field, true ); // true means single value
339 + public function get_meta_field( int $post_id, string $field ): string {
340 + return get_post_meta( $post_id, $field, true ); // `true` means single value.
354 341 }
355 342
356 343 /**
357 - * Delete a post meta field of a post.
344 + * Deletes a post meta field of a post.
358 345 * (yet unused)
359 346 *
360 347 * @since 1.0.0
361 348 *
@@ -362,20 +349,20 @@
362 349 * @param int $post_id ID of the post of which the field shall be deleted.
363 350 * @param string $field Name of the post meta field.
364 351 * @return bool True on success, false on error.
365 352 */
366 - public function delete_meta_field( $post_id, $field ) {
367 - return delete_post_meta( $post_id, $field, true ); // true means single value
353 + public function delete_meta_field( int $post_id, string $field ): bool {
354 + return delete_post_meta( $post_id, wp_slash( $field ) ); // WP expects a slashed value.
368 355 }
369 356
370 357 /**
371 - * Return the Custom Post Type that TablePress uses.
358 + * Returns the Custom Post Type that TablePress uses.
372 359 *
373 360 * @since 1.5.0
374 361 *
375 362 * @return string The used Custom Post Type.
376 363 */
377 - public function get_post_type() {
364 + public function get_post_type(): string {
378 365 return $this->post_type;
379 366 }
380 367
381 368 } // class TablePress_Post_Model