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 | posts-data-table.php +36 -363 1.0.61.4.13 View file →
@@ -1,378 +1,51 @@
1 1 <?php
2 2 /**
3 3 * The main plugin file for Posts Table with Search & Sort.
4 4 *
5 - * @package Posts_Data_Table
6 - * @author Andrew Keith <andy@barn2.co.uk>
7 - * @license GPL-2.0+
8 - * @link http://barn2.co.uk
9 - * @copyright 2016 Barn2 Media
5 + * @package Barn2\posts-table-search-sort
6 + * @author Barn2 Plugins <support@barn2.com>
7 + * @license GPL-3.0
8 + * @copyright Barn2 Media Ltd
10 9 *
11 10 * @wordpress-plugin
12 - * Plugin Name: Posts Table with Search & Sort
13 - * Description: This plugin provides a shortcode to show a list of your site's posts in a searchable and sortable table.
14 - * Version: 1.0.6
15 - * Author: Barn2 Media
16 - * Author URI: http://barn2.co.uk
17 - * Text Domain: posts-data-table
18 - * Domain Path: /languages
19 - * License: GPL-2.0+
20 - * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11 + * Plugin Name: Posts Table with Search & Sort
12 + * Plugin URI: https://wordpress.org/plugins/posts-data-table/
13 + * Description: List your posts in an instantly searchable & sortable table.
14 + * Version: 1.4.13
15 + * Author: Barn2 Plugins
16 + * Author URI: https://barn2.com
17 + * Text Domain: posts-data-table
18 + * Domain Path: /languages
19 + *
20 + * Requires at least: 6.1
21 + * Requires PHP: 7.4
22 + *
23 + * Copyright: Barn2 Media Ltd
24 + * License: GNU General Public License v3.0
25 + * License URI: https://www.gnu.org/licenses/gpl.html
21 26 */
22 27
28 +namespace Barn2\Plugin\Posts_Table_Search_Sort;
29 +
23 30 // Prevent direct file access
24 -if ( ! defined ( 'ABSPATH' ) ) {
31 +if ( ! defined( '\ABSPATH' ) ) {
25 32 exit;
26 33 }
27 34
28 -// Current version of this plugin
29 -define( 'POSTS_DATA_TABLE_VERSION', '1.0.5' );
35 +const PLUGIN_VERSION = '1.4.13';
36 +const PLUGIN_FILE = __FILE__;
30 37
31 -class Posts_Data_Table_Plugin {
32 -
33 - private $shortcode = 'posts_data_table';
34 -
35 - private $shortcode_defaults = array(
36 - 'columns' => 'title,content,date,author,category',
37 - 'rows_per_page' => 20,
38 - 'sort_by' => 'date',
39 - 'sort_order' => '',
40 - 'category' => '',
41 - 'search_on_click' => true,
42 - 'wrap' => true,
43 - 'content_length' => 15,
44 - 'scroll_offset' => 15
45 - );
46 -
47 - private $table_count = 1;
48 -
49 - public function __construct() {
50 - add_action( 'plugins_loaded', array( $this, 'init' ) );
51 - add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'add_plugin_settings_link' ) );
52 - }
53 -
54 - public function init() {
55 - // Don't init plugin if Pro version exists
56 - if ( !class_exists( 'Posts_Table_Pro_Plugin' ) ) {
57 - // Load the text domain - should go on 'plugins_loaded' hook
58 - $this->load_textdomain();
59 -
60 - // Register shortcode
61 - add_shortcode( $this->shortcode, array( $this, 'shortcode' ) );
62 -
63 - // Register styles and scripts
64 - add_action( 'wp_enqueue_scripts', array( $this, 'register_styles' ) );
65 - add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
66 - }
67 - }
68 -
69 - public function load_textdomain() {
70 - load_plugin_textdomain( 'posts-data-table', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
71 - }
72 -
73 - public function register_styles() {
74 - wp_enqueue_style( 'jquery-data-tables', plugins_url( 'assets/css/datatables.min.css', __FILE__ ), array(), '1.10.12' );
75 - wp_enqueue_style( 'posts-data-table', plugins_url( 'assets/css/posts-data-table.min.css', __FILE__ ), array( 'jquery-data-tables' ), POSTS_DATA_TABLE_VERSION );
76 - //wp_enqueue_style( 'posts-data-table', plugins_url( 'assets/css/posts-data-table.css', __FILE__ ), array( 'jquery-data-tables' ), POSTS_DATA_TABLE_VERSION );
77 - }
78 -
79 - public function register_scripts() {
80 - wp_enqueue_script( 'jquery-data-tables', plugins_url( 'assets/js/datatables.min.js', __FILE__ ), array( 'jquery' ), '1.10.12', true );
81 - wp_enqueue_script( 'posts-data-table', plugins_url( 'assets/js/posts-data-table.min.js', __FILE__ ), array( 'jquery-data-tables' ), POSTS_DATA_TABLE_VERSION, true );
82 - //wp_enqueue_script( 'posts-data-table', plugins_url( 'assets/js/posts-data-table.js', __FILE__ ), array( 'jquery-data-tables' ), POSTS_DATA_TABLE_VERSION, true );
83 -
84 - $locale = get_locale();
85 - $supported_locales = $this->get_supported_locales();
86 -
87 - // Add language file to script if locale is supported (English file is not added as this is the default language)
88 - if ( array_key_exists( $locale, $supported_locales ) ) {
89 - wp_localize_script( 'posts-data-table', 'posts_data_table', array(
90 - 'langurl' => $supported_locales[$locale]
91 - ) );
92 - }
93 - }
94 -
95 - public function add_plugin_settings_link( $links ) {
96 - $links[] = sprintf( '<a href="%1$s" target="_blank">%2$s</a>', esc_url( 'https://barn2.co.uk/wordpress-products/posts-table-pro/'), __( 'Pro Version', 'posts-data-table' ) );
97 - return $links;
98 - }
99 -
100 - /**
101 - * Handles our posts data table shortcode.
102 - *
103 - * @param array $atts The attributes passed in to the shortcode
104 - * @param string $content The content passed to the shortcode (not used)
105 - * @return string The shortcode output
106 - */
107 - public function shortcode( $atts, $content = '' ) {
108 - $atts = shortcode_atts( $this->shortcode_defaults, $atts, $this->shortcode );
109 - return $this->get_posts_data_table( $atts );
110 - }
111 -
112 - /**
113 - * Returns an array of locales supported by the plugin.
114 - * The array returned uses the locale as the array key mapped to the URL of the corresponding translation file.
115 - *
116 - * @return array The supported locales
117 - */
118 - private function get_supported_locales() {
119 - $lang_file_base_url = plugins_url( 'languages/data-tables/', __FILE__ );
120 -
121 - return array(
122 - 'es_ES' => $lang_file_base_url . 'Spanish.json',
123 - 'fr_FR' => $lang_file_base_url . 'French.json',
124 - 'fr_BE' => $lang_file_base_url . 'French.json',
125 - 'fr_CA' => $lang_file_base_url . 'French.json',
126 - 'de_DE' => $lang_file_base_url . 'German.json',
127 - 'de_CH' => $lang_file_base_url . 'German.json',
128 - 'el' => $lang_file_base_url . 'Greek.json',
129 - 'el_EL' => $lang_file_base_url . 'Greek.json',
130 - );
131 - }
132 -
133 - /**
134 - * Retrieves a data table containing a list of posts based on the specified arguments.
135 - *
136 - * @param array $args An array of options used to display the posts table
137 - * @return string The posts table HTML output
138 - */
139 - private function get_posts_data_table( $args ) {
38 +// Autoloader.
39 +require_once __DIR__ . '/vendor/autoload.php';
140 40
141 - if ( empty( $args['columns'] ) ) {
142 - $args['columns'] = $this->shortcode_defaults['columns'];
143 - }
144 -
145 - $args['rows_per_page'] = filter_var( $args['rows_per_page'], FILTER_VALIDATE_INT );
146 - if ( ($args['rows_per_page'] < 1) || !$args['rows_per_page'] ) {
147 - $args['rows_per_page'] = false;
148 - }
149 -
150 - if ( !in_array( $args['sort_by'], array('id', 'title', 'category', 'date', 'author', 'content') ) ) {
151 - $args['sort_by'] = $this->shortcode_defaults['sort_by'];
152 - }
153 -
154 - if ( !in_array( $args['sort_order'], array('asc', 'desc') ) ) {
155 - $args['sort_order'] = $this->shortcode_defaults['sort_order'];
156 - }
157 -
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 - }
166 -
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 );
171 -
172 - $date_format = 'Y/m/d';
173 - $output = $table_head = $table_body = $body_row_fmt = '';
174 -
175 - // Start building the args needed for our posts query
176 - $post_args = array(
177 - 'post_type' => 'post',
178 - 'posts_per_page' => -1,
179 - 'post_status' => 'publish',
180 - 'suppress_filters' => false // Ensure WPML filters run on this query
181 - );
182 -
183 - if ( $args['category'] ) {
184 - $category = get_category_by_slug( $args['category'] );
185 -
186 - if ( $category ) {
187 - $post_args['category_name'] = $category->slug;
188 - }
189 - }
190 -
191 - // Get all published posts in the current language
192 - $all_posts_curr_lang = get_posts( $post_args );
41 +/**
42 + * Helper function to access the shared plugin instance.
43 + *
44 + * @return Plugin
45 + */
46 +function posts_table_search_sort() {
47 + return Plugin_Factory::create( PLUGIN_FILE, PLUGIN_VERSION );
48 +}
193 49
194 - if ( is_array( $all_posts_curr_lang ) && $all_posts_curr_lang ) { // if we have posts
195 -
196 - /**
197 - * Define an array of all possible columns and their default heading, priority, and column width.
198 - *
199 - * Priority values are used to determine visiblity at small screen sizes (1 = highest priority, 6 = lowest priority).
200 - * Column widths are automatically calculated by DataTables, but can be overridden by using filter 'posts_data_table_column_defaults'.
201 - */
202 - $column_defaults = array(
203 - 'id' => array(
204 - 'heading' => __('ID', 'posts-data-table'),
205 - 'priority' => 3,
206 - 'width' => ''
207 - ),
208 - 'title' => array(
209 - 'heading' => __('Title', 'posts-data-table'),
210 - 'priority' => 1,
211 - 'width' => ''
212 - ),
213 - 'category' => array(
214 - 'heading' => __('Categories', 'posts-data-table'),
215 - 'priority' => 6,
216 - 'width' => ''
217 - ),
218 - 'date' => array(
219 - 'heading' => __('Date', 'posts-data-table'),
220 - 'priority' => 2,
221 - 'width' => ''
222 - ),
223 - 'author' => array(
224 - 'heading' => __('Author', 'posts-data-table'),
225 - 'priority' => 4,
226 - 'width' => ''
227 - ),
228 - 'content' => array(
229 - 'heading' => __('Content', 'posts-data-table'),
230 - 'priority' => 5,
231 - 'width' => ''
232 - ),
233 - );
234 -
235 - $all_columns = array_keys( $column_defaults );
236 -
237 - // Allow users to override defaults
238 - $column_defaults = apply_filters( 'posts_data_table_column_defaults', $column_defaults );
239 - $column_defaults = apply_filters( 'posts_data_table_column_defaults_' . $this->table_count, $column_defaults );
240 -
241 - // Get the columns to be used in this table
242 - $columns = array_map( 'trim', explode( ',', strtolower( $args['columns'] ) ) );
243 -
244 - // If none of the user-specfied columns are valid, use the default columns instead
245 - if ( !array_intersect( $all_columns, $columns ) ) {
246 - $columns = explode( ',', $this->shortcode_defaults['columns'] );
247 - }
248 -
249 - // Build table header
250 - $heading_fmt = '<th data-name="%1$s" data-priority="%2$u" data-width="%3$s">%4$s</th>';
251 - $cell_fmt = '<td>%s</td>';
252 -
253 - foreach( $columns as $column ) {
254 -
255 - if ( array_key_exists( $column, $column_defaults ) ) { // Double-check column name is valid
256 -
257 - // Add heading to table
258 - $table_head .= sprintf( $heading_fmt, $column, $column_defaults[$column]['priority'], $column_defaults[$column]['width'], $column_defaults[$column]['heading'] );
259 -
260 - // Add placeholder to table body format string so that content for this column is included in table output
261 - $body_row_fmt .= sprintf($cell_fmt, '{' . $column . '}');
262 - }
263 - }
264 -
265 - $sort_column = $args['sort_by'];
266 - $sort_index = array_search( $sort_column, $columns );
267 -
268 - if ( $sort_index === false && array_key_exists( $sort_column, $column_defaults ) ) {
269 - // Sort column is not in list of displayed columns so we'll add it as a hidden column at end of table
270 - $table_head .= sprintf( '<th data-name="%1$s" data-visible="false">%2$s</th>', $sort_column, $column_defaults[$sort_column]['heading'] );
271 -
272 - // Make sure data for this column is included in table content
273 - $body_row_fmt .= sprintf($cell_fmt, $sort_column);
274 -
275 - // Set the sort column index to be this hidden column
276 - $sort_index = count($columns);
277 - }
278 -
279 - $table_head = sprintf( '<thead><tr>%s</tr></thead>', $table_head );
280 - // end table header
281 -
282 - // Build table body
283 - $body_row_fmt = '<tr>' . $body_row_fmt . '</tr>';
284 -
285 - // Loop through posts and add a row for each
286 - foreach ( (array) $all_posts_curr_lang as $_post ) {
287 - setup_postdata( $_post );
288 -
289 - // Format title
290 - $title = sprintf( '<a href="%1$s">%2$s</a>', get_permalink($_post), get_the_title( $_post ) );
291 -
292 - // Format author
293 - $author = sprintf(
294 - '<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
295 - esc_url( get_author_posts_url( $_post->post_author ) ),
296 - esc_attr( sprintf( __( 'Posts by %s' ), get_the_author() ) ),
297 - get_the_author()
298 - );
299 -
300 - $post_data_trans = array(
301 - '{id}' => $_post->ID,
302 - '{title}' => $title,
303 - '{category}' => get_the_category_list( ', ', '', $_post->ID ),
304 - '{date}' => get_the_date( $date_format, $_post ),
305 - '{author}' => $author,
306 - '{content}' => $this->get_post_content( $args['content_length'] )
307 - );
308 -
309 - $table_body .= strtr( $body_row_fmt, $post_data_trans );
310 -
311 - } // foreach post
312 -
313 - wp_reset_postdata();
314 -
315 - $table_body = sprintf( '<tbody>%s</tbody>', $table_body );
316 - // end table body
317 -
318 - $paging_attr = 'false';
319 - if ( ( $args['rows_per_page'] > 1 ) && ( $args['rows_per_page'] < count($all_posts_curr_lang) ) ) {
320 - $paging_attr = 'true';
321 - }
322 -
323 - $order_attr = ( $sort_index === false ) ? '' : sprintf( '[[%u, "%s"]]', $sort_index, $args['sort_order'] );
324 - $offset_attr = ( $args['scroll_offset'] === false ) ? 'false' : $args['scroll_offset'];
325 -
326 - $table_class = 'posts-data-table';
327 - if ( !$args['wrap'] ) {
328 - $table_class .= ' nowrap';
329 - }
330 -
331 - $output = sprintf(
332 - '<table '
333 - . 'id="posts-table-%1$u" '
334 - . 'class="%2$s" '
335 - . 'data-page-length="%3$u" '
336 - . 'data-paging="%4$s" '
337 - . 'data-order=\'%5$s\' '
338 - . 'data-click-filter="%6$s" '
339 - . 'data-scroll-offset="%7$s" '
340 - . 'cellspacing="0" width="100%%">'
341 - . '%8$s%9$s' .
342 - '</table>',
343 - $this->table_count,
344 - esc_attr( $table_class ),
345 - esc_attr( $args['rows_per_page'] ),
346 - esc_attr( $paging_attr ),
347 - esc_attr( $order_attr ),
348 - ( $args['search_on_click'] ? 'true' : 'false' ),
349 - esc_attr( $offset_attr ),
350 - $table_head,
351 - $table_body
352 - );
353 -
354 - $this->table_count++;
355 - } // if posts found
356 -
357 - return $output;
358 - } // get_comments_list
359 -
360 - /**
361 - * Retrieve the post content, truncated to the number of words specified by $num_words.
362 - *
363 - * Must be called with the Loop or a secondary loop after a call to setup_postdata().
364 - *
365 - * @param int $num_words The number of words to trim the content to
366 - * @return string The (truncated) post content
367 - */
368 - private function get_post_content( $num_words = 15 ) {
369 - $text = get_the_content('');
370 - $text = strip_shortcodes( $text );
371 - $text = apply_filters( 'the_content', $text );
372 - $text = wp_trim_words( $text, $num_words, ' &hellip;' );
373 - return $text;
374 - }
375 -
376 -} // end class
377 -
378 -$posts_data_table = new Posts_Data_Table_Plugin();
50 +// Load the plugin.
51 +posts_table_search_sort()->register();