Admin Post Navigation - Version 1.9

Version Description

Feature update: fix to only apply navigation to first h2 on page; added filters to facilitate customizing link text; added unit tests; noted compatibility through WP 4.1+; added plugin icon

Download this release

Release Info

Developer coffee2code
Plugin Icon 128x128 Admin Post Navigation
Version 1.9
Comparing to
See all releases

Code changes from version 1.8 to 1.9

admin-post-navigation.php CHANGED
@@ -1,39 +1,41 @@
1
  <?php
2
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * @package Admin_Post_Navigation
4
- * @author Scott Reilly
5
- * @version 1.8
6
  */
 
7
  /*
8
- Plugin Name: Admin Post Navigation
9
- Version: 1.8
10
- Plugin URI: http://coffee2code.com/wp-plugins/admin-post-navigation/
11
- Author: Scott Reilly
12
- Author URI: http://coffee2code.com/
13
- Text Domain: admin-post-navigation
14
- Domain Path: /lang/
15
- License: GPLv2 or later
16
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
17
- Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
18
-
19
- Compatible with WordPress 3.0 through 3.8+.
20
-
21
- =>> Read the accompanying readme.txt file for instructions and documentation.
22
- =>> Also, visit the plugin's homepage for additional information and updates.
23
- =>> Or visit: http://wordpress.org/plugins/admin-post-navigation/
24
-
25
- TODO:
26
- * Hide screen option checkbox for metabox if metabox is being hidden
27
- * Add screen option allowing user selection of post navigation order
28
- * Add unit tests
29
- * Put CSS into enqueuable .css file
30
- * Put JS into enqueueable .js file
31
- * Add dropdown to post nav links to allow selecting different types of things
32
- to navigate to (e.g. next draft (if looking at a draft), next in category X)
33
- */
34
 
35
  /*
36
- Copyright (c) 2008-2014 by Scott Reilly (aka coffee2code)
37
 
38
  This program is free software; you can redistribute it and/or
39
  modify it under the terms of the GNU General Public License
@@ -52,7 +54,7 @@ TODO:
52
 
53
  defined( 'ABSPATH' ) or die();
54
 
55
- if ( is_admin() && ! class_exists( 'c2c_AdminPostNavigation' ) ) :
56
 
57
  class c2c_AdminPostNavigation {
58
 
@@ -67,7 +69,7 @@ class c2c_AdminPostNavigation {
67
  * @since 1.7
68
  */
69
  public static function version() {
70
- return '1.8';
71
  }
72
 
73
  /**
@@ -81,44 +83,55 @@ class c2c_AdminPostNavigation {
81
  * Filters/actions to hook on the admin post.php page.
82
  *
83
  * @since 1.7
84
- *
85
  */
86
  public static function register_post_page_hooks() {
87
 
88
- // Load textdomain
89
  load_plugin_textdomain( 'admin-post-navigation', false, basename( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' );
90
 
91
- // Set translatable strings
92
- self::$prev_text = __( '&larr; Previous', 'admin-post-navigation' );
93
- self::$next_text = __( 'Next &rarr;', 'admin-post-navigation' );
94
 
95
- // Register hooks
96
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'add_css' ) );
97
  add_action( 'admin_print_footer_scripts', array( __CLASS__, 'add_js' ) );
98
  add_action( 'do_meta_boxes', array( __CLASS__, 'do_meta_box' ), 10, 3 );
99
  }
100
 
101
  /**
102
- * Register meta box
103
  *
104
- * By default, the navigation is present for all post types. Filter
105
  * 'c2c_admin_post_navigation_post_types' to limit its use.
106
  *
107
- * @param string $post_type The post type
108
- * @param string $type The mode for the meta box (normal, advanced, or side)
109
- * @param WP_Post $post The post
110
- * @return void
111
  */
112
  public static function do_meta_box( $post_type, $type, $post ) {
113
  $post_types = apply_filters( 'c2c_admin_post_navigation_post_types', get_post_types() );
114
- if ( ! in_array( $post_type, $post_types ) )
115
  return;
 
116
 
117
- $post_statuses = apply_filters( 'c2c_admin_post_navigation_post_statuses', self::$post_statuses, $post_type, $post );
118
- self::$post_statuses_sql = "'" . implode( "', '", array_map( 'esc_sql', $post_statuses ) ) . "'";
 
 
 
119
  $label = self::_get_post_type_label( $post_type );
120
- if ( in_array( $post->post_status, $post_statuses ) )
121
- add_meta_box( 'adminpostnav', sprintf( __( '%s Navigation', 'admin-post-navigation' ), ucfirst( $post_type ) ), array( __CLASS__, 'add_meta_box' ), $post_type, 'side', 'core' );
 
 
 
 
 
 
 
 
 
122
  }
123
 
124
  /**
@@ -126,17 +139,15 @@ class c2c_AdminPostNavigation {
126
  *
127
  * @param object $object
128
  * @param array $box
129
- * @return void (Text is echoed.)
130
  */
131
  public static function add_meta_box( $object, $box ) {
132
- global $post_ID;
133
  $display = '';
134
 
135
  $context = self::_get_post_type_label( $object->post_type );
136
 
137
  $prev = self::previous_post();
138
  if ( $prev ) {
139
- $post_title = strip_tags( get_the_title( $prev->ID ) ); /* If only the_title_attribute() accepted post ID as arg */
140
  $display .= '<a href="' . get_edit_post_link( $prev->ID ) . '" id="admin-post-nav-prev" title="' .
141
  esc_attr( sprintf( __( 'Previous %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ) .
142
  '" class="admin-post-nav-prev add-new-h2">' . self::$prev_text . '</a>';
@@ -144,9 +155,10 @@ class c2c_AdminPostNavigation {
144
 
145
  $next = self::next_post();
146
  if ( $next ) {
147
- if ( ! empty( $display ) )
148
  $display .= ' ';
149
- $post_title = strip_tags( get_the_title( $next->ID ) ); /* If only the_title_attribute() accepted post ID as arg */
 
150
  $display .= '<a href="' . get_edit_post_link( $next->ID ) .
151
  '" id="admin-post-nav-next" title="' .
152
  esc_attr( sprintf( __( 'Next %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ).
@@ -163,19 +175,21 @@ class c2c_AdminPostNavigation {
163
  *
164
  * @since 1.7
165
  *
166
- * @param string $post_type The post_type
167
- * @return string The label for the post_type
168
  */
169
  public static function _get_post_type_label( $post_type ) {
170
  $label = $post_type;
171
  $post_type_object = get_post_type_object( $label );
172
- if ( is_object( $post_type_object ) )
173
  $label = $post_type_object->labels->singular_name;
 
 
174
  return strtolower( $label );
175
  }
176
 
177
  /**
178
- * Outputs CSS within style tags
179
  */
180
  public static function add_css() {
181
  echo <<<HTML
@@ -201,7 +215,7 @@ HTML;
201
  echo <<<JS
202
  <script type="text/javascript">
203
  jQuery(document).ready(function($) {
204
- $('#admin-post-nav').appendTo($('h2'));
205
  $('#adminpostnav, label[for="adminpostnav-hide"]').hide();
206
  });
207
  </script>
@@ -218,35 +232,50 @@ JS;
218
  * publish date, post author, category, etc, are not taken into
219
  * consideration when determining the previous or next post.
220
  *
221
- * @param string $type (optional) Either '<' or '>', indicating previous or next post, respectively. Default is '<'.
222
- * @param int $offset (optional) Offset. Default is 0.
223
- * @param int $limit (optional) Limit. Default is 15.
224
- * @return string
 
225
  */
226
  public static function query( $type = '<', $offset = 0, $limit = 15 ) {
227
  global $post_ID, $wpdb;
228
 
229
- if ( $type != '<' )
230
  $type = '>';
 
231
  $offset = (int) $offset;
232
  $limit = (int) $limit;
233
 
 
 
 
 
 
 
234
  $post_type = esc_sql( get_post_type( $post_ID ) );
 
235
  $sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status IN (" . self::$post_statuses_sql . ') ';
236
 
237
- // Determine order
238
- if ( function_exists( 'is_post_type_hierarchical' ) && is_post_type_hierarchical( $post_type ) )
239
  $orderby = 'post_title';
240
- else
241
  $orderby = 'ID';
 
 
 
242
  $orderby = esc_sql( apply_filters( 'c2c_admin_post_navigation_orderby', $orderby, $post_type ) );
243
- $post = get_post( $post_ID );
244
- $sql .= "AND $orderby $type '{$post->$orderby}' ";
 
 
 
245
 
246
  $sort = $type == '<' ? 'DESC' : 'ASC';
247
- $sql .= "ORDER BY $orderby $sort LIMIT $offset, $limit";
248
 
249
- // Find the first one the user can actually edit
250
  $posts = $wpdb->get_results( $sql );
251
  $result = false;
252
  if ( $posts ) {
@@ -258,7 +287,7 @@ JS;
258
  }
259
  if ( ! $result ) { // The fetch did not yield a post editable by user, so query again.
260
  $offset += $limit;
261
- // Double the limit each time (if haven't found a post yet, chances are we may not, so try to get through posts quicker)
262
  $limit += $limit;
263
  return self::query( $type, $offset, $limit );
264
  }
1
  <?php
2
  /**
3
+ * Plugin Name: Admin Post Navigation
4
+ * Version: 1.9
5
+ * Plugin URI: http://coffee2code.com/wp-plugins/admin-post-navigation/
6
+ * Author: Scott Reilly
7
+ * Author URI: http://coffee2code.com/
8
+ * Text Domain: admin-post-navigation
9
+ * Domain Path: /lang/
10
+ * License: GPLv2 or later
11
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
+ * Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
13
+ *
14
+ * Compatible with WordPress 3.0 through 4.1+.
15
+ *
16
+ * =>> Read the accompanying readme.txt file for instructions and documentation.
17
+ * =>> Also, visit the plugin's homepage for additional information and updates.
18
+ * =>> Or visit: https://wordpress.org/plugins/admin-post-navigation/
19
+ *
20
  * @package Admin_Post_Navigation
21
+ * @author Scott Reilly
22
+ * @version 1.9
23
  */
24
+
25
  /*
26
+ * TODO:
27
+ * - Drop pre-WP3.6 support and pass post to the_title_attribute() in add_meta_box()
28
+ * - Hide screen option checkbox for metabox if metabox is being hidden
29
+ * - Add screen option allowing user selection of post navigation order
30
+ * - Add more unit tests
31
+ * - Put CSS into enqueuable .css file
32
+ * - Put JS into enqueueable .js file
33
+ * - Add dropdown to post nav links to allow selecting different types of things
34
+ * to navigate to (e.g. next draft (if looking at a draft), next in category X)
35
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  /*
38
+ Copyright (c) 2008-2015 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
54
 
55
  defined( 'ABSPATH' ) or die();
56
 
57
+ if ( ! class_exists( 'c2c_AdminPostNavigation' ) ) :
58
 
59
  class c2c_AdminPostNavigation {
60
 
69
  * @since 1.7
70
  */
71
  public static function version() {
72
+ return '1.9';
73
  }
74
 
75
  /**
83
  * Filters/actions to hook on the admin post.php page.
84
  *
85
  * @since 1.7
 
86
  */
87
  public static function register_post_page_hooks() {
88
 
89
+ // Load textdomain.
90
  load_plugin_textdomain( 'admin-post-navigation', false, basename( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' );
91
 
92
+ // Set translatable strings.
93
+ self::$prev_text = apply_filters( 'c2c_admin_post_navigation_prev_text', __( '&larr; Previous', 'admin-post-navigation' ) );
94
+ self::$next_text = apply_filters( 'c2c_admin_post_navigation_next_text', __( 'Next &rarr;', 'admin-post-navigation' ) );
95
 
96
+ // Register hooks.
97
  add_action( 'admin_enqueue_scripts', array( __CLASS__, 'add_css' ) );
98
  add_action( 'admin_print_footer_scripts', array( __CLASS__, 'add_js' ) );
99
  add_action( 'do_meta_boxes', array( __CLASS__, 'do_meta_box' ), 10, 3 );
100
  }
101
 
102
  /**
103
+ * Register meta box.
104
  *
105
+ * By default, the navigation is present for all post types. Filter
106
  * 'c2c_admin_post_navigation_post_types' to limit its use.
107
  *
108
+ * @param string $post_type The post type.
109
+ * @param string $type The mode for the meta box (normal, advanced, or side).
110
+ * @param WP_Post $post The post.
 
111
  */
112
  public static function do_meta_box( $post_type, $type, $post ) {
113
  $post_types = apply_filters( 'c2c_admin_post_navigation_post_types', get_post_types() );
114
+ if ( ! in_array( $post_type, $post_types ) ) {
115
  return;
116
+ }
117
 
118
+ $post_statuses = (array) apply_filters( 'c2c_admin_post_navigation_post_statuses', self::$post_statuses, $post_type, $post );
119
+ if ( $post_statuses ) {
120
+ foreach( $post_statuses as $i => $v ) { $GLOBALS['wpdb']->escape_by_ref( $v ); $post_statuses[ $i ] = $v; }
121
+ self::$post_statuses_sql = "'" . implode( "', '", $post_statuses ) . "'";
122
+ }
123
  $label = self::_get_post_type_label( $post_type );
124
+
125
+ if ( in_array( $post->post_status, $post_statuses ) ) {
126
+ add_meta_box(
127
+ 'adminpostnav',
128
+ sprintf( __( '%s Navigation', 'admin-post-navigation' ), ucfirst( $post_type ) ),
129
+ array( __CLASS__, 'add_meta_box' ),
130
+ $post_type,
131
+ 'side',
132
+ 'core'
133
+ );
134
+ }
135
  }
136
 
137
  /**
139
  *
140
  * @param object $object
141
  * @param array $box
 
142
  */
143
  public static function add_meta_box( $object, $box ) {
 
144
  $display = '';
145
 
146
  $context = self::_get_post_type_label( $object->post_type );
147
 
148
  $prev = self::previous_post();
149
  if ( $prev ) {
150
+ $post_title = strip_tags( get_the_title( $prev->ID ) ); /* TODO: Drop pre-WP3.6 support and pass post to the_title_attribute() instead */
151
  $display .= '<a href="' . get_edit_post_link( $prev->ID ) . '" id="admin-post-nav-prev" title="' .
152
  esc_attr( sprintf( __( 'Previous %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ) .
153
  '" class="admin-post-nav-prev add-new-h2">' . self::$prev_text . '</a>';
155
 
156
  $next = self::next_post();
157
  if ( $next ) {
158
+ if ( ! empty( $display ) ) {
159
  $display .= ' ';
160
+ }
161
+ $post_title = strip_tags( get_the_title( $next->ID ) ); /* TODO: Drop pre-WP3.6 support and pass post to the_title_attribute() instead */
162
  $display .= '<a href="' . get_edit_post_link( $next->ID ) .
163
  '" id="admin-post-nav-next" title="' .
164
  esc_attr( sprintf( __( 'Next %1$s: %2$s', 'admin-post-navigation' ), $context, $post_title ) ).
175
  *
176
  * @since 1.7
177
  *
178
+ * @param string $post_type The post_type.
179
+ * @return string The label for the post_type.
180
  */
181
  public static function _get_post_type_label( $post_type ) {
182
  $label = $post_type;
183
  $post_type_object = get_post_type_object( $label );
184
+ if ( is_object( $post_type_object ) ) {
185
  $label = $post_type_object->labels->singular_name;
186
+ }
187
+
188
  return strtolower( $label );
189
  }
190
 
191
  /**
192
+ * Outputs CSS within style tags.
193
  */
194
  public static function add_css() {
195
  echo <<<HTML
215
  echo <<<JS
216
  <script type="text/javascript">
217
  jQuery(document).ready(function($) {
218
+ $('#admin-post-nav').appendTo($('h2:first'));
219
  $('#adminpostnav, label[for="adminpostnav-hide"]').hide();
220
  });
221
  </script>
232
  * publish date, post author, category, etc, are not taken into
233
  * consideration when determining the previous or next post.
234
  *
235
+ * @param string $type Optional. Either '<' or '>', indicating previous or next post, respectively. Default '<'.
236
+ * @param int $offset Optional. Offset. Primarily for internal, self-referencial use. Default 0.
237
+ * @param int $limit Optional. Number of posts to get in the query. Not just the next post because a few might
238
+ * need to be traversed to find a post the user has the capability to edit. Default 15.
239
+ * @return WP_Post|false
240
  */
241
  public static function query( $type = '<', $offset = 0, $limit = 15 ) {
242
  global $post_ID, $wpdb;
243
 
244
+ if ( $type != '<' ) {
245
  $type = '>';
246
+ }
247
  $offset = (int) $offset;
248
  $limit = (int) $limit;
249
 
250
+ $post = get_post( $post_ID );
251
+
252
+ if ( ! $post || ! self::$post_statuses_sql ) {
253
+ return false;
254
+ }
255
+
256
  $post_type = esc_sql( get_post_type( $post_ID ) );
257
+
258
  $sql = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status IN (" . self::$post_statuses_sql . ') ';
259
 
260
+ // Determine order.
261
+ if ( function_exists( 'is_post_type_hierarchical' ) && is_post_type_hierarchical( $post_type ) ) {
262
  $orderby = 'post_title';
263
+ } else {
264
  $orderby = 'ID';
265
+ }
266
+ $default_orderby = $orderby;
267
+ // Restrict orderby to actual post fields.
268
  $orderby = esc_sql( apply_filters( 'c2c_admin_post_navigation_orderby', $orderby, $post_type ) );
269
+ 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' ) ) ) {
270
+ $orderby = $default_orderby;
271
+ }
272
+
273
+ $sql .= "AND {$orderby} {$type} '{$post->$orderby}' ";
274
 
275
  $sort = $type == '<' ? 'DESC' : 'ASC';
276
+ $sql .= "ORDER BY {$orderby} {$sort} LIMIT {$offset}, {$limit}";
277
 
278
+ // Find the first post the user can actually edit.
279
  $posts = $wpdb->get_results( $sql );
280
  $result = false;
281
  if ( $posts ) {
287
  }
288
  if ( ! $result ) { // The fetch did not yield a post editable by user, so query again.
289
  $offset += $limit;
290
+ // Double the limit each time (if haven't found a post yet, chances are we may not, so try to get through posts quicker).
291
  $limit += $limit;
292
  return self::query( $type, $offset, $limit );
293
  }
bin/install-wp-tests.sh ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ if [ $# -lt 3 ]; then
4
+ echo "usage: $0 <db-name> <db-user> <db-pass> [wp-version]"
5
+ exit 1
6
+ fi
7
+
8
+ DB_NAME=$1
9
+ DB_USER=$2
10
+ DB_PASS=$3
11
+ WP_VERSION=${4-master}
12
+
13
+ set -ex
14
+
15
+ # set up a WP install
16
+ WP_CORE_DIR=/tmp/wordpress/
17
+ mkdir -p $WP_CORE_DIR
18
+ wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION
19
+ tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
20
+
21
+ # set up testing suite
22
+ svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR
23
+
24
+ cd $WP_TESTS_DIR
25
+ cp wp-tests-config-sample.php wp-tests-config.php
26
+ sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php
27
+ sed -i "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php
28
+ sed -i "s/yourusernamehere/$DB_USER/" wp-tests-config.php
29
+ sed -i "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php
30
+
31
+ # create database
32
+ mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"
lang/admin-post-navigation.pot CHANGED
@@ -1,35 +1,36 @@
1
- # Translation of the WordPress plugin Admin Post Navigation v1.7 by Scott Reilly.
2
- # Copyright (C) 2011 Scott Reilly
3
  # This file is distributed under the same license as the Admin Post Navigation plugin.
4
  msgid ""
5
  msgstr ""
6
- "Project-Id-Version: Admin Post Navigation 1.7\n"
7
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/admin-post-navigation\n"
8
- "POT-Creation-Date: 2011-12-15 22:01:43+00:00\n"
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
 
16
- #: admin-post-navigation.php:75
17
  msgid "&larr; Previous"
18
  msgstr ""
19
 
20
- #: admin-post-navigation.php:76
21
  msgid "Next &rarr;"
22
  msgstr ""
23
 
24
- #: admin-post-navigation.php:103
25
  msgid "%s Navigation"
26
  msgstr ""
27
 
28
- #: admin-post-navigation.php:123
29
  msgid "Previous %1$s: %2$s"
30
  msgstr ""
31
 
32
- #: admin-post-navigation.php:134
33
  msgid "Next %1$s: %2$s"
34
  msgstr ""
35
 
@@ -52,5 +53,5 @@ msgid "Scott Reilly"
52
  msgstr ""
53
 
54
  #. Author URI of the plugin/theme
55
- msgid "http://coffee2code.com"
56
  msgstr ""
1
+ # Translation of the WordPress plugin Admin Post Navigation v1.9 by Scott Reilly.
2
+ # Copyright (C) 2015 Scott Reilly
3
  # This file is distributed under the same license as the Admin Post Navigation plugin.
4
  msgid ""
5
  msgstr ""
6
+ "Project-Id-Version: Admin Post Navigation 1.9\n"
7
+ "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/admin-post-"
8
+ "navigation\n"
9
+ "POT-Creation-Date: 2015-03-14 08:03:14+00:00\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
14
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
15
  "Language-Team: LANGUAGE <LL@li.org>\n"
16
 
17
+ #: admin-post-navigation.php:93
18
  msgid "&larr; Previous"
19
  msgstr ""
20
 
21
+ #: admin-post-navigation.php:94
22
  msgid "Next &rarr;"
23
  msgstr ""
24
 
25
+ #: admin-post-navigation.php:128
26
  msgid "%s Navigation"
27
  msgstr ""
28
 
29
+ #: admin-post-navigation.php:152
30
  msgid "Previous %1$s: %2$s"
31
  msgstr ""
32
 
33
+ #: admin-post-navigation.php:164
34
  msgid "Next %1$s: %2$s"
35
  msgstr ""
36
 
53
  msgstr ""
54
 
55
  #. Author URI of the plugin/theme
56
+ msgid "http://coffee2code.com/"
57
  msgstr ""
phpunit.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="tests/bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite>
11
+ <directory prefix="test-" suffix=".php">./tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ </phpunit>
readme.txt CHANGED
@@ -5,8 +5,8 @@ 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: 3.0
8
- Tested up to: 3.8
9
- Stable tag: 1.8
10
 
11
  Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
12
 
@@ -19,7 +19,7 @@ By default, a previous/next post is determined by the next lower/higher valid po
19
 
20
  NOTE: Be sure to save the post currently being edited before navigating away to the previous/next post.
21
 
22
- Links: [Plugin Homepage](http://coffee2code.com/wp-plugins/admin-post-navigation/) | [Plugin Directory Page](http://wordpress.org/plugins/admin-post-navigation/) | [Author Homepage](http://coffee2code.com)
23
 
24
 
25
  == Installation ==
@@ -41,10 +41,14 @@ Links: [Plugin Homepage](http://coffee2code.com/wp-plugins/admin-post-navigation
41
 
42
  See the Filters section for the `c2c_admin_post_navigation_orderby` filter, which has just such an example.
43
 
 
 
 
 
44
 
45
  == Filters ==
46
 
47
- The plugin is further customizable via four filters. Typically, these customizations would be put into your active theme's functions.php file, or used by another plugin.
48
 
49
  = c2c_admin_post_navigation_orderby (filter) =
50
 
@@ -56,10 +60,18 @@ Arguments:
56
 
57
  Example:
58
 
59
- `add_filter( 'c2c_admin_post_navigation_orderby', 'order_apn_by_post_date' );
 
 
 
 
 
 
60
  function order_apn_by_post_date( $field ) {
61
  return 'post_date';
62
- }`
 
 
63
 
64
  = c2c_admin_post_navigation_post_statuses (filter) =
65
 
@@ -72,12 +84,24 @@ Arguments:
72
  Example:
73
 
74
  `
75
- add_filter( 'c2c_admin_post_navigation_post_statuses', 'change_apn_post_status' );
 
 
 
 
 
76
  function change_apn_post_status( $post_statuses ) {
77
- $post_statuses[] = 'trash'; // Adding a post status
78
- if ( isset( $post_statuses['future'] ) ) unset( $post_statuses['future'] ); // Removing a post status
 
 
 
 
 
 
79
  return $post_statuses;
80
  }
 
81
  `
82
 
83
  = c2c_admin_post_navigation_post_types (filter) =
@@ -91,21 +115,78 @@ Arguments:
91
  Examples:
92
 
93
  `
94
- // Modify Admin Post Navigation to only allow navigating strictly for posts.
95
- add_filter( 'c2c_admin_post_navigation_post_types', 'change_apn_post_types' );
 
 
 
 
96
  function change_apn_post_types( $post_types ) {
97
  return array( 'post' );
98
  }
 
99
  `
100
 
101
  `
102
- // Modify Admin Post Navigation to disallow navigation for the 'recipe' post type
103
- add_filter( 'c2c_admin_post_navigation_post_types', 'remove_recipe_apn_post_types' );
 
 
 
 
104
  function remove_recipe_apn_post_types( $post_types ) {
105
- if ( isset( $post_types['recipe'] ) )
106
  unset( $post_types['recipe'] ); // Removing a post type
 
107
  return $post_types;
108
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  `
110
 
111
  = c2c_admin_post_navigation_display (filter) =
@@ -119,16 +200,41 @@ Arguments:
119
  Example:
120
 
121
  `
122
- add_filter( 'c2c_admin_post_navigation_display', 'override_apn_display' );
 
 
 
 
 
123
  function override_apn_display( $text ) {
124
  // Simplistic example. You could preferably make the text bold using CSS.
125
  return '<strong>' . $text . '</strong>';
126
  }
 
127
  `
128
 
129
 
130
  == Changelog ==
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  = 1.8 (2013-12-29) =
133
  * Hide screen option checkbox for metabox if JS hides metabox for inline use
134
  * Improve spacing within its metabox (when shown if JS is disabled)
@@ -239,6 +345,9 @@ function override_apn_display( $text ) {
239
 
240
  == Upgrade Notice ==
241
 
 
 
 
242
  = 1.8 =
243
  Minor update: hid screen options checkbox when JS is enabled since metabox is hidden; improved metabox spacing; noted compatibility through WP 3.8+
244
 
5
  License: GPLv2 or later
6
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
7
  Requires at least: 3.0
8
+ Tested up to: 4.1
9
+ Stable tag: 1.9
10
 
11
  Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.
12
 
19
 
20
  NOTE: Be sure to save the post currently being edited before navigating away to the previous/next post.
21
 
22
+ Links: [Plugin Homepage](http://coffee2code.com/wp-plugins/admin-post-navigation/) | [Plugin Directory Page](https://wordpress.org/plugins/admin-post-navigation/) | [Author Homepage](http://coffee2code.com)
23
 
24
 
25
  == Installation ==
41
 
42
  See the Filters section for the `c2c_admin_post_navigation_orderby` filter, which has just such an example.
43
 
44
+ = Can I change the link text to something other than "&larr; Previous" and/or "Next &rarr;"? =
45
+
46
+ Yes. See the Filters section for the `c2c_admin_post_navigation_prev_text` and/or `c2c_admin_post_navigation_next_text` filters, which have just such examples. To change or amend the overall markup for the links, look into the `c2c_admin_post_navigation_display` filter.
47
+
48
 
49
  == Filters ==
50
 
51
+ The plugin is further customizable via six filters. Typically, these customizations would be put into your active theme's functions.php file, or used by another plugin.
52
 
53
  = c2c_admin_post_navigation_orderby (filter) =
54
 
60
 
61
  Example:
62
 
63
+ `
64
+ /**
65
+ * Modify how Admin Post Navigation orders posts for navigation.
66
+ *
67
+ * @param string $field The field used to order posts for navigation.
68
+ * @return string
69
+ */
70
  function order_apn_by_post_date( $field ) {
71
  return 'post_date';
72
+ }
73
+ add_filter( 'c2c_admin_post_navigation_orderby', 'order_apn_by_post_date' );
74
+ `
75
 
76
  = c2c_admin_post_navigation_post_statuses (filter) =
77
 
84
  Example:
85
 
86
  `
87
+ /**
88
+ * Modify Admin Post Navigation to allow and disallow certain post statuses from being navigated.
89
+ *
90
+ * @param array $post_statuses Post statuses permitted for admin navigation.
91
+ * @return array
92
+ */
93
  function change_apn_post_status( $post_statuses ) {
94
+ // Adding a post status.
95
+ $post_statuses[] = 'trash';
96
+
97
+ // Removing a post status.
98
+ if ( isset( $post_statuses['future'] ) ) {
99
+ unset( $post_statuses['future'] );
100
+ }
101
+
102
  return $post_statuses;
103
  }
104
+ add_filter( 'c2c_admin_post_navigation_post_statuses', 'change_apn_post_status' );
105
  `
106
 
107
  = c2c_admin_post_navigation_post_types (filter) =
115
  Examples:
116
 
117
  `
118
+ /**
119
+ * Modify Admin Post Navigation to only allow navigating strictly for posts.
120
+ *
121
+ * @param array $post_types Post types that should have admin post navigation.
122
+ * @return array
123
+ */
124
  function change_apn_post_types( $post_types ) {
125
  return array( 'post' );
126
  }
127
+ add_filter( 'c2c_admin_post_navigation_post_types', 'change_apn_post_types' );
128
  `
129
 
130
  `
131
+ /**
132
+ * Modify Admin Post Navigation to disallow navigation for the 'recipe' post type.
133
+ *
134
+ * @param array $post_types Post types that should have admin post navigation.
135
+ * @return array
136
+ */
137
  function remove_recipe_apn_post_types( $post_types ) {
138
+ if ( isset( $post_types['recipe'] ) ) {
139
  unset( $post_types['recipe'] ); // Removing a post type
140
+ }
141
  return $post_types;
142
  }
143
+ add_filter( 'c2c_admin_post_navigation_post_types', 'remove_recipe_apn_post_types' );
144
+ `
145
+
146
+ = c2c_admin_post_navigation_prev_text (filter) =
147
+
148
+ The 'c2c_admin_post_navigation_prev_text' filter allows you to change the link text used for the 'Previous' link. By default this is '&larr; Previous'.
149
+
150
+ Arguments:
151
+
152
+ * $text (string) The 'previous' link text.
153
+
154
+ Example:
155
+
156
+ `
157
+ /**
158
+ * Changes the text for the 'previous' link to 'Older' output by the Admin Post Navigation plugin.
159
+ *
160
+ * @param string $text The text used to indicate the 'next' post.
161
+ * @return string
162
+ */
163
+ function my_c2c_admin_post_navigation_prev_text( $text ) {
164
+ return 'Older';
165
+ }
166
+ add_filter( 'c2c_admin_post_navigation_prev_text', 'my_c2c_admin_post_navigation_prev_text' );
167
+ `
168
+
169
+ = c2c_admin_post_navigation_next_text (filter) =
170
+
171
+ The 'c2c_admin_post_navigation_next_text' filter allows you to change the link text used for the 'Next' link. By default this is 'Next &rarr;'.
172
+
173
+ Arguments:
174
+
175
+ * $text (string) The 'next' link text.
176
+
177
+ Example:
178
+
179
+ `
180
+ /**
181
+ * Changes the text for the 'next' link to 'Newer' output by the Admin Post Navigation plugin.
182
+ *
183
+ * @param string $text The text used to indicate the 'next' post.
184
+ * @return string
185
+ */
186
+ function my_c2c_admin_post_navigation_next_text( $text ) {
187
+ return 'Newer';
188
+ }
189
+ add_filter( 'c2c_admin_post_navigation_next_text', 'my_c2c_admin_post_navigation_next_text' );
190
  `
191
 
192
  = c2c_admin_post_navigation_display (filter) =
200
  Example:
201
 
202
  `
203
+ /**
204
+ * Change the markup displayed by the Admin Post Navigation plugin.
205
+ *
206
+ * @param string $text The text being output by the plugin.
207
+ * @return string
208
+ */
209
  function override_apn_display( $text ) {
210
  // Simplistic example. You could preferably make the text bold using CSS.
211
  return '<strong>' . $text . '</strong>';
212
  }
213
+ add_filter( 'c2c_admin_post_navigation_display', 'override_apn_display' );
214
  `
215
 
216
 
217
  == Changelog ==
218
 
219
+ = 1.9 (2015-03-14) =
220
+ * Fix to only append navigation to the first h2 on the page. props @pomegranate
221
+ * Add filter 'c2c_admin_post_navigation_prev_text' to allow customization of the previous navigation link text. props @pomegranate
222
+ * Add filter 'c2c_admin_post_navigation_next_text' to allow customization of the next navigation link text. props @pomegranate
223
+ * Restrict orderby value to be an actual posts table field
224
+ * Add unit tests
225
+ * Prevent querying for a post if there isn't a global post_ID set or if no valid post_statuses were set
226
+ * Cast result of 'c2c_admin_post_navigation_post_statuses' filter to an array to avoid potential PHP warnings with improper use
227
+ * Improved sanitization of values returned via the 'c2c_admin_post_navigation_post_statuses' filter
228
+ * Add docs for new filters
229
+ * Documentation improvements
230
+ * Reformat plugin header
231
+ * Note compatibility through WP 4.1+
232
+ * Update copyright date (2015)
233
+ * Minor code reformatting (bracing, spacing)
234
+ * Change documentation links to wp.org to be https
235
+ * Add plugin icon
236
+ * Regenerate .pot
237
+
238
  = 1.8 (2013-12-29) =
239
  * Hide screen option checkbox for metabox if JS hides metabox for inline use
240
  * Improve spacing within its metabox (when shown if JS is disabled)
345
 
346
  == Upgrade Notice ==
347
 
348
+ = 1.9 =
349
+ Feature update: fix to only apply navigation to first h2 on page; added filters to facilitate customizing link text; added unit tests; noted compatibility through WP 4.1+; added plugin icon
350
+
351
  = 1.8 =
352
  Minor update: hid screen options checkbox when JS is enabled since metabox is hidden; improved metabox spacing; noted compatibility through WP 3.8+
353
 
tests/bootstrap.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once getenv( 'WP_TESTS_DIR' ) . '/includes/functions.php';
4
+
5
+ function _manually_load_plugin() {
6
+ require dirname( __FILE__ ) . '/../admin-post-navigation.php';
7
+ }
8
+ tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
9
+
10
+ require getenv( 'WP_TESTS_DIR' ) . '/includes/bootstrap.php';
tests/test-admin-post-navigation.php ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Admin_Post_Navigation_Test extends WP_UnitTestCase {
4
+
5
+ function setUp() {
6
+ parent::setUp();
7
+
8
+ c2c_AdminPostNavigation::register_post_page_hooks();
9
+ }
10
+
11
+ function tearDown() {
12
+ parent::tearDown();
13
+
14
+ unset( $GLOBALS['post_ID'] );
15
+ $this->unset_current_user();
16
+
17
+ remove_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
18
+ remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby' ), 10, 2 );
19
+ remove_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_bad_value' ), 10, 2 );
20
+ }
21
+
22
+
23
+ /*
24
+ *
25
+ * DATA PROVIDERS
26
+ *
27
+ */
28
+
29
+
30
+
31
+ /*
32
+ *
33
+ * HELPER FUNCTIONS
34
+ *
35
+ */
36
+
37
+
38
+ private function create_user( $role, $set_as_current = true ) {
39
+ $user_id = $this->factory->user->create( array( 'role' => $role ) );
40
+ if ( $set_as_current ) {
41
+ wp_set_current_user( $user_id );
42
+ }
43
+ return $user_id;
44
+ }
45
+
46
+ // helper function, unsets current user globally. Taken from post.php test.
47
+ private function unset_current_user() {
48
+ global $current_user, $user_ID;
49
+
50
+ $current_user = $user_ID = null;
51
+ }
52
+
53
+ private function create_posts( $number = 5, $current_post_index = 2 ) {
54
+ $user_id = $this->create_user( 'administrator' );
55
+
56
+ $posts = $this->factory->post->create_many( $number, array( 'post_author' => $user_id ) );
57
+
58
+ $GLOBALS['post_ID'] = $posts[ $current_post_index ];
59
+ $current_post = get_post( $posts[ $current_post_index ] );
60
+
61
+ c2c_AdminPostNavigation::do_meta_box( $current_post->post_type, 'normal', $current_post );
62
+
63
+ return $posts;
64
+ }
65
+
66
+ public function c2c_admin_post_navigation_post_statuses( $post_statuses, $post_type, $post ) {
67
+ $this->assertTrue( is_array( $post_statuses ) );
68
+ $this->assertEquals( 'post', $post_type );
69
+ $this->assertTrue( is_a( $post, 'WP_Post' ) );
70
+
71
+ $post_statuses[] = 'trash';
72
+
73
+ return $post_statuses;
74
+ }
75
+
76
+ public function c2c_admin_post_navigation_orderby( $orderby, $post_type ) {
77
+ return 'post_date';
78
+ }
79
+
80
+ public function c2c_admin_post_navigation_orderby_bad_value( $orderby, $post_type ) {
81
+ return 'gibberish';
82
+ }
83
+
84
+
85
+ /*
86
+ *
87
+ * TESTS
88
+ *
89
+ */
90
+
91
+
92
+ function test_class_exists() {
93
+ $this->assertTrue( class_exists( 'c2c_AdminPostNavigation' ) );
94
+ }
95
+
96
+ function test_version() {
97
+ $this->assertEquals( '1.9', c2c_AdminPostNavigation::version() );
98
+ }
99
+
100
+ /*
101
+ * c2c_AdminPostNavigation::next_post()
102
+ */
103
+
104
+ function test_navigate_next_to_post() {
105
+ $posts = $this->create_posts();
106
+
107
+ $next_post = c2c_AdminPostNavigation::next_post();
108
+
109
+ $this->assertEquals( $posts[3], $next_post->ID );
110
+ }
111
+
112
+ function test_navigate_next_at_end() {
113
+ $posts = $this->create_posts( 5, 4 );
114
+
115
+ $next_post = c2c_AdminPostNavigation::next_post();
116
+
117
+ $this->assertEmpty( $next_post );
118
+ }
119
+
120
+ function test_navigate_next_skips_unwhitelisted_post_status() {
121
+ $posts = $this->create_posts();
122
+
123
+ $post = get_post( $posts[3] );
124
+ $post->post_status = 'trash';
125
+ wp_update_post( $post );
126
+
127
+ $next_post = c2c_AdminPostNavigation::next_post();
128
+
129
+ $this->assertEquals( $posts[4], $next_post->ID );
130
+ }
131
+
132
+ function test_navigate_next_when_no_editable_next() {
133
+ $posts = $this->create_posts();
134
+ $user_id = $this->create_user( 'author' );
135
+
136
+ $post = get_post( $posts[2] );
137
+ $post->post_author = $user_id;
138
+ wp_update_post( $post );
139
+
140
+ $next_post = c2c_AdminPostNavigation::next_post();
141
+
142
+ $this->assertEmpty( $next_post );
143
+ }
144
+
145
+ /*
146
+ * c2c_AdminPostNavigation::previous_post()
147
+ */
148
+
149
+ function test_navigate_previous_to_post() {
150
+ $posts = $this->create_posts();
151
+
152
+ $previous_post = c2c_AdminPostNavigation::previous_post();
153
+
154
+ $this->assertEquals( $posts[1], $previous_post->ID );
155
+ }
156
+
157
+ function test_navigate_previous_at_beginning() {
158
+ $posts = $this->create_posts( 5, 0 );
159
+
160
+ $previous_post = c2c_AdminPostNavigation::previous_post();
161
+
162
+ $this->assertEmpty( $previous_post );
163
+ }
164
+
165
+ function test_navigate_previous_skips_unwhitelisted_post_status() {
166
+ $posts = $this->create_posts();
167
+
168
+ $post = get_post( $posts[1] );
169
+ $post->post_status = 'trash';
170
+ wp_update_post( $post );
171
+
172
+ $previous_post = c2c_AdminPostNavigation::previous_post();
173
+
174
+ $this->assertEquals( $posts[0], $previous_post->ID );
175
+ }
176
+
177
+ function test_navigate_previous_when_no_editable_previous() {
178
+ $posts = $this->create_posts();
179
+ $user_id = $this->create_user( 'author' );
180
+
181
+ $post = get_post( $posts[2] );
182
+ $post->post_author = $user_id;
183
+ wp_update_post( $post );
184
+
185
+ $previous_post = c2c_AdminPostNavigation::previous_post();
186
+
187
+ $this->assertEmpty( $previous_post );
188
+ }
189
+
190
+
191
+ /*
192
+ * Filters.
193
+ */
194
+
195
+
196
+ function test_hooks_action_load_post_php() {
197
+ $this->assertEquals( 10, has_action( 'load-post.php', array( 'c2c_AdminPostNavigation', 'register_post_page_hooks' ) ) );
198
+ }
199
+
200
+ function test_hooks_action_admin_enqueue_scripts() {
201
+ $this->assertEquals( 10, has_action( 'admin_enqueue_scripts', array( 'c2c_AdminPostNavigation', 'add_css' ) ) );
202
+ }
203
+
204
+ function test_hooks_action_admin_print_footer_scripts() {
205
+ $this->assertEquals( 10, has_action( 'admin_print_footer_scripts', array( 'c2c_AdminPostNavigation', 'add_js' ) ) );
206
+ }
207
+
208
+ function test_hooks_action_do_meta_boxes() {
209
+ $this->assertEquals( 10, has_action( 'do_meta_boxes', array( 'c2c_AdminPostNavigation', 'do_meta_box' ) ) );
210
+ }
211
+
212
+ function test_filter_c2c_admin_post_navigation_post_statuses() {
213
+ add_filter( 'c2c_admin_post_navigation_post_statuses', array( $this, 'c2c_admin_post_navigation_post_statuses' ), 10, 3 );
214
+
215
+ $posts = $this->create_posts();
216
+
217
+ $post = get_post( $posts[3] );
218
+ $post->post_status = 'trash';
219
+ wp_update_post( $post );
220
+
221
+ $next_post = c2c_AdminPostNavigation::next_post();
222
+
223
+ $this->assertEquals( $posts[3], $next_post->ID );
224
+ }
225
+
226
+ function test_filter_c2c_admin_post_navigation_orderby() {
227
+ add_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby' ), 10, 2 );
228
+
229
+ $posts = $this->create_posts();
230
+
231
+ // Change post dates so post ordering by date is 3, 0, 2, 4, 1
232
+ $new_post_dates = array(
233
+ '2015-06-13 12:30:00',
234
+ '2015-03-13 12:30:00',
235
+ '2015-05-13 12:30:00',
236
+ '2015-07-13 12:30:00',
237
+ '2015-04-13 12:30:00',
238
+ );
239
+ foreach ( $new_post_dates as $i => $date ) {
240
+ $post = get_post( $posts[ $i ] );
241
+ $post->post_date = $date;
242
+ wp_update_post( $post );
243
+ }
244
+
245
+ $next_post = c2c_AdminPostNavigation::next_post();
246
+
247
+ $this->assertEquals( $posts[0], $next_post->ID );
248
+
249
+ $previous_post = c2c_AdminPostNavigation::previous_post();
250
+
251
+ $this->assertEquals( $posts[4], $previous_post->ID );
252
+ }
253
+
254
+ function test_filter_c2c_admin_post_navigation_orderby_with_bad_value() {
255
+ add_filter( 'c2c_admin_post_navigation_orderby', array( $this, 'c2c_admin_post_navigation_orderby_bad_value' ), 10, 2 );
256
+
257
+ // Should function as if never hooked.
258
+ $this->test_navigate_next_to_post();
259
+ $this->test_navigate_previous_to_post();
260
+ }
261
+
262
+ /*
263
+ * TODO tests:
264
+ * - JS is not enqueued on frontend
265
+ * - JS is enqueue on appropriate admin page(s)
266
+ * - JS is not enqueued on inappropriate admin page(s)
267
+ * - CSS is not enqueued on frontend
268
+ * - CSS is enqueue on appropriate admin page(s)
269
+ * - CSS is not enqueued on inappropriate admin page(s)
270
+ */
271
+
272
+ }