PluginProbe
Posts Table with Search & Sort / 1.4.13
Posts Table with Search & Sort v1.4.13
1.4.13 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2 1.3 1.3.1 1.3.1-v2 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 All 40 releases
← All changes | src/Simple_Posts_Table.php +363 -322 1.3.51.4.13 View file →
@@ -1,5 +1,6 @@
1 1 <?php
2 +
2 3 namespace Barn2\Plugin\Posts_Table_Search_Sort;
3 4
4 5 /**
5 6 * This class is responsible for generating a HTML table from a list of supplied attributes.
@@ -4,403 +5,443 @@
4 5 /**
5 6 * This class is responsible for generating a HTML table from a list of supplied attributes.
6 7 *
7 8 * @package Barn2\posts-table-search-sort
8 - * @author Barn2 Plugins <support@barn2.co.uk>
9 + * @author Barn2 Plugins <support@barn2.com>
9 10 * @license GPL-3.0
10 11 * @copyright Barn2 Media Ltd
11 12 */
12 13 class Simple_Posts_Table {
13 14
14 - /**
15 - * Stores the number of tables on this page. Used to generate the table ID.
16 - *
17 - * @var int
18 - */
19 - private static $table_count = 1;
15 + /**
16 + * Stores the number of tables on this page. Used to generate the table ID.
17 + *
18 + * @var int
19 + */
20 + private static $table_count = 1;
20 21
21 - /**
22 - * The complete list of table attributes, and their defaults.
23 - *
24 - * @var array
25 - */
26 - public static $default_args = array(
27 - 'columns' => 'title,content,date,author,categories',
28 - 'rows_per_page' => 20,
29 - 'sort_by' => 'date',
30 - 'sort_order' => '',
31 - 'category' => '',
32 - 'tag' => '',
33 - 'author' => '',
34 - 'post_status' => '',
35 - 'date_format' => 'Y/m/d',
36 - 'search_on_click' => true,
37 - 'wrap' => true,
38 - 'content_length' => 15,
39 - 'scroll_offset' => 15
40 - );
22 + /**
23 + * The complete list of table attributes, and their defaults.
24 + *
25 + * @var array
26 + */
27 + public static $default_args = [
28 + 'columns' => 'title,content,date,author,categories',
29 + 'rows_per_page' => 20,
30 + 'sort_by' => 'date',
31 + 'sort_order' => '',
32 + 'category' => '',
33 + 'tag' => '',
34 + 'author' => '',
35 + 'post_status' => '',
36 + 'date_format' => 'Y/m/d',
37 + 'search_on_click' => true,
38 + 'wrap' => true,
39 + 'content_length' => 15,
40 + 'scroll_offset' => 15
41 + ];
41 42
42 - /**
43 - * An array of all possible columns and their default heading, priority, and column width.
44 - *
45 - * @var array
46 - */
47 - private static $column_defaults = array();
43 + /**
44 + * An array of all possible columns and their default heading, priority, and column width.
45 + *
46 + * @var array
47 + */
48 + private static $column_defaults = [];
48 49
49 - /**
50 - * An array of all allowed column keys.
51 - *
52 - * @var array
53 - */
54 - private static $allowed_columns = array();
50 + /**
51 + * An array of all allowed column keys.
52 + *
53 + * @var array
54 + */
55 + private static $allowed_columns = [];
55 56
56 - public static function get_defaults() {
57 - return wp_parse_args( Settings::get_table_args(), self::$default_args );
58 - }
57 + public static function get_defaults() {
58 + return wp_parse_args( Settings::get_table_args(), self::$default_args );
59 + }
59 60
60 - public static function get_column_defaults() {
61 - if ( empty( self::$column_defaults ) ) {
62 - /**
63 - * Priority values are used to determine visiblity at small screen sizes (1 = highest priority, 6 = lowest priority).
64 - * Column widths are automatically calculated by DataTables, but can be overridden by using filter 'posts_data_table_column_defaults'.
65 - */
66 - self::$column_defaults = array(
67 - 'id' => array(
68 - 'heading' => __( 'ID', 'posts-data-table' ),
69 - 'priority' => 3,
70 - 'width' => ''
71 - ),
72 - 'image' => array(
73 - 'heading' => __( 'Image', 'posts-data-table' ),
74 - 'priority' => 6,
75 - 'width' => ''
76 - ),
77 - 'title' => array(
78 - 'heading' => __( 'Title', 'posts-data-table' ),
79 - 'priority' => 1,
80 - 'width' => ''
81 - ),
82 - 'categories' => array(
83 - 'heading' => __( 'Categories', 'posts-data-table' ),
84 - 'priority' => 7,
85 - 'width' => ''
86 - ),
87 - 'tags' => array(
88 - 'heading' => __( 'Tags', 'posts-data-table' ),
89 - 'priority' => 8,
90 - 'width' => ''
91 - ),
92 - 'date' => array(
93 - 'heading' => __( 'Date', 'posts-data-table' ),
94 - 'priority' => 2,
95 - 'width' => ''
96 - ),
97 - 'author' => array(
98 - 'heading' => __( 'Author', 'posts-data-table' ),
99 - 'priority' => 4,
100 - 'width' => ''
101 - ),
102 - 'content' => array(
103 - 'heading' => __( 'Content', 'posts-data-table' ),
104 - 'priority' => 5,
105 - 'width' => ''
106 - )
107 - );
108 - }
61 + public static function get_column_defaults() {
62 + if ( empty( self::$column_defaults ) ) {
63 + /**
64 + * Priority values are used to determine visiblity at small screen sizes (1 = highest priority, 6 = lowest priority).
65 + * Column widths are automatically calculated by DataTables, but can be overridden by using filter 'posts_data_table_column_defaults'.
66 + */
67 + self::$column_defaults = [
68 + 'id' => [
69 + 'heading' => __( 'ID', 'posts-data-table' ),
70 + 'priority' => 3,
71 + 'width' => ''
72 + ],
73 + 'image' => [
74 + 'heading' => __( 'Image', 'posts-data-table' ),
75 + 'priority' => 6,
76 + 'width' => ''
77 + ],
78 + 'title' => [
79 + 'heading' => __( 'Title', 'posts-data-table' ),
80 + 'priority' => 1,
81 + 'width' => ''
82 + ],
83 + 'categories' => [
84 + 'heading' => __( 'Categories', 'posts-data-table' ),
85 + 'priority' => 7,
86 + 'width' => ''
87 + ],
88 + 'tags' => [
89 + 'heading' => __( 'Tags', 'posts-data-table' ),
90 + 'priority' => 8,
91 + 'width' => ''
92 + ],
93 + 'date' => [
94 + 'heading' => __( 'Date', 'posts-data-table' ),
95 + 'priority' => 2,
96 + 'width' => ''
97 + ],
98 + 'author' => [
99 + 'heading' => __( 'Author', 'posts-data-table' ),
100 + 'priority' => 4,
101 + 'width' => ''
102 + ],
103 + 'content' => [
104 + 'heading' => __( 'Content', 'posts-data-table' ),
105 + 'priority' => 5,
106 + 'width' => ''
107 + ]
108 + ];
109 + }
109 110
110 - return self::$column_defaults;
111 - }
111 + return self::$column_defaults;
112 + }
112 113
113 - public static function get_allowed_columns() {
114 - if ( empty( self::$allowed_columns ) ) {
115 - self::$allowed_columns = array_keys( self::get_column_defaults() );
116 - }
117 - return self::$allowed_columns;
118 - }
114 + public static function get_allowed_columns() {
115 + if ( empty( self::$allowed_columns ) ) {
116 + self::$allowed_columns = array_keys( self::get_column_defaults() );
117 + }
119 118
120 - /**
121 - * Retrieves a data table containing a list of posts based on the specified arguments.
122 - *
123 - * @param array $args An array of options used to display the posts table
124 - * @return string The posts table HTML output
125 - */
126 - public function get_table( $args ) {
127 - // Load the scripts and styles.
128 - if ( apply_filters( 'posts_data_table_load_scripts', true ) ) {
129 - wp_enqueue_style( 'posts-data-table' );
130 - wp_enqueue_script( 'posts-data-table' );
131 - }
119 + return self::$allowed_columns;
120 + }
132 121
133 - $args = wp_parse_args( $args, self::get_defaults() );
134 - $args = $this->back_compat_args( $args );
122 + /**
123 + * Retrieves a data table containing a list of posts based on the specified arguments.
124 + *
125 + * @param array $args An array of options used to display the posts table
126 + * @return string The posts table HTML output
127 + */
128 + public function get_table( $args ) {
129 + $args = wp_parse_args( $args, self::get_defaults() );
130 + $args = $this->back_compat_args( $args );
135 131
136 - if ( empty( $args['columns'] ) ) {
137 - $args['columns'] = self::$default_args['columns'];
138 - }
132 + if ( empty( $args['columns'] ) ) {
133 + $args['columns'] = self::$default_args['columns'];
134 + }
139 135
140 - // Get the columns to be used in this table
141 - $columns = array_filter( array_map( 'trim', explode( ',', strtolower( $args['columns'] ) ) ) );
142 - $columns = array_intersect( $columns, self::get_allowed_columns() );
136 + // Get the columns to be used in this table
137 + $columns = array_filter( array_map( 'trim', explode( ',', strtolower( $args['columns'] ) ) ) );
138 + $columns = array_intersect( $columns, self::get_allowed_columns() );
143 139
144 - if ( empty( $columns ) ) {
145 - $columns = explode( ',', self::$default_args['columns'] );
146 - }
140 + if ( empty( $columns ) ) {
141 + $columns = explode( ',', self::$default_args['columns'] );
142 + }
147 143
148 - $args['rows_per_page'] = filter_var( $args['rows_per_page'], FILTER_VALIDATE_INT );
144 + $args['rows_per_page'] = filter_var( $args['rows_per_page'], FILTER_VALIDATE_INT );
149 145
150 - if ( $args['rows_per_page'] < 1 || ! $args['rows_per_page'] ) {
151 - $args['rows_per_page'] = false;
152 - }
146 + if ( $args['rows_per_page'] < 1 || ! $args['rows_per_page'] ) {
147 + $args['rows_per_page'] = -1;
148 + }
153 149
154 - if ( ! in_array( $args['sort_by'], self::get_allowed_columns() ) ) {
155 - $args['sort_by'] = self::$default_args['sort_by'];
156 - }
150 + if ( ! in_array( $args['sort_by'], self::get_allowed_columns() ) ) {
151 + $args['sort_by'] = self::$default_args['sort_by'];
152 + }
157 153
158 - if ( ! in_array( $args['sort_order'], array( 'asc', 'desc' ) ) ) {
159 - $args['sort_order'] = self::$default_args['sort_order'];
160 - }
154 + if ( ! in_array( $args['sort_order'], [ 'asc', 'desc' ] ) ) {
155 + $args['sort_order'] = self::$default_args['sort_order'];
156 + }
161 157
162 - // Set default sort direction
163 - if ( ! $args['sort_order'] ) {
164 - if ( $args['sort_by'] === 'date' ) {
165 - $args['sort_order'] = 'desc';
166 - } else {
167 - $args['sort_order'] = 'asc';
168 - }
169 - }
158 + // Set default sort direction
159 + if ( ! $args['sort_order'] ) {
160 + if ( $args['sort_by'] === 'date' ) {
161 + $args['sort_order'] = 'desc';
162 + } else {
163 + $args['sort_order'] = 'asc';
164 + }
165 + }
170 166
171 - $args['search_on_click'] = filter_var( $args['search_on_click'], FILTER_VALIDATE_BOOLEAN );
172 - $args['wrap'] = filter_var( $args['wrap'], FILTER_VALIDATE_BOOLEAN );
173 - $args['content_length'] = filter_var( $args['content_length'], FILTER_VALIDATE_INT );
174 - $args['scroll_offset'] = filter_var( $args['scroll_offset'], FILTER_VALIDATE_INT );
167 + $args['search_on_click'] = filter_var( $args['search_on_click'], FILTER_VALIDATE_BOOLEAN );
168 + $args['wrap'] = filter_var( $args['wrap'], FILTER_VALIDATE_BOOLEAN );
169 + $args['content_length'] = filter_var( $args['content_length'], FILTER_VALIDATE_INT );
170 + $args['scroll_offset'] = filter_var( $args['scroll_offset'], FILTER_VALIDATE_INT );
175 171
176 - if ( empty( $args['date_format'] ) ) {
177 - $args['date_format'] = self::$default_args['date_format'];
178 - }
172 + if ( empty( $args['date_format'] ) ) {
173 + $args['date_format'] = self::$default_args['date_format'];
174 + }
179 175
180 - $output = $table_head = $table_body = $body_row_fmt = '';
176 + $output = '';
177 + $table_head = '';
178 + $table_body = '';
179 + $body_row_fmt = '';
181 180
182 - // Start building the args needed for our posts query
183 - $post_args = array(
184 - 'post_type' => 'post',
185 - 'posts_per_page' => apply_filters( 'posts_data_table_post_limit', 1000 ),
186 - 'post_status' => 'publish',
187 - 'suppress_filters' => false // Ensure WPML filters run on this query
188 - );
181 + // Start building the args needed for our posts query
182 + $post_args = [
183 + 'post_type' => 'post',
184 + 'posts_per_page' => apply_filters( 'posts_data_table_post_limit', 1000 ),
185 + 'post_status' => 'publish',
186 + 'suppress_filters' => false // Ensure WPML filters run on this query
187 + ];
189 188
190 - if ( ! empty( $args['category'] ) ) {
191 - if ( is_numeric( $args['category'] ) ) {
192 - $post_args['cat'] = $args['category'];
193 - } else {
194 - $category = get_category_by_slug( $args['category'] );
189 + if ( ! empty( $args['category'] ) ) {
190 + if ( is_numeric( $args['category'] ) ) {
191 + $post_args['cat'] = $args['category'];
192 + } else {
193 + $category = get_category_by_slug( $args['category'] );
195 194
196 - if ( $category ) {
197 - $post_args['category_name'] = $category->slug;
198 - }
199 - }
200 - }
195 + if ( $category ) {
196 + $post_args['category_name'] = $category->slug;
197 + }
198 + }
199 + }
201 200
202 - if ( ! empty( $args['tag'] ) ) {
203 - if ( is_numeric( $args['tag'] ) ) {
204 - $post_args['tag_id'] = $args['tag'];
205 - } else {
206 - $post_args['tag'] = $args['tag'];
207 - }
208 - }
201 + if ( ! empty( $args['tag'] ) ) {
202 + if ( is_numeric( $args['tag'] ) ) {
203 + $post_args['tag_id'] = $args['tag'];
204 + } else {
205 + $post_args['tag'] = $args['tag'];
206 + }
207 + }
209 208
210 - if ( ! empty( $args['author'] ) ) {
211 - $author = $args['author'];
209 + if ( ! empty( $args['author'] ) ) {
210 + $author = $args['author'];
212 211
213 - if ( is_numeric( $author ) || false !== strpos( $author, ',' ) ) {
214 - $post_args['author'] = $author;
215 - } else {
216 - $post_args['author_name'] = $author;
217 - }
218 - }
212 + if ( is_numeric( $author ) || false !== strpos( $author, ',' ) ) {
213 + $post_args['author'] = $author;
214 + } else {
215 + $post_args['author_name'] = $author;
216 + }
217 + }
219 218
220 - if ( ! empty( $args['post_status'] ) ) {
221 - $post_args['post_status'] = $args['post_status'];
222 - }
219 + if ( ! empty( $args['post_status'] ) ) {
220 + $post_args['post_status'] = $args['post_status'];
221 + }
223 222
224 - // Get all published posts in the current language
225 - $all_posts = get_posts( apply_filters( 'posts_data_table_query_args', $post_args, $args ) );
223 + // Get all published posts in the current language
224 + $all_posts = get_posts( apply_filters( 'posts_data_table_query_args', $post_args, $args ) );
226 225
227 - // Bail early if no posts found
228 - if ( ! $all_posts || ! is_array( $all_posts ) ) {
229 - return $output;
230 - }
226 + // Bail early if no posts found
227 + if ( ! $all_posts || ! is_array( $all_posts ) ) {
228 + return $output;
229 + }
231 230
232 - $hidden_columns = array();
231 + $hidden_columns = [];
233 232
234 - // Set hidden columns and sort indexes
235 - $table_sort_index = array_search( $args['sort_by'], $columns );
236 - $date_sort_index = false;
237 - $hidden_date = in_array( 'date', $columns ) || 'date' === $args['sort_by'];
233 + // Set hidden columns and sort indexes
234 + $table_sort_index = array_search( $args['sort_by'], $columns );
235 + $date_sort_index = false;
236 + $hidden_date = in_array( 'date', $columns ) || 'date' === $args['sort_by'];
238 237
239 - if ( $hidden_date ) {
240 - $hidden_columns[] = 'timestamp';
241 - $date_sort_index = count( $columns );
238 + if ( $hidden_date ) {
239 + $hidden_columns[] = 'timestamp';
240 + $date_sort_index = count( $columns );
242 241
243 - // If we're sorting by date, make sure we use this hidden column for the initial table sort
244 - if ( 'date' === $args['sort_by'] && false === $table_sort_index ) {
245 - $table_sort_index = $date_sort_index;
246 - }
247 - }
242 + // If we're sorting by date, make sure we use this hidden column for the initial table sort
243 + if ( 'date' === $args['sort_by'] && false === $table_sort_index ) {
244 + $table_sort_index = $date_sort_index;
245 + }
246 + }
248 247
249 - if ( false === $table_sort_index ) {
250 - // Sort column is not in list of displayed columns so we'll add it as a hidden column at end of table
251 - $hidden_columns[] = $args['sort_by'];
248 + if ( false === $table_sort_index ) {
249 + // Sort column is not in list of displayed columns so we'll add it as a hidden column at end of table
250 + $hidden_columns[] = $args['sort_by'];
252 251
253 - // Set the table sort index to the index of the hidden sort column
254 - $table_sort_index = $date_sort_index ? $date_sort_index + 1 : \count( $columns );
255 - }
252 + // Set the table sort index to the index of the hidden sort column
253 + $table_sort_index = $date_sort_index ? $date_sort_index + 1 : \count( $columns );
254 + }
256 255
257 - // Allow theme/plugins to override defaults
258 - $column_defaults = apply_filters( 'posts_data_table_column_defaults_' . self::$table_count, apply_filters( 'posts_data_table_column_defaults', self::get_column_defaults() ) );
256 + // Allow theme/plugins to override defaults
257 + $column_defaults = apply_filters( 'posts_data_table_column_defaults_' . self::$table_count, apply_filters( 'posts_data_table_column_defaults', self::get_column_defaults() ) );
259 258
260 - // Build table header
261 - $heading_fmt = '<th data-name="%1$s" data-priority="%2$u" data-width="%3$s"%5$s>%4$s</th>';
262 - $cell_fmt = '<td>{%s}</td>';
259 + // Load the scripts and styles.
260 + $load_scripts = apply_filters( 'posts_data_table_load_scripts', true );
263 261
264 - foreach ( $columns as $column ) {
265 - // Double-check column name is valid
266 - if ( ! in_array( $column, self::get_allowed_columns() ) ) {
267 - continue;
268 - }
262 + if ( $load_scripts ) {
263 + wp_enqueue_style( 'posts-data-table' );
269 264
270 - // Do we need to use custom data for ordering this column?
271 - $order_data = '';
265 + wp_localize_script(
266 + 'posts-data-table',
267 + 'configOptions',
268 + [
269 + 'lengthMenu' => json_encode( $this->get_page_lengths( $args['rows_per_page'] ) ),
270 + 'displayLength' => $args['rows_per_page']
271 + ]
272 + );
272 273
273 - if ( 'date' === $column && false !== $date_sort_index ) {
274 - $order_data = sprintf( ' data-order-data="%u"', $date_sort_index );
275 - }
274 + wp_enqueue_script( 'posts-data-table' );
275 + }
276 276
277 - // Add heading to table
278 - $table_head .= sprintf( $heading_fmt, $column, $column_defaults[$column]['priority'], $column_defaults[$column]['width'], $column_defaults[$column]['heading'], $order_data );
277 + // Build table header
278 + $heading_fmt = '<th data-name="%1$s" data-priority="%2$u" data-width="%3$s"%5$s>%4$s</th>';
279 + $cell_fmt = '<td>{%s}</td>';
279 280
280 - // Add placeholder to table body format string so that content for this column is included in table output
281 - $body_row_fmt .= sprintf( $cell_fmt, $column );
282 - }
281 + foreach ( $columns as $column ) {
282 + // Double-check column name is valid
283 + if ( ! in_array( $column, self::get_allowed_columns() ) ) {
284 + continue;
285 + }
283 286
284 - foreach ( $hidden_columns as $column ) {
285 - $table_head .= sprintf( '<th data-name="%s" data-visible="false"></th>', $column );
287 + // Do we need to use custom data for ordering this column?
288 + $order_data = '';
286 289
287 - // Make sure data for the hidden column is included in table content
288 - $body_row_fmt .= sprintf( $cell_fmt, $column );
289 - }
290 + if ( 'date' === $column && false !== $date_sort_index ) {
291 + $order_data = sprintf( ' data-order-data="%u"', $date_sort_index );
292 + }
290 293
291 - $table_head = sprintf( '<thead><tr>%s</tr></thead>', $table_head );
294 + // Add heading to table
295 + $table_head .= sprintf( $heading_fmt, $column, $column_defaults[ $column ]['priority'], $column_defaults[ $column ]['width'], $column_defaults[ $column ]['heading'], $order_data );
292 296
293 - // Build table body
294 - $body_row_fmt = '<tr>' . $body_row_fmt . '</tr>';
297 + // Add placeholder to table body format string so that content for this column is included in table output
298 + $body_row_fmt .= sprintf( $cell_fmt, $column );
299 + }
295 300
296 - // Loop through posts and add a row for each
297 - foreach ( (array) $all_posts as $_post ) {
298 - setup_postdata( $_post );
301 + foreach ( $hidden_columns as $column ) {
302 + $table_head .= sprintf( '<th data-name="%s" data-visible="false"></th>', $column );
299 303
300 - // Format title
301 - $title = sprintf( '<a href="%1$s">%2$s</a>', get_permalink( $_post ), get_the_title( $_post ) );
304 + // Make sure data for the hidden column is included in table content.
305 + // The 'pdt-hidden-column' class hides it via CSS so it never briefly flashes on screen while DataTables initialises.
306 + $body_row_fmt .= sprintf( '<td class="pdt-hidden-column">{%s}</td>', $column );
307 + }
302 308
303 - // Format author
304 - $author = sprintf(
305 - '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
306 - esc_url( \get_author_posts_url( $_post->post_author ) ),
307 - esc_attr( sprintf( __( 'Posts by %s', 'posts-data-table' ), get_the_author() ) ),
308 - get_the_author()
309 - );
309 + $table_head = sprintf( '<thead><tr>%s</tr></thead>', $table_head );
310 310
311 - $post_data_trans = apply_filters( 'posts_data_table_row_data_format', array(
312 - '{id}' => $_post->ID,
313 - '{image}' => get_the_post_thumbnail( $_post, apply_filters( 'posts_data_table_image_size', 'thumbnail' ) ),
314 - '{title}' => $title,
315 - '{categories}' => \get_the_category_list( ', ', '', $_post->ID ),
316 - '{tags}' => \get_the_tag_list( '', ', ', '', $_post->ID ),
317 - '{date}' => \get_the_date( $args['date_format'], $_post ),
318 - '{author}' => $author,
319 - '{content}' => $this->get_post_content( $args['content_length'] ),
320 - '{timestamp}' => $_post->post_date
321 - ) );
311 + // Build table body
312 + $body_row_fmt = '<tr>' . $body_row_fmt . '</tr>';
322 313
323 - $table_body .= strtr( $body_row_fmt, $post_data_trans );
324 - } // foreach post
314 + // Loop through posts and add a row for each
315 + foreach ( (array) $all_posts as $_post ) {
316 + setup_postdata( $_post );
325 317
326 - wp_reset_postdata();
318 + // Format title
319 + $title = sprintf( '<a href="%1$s">%2$s</a>', esc_url( get_permalink( $_post ) ), esc_html( get_the_title( $_post ) ) );
327 320
328 - $table_body = sprintf( '<tbody>%s</tbody>', $table_body );
321 + // Format author
322 + $author = sprintf(
323 + '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
324 + esc_url( get_author_posts_url( $_post->post_author ) ),
325 + /* translators: %s: the author's name */
326 + esc_attr( sprintf( __( 'Posts by %s', 'posts-data-table' ), get_the_author() ) ),
327 + esc_html( get_the_author() )
328 + );
329 329
330 - $paging_attr = 'false';
330 + $post_data_trans = apply_filters(
331 + 'posts_data_table_row_data_format',
332 + [
333 + '{id}' => $_post->ID,
334 + '{image}' => get_the_post_thumbnail( $_post, apply_filters( 'posts_data_table_image_size', 'thumbnail' ) ),
335 + '{title}' => $title,
336 + '{categories}' => get_the_category_list( ', ', '', $_post->ID ),
337 + '{tags}' => get_the_tag_list( '', ', ', '', $_post->ID ),
338 + '{date}' => get_the_date( $args['date_format'], $_post ),
339 + '{author}' => $author,
340 + '{content}' => $this->get_post_content( $args['content_length'] ),
341 + '{timestamp}' => $_post->post_date
342 + ]
343 + );
331 344
332 - if ( $args['rows_per_page'] && $args['rows_per_page'] < count( $all_posts ) ) {
333 - $paging_attr = 'true';
334 - }
345 + $table_body .= strtr( $body_row_fmt, $post_data_trans );
346 + } // foreach post
335 347
336 - $order_attr = '';
348 + wp_reset_postdata();
337 349
338 - if ( false !== $table_sort_index ) {
339 - // Order attribute should be escaped here rather than in sprintf below as we don't want to escape the double-quotes around "asc" or "desc"
340 - $order_attr = sprintf( '[[%u, "%s"]]', esc_attr( $table_sort_index ), esc_attr( $args['sort_order'] ) );
341 - }
350 + $table_body = sprintf( '<tbody>%s</tbody>', $table_body );
342 351
343 - $offset_attr = ( $args['scroll_offset'] === false ) ? 'false' : $args['scroll_offset'];
344 - $table_class = 'posts-data-table';
352 + $paging_attr = 'true';
345 353
346 - if ( ! $args['wrap'] ) {
347 - $table_class .= ' nowrap';
348 - }
354 + $order_attr = '';
349 355
350 - $table_attributes = sprintf(
351 - 'id="posts-table-%1$u" class="%2$s" data-page-length="%3$u" data-paging="%4$s" data-order=\'%5$s\' data-click-filter="%6$s" data-scroll-offset="%7$s" cellspacing="0" width="100%%"',
352 - self::$table_count,
353 - esc_attr( $table_class ),
354 - esc_attr( $args['rows_per_page'] ),
355 - esc_attr( $paging_attr ),
356 - $order_attr, // escaped above
357 - esc_attr( $args['search_on_click'] ? 'true' : 'false' ),
358 - esc_attr( $offset_attr )
359 - );
356 + if ( false !== $table_sort_index ) {
357 + // Order attribute should be escaped here rather than in sprintf below as we don't want to escape the double-quotes around "asc" or "desc"
358 + $order_attr = sprintf( '[[%u, "%s"]]', esc_attr( $table_sort_index ), esc_attr( $args['sort_order'] ) );
359 + }
360 360
361 - $output = sprintf( '<table %1$s>%2$s%3$s</table>', $table_attributes, $table_head, $table_body );
361 + $offset_attr = ( $args['scroll_offset'] === false ) ? 'false' : $args['scroll_offset'];
362 + $table_class = 'posts-data-table';
362 363
363 - // Increment the table count
364 - self::$table_count ++;
364 + if ( ! $args['wrap'] ) {
365 + $table_class .= ' nowrap';
366 + }
365 367
366 - return apply_filters( 'posts_data_table_html_output', $output, $args );
367 - }
368 + // Keep the raw table hidden until the DataTables JS has initialised, so it never briefly flashes unstyled on screen.
369 + if ( $load_scripts ) {
370 + $table_class .= ' pdt-loading';
371 + }
368 372
369 - private function back_compat_args( $args ) {
370 - if ( ! empty( $args['columns'] ) ) {
371 - $columns = array_map( 'trim', explode( ',', $args['columns'] ) );
373 + $table_attributes = sprintf(
374 + 'id="posts-table-%1$u" class="%2$s" data-page-length="%3$u" data-paging="%4$s" data-order=\'%5$s\' data-click-filter="%6$s" data-scroll-offset="%7$s" cellspacing="0" width="100%%"',
375 + self::$table_count,
376 + esc_attr( $table_class ),
377 + esc_attr( $args['rows_per_page'] ),
378 + esc_attr( $paging_attr ),
379 + $order_attr, // escaped above
380 + esc_attr( $args['search_on_click'] ? 'true' : 'false' ),
381 + esc_attr( $offset_attr )
382 + );
372 383
373 - if ( false !== ( $index = array_search( 'category', $columns, true ) ) ) {
374 - $columns[$index] = 'categories';
375 - }
384 + $output = sprintf( '<table %1$s>%2$s%3$s</table>', $table_attributes, $table_head, $table_body );
376 385
377 - $args['columns'] = implode( ',', $columns );
378 - }
386 + // Increment the table count
387 + self::$table_count++;
379 388
380 - if ( ! empty( $args['sort_by'] ) && 'category' === $args['sort_by'] ) {
381 - $args['sort_by'] = 'categories';
382 - }
389 + return apply_filters( 'posts_data_table_html_output', $output, $args );
390 + }
383 391
384 - return $args;
385 - }
392 + private function back_compat_args( $args ) {
393 + if ( ! empty( $args['columns'] ) ) {
394 + $columns = array_map( 'trim', explode( ',', $args['columns'] ) );
386 395
387 - /**
388 - * Retrieve the post content, truncated to the number of words specified by $num_words.
389 - *
390 - * Must be called with the Loop or a secondary loop after a call to setup_postdata().
391 - *
392 - * @param int $num_words The number of words to trim the content to
393 - * @return string The (truncated) post content
394 - */
395 - private function get_post_content( $num_words = 15 ) {
396 - $text = get_the_content( '' );
397 - $text = strip_shortcodes( $text );
398 - $text = apply_filters( 'the_content', $text );
396 + if ( false !== ( $index = array_search( 'category', $columns, true ) ) ) {
397 + $columns[ $index ] = 'categories';
398 + }
399 399
400 - if ( $num_words > 0 ) {
401 - $text = wp_trim_words( $text, $num_words, ' &hellip;' );
402 - }
403 - return $text;
404 - }
400 + $args['columns'] = implode( ',', $columns );
401 + }
402 +
403 + if ( ! empty( $args['sort_by'] ) && 'category' === $args['sort_by'] ) {
404 + $args['sort_by'] = 'categories';
405 + }
406 +
407 + return $args;
408 + }
409 +
410 + /**
411 + * Retrieve the post content, truncated to the number of words specified by $num_words.
412 + *
413 + * Must be called with the Loop or a secondary loop after a call to setup_postdata().
414 + *
415 + * @param int $num_words The number of words to trim the content to
416 + * @return string The (truncated) post content
417 + */
418 + private function get_post_content( $num_words = 15 ) {
419 + $text = get_the_content( '' );
420 + $text = strip_shortcodes( $text );
421 + $text = apply_filters( 'the_content', $text );
422 +
423 + if ( $num_words > 0 ) {
424 + $text = wp_trim_words( $text, $num_words, ' &hellip;' );
425 + }
426 +
427 + return $text;
428 + }
429 +
430 + public function get_page_lengths( $default_length ) {
431 + $length_numbers = apply_filters( 'posts_data_table_default_page_lengths', [ 10, 25, 50, 100 ] );
432 +
433 + if ( $default_length != -1 && !in_array( $default_length, $length_numbers ) ) {
434 + $length_numbers[] = $default_length;
435 + }
436 +
437 + sort( $length_numbers );
438 +
439 + $lengths = [
440 + array_merge( $length_numbers, [ -1 ] ),
441 + array_merge( $length_numbers, [ __( 'All', 'posts-data-table' ) ] )
442 + ];
443 +
444 + return $lengths;
445 + }
405 446
406 447 }