Insert Pages - Version 3.4.0

Version Description

  • Add integration with WPBakery Page Builder (Visual Composer).
  • Fix error messages about deprecated functions in PHP 7.2.
  • Adhere to WordPress Coding Standards.
Download this release

Release Info

Developer figureone
Plugin Icon wp plugin Insert Pages
Version 3.4.0
Comparing to
See all releases

Code changes from version 3.3.0 to 3.4.0

Files changed (6) hide show
  1. insert-pages.php +537 -335
  2. js/wpinsertpages.js +2 -2
  3. options.php +57 -13
  4. phpcs.xml +37 -0
  5. readme.txt +6 -1
  6. widget.php +43 -33
insert-pages.php CHANGED
@@ -1,71 +1,101 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  /*
4
- Plugin Name: Insert Pages
5
- Plugin URI: https://github.com/uhm-coe/insert-pages
6
- Description: Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
7
- Author: Paul Ryan
8
- Author URI: http://www.linkedin.com/in/paulrryan
9
- Text Domain: insert-pages
10
- Domain Path: /languages
11
- License: GPL2
12
- Version: 3.3.0
13
- */
14
-
15
- /* Copyright 2011 Paul Ryan (email: prar@hawaii.edu)
16
 
17
- This program is free software; you can redistribute it and/or modify
18
- it under the terms of the GNU General Public License, version 2, as
19
- published by the Free Software Foundation.
20
 
21
- This program is distributed in the hope that it will be useful,
22
- but WITHOUT ANY WARRANTY; without even the implied warranty of
23
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
- GNU General Public License for more details.
25
 
26
- You should have received a copy of the GNU General Public License
27
- along with this program; if not, write to the Free Software
28
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
  */
30
 
31
- /* Shortcode Format:
32
- [insert page='{slug}|{id}' display='title|link|excerpt|excerpt-only|content|post-thumbnail|all|{custom-template.php}' class='any-classes']
33
- */
 
34
 
35
- // Define the InsertPagesPlugin class (variables and functions)
36
- if ( !class_exists( 'InsertPagesPlugin' ) ) {
 
 
37
  class InsertPagesPlugin {
38
- // Save the id of the page being edited
39
- protected $pageID;
 
 
 
 
40
 
41
- // Constructor
 
 
42
  public function __construct() {
43
  // Include the code that generates the options page.
44
- require_once( dirname( __FILE__ ) . '/options.php' );
45
  }
46
 
47
- // Getter/Setter for pageID
48
- function getPageID() {
49
- return $this->pageID;
 
 
 
 
50
  }
51
- function setPageID( $id ) {
52
- return $this->pageID = $id;
 
 
 
 
 
 
 
 
53
  }
54
 
55
- // Action hook: Wordpress 'init'
56
- function insertPages_init() {
57
- add_shortcode( 'insert', array( $this, 'insertPages_handleShortcode_insert' ) );
 
 
 
 
58
  }
59
 
60
- // Action hook: Wordpress 'admin_init'
61
- function insertPages_admin_init() {
 
 
 
 
62
  // Get options set in WordPress dashboard (Settings > Insert Pages).
63
  $options = get_option( 'wpip_settings' );
64
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
65
  $options = wpip_set_defaults();
66
  }
67
 
68
- // Register the TinyMCE toolbar button script
69
  wp_enqueue_script(
70
  'wpinsertpages',
71
  plugins_url( '/js/wpinsertpages.js', __FILE__ ),
@@ -85,7 +115,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
85
  )
86
  );
87
 
88
- // Register the TinyMCE toolbar button styles
89
  wp_enqueue_style(
90
  'wpinsertpagescss',
91
  plugins_url( '/css/wpinsertpages.css', __FILE__ ),
@@ -93,13 +123,16 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
93
  '20151230'
94
  );
95
 
96
- // Register TinyMCE plugin for the toolbar button if in normal mode
97
- // (register TinyMCE plugin filters below before plugins_loaded
98
- // if in compatibility mode, to work around a SiteOrigin PageBuilder bug).
99
- // Ref: https://wordpress.org/support/topic/button-in-the-toolbar-of-tinymce-disappear-conflict-page-builder/
100
- if ( $options['wpip_tinymce_filter'] === 'normal' ) {
101
- add_filter( 'mce_external_plugins', array( $this, 'insertPages_handleFilter_mceExternalPlugins' ) );
102
- add_filter( 'mce_buttons', array( $this, 'insertPages_handleFilter_mceButtons' ) );
 
 
 
103
  }
104
 
105
  load_plugin_textdomain(
@@ -111,8 +144,14 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
111
  }
112
 
113
 
114
- // Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content
115
- function insertPages_handleShortcode_insert( $atts, $content = null ) {
 
 
 
 
 
 
116
  global $wp_query, $post, $wp_current_filter;
117
 
118
  // Shortcode attributes.
@@ -125,25 +164,25 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
125
  ), $atts, 'insert' );
126
 
127
  // Validation checks.
128
- if ( $attributes['page'] === '0' ) {
129
  return $content;
130
  }
131
 
132
  // Trying to embed same page in itself.
133
  if (
134
  ! is_null( $post ) && property_exists( $post, 'ID' ) &&
135
- ( $attributes['page'] == $post->ID || $attributes['page'] == $post->post_name )
136
  ) {
137
  return $content;
138
  }
139
 
140
  // Get options set in WordPress dashboard (Settings > Insert Pages).
141
  $options = get_option( 'wpip_settings' );
142
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
143
  $options = wpip_set_defaults();
144
  }
145
 
146
- $attributes['inline'] = ( $attributes['inline'] !== false && $attributes['inline'] !== 'false' ) || array_search( 'inline', $atts ) === 0 || ( array_key_exists( 'wpip_wrapper', $options ) && $options['wpip_wrapper'] === 'inline' );
147
  /**
148
  * Filter the flag indicating whether to wrap the inserted content in inline tags (span).
149
  *
@@ -202,12 +241,11 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
202
  */
203
  $attributes['display'] = apply_filters( 'insert_pages_override_display', $attributes['display'] );
204
 
205
-
206
  // Don't allow inserted pages to be added to the_content more than once (prevent infinite loops).
207
  if ( $attributes['should_apply_nesting_check'] ) {
208
  $done = false;
209
  foreach ( $wp_current_filter as $filter ) {
210
- if ( 'the_content' == $filter ) {
211
  if ( $done ) {
212
  return $content;
213
  } else {
@@ -223,7 +261,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
223
  // types), excluding builtin types (nav_menu_item, attachment).
224
  $insertable_post_types = array_filter(
225
  get_post_types(),
226
- create_function( '$type', 'return ! in_array( $type, array( "nav_menu_item", "attachment" ) );' )
227
  );
228
  $inserted_page = get_page_by_path( $attributes['page'], OBJECT, $insertable_post_types );
229
 
@@ -236,7 +274,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
236
  "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' LIMIT 1", $attributes['page']
237
  ) );
238
  if ( $page ) {
239
- $inserted_page = get_post( $page );
240
  }
241
  }
242
 
@@ -250,15 +288,15 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
250
  $original_get = $_GET;
251
  $original_request = $_REQUEST;
252
  foreach ( $querystring as $param => $value ) {
253
- $_GET[$param] = $value;
254
- $_REQUEST[$param] = $value;
255
  }
256
 
257
  // Use "Normal" insert method (get_post()).
258
- if ( $options['wpip_insert_method'] !== 'legacy' ) {
259
 
260
  // If we couldn't retrieve the page, fire the filter hook showing a not-found message.
261
- if ( $inserted_page === null ) {
262
  /**
263
  * Filter the html that should be displayed if an inserted page was not found.
264
  *
@@ -273,11 +311,17 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
273
  // Start output buffering so we can save the output to a string.
274
  ob_start();
275
 
276
- // If Beaver Builder, SiteOrigin Page Builder, or Elementor are enabled,
277
- // load any cached styles associated with the inserted page.
 
278
  // Note: Temporarily set the global $post->ID to the inserted page ID,
279
  // since both builders rely on the id to load the appropriate styles.
280
- if ( class_exists( 'FLBuilder' ) || class_exists( 'SiteOrigin_Panels' ) || class_exists( '\Elementor\Post_CSS_File' ) ) {
 
 
 
 
 
281
  // If we're not in The Loop (i.e., global $post isn't assigned),
282
  // temporarily populate it with the post to be inserted so we can
283
  // retrieve generated styles for that post. Reset $post to null
@@ -304,6 +348,33 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
304
  $css_file->enqueue();
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  if ( is_null( $old_post_id ) ) {
308
  $post = null;
309
  } else {
@@ -311,146 +382,161 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
311
  }
312
  }
313
 
314
- // Show either the title, link, content, everything, or everything via a custom template
315
- // Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled;
316
- // This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters
317
- // are only getting called once. The fix here is to disable processing of filters on the_content in
318
- // the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
 
 
 
 
 
 
 
319
  switch ( $attributes['display'] ) {
 
 
 
 
 
 
320
 
321
- case "title":
322
- $title_tag = $attributes['inline'] ? 'span' : 'h1';
323
- echo "<$title_tag class='insert-page-title'>";
324
- echo get_the_title( $inserted_page->ID );
325
- echo "</$title_tag>";
326
- break;
327
-
328
- case "link":
329
- ?><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a><?php
330
- break;
331
-
332
- case "excerpt":
333
- ?><h1><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a></h1><?php
334
- echo $this->insertPages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] );
335
- break;
336
-
337
- case "excerpt-only":
338
- echo $this->insertPages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] );
339
- break;
340
-
341
- case "content":
342
- // If Elementor is installed, try to render the page with it. If there is no Elementor content, fall back to normal rendering.
343
- if ( class_exists( '\Elementor\Plugin' ) ) {
344
- $elementor_content = \Elementor\Plugin::$instance->frontend->get_builder_content( $inserted_page->ID );
345
- if ( strlen( $elementor_content ) > 0 ) {
346
- echo $elementor_content;
347
- break;
348
- }
349
- }
350
 
351
- // Render the content normally.
352
- $content = get_post_field( 'post_content', $inserted_page->ID );
353
- if ( $attributes['should_apply_the_content_filter'] ) {
354
- $content = apply_filters( 'the_content', $content );
355
- }
356
- echo $content;
357
- break;
358
-
359
- case "post-thumbnail":
360
- ?><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_post_thumbnail( $inserted_page->ID ); ?></a><?php
361
- break;
362
-
363
- case "all":
364
- // Title.
365
- $title_tag = $attributes['inline'] ? 'span' : 'h1';
366
- echo "<$title_tag class='insert-page-title'>";
367
- echo get_the_title( $inserted_page->ID );
368
- echo "</$title_tag>";
369
- // Content.
370
- $content = get_post_field( 'post_content', $inserted_page->ID );
371
- if ( $attributes['should_apply_the_content_filter'] ) {
372
- $content = apply_filters( 'the_content', $content );
373
- }
374
- echo $content;
375
- // Meta.
376
- // @ref https://core.trac.wordpress.org/browser/tags/4.4/src/wp-includes/post-template.php#L968
377
- if ( $keys = get_post_custom_keys( $inserted_page->ID ) ) {
378
- echo "<ul class='post-meta'>\n";
379
- foreach ( (array) $keys as $key ) {
380
- $keyt = trim( $key );
381
- if ( is_protected_meta( $keyt, 'post' ) ) {
382
- continue;
383
- }
384
- $value = get_post_custom_values( $key, $inserted_page->ID );
385
- if ( is_array( $value ) ) {
386
- $values = array_map( 'trim', $value );
387
- $value = implode( $values, ', ' );
388
  }
 
389
 
390
- /**
391
- * Filter the HTML output of the li element in the post custom fields list.
392
- *
393
- * @since 2.2.0
394
- *
395
- * @param string $html The HTML output for the li element.
396
- * @param string $key Meta key.
397
- * @param string $value Meta value.
398
- */
399
- echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value );
400
  }
401
- echo "</ul>\n";
402
- }
403
- break;
404
-
405
- default: // display is either invalid, or contains a template file to use
406
- // Legacy/compatibility code: In order to use custom templates,
407
- // we use query_posts() to provide the template with the global
408
- // state it requires for the inserted page (in other words, all
409
- // template tags will work with respect to the inserted page
410
- // instead of the parent page / main loop). Note that this may
411
- // cause some compatibility issues with other plugins.
412
- // @ref https://codex.wordpress.org/Function_Reference/query_posts
413
- if ( is_numeric( $attributes['page'] ) ) {
414
- $args = array(
415
- 'p' => intval( $attributes['page'] ),
416
- 'post_type' => get_post_types(),
417
- );
418
- } else {
419
- $args = array(
420
- 'name' => esc_attr( $attributes['page'] ),
421
- 'post_type' => get_post_types(),
422
- );
423
- }
424
- $inserted_page = query_posts( $args );
425
- if ( have_posts() ) {
426
- $template = locate_template( $attributes['display'] );
427
- // Only allow templates that don't have any directory traversal in
428
- // them (to prevent including php files that aren't in the active
429
- // theme directory or the /wp-includes/theme-compat/ directory).
430
- $path_in_theme_or_childtheme_or_compat = (
431
- // Template is in current theme folder.
432
- 0 === strpos( realpath( $template ), realpath( STYLESHEETPATH ) ) ||
433
- // Template is in current or parent theme folder.
434
- 0 === strpos( realpath( $template ), realpath( TEMPLATEPATH ) ) ||
435
- // Template is in theme-compat folder.
436
- 0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) )
437
- );
438
- if ( strlen( $template ) > 0 && $path_in_theme_or_childtheme_or_compat ) {
439
- include $template; // execute the template code
440
- } else { // Couldn't find template, so fall back to printing a link to the page.
441
- the_post();
442
- ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
443
  }
444
- }
445
- wp_reset_query();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  }
448
 
449
  // Save output buffer contents.
450
  $content = ob_get_clean();
451
 
452
- // Use "Legacy" insert method (query_posts()).
453
- } else {
454
 
455
  // Construct query_posts arguments.
456
  if ( is_numeric( $attributes['page'] ) ) {
@@ -466,14 +552,20 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
466
  }
467
  $posts = query_posts( $args );
468
  if ( have_posts() ) {
469
- // Start output buffering so we can save the output to string
470
  ob_start();
471
 
472
- // If Beaver Builder, SiteOrigin Page Builder, or Elementor are enabled,
473
- // load any cached styles associated with the inserted page.
 
474
  // Note: Temporarily set the global $post->ID to the inserted page ID,
475
  // since both builders rely on the id to load the appropriate styles.
476
- if ( class_exists( 'FLBuilder' ) || class_exists( 'SiteOrigin_Panels' ) || class_exists( '\Elementor\Post_CSS_File' ) ) {
 
 
 
 
 
477
  // If we're not in The Loop (i.e., global $post isn't assigned),
478
  // temporarily populate it with the post to be inserted so we can
479
  // retrieve generated styles for that post. Reset $post to null
@@ -500,6 +592,33 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
500
  $css_file->enqueue();
501
  }
502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  if ( is_null( $old_post_id ) ) {
504
  $post = null;
505
  } else {
@@ -507,68 +626,95 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
507
  }
508
  }
509
 
510
- // Show either the title, link, content, everything, or everything via a custom template
511
- // Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled;
512
- // This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters
513
- // are only getting called once. The fix here is to disable processing of filters on the_content in
514
- // the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
 
 
 
 
 
 
 
515
  switch ( $attributes['display'] ) {
516
- case "title":
517
- the_post();
518
- $title_tag = $attributes['inline'] ? 'span' : 'h1';
519
- echo "<$title_tag class='insert-page-title'>";
520
- the_title();
521
- echo "</$title_tag>";
522
- break;
523
- case "link":
524
- the_post();
525
- ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
526
- break;
527
- case "excerpt":
528
- the_post();
529
- ?><h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1><?php
530
- if ( $attributes['should_apply_the_content_filter'] ) the_excerpt(); else echo get_the_excerpt();
531
- break;
532
- case "excerpt-only":
533
- the_post();
534
- if ( $attributes['should_apply_the_content_filter'] ) the_excerpt(); else echo get_the_excerpt();
535
- break;
536
- case "content":
537
- the_post();
538
- if ( $attributes['should_apply_the_content_filter'] ) the_content(); else echo get_the_content();
539
- break;
540
- case "post-thumbnail":
541
- ?><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a><?php
542
- break;
543
- case "all":
544
- the_post();
545
- $title_tag = $attributes['inline'] ? 'span' : 'h1';
546
- echo "<$title_tag class='insert-page-title'>";
547
- the_title();
548
- echo "</$title_tag>";
549
- if ( $attributes['should_apply_the_content_filter'] ) the_content(); else echo get_the_content();
550
- the_meta();
551
- break;
552
- default: // display is either invalid, or contains a template file to use
553
- $template = locate_template( $attributes['display'] );
554
- // Only allow templates that don't have any directory traversal in
555
- // them (to prevent including php files that aren't in the active
556
- // theme directory or the /wp-includes/theme-compat/ directory).
557
- $path_in_theme_or_childtheme_or_compat = (
558
- // Template is in current theme folder.
559
- 0 === strpos( realpath( $template ), realpath( STYLESHEETPATH ) ) ||
560
- // Template is in current or parent theme folder.
561
- 0 === strpos( realpath( $template ), realpath( TEMPLATEPATH ) ) ||
562
- // Template is in theme-compat folder.
563
- 0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) )
564
- );
565
- if ( strlen( $template ) > 0 && $path_in_theme_or_childtheme_or_compat ) {
566
- include $template; // execute the template code
567
- } else { // Couldn't find template, so fall back to printing a link to the page.
568
  the_post();
569
- ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
570
- }
571
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
  }
573
  // Save output buffer contents.
574
  $content = ob_get_clean();
@@ -607,37 +753,61 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
607
  return $content;
608
  }
609
 
610
- // Default filter for insert_pages_wrap_content.
611
- function insertPages_wrap_content( $content, $posts, $attributes ) {
 
 
 
 
 
 
 
612
  return "<{$attributes['wrapper_tag']} data-post-id='{$attributes['page']}' class='insert-page insert-page-{$attributes['page']} {$attributes['class']}'>{$content}</{$attributes['wrapper_tag']}>";
613
  }
614
 
615
- // Filter hook: Add a button to the TinyMCE toolbar for our insert page tool
616
- function insertPages_handleFilter_mceButtons( $buttons ) {
617
- if ( ! in_array( 'wpInsertPages_button', $buttons ) ) {
 
 
 
 
 
618
  array_push( $buttons, 'wpInsertPages_button' );
619
  }
620
  return $buttons;
621
  }
622
 
623
- // Filter hook: Load the javascript for our custom toolbar button
624
- function insertPages_handleFilter_mceExternalPlugins( $plugins ) {
 
 
 
 
 
625
  if ( ! array_key_exists( 'wpInsertPages', $plugins ) ) {
626
  $plugins['wpInsertPages'] = plugins_url( '/js/wpinsertpages_plugin.js', __FILE__ );
627
  }
628
  return $plugins;
629
  }
630
 
631
- // Helper function to generate an excerpt (outside of the Loop) for a given ID.
632
- // @ref wp_trim_excerpt()
633
- function insertPages_trim_excerpt( $text = '', $post_id = 0, $apply_the_content_filter = true ) {
 
 
 
 
 
 
 
634
  $post_id = intval( $post_id );
635
  if ( $post_id < 1 ) {
636
  return '';
637
  }
638
 
639
  $raw_excerpt = $text;
640
- if ( '' == $text ) {
641
  $text = get_post_field( 'post_content', $post_id );
642
 
643
  $text = strip_shortcodes( $text );
@@ -656,6 +826,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
656
  * @param int $number The number of words. Default 55.
657
  */
658
  $excerpt_length = apply_filters( 'excerpt_length', 55 );
 
659
  /**
660
  * Filter the string in the "more" link displayed after a trimmed excerpt.
661
  *
@@ -663,7 +834,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
663
  *
664
  * @param string $more_string The string shown within the more link.
665
  */
666
- $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[&hellip;]' );
667
  $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
668
  }
669
  /**
@@ -683,7 +854,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
683
  *
684
  * @since 3.1.0
685
  */
686
- function insertPages_wp_tinymce_dialog() {
687
  // If wp_editor() is being called outside of an admin context,
688
  // required dependencies for Insert Pages will be missing (e.g.,
689
  // wp-admin/includes/template.php will not be loaded, admin_head
@@ -693,26 +864,27 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
693
  return;
694
  }
695
 
696
- $options_panel_visible = '1' == get_user_setting( 'wpinsertpage', '0' ) ? ' options-panel-visible' : '';
697
-
698
  // Get ID of post currently being edited.
699
  $post_id = array_key_exists( 'post', $_REQUEST ) && intval( $_REQUEST['post'] ) > 0 ? intval( $_REQUEST['post'] ) : '';
700
 
701
- // display: none is required here, see #WP27605
702
  ?><div id="wp-insertpage-backdrop" style="display: none"></div>
703
- <div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $options_panel_visible; ?>" style="display: none">
 
 
 
704
  <form id="wp-insertpage" tabindex="-1">
705
  <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
706
- <input type="hidden" id="insertpage-parent-pageID" value="<?php echo $post_id; ?>" />
707
  <div id="insertpage-modal-title">
708
- <?php _e( 'Insert page', 'insert-pages' ) ?>
709
  <div id="wp-insertpage-close" tabindex="0"></div>
710
  </div>
711
  <div id="insertpage-selector">
712
  <div id="insertpage-search-panel">
713
  <div class="insertpage-search-wrapper">
714
  <label>
715
- <span class="search-label"><?php _e( 'Search', 'insert-pages' ); ?></span>
716
  <input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" />
717
  <span class="spinner"></span>
718
  </label>
@@ -724,52 +896,52 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
724
  </div>
725
  </div>
726
  <div id="insertpage-most-recent-results" class="query-results">
727
- <div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.', 'insert-pages' ); ?></em></div>
728
  <ul></ul>
729
  <div class="river-waiting">
730
  <span class="spinner"></span>
731
  </div>
732
  </div>
733
  </div>
734
- <p class="howto" id="insertpage-options-toggle"><?php _e( 'Options', 'insert-pages' ); ?></p>
735
  <div id="insertpage-options-panel">
736
  <div class="insertpage-options-wrapper">
737
  <label for="insertpage-slug-field">
738
- <span><?php _e( 'Slug or ID', 'insert-pages' ); ?></span>
739
  <input id="insertpage-slug-field" type="text" autocomplete="off" />
740
- <input id="insertpage-pageID" type="hidden" />
741
  </label>
742
  </div>
743
  <div class="insertpage-format">
744
  <label for="insertpage-format-select">
745
- <?php _e( 'Display', 'insert-pages' ); ?>
746
  <select name="insertpage-format-select" id="insertpage-format-select">
747
- <option value='title'><?php _e( 'Title', 'insert-pages' ); ?></option>
748
- <option value='link'><?php _e( 'Link', 'insert-pages' ); ?></option>
749
- <option value='excerpt'><?php _e( 'Excerpt with title', 'insert-pages' ); ?></option>
750
- <option value='excerpt-only'><?php _e( 'Excerpt only (no title)', 'insert-pages' ); ?></option>
751
- <option value='content'><?php _e( 'Content', 'insert-pages' ); ?></option>
752
- <option value='post-thumbnail'><?php _e( 'Post Thumbnail', 'insert-pages' ); ?></option>
753
- <option value='all'><?php _e( 'All (includes custom fields)', 'insert-pages' ); ?></option>
754
- <option value='template'><?php _e( 'Use a custom template', 'insert-pages' ); ?> &raquo;</option>
755
  </select>
756
  <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
757
- <option value='all'><?php _e( 'Default Template', 'insert-pages' ); ?></option>
758
  <?php page_template_dropdown(); ?>
759
  </select>
760
  </label>
761
  </div>
762
  <div class="insertpage-extra">
763
  <label for="insertpage-extra-classes">
764
- <?php _e( 'Extra Classes', 'insert-pages' ); ?>
765
  <input id="insertpage-extra-classes" type="text" autocomplete="off" />
766
  </label>
767
  <label for="insertpage-extra-inline">
768
- <?php _e( 'Inline?', 'insert-pages' ); ?>
769
  <input id="insertpage-extra-inline" type="checkbox" />
770
  </label>
771
  <label for="insertpage-extra-querystring">
772
- <?php _e( 'Querystring', 'insert-pages' ); ?>
773
  <input id="insertpage-extra-querystring" type="text" autocomplete="off" />
774
  </label>
775
  </div>
@@ -780,7 +952,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
780
  <input type="submit" value="<?php esc_attr_e( 'Insert Page', 'insert-pages' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit">
781
  </div>
782
  <div id="wp-insertpage-cancel">
783
- <a class="submitdelete deletion" href="#"><?php _e( 'Cancel', 'insert-pages' ); ?></a>
784
  </div>
785
  </div>
786
  </form>
@@ -788,53 +960,55 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
788
  <?php
789
  }
790
 
791
- /** Modified from:
 
792
  * Internal linking functions.
793
  *
794
  * @package WordPress
795
  * @subpackage Administration
796
  * @since 3.1.0
797
  */
798
- function insertPages_insert_page_callback() {
799
  check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
800
  $args = array();
801
  if ( isset( $_POST['search'] ) ) {
802
- $args['s'] = stripslashes( $_POST['search'] );
803
  }
804
- $args['pagenum'] = !empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
805
- $args['pageID'] = !empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0;
806
 
807
  // Change search to slug or post ID if we're not doing a plaintext
808
  // search (e.g., if we're editing an existing shortcode and the
809
  // search field is populated with the post's slug or ID).
810
- if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'slug' ) {
811
  $args['name'] = $args['s'];
812
  unset( $args['s'] );
813
- } else if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'post_id' ) {
814
  $args['p'] = $args['s'];
815
  unset( $args['s'] );
816
  }
817
 
818
- $results = $this->insertPages_wp_query( $args );
819
 
820
  // Fail if our query didn't work.
821
  if ( ! isset( $results ) ) {
822
  die( '0' );
823
  }
824
 
825
- echo json_encode( $results );
826
  echo "\n";
827
  die();
828
  }
829
 
830
- /** Modified from:
 
831
  * Performs post queries for internal linking.
832
  *
833
  * @since 3.1.0
834
- * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
835
  * @return array Results.
836
  */
837
- function insertPages_wp_query( $args = array() ) {
838
  $pts = get_post_types( array( 'public' => true ), 'objects' );
839
  $post_types = array_keys( $pts );
840
 
@@ -880,7 +1054,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
880
  }
881
 
882
  // Do main query.
883
- $get_posts = new WP_Query;
884
  $posts = $get_posts->query( $query );
885
  // Check if any posts were found.
886
  if ( ! $get_posts->post_count ) {
@@ -890,7 +1064,7 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
890
  // Build results.
891
  $results = array();
892
  foreach ( $posts as $post ) {
893
- if ( 'post' == $post->post_type ) {
894
  $info = mysql2date( 'Y/m/d', $post->post_date );
895
  } else {
896
  $info = $pts[ $post->post_type ]->labels->singular_name;
@@ -907,60 +1081,88 @@ if ( !class_exists( 'InsertPagesPlugin' ) ) {
907
  return $results;
908
  }
909
 
910
- function insertPages_add_quicktags() {
 
 
 
 
 
911
  if ( wp_script_is( 'quicktags' ) ) : ?>
912
  <script type="text/javascript">
913
  QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|post-thumbnail|all']\n", '', '', 'Insert Page', 999 );
914
  </script>
915
- <?php endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916
  }
917
 
918
  }
919
  }
920
 
921
- // Initialize InsertPagesPlugin object
922
  if ( class_exists( 'InsertPagesPlugin' ) ) {
923
- $insertPages_plugin = new InsertPagesPlugin();
924
  }
925
 
926
- // Actions and Filters handled by InsertPagesPlugin class
927
- if ( isset( $insertPages_plugin ) ) {
928
  // Get options set in WordPress dashboard (Settings > Insert Pages).
929
  $options = get_option( 'wpip_settings' );
930
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
931
  $options = wpip_set_defaults();
932
  }
933
 
934
  // Register shortcode [insert ...].
935
- add_action( 'init', array( $insertPages_plugin, 'insertPages_init' ), 1 );
936
  // Register shortcode [insert ...] when TinyMCE is included in a frontend ACF form.
937
- add_action( 'acf_head-input', array( $insertPages_plugin, 'insertPages_init' ), 1 ); // ACF 3
938
- add_action( 'acf/input/admin_head', array( $insertPages_plugin, 'insertPages_init' ), 1 ); // ACF 4
939
 
940
  // Add TinyMCE button for shortcode.
941
- add_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 );
942
 
943
  // Add quicktags button for shortcode.
944
- add_action( 'admin_print_footer_scripts', array( $insertPages_plugin, 'insertPages_add_quicktags' ) );
945
 
946
  // Preload TinyMCE popup.
947
- add_action( 'before_wp_tiny_mce', array( $insertPages_plugin, 'insertPages_wp_tinymce_dialog' ), 1 );
948
 
949
  // Ajax: Populate page search in TinyMCE button popup.
950
- add_action( 'wp_ajax_insertpage', array( $insertPages_plugin, 'insertPages_insert_page_callback' ) );
951
 
952
  // Use internal filter to wrap inserted content in a div or span.
953
- add_filter( 'insert_pages_wrap_content', array( $insertPages_plugin, 'insertPages_wrap_content' ), 10, 3 );
954
-
955
- // Register TinyMCE plugin for the toolbar button if in compatibility mode.
956
- // (to work around a SiteOrigin PageBuilder bug).
957
- // Ref: https://wordpress.org/support/topic/button-in-the-toolbar-of-tinymce-disappear-conflict-page-builder/
958
- if ( $options['wpip_tinymce_filter'] === 'compatibility' ) {
959
- add_filter( 'mce_external_plugins', array( $insertPages_plugin, 'insertPages_handleFilter_mceExternalPlugins' ) );
960
- add_filter( 'mce_buttons', array( $insertPages_plugin, 'insertPages_handleFilter_mceButtons' ) );
 
 
 
961
  }
962
 
963
  // Register Insert Pages shortcode widget.
964
- require_once( dirname( __FILE__ ) . '/widget.php' );
965
- add_action( 'widgets_init', create_function( '', 'return register_widget( "InsertPagesWidget" );' ) );
966
  }
1
  <?php
2
+ /**
3
+ * Plugin Name: Insert Pages
4
+ * Plugin URI: https://github.com/uhm-coe/insert-pages
5
+ * Description: Insert Pages lets you embed any WordPress content (e.g., pages, posts, custom post types) into other WordPress content using the Shortcode API.
6
+ * Author: Paul Ryan
7
+ * Text Domain: insert-pages
8
+ * Domain Path: /languages
9
+ * License: GPL2
10
+ * Version: 3.4.0
11
+ *
12
+ * @package insert-pages
13
+ */
14
 
15
  /*
16
+ Copyright 2011 Paul Ryan (email: prar@hawaii.edu)
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ This program is free software; you can redistribute it and/or modify
19
+ it under the terms of the GNU General Public License, version 2, as
20
+ published by the Free Software Foundation.
21
 
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
 
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
  */
31
 
32
+ /**
33
+ * Shortcode Format:
34
+ * [insert page='{slug}|{id}' display='title|link|excerpt|excerpt-only|content|post-thumbnail|all|{custom-template.php}' class='any-classes']
35
+ */
36
 
37
+ if ( ! class_exists( 'InsertPagesPlugin' ) ) {
38
+ /**
39
+ * Class InsertPagesPlugin
40
+ */
41
  class InsertPagesPlugin {
42
+ /**
43
+ * Page ID being inserted.
44
+ *
45
+ * @var int
46
+ */
47
+ protected $page_id;
48
 
49
+ /**
50
+ * Constructor.
51
+ */
52
  public function __construct() {
53
  // Include the code that generates the options page.
54
+ require_once dirname( __FILE__ ) . '/options.php';
55
  }
56
 
57
+ /**
58
+ * Getter for page_id.
59
+ *
60
+ * @return int Page ID being inserted.
61
+ */
62
+ public function get_page_id() {
63
+ return $this->page_id;
64
  }
65
+
66
+ /**
67
+ * Setter for page_id.
68
+ *
69
+ * @param int $id Page ID being inserted.
70
+ */
71
+ public function set_page_id( $id ) {
72
+ $this->page_id = $id;
73
+
74
+ return $this->page_id;
75
  }
76
 
77
+ /**
78
+ * Action hook: WordPress 'init'.
79
+ *
80
+ * @return void
81
+ */
82
+ public function insert_pages_init() {
83
+ add_shortcode( 'insert', array( $this, 'insert_pages_handle_shortcode_insert' ) );
84
  }
85
 
86
+ /**
87
+ * Action hook: WordPress 'admin_init'.
88
+ *
89
+ * @return void
90
+ */
91
+ public function insert_pages_admin_init() {
92
  // Get options set in WordPress dashboard (Settings > Insert Pages).
93
  $options = get_option( 'wpip_settings' );
94
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
95
  $options = wpip_set_defaults();
96
  }
97
 
98
+ // Register the TinyMCE toolbar button script.
99
  wp_enqueue_script(
100
  'wpinsertpages',
101
  plugins_url( '/js/wpinsertpages.js', __FILE__ ),
115
  )
116
  );
117
 
118
+ // Register the TinyMCE toolbar button styles.
119
  wp_enqueue_style(
120
  'wpinsertpagescss',
121
  plugins_url( '/css/wpinsertpages.css', __FILE__ ),
123
  '20151230'
124
  );
125
 
126
+ /**
127
+ * Register TinyMCE plugin for the toolbar button in normal mode (register
128
+ * TinyMCE plugin filters below before plugins_loaded in compatibility
129
+ * mode, to work around a SiteOrigin PageBuilder bug).
130
+ *
131
+ * @see https://wordpress.org/support/topic/button-in-the-toolbar-of-tinymce-disappear-conflict-page-builder/
132
+ */
133
+ if ( 'normal' === $options['wpip_tinymce_filter'] ) {
134
+ add_filter( 'mce_external_plugins', array( $this, 'insert_pages_handle_filter_mce_external_plugins' ) );
135
+ add_filter( 'mce_buttons', array( $this, 'insert_pages_handle_filter_mce_buttons' ) );
136
  }
137
 
138
  load_plugin_textdomain(
144
  }
145
 
146
 
147
+ /**
148
+ * Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content.
149
+ *
150
+ * @param array $atts Shortcode attributes.
151
+ * @param string $content Content to replace shortcode.
152
+ * @return string Content to replace shortcode.
153
+ */
154
+ public function insert_pages_handle_shortcode_insert( $atts, $content = null ) {
155
  global $wp_query, $post, $wp_current_filter;
156
 
157
  // Shortcode attributes.
164
  ), $atts, 'insert' );
165
 
166
  // Validation checks.
167
+ if ( '0' === $attributes['page'] ) {
168
  return $content;
169
  }
170
 
171
  // Trying to embed same page in itself.
172
  if (
173
  ! is_null( $post ) && property_exists( $post, 'ID' ) &&
174
+ ( intval( $attributes['page'] ) === $post->ID || $attributes['page'] === $post->post_name )
175
  ) {
176
  return $content;
177
  }
178
 
179
  // Get options set in WordPress dashboard (Settings > Insert Pages).
180
  $options = get_option( 'wpip_settings' );
181
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
182
  $options = wpip_set_defaults();
183
  }
184
 
185
+ $attributes['inline'] = ( false !== $attributes['inline'] && 'false' !== $attributes['inline'] ) || array_search( 'inline', $atts, true ) === 0 || ( array_key_exists( 'wpip_wrapper', $options ) && 'inline' === $options['wpip_wrapper'] );
186
  /**
187
  * Filter the flag indicating whether to wrap the inserted content in inline tags (span).
188
  *
241
  */
242
  $attributes['display'] = apply_filters( 'insert_pages_override_display', $attributes['display'] );
243
 
 
244
  // Don't allow inserted pages to be added to the_content more than once (prevent infinite loops).
245
  if ( $attributes['should_apply_nesting_check'] ) {
246
  $done = false;
247
  foreach ( $wp_current_filter as $filter ) {
248
+ if ( 'the_content' === $filter ) {
249
  if ( $done ) {
250
  return $content;
251
  } else {
261
  // types), excluding builtin types (nav_menu_item, attachment).
262
  $insertable_post_types = array_filter(
263
  get_post_types(),
264
+ array( $this, 'is_post_type_insertable' )
265
  );
266
  $inserted_page = get_page_by_path( $attributes['page'], OBJECT, $insertable_post_types );
267
 
274
  "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' LIMIT 1", $attributes['page']
275
  ) );
276
  if ( $page ) {
277
+ $inserted_page = get_post( $page );
278
  }
279
  }
280
 
288
  $original_get = $_GET;
289
  $original_request = $_REQUEST;
290
  foreach ( $querystring as $param => $value ) {
291
+ $_GET[ $param ] = $value;
292
+ $_REQUEST[ $param ] = $value;
293
  }
294
 
295
  // Use "Normal" insert method (get_post()).
296
+ if ( 'legacy' !== $options['wpip_insert_method'] ) {
297
 
298
  // If we couldn't retrieve the page, fire the filter hook showing a not-found message.
299
+ if ( null === $inserted_page ) {
300
  /**
301
  * Filter the html that should be displayed if an inserted page was not found.
302
  *
311
  // Start output buffering so we can save the output to a string.
312
  ob_start();
313
 
314
+ // If Beaver Builder, SiteOrigin Page Builder, Elementor, or WPBakery
315
+ // Page Builder (Visual Composer) are enabled, load any cached styles
316
+ // associated with the inserted page.
317
  // Note: Temporarily set the global $post->ID to the inserted page ID,
318
  // since both builders rely on the id to load the appropriate styles.
319
+ if (
320
+ class_exists( 'FLBuilder' ) ||
321
+ class_exists( 'SiteOrigin_Panels' ) ||
322
+ class_exists( '\Elementor\Post_CSS_File' ) ||
323
+ defined( 'VCV_VERSION' )
324
+ ) {
325
  // If we're not in The Loop (i.e., global $post isn't assigned),
326
  // temporarily populate it with the post to be inserted so we can
327
  // retrieve generated styles for that post. Reset $post to null
348
  $css_file->enqueue();
349
  }
350
 
351
+ // Enqueue custom style from WPBakery Page Builder (Visual Composer).
352
+ if ( defined( 'VCV_VERSION' ) ) {
353
+ $bundle_url = get_post_meta( $inserted_page->ID, 'vcvSourceCssFileUrl', true );
354
+ if ( $bundle_url ) {
355
+ $version = get_post_meta( $inserted_page->ID, 'vcvSourceCssFileHash', true );
356
+ if ( ! preg_match( '/^http/', $bundle_url ) ) {
357
+ if ( ! preg_match( '/assets-bundles/', $bundle_url ) ) {
358
+ $bundle_url = '/assets-bundles/' . $bundle_url;
359
+ }
360
+ }
361
+ if ( preg_match( '/^http/', $bundle_url ) ) {
362
+ $bundle_url = set_url_scheme( $bundle_url );
363
+ } elseif ( defined( 'VCV_TF_ASSETS_IN_UPLOADS' ) && constant( 'VCV_TF_ASSETS_IN_UPLOADS' ) ) {
364
+ $upload_dir = wp_upload_dir();
365
+ $bundle_url = set_url_scheme( $upload_dir['baseurl'] . '/' . VCV_PLUGIN_ASSETS_DIRNAME . '/' . ltrim( $bundle_url, '/\\' ) );
366
+ } else {
367
+ $bundle_url = content_url() . '/' . VCV_PLUGIN_ASSETS_DIRNAME . '/' . ltrim( $bundle_url, '/\\' );
368
+ }
369
+ wp_enqueue_style(
370
+ 'vcv:assets:source:main:styles:' . sanitize_title( $bundle_url ),
371
+ $bundle_url,
372
+ array(),
373
+ VCV_VERSION . '.' . $version
374
+ );
375
+ }
376
+ }
377
+
378
  if ( is_null( $old_post_id ) ) {
379
  $post = null;
380
  } else {
382
  }
383
  }
384
 
385
+ /**
386
+ * Show either the title, link, content, everything, or everything via a
387
+ * custom template.
388
+ *
389
+ * Note: if the sharing_display filter exists, it means Jetpack is
390
+ * installed and Sharing is enabled; this plugin conflicts with Sharing,
391
+ * because Sharing assumes the_content and the_excerpt filters are only
392
+ * getting called once. The fix here is to disable processing of filters
393
+ * on the_content in the inserted page.
394
+ *
395
+ * @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
396
+ */
397
  switch ( $attributes['display'] ) {
398
+ case 'title':
399
+ $title_tag = $attributes['inline'] ? 'span' : 'h1';
400
+ echo "<$title_tag class='insert-page-title'>";
401
+ echo get_the_title( $inserted_page->ID );
402
+ echo "</$title_tag>";
403
+ break;
404
 
405
+ case 'link':
406
+ ?><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a>
407
+ <?php
408
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
+ case 'excerpt':
411
+ ?><h1><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a></h1>
412
+ <?php
413
+ echo $this->insert_pages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] );
414
+ break;
415
+
416
+ case 'excerpt-only':
417
+ echo $this->insert_pages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] );
418
+ break;
419
+
420
+ case 'content':
421
+ // If Elementor is installed, try to render the page with it. If there is no Elementor content, fall back to normal rendering.
422
+ if ( class_exists( '\Elementor\Plugin' ) ) {
423
+ $elementor_content = \Elementor\Plugin::$instance->frontend->get_builder_content( $inserted_page->ID );
424
+ if ( strlen( $elementor_content ) > 0 ) {
425
+ echo $elementor_content;
426
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  }
428
+ }
429
 
430
+ // Render the content normally.
431
+ $content = get_post_field( 'post_content', $inserted_page->ID );
432
+ if ( $attributes['should_apply_the_content_filter'] ) {
433
+ $content = apply_filters( 'the_content', $content );
 
 
 
 
 
 
434
  }
435
+ echo $content;
436
+ break;
437
+
438
+ case 'post-thumbnail':
439
+ ?><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_post_thumbnail( $inserted_page->ID ); ?></a>
440
+ <?php
441
+ break;
442
+
443
+ case 'all':
444
+ // Title.
445
+ $title_tag = $attributes['inline'] ? 'span' : 'h1';
446
+ echo "<$title_tag class='insert-page-title'>";
447
+ echo get_the_title( $inserted_page->ID );
448
+ echo "</$title_tag>";
449
+ // Content.
450
+ $content = get_post_field( 'post_content', $inserted_page->ID );
451
+ if ( $attributes['should_apply_the_content_filter'] ) {
452
+ $content = apply_filters( 'the_content', $content );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  }
454
+ echo $content;
455
+ /**
456
+ * Meta.
457
+ *
458
+ * @see https://core.trac.wordpress.org/browser/tags/4.4/src/wp-includes/post-template.php#L968
459
+ */
460
+ $keys = get_post_custom_keys( $inserted_page->ID );
461
+ if ( $keys ) {
462
+ echo "<ul class='post-meta'>\n";
463
+ foreach ( (array) $keys as $key ) {
464
+ $keyt = trim( $key );
465
+ if ( is_protected_meta( $keyt, 'post' ) ) {
466
+ continue;
467
+ }
468
+ $value = get_post_custom_values( $key, $inserted_page->ID );
469
+ if ( is_array( $value ) ) {
470
+ $values = array_map( 'trim', $value );
471
+ $value = implode( $values, ', ' );
472
+ }
473
+
474
+ /**
475
+ * Filter the HTML output of the li element in the post custom fields list.
476
+ *
477
+ * @since 2.2.0
478
+ *
479
+ * @param string $html The HTML output for the li element.
480
+ * @param string $key Meta key.
481
+ * @param string $value Meta value.
482
+ */
483
+ echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value );
484
+ }
485
+ echo "</ul>\n";
486
+ }
487
+ break;
488
 
489
+ default: // Display is either invalid, or contains a template file to use.
490
+ /**
491
+ * Legacy/compatibility code: In order to use custom templates,
492
+ * we use query_posts() to provide the template with the global
493
+ * state it requires for the inserted page (in other words, all
494
+ * template tags will work with respect to the inserted page
495
+ * instead of the parent page / main loop). Note that this may
496
+ * cause some compatibility issues with other plugins.
497
+ *
498
+ * @see https://codex.wordpress.org/Function_Reference/query_posts
499
+ */
500
+ if ( is_numeric( $attributes['page'] ) ) {
501
+ $args = array(
502
+ 'p' => intval( $attributes['page'] ),
503
+ 'post_type' => get_post_types(),
504
+ );
505
+ } else {
506
+ $args = array(
507
+ 'name' => esc_attr( $attributes['page'] ),
508
+ 'post_type' => get_post_types(),
509
+ );
510
+ }
511
+ $inserted_page = query_posts( $args );
512
+ if ( have_posts() ) {
513
+ $template = locate_template( $attributes['display'] );
514
+ // Only allow templates that don't have any directory traversal in
515
+ // them (to prevent including php files that aren't in the active
516
+ // theme directory or the /wp-includes/theme-compat/ directory).
517
+ $path_in_theme_or_childtheme_or_compat = (
518
+ // Template is in current theme folder.
519
+ 0 === strpos( realpath( $template ), realpath( get_stylesheet_directory() ) ) ||
520
+ // Template is in current or parent theme folder.
521
+ 0 === strpos( realpath( $template ), realpath( get_template_directory() ) ) ||
522
+ // Template is in theme-compat folder.
523
+ 0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) )
524
+ );
525
+ if ( strlen( $template ) > 0 && $path_in_theme_or_childtheme_or_compat ) {
526
+ include $template; // Execute the template code.
527
+ } else { // Couldn't find template, so fall back to printing a link to the page.
528
+ the_post();
529
+ ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
530
+ <?php
531
+ }
532
+ }
533
+ wp_reset_query();
534
  }
535
 
536
  // Save output buffer contents.
537
  $content = ob_get_clean();
538
 
539
+ } else { // Use "Legacy" insert method (query_posts()).
 
540
 
541
  // Construct query_posts arguments.
542
  if ( is_numeric( $attributes['page'] ) ) {
552
  }
553
  $posts = query_posts( $args );
554
  if ( have_posts() ) {
555
+ // Start output buffering so we can save the output to string.
556
  ob_start();
557
 
558
+ // If Beaver Builder, SiteOrigin Page Builder, Elementor, or WPBakery
559
+ // Page Builder (Visual Composer) are enabled, load any cached styles
560
+ // associated with the inserted page.
561
  // Note: Temporarily set the global $post->ID to the inserted page ID,
562
  // since both builders rely on the id to load the appropriate styles.
563
+ if (
564
+ class_exists( 'FLBuilder' ) ||
565
+ class_exists( 'SiteOrigin_Panels' ) ||
566
+ class_exists( '\Elementor\Post_CSS_File' ) ||
567
+ defined( 'VCV_VERSION' )
568
+ ) {
569
  // If we're not in The Loop (i.e., global $post isn't assigned),
570
  // temporarily populate it with the post to be inserted so we can
571
  // retrieve generated styles for that post. Reset $post to null
592
  $css_file->enqueue();
593
  }
594
 
595
+ // Enqueue custom style from WPBakery Page Builder (Visual Composer).
596
+ if ( defined( 'VCV_VERSION' ) ) {
597
+ $bundle_url = get_post_meta( $inserted_page->ID, 'vcvSourceCssFileUrl', true );
598
+ if ( $bundle_url ) {
599
+ $version = get_post_meta( $inserted_page->ID, 'vcvSourceCssFileHash', true );
600
+ if ( ! preg_match( '/^http/', $bundle_url ) ) {
601
+ if ( ! preg_match( '/assets-bundles/', $bundle_url ) ) {
602
+ $bundle_url = '/assets-bundles/' . $bundle_url;
603
+ }
604
+ }
605
+ if ( preg_match( '/^http/', $bundle_url ) ) {
606
+ $bundle_url = set_url_scheme( $bundle_url );
607
+ } elseif ( defined( 'VCV_TF_ASSETS_IN_UPLOADS' ) && constant( 'VCV_TF_ASSETS_IN_UPLOADS' ) ) {
608
+ $upload_dir = wp_upload_dir();
609
+ $bundle_url = set_url_scheme( $upload_dir['baseurl'] . '/' . VCV_PLUGIN_ASSETS_DIRNAME . '/' . ltrim( $bundle_url, '/\\' ) );
610
+ } else {
611
+ $bundle_url = content_url() . '/' . VCV_PLUGIN_ASSETS_DIRNAME . '/' . ltrim( $bundle_url, '/\\' );
612
+ }
613
+ wp_enqueue_style(
614
+ 'vcv:assets:source:main:styles:' . sanitize_title( $bundle_url ),
615
+ $bundle_url,
616
+ array(),
617
+ VCV_VERSION . '.' . $version
618
+ );
619
+ }
620
+ }
621
+
622
  if ( is_null( $old_post_id ) ) {
623
  $post = null;
624
  } else {
626
  }
627
  }
628
 
629
+ /**
630
+ * Show either the title, link, content, everything, or everything via a
631
+ * custom template.
632
+ *
633
+ * Note: if the sharing_display filter exists, it means Jetpack is
634
+ * installed and Sharing is enabled; this plugin conflicts with Sharing,
635
+ * because Sharing assumes the_content and the_excerpt filters are only
636
+ * getting called once. The fix here is to disable processing of filters
637
+ * on the_content in the inserted page.
638
+ *
639
+ * @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
640
+ */
641
  switch ( $attributes['display'] ) {
642
+ case 'title':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  the_post();
644
+ $title_tag = $attributes['inline'] ? 'span' : 'h1';
645
+ echo "<$title_tag class='insert-page-title'>";
646
+ the_title();
647
+ echo "</$title_tag>";
648
+ break;
649
+ case 'link':
650
+ the_post();
651
+ ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
652
+ <?php
653
+ break;
654
+ case 'excerpt':
655
+ the_post();
656
+ ?><h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
657
+ <?php
658
+ if ( $attributes['should_apply_the_content_filter'] ) {
659
+ the_excerpt();
660
+ } else {
661
+ echo get_the_excerpt();
662
+ }
663
+ break;
664
+ case 'excerpt-only':
665
+ the_post();
666
+ if ( $attributes['should_apply_the_content_filter'] ) {
667
+ the_excerpt();
668
+ } else {
669
+ echo get_the_excerpt();
670
+ }
671
+ break;
672
+ case 'content':
673
+ the_post();
674
+ if ( $attributes['should_apply_the_content_filter'] ) {
675
+ the_content();
676
+ } else {
677
+ echo get_the_content();
678
+ }
679
+ break;
680
+ case 'post-thumbnail':
681
+ ?><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
682
+ <?php
683
+ break;
684
+ case 'all':
685
+ the_post();
686
+ $title_tag = $attributes['inline'] ? 'span' : 'h1';
687
+ echo "<$title_tag class='insert-page-title'>";
688
+ the_title();
689
+ echo "</$title_tag>";
690
+ if ( $attributes['should_apply_the_content_filter'] ) {
691
+ the_content();
692
+ } else {
693
+ echo get_the_content();
694
+ }
695
+ the_meta();
696
+ break;
697
+ default: // Display is either invalid, or contains a template file to use.
698
+ $template = locate_template( $attributes['display'] );
699
+ // Only allow templates that don't have any directory traversal in
700
+ // them (to prevent including php files that aren't in the active
701
+ // theme directory or the /wp-includes/theme-compat/ directory).
702
+ $path_in_theme_or_childtheme_or_compat = (
703
+ // Template is in current theme folder.
704
+ 0 === strpos( realpath( $template ), realpath( get_stylesheet_directory() ) ) ||
705
+ // Template is in current or parent theme folder.
706
+ 0 === strpos( realpath( $template ), realpath( get_template_directory() ) ) ||
707
+ // Template is in theme-compat folder.
708
+ 0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) )
709
+ );
710
+ if ( strlen( $template ) > 0 && $path_in_theme_or_childtheme_or_compat ) {
711
+ include $template; // Execute the template code.
712
+ } else { // Couldn't find template, so fall back to printing a link to the page.
713
+ the_post();
714
+ ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
715
+ <?php
716
+ }
717
+ break;
718
  }
719
  // Save output buffer contents.
720
  $content = ob_get_clean();
753
  return $content;
754
  }
755
 
756
+ /**
757
+ * Default filter for insert_pages_wrap_content.
758
+ *
759
+ * @param string $content Content of shortcode.
760
+ * @param array $posts Post data of inserted page.
761
+ * @param array $attributes Shortcode attributes.
762
+ * @return string Content to replace shortcode.
763
+ */
764
+ public function insert_pages_wrap_content( $content, $posts, $attributes ) {
765
  return "<{$attributes['wrapper_tag']} data-post-id='{$attributes['page']}' class='insert-page insert-page-{$attributes['page']} {$attributes['class']}'>{$content}</{$attributes['wrapper_tag']}>";
766
  }
767
 
768
+ /**
769
+ * Filter hook: Add a button to the TinyMCE toolbar for our insert page tool.
770
+ *
771
+ * @param array $buttons TinyMCE buttons.
772
+ * @return array TinyMCE buttons with Insert Pages button.
773
+ */
774
+ public function insert_pages_handle_filter_mce_buttons( $buttons ) {
775
+ if ( ! in_array( 'wpInsertPages_button', $buttons, true ) ) {
776
  array_push( $buttons, 'wpInsertPages_button' );
777
  }
778
  return $buttons;
779
  }
780
 
781
+ /**
782
+ * Filter hook: Load the javascript for our custom toolbar button.
783
+ *
784
+ * @param array $plugins TinyMCE plugins.
785
+ * @return array TinyMCE plugins with Insert Pages plugin.
786
+ */
787
+ public function insert_pages_handle_filter_mce_external_plugins( $plugins ) {
788
  if ( ! array_key_exists( 'wpInsertPages', $plugins ) ) {
789
  $plugins['wpInsertPages'] = plugins_url( '/js/wpinsertpages_plugin.js', __FILE__ );
790
  }
791
  return $plugins;
792
  }
793
 
794
+ /**
795
+ * Helper function to generate an excerpt (outside of the Loop) for a given
796
+ * ID (based on wp_trim_excerpt()).
797
+ *
798
+ * @param string $text Excerpt.
799
+ * @param integer $post_id Post ID of excerpt.
800
+ * @param boolean $apply_the_content_filter Whether to apply `the_content`.
801
+ * @return string Excerpt.
802
+ */
803
+ public function insert_pages_trim_excerpt( $text = '', $post_id = 0, $apply_the_content_filter = true ) {
804
  $post_id = intval( $post_id );
805
  if ( $post_id < 1 ) {
806
  return '';
807
  }
808
 
809
  $raw_excerpt = $text;
810
+ if ( '' === $text ) {
811
  $text = get_post_field( 'post_content', $post_id );
812
 
813
  $text = strip_shortcodes( $text );
826
  * @param int $number The number of words. Default 55.
827
  */
828
  $excerpt_length = apply_filters( 'excerpt_length', 55 );
829
+
830
  /**
831
  * Filter the string in the "more" link displayed after a trimmed excerpt.
832
  *
834
  *
835
  * @param string $more_string The string shown within the more link.
836
  */
837
+ $excerpt_more = apply_filters( 'excerpt_more', ' [&hellip;]' );
838
  $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
839
  }
840
  /**
854
  *
855
  * @since 3.1.0
856
  */
857
+ public function insert_pages_wp_tinymce_dialog() {
858
  // If wp_editor() is being called outside of an admin context,
859
  // required dependencies for Insert Pages will be missing (e.g.,
860
  // wp-admin/includes/template.php will not be loaded, admin_head
864
  return;
865
  }
866
 
 
 
867
  // Get ID of post currently being edited.
868
  $post_id = array_key_exists( 'post', $_REQUEST ) && intval( $_REQUEST['post'] ) > 0 ? intval( $_REQUEST['post'] ) : '';
869
 
870
+ // display: none is required here, see #WP27605.
871
  ?><div id="wp-insertpage-backdrop" style="display: none"></div>
872
+ <div id="wp-insertpage-wrap" class="wp-core-ui<?php
873
+ if ( 1 === intval( get_user_setting( 'wpinsertpage', 0 ) ) ) :
874
+ ?> options-panel-visible<?php
875
+ endif; ?>" style="display: none">
876
  <form id="wp-insertpage" tabindex="-1">
877
  <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
878
+ <input type="hidden" id="insertpage-parent-page-id" value="<?php echo esc_attr( $post_id ); ?>" />
879
  <div id="insertpage-modal-title">
880
+ <?php esc_html_e( 'Insert page', 'insert-pages' ); ?>
881
  <div id="wp-insertpage-close" tabindex="0"></div>
882
  </div>
883
  <div id="insertpage-selector">
884
  <div id="insertpage-search-panel">
885
  <div class="insertpage-search-wrapper">
886
  <label>
887
+ <span class="search-label"><?php esc_html_e( 'Search', 'insert-pages' ); ?></span>
888
  <input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" />
889
  <span class="spinner"></span>
890
  </label>
896
  </div>
897
  </div>
898
  <div id="insertpage-most-recent-results" class="query-results">
899
+ <div class="query-notice"><em><?php esc_html_e( 'No search term specified. Showing recent items.', 'insert-pages' ); ?></em></div>
900
  <ul></ul>
901
  <div class="river-waiting">
902
  <span class="spinner"></span>
903
  </div>
904
  </div>
905
  </div>
906
+ <p class="howto" id="insertpage-options-toggle"><?php esc_html_e( 'Options', 'insert-pages' ); ?></p>
907
  <div id="insertpage-options-panel">
908
  <div class="insertpage-options-wrapper">
909
  <label for="insertpage-slug-field">
910
+ <span><?php esc_html_e( 'Slug or ID', 'insert-pages' ); ?></span>
911
  <input id="insertpage-slug-field" type="text" autocomplete="off" />
912
+ <input id="insertpage-page-id" type="hidden" />
913
  </label>
914
  </div>
915
  <div class="insertpage-format">
916
  <label for="insertpage-format-select">
917
+ <?php esc_html_e( 'Display', 'insert-pages' ); ?>
918
  <select name="insertpage-format-select" id="insertpage-format-select">
919
+ <option value='title'><?php esc_html_e( 'Title', 'insert-pages' ); ?></option>
920
+ <option value='link'><?php esc_html_e( 'Link', 'insert-pages' ); ?></option>
921
+ <option value='excerpt'><?php esc_html_e( 'Excerpt with title', 'insert-pages' ); ?></option>
922
+ <option value='excerpt-only'><?php esc_html_e( 'Excerpt only (no title)', 'insert-pages' ); ?></option>
923
+ <option value='content'><?php esc_html_e( 'Content', 'insert-pages' ); ?></option>
924
+ <option value='post-thumbnail'><?php esc_html_e( 'Post Thumbnail', 'insert-pages' ); ?></option>
925
+ <option value='all'><?php esc_html_e( 'All (includes custom fields)', 'insert-pages' ); ?></option>
926
+ <option value='template'><?php esc_html_e( 'Use a custom template', 'insert-pages' ); ?> &raquo;</option>
927
  </select>
928
  <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
929
+ <option value='all'><?php esc_html_e( 'Default Template', 'insert-pages' ); ?></option>
930
  <?php page_template_dropdown(); ?>
931
  </select>
932
  </label>
933
  </div>
934
  <div class="insertpage-extra">
935
  <label for="insertpage-extra-classes">
936
+ <?php esc_html_e( 'Extra Classes', 'insert-pages' ); ?>
937
  <input id="insertpage-extra-classes" type="text" autocomplete="off" />
938
  </label>
939
  <label for="insertpage-extra-inline">
940
+ <?php esc_html_e( 'Inline?', 'insert-pages' ); ?>
941
  <input id="insertpage-extra-inline" type="checkbox" />
942
  </label>
943
  <label for="insertpage-extra-querystring">
944
+ <?php esc_html_e( 'Querystring', 'insert-pages' ); ?>
945
  <input id="insertpage-extra-querystring" type="text" autocomplete="off" />
946
  </label>
947
  </div>
952
  <input type="submit" value="<?php esc_attr_e( 'Insert Page', 'insert-pages' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit">
953
  </div>
954
  <div id="wp-insertpage-cancel">
955
+ <a class="submitdelete deletion" href="#"><?php esc_html_e( 'Cancel', 'insert-pages' ); ?></a>
956
  </div>
957
  </div>
958
  </form>
960
  <?php
961
  }
962
 
963
+ /**
964
+ * Modified from:
965
  * Internal linking functions.
966
  *
967
  * @package WordPress
968
  * @subpackage Administration
969
  * @since 3.1.0
970
  */
971
+ public function insert_pages_insert_page_callback() {
972
  check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
973
  $args = array();
974
  if ( isset( $_POST['search'] ) ) {
975
+ $args['s'] = wp_unslash( $_POST['search'] );
976
  }
977
+ $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
978
+ $args['pageID'] = ! empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0;
979
 
980
  // Change search to slug or post ID if we're not doing a plaintext
981
  // search (e.g., if we're editing an existing shortcode and the
982
  // search field is populated with the post's slug or ID).
983
+ if ( array_key_exists( 'type', $_POST ) && 'slug' === $_POST['type'] ) {
984
  $args['name'] = $args['s'];
985
  unset( $args['s'] );
986
+ } elseif ( array_key_exists( 'type', $_POST ) && 'post_id' === $_POST['type'] ) {
987
  $args['p'] = $args['s'];
988
  unset( $args['s'] );
989
  }
990
 
991
+ $results = $this->insert_pages_wp_query( $args );
992
 
993
  // Fail if our query didn't work.
994
  if ( ! isset( $results ) ) {
995
  die( '0' );
996
  }
997
 
998
+ echo wp_json_encode( $results );
999
  echo "\n";
1000
  die();
1001
  }
1002
 
1003
+ /**
1004
+ * Modified from:
1005
  * Performs post queries for internal linking.
1006
  *
1007
  * @since 3.1.0
1008
+ * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
1009
  * @return array Results.
1010
  */
1011
+ private function insert_pages_wp_query( $args = array() ) {
1012
  $pts = get_post_types( array( 'public' => true ), 'objects' );
1013
  $post_types = array_keys( $pts );
1014
 
1054
  }
1055
 
1056
  // Do main query.
1057
+ $get_posts = new WP_Query();
1058
  $posts = $get_posts->query( $query );
1059
  // Check if any posts were found.
1060
  if ( ! $get_posts->post_count ) {
1064
  // Build results.
1065
  $results = array();
1066
  foreach ( $posts as $post ) {
1067
+ if ( 'post' === $post->post_type ) {
1068
  $info = mysql2date( 'Y/m/d', $post->post_date );
1069
  } else {
1070
  $info = $pts[ $post->post_type ]->labels->singular_name;
1081
  return $results;
1082
  }
1083
 
1084
+ /**
1085
+ * Add Insert Page quicktag button to Text editor.
1086
+ *
1087
+ * @return void
1088
+ */
1089
+ public function insert_pages_add_quicktags() {
1090
  if ( wp_script_is( 'quicktags' ) ) : ?>
1091
  <script type="text/javascript">
1092
  QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|post-thumbnail|all']\n", '', '', 'Insert Page', 999 );
1093
  </script>
1094
+ <?php
1095
+ endif;
1096
+ }
1097
+
1098
+ /**
1099
+ * Indicates whether a particular post type is able to be inserted.
1100
+ *
1101
+ * @param boolean $type Post type.
1102
+ * @return boolean Whether post type is insertable.
1103
+ */
1104
+ private function is_post_type_insertable( $type ) {
1105
+ return ! in_array( $type, array( 'nav_menu_item', 'attachment', 'revision', 'customize_changeset', 'oembed_cache' ), true );
1106
+ }
1107
+
1108
+ /**
1109
+ * Registers the theme widget for inserting a page into an area.
1110
+ *
1111
+ * @return void
1112
+ */
1113
+ public function insert_pages_widgets_init() {
1114
+ register_widget( 'InsertPagesWidget' );
1115
  }
1116
 
1117
  }
1118
  }
1119
 
1120
+ // Initialize InsertPagesPlugin object.
1121
  if ( class_exists( 'InsertPagesPlugin' ) ) {
1122
+ $insert_pages_plugin = new InsertPagesPlugin();
1123
  }
1124
 
1125
+ // Actions and Filters handled by InsertPagesPlugin class.
1126
+ if ( isset( $insert_pages_plugin ) ) {
1127
  // Get options set in WordPress dashboard (Settings > Insert Pages).
1128
  $options = get_option( 'wpip_settings' );
1129
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
1130
  $options = wpip_set_defaults();
1131
  }
1132
 
1133
  // Register shortcode [insert ...].
1134
+ add_action( 'init', array( $insert_pages_plugin, 'insert_pages_init' ), 1 );
1135
  // Register shortcode [insert ...] when TinyMCE is included in a frontend ACF form.
1136
+ add_action( 'acf_head-input', array( $insert_pages_plugin, 'insert_pages_init' ), 1 ); // ACF 3.
1137
+ add_action( 'acf/input/admin_head', array( $insert_pages_plugin, 'insert_pages_init' ), 1 ); // ACF 4.
1138
 
1139
  // Add TinyMCE button for shortcode.
1140
+ add_action( 'admin_head', array( $insert_pages_plugin, 'insert_pages_admin_init' ), 1 );
1141
 
1142
  // Add quicktags button for shortcode.
1143
+ add_action( 'admin_print_footer_scripts', array( $insert_pages_plugin, 'insert_pages_add_quicktags' ) );
1144
 
1145
  // Preload TinyMCE popup.
1146
+ add_action( 'before_wp_tiny_mce', array( $insert_pages_plugin, 'insert_pages_wp_tinymce_dialog' ), 1 );
1147
 
1148
  // Ajax: Populate page search in TinyMCE button popup.
1149
+ add_action( 'wp_ajax_insertpage', array( $insert_pages_plugin, 'insert_pages_insert_page_callback' ) );
1150
 
1151
  // Use internal filter to wrap inserted content in a div or span.
1152
+ add_filter( 'insert_pages_wrap_content', array( $insert_pages_plugin, 'insert_pages_wrap_content' ), 10, 3 );
1153
+
1154
+ /**
1155
+ * Register TinyMCE plugin for the toolbar button if in compatibility mode.
1156
+ * (to work around a SiteOrigin PageBuilder bug).
1157
+ *
1158
+ * @see https://wordpress.org/support/topic/button-in-the-toolbar-of-tinymce-disappear-conflict-page-builder/
1159
+ */
1160
+ if ( 'compatibility' === $options['wpip_tinymce_filter'] ) {
1161
+ add_filter( 'mce_external_plugins', array( $insert_pages_plugin, 'insert_pages_handle_filter_mce_external_plugins' ) );
1162
+ add_filter( 'mce_buttons', array( $insert_pages_plugin, 'insert_pages_handle_filter_mce_buttons' ) );
1163
  }
1164
 
1165
  // Register Insert Pages shortcode widget.
1166
+ require_once dirname( __FILE__ ) . '/widget.php';
1167
+ add_action( 'widgets_init', array( $insert_pages_plugin, 'insert_pages_widgets_init' ) );
1168
  }
js/wpinsertpages.js CHANGED
@@ -21,8 +21,8 @@ var wpInsertPages;
21
  inputs.close = $( '#wp-insertpage-close' );
22
  // Page info
23
  inputs.slug = $( '#insertpage-slug-field' );
24
- inputs.pageID = $( '#insertpage-pageID' );
25
- inputs.parentPageID = $( '#insertpage-parent-pageID' );
26
  // Format field (title, link, content, all, choose a custom template ->)
27
  inputs.format = $( '#insertpage-format-select' );
28
  // Extra fields (wrapper classes, inline checkbox)
21
  inputs.close = $( '#wp-insertpage-close' );
22
  // Page info
23
  inputs.slug = $( '#insertpage-slug-field' );
24
+ inputs.pageID = $( '#insertpage-page-id' );
25
+ inputs.parentPageID = $( '#insertpage-parent-page-id' );
26
  // Format field (title, link, content, all, choose a custom template ->)
27
  inputs.format = $( '#insertpage-format-select' );
28
  // Extra fields (wrapper classes, inline checkbox)
options.php CHANGED
@@ -1,11 +1,25 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
 
 
3
  function wpip_add_admin_menu() {
4
  add_options_page( 'Insert Pages', 'Insert Pages', 'manage_options', 'insert_pages', 'wpip_options_page' );
5
  }
6
  add_action( 'admin_menu', 'wpip_add_admin_menu' );
7
 
8
-
 
 
 
 
9
  function wpip_settings_init() {
10
  register_setting( 'wpipSettings', 'wpip_settings' );
11
  add_settings_section(
@@ -45,10 +59,14 @@ function wpip_settings_init() {
45
  }
46
  add_action( 'admin_init', 'wpip_settings_init' );
47
 
48
-
 
 
 
 
49
  function wpip_set_defaults() {
50
  $options = get_option( 'wpip_settings' );
51
- if ( $options === FALSE ) {
52
  $options = array();
53
  }
54
 
@@ -74,12 +92,20 @@ function wpip_set_defaults() {
74
  }
75
  register_activation_hook( __FILE__, 'wpip_set_defaults' );
76
 
77
-
 
 
 
 
78
  function wpip_settings_section_callback() {
79
- echo __( 'You may override some default settings here.', 'insert-pages' );
80
  }
81
 
82
-
 
 
 
 
83
  function wpip_options_page() {
84
  ?>
85
  <form action='options.php' method='post'>
@@ -92,10 +118,14 @@ function wpip_options_page() {
92
  <?php
93
  }
94
 
95
-
 
 
 
 
96
  function wpip_format_render() {
97
  $options = get_option( 'wpip_settings' );
98
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) ) {
99
  $options = wpip_set_defaults();
100
  }
101
  ?>
@@ -105,10 +135,14 @@ function wpip_format_render() {
105
  <?php
106
  }
107
 
108
-
 
 
 
 
109
  function wpip_wrapper_render() {
110
  $options = get_option( 'wpip_settings' );
111
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_wrapper', $options ) ) {
112
  $options = wpip_set_defaults();
113
  }
114
  ?>
@@ -118,9 +152,14 @@ function wpip_wrapper_render() {
118
  <?php
119
  }
120
 
 
 
 
 
 
121
  function wpip_insert_method_render() {
122
  $options = get_option( 'wpip_settings' );
123
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_insert_method', $options ) ) {
124
  $options = wpip_set_defaults();
125
  }
126
  ?>
@@ -130,9 +169,14 @@ function wpip_insert_method_render() {
130
  <?php
131
  }
132
 
 
 
 
 
 
133
  function wpip_tinymce_filter_render() {
134
  $options = get_option( 'wpip_settings' );
135
- if ( $options === FALSE || ! is_array( $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
136
  $options = wpip_set_defaults();
137
  }
138
  ?>
1
  <?php
2
+ /**
3
+ * Render the Insert Pages Settings page.
4
+ *
5
+ * @package insert-pages
6
+ */
7
+
8
+ /**
9
+ * Add 'Insert Pages' to the Settings menu.
10
+ *
11
+ * @return void
12
+ */
13
  function wpip_add_admin_menu() {
14
  add_options_page( 'Insert Pages', 'Insert Pages', 'manage_options', 'insert_pages', 'wpip_options_page' );
15
  }
16
  add_action( 'admin_menu', 'wpip_add_admin_menu' );
17
 
18
+ /**
19
+ * Register settings fields.
20
+ *
21
+ * @return void
22
+ */
23
  function wpip_settings_init() {
24
  register_setting( 'wpipSettings', 'wpip_settings' );
25
  add_settings_section(
59
  }
60
  add_action( 'admin_init', 'wpip_settings_init' );
61
 
62
+ /**
63
+ * Set meaningful defaults for settings.
64
+ *
65
+ * @return array Insert Pages settings.
66
+ */
67
  function wpip_set_defaults() {
68
  $options = get_option( 'wpip_settings' );
69
+ if ( false === $options ) {
70
  $options = array();
71
  }
72
 
92
  }
93
  register_activation_hook( __FILE__, 'wpip_set_defaults' );
94
 
95
+ /**
96
+ * Print heading for Insert Pages settings page.
97
+ *
98
+ * @return void
99
+ */
100
  function wpip_settings_section_callback() {
101
+ esc_html_e( 'You may override some default settings here.', 'insert-pages' );
102
  }
103
 
104
+ /**
105
+ * Print Insert Pages settings page.
106
+ *
107
+ * @return void
108
+ */
109
  function wpip_options_page() {
110
  ?>
111
  <form action='options.php' method='post'>
118
  <?php
119
  }
120
 
121
+ /**
122
+ * Print 'Format' setting.
123
+ *
124
+ * @return void
125
+ */
126
  function wpip_format_render() {
127
  $options = get_option( 'wpip_settings' );
128
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) ) {
129
  $options = wpip_set_defaults();
130
  }
131
  ?>
135
  <?php
136
  }
137
 
138
+ /**
139
+ * Print 'Wrapper' setting.
140
+ *
141
+ * @return void
142
+ */
143
  function wpip_wrapper_render() {
144
  $options = get_option( 'wpip_settings' );
145
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_wrapper', $options ) ) {
146
  $options = wpip_set_defaults();
147
  }
148
  ?>
152
  <?php
153
  }
154
 
155
+ /**
156
+ * Print 'Insert Method' setting.
157
+ *
158
+ * @return void
159
+ */
160
  function wpip_insert_method_render() {
161
  $options = get_option( 'wpip_settings' );
162
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_insert_method', $options ) ) {
163
  $options = wpip_set_defaults();
164
  }
165
  ?>
169
  <?php
170
  }
171
 
172
+ /**
173
+ * Print 'TinyMCE Filter' setting.
174
+ *
175
+ * @return void
176
+ */
177
  function wpip_tinymce_filter_render() {
178
  $options = get_option( 'wpip_settings' );
179
+ if ( false === $options || ! is_array( $options ) || ! array_key_exists( 'wpip_tinymce_filter', $options ) ) {
180
  $options = wpip_set_defaults();
181
  }
182
  ?>
phpcs.xml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="WordPress">
3
+ <description>WordPress Coding Standards</description>
4
+
5
+ <!-- Use WordPress as a base -->
6
+ <rule ref="WordPress">
7
+ <exclude name="WordPress.Arrays.MultipleStatementAlignment" />
8
+ <exclude name="Generic.Formatting.MultipleStatementAlignment" />
9
+ <exclude name="WordPress.VIP.SlowDBQuery" />
10
+ <exclude name="WordPress.VIP.RestrictedFunctions" />
11
+
12
+ <!-- Allow opening and closing braces for functions and classes to be on the same line -->
13
+ <exclude name="Squiz.PHP.EmbeddedPhp.ContentAfterOpen"/>
14
+ <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine"/>
15
+ <exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/>
16
+ <exclude name="Squiz.WhiteSpace.ScopeClosingBrace"/>
17
+
18
+ <!-- Disable newline after opening brace -->
19
+ <exclude name="Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace"/>
20
+
21
+ <!-- Allow multiple PHP statements in the same line (usually in template files) -->
22
+ <exclude name="Generic.Formatting.DisallowMultipleStatements.SameLine"/>
23
+
24
+ <!-- Disable PSR-2 indentation rules that are buggy with 2 spaces -->
25
+ <exclude name="PSR2.ControlStructures.SwitchDeclaration.BreakIndent"/>
26
+ <exclude name="PSR2.Methods.FunctionCallSignature.Indent"/>
27
+
28
+ <!-- Disable picky rules. -->
29
+ <exclude name="WordPress.VIP.SuperGlobalInputUsage"/>
30
+ <exclude name="Squiz.PHP.EmbeddedPhp"/>
31
+ <exclude name="WordPress.VIP.DirectDatabaseQuery"/>
32
+ <exclude name="WordPress.Files.FileName"/>
33
+ <exclude name="WordPress.Variables.GlobalVariables"/>
34
+ <exclude name="WordPress.VIP.ValidatedSanitizedInput"/>
35
+ <exclude name="WordPress.WP.DiscouragedFunctions"/>
36
+ </rule>
37
+ </ruleset>
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: figureone, the_magician
3
  Tags: insert, pages, shortcode, embed
4
  Requires at least: 3.0.1
5
- Tested up to: 4.9
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -86,6 +86,11 @@ Just one! The plugin prevents you from embedding a page in itself, but you can t
86
 
87
  == Changelog ==
88
 
 
 
 
 
 
89
  = 3.3.0 =
90
  * Fix custom field values coming from parent post in certain contexts. Props @chrisneward for catching it!
91
  * Add post-thumbnail display to output just the featured image of a post. Props @pereztroff for the feature request.
2
  Contributors: figureone, the_magician
3
  Tags: insert, pages, shortcode, embed
4
  Requires at least: 3.0.1
5
+ Tested up to: 4.9.5
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
86
 
87
  == Changelog ==
88
 
89
+ = 3.4.0 =
90
+ * Add integration with WPBakery Page Builder (Visual Composer).
91
+ * Fix error messages about deprecated functions in PHP 7.2.
92
+ * Adhere to WordPress Coding Standards.
93
+
94
  = 3.3.0 =
95
  * Fix custom field values coming from parent post in certain contexts. Props @chrisneward for catching it!
96
  * Add post-thumbnail display to output just the featured image of a post. Props @pereztroff for the feature request.
widget.php CHANGED
@@ -1,10 +1,17 @@
1
  <?php
 
 
 
 
 
2
 
3
  /**
4
  * Class: InsertPagesWidget extends WP_Widget
 
5
  * Provides a widget for inserting a page into a widget area.
 
 
6
  */
7
-
8
  class InsertPagesWidget extends WP_Widget {
9
 
10
  /**
@@ -14,7 +21,7 @@ class InsertPagesWidget extends WP_Widget {
14
  // Load admin javascript for Widget options on admin page (widgets.php).
15
  add_action( 'sidebar_admin_page', array( $this, 'widget_admin_js' ) );
16
 
17
- // Load admin javascript for Widget options on theme customize page (customize.php)
18
  add_action( 'customize_controls_enqueue_scripts', array( $this, 'widget_admin_js' ) );
19
 
20
  // Call parent constructor to initialize the widget.
@@ -24,18 +31,18 @@ class InsertPagesWidget extends WP_Widget {
24
  /**
25
  * Load javascript for interacting with the Insert Page widget.
26
  */
27
- function widget_admin_js() {
28
  wp_enqueue_script( 'insertpages_widget', plugins_url( '/js/widget.js', __FILE__ ), array( 'jquery' ), '20160429' );
29
  }
30
 
31
  /**
32
  * Output the content of the widget.
33
  *
34
- * @param array $args
35
- * @param array $instance
36
  */
37
  public function widget( $args, $instance ) {
38
- global $insertPages_plugin;
39
 
40
  // Print widget wrapper.
41
  echo $args['before_widget'];
@@ -48,18 +55,18 @@ class InsertPagesWidget extends WP_Widget {
48
  if ( array_key_exists( 'display', $instance ) ) {
49
  $atts['display'] = $instance['display'];
50
  }
51
- if ( array_key_exists( 'template', $instance ) && $instance['display'] === 'template' ) {
52
  $atts['display'] = $instance['template'];
53
  }
54
  if ( array_key_exists( 'class', $instance ) ) {
55
  $atts['class'] = $instance['class'];
56
  }
57
  if ( array_key_exists( 'inline', $instance ) ) {
58
- $atts['inline'] = $instance['inline'] === '1';
59
  }
60
 
61
  // Render the inserted page using the plugin's shortcode handler.
62
- $content = $insertPages_plugin->insertPages_handleShortcode_insert( $atts );
63
 
64
  // Print inserted page.
65
  echo $content;
@@ -71,10 +78,10 @@ class InsertPagesWidget extends WP_Widget {
71
  /**
72
  * Output the options form on admin.
73
  *
74
- * @param array $instance The widget options
75
  */
76
  public function form( $instance ) {
77
- $instance = wp_parse_args( (array)$instance, array(
78
  'page' => '',
79
  'display' => 'link',
80
  'template' => '',
@@ -82,41 +89,44 @@ class InsertPagesWidget extends WP_Widget {
82
  'inline' => '',
83
  )); ?>
84
  <p>
85
- <label for="<?php echo $this->get_field_id( 'page' ); ?>"><?php _e( 'Page/Post ID or Slug', 'insert-pages' ); ?>:</label>
86
- <input type="text" class="widefat" id="<?php echo $this->get_field_id( 'page' ); ?>" name="<?php echo $this->get_field_name( 'page' ); ?>" value="<?php echo $instance['page']; ?>" />
87
  </p>
88
  <p>
89
- <label for="<?php echo $this->get_field_id( 'display' ); ?>"><?php _e( 'Display', 'insert-pages' ); ?>:</label><br />
90
- <select class="insertpage-format-select" name="<?php echo $this->get_field_name( 'display' ); ?>" id="<?php echo $this->get_field_id( 'display' ); ?>">
91
- <option value='title' <?php selected( $instance['display'], 'title' ); ?>><?php _e( 'Title', 'insert-pages' ); ?></option>
92
- <option value='link' <?php selected( $instance['display'], 'link' ); ?>><?php _e( 'Link', 'insert-pages' ); ?></option>
93
- <option value='excerpt' <?php selected( $instance['display'], 'excerpt' ); ?>><?php _e( 'Excerpt', 'insert-pages' ); ?></option>
94
- <option value='excerpt-only' <?php selected( $instance['display'], 'excerpt-only' ); ?>><?php _e( 'Excerpt only (no title)', 'insert-pages' ); ?></option>
95
- <option value='content' <?php selected( $instance['display'], 'content' ); ?>><?php _e( 'Content', 'insert-pages' ); ?></option>
96
- <option value='post-thumbnail' <?php selected( $instance['display'], 'post-thumbnail' ); ?>><?php _e( 'Post Thumbnail', 'insert-pages' ); ?></option>
97
- <option value='all' <?php selected( $instance['display'], 'all' ); ?>><?php _e( 'All (includes custom fields)', 'insert-pages' ); ?></option>
98
- <option value='template' <?php selected( $instance['display'], 'template' ); ?>><?php _e( 'Use a custom template', 'insert-pages' ); ?> &raquo;</option>
99
  </select>
100
- <select class="insertpage-template-select" name="<?php echo $this->get_field_name( 'template' ); ?>" id="<?php echo $this->get_field_id( 'template' ); ?>" disabled="disabled">
101
- <option value='all'><?php _e( 'Default Template', 'insert-pages' ); ?></option>
102
- <?php if ( function_exists( 'page_template_dropdown' ) ) page_template_dropdown( $instance['template'] ); ?>
 
 
103
  </select>
104
  </p>
105
  <p>
106
- <label for="<?php echo $this->get_field_id( 'class' ); ?>"><?php _e( 'Extra Classes', 'insert-pages' ); ?>:</label>
107
- <input type="text" class="widefat" autocomplete="off" name="<?php echo $this->get_field_name( 'class' ); ?>" id="<?php echo $this->get_field_id( 'class' ); ?>" value="<?php echo esc_attr( $instance['class'] ); ?>" />
108
  </p>
109
  <p>
110
- <input class="checkbox" type="checkbox" name="<?php echo $this->get_field_name( 'inline' ); ?>" id="<?php echo $this->get_field_id( 'inline' ); ?>" value="1" <?php checked( $instance['inline'], '1' ); ?> />
111
- <label for="<?php echo $this->get_field_id( 'inline' ); ?>"><?php _e( 'Inline?', 'insert-pages' ); ?></label>
112
- </p><?php
 
113
  }
114
 
115
  /**
116
  * Process widget options on save.
117
  *
118
- * @param array $new_instance The new options
119
- * @param array $old_instance The previous options
120
  */
121
  public function update( $new_instance, $old_instance ) {
122
  // Sanitize form options.
1
  <?php
2
+ /**
3
+ * Insert Pages widget.
4
+ *
5
+ * @package insert-pages
6
+ */
7
 
8
  /**
9
  * Class: InsertPagesWidget extends WP_Widget
10
+ *
11
  * Provides a widget for inserting a page into a widget area.
12
+ *
13
+ * @package insert-pages
14
  */
 
15
  class InsertPagesWidget extends WP_Widget {
16
 
17
  /**
21
  // Load admin javascript for Widget options on admin page (widgets.php).
22
  add_action( 'sidebar_admin_page', array( $this, 'widget_admin_js' ) );
23
 
24
+ // Load admin javascript for Widget options on theme customize page (customize.php).
25
  add_action( 'customize_controls_enqueue_scripts', array( $this, 'widget_admin_js' ) );
26
 
27
  // Call parent constructor to initialize the widget.
31
  /**
32
  * Load javascript for interacting with the Insert Page widget.
33
  */
34
+ public function widget_admin_js() {
35
  wp_enqueue_script( 'insertpages_widget', plugins_url( '/js/widget.js', __FILE__ ), array( 'jquery' ), '20160429' );
36
  }
37
 
38
  /**
39
  * Output the content of the widget.
40
  *
41
+ * @param array $args Widget args.
42
+ * @param array $instance Widget instance.
43
  */
44
  public function widget( $args, $instance ) {
45
+ global $insert_pages_plugin;
46
 
47
  // Print widget wrapper.
48
  echo $args['before_widget'];
55
  if ( array_key_exists( 'display', $instance ) ) {
56
  $atts['display'] = $instance['display'];
57
  }
58
+ if ( array_key_exists( 'template', $instance ) && 'template' === $instance['display'] ) {
59
  $atts['display'] = $instance['template'];
60
  }
61
  if ( array_key_exists( 'class', $instance ) ) {
62
  $atts['class'] = $instance['class'];
63
  }
64
  if ( array_key_exists( 'inline', $instance ) ) {
65
+ $atts['inline'] = '1' === $instance['inline'];
66
  }
67
 
68
  // Render the inserted page using the plugin's shortcode handler.
69
+ $content = $insert_pages_plugin->insert_pages_handle_shortcode_insert( $atts );
70
 
71
  // Print inserted page.
72
  echo $content;
78
  /**
79
  * Output the options form on admin.
80
  *
81
+ * @param array $instance The widget options.
82
  */
83
  public function form( $instance ) {
84
+ $instance = wp_parse_args( (array) $instance, array(
85
  'page' => '',
86
  'display' => 'link',
87
  'template' => '',
89
  'inline' => '',
90
  )); ?>
91
  <p>
92
+ <label for="<?php echo esc_attr( $this->get_field_id( 'page' ) ); ?>"><?php esc_html_e( 'Page/Post ID or Slug', 'insert-pages' ); ?>:</label>
93
+ <input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'page' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'page' ) ); ?>" value="<?php echo esc_attr( $instance['page'] ); ?>" />
94
  </p>
95
  <p>
96
+ <label for="<?php echo esc_attr( $this->get_field_id( 'display' ) ); ?>"><?php esc_html_e( 'Display', 'insert-pages' ); ?>:</label><br />
97
+ <select class="insertpage-format-select" name="<?php echo esc_attr( $this->get_field_name( 'display' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'display' ) ); ?>">
98
+ <option value='title' <?php selected( $instance['display'], 'title' ); ?>><?php esc_html_e( 'Title', 'insert-pages' ); ?></option>
99
+ <option value='link' <?php selected( $instance['display'], 'link' ); ?>><?php esc_html_e( 'Link', 'insert-pages' ); ?></option>
100
+ <option value='excerpt' <?php selected( $instance['display'], 'excerpt' ); ?>><?php esc_html_e( 'Excerpt', 'insert-pages' ); ?></option>
101
+ <option value='excerpt-only' <?php selected( $instance['display'], 'excerpt-only' ); ?>><?php esc_html_e( 'Excerpt only (no title)', 'insert-pages' ); ?></option>
102
+ <option value='content' <?php selected( $instance['display'], 'content' ); ?>><?php esc_html_e( 'Content', 'insert-pages' ); ?></option>
103
+ <option value='post-thumbnail' <?php selected( $instance['display'], 'post-thumbnail' ); ?>><?php esc_html_e( 'Post Thumbnail', 'insert-pages' ); ?></option>
104
+ <option value='all' <?php selected( $instance['display'], 'all' ); ?>><?php esc_html_e( 'All (includes custom fields)', 'insert-pages' ); ?></option>
105
+ <option value='template' <?php selected( $instance['display'], 'template' ); ?>><?php esc_html_e( 'Use a custom template', 'insert-pages' ); ?> &raquo;</option>
106
  </select>
107
+ <select class="insertpage-template-select" name="<?php echo esc_attr( $this->get_field_name( 'template' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'template' ) ); ?>" disabled="disabled">
108
+ <option value='all'><?php esc_html_e( 'Default Template', 'insert-pages' ); ?></option>
109
+ <?php if ( function_exists( 'page_template_dropdown' ) ) :
110
+ page_template_dropdown( $instance['template'] );
111
+ endif; ?>
112
  </select>
113
  </p>
114
  <p>
115
+ <label for="<?php echo esc_attr( $this->get_field_id( 'class' ) ); ?>"><?php esc_html_e( 'Extra Classes', 'insert-pages' ); ?>:</label>
116
+ <input type="text" class="widefat" autocomplete="off" name="<?php echo esc_attr( $this->get_field_name( 'class' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'class' ) ); ?>" value="<?php echo esc_attr( $instance['class'] ); ?>" />
117
  </p>
118
  <p>
119
+ <input class="checkbox" type="checkbox" name="<?php echo esc_attr( $this->get_field_name( 'inline' ) ); ?>" id="<?php echo esc_attr( $this->get_field_id( 'inline' ) ); ?>" value="1" <?php checked( $instance['inline'], '1' ); ?> />
120
+ <label for="<?php echo esc_attr( $this->get_field_id( 'inline' ) ); ?>"><?php esc_html_e( 'Inline?', 'insert-pages' ); ?></label>
121
+ </p>
122
+ <?php
123
  }
124
 
125
  /**
126
  * Process widget options on save.
127
  *
128
+ * @param array $new_instance The new options.
129
+ * @param array $old_instance The previous options.
130
  */
131
  public function update( $new_instance, $old_instance ) {
132
  // Sanitize form options.