Page Links To - Version 2.11.0

Version Description

  • Code cleanup
Download this release

Release Info

Developer markjaquith
Plugin Icon wp plugin Page Links To
Version 2.11.0
Comparing to
See all releases

Code changes from version 2.10.4 to 2.11.0

Files changed (3) hide show
  1. lib/wp-stack-plugin.php +0 -24
  2. page-links-to.php +447 -211
  3. readme.txt +4 -1
lib/wp-stack-plugin.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- // Convenience methods
4
- if ( !class_exists( 'WP_Stack_Plugin' ) ) {
5
- class WP_Stack_Plugin {
6
- public function hook( $hook ) {
7
- $priority = 10;
8
- $method = $this->sanitize_method( $hook );
9
- $args = func_get_args();
10
- unset( $args[0] );
11
- foreach( (array) $args as $arg ) {
12
- if ( is_int( $arg ) )
13
- $priority = $arg;
14
- else
15
- $method = $arg;
16
- }
17
- return add_action( $hook, array( $this, $method ), $priority, 999 );
18
- }
19
-
20
- private function sanitize_method( $method ) {
21
- return str_replace( array( '.', '-' ), array( '_DOT_', '_DASH_' ), $method );
22
- }
23
- }
24
- }
page-links-to.php CHANGED
@@ -1,92 +1,166 @@
1
<?php
2
- /*
3
- Plugin Name: Page Links To
4
- Plugin URI: http://txfx.net/wordpress-plugins/page-links-to/
5
- Description: Allows you to point WordPress pages or posts to a URL of your choosing. Good for setting up navigational links to non-WP sections of your site or to off-site resources.
6
- Version: 2.10.4
7
- Author: Mark Jaquith
8
- Author URI: http://coveredweb.com/
9
- Text Domain: page-links-to
10
- Domain Path: /languages
11
- */
12
13
- /* Copyright 2005-2017 Mark Jaquith
14
15
- This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License as published by
17
- the Free Software Foundation; either version 2 of the License, or
18
- (at your option) any later version.
19
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU General Public License for more details.
24
25
- You should have received a copy of the GNU General Public License
26
- along with this program; if not, write to the Free Software
27
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
*/
29
30
- // Pull in WP Stack plugin library
31
- include( dirname( __FILE__ ) . '/lib/wp-stack-plugin.php' );
32
-
33
- class CWS_PageLinksTo extends WP_Stack_Plugin {
34
static $instance;
35
const LINKS_CACHE_KEY = 'plt_cache__links';
36
const TARGETS_CACHE_KEY = 'plt_cache__targets';
37
const LINK_META_KEY = '_links_to';
38
const TARGET_META_KEY = '_links_to_target';
39
const VERSION_KEY = 'txfx_plt_schema_version';
40
const FILE = __FILE__;
41
- const CSS_JS_VERSION = '2.10.4';
42
43
protected $replace = true;
44
45
function __construct() {
46
self::$instance = $this;
47
$this->hook( 'init' );
48
}
49
50
/**
51
* Bootstraps the upgrade process and registers all the hooks.
52
*/
53
function init() {
54
- // Check to see if any of our data needs to be upgraded
55
$this->maybe_upgrade();
56
57
- // Load translation files
58
load_plugin_textdomain( 'page-links-to', false, basename( dirname( self::FILE ) ) . '/languages' );
59
60
- // Register hooks
61
$this->register_hooks();
62
}
63
64
/**
65
- * Registers all the hooks
66
*/
67
function register_hooks() {
68
- // Hook in to URL generation
69
$this->hook( 'page_link', 'link', 20 );
70
$this->hook( 'post_link', 'link', 20 );
71
$this->hook( 'post_type_link', 'link', 20 );
72
$this->hook( 'attachment_link', 'link', 20 );
73
74
- // Non-standard priority hooks
75
$this->hook( 'do_meta_boxes', 20 );
76
$this->hook( 'wp_enqueue_scripts' );
77
78
- // Non-standard callback hooks
79
- $this->hook( 'load-post.php', 'load_post' );
80
81
- // Standard hooks
82
- $this->hook( 'wp_list_pages' );
83
- $this->hook( 'template_redirect' );
84
- $this->hook( 'save_post' );
85
- $this->hook( 'edit_attachment' );
86
$this->hook( 'wp_nav_menu_objects' );
87
- $this->hook( 'plugin_row_meta' );
88
89
- // Metadata validation grants users editing privileges for our custom fields
90
register_meta( 'post', self::LINK_META_KEY, null, '__return_true' );
91
register_meta( 'post', self::TARGET_META_KEY, null, '__return_true' );
92
}
@@ -104,138 +178,173 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
104
$total_affected = 0;
105
foreach ( array( '', '_target', '_type' ) as $meta_key ) {
106
$meta_key = 'links_to' . $meta_key;
107
- $affected = $wpdb->update( $wpdb->postmeta, array( 'meta_key' => '_' . $meta_key ), compact( 'meta_key' ) );
108
if ( $affected ) {
109
$total_affected += $affected;
110
}
111
}
112
- // Only flush the cache if something changed
113
if ( $total_affected > 0 ) {
114
wp_cache_flush();
115
}
116
if ( update_option( self::VERSION_KEY, 3 ) ) {
117
- $this->flush_links_cache();
118
- $this->flush_targets_cache();
119
}
120
}
121
}
122
123
/**
124
- * Enqueues front end scripts
125
*/
126
function wp_enqueue_scripts() {
127
- wp_enqueue_script( 'page-links-to', $this->get_url() . 'js/new-tab.min.js', array(), self::CSS_JS_VERSION, true );
128
}
129
130
/**
131
- * Returns post ids and meta values that have a given key
132
*
133
- * @param string $key post meta key
134
- * @return array|false objects with post_id and meta_value properties
135
*/
136
- function meta_by_key( $key ) {
137
global $wpdb;
138
return $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $key ) );
139
}
140
141
/**
142
- * Returns a single piece of post meta
143
- * @param integer $post_id a post ID
144
- * @param string $key a post meta key
145
- * @return string|false the post meta, or false, if it doesn't exist
146
*/
147
- function get_post_meta( $post_id, $key ) {
148
$meta = get_post_meta( absint( $post_id ), $key, true );
149
if ( '' === $meta ) {
150
return false;
151
}
152
return $meta;
153
}
154
155
/**
156
- * Returns all links for the current site
157
*
158
- * @return array an array of links, keyed by post ID
159
*/
160
- function get_links() {
161
- if ( false === $links = get_transient( self::LINKS_CACHE_KEY ) ) {
162
- $db_links = $this->meta_by_key( self::LINK_META_KEY );
163
$links = array();
164
if ( $db_links ) {
165
foreach ( $db_links as $link ) {
166
$links[ intval( $link->post_id ) ] = $link->meta_value;
167
}
168
}
169
set_transient( self::LINKS_CACHE_KEY, $links, 10 * 60 );
170
}
171
return $links;
172
}
173
174
/**
175
- * Returns the link for the specified post ID
176
*
177
- * @param integer $post_id a post ID
178
- * @return mixed either a URL or false
179
*/
180
- function get_link( $post_id ) {
181
- return $this->get_post_meta( $post_id, self::LINK_META_KEY );
182
}
183
184
/**
185
- * Returns all targets for the current site
186
*
187
- * @return array an array of targets, keyed by post ID
188
*/
189
- function get_targets() {
190
- if ( false === $targets = get_transient( self::TARGETS_CACHE_KEY ) ) {
191
- $db_targets = $this->meta_by_key( self::TARGET_META_KEY );
192
$targets = array();
193
if ( $db_targets ) {
194
foreach ( $db_targets as $target ) {
195
$targets[ intval( $target->post_id ) ] = true;
196
}
197
}
198
set_transient( self::TARGETS_CACHE_KEY, $targets, 10 * 60 );
199
}
200
return $targets;
201
}
202
203
/**
204
- * Returns the _blank target status for the specified post ID
205
*
206
- * @param integer $post_id a post ID
207
- * @return bool whether it should open in a new tab
208
*/
209
- function get_target( $post_id ) {
210
- return (bool) $this->get_post_meta( $post_id, self::TARGET_META_KEY );
211
}
212
213
/**
214
- * Adds the meta box to the post or page edit screen
215
*
216
- * @param string $page the name of the current page
217
- * @param string $context the current context
218
*/
219
- function do_meta_boxes( $page, $context ) {
220
- // Plugins that use custom post types can use this filter to hide the
221
- // PLT UI in their post type.
222
- $plt_post_types = apply_filters( 'page-links-to-post-types', array_keys( get_post_types( array('show_ui' => true ) ) ) );
223
-
224
- if ( in_array( $page, $plt_post_types ) && 'advanced' === $context ) {
225
- add_meta_box( 'page-links-to', _x( 'Page Links To', 'Meta box title', 'page-links-to'), array( $this, 'meta_box' ), $page, 'advanced', 'low' );
226
}
227
}
228
229
/**
230
- * Outputs the Page Links To post screen meta box
231
*/
232
- function meta_box() {
233
$null = null;
234
$post = get_post( $null );
235
echo '<p>';
236
wp_nonce_field( 'cws_plt_' . $post->ID, '_cws_plt_nonce', false, true );
237
echo '</p>';
238
- $url = $this->get_link( $post->ID );
239
if ( ! $url ) {
240
$linked = false;
241
$url = '';
@@ -243,120 +352,154 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
243
$linked = true;
244
}
245
?>
246
<p><?php _e( 'Point this content to:', 'page-links-to' ); ?></p>
247
- <p><label><input type="radio" id="cws-links-to-choose-wp" name="cws_links_to_choice" value="wp" <?php checked( !$linked ); ?> /> <?php _e( 'Its normal WordPress URL', 'page-links-to' ); ?></label></p>
248
<p><label><input type="radio" id="cws-links-to-choose-custom" name="cws_links_to_choice" value="custom" <?php checked( $linked ); ?> /> <?php _e( 'A custom URL', 'page-links-to' ); ?></label></p>
249
- <div style="webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin-left: 30px;" id="cws-links-to-custom-section" class="<?php echo ! $linked ? 'hide-if-js' : ''; ?>">
250
- <p><input placeholder="http://" name="cws_links_to" type="text" style="width:75%" id="cws-links-to" value="<?php echo esc_attr( $url ); ?>" /></p>
251
- <p><label for="cws-links-to-new-tab"><input type="checkbox" name="cws_links_to_new_tab" id="cws-links-to-new-tab" value="_blank" <?php checked( (bool) $this->get_target( $post->ID ) ); ?>> <?php _e( 'Open this link in a new tab', 'page-links-to' ); ?></label></p>
252
</div>
253
- <script src="<?php echo $this->get_url() . 'js/page-links-to.min.js?v=' . self::CSS_JS_VERSION; ?>"></script>
254
<?php
255
}
256
257
/**
258
- * Saves data on attachment save
259
*
260
- * @param int $post_id
261
- * @return int the attachment post ID that was passed in
262
*/
263
function edit_attachment( $post_id ) {
264
return $this->save_post( $post_id );
265
}
266
267
/**
268
- * Saves data on post save
269
*
270
- * @param int $post_id a post ID
271
- * @return int the post ID that was passed in
272
*/
273
- function save_post( $post_id ) {
274
if ( isset( $_REQUEST['_cws_plt_nonce'] ) && wp_verify_nonce( $_REQUEST['_cws_plt_nonce'], 'cws_plt_' . $post_id ) ) {
275
if ( ( ! isset( $_POST['cws_links_to_choice'] ) || 'custom' == $_POST['cws_links_to_choice'] ) && isset( $_POST['cws_links_to'] ) && strlen( $_POST['cws_links_to'] ) > 0 && $_POST['cws_links_to'] !== 'http://' ) {
276
- $url = $this->clean_url( stripslashes( $_POST['cws_links_to'] ) );
277
- $this->flush_links_if( $this->set_link( $post_id, $url ) );
278
- if ( isset( $_POST['cws_links_to_new_tab'] ) )
279
- $this->flush_targets_if( $this->set_link_new_tab( $post_id ) );
280
- else
281
- $this->flush_targets_if( $this->set_link_same_tab( $post_id ) );
282
} else {
283
- $this->flush_links_if( $this->delete_link( $post_id ) );
284
}
285
}
286
return $post_id;
287
}
288
289
/**
290
- * Cleans up a URL
291
*
292
- * @param string $url URL
293
- * @return string cleaned up URL
294
*/
295
- function clean_url( $url ) {
296
$url = trim( $url );
297
// Starts with 'www.'. Probably a mistake. So add 'http://'.
298
if ( 0 === strpos( $url, 'www.' ) ) {
299
$url = 'http://' . $url;
300
}
301
return $url;
302
}
303
304
/**
305
- * Have a post point to a custom URL
306
*
307
- * @param int $post_id post ID
308
- * @param string $url the URL to point the post to
309
- * @return bool whether anything changed
310
*/
311
- function set_link( $post_id, $url ) {
312
- return $this->flush_links_if( (bool) update_post_meta( $post_id, self::LINK_META_KEY, $url ) );
313
}
314
315
/**
316
- * Tell an custom URL post to open in a new tab
317
*
318
- * @param int $post_id post ID
319
- * @return bool whether anything changed
320
*/
321
- function set_link_new_tab( $post_id ) {
322
- return $this->flush_targets_if( (bool) update_post_meta( $post_id, self::TARGET_META_KEY, '_blank' ) );
323
}
324
325
/**
326
- * Tell an custom URL post to open in the same tab
327
*
328
- * @param int $post_id post ID
329
- * @return bool whether anything changed
330
*/
331
- function set_link_same_tab( $post_id ) {
332
- return $this->flush_targets_if( delete_post_meta( $post_id, self::TARGET_META_KEY ) );
333
}
334
335
/**
336
- * Discard a custom URL and point a post to its normal URL
337
*
338
- * @param int $post_id post ID
339
- * @return bool whether the link was deleted
340
*/
341
- function delete_link( $post_id ) {
342
- $return = $this->flush_links_if( delete_post_meta( $post_id, self::LINK_META_KEY ) );
343
- $this->flush_targets_if( delete_post_meta( $post_id, self::TARGET_META_KEY ) );
344
345
- // Old, unused data that we can delete on the fly
346
delete_post_meta( $post_id, '_links_to_type' );
347
348
return $return;
349
}
350
351
/**
352
- * Flushes the links transient cache if the condition is true
353
*
354
- * @param bool $condition whether to proceed with the flush
355
- * @return bool whether the flush happened
356
*/
357
- function flush_links_if( $condition ) {
358
if ( $condition ) {
359
- $this->flush_links_cache();
360
return true;
361
} else {
362
return false;
@@ -364,14 +507,14 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
364
}
365
366
/**
367
- * Flushes the targets transient cache if the condition is true
368
*
369
- * @param bool $condition whether to proceed with the flush
370
- * @return bool whether the flush happened
371
*/
372
- function flush_targets_if( $condition ) {
373
if ( $condition ) {
374
- $this->flush_targets_cache();
375
return true;
376
} else {
377
return false;
@@ -379,43 +522,39 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
379
}
380
381
/**
382
- * Flushes the links transient cache
383
*
384
- * @param bool $condition whether to flush the cache
385
- * @param string $type which cache to flush
386
- * @return bool whether the flush attempt occurred
387
*/
388
- function flush_links_cache() {
389
- delete_transient( self::LINKS_CACHE_KEY );
390
}
391
392
/**
393
- * Flushes the targets transient cache
394
*
395
- * @param bool $condition whether to flush the cache
396
- * @param string $type which cache to flush
397
- * @return bool whether the flush attempt occurred
398
*/
399
- function flush_targets_cache() {
400
- delete_transient( self::TARGETS_CACHE_KEY );
401
}
402
403
/**
404
- * Filter for Post links
405
*
406
- * @param string $link the URL for the post or page
407
- * @param int|WP_Post $post post ID or object
408
- * @return string output URL
409
*/
410
- function link( $link, $post ) {
411
if ( $this->replace ) {
412
$post = get_post( $post );
413
414
- $meta_link = $this->get_link( $post->ID );
415
416
if ( $meta_link ) {
417
$link = esc_url( $meta_link );
418
- if ( ! is_admin() && $this->get_target( $post->ID ) ) {
419
$link .= '#new_tab';
420
}
421
}
@@ -439,10 +578,12 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
439
}
440
441
/**
442
- * Performs a redirect
443
*/
444
function template_redirect() {
445
- $link = $this->get_redirect();
446
447
if ( $link ) {
448
wp_redirect( $link, 301 );
@@ -451,25 +592,25 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
451
}
452
453
/**
454
- * gets the redirection URL
455
*
456
- * @return string|bool the redirection URL, or false
457
*/
458
- function get_redirect() {
459
if ( ! is_singular() || ! get_queried_object_id() ) {
460
return false;
461
}
462
463
- $link = $this->get_link( get_queried_object_id() );
464
465
- // Convert server- and protocol-relative URLs to absolute URLs
466
- if ( "/" === $link[0] ) {
467
- // Protocol-relative
468
- if ( "/" === $link[1] ) {
469
$link = set_url_scheme( 'http:' . $link );
470
} else {
471
- // Host-relative
472
- $link = set_url_scheme( 'http://' . $_SERVER["HTTP_HOST"] . $link );
473
}
474
}
475
@@ -481,20 +622,22 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
481
}
482
483
/**
484
- * Filters the list of pages to alter the links and targets
485
*
486
- * @param string $pages the wp_list_pages() HTML block from WordPress
487
- * @return string the modified HTML block
488
*/
489
function wp_list_pages( $pages ) {
490
$highlight = false;
491
492
- // We use the "fetch all" versions here, because the pages might not be queried here
493
- $links = $this->get_links();
494
- $targets = $this->get_targets();
495
$targets_by_url = array();
496
- foreach( array_keys( $targets ) as $targeted_id )
497
- $targets_by_url[$links[$targeted_id]] = true;
498
499
if ( ! $links ) {
500
return $pages;
@@ -503,9 +646,10 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
503
$this_url = ( is_ssl() ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
504
505
foreach ( (array) $links as $id => $page ) {
506
- if ( isset( $targets_by_url[$page] ) ) {
507
$page .= '#new_tab';
508
}
509
if ( str_replace( 'http://www.', 'http://', $this_url ) === str_replace( 'http://www.', 'http://', $page ) || ( is_home() && str_replace( 'http://www.', 'http://', trailingslashit( get_bloginfo( 'url' ) ) ) === str_replace( 'http://www.', 'http://', trailingslashit( $page ) ) ) ) {
510
$highlight = true;
511
$current_page = esc_url( $page );
@@ -520,53 +664,145 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
520
}
521
522
if ( $highlight ) {
523
- $pages = preg_replace( '| class="([^"]+)current_page_item"|', ' class="$1"', $pages ); // Kill default highlighting
524
$pages = preg_replace( '|<li class="([^"]+)"><a href="' . preg_quote( $current_page ) . '"|', '<li class="$1 current_page_item"><a href="' . $current_page . '"', $pages );
525
}
526
return $pages;
527
}
528
529
/**
530
- * Filters nav menu objects and adds target=_blank to the ones that need it
531
*
532
- * @param array $items nav menu items
533
- * @return array modified nav menu items
534
*/
535
- function wp_nav_menu_objects( $items ) {
536
$new_items = array();
537
foreach ( $items as $item ) {
538
- if ( isset( $item->object_id ) && $this->get_target( $item->object_id ) ) {
539
$item->target = '_blank';
540
}
541
$new_items[] = $item;
542
}
543
return $new_items;
544
}
545
546
/**
547
- * Hooks in as a post is being loaded for editing and conditionally adds a notice
548
*/
549
- function load_post() {
550
- if ( isset( $_GET['post'] ) && $this->get_link( (int) $_GET['post'] ) ) {
551
$this->hook( 'admin_notices', 'notify_of_external_link' );
552
}
553
}
554
555
/**
556
- * Outputs a notice that the current post item is pointed to a custom URL
557
*/
558
- function notify_of_external_link() {
559
- ?><div class="updated"><p><?php _e( '<strong>Note</strong>: This content is pointing to a custom URL. Use the &#8220;Page Links To&#8221; box to change this behavior.', 'page-links-to' ); ?></p></div><?php
560
}
561
562
/**
563
- * Adds a GitHub link to the plugin meta
564
*
565
- * @param array $links the current array of links
566
- * @param string $file the current plugin being processed
567
- * @return array the modified array of links
568
*/
569
- function plugin_row_meta( $links, $file ) {
570
if ( $file === plugin_basename( self::FILE ) ) {
571
return array_merge(
572
$links,
@@ -578,25 +814,25 @@ class CWS_PageLinksTo extends WP_Stack_Plugin {
578
}
579
580
/**
581
- * Returns the URL of this plugin's directory
582
*
583
- * @return string this plugin's directory URL
584
*/
585
- public function get_url() {
586
return plugin_dir_url( self::FILE );
587
}
588
589
/**
590
- * Returns the filesystem path of this plugin's directory
591
*
592
- * @return string this plugin's directory filesystem path
593
*/
594
- public function get_path() {
595
return plugin_dir_path( self::FILE );
596
}
597
}
598
599
- // Bootstrap everything
600
new CWS_PageLinksTo;
601
602
/**
@@ -606,5 +842,5 @@ new CWS_PageLinksTo;
606
* @return string The post's original URL.
607
*/
608
function plt_get_original_permalink( $post = null ) {
609
- return CWS_PageLinksTo::$instance->original_link( $post );
610
}
1
<?php
2
+ /**
3
+ * The Page Links To plugin class.
4
+ *
5
+ * @package PageLinks
6
+ *
7
+ * Plugin Name: Page Links To
8
+ * Plugin URI: http://txfx.net/wordpress-plugins/page-links-to/
9
+ * Description: Allows you to point WordPress pages or posts to a URL of your choosing. Good for setting up navigational links to non-WP sections of your site or to off-site resources.
10
+ * Version: 2.11.0
11
+ * Author: Mark Jaquith
12
+ * Author URI: https://coveredweb.com/
13
+ * Text Domain: page-links-to
14
+ * Domain Path: /languages
15
+ */
16
17
+ /*
18
+ Copyright 2005-2018 Mark Jaquith
19
20
+ This program is free software; you can redistribute it and/or modify
21
+ it under the terms of the GNU General Public License as published by
22
+ the Free Software Foundation; either version 2 of the License, or
23
+ (at your option) any later version.
24
25
+ This program is distributed in the hope that it will be useful,
26
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ GNU General Public License for more details.
29
30
+ You should have received a copy of the GNU General Public License
31
+ along with this program; if not, write to the Free Software
32
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
*/
34
35
+ /**
36
+ * The Page Links To class.
37
+ */
38
+ class CWS_PageLinksTo {
39
+ /**
40
+ * The class instance.
41
+ *
42
+ * @var CWS_PageLinksTo
43
+ */
44
static $instance;
45
+
46
const LINKS_CACHE_KEY = 'plt_cache__links';
47
const TARGETS_CACHE_KEY = 'plt_cache__targets';
48
const LINK_META_KEY = '_links_to';
49
const TARGET_META_KEY = '_links_to_target';
50
const VERSION_KEY = 'txfx_plt_schema_version';
51
+ const DISMISSED_NOTICES = 'page_links_dismissed_options';
52
+ const MESSAGE_ID = 3;
53
+ const SURVEY_URL = 'https://goo.gl/forms/8sTKH0LjPCCqBlrG2';
54
const FILE = __FILE__;
55
+ const CSS_JS_VERSION = '2.11.0';
56
57
+ /**
58
+ * Whether to replace WP links with their specified URLs.
59
+ *
60
+ * @var bool
61
+ */
62
protected $replace = true;
63
64
+ /**
65
+ * Class constructor. Adds init hook.
66
+ */
67
function __construct() {
68
self::$instance = $this;
69
$this->hook( 'init' );
70
}
71
72
+ /**
73
+ * Get the plugin instance.
74
+ *
75
+ * @return CWS_PageLinksTo The plugin class instance.
76
+ */
77
+ public static function get_instance() {
78
+ if ( ! self::$instance ) {
79
+ self::$instance = $this;
80
+ }
81
+
82
+ return self::$instance;
83
+ }
84
+
85
+ /**
86
+ * Add a WordPress hook (action/filter).
87
+ *
88
+ * @param mixed $hook first parameter is the name of the hook. If second or third parameters are included, they will be used as a priority (if an integer) or as a class method callback name (if a string).
89
+ */
90
+ public function hook( $hook ) {
91
+ $priority = 10;
92
+ $method = self::sanitize_method( $hook );
93
+ $args = func_get_args();
94
+ unset( $args[0] );
95
+ foreach ( (array) $args as $arg ) {
96
+ if ( is_int( $arg ) ) {
97
+ $priority = $arg;
98
+ } else {
99
+ $method = $arg;
100
+ }
101
+ }
102
+
103
+ return add_action( $hook, [ $this, $method ], $priority, 999 );
104
+ }
105
+
106
+ /**
107
+ * Sanitizes method names with bad characters.
108
+ *
109
+ * @param string $method The raw method name.
110
+ * @return string The sanitized method name.
111
+ */
112
+ private static function sanitize_method( $method ) {
113
+ return str_replace( [ '.', '-' ], [ '_DOT_', '_DASH_' ], $method );
114
+ }
115
+
116
/**
117
* Bootstraps the upgrade process and registers all the hooks.
118
*/
119
function init() {
120
+ // Check to see if any of our data needs to be upgraded.
121
$this->maybe_upgrade();
122
123
+ // Load translation files.
124
load_plugin_textdomain( 'page-links-to', false, basename( dirname( self::FILE ) ) . '/languages' );
125
126
+ // Register hooks.
127
$this->register_hooks();
128
}
129
130
/**
131
+ * Registers all the hooks.
132
+ *
133
+ * @return void
134
*/
135
function register_hooks() {
136
+ // Hook in to URL generation.
137
$this->hook( 'page_link', 'link', 20 );
138
$this->hook( 'post_link', 'link', 20 );
139
$this->hook( 'post_type_link', 'link', 20 );
140
$this->hook( 'attachment_link', 'link', 20 );
141
142
+ // Non-standard priority hooks.
143
$this->hook( 'do_meta_boxes', 20 );
144
$this->hook( 'wp_enqueue_scripts' );
145
146
+ // Non-standard callback hooks.
147
+ $this->hook( 'load-post.php', 'load_post' );
148
+ $this->hook( 'wp_ajax_plt_dismiss_notice', 'ajax_dismiss_notice' );
149
150
+ // Standard hooks.
151
+ $this->hook( 'wp_list_pages' );
152
+ $this->hook( 'template_redirect' );
153
+ $this->hook( 'save_post' );
154
+ $this->hook( 'edit_attachment' );
155
$this->hook( 'wp_nav_menu_objects' );
156
+ $this->hook( 'plugin_row_meta' );
157
+
158
+ // Notices.
159
+ if ( self::should_display_message() ) {
160
+ $this->hook( 'admin_notices', 'notify_generic' );
161
+ }
162
163
+ // Metadata validation grants users editing privileges for our custom fields.
164
register_meta( 'post', self::LINK_META_KEY, null, '__return_true' );
165
register_meta( 'post', self::TARGET_META_KEY, null, '__return_true' );
166
}
178
$total_affected = 0;
179
foreach ( array( '', '_target', '_type' ) as $meta_key ) {
180
$meta_key = 'links_to' . $meta_key;
181
+ $affected = $wpdb->update( $wpdb->postmeta, array(
182
+ 'meta_key' => '_' . $meta_key,
183
+ ), compact( 'meta_key' ) );
184
if ( $affected ) {
185
$total_affected += $affected;
186
}
187
}
188
+ // Only flush the cache if something changed.
189
if ( $total_affected > 0 ) {
190
wp_cache_flush();
191
}
192
if ( update_option( self::VERSION_KEY, 3 ) ) {
193
+ self::flush_links_cache();
194
+ self::flush_targets_cache();
195
}
196
}
197
}
198
199
/**
200
+ * Enqueues frontend scripts.
201
*/
202
function wp_enqueue_scripts() {
203
+ wp_enqueue_script( 'page-links-to', self::get_url() . 'js/new-tab.min.js', array(), self::CSS_JS_VERSION, true );
204
}
205
206
/**
207
+ * Returns post ids and meta values that have a given key.
208
*
209
+ * @param string $key post meta key.
210
+ * @return array|false objects with post_id and meta_value properties.
211
*/
212
+ public static function meta_by_key( $key ) {
213
global $wpdb;
214
+
215
return $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $key ) );
216
}
217
218
/**
219
+ * Returns a single piece of post meta.
220
+ *
221
+ * @param integer $post_id a post ID.
222
+ * @param string $key a post meta key.
223
+ * @return string|false the post meta, or false, if it doesn't exist.
224
*/
225
+ public static function get_post_meta( $post_id, $key ) {
226
$meta = get_post_meta( absint( $post_id ), $key, true );
227
+
228
if ( '' === $meta ) {
229
return false;
230
}
231
+
232
return $meta;
233
}
234
235
/**
236
+ * Returns all links for the current site.
237
*
238
+ * @return array an array of links, keyed by post ID.
239
*/
240
+ public static function get_links() {
241
+ $links = get_transient( self::LINKS_CACHE_KEY );
242
+
243
+ if ( false === $links ) {
244
+ $db_links = self::meta_by_key( self::LINK_META_KEY );
245
$links = array();
246
+
247
if ( $db_links ) {
248
foreach ( $db_links as $link ) {
249
$links[ intval( $link->post_id ) ] = $link->meta_value;
250
}
251
}
252
+
253
set_transient( self::LINKS_CACHE_KEY, $links, 10 * 60 );
254
}
255
+
256
return $links;
257
}
258
259
/**
260
+ * Returns the link for the specified post ID.
261
*
262
+ * @param integer $post_id a post ID.
263
+ * @return mixed either a URL or false.
264
*/
265
+ public static function get_link( $post_id ) {
266
+ return self::get_post_meta( $post_id, self::LINK_META_KEY );
267
}
268
269
/**
270
+ * Returns all targets for the current site.
271
*
272
+ * @return array an array of targets, keyed by post ID.
273
*/
274
+ public static function get_targets() {
275
+ $targets = get_transient( self::TARGETS_CACHE_KEY );
276
+
277
+ if ( false === $targets ) {
278
+ $db_targets = self::meta_by_key( self::TARGET_META_KEY );
279
$targets = array();
280
+
281
if ( $db_targets ) {
282
foreach ( $db_targets as $target ) {
283
$targets[ intval( $target->post_id ) ] = true;
284
}
285
}
286
+
287
set_transient( self::TARGETS_CACHE_KEY, $targets, 10 * 60 );
288
}
289
+
290
return $targets;
291
}
292
293
/**
294
+ * Returns the _blank target status for the specified post ID.
295
*
296
+ * @param integer $post_id a post ID.
297
+ * @return bool whether it should open in a new tab.
298
*/
299
+ public static function get_target( $post_id ) {
300
+ return (bool) self::get_post_meta( $post_id, self::TARGET_META_KEY );
301
}
302
303
/**
304
+ * Adds the meta box to the post or page edit screen.
305
*
306
+ * @param string $page the name of the current page.
307
+ * @param string $context the current context.
308
+ * @return void
309
*/
310
+ public function do_meta_boxes( $page, $context ) {
311
+ if ( self::is_supported_post_type( $page ) && 'advanced' === $context ) {
312
+ add_meta_box( 'page-links-to', _x( 'Page Links To', 'Meta box title', 'page-links-to' ), array( $this, 'meta_box' ), $page, 'advanced', 'low' );
313
}
314
}
315
316
/**
317
+ * Determine whether a post type supports custom links.
318
+ *
319
+ * @param string $type The post type to check.
320
+ * @return bool Whether this post type supports custom links.
321
+ */
322
+ public static function is_supported_post_type( $type ) {
323
+ /*
324
+ Plugins that use custom post types can use this filter to hide the
325
+ PLT UI in their post type.
326
+ */
327
+ $hook = 'page-links-to-post-types';
328
+
329
+ $supported_post_types = (array) apply_filters( $hook, array_keys( get_post_types( array(
330
+ 'show_ui' => true,
331
+ ) ) ) );
332
+
333
+ return in_array( $type, $supported_post_types );
334
+ }
335
+
336
+ /**
337
+ * Outputs the Page Links To post screen meta box.
338
+ *
339
+ * @return void
340
*/
341
+ public static function meta_box() {
342
$null = null;
343
$post = get_post( $null );
344
echo '<p>';
345
wp_nonce_field( 'cws_plt_' . $post->ID, '_cws_plt_nonce', false, true );
346
echo '</p>';
347
+ $url = self::get_link( $post->ID );
348
if ( ! $url ) {
349
$linked = false;
350
$url = '';
352
$linked = true;
353
}
354
?>
355
+ <style>
356
+ #cws-links-to-custom-section {
357
+ webkit-box-sizing: border-box;
358
+ -moz-box-sizing: border-box;
359
+ box-sizing: border-box;
360
+ margin-left: 30px;
361
+ }
362
+
363
+ #cws-links-to {
364
+ width: 75%;
365
+ }
366
+ </style>
367
+
368
<p><?php _e( 'Point this content to:', 'page-links-to' ); ?></p>
369
+ <p><label><input type="radio" id="cws-links-to-choose-wp" name="cws_links_to_choice" value="wp" <?php checked( ! $linked ); ?> /> <?php _e( 'Its normal WordPress URL', 'page-links-to' ); ?></label></p>
370
<p><label><input type="radio" id="cws-links-to-choose-custom" name="cws_links_to_choice" value="custom" <?php checked( $linked ); ?> /> <?php _e( 'A custom URL', 'page-links-to' ); ?></label></p>
371
+ <div id="cws-links-to-custom-section" class="<?php echo ! $linked ? 'hide-if-js' : ''; ?>">
372
+ <p><input placeholder="http://" name="cws_links_to" type="text" id="cws-links-to" value="<?php echo esc_attr( $url ); ?>" /></p>
373
+ <p><label for="cws-links-to-new-tab"><input type="checkbox" name="cws_links_to_new_tab" id="cws-links-to-new-tab" value="_blank" <?php checked( (bool) self::get_target( $post->ID ) ); ?>> <?php _e( 'Open this link in a new tab', 'page-links-to' ); ?></label></p>
374
</div>
375
+
376
+ <?php if ( true ) { ?>
377
+ <style>
378
+ #cws-links-to-survey {
379
+ border: 1px solid #eee;
380
+ }
381
+
382
+ #cws-links-to-survey h3, #cws-links-to-survey p {
383
+ margin: 1em;
384
+ }
385
+ </style>
386
+ <div id="cws-links-to-survey">
387
+ <h3>New Features Coming Soon!</h3>
388
+ <p>Do you have a minute? <a target="_blank" href="<?php echo self::SURVEY_URL; ?>">Please take this quick survey</a> and help me decide what features to build next!</p>
389
+ </div>
390
+ <?php } ?>
391
+
392
+ <script src="<?php echo self::get_url() . 'js/page-links-to.min.js?v=' . self::CSS_JS_VERSION; ?>"></script>
393
<?php
394
}
395
396
/**
397
+ * Saves data on attachment save.
398
*
399
+ * @param int $post_id The ID of the post being saved.
400
+ * @return int the attachment post ID that was passed in.
401
*/
402
function edit_attachment( $post_id ) {
403
return $this->save_post( $post_id );
404
}
405
406
/**
407
+ * Saves data on post save.
408
*
409
+ * @param int $post_id a post ID.
410
+ * @return int the post ID that was passed in.
411
*/
412
+ public static function save_post( $post_id ) {
413
if ( isset( $_REQUEST['_cws_plt_nonce'] ) && wp_verify_nonce( $_REQUEST['_cws_plt_nonce'], 'cws_plt_' . $post_id ) ) {
414
if ( ( ! isset( $_POST['cws_links_to_choice'] ) || 'custom' == $_POST['cws_links_to_choice'] ) && isset( $_POST['cws_links_to'] ) && strlen( $_POST['cws_links_to'] ) > 0 && $_POST['cws_links_to'] !== 'http://' ) {
415
+ $url = self::clean_url( stripslashes( $_POST['cws_links_to'] ) );
416
+ self::flush_links_if( self::set_link( $post_id, $url ) );
417
+ if ( isset( $_POST['cws_links_to_new_tab'] ) ) {
418
+ self::flush_targets_if( self::set_link_new_tab( $post_id ) );
419
+ } else {
420
+ self::flush_targets_if( self::set_link_same_tab( $post_id ) );
421
+ }
422
} else {
423
+ self::flush_links_if( self::delete_link( $post_id ) );
424
}
425
}
426
+
427
return $post_id;
428
}
429
430
/**
431
+ * Cleans up a URL.
432
*
433
+ * @param string $url URL.
434
+ * @return string cleaned up URL.
435
*/
436
+ public static function clean_url( $url ) {
437
$url = trim( $url );
438
+
439
// Starts with 'www.'. Probably a mistake. So add 'http://'.
440
if ( 0 === strpos( $url, 'www.' ) ) {
441
$url = 'http://' . $url;
442
}
443
+
444
return $url;
445
}
446
447
/**
448
+ * Have a post point to a custom URL.
449
*
450
+ * @param int $post_id post ID.
451
+ * @param string $url the URL to point the post to.
452
+ * @return bool whether anything changed.
453
*/
454
+ public static function set_link( $post_id, $url ) {
455
+ return self::flush_links_if( (bool) update_post_meta( $post_id, self::LINK_META_KEY, $url ) );
456
}
457
458
/**
459
+ * Tell an custom URL post to open in a new tab.
460
*
461
+ * @param int $post_id post ID.
462
+ * @return bool whether anything changed.
463
*/
464
+ public static function set_link_new_tab( $post_id ) {
465
+ return self::flush_targets_if( (bool) update_post_meta( $post_id, self::TARGET_META_KEY, '_blank' ) );
466
}
467
468
/**
469
+ * Tell an custom URL post to open in the same tab.
470
*
471
+ * @param int $post_id post ID.
472
+ * @return bool whether anything changed.
473
*/
474
+ public static function set_link_same_tab( $post_id ) {
475
+ return self::flush_targets_if( delete_post_meta( $post_id, self::TARGET_META_KEY ) );
476
}
477
478
/**
479
+ * Discard a custom URL and point a post to its normal URL.
480
*
481
+ * @param int $post_id post ID.
482
+ * @return bool whether the link was deleted.
483
*/
484
+ public static function delete_link( $post_id ) {
485
+ $return = self::flush_links_if( delete_post_meta( $post_id, self::LINK_META_KEY ) );
486
+ self::flush_targets_if( delete_post_meta( $post_id, self::TARGET_META_KEY ) );
487
488
+ // Old, unused data that we can delete on the fly.
489
delete_post_meta( $post_id, '_links_to_type' );
490
491
return $return;
492
}
493
494
/**
495
+ * Flushes the links transient cache if the condition is true.
496
*
497
+ * @param bool $condition whether to proceed with the flush.
498
+ * @return bool whether the flush happened.
499
*/
500
+ public static function flush_links_if( $condition ) {
501
if ( $condition ) {
502
+ self::flush_links_cache();
503
return true;
504
} else {
505
return false;
507
}
508
509
/**
510
+ * Flushes the targets transient cache if the condition is true.
511
*
512
+ * @param bool $condition whether to proceed with the flush.
513
+ * @return bool whether the flush happened.
514
*/
515
+ public static function flush_targets_if( $condition ) {
516
if ( $condition ) {
517
+ self::flush_targets_cache();
518
return true;
519
} else {
520
return false;
522
}
523
524
/**
525
+ * Flushes the links transient cache.
526
*
527
+ * @return bool whether the flush attempt occurred.
528
*/
529
+ public static function flush_links_cache() {
530
+ return delete_transient( self::LINKS_CACHE_KEY );
531
}
532
533
/**
534
+ * Flushes the targets transient cache.
535
*
536
+ * @return bool whether the flush attempt occurred.
537
*/
538
+ public static function flush_targets_cache() {
539
+ return delete_transient( self::TARGETS_CACHE_KEY );
540
}
541
542
/**
543
+ * Filter for post links.
544
*
545
+ * @param string $link the URL for the post or page.
546
+ * @param int|WP_Post $post post ID or object.
547
+ * @return string output URL.
548
*/
549
+ public function link( $link, $post ) {
550
if ( $this->replace ) {
551
$post = get_post( $post );
552
553
+ $meta_link = self::get_link( $post->ID );
554
555
if ( $meta_link ) {
556
$link = esc_url( $meta_link );
557
+ if ( ! is_admin() && self::get_target( $post->ID ) ) {
558
$link .= '#new_tab';
559
}
560
}
578
}
579
580
/**
581
+ * Performs a redirect.
582
+ *
583
+ * @return void
584
*/
585
function template_redirect() {
586
+ $link = self::get_redirect();
587
588
if ( $link ) {
589
wp_redirect( $link, 301 );
592
}
593
594
/**
595
+ * Gets the redirection URL.
596
*
597
+ * @return string|bool the redirection URL, or false.
598
*/
599
+ public static function get_redirect() {
600
if ( ! is_singular() || ! get_queried_object_id() ) {
601
return false;
602
}
603
604
+ $link = self::get_link( get_queried_object_id() );
605
606
+ // Convert server- and protocol-relative URLs to absolute URLs.
607
+ if ( '/' === $link[0] ) {
608
+ // Protocol-relative.
609
+ if ( '/' === $link[1] ) {
610
$link = set_url_scheme( 'http:' . $link );
611
} else {
612
+ // Host-relative.
613
+ $link = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $link );
614
}
615
}
616
622
}
623
624
/**
625
+ * Filters the list of pages to alter the links and targets.
626
*
627
+ * @param string $pages the wp_list_pages() HTML block from WordPress.
628
+ * @return string the modified HTML block.
629
*/
630
function wp_list_pages( $pages ) {
631
$highlight = false;
632
633
+ // We use the "fetch all" versions here, because the pages might not be queried here.
634
+ $links = self::get_links();
635
+ $targets = self::get_targets();
636
$targets_by_url = array();
637
+
638
+ foreach ( array_keys( $targets ) as $targeted_id ) {
639
+ $targets_by_url[ $links[ $targeted_id ] ] = true;
640
+ }
641
642
if ( ! $links ) {
643
return $pages;
646
$this_url = ( is_ssl() ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
647
648
foreach ( (array) $links as $id => $page ) {
649
+ if ( isset( $targets_by_url[ $page ] ) ) {
650
$page .= '#new_tab';
651
}
652
+
653
if ( str_replace( 'http://www.', 'http://', $this_url ) === str_replace( 'http://www.', 'http://', $page ) || ( is_home() && str_replace( 'http://www.', 'http://', trailingslashit( get_bloginfo( 'url' ) ) ) === str_replace( 'http://www.', 'http://', trailingslashit( $page ) ) ) ) {
654
$highlight = true;
655
$current_page = esc_url( $page );
664
}
665
666
if ( $highlight ) {
667
+ $pages = preg_replace( '| class="([^"]+)current_page_item"|', ' class="$1"', $pages ); // Kill default highlighting.
668
$pages = preg_replace( '|<li class="([^"]+)"><a href="' . preg_quote( $current_page ) . '"|', '<li class="$1 current_page_item"><a href="' . $current_page . '"', $pages );
669
}
670
+
671
return $pages;
672
}
673
674
/**
675
+ * Filters nav menu objects and adds target=_blank to the ones that need it.
676
*
677
+ * @param array $items nav menu items.
678
+ * @return array modified nav menu items.
679
*/
680
+ public static function wp_nav_menu_objects( $items ) {
681
$new_items = array();
682
+
683
foreach ( $items as $item ) {
684
+ if ( isset( $item->object_id ) && self::get_target( $item->object_id ) ) {
685
$item->target = '_blank';
686
}
687
+
688
$new_items[] = $item;
689
}
690
+
691
return $new_items;
692
}
693
694
/**
695
+ * Hooks in as a post is being loaded for editing and conditionally adds a notice.
696
+ *
697
+ * @return void
698
*/
699
+ public function load_post() {
700
+ if ( isset( $_GET['post'] ) && self::get_link( (int) $_GET['post'] ) ) {
701
$this->hook( 'admin_notices', 'notify_of_external_link' );
702
}
703
}
704
705
+ public static function ajax_dismiss_notice() {
706
+ if ( isset( $_GET['plt_notice'] ) ) {
707
+ self::dismiss_notice( $_GET['plt_notice'] );
708
+ }
709
+ }
710
+
711
+ /**
712
+ * Whether a message should be displayed.
713
+ *
714
+ * @return bool Whether to display the message.
715
+ */
716
+ public static function should_display_message() {
717
+ $start_time = 1529283010;
718
+ $end_time = $start_time + WEEK_IN_SECONDS;
719
+
720
+ return time() > $start_time && time() < $end_time && ! self::has_dismissed_notice( self::MESSAGE_ID ) && current_user_can( 'manage_options' );
721
+ }
722
+
723
+ /**
724
+ * Return the notices which have been dismissed.
725
+ *
726
+ * @return array The list of notice IDs that have been dismissed.
727
+ */
728
+ public function get_dismissed_notices() {
729
+ return get_option( self::DISMISSED_NOTICES, array() );
730
+ }
731
+
732
/**
733
+ * Mark a notice as dismissed.
734
+ *
735
+ * @param int $id The notice ID to dismiss.
736
+ * @return void
737
+ */
738
+ public static function dismiss_notice( $id ) {
739
+ $notices = self::get_dismissed_notices();
740
+ $notices[] = (int) $id;
741
+
742
+ $notices = array_unique( $notices );
743
+ update_option( self::DISMISSED_NOTICES, $notices );
744
+ }
745
+
746
+ /**
747
+ * Whether anyone on this site has dismissed the given notice.
748
+ *
749
+ * @param int $id The ID of the notice.
750
+ * @return bool Whether anyone has dismissed it.
751
+ */
752
+ public static function has_dismissed_notice( $id ) {
753
+ $dismissed_notices = get_option( self::DISMISSED_NOTICES, array() );
754
+
755
+ return in_array( (int) $id, $dismissed_notices );
756
+ }
757
+
758
+ /**
759
+ * Output the generic notice.
760
+ *
761
+ * @return void
762
+ */
763
+ public static function notify_generic() {
764
+ ?>
765
+ <div id="page-links-to-notification" class="notice updated is-dismissible"><?php _e( '<h3>Page Links To</h3><p>Do you have a minute? <a target="_blank" href="' . self::SURVEY_URL . '" class="plt-dismiss">Please take this quick survey</a> and help me decide what features to build next!</p><p><a class="button plt-dismiss" target="_blank" href="' . self::SURVEY_URL . '">Take the survey</a>&nbsp;&nbsp;<small><a href="#" class="plt-dismiss">No thanks</a></small></p>', 'page-links-to' ); ?></div>
766
+ <script>
767
+ (function($){
768
+ var $plt = $('#page-links-to-notification');
769
+ $plt
770
+ .on('click', '.notice-dismiss', function(e){
771
+ $.ajax( ajaxurl, {
772
+ type: 'GET',
773
+ data: {
774
+ action: 'plt_dismiss_notice',
775
+ plt_notice: <?php echo json_encode( self::MESSAGE_ID ); ?>
776
+ }
777
+ });
778
+ })
779
+ .on('click', '.plt-dismiss', function(e){
780
+ $(this).parents('.notice').first().find('.notice-dismiss').click();
781
+ });
782
+ })(jQuery);
783
+ </script>
784
+ <?php
785
+ }
786
+
787
+ /**
788
+ * Outputs a notice that the current post item is pointed to a custom URL.
789
+ *
790
+ * @return void
791
*/
792
+ public static function notify_of_external_link() {
793
+ ?>
794
+ <div class="notice updated"><p><?php _e( '<strong>Note</strong>: This content is pointing to a custom URL. Use the &#8220;Page Links To&#8221; box to change this behavior.', 'page-links-to' ); ?></p></div>
795
+ <?php
796
}
797
798
/**
799
+ * Adds a GitHub link to the plugin meta.
800
*
801
+ * @param array $links the current array of links.
802
+ * @param string $file the current plugin being processed.
803
+ * @return array the modified array of links.
804
*/
805
+ public static function plugin_row_meta( $links, $file ) {
806
if ( $file === plugin_basename( self::FILE ) ) {
807
return array_merge(
808
$links,
814
}
815
816
/**
817
+ * Returns the URL of this plugin's directory.
818
*
819
+ * @return string this plugin's directory URL.
820
*/
821
+ public static function get_url() {
822
return plugin_dir_url( self::FILE );
823
}
824
825
/**
826
+ * Returns the filesystem path of this plugin's directory.
827
*
828
+ * @return string this plugin's directory filesystem path.
829
*/
830
+ public static function get_path() {
831
return plugin_dir_path( self::FILE );
832
}
833
}
834
835
+ // Bootstrap everything.
836
new CWS_PageLinksTo;
837
838
/**
842
* @return string The post's original URL.
843
*/
844
function plt_get_original_permalink( $post = null ) {
845
+ return CWS_PageLinksTo::get_instance()->original_link( $post );
846
}
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate link: http://txfx.net/wordpress-plugins/donate
5
Tags: page, redirect, link, external link, repoint
6
Requires at least: 4.8
7
Tested up to: 4.9.6
8
- Stable tag: 2.10.4
9
10
Lets you make a WordPress page (or port or other content type) link to a URL of your choosing (on your site, or on another site), instead of its normal WordPress URL.
11
@@ -64,6 +64,9 @@ You can contribute (or report bugs) on [Github](https://github.com/markjaquith/p
64
65
== Changelog ==
66
67
= 2.10.4 =
68
* New screenshot and assets
69
5
Tags: page, redirect, link, external link, repoint
6
Requires at least: 4.8
7
Tested up to: 4.9.6
8
+ Stable tag: 2.11.0
9
10
Lets you make a WordPress page (or port or other content type) link to a URL of your choosing (on your site, or on another site), instead of its normal WordPress URL.
11
64
65
== Changelog ==
66
67
+ = 2.11.0 =
68
+ * Code cleanup
69
+
70
= 2.10.4 =
71
* New screenshot and assets
72