PluginProbe
Posts Table with Search & Sort / 1.4.11
Posts Table with Search & Sort v1.4.11
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 +360 -308 1.3.21.4.11 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,384 +5,435 @@
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,category',
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 - 'category' => 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() );
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 );
134 131
135 - if ( empty( $args['columns'] ) ) {
136 - $args['columns'] = self::$default_args['columns'];
137 - }
132 + if ( empty( $args['columns'] ) ) {
133 + $args['columns'] = self::$default_args['columns'];
134 + }
138 135
139 - // Get the columns to be used in this table
140 - $columns = array_filter( array_map( 'trim', explode( ',', strtolower( $args['columns'] ) ) ) );
141 - $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() );
142 139
143 - if ( empty( $columns ) ) {
144 - $columns = explode( ',', self::$default_args['columns'] );
145 - }
140 + if ( empty( $columns ) ) {
141 + $columns = explode( ',', self::$default_args['columns'] );
142 + }
146 143
147 - $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 );
148 145
149 - if ( $args['rows_per_page'] < 1 || ! $args['rows_per_page'] ) {
150 - $args['rows_per_page'] = false;
151 - }
146 + if ( $args['rows_per_page'] < 1 || ! $args['rows_per_page'] ) {
147 + $args['rows_per_page'] = -1;
148 + }
152 149
153 - if ( ! in_array( $args['sort_by'], self::get_allowed_columns() ) ) {
154 - $args['sort_by'] = self::$default_args['sort_by'];
155 - }
150 + if ( ! in_array( $args['sort_by'], self::get_allowed_columns() ) ) {
151 + $args['sort_by'] = self::$default_args['sort_by'];
152 + }
156 153
157 - if ( ! in_array( $args['sort_order'], array( 'asc', 'desc' ) ) ) {
158 - $args['sort_order'] = self::$default_args['sort_order'];
159 - }
154 + if ( ! in_array( $args['sort_order'], [ 'asc', 'desc' ] ) ) {
155 + $args['sort_order'] = self::$default_args['sort_order'];
156 + }
160 157
161 - // Set default sort direction
162 - if ( ! $args['sort_order'] ) {
163 - if ( $args['sort_by'] === 'date' ) {
164 - $args['sort_order'] = 'desc';
165 - } else {
166 - $args['sort_order'] = 'asc';
167 - }
168 - }
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 + }
169 166
170 - $args['search_on_click'] = filter_var( $args['search_on_click'], FILTER_VALIDATE_BOOLEAN );
171 - $args['wrap'] = filter_var( $args['wrap'], FILTER_VALIDATE_BOOLEAN );
172 - $args['content_length'] = filter_var( $args['content_length'], FILTER_VALIDATE_INT );
173 - $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 );
174 171
175 - if ( empty( $args['date_format'] ) ) {
176 - $args['date_format'] = self::$default_args['date_format'];
177 - }
172 + if ( empty( $args['date_format'] ) ) {
173 + $args['date_format'] = self::$default_args['date_format'];
174 + }
178 175
179 - $output = $table_head = $table_body = $body_row_fmt = '';
176 + $output = '';
177 + $table_head = '';
178 + $table_body = '';
179 + $body_row_fmt = '';
180 180
181 - // Start building the args needed for our posts query
182 - $post_args = array(
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 - );
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 + ];
188 188
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'] );
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'] );
194 194
195 - if ( $category ) {
196 - $post_args['category_name'] = $category->slug;
197 - }
198 - }
199 - }
195 + if ( $category ) {
196 + $post_args['category_name'] = $category->slug;
197 + }
198 + }
199 + }
200 200
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 - }
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 + }
208 208
209 - if ( ! empty( $args['author'] ) ) {
210 - $author = $args['author'];
209 + if ( ! empty( $args['author'] ) ) {
210 + $author = $args['author'];
211 211
212 - if ( is_numeric( $author ) || false !== strpos( $author, ',' ) ) {
213 - $post_args['author'] = $author;
214 - } else {
215 - $post_args['author_name'] = $author;
216 - }
217 - }
212 + if ( is_numeric( $author ) || false !== strpos( $author, ',' ) ) {
213 + $post_args['author'] = $author;
214 + } else {
215 + $post_args['author_name'] = $author;
216 + }
217 + }
218 218
219 - if ( ! empty( $args['post_status'] ) ) {
220 - $post_args['post_status'] = $args['post_status'];
221 - }
219 + if ( ! empty( $args['post_status'] ) ) {
220 + $post_args['post_status'] = $args['post_status'];
221 + }
222 222
223 - // Get all published posts in the current language
224 - $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 ) );
225 225
226 - // Bail early if no posts found
227 - if ( ! $all_posts || ! is_array( $all_posts ) ) {
228 - return $output;
229 - }
226 + // Bail early if no posts found
227 + if ( ! $all_posts || ! is_array( $all_posts ) ) {
228 + return $output;
229 + }
230 230
231 - $hidden_columns = array();
231 + $hidden_columns = [];
232 232
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'];
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'];
237 237
238 - if ( $hidden_date ) {
239 - $hidden_columns[] = 'timestamp';
240 - $date_sort_index = count( $columns );
238 + if ( $hidden_date ) {
239 + $hidden_columns[] = 'timestamp';
240 + $date_sort_index = count( $columns );
241 241
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 - }
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 + }
247 247
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'];
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'];
251 251
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 - }
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 + }
255 255
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() ) );
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() ) );
258 258
259 - // Build table header
260 - $heading_fmt = '<th data-name="%1$s" data-priority="%2$u" data-width="%3$s"%5$s>%4$s</th>';
261 - $cell_fmt = '<td>{%s}</td>';
259 + // Load the scripts and styles.
260 + if ( apply_filters( 'posts_data_table_load_scripts', true ) ) {
261 + wp_enqueue_style( 'posts-data-table' );
262 262
263 - foreach ( $columns as $column ) {
264 - // Double-check column name is valid
265 - if ( ! in_array( $column, self::get_allowed_columns() ) ) {
266 - continue;
267 - }
263 + wp_localize_script(
264 + 'posts-data-table',
265 + 'configOptions',
266 + [
267 + 'lengthMenu' => json_encode( $this->get_page_lengths( $args['rows_per_page'] ) ),
268 + 'displayLength' => $args['rows_per_page']
269 + ]
270 + );
268 271
269 - // Do we need to use custom data for ordering this column?
270 - $order_data = '';
272 + wp_enqueue_script( 'posts-data-table' );
273 + }
271 274
272 - if ( 'date' === $column && false !== $date_sort_index ) {
273 - $order_data = sprintf( ' data-order-data="%u"', $date_sort_index );
274 - }
275 + // Build table header
276 + $heading_fmt = '<th data-name="%1$s" data-priority="%2$u" data-width="%3$s"%5$s>%4$s</th>';
277 + $cell_fmt = '<td>{%s}</td>';
275 278
276 - // Add heading to table
277 - $table_head .= sprintf( $heading_fmt, $column, $column_defaults[$column]['priority'], $column_defaults[$column]['width'], $column_defaults[$column]['heading'], $order_data );
279 + foreach ( $columns as $column ) {
280 + // Double-check column name is valid
281 + if ( ! in_array( $column, self::get_allowed_columns() ) ) {
282 + continue;
283 + }
278 284
279 - // Add placeholder to table body format string so that content for this column is included in table output
280 - $body_row_fmt .= sprintf( $cell_fmt, $column );
281 - }
285 + // Do we need to use custom data for ordering this column?
286 + $order_data = '';
282 287
283 - foreach ( $hidden_columns as $column ) {
284 - $table_head .= sprintf( '<th data-name="%s" data-visible="false"></th>', $column );
288 + if ( 'date' === $column && false !== $date_sort_index ) {
289 + $order_data = sprintf( ' data-order-data="%u"', $date_sort_index );
290 + }
285 291
286 - // Make sure data for the hidden column is included in table content
287 - $body_row_fmt .= sprintf( $cell_fmt, $column );
288 - }
292 + // Add heading to table
293 + $table_head .= sprintf( $heading_fmt, $column, $column_defaults[ $column ]['priority'], $column_defaults[ $column ]['width'], $column_defaults[ $column ]['heading'], $order_data );
289 294
290 - $table_head = sprintf( '<thead><tr>%s</tr></thead>', $table_head );
295 + // Add placeholder to table body format string so that content for this column is included in table output
296 + $body_row_fmt .= sprintf( $cell_fmt, $column );
297 + }
291 298
292 - // Build table body
293 - $body_row_fmt = '<tr>' . $body_row_fmt . '</tr>';
299 + foreach ( $hidden_columns as $column ) {
300 + $table_head .= sprintf( '<th data-name="%s" data-visible="false"></th>', $column );
294 301
295 - // Loop through posts and add a row for each
296 - foreach ( (array) $all_posts as $_post ) {
297 - setup_postdata( $_post );
302 + // Make sure data for the hidden column is included in table content
303 + $body_row_fmt .= sprintf( $cell_fmt, $column );
304 + }
298 305
299 - // Format title
300 - $title = sprintf( '<a href="%1$s">%2$s</a>', get_permalink( $_post ), get_the_title( $_post ) );
306 + $table_head = sprintf( '<thead><tr>%s</tr></thead>', $table_head );
301 307
302 - // Format author
303 - $author = sprintf(
304 - '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
305 - esc_url( \get_author_posts_url( $_post->post_author ) ),
306 - esc_attr( sprintf( __( 'Posts by %s', 'posts-data-table' ), get_the_author() ) ),
307 - get_the_author()
308 - );
308 + // Build table body
309 + $body_row_fmt = '<tr>' . $body_row_fmt . '</tr>';
309 310
310 - $post_data_trans = apply_filters( 'posts_data_table_row_data_format', array(
311 - '{id}' => $_post->ID,
312 - '{image}' => get_the_post_thumbnail( $_post, apply_filters( 'posts_data_table_image_size', 'thumbnail' ) ),
313 - '{title}' => $title,
314 - '{category}' => \get_the_category_list( ', ', '', $_post->ID ),
315 - '{tags}' => \get_the_tag_list( '', ', ', '', $_post->ID ),
316 - '{date}' => \get_the_date( $args['date_format'], $_post ),
317 - '{author}' => $author,
318 - '{content}' => $this->get_post_content( $args['content_length'] ),
319 - '{timestamp}' => $_post->post_date
320 - ) );
311 + // Loop through posts and add a row for each
312 + foreach ( (array) $all_posts as $_post ) {
313 + setup_postdata( $_post );
321 314
322 - $table_body .= strtr( $body_row_fmt, $post_data_trans );
323 - } // foreach post
315 + // Format title
316 + $title = sprintf( '<a href="%1$s">%2$s</a>', get_permalink( $_post ), get_the_title( $_post ) );
324 317
325 - wp_reset_postdata();
318 + // Format author
319 + $author = sprintf(
320 + '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
321 + esc_url( get_author_posts_url( $_post->post_author ) ),
322 + /* translators: %s: the author's name */
323 + esc_attr( sprintf( __( 'Posts by %s', 'posts-data-table' ), get_the_author() ) ),
324 + get_the_author()
325 + );
326 326
327 - $table_body = sprintf( '<tbody>%s</tbody>', $table_body );
327 + $post_data_trans = apply_filters(
328 + 'posts_data_table_row_data_format',
329 + [
330 + '{id}' => $_post->ID,
331 + '{image}' => get_the_post_thumbnail( $_post, apply_filters( 'posts_data_table_image_size', 'thumbnail' ) ),
332 + '{title}' => $title,
333 + '{categories}' => get_the_category_list( ', ', '', $_post->ID ),
334 + '{tags}' => get_the_tag_list( '', ', ', '', $_post->ID ),
335 + '{date}' => get_the_date( $args['date_format'], $_post ),
336 + '{author}' => $author,
337 + '{content}' => $this->get_post_content( $args['content_length'] ),
338 + '{timestamp}' => $_post->post_date
339 + ]
340 + );
328 341
329 - $paging_attr = 'false';
342 + $table_body .= strtr( $body_row_fmt, $post_data_trans );
343 + } // foreach post
330 344
331 - if ( $args['rows_per_page'] && $args['rows_per_page'] < count( $all_posts ) ) {
332 - $paging_attr = 'true';
333 - }
345 + wp_reset_postdata();
334 346
335 - $order_attr = '';
347 + $table_body = sprintf( '<tbody>%s</tbody>', $table_body );
336 348
337 - if ( false !== $table_sort_index ) {
338 - // 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"
339 - $order_attr = sprintf( '[[%u, "%s"]]', esc_attr( $table_sort_index ), esc_attr( $args['sort_order'] ) );
340 - }
349 + $paging_attr = 'true';
341 350
342 - $offset_attr = ( $args['scroll_offset'] === false ) ? 'false' : $args['scroll_offset'];
343 - $table_class = 'posts-data-table';
351 + $order_attr = '';
344 352
345 - if ( ! $args['wrap'] ) {
346 - $table_class .= ' nowrap';
347 - }
353 + if ( false !== $table_sort_index ) {
354 + // 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"
355 + $order_attr = sprintf( '[[%u, "%s"]]', esc_attr( $table_sort_index ), esc_attr( $args['sort_order'] ) );
356 + }
348 357
349 - $table_attributes = sprintf(
350 - '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%%"',
351 - self::$table_count,
352 - esc_attr( $table_class ),
353 - esc_attr( $args['rows_per_page'] ),
354 - esc_attr( $paging_attr ),
355 - $order_attr, // escaped above
356 - esc_attr( $args['search_on_click'] ? 'true' : 'false' ),
357 - esc_attr( $offset_attr )
358 - );
358 + $offset_attr = ( $args['scroll_offset'] === false ) ? 'false' : $args['scroll_offset'];
359 + $table_class = 'posts-data-table';
359 360
360 - $output = sprintf( '<table %1$s>%2$s%3$s</table>', $table_attributes, $table_head, $table_body );
361 + if ( ! $args['wrap'] ) {
362 + $table_class .= ' nowrap';
363 + }
361 364
362 - // Increment the table count
363 - self::$table_count ++;
365 + $table_attributes = sprintf(
366 + '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%%"',
367 + self::$table_count,
368 + esc_attr( $table_class ),
369 + esc_attr( $args['rows_per_page'] ),
370 + esc_attr( $paging_attr ),
371 + $order_attr, // escaped above
372 + esc_attr( $args['search_on_click'] ? 'true' : 'false' ),
373 + esc_attr( $offset_attr )
374 + );
364 375
365 - return apply_filters( 'posts_data_table_html_output', $output, $args );
366 - }
376 + $output = sprintf( '<table %1$s>%2$s%3$s</table>', $table_attributes, $table_head, $table_body );
367 377
368 - /**
369 - * Retrieve the post content, truncated to the number of words specified by $num_words.
370 - *
371 - * Must be called with the Loop or a secondary loop after a call to setup_postdata().
372 - *
373 - * @param int $num_words The number of words to trim the content to
374 - * @return string The (truncated) post content
375 - */
376 - private function get_post_content( $num_words = 15 ) {
377 - $text = get_the_content( '' );
378 - $text = strip_shortcodes( $text );
379 - $text = apply_filters( 'the_content', $text );
378 + // Increment the table count
379 + self::$table_count++;
380 380
381 - if ( $num_words > 0 ) {
382 - $text = wp_trim_words( $text, $num_words, ' &hellip;' );
383 - }
384 - return $text;
385 - }
381 + return apply_filters( 'posts_data_table_html_output', $output, $args );
382 + }
383 +
384 + private function back_compat_args( $args ) {
385 + if ( ! empty( $args['columns'] ) ) {
386 + $columns = array_map( 'trim', explode( ',', $args['columns'] ) );
387 +
388 + if ( false !== ( $index = array_search( 'category', $columns, true ) ) ) {
389 + $columns[ $index ] = 'categories';
390 + }
391 +
392 + $args['columns'] = implode( ',', $columns );
393 + }
394 +
395 + if ( ! empty( $args['sort_by'] ) && 'category' === $args['sort_by'] ) {
396 + $args['sort_by'] = 'categories';
397 + }
398 +
399 + return $args;
400 + }
401 +
402 + /**
403 + * Retrieve the post content, truncated to the number of words specified by $num_words.
404 + *
405 + * Must be called with the Loop or a secondary loop after a call to setup_postdata().
406 + *
407 + * @param int $num_words The number of words to trim the content to
408 + * @return string The (truncated) post content
409 + */
410 + private function get_post_content( $num_words = 15 ) {
411 + $text = get_the_content( '' );
412 + $text = strip_shortcodes( $text );
413 + $text = apply_filters( 'the_content', $text );
414 +
415 + if ( $num_words > 0 ) {
416 + $text = wp_trim_words( $text, $num_words, ' &hellip;' );
417 + }
418 +
419 + return $text;
420 + }
421 +
422 + public function get_page_lengths( $default_length ) {
423 + $length_numbers = apply_filters( 'posts_data_table_default_page_lengths', [ 10, 25, 50, 100 ] );
424 +
425 + if ( $default_length != -1 && !in_array( $default_length, $length_numbers ) ) {
426 + $length_numbers[] = $default_length;
427 + }
428 +
429 + sort( $length_numbers );
430 +
431 + $lengths = [
432 + array_merge( $length_numbers, [ -1 ] ),
433 + array_merge( $length_numbers, [ __( 'All', 'posts-data-table' ) ] )
434 + ];
435 +
436 + return $lengths;
437 + }
386 438
387 439 }