PluginProbe
TablePress – Tables in WordPress made easy / 1.12
TablePress – Tables in WordPress made easy v1.12
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-post.php

model-post.php in TablePress – Tables in WordPress made easy 1.12, at models/model-post.php

382 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Post 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 * Post Model class
16 * @package TablePress
17 * @subpackage Models
18 * @author Tobias Bäthge
19 * @since 1.0.0
20 */
21 class TablePress_Post_Model extends TablePress_Model {
22
23 /**
24 * Name of the "Custom Post Type" for the tables.
25 *
26 * @since 1.0.0
27 * @var string
28 */
29 protected $post_type = 'tablepress_table';
30
31 /**
32 * Init the model by registering the Custom Post Type.
33 *
34 * @since 1.0.0
35 */
36 public function __construct() {
37 parent::__construct();
38 $this->_register_post_type(); // we are on WP "init" hook already
39 }
40
41 /**
42 * Register the Custom Post Type which the tables use.
43 *
44 * @since 1.0.0
45 */
46 protected function _register_post_type() {
47 /**
48 * Filter the "Custom Post Type" that TablePress uses for storing tables in the database.
49 *
50 * @since 1.0.0
51 *
52 * @param string $post_type The "Custom Post Type" that TablePress uses.
53 */
54 $this->post_type = apply_filters( 'tablepress_post_type', $this->post_type );
55 $post_type_args = array(
56 'labels' => array(
57 'name' => 'TablePress Tables',
58 ),
59 'public' => false,
60 'show_ui' => false,
61 'query_var' => false,
62 'rewrite' => false,
63 'capability_type' => 'tablepress_table', // This ensures, that WP's regular CPT UI respects our capabilities.
64 'map_meta_cap' => false, // Integrated WP mapping does not fit our needs, therefore use our own in a filter.
65 'supports' => array( 'title', 'editor', 'excerpt', 'revisions' ),
66 'can_export' => true,
67 );
68 /**
69 * Filter the arguments for the registration of the "Custom Post Type" that TablePress uses.
70 *
71 * @since 1.0.0
72 *
73 * @param array $post_type_args Arguments for the registration of the TablePress "Custom Post Type".
74 */
75 $post_type_args = apply_filters( 'tablepress_post_type_args', $post_type_args );
76 register_post_type( $this->post_type, $post_type_args );
77 }
78
79 /**
80 * Insert a post with the correct Custom Post Type and default values in the the wp_posts table in the database.
81 *
82 * @since 1.0.0
83 *
84 * @param array $post Post to insert.
85 * @return int|WP_Error Post ID of the inserted post on success, WP_Error on error.
86 */
87 public function insert( array $post ) {
88 $default_post = array(
89 'ID' => false, // false on new insert, but existing post ID on update
90 'comment_status' => 'closed',
91 'ping_status' => 'closed',
92 'post_category' => false,
93 'post_content' => '',
94 'post_excerpt' => '',
95 'post_parent' => 0,
96 'post_password' => '',
97 'post_status' => 'publish',
98 'post_title' => '',
99 'post_type' => $this->post_type,
100 'tags_input' => '',
101 'to_ping' => '',
102 );
103 $post = array_merge( $default_post, $post );
104 // WP expects everything to be slashed.
105 $post = wp_slash( $post );
106
107 // Remove balanceTags() from sanitize_post(), as it can destroy the JSON when messing with HTML.
108 remove_filter( 'content_save_pre', 'balanceTags', 50 );
109 remove_filter( 'excerpt_save_pre', 'balanceTags', 50 );
110 /*
111 * Remove possible KSES filtering, as it can destroy the JSON when messing with HTML.
112 * KSES filtering is done to table cells individually, when saving.
113 */
114 $has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
115 if ( $has_kses ) {
116 kses_remove_filters();
117 }
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
124 $post_id = wp_insert_post( $post, true );
125
126 // Restore removed content filters.
127 add_filter( 'content_save_pre', 'balanceTags', 50 );
128 add_filter( 'excerpt_save_pre', 'balanceTags', 50 );
129 if ( $has_kses ) {
130 kses_init_filters();
131 }
132 if ( $has_targeted_link_rel_filters ) {
133 wp_init_targeted_link_rel_filters();
134 }
135
136 return $post_id;
137 }
138
139 /**
140 * Update an existing post with the correct Custom Post Type and default values in the the wp_posts table in the database.
141 *
142 * @since 1.0.0
143 *
144 * @param array $post Post.
145 * @return int|WP_Error Post ID of the updated post on success, WP_Error on error.
146 */
147 public function update( array $post ) {
148 $default_post = array(
149 'ID' => false, // false on new insert, but existing post ID on update
150 'comment_status' => 'closed',
151 'ping_status' => 'closed',
152 'post_category' => false,
153 'post_content' => '',
154 'post_excerpt' => '',
155 'post_parent' => 0,
156 'post_password' => '',
157 'post_status' => 'publish',
158 'post_title' => '',
159 'post_type' => $this->post_type,
160 'tags_input' => '',
161 'to_ping' => '',
162 );
163 $post = array_merge( $default_post, $post );
164 // WP expects everything to be slashed.
165 $post = wp_slash( $post );
166
167 // Remove balanceTags() from sanitize_post(), as it can destroy the JSON when messing with HTML
168 remove_filter( 'content_save_pre', 'balanceTags', 50 );
169 remove_filter( 'excerpt_save_pre', 'balanceTags', 50 );
170 /*
171 * Remove possible KSES filtering, as it can destroy the JSON when messing with HTML.
172 * KSES filtering is done to table cells individually, when saving.
173 */
174 $has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
175 if ( $has_kses ) {
176 kses_remove_filters();
177 }
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
184 $post_id = wp_update_post( $post, true );
185
186 // Restore removed content filters.
187 add_filter( 'content_save_pre', 'balanceTags', 50 );
188 add_filter( 'excerpt_save_pre', 'balanceTags', 50 );
189 if ( $has_kses ) {
190 kses_init_filters();
191 }
192 if ( $has_targeted_link_rel_filters ) {
193 wp_init_targeted_link_rel_filters();
194 }
195
196 return $post_id;
197 }
198
199 /**
200 * Get a post from the wp_posts table in the database.
201 *
202 * @since 1.0.0
203 *
204 * @param int $post_id Post ID.
205 * @return WP_Post|bool Post on success, false on error.
206 */
207 public function get( $post_id ) {
208 $post = get_post( $post_id );
209 if ( is_null( $post ) ) {
210 return false;
211 }
212 return $post;
213 }
214
215 /**
216 * Delete a post (and all revisions) from the wp_posts table in the database.
217 *
218 * @since 1.0.0
219 *
220 * @param int $post_id Post ID.
221 * @return mixed|bool Post on success, false on error.
222 */
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
225 }
226
227 /**
228 * Move a post to the trash (if trash is globally enabled), instead of directly deleting the post.
229 * (yet unused)
230 *
231 * @since 1.0.0
232 *
233 * @param int $post_id Post ID.
234 * @return mixed|bool Post on success, false on error.
235 */
236 public function trash( $post_id ) {
237 return wp_trash_post( $post_id );
238 }
239
240 /**
241 * Restore a post from the trash.
242 * (yet unused)
243 *
244 * @since 1.0.0
245 *
246 * @param int $post_id Post ID.
247 * @return array|bool Post on success, false on error.
248 */
249 public function untrash( $post_id ) {
250 return wp_untrash_post( $post_id );
251 }
252
253 /**
254 * Load all posts with one query, to prime the cache.
255 *
256 * @since 1.0.0
257 *
258 * @global wpdb $wpdb WordPress database abstraction object.
259 * @see get_post()
260 *
261 * @param array $all_post_ids List of Post IDs.
262 * @param bool $update_meta_cache Optional. Whether to update the Post Meta Cache (for table options and visibility).
263 */
264 public function load_posts( array $all_post_ids, $update_meta_cache = true ) {
265 global $wpdb;
266
267 // 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 );
273 // Don't load posts that are in the cache already.
274 $post_ids = _get_non_cached_ids( $post_ids, 'posts' );
275 if ( ! empty( $post_ids ) ) {
276 $post_ids_list = implode( ',', $post_ids );
277 $posts = $wpdb->get_results( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID IN ({$post_ids_list})" );
278 update_post_cache( $posts );
279 if ( $update_meta_cache ) {
280 // Get all post meta data for all table posts, @see get_post_meta().
281 update_meta_cache( 'post', $post_ids );
282 }
283 }
284 $offset += $length; // next array_slice() $offset
285 }
286 }
287
288 /**
289 * Count the number of posts with the model's CPT in the wp_posts table in the database.
290 * (currently for debug only)
291 *
292 * @since 1.0.0
293 *
294 * @return int Number of posts.
295 */
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
298 }
299
300 /**
301 * Add a post meta field to a post.
302 *
303 * @since 1.0.0
304 *
305 * @param int $post_id ID of the post for which the field shall be added.
306 * @param string $field Name of the post meta field.
307 * @param string $value Value of the post meta field (not slashed).
308 * @return bool True on success, false on error.
309 */
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
314 // Make sure that $success is a boolean, as add_post_meta() returns an ID or false.
315 $success = ( false === $success ) ? false : true;
316 return $success;
317 }
318
319 /**
320 * Update the value of a post meta field of a post.
321 *
322 * If the field does not yet exist, it is added.
323 *
324 * @since 1.0.0
325 *
326 * @param int $post_id ID of the post for which the field shall be updated.
327 * @param string $field Name of the post meta field.
328 * @param string $value Value of the post meta field (not slashed).
329 * @return bool True on success, false on error.
330 */
331 public function update_meta_field( $post_id, $field, $value ) {
332 $prev_value = (string) get_post_meta( $post_id, $field, true );
333 // No need to update, if values are equal (also, update_post_meta() would return false for this).
334 if ( $prev_value === $value ) {
335 return true;
336 }
337
338 // WP expects a slashed value.
339 $value = wp_slash( $value );
340 return update_post_meta( $post_id, $field, $value, $prev_value );
341 }
342
343 /**
344 * Get the value of a post meta field of a post.
345 *
346 * @since 1.0.0
347 *
348 * @param int $post_id ID of the post for which the field shall be retrieved.
349 * @param string $field Name of the post meta field.
350 * @return string Value of the meta field.
351 */
352 public function get_meta_field( $post_id, $field ) {
353 return get_post_meta( $post_id, $field, true ); // true means single value
354 }
355
356 /**
357 * Delete a post meta field of a post.
358 * (yet unused)
359 *
360 * @since 1.0.0
361 *
362 * @param int $post_id ID of the post of which the field shall be deleted.
363 * @param string $field Name of the post meta field.
364 * @return bool True on success, false on error.
365 */
366 public function delete_meta_field( $post_id, $field ) {
367 return delete_post_meta( $post_id, $field, true ); // true means single value
368 }
369
370 /**
371 * Return the Custom Post Type that TablePress uses.
372 *
373 * @since 1.5.0
374 *
375 * @return string The used Custom Post Type.
376 */
377 public function get_post_type() {
378 return $this->post_type;
379 }
380
381 } // class TablePress_Post_Model
382