Version Description
Recommended update: added screen option for users to customize post navigation order for each post type, fixed bug where navigation didn't appear for posts with apostrophe in title, updated unit test bootstrap file, noted compatibility is now WP 4.7-4.9+, and updated copyright date (2018)
Download this release
Release Info
Developer | coffee2code |
Plugin | Admin Post Navigation |
Version | 2.1 |
Comparing to | |
See all releases |
Code changes from version 2.0 to 2.1
- README.md +25 -0
- admin-post-navigation.php +207 -49
- assets/admin-post-navigation.js +1 -1
- readme.txt +60 -21
- tests/bootstrap.php +21 -3
- tests/test-admin-post-navigation.php +135 -12
README.md
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Admin Post Navigation
|
2 |
+
|
3 |
+
A plugin for WordPress that adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
|
4 |
+
|
5 |
+
This plugin can be found in the WordPress Plugin Directory: https://wordpress.org/plugins/admin-post-navigation/
|
6 |
+
|
7 |
+
## Installation
|
8 |
+
|
9 |
+
1. Install via the built-in WordPress plugin installer. Or install the plugin code inside the plugins directory for your site (typically `/wp-content/plugins/`).
|
10 |
+
2. Activate the plugin through the 'Plugins' admin menu in WordPress
|
11 |
+
|
12 |
+
|
13 |
+
## Additional Documentation
|
14 |
+
|
15 |
+
See [readme.txt](https://github.com/coffee2code/admin-post-navigation/blob/master/readme.txt) for additional usage information.
|
16 |
+
|
17 |
+
|
18 |
+
## Support
|
19 |
+
|
20 |
+
Commercial support and custom development are not presently available. You can raise an [issue](https://github.com/coffee2code/admin-post-navigation/issues) on GitHub or post in the [plugin's support forum on WordPress.org](https://wordpress.org/support/plugin/admin-post-navigation/). If the plugin has been of benefit to you, how about [submitting a review](https://wordpress.org/support/plugin/admin-post-navigation/reviews/) for it in the WordPress Plugin Directory or considerating a [donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6ARCFJ9TX3522)?
|
21 |
+
|
22 |
+
|
23 |
+
## License
|
24 |
+
|
25 |
+
This plugin is free software; you can redistribute it and/or modify it under the terms of the [GNU General Public License](http://www.gnu.org/licenses/gpl-2.0.html) as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
admin-post-navigation.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: Admin Post Navigation
|
4 |
-
* Version: 2.
|
5 |
* Plugin URI: http://coffee2code.com/wp-plugins/admin-post-navigation/
|
6 |
* Author: Scott Reilly
|
7 |
* Author URI: http://coffee2code.com/
|
@@ -10,7 +10,7 @@
|
|
10 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
* Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
|
12 |
*
|
13 |
-
* Compatible with WordPress
|
14 |
*
|
15 |
* =>> Read the accompanying readme.txt file for instructions and documentation.
|
16 |
* =>> Also, visit the plugin's homepage for additional information and updates.
|
@@ -18,21 +18,24 @@
|
|
18 |
*
|
19 |
* @package Admin_Post_Navigation
|
20 |
* @author Scott Reilly
|
21 |
-
* @version 2.
|
22 |
*/
|
23 |
|
24 |
/*
|
25 |
* TODO:
|
26 |
* - Add ability for navigation to save current post before navigating away.
|
27 |
-
* - Hide screen option checkbox for metabox if metabox is being hidden
|
28 |
* - Add screen option allowing user selection of post navigation order
|
29 |
* - Add more unit tests
|
30 |
* - Add dropdown to post nav links to allow selecting different types of things
|
31 |
* to navigate to (e.g. next draft (if looking at a draft), next in category X)
|
|
|
|
|
|
|
|
|
32 |
*/
|
33 |
|
34 |
/*
|
35 |
-
Copyright (c) 2008-
|
36 |
|
37 |
This program is free software; you can redistribute it and/or
|
38 |
modify it under the terms of the GNU General Public License
|
@@ -74,24 +77,28 @@ class c2c_AdminPostNavigation {
|
|
74 |
private static $next_text = '';
|
75 |
|
76 |
/**
|
77 |
-
*
|
78 |
*
|
79 |
-
*
|
|
|
80 |
*
|
81 |
* @access private
|
|
|
82 |
*
|
83 |
* @var array
|
84 |
*/
|
85 |
-
private static $
|
86 |
|
87 |
/**
|
88 |
-
*
|
|
|
|
|
89 |
*
|
90 |
* @access private
|
91 |
*
|
92 |
-
* @var
|
93 |
*/
|
94 |
-
private static $
|
95 |
|
96 |
/**
|
97 |
* Returns version of the plugin.
|
@@ -99,14 +106,15 @@ class c2c_AdminPostNavigation {
|
|
99 |
* @since 1.7
|
100 |
*/
|
101 |
public static function version() {
|
102 |
-
return '2.
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
* Class constructor: initializes class variables and adds actions and filters.
|
107 |
*/
|
108 |
public static function init() {
|
109 |
-
|
|
|
110 |
}
|
111 |
|
112 |
/**
|
@@ -115,7 +123,6 @@ class c2c_AdminPostNavigation {
|
|
115 |
* @since 1.7
|
116 |
*/
|
117 |
public static function register_post_page_hooks() {
|
118 |
-
|
119 |
// Load textdomain.
|
120 |
load_plugin_textdomain( 'admin-post-navigation' );
|
121 |
|
@@ -126,6 +133,9 @@ class c2c_AdminPostNavigation {
|
|
126 |
// Register hooks.
|
127 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_enqueue_scripts_and_styles' ) );
|
128 |
add_action( 'do_meta_boxes', array( __CLASS__, 'do_meta_box' ), 10, 3 );
|
|
|
|
|
|
|
129 |
}
|
130 |
|
131 |
/**
|
@@ -138,13 +148,61 @@ class c2c_AdminPostNavigation {
|
|
138 |
wp_enqueue_style( 'admin-post-navigation-admin' );
|
139 |
|
140 |
wp_register_script( 'admin-post-navigation-admin', plugins_url( 'assets/admin-post-navigation.js', __FILE__ ), array( 'jquery' ), self::version(), true );
|
141 |
-
// Localize script.
|
142 |
-
wp_localize_script( 'admin-post-navigation-admin', 'c2c_apn', array(
|
143 |
-
'tag' => version_compare( $GLOBALS['wp_version'], '4.3', '>=' ) ? 'h1' : 'h2',
|
144 |
-
) );
|
145 |
wp_enqueue_script( 'admin-post-navigation-admin' );
|
146 |
}
|
147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
/**
|
149 |
* Register meta box.
|
150 |
*
|
@@ -156,16 +214,11 @@ class c2c_AdminPostNavigation {
|
|
156 |
* @param WP_Post $post The post.
|
157 |
*/
|
158 |
public static function do_meta_box( $post_type, $type, $post ) {
|
159 |
-
|
160 |
-
if ( ! in_array( $post_type, $post_types ) ) {
|
161 |
return;
|
162 |
}
|
163 |
|
164 |
-
$post_statuses = (
|
165 |
-
if ( $post_statuses ) {
|
166 |
-
foreach( $post_statuses as $i => $v ) { $GLOBALS['wpdb']->escape_by_ref( $v ); $post_statuses[ $i ] = $v; }
|
167 |
-
self::$post_statuses_sql = "'" . implode( "', '", $post_statuses ) . "'";
|
168 |
-
}
|
169 |
|
170 |
if ( in_array( $post->post_status, $post_statuses ) ) {
|
171 |
add_meta_box(
|
@@ -192,10 +245,13 @@ class c2c_AdminPostNavigation {
|
|
192 |
|
193 |
$prev = self::previous_post();
|
194 |
if ( $prev ) {
|
195 |
-
$post_title =
|
196 |
-
$display .=
|
197 |
-
|
198 |
-
|
|
|
|
|
|
|
199 |
}
|
200 |
|
201 |
$next = self::next_post();
|
@@ -203,11 +259,13 @@ class c2c_AdminPostNavigation {
|
|
203 |
if ( $display ) {
|
204 |
$display .= ' ';
|
205 |
}
|
206 |
-
$post_title =
|
207 |
-
$display .=
|
208 |
-
'" id="admin-post-nav-next" title="'
|
209 |
-
|
210 |
-
'
|
|
|
|
|
211 |
}
|
212 |
|
213 |
$display = '<span id="admin-post-nav">' . $display . '</span>';
|
@@ -233,6 +291,110 @@ class c2c_AdminPostNavigation {
|
|
233 |
return strtolower( $label );
|
234 |
}
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
/**
|
237 |
* Returns the previous or next post relative to the current post.
|
238 |
*
|
@@ -259,28 +421,24 @@ class c2c_AdminPostNavigation {
|
|
259 |
|
260 |
$post = get_post( $post_ID );
|
261 |
|
262 |
-
|
|
|
|
|
|
|
|
|
263 |
return false;
|
264 |
}
|
265 |
|
266 |
-
$
|
|
|
267 |
|
268 |
-
$sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status IN (" .
|
269 |
|
270 |
// Determine order.
|
271 |
-
|
272 |
-
$orderby = 'post_title';
|
273 |
-
} else {
|
274 |
-
$orderby = 'post_date';
|
275 |
-
}
|
276 |
-
$default_orderby = $orderby;
|
277 |
-
// Restrict orderby to actual post fields.
|
278 |
-
$orderby = esc_sql( apply_filters( 'c2c_admin_post_navigation_orderby', $orderby, $post_type ) );
|
279 |
-
if ( ! in_array( $orderby, array( 'comment_count', 'ID', 'menu_order', 'post_author', 'post_content', 'post_content_filtered', 'post_date', 'post_excerpt', 'post_date_gmt', 'post_mime_type', 'post_modified', 'post_modified_gmt', 'post_name', 'post_parent', 'post_status', 'post_title', 'post_type' ) ) ) {
|
280 |
-
$orderby = $default_orderby;
|
281 |
-
}
|
282 |
|
283 |
-
$
|
|
|
284 |
|
285 |
$sort = $type == '<' ? 'DESC' : 'ASC';
|
286 |
$sql .= "ORDER BY {$orderby} {$sort} LIMIT {$offset}, {$limit}";
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: Admin Post Navigation
|
4 |
+
* Version: 2.1
|
5 |
* Plugin URI: http://coffee2code.com/wp-plugins/admin-post-navigation/
|
6 |
* Author: Scott Reilly
|
7 |
* Author URI: http://coffee2code.com/
|
10 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
* Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
|
12 |
*
|
13 |
+
* Compatible with WordPress 4.7 through 4.9+.
|
14 |
*
|
15 |
* =>> Read the accompanying readme.txt file for instructions and documentation.
|
16 |
* =>> Also, visit the plugin's homepage for additional information and updates.
|
18 |
*
|
19 |
* @package Admin_Post_Navigation
|
20 |
* @author Scott Reilly
|
21 |
+
* @version 2.1
|
22 |
*/
|
23 |
|
24 |
/*
|
25 |
* TODO:
|
26 |
* - Add ability for navigation to save current post before navigating away.
|
|
|
27 |
* - Add screen option allowing user selection of post navigation order
|
28 |
* - Add more unit tests
|
29 |
* - Add dropdown to post nav links to allow selecting different types of things
|
30 |
* to navigate to (e.g. next draft (if looking at a draft), next in category X)
|
31 |
+
* - When navigating via menu_order, respect hierarchy and navigate siblings.
|
32 |
+
* - Add filter to allow customizing the list of orderby options in screen options?
|
33 |
+
* - Add post status as series of checkboxes in Screen Options
|
34 |
+
* - Add support for secondary orderby
|
35 |
*/
|
36 |
|
37 |
/*
|
38 |
+
Copyright (c) 2008-2018 by Scott Reilly (aka coffee2code)
|
39 |
|
40 |
This program is free software; you can redistribute it and/or
|
41 |
modify it under the terms of the GNU General Public License
|
77 |
private static $next_text = '';
|
78 |
|
79 |
/**
|
80 |
+
* Post fields available as orderby options.
|
81 |
*
|
82 |
+
* Note: not meant to be an exhaustive list, just the ones available to users
|
83 |
+
* via dropdown in Screen Options panel.
|
84 |
*
|
85 |
* @access private
|
86 |
+
* @since 2.1
|
87 |
*
|
88 |
* @var array
|
89 |
*/
|
90 |
+
private static $orderby_fields = array( 'ID', 'menu_order', 'post_date', 'post_modified', 'post_name', 'post_title' );
|
91 |
|
92 |
/**
|
93 |
+
* Default post statuses for navigation.
|
94 |
+
*
|
95 |
+
* Filterable later.
|
96 |
*
|
97 |
* @access private
|
98 |
*
|
99 |
+
* @var array
|
100 |
*/
|
101 |
+
private static $post_statuses = array( 'draft', 'future', 'pending', 'private', 'publish' );
|
102 |
|
103 |
/**
|
104 |
* Returns version of the plugin.
|
106 |
* @since 1.7
|
107 |
*/
|
108 |
public static function version() {
|
109 |
+
return '2.1';
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* Class constructor: initializes class variables and adds actions and filters.
|
114 |
*/
|
115 |
public static function init() {
|
116 |
+
add_filter( 'set-screen-option', array( __CLASS__, 'save_screen_settings' ), 10, 3 );
|
117 |
+
add_action( 'load-post.php', array( __CLASS__, 'register_post_page_hooks' ) );
|
118 |
}
|
119 |
|
120 |
/**
|
123 |
* @since 1.7
|
124 |
*/
|
125 |
public static function register_post_page_hooks() {
|
|
|
126 |
// Load textdomain.
|
127 |
load_plugin_textdomain( 'admin-post-navigation' );
|
128 |
|
133 |
// Register hooks.
|
134 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_enqueue_scripts_and_styles' ) );
|
135 |
add_action( 'do_meta_boxes', array( __CLASS__, 'do_meta_box' ), 10, 3 );
|
136 |
+
|
137 |
+
// Screen options.
|
138 |
+
add_filter( 'screen_settings', array( __CLASS__, 'screen_settings' ), 10, 2 );
|
139 |
}
|
140 |
|
141 |
/**
|
148 |
wp_enqueue_style( 'admin-post-navigation-admin' );
|
149 |
|
150 |
wp_register_script( 'admin-post-navigation-admin', plugins_url( 'assets/admin-post-navigation.js', __FILE__ ), array( 'jquery' ), self::version(), true );
|
|
|
|
|
|
|
|
|
151 |
wp_enqueue_script( 'admin-post-navigation-admin' );
|
152 |
}
|
153 |
|
154 |
+
/**
|
155 |
+
* Outputs screen settings.
|
156 |
+
*
|
157 |
+
* @since 2.1
|
158 |
+
*
|
159 |
+
* @param string $screen_settings Screen settings markup.
|
160 |
+
* @param WP_Screen $screen WP_Screen object.
|
161 |
+
* @return string
|
162 |
+
*/
|
163 |
+
public static function screen_settings( $screen_settings, $screen ) {
|
164 |
+
if ( empty( $screen->post_type ) || ! self::is_post_type_navigable( $screen->post_type ) ) {
|
165 |
+
return $screen_settings;
|
166 |
+
}
|
167 |
+
|
168 |
+
$option = self::get_setting_name( $screen->post_type );
|
169 |
+
$value = self::get_post_type_orderby( $screen->post_type, get_current_user_id() );
|
170 |
+
|
171 |
+
$screen_settings .= '<fieldset class="">'
|
172 |
+
. '<legend>' . __( 'Admin Post Navigation', 'admin-post-navigation' ) . '</legend>'
|
173 |
+
. '<input type="hidden" name="wp_screen_options[option]" value="' . $option . '" />' . "\n"
|
174 |
+
. '<label for="' . $option . '">'
|
175 |
+
. sprintf( __( 'Navigation order for this post type (%s)', 'admin-post-navigation' ), $screen->post_type )
|
176 |
+
. ' <select name="wp_screen_options[value]">';
|
177 |
+
foreach ( self::$orderby_fields as $orderby ) {
|
178 |
+
$screen_settings .= '<option value="' . $orderby . '" ' . selected( $value, $orderby, false ) . '>' . $orderby . '</option>';
|
179 |
+
}
|
180 |
+
$screen_settings .= '</select>'
|
181 |
+
. '</label>' . "\n"
|
182 |
+
. get_submit_button( __( 'Apply', 'admin-post-navigation' ), 'button', 'screen-options-apply', false )
|
183 |
+
. '</fieldset>';
|
184 |
+
|
185 |
+
return $screen_settings;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Saves screen option values.
|
190 |
+
*
|
191 |
+
* @since 2.1
|
192 |
+
*
|
193 |
+
* @param bool|int $status Screen option value. Default false to skip.
|
194 |
+
* @param string $option The option name.
|
195 |
+
* @param int $value The number of rows to use.
|
196 |
+
* @return bool|string
|
197 |
+
*/
|
198 |
+
public static function save_screen_settings( $status, $option, $value ) {
|
199 |
+
if ( 'c2c_apn_' == substr( $option, 0, 8 ) ) {
|
200 |
+
$status = $value;
|
201 |
+
}
|
202 |
+
|
203 |
+
return $status;
|
204 |
+
}
|
205 |
+
|
206 |
/**
|
207 |
* Register meta box.
|
208 |
*
|
214 |
* @param WP_Post $post The post.
|
215 |
*/
|
216 |
public static function do_meta_box( $post_type, $type, $post ) {
|
217 |
+
if ( ! self::is_post_type_navigable( $post_type ) ) {
|
|
|
218 |
return;
|
219 |
}
|
220 |
|
221 |
+
$post_statuses = self::get_post_statuses( $post_type );
|
|
|
|
|
|
|
|
|
222 |
|
223 |
if ( in_array( $post->post_status, $post_statuses ) ) {
|
224 |
add_meta_box(
|
245 |
|
246 |
$prev = self::previous_post();
|
247 |
if ( $prev ) {
|
248 |
+
$post_title = strip_tags( get_the_title( $prev ) );
|
249 |
+
$display .= sprintf(
|
250 |
+
'<a href="%s" id="admin-post-nav-prev" title="%s" class="admin-post-nav-prev add-new-h2">%s</a>',
|
251 |
+
get_edit_post_link( $prev->ID ),
|
252 |
+
esc_attr( sprintf( __( 'Previous %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ),
|
253 |
+
self::$prev_text
|
254 |
+
);
|
255 |
}
|
256 |
|
257 |
$next = self::next_post();
|
259 |
if ( $display ) {
|
260 |
$display .= ' ';
|
261 |
}
|
262 |
+
$post_title = strip_tags( get_the_title( $next ) );
|
263 |
+
$display .= sprintf(
|
264 |
+
'<a href="%s" id="admin-post-nav-next" title="%s" class="admin-post-nav-next add-new-h2">%s</a>',
|
265 |
+
get_edit_post_link( $next->ID ),
|
266 |
+
esc_attr( sprintf( __( 'Next %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ),
|
267 |
+
self::$next_text
|
268 |
+
);
|
269 |
}
|
270 |
|
271 |
$display = '<span id="admin-post-nav">' . $display . '</span>';
|
291 |
return strtolower( $label );
|
292 |
}
|
293 |
|
294 |
+
/**
|
295 |
+
* Returns the name of the screen option setting for the orderby setting for
|
296 |
+
* the given post type.
|
297 |
+
*
|
298 |
+
* @since 2.1
|
299 |
+
*
|
300 |
+
* @param string $post_type The post type.
|
301 |
+
* @return string
|
302 |
+
*/
|
303 |
+
public static function get_setting_name( $post_type ) {
|
304 |
+
return 'c2c_apn_' . $post_type . '_orderby';
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Determines if a post type has admin navigation enabled.
|
309 |
+
*
|
310 |
+
* By default, the navigation is enabled for all post types. Filter
|
311 |
+
* 'c2c_admin_post_navigation_post_types' to limit its use.
|
312 |
+
*
|
313 |
+
* @since 2.1
|
314 |
+
*
|
315 |
+
* @param string $post_type The post type.
|
316 |
+
* @return bool True if post type has admin navigation enabled, else false.
|
317 |
+
*/
|
318 |
+
public static function is_post_type_navigable( $post_type ) {
|
319 |
+
$post_types = (array) apply_filters( 'c2c_admin_post_navigation_post_types', get_post_types() );
|
320 |
+
|
321 |
+
return in_array( $post_type, $post_types );
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Determines if a given orderby field value is valid.
|
326 |
+
*
|
327 |
+
* Only post table fields are valid.
|
328 |
+
*
|
329 |
+
* @since 2.1
|
330 |
+
*
|
331 |
+
* @param string $orderby The orderby.
|
332 |
+
* @return bool. True if valid, false if not.
|
333 |
+
*/
|
334 |
+
public static function is_valid_orderby( $orderby ) {
|
335 |
+
// By default, restrict orderby to actual post fields.
|
336 |
+
$valid = array(
|
337 |
+
'comment_count', 'ID', 'menu_order', 'post_author', 'post_content', 'post_content_filtered',
|
338 |
+
'post_date', 'post_excerpt', 'post_date_gmt', 'post_mime_type', 'post_modified',
|
339 |
+
'post_modified_gmt', 'post_name', 'post_parent', 'post_status', 'post_title', 'post_type',
|
340 |
+
);
|
341 |
+
|
342 |
+
// Filter the value.
|
343 |
+
//$valid = (array) apply_filters( 'c2c_admin_post_navigation_valid_orderbys', $valid );
|
344 |
+
|
345 |
+
return in_array( $orderby, $valid );
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Determines the orderby value to use for a given post type's navigation.
|
350 |
+
*
|
351 |
+
* @since 2.1
|
352 |
+
*
|
353 |
+
* @param string $post_type The post type.
|
354 |
+
* @param int $user_id Optional. User ID of user, to account for the
|
355 |
+
* value the set via screen options.
|
356 |
+
* @return string
|
357 |
+
*/
|
358 |
+
public static function get_post_type_orderby( $post_type, $user_id = false ) {
|
359 |
+
if ( ! $user_id ) {
|
360 |
+
$user_id = get_current_user_id();
|
361 |
+
}
|
362 |
+
|
363 |
+
if ( is_post_type_hierarchical( $post_type ) ) {
|
364 |
+
$orderby = 'post_title';
|
365 |
+
} else {
|
366 |
+
$orderby = 'post_date';
|
367 |
+
}
|
368 |
+
|
369 |
+
// Get user-selected order for this post type.
|
370 |
+
if ( $user_id ) {
|
371 |
+
$user_orderby = get_user_meta( $user_id, self::get_setting_name( $post_type ), true );
|
372 |
+
if ( $user_orderby && self::is_valid_orderby( $user_orderby ) ) {
|
373 |
+
$orderby = $user_orderby;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
// Filter orderby value.
|
378 |
+
$filter_orderby = apply_filters( 'c2c_admin_post_navigation_orderby', $orderby, $post_type, $user_id );
|
379 |
+
if ( $filter_orderby && self::is_valid_orderby( $filter_orderby ) ) {
|
380 |
+
$orderby = $filter_orderby;
|
381 |
+
}
|
382 |
+
|
383 |
+
return $orderby;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Returns the post statuses valid for navigation of the post type.
|
388 |
+
*
|
389 |
+
* @since 2.1
|
390 |
+
*
|
391 |
+
* @param string $post_type The post type.
|
392 |
+
* @return array
|
393 |
+
*/
|
394 |
+
public static function get_post_statuses( $post_type ) {
|
395 |
+
return (array) apply_filters( 'c2c_admin_post_navigation_post_statuses', self::$post_statuses, $post_type );
|
396 |
+
}
|
397 |
+
|
398 |
/**
|
399 |
* Returns the previous or next post relative to the current post.
|
400 |
*
|
421 |
|
422 |
$post = get_post( $post_ID );
|
423 |
|
424 |
+
$post_type = esc_sql( get_post_type( $post->ID ) );
|
425 |
+
|
426 |
+
$post_statuses = self::get_post_statuses( $post_type );
|
427 |
+
|
428 |
+
if ( ! $post || ! $post_statuses ) {
|
429 |
return false;
|
430 |
}
|
431 |
|
432 |
+
foreach( $post_statuses as $i => $v ) { $GLOBALS['wpdb']->escape_by_ref( $v ); $post_statuses[ $i ] = $v; }
|
433 |
+
$post_statuses_sql = "'" . implode( "', '", $post_statuses ) . "'";
|
434 |
|
435 |
+
$sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status IN (" . $post_statuses_sql . ') ';
|
436 |
|
437 |
// Determine order.
|
438 |
+
$orderby = self::get_post_type_orderby( $post_type );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
|
440 |
+
$datatype = in_array( $orderby, array( 'comment_count', 'ID', 'menu_order', 'post_parent' ) ) ? '%d' : '%s';
|
441 |
+
$sql .= $wpdb->prepare( "AND {$orderby} {$type} {$datatype} ", $post->$orderby );
|
442 |
|
443 |
$sort = $type == '<' ? 'DESC' : 'ASC';
|
444 |
$sql .= "ORDER BY {$orderby} {$sort} LIMIT {$offset}, {$limit}";
|
assets/admin-post-navigation.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
jQuery(document).ready(function($) {
|
2 |
-
$('#admin-post-nav').appendTo($('#wpbody-content .wrap:first
|
3 |
$('#adminpostnav, label[for="adminpostnav-hide"]').hide();
|
4 |
});
|
1 |
jQuery(document).ready(function($) {
|
2 |
+
$('#admin-post-nav').appendTo($('#wpbody-content .wrap:first h1:first'));
|
3 |
$('#adminpostnav, label[for="adminpostnav-hide"]').hide();
|
4 |
});
|
readme.txt
CHANGED
@@ -4,9 +4,9 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: admin, navigation, post, next, previous, edit, post types, coffee2code
|
5 |
License: GPLv2 or later
|
6 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
7 |
-
Requires at least: 4.
|
8 |
-
Tested up to: 4.
|
9 |
-
Stable tag: 2.
|
10 |
|
11 |
Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
|
12 |
|
@@ -15,18 +15,21 @@ Adds links to navigate to the next and previous posts when editing a post in the
|
|
15 |
|
16 |
This plugin adds "← Previous" and "Next →" links to the "Edit Post" admin page if a previous and next post are present, respectively. The link titles (visible when hovering over the links) reveal the title of the previous/next post. The links link to the "Edit Post" admin page for the previous/next posts so that you may edit them.
|
17 |
|
18 |
-
By default, a previous/next post is determined by the next lower/higher valid post based on
|
19 |
|
20 |
-
|
21 |
|
22 |
-
|
|
|
|
|
23 |
|
24 |
|
25 |
== Installation ==
|
26 |
|
27 |
1. Unzip `admin-post-navigation.zip` inside the `/wp-content/plugins/` directory for your site (or install via the built-in WordPress plugin installer)
|
28 |
-
|
29 |
-
|
|
|
30 |
|
31 |
|
32 |
== Screenshots ==
|
@@ -48,36 +51,39 @@ Yes. See the Filters section for the `c2c_admin_post_navigation_prev_text` and/o
|
|
48 |
|
49 |
== Filters ==
|
50 |
|
51 |
-
The plugin is further customizable via six filters.
|
52 |
|
53 |
= c2c_admin_post_navigation_orderby (filter) =
|
54 |
|
55 |
-
The 'c2c_admin_post_navigation_orderby' filter allows you to change the post field used in the ORDER BY clause for the SQL to find the previous/next post. By default this is '
|
56 |
|
57 |
Arguments:
|
58 |
|
59 |
* $field (string) The current ORDER BY field
|
60 |
* $post_type (string) The post type being navigated
|
|
|
61 |
|
62 |
Example:
|
63 |
|
64 |
`
|
65 |
/**
|
66 |
-
* Modify how Admin Post Navigation orders posts for navigation by
|
67 |
-
* pages by 'menu_order'
|
68 |
*
|
69 |
* @param string $field The field used to order posts for navigation.
|
70 |
* @param string $post_type The post type being navigated.
|
|
|
71 |
* @return string
|
72 |
*/
|
73 |
-
function custom_order_apn( $field, $post_type ) {
|
|
|
74 |
if ( 'page' === $post_type ) {
|
75 |
-
|
76 |
-
} else {
|
77 |
-
return 'post_date';
|
78 |
}
|
|
|
|
|
79 |
}
|
80 |
-
add_filter( 'c2c_admin_post_navigation_orderby', 'custom_order_apn', 10,
|
81 |
`
|
82 |
|
83 |
= c2c_admin_post_navigation_post_statuses (filter) =
|
@@ -87,6 +93,7 @@ The 'c2c_admin_post_navigation_post_statuses' filter allows you to modify the li
|
|
87 |
Arguments:
|
88 |
|
89 |
* $post_statuses (array) The array of valid post_statuses
|
|
|
90 |
|
91 |
Example:
|
92 |
|
@@ -94,25 +101,29 @@ Example:
|
|
94 |
/**
|
95 |
* Modify Admin Post Navigation to allow and disallow certain post statuses from being navigated.
|
96 |
*
|
97 |
-
* @param array
|
|
|
98 |
* @return array
|
99 |
*/
|
100 |
-
function change_apn_post_status( $post_statuses ) {
|
101 |
// Add a post status.
|
102 |
// Note: by default these are already in the $post_statuses array: 'draft', 'future', 'pending', 'private', 'publish'
|
103 |
$post_statuses[] = 'trash';
|
104 |
|
105 |
// Remove post status(es).
|
106 |
$post_statuses_to_remove = array( 'draft' ); // Customize here.
|
|
|
|
|
|
|
107 |
foreach ( $post_statuses_to_remove as $remove ) {
|
108 |
if ( false !== $index = array_search( $remove, $post_statuses ) ) {
|
109 |
unset( $post_statuses[ $index ] );
|
110 |
}
|
111 |
}
|
112 |
|
113 |
-
return $post_statuses;
|
114 |
}
|
115 |
-
add_filter( 'c2c_admin_post_navigation_post_statuses', 'change_apn_post_status' );
|
116 |
`
|
117 |
|
118 |
= c2c_admin_post_navigation_post_types (filter) =
|
@@ -227,6 +238,31 @@ add_filter( 'c2c_admin_post_navigation_display', 'override_apn_display' );
|
|
227 |
|
228 |
== Changelog ==
|
229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
= 2.0 (2016-01-14) =
|
231 |
* New: Add support for RTL display.
|
232 |
* New: Enable post navigation for media when viewed/edited from list mode.
|
@@ -386,6 +422,9 @@ add_filter( 'c2c_admin_post_navigation_display', 'override_apn_display' );
|
|
386 |
|
387 |
== Upgrade Notice ==
|
388 |
|
|
|
|
|
|
|
389 |
= 2.0 =
|
390 |
Recommended update: added RTL support, moved CSS & JS into enqueueable files, enabled navigation for media files, adjustments to utilize language packs, minor unit test tweaks, noted compatibility through WP 4.4+, and updated copyright date
|
391 |
|
4 |
Tags: admin, navigation, post, next, previous, edit, post types, coffee2code
|
5 |
License: GPLv2 or later
|
6 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
7 |
+
Requires at least: 4.7
|
8 |
+
Tested up to: 4.9
|
9 |
+
Stable tag: 2.1
|
10 |
|
11 |
Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
|
12 |
|
15 |
|
16 |
This plugin adds "← Previous" and "Next →" links to the "Edit Post" admin page if a previous and next post are present, respectively. The link titles (visible when hovering over the links) reveal the title of the previous/next post. The links link to the "Edit Post" admin page for the previous/next posts so that you may edit them.
|
17 |
|
18 |
+
By default, a previous/next post is determined by the next lower/higher valid post based on the date the post was created and which is also a post the user can edit. Other post criteria such as post type (draft, pending, etc), publish date, post author, category, etc, are not taken into consideration when determining the previous or next post.
|
19 |
|
20 |
+
Users can customize how post navigation ordering is handled via the "Screen Options" panel available at the top of every page when editing a post. A dropdown presents options to order navigation by: 'ID', 'menu_order', 'post_date', 'post_modified', 'post_name', and 'post_title'. Post navigation can further be customized via filters (see Filters section).
|
21 |
|
22 |
+
NOTE: Be sure to save the post currently being edited (if you've made any changes) before navigating away to the previous/next post!
|
23 |
+
|
24 |
+
Links: [Plugin Homepage](http://coffee2code.com/wp-plugins/admin-post-navigation/) | [Plugin Directory Page](https://wordpress.org/plugins/admin-post-navigation/) | [GitHub](https://github.com/coffe2code/admin-post-navigation/) | [Author Homepage](http://coffee2code.com)
|
25 |
|
26 |
|
27 |
== Installation ==
|
28 |
|
29 |
1. Unzip `admin-post-navigation.zip` inside the `/wp-content/plugins/` directory for your site (or install via the built-in WordPress plugin installer)
|
30 |
+
2. Activate the plugin through the 'Plugins' admin menu in WordPress
|
31 |
+
3. Optional: When editing a post type that supports admin navigation (which are all post types by default), use the "Screen Options" menu to customize how navigation is handled.
|
32 |
+
4. Optional: See documentation for available programmatic customizations
|
33 |
|
34 |
|
35 |
== Screenshots ==
|
51 |
|
52 |
== Filters ==
|
53 |
|
54 |
+
The plugin is further customizable via six filters. Such code should ideally be put into a mu-plugin or site-specific plugin (which is beyond the scope of this readme to explain).
|
55 |
|
56 |
= c2c_admin_post_navigation_orderby (filter) =
|
57 |
|
58 |
+
The 'c2c_admin_post_navigation_orderby' filter allows you to change the post field used in the ORDER BY clause for the SQL to find the previous/next post. By default this is 'post_date' for non-hierarchical post types (such as posts) and 'post_title' for hierarchical post types (such as pages). If you wish to change this, hook this filter. Note: users can customize the post navigation order field for themselves on a per-post type basis via "Screen Options" (see FAQ and screenshot for more info).
|
59 |
|
60 |
Arguments:
|
61 |
|
62 |
* $field (string) The current ORDER BY field
|
63 |
* $post_type (string) The post type being navigated
|
64 |
+
* $user_id (int) The user's ID
|
65 |
|
66 |
Example:
|
67 |
|
68 |
`
|
69 |
/**
|
70 |
+
* Modify how Admin Post Navigation orders posts for navigation by changing the
|
71 |
+
* ordering of pages by 'menu_order'.
|
72 |
*
|
73 |
* @param string $field The field used to order posts for navigation.
|
74 |
* @param string $post_type The post type being navigated.
|
75 |
+
* @param int $user_id. The user's ID.
|
76 |
* @return string
|
77 |
*/
|
78 |
+
function custom_order_apn( $field, $post_type, $user_id ) {
|
79 |
+
// Only change the order for the 'page' post type.
|
80 |
if ( 'page' === $post_type ) {
|
81 |
+
$field = 'menu_order';
|
|
|
|
|
82 |
}
|
83 |
+
|
84 |
+
return $field;
|
85 |
}
|
86 |
+
add_filter( 'c2c_admin_post_navigation_orderby', 'custom_order_apn', 10, 3 );
|
87 |
`
|
88 |
|
89 |
= c2c_admin_post_navigation_post_statuses (filter) =
|
93 |
Arguments:
|
94 |
|
95 |
* $post_statuses (array) The array of valid post_statuses
|
96 |
+
* $post_type (string) The post type
|
97 |
|
98 |
Example:
|
99 |
|
101 |
/**
|
102 |
* Modify Admin Post Navigation to allow and disallow certain post statuses from being navigated.
|
103 |
*
|
104 |
+
* @param array $post_statuses Post statuses permitted for admin navigation.
|
105 |
+
* @param string $post_type The post type.
|
106 |
* @return array
|
107 |
*/
|
108 |
+
function change_apn_post_status( $post_statuses, $post_type ) {
|
109 |
// Add a post status.
|
110 |
// Note: by default these are already in the $post_statuses array: 'draft', 'future', 'pending', 'private', 'publish'
|
111 |
$post_statuses[] = 'trash';
|
112 |
|
113 |
// Remove post status(es).
|
114 |
$post_statuses_to_remove = array( 'draft' ); // Customize here.
|
115 |
+
if ( 'page' === $post_type ) {
|
116 |
+
$post_statuses_to_remove[] = 'pending';
|
117 |
+
}
|
118 |
foreach ( $post_statuses_to_remove as $remove ) {
|
119 |
if ( false !== $index = array_search( $remove, $post_statuses ) ) {
|
120 |
unset( $post_statuses[ $index ] );
|
121 |
}
|
122 |
}
|
123 |
|
124 |
+
return array_values( $post_statuses );
|
125 |
}
|
126 |
+
add_filter( 'c2c_admin_post_navigation_post_statuses', 'change_apn_post_status', 10, 2 );
|
127 |
`
|
128 |
|
129 |
= c2c_admin_post_navigation_post_types (filter) =
|
238 |
|
239 |
== Changelog ==
|
240 |
|
241 |
+
= 2.1 (2017-12-26) =
|
242 |
+
* New: Add ability for users to customize the navigation order via a Screen Options dropdown.
|
243 |
+
* Add optional `$user_id` arg to `get_post_type_orderby()`, and use it, to take into account user preference.
|
244 |
+
* Add `$user_id` arg to 'c2c_admin_post_navigation_orderby' filter.
|
245 |
+
* Add `get_setting_name()` helper function for getting the setting name for the given post type.
|
246 |
+
* Add `screen_settings()` to output the dropdown.
|
247 |
+
* Add `save_screen_settings()` to save user's preference.
|
248 |
+
* Fix: Resolve issue where navigation links failed to appear on posts with an apostrophe in their titles.
|
249 |
+
* New: Add `is_valid_orderby()` helper function to verify a given orderby value is valid.
|
250 |
+
* New: Add `get_post_statuses()` for getting post statuses valid for navigation of a given post type.
|
251 |
+
* New: Abstract logic for determining the orderby for a given post type into `get_post_type_orderby()`.
|
252 |
+
* New: Abstract logic for determining if a post type has admin navigation enabled into `is_post_type_navigable()`.
|
253 |
+
* New: Add README.md.
|
254 |
+
* Change: Use `get_the_title()` instead of `the_title_attribute()` to get post titles.
|
255 |
+
* Change: Discontinue sending `$user_id` arg to 'c2c_admin_post_navigation_post_statuses' filter.
|
256 |
+
* Change: Remove pre-WP 4.3 support for JS relocation of prev/next links.
|
257 |
+
* Change: Use `sprintf()` to format output markup rather than concatenating strings, variables, and function calls.
|
258 |
+
* Change: For unit tests, enable more error output.
|
259 |
+
* Change: For unit tests, default `WP_TESTS_DIR` to `/tmp/wordpress-tests-lib` rather than erroring out if not defined via environment variable.
|
260 |
+
* Change: Add GitHub link to readme.
|
261 |
+
* Change: Note compatibility through WP 4.9+.
|
262 |
+
* Change: Remove support for WordPress older than 4.7 (should still work for earlier versions)
|
263 |
+
* Change: Update copyright date (2018).
|
264 |
+
* Change: Minor whitespace tweaks in unit test bootstrap
|
265 |
+
|
266 |
= 2.0 (2016-01-14) =
|
267 |
* New: Add support for RTL display.
|
268 |
* New: Enable post navigation for media when viewed/edited from list mode.
|
422 |
|
423 |
== Upgrade Notice ==
|
424 |
|
425 |
+
= 2.1 =
|
426 |
+
Recommended update: added screen option for users to customize post navigation order for each post type, fixed bug where navigation didn't appear for posts with apostrophe in title, updated unit test bootstrap file, noted compatibility is now WP 4.7-4.9+, and updated copyright date (2018)
|
427 |
+
|
428 |
= 2.0 =
|
429 |
Recommended update: added RTL support, moved CSS & JS into enqueueable files, enabled navigation for media files, adjustments to utilize language packs, minor unit test tweaks, noted compatibility through WP 4.4+, and updated copyright date
|
430 |
|
tests/bootstrap.php
CHANGED
@@ -1,10 +1,28 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
|
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
function _manually_load_plugin() {
|
6 |
-
require dirname( __FILE__ ) . '
|
7 |
}
|
8 |
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
9 |
|
10 |
-
|
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* PHPUnit bootstrap file
|
4 |
+
*
|
5 |
+
* @package Admin_Post_Navigation
|
6 |
+
*/
|
7 |
|
8 |
+
ini_set( 'display_errors', 'on' );
|
9 |
+
error_reporting( E_ALL );
|
10 |
|
11 |
+
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
12 |
+
if ( ! $_tests_dir ) {
|
13 |
+
$_tests_dir = '/tmp/wordpress-tests-lib';
|
14 |
+
}
|
15 |
+
|
16 |
+
// Give access to tests_add_filter() function.
|
17 |
+
require_once $_tests_dir . '/includes/functions.php';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Manually load the plugin being tested.
|
21 |
+
*/
|
22 |
function _manually_load_plugin() {
|
23 |
+
require dirname( dirname( __FILE__ ) ) . '/admin-post-navigation.php';
|
24 |
}
|
25 |
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
26 |
|
27 |
+
// Start up the WP testing environment.
|
28 |
+
require $_tests_dir . '/includes/bootstrap.php';
|
tests/test-admin-post-navigation.php
CHANGED
@@ -9,7 +9,7 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
9 |
public function setUp() {
|
10 |
parent::setUp();
|
11 |
|
12 |
-
|
13 |
}
|
14 |
|
15 |
public function tearDown() {
|
@@ -20,6 +20,7 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
20 |
|
21 |
remove_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
|
22 |
remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby' ), 10, 2 );
|
|
|
23 |
remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_bad_value' ), 10, 2 );
|
24 |
}
|
25 |
|
@@ -31,6 +32,36 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
31 |
//
|
32 |
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
//
|
36 |
//
|
@@ -74,29 +105,35 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
74 |
return $posts;
|
75 |
}
|
76 |
|
77 |
-
public function c2c_admin_post_navigation_post_statuses( $post_statuses, $post_type
|
78 |
$this->assertTrue( is_array( $post_statuses ) );
|
79 |
-
$this->
|
80 |
-
$this->assertTrue( is_a( $post, 'WP_Post' ) );
|
81 |
|
82 |
// Add a post status.
|
83 |
$post_statuses[] = 'trash';
|
84 |
|
85 |
// Remove post status.
|
86 |
$post_statuses_to_remove = array( 'draft' );
|
|
|
|
|
|
|
87 |
foreach ( $post_statuses_to_remove as $remove ) {
|
88 |
if ( false !== $index = array_search( $remove, $post_statuses ) ) {
|
89 |
unset( $post_statuses[ $index ] );
|
90 |
}
|
91 |
}
|
92 |
|
93 |
-
return $post_statuses;
|
94 |
}
|
95 |
|
96 |
public function c2c_admin_post_navigation_orderby( $orderby, $post_type ) {
|
97 |
return 'post_date';
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
100 |
public function c2c_admin_post_navigation_orderby_bad_value( $orderby, $post_type ) {
|
101 |
return 'gibberish';
|
102 |
}
|
@@ -114,7 +151,7 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
114 |
}
|
115 |
|
116 |
public function test_version() {
|
117 |
-
$this->assertEquals( '2.
|
118 |
}
|
119 |
|
120 |
/*
|
@@ -207,6 +244,92 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
207 |
$this->assertEmpty( $previous_post );
|
208 |
}
|
209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
|
211 |
/*
|
212 |
* Filters.
|
@@ -226,13 +349,13 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
226 |
}
|
227 |
|
228 |
public function test_filter_c2c_admin_post_navigation_post_statuses_when_adding_post_status() {
|
229 |
-
add_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
|
230 |
-
|
231 |
$posts = $this->create_posts();
|
232 |
|
|
|
|
|
233 |
$post = get_post( $posts[3] );
|
234 |
-
$post->
|
235 |
-
|
236 |
|
237 |
$next_post = c2c_AdminPostNavigation::next_post();
|
238 |
|
@@ -240,10 +363,10 @@ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
|
|
240 |
}
|
241 |
|
242 |
public function test_filter_c2c_admin_post_navigation_post_statuses_when_removing_post_status() {
|
243 |
-
add_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
|
244 |
-
|
245 |
$posts = $this->create_posts();
|
246 |
|
|
|
|
|
247 |
$post = get_post( $posts[3] );
|
248 |
$post->post_status = 'draft';
|
249 |
wp_update_post( $post );
|
9 |
public function setUp() {
|
10 |
parent::setUp();
|
11 |
|
12 |
+
do_action( 'load-post.php' );
|
13 |
}
|
14 |
|
15 |
public function tearDown() {
|
20 |
|
21 |
remove_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
|
22 |
remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby' ), 10, 2 );
|
23 |
+
remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_title' ), 10, 2 );
|
24 |
remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_bad_value' ), 10, 2 );
|
25 |
}
|
26 |
|
32 |
//
|
33 |
|
34 |
|
35 |
+
public function valid_orderbys() {
|
36 |
+
return array(
|
37 |
+
array( 'comment_count' ),
|
38 |
+
array( 'ID' ),
|
39 |
+
array( 'menu_order' ),
|
40 |
+
array( 'post_author' ),
|
41 |
+
array( 'post_content' ),
|
42 |
+
array( 'post_content_filtered' ),
|
43 |
+
array( 'post_date' ),
|
44 |
+
array( 'post_excerpt' ),
|
45 |
+
array( 'post_date_gmt' ),
|
46 |
+
array( 'post_mime_type' ),
|
47 |
+
array( 'post_modified' ),
|
48 |
+
array( 'post_modified_gmt' ),
|
49 |
+
array( 'post_name' ),
|
50 |
+
array( 'post_parent' ),
|
51 |
+
array( 'post_status' ),
|
52 |
+
array( 'post_title' ),
|
53 |
+
array( 'post_type' ),
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
public function invalid_orderbys() {
|
58 |
+
return array(
|
59 |
+
array( 'title' ),
|
60 |
+
array( 'id' ),
|
61 |
+
array( 'gibberish' ),
|
62 |
+
);
|
63 |
+
}
|
64 |
+
|
65 |
|
66 |
//
|
67 |
//
|
105 |
return $posts;
|
106 |
}
|
107 |
|
108 |
+
public function c2c_admin_post_navigation_post_statuses( $post_statuses, $post_type ) {
|
109 |
$this->assertTrue( is_array( $post_statuses ) );
|
110 |
+
$this->assertTrue( is_string( $post_type ) );
|
|
|
111 |
|
112 |
// Add a post status.
|
113 |
$post_statuses[] = 'trash';
|
114 |
|
115 |
// Remove post status.
|
116 |
$post_statuses_to_remove = array( 'draft' );
|
117 |
+
if ( 'page' === $post_type ) {
|
118 |
+
$post_statuses_to_remove[] = 'pending';
|
119 |
+
}
|
120 |
foreach ( $post_statuses_to_remove as $remove ) {
|
121 |
if ( false !== $index = array_search( $remove, $post_statuses ) ) {
|
122 |
unset( $post_statuses[ $index ] );
|
123 |
}
|
124 |
}
|
125 |
|
126 |
+
return array_values( $post_statuses );
|
127 |
}
|
128 |
|
129 |
public function c2c_admin_post_navigation_orderby( $orderby, $post_type ) {
|
130 |
return 'post_date';
|
131 |
}
|
132 |
|
133 |
+
public function c2c_admin_post_navigation_orderby_title( $orderby, $post_type ) {
|
134 |
+
return 'post_title';
|
135 |
+
}
|
136 |
+
|
137 |
public function c2c_admin_post_navigation_orderby_bad_value( $orderby, $post_type ) {
|
138 |
return 'gibberish';
|
139 |
}
|
151 |
}
|
152 |
|
153 |
public function test_version() {
|
154 |
+
$this->assertEquals( '2.1', c2c_AdminPostNavigation::version() );
|
155 |
}
|
156 |
|
157 |
/*
|
244 |
$this->assertEmpty( $previous_post );
|
245 |
}
|
246 |
|
247 |
+
public function test_navigate_by_post_title_on_posts_with_quotes_in_title() {
|
248 |
+
add_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_title' ), 10, 2 );
|
249 |
+
|
250 |
+
$posts = $this->create_posts();
|
251 |
+
|
252 |
+
// Change post titles so post ordering by title is 3, 0, 2, 4, 1
|
253 |
+
$new_post_titles = array(
|
254 |
+
"Don't wake the dragon",
|
255 |
+
'A very good post',
|
256 |
+
"Can you 'dig' it?",
|
257 |
+
'Everything must come to an end',
|
258 |
+
'Be a good person',
|
259 |
+
);
|
260 |
+
foreach ( $new_post_titles as $i => $title ) {
|
261 |
+
$post = get_post( $posts[ $i ] );
|
262 |
+
$post->post_title = $title;
|
263 |
+
wp_update_post( $post );
|
264 |
+
}
|
265 |
+
|
266 |
+
$next_post = c2c_AdminPostNavigation::next_post();
|
267 |
+
|
268 |
+
$this->assertEquals( get_post( $posts[0] )->post_title, get_post( $next_post->ID )->post_title );
|
269 |
+
|
270 |
+
$previous_post = c2c_AdminPostNavigation::previous_post();
|
271 |
+
|
272 |
+
$this->assertEquals( get_post( $posts[4] )->post_title, get_post( $previous_post->ID )->post_title );
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
/*
|
277 |
+
* c2c_AdminPostNavigation::is_valid_orderby()
|
278 |
+
*/
|
279 |
+
|
280 |
+
/**
|
281 |
+
* @dataProvider valid_orderbys
|
282 |
+
*/
|
283 |
+
public function test_is_valid_orderby_with_valid( $orderby ) {
|
284 |
+
$this->assertTrue( c2c_AdminPostNavigation::is_valid_orderby( $orderby ) );
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* @dataProvider invalid_orderbys
|
289 |
+
*/
|
290 |
+
public function test_is_valid_orderby_with_invalid( $orderby ) {
|
291 |
+
$this->assertFalse( c2c_AdminPostNavigation::is_valid_orderby( $orderby ) );
|
292 |
+
}
|
293 |
+
|
294 |
+
|
295 |
+
/*
|
296 |
+
* c2c_AdminPostNavigation::get_post_type_orderby()
|
297 |
+
*/
|
298 |
+
|
299 |
+
|
300 |
+
public function test_get_post_type_orderby() {
|
301 |
+
$this->assertEquals( 'post_title', c2c_AdminPostNavigation::get_post_type_orderby( 'page' ) );
|
302 |
+
$this->assertEquals( 'post_date', c2c_AdminPostNavigation::get_post_type_orderby( 'post' ) );
|
303 |
+
}
|
304 |
+
|
305 |
+
public function test_get_post_type_orderby_for_user_with_no_saved_screen_option() {
|
306 |
+
$user_id = $this->create_user( 'administrator' );
|
307 |
+
|
308 |
+
$this->assertEquals( 'post_title', c2c_AdminPostNavigation::get_post_type_orderby( 'page', $user_id ) );
|
309 |
+
$this->assertEquals( 'post_date', c2c_AdminPostNavigation::get_post_type_orderby( 'post', $user_id ) );
|
310 |
+
}
|
311 |
+
|
312 |
+
public function test_get_post_type_orderby_for_user_with_saved_screen_option() {
|
313 |
+
$user_id = $this->create_user( 'administrator' );
|
314 |
+
add_user_meta( $user_id, c2c_AdminPostNavigation::get_setting_name( 'page' ), 'ID', true );
|
315 |
+
|
316 |
+
$this->assertEquals( 'ID', c2c_AdminPostNavigation::get_post_type_orderby( 'page', $user_id ) );
|
317 |
+
// Ensure it doesn't affect value for other post types.
|
318 |
+
$this->assertEquals( 'post_date', c2c_AdminPostNavigation::get_post_type_orderby( 'post', $user_id ) );
|
319 |
+
}
|
320 |
+
|
321 |
+
|
322 |
+
/*
|
323 |
+
* c2c_AdminPostNavigation::get_setting_name()
|
324 |
+
*/
|
325 |
+
|
326 |
+
|
327 |
+
public function test_get_setting_name() {
|
328 |
+
$this->assertEquals( 'c2c_apn_page_orderby', c2c_AdminPostNavigation::get_setting_name( 'page' ) );
|
329 |
+
$this->assertEquals( 'c2c_apn_post_orderby', c2c_AdminPostNavigation::get_setting_name( 'post' ) );
|
330 |
+
$this->assertEquals( 'c2c_apn_book_orderby', c2c_AdminPostNavigation::get_setting_name( 'book' ) );
|
331 |
+
}
|
332 |
+
|
333 |
|
334 |
/*
|
335 |
* Filters.
|
349 |
}
|
350 |
|
351 |
public function test_filter_c2c_admin_post_navigation_post_statuses_when_adding_post_status() {
|
|
|
|
|
352 |
$posts = $this->create_posts();
|
353 |
|
354 |
+
add_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 2 );
|
355 |
+
|
356 |
$post = get_post( $posts[3] );
|
357 |
+
wp_trash_post( $post->ID );
|
358 |
+
$post = get_post( $posts[2] );
|
359 |
|
360 |
$next_post = c2c_AdminPostNavigation::next_post();
|
361 |
|
363 |
}
|
364 |
|
365 |
public function test_filter_c2c_admin_post_navigation_post_statuses_when_removing_post_status() {
|
|
|
|
|
366 |
$posts = $this->create_posts();
|
367 |
|
368 |
+
add_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
|
369 |
+
|
370 |
$post = get_post( $posts[3] );
|
371 |
$post->post_status = 'draft';
|
372 |
wp_update_post( $post );
|