PluginProbe
Insert Pages / 2.8
Insert Pages v2.8
3.11.5 trunk 1.4 2.4 2.5 2.6 2.7 2.7.1 2.7.2 2.8 2.9 2.9.1 3.0 3.0.1 3.0.2 3.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 All 79 releases
insert-pages / insert-pages.php

insert-pages.php in Insert Pages 2.8, at insert-pages.php

535 lines 18.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 Plugin Name: Insert Pages
5 Plugin URI: https://bitbucket.org/figureone/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 Version: 2.8
9 Author URI: http://www.linkedin.com/in/paulrryan
10 License: GPL2
11 */
12
13 /* Copyright 2011 Paul Ryan (email: prar@hawaii.edu)
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, version 2, as
17 published by the Free Software Foundation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29 /* Shortcode Format:
30 [insert page='{slug}|{id}' display='title|link|excerpt|excerpt-only|content|all|{custom-template.php}' class='any-classes']
31 */
32
33 // Define the InsertPagesPlugin class (variables and functions)
34 if ( !class_exists( 'InsertPagesPlugin' ) ) {
35 class InsertPagesPlugin {
36 // Save the id of the page being edited
37 protected $pageID;
38
39 // Constructor
40 public function InsertPagesPlugin() {
41 // Include the code that generates the options page.
42 require_once( dirname( __FILE__ ) . '/options.php' );
43 }
44
45 // Getter/Setter for pageID
46 function getPageID() {
47 return $this->pageID;
48 }
49 function setPageID( $id ) {
50 return $this->pageID = $id;
51 }
52
53 // Action hook: Wordpress 'init'
54 function insertPages_init() {
55 add_shortcode( 'insert', array( $this, 'insertPages_handleShortcode_insert' ) );
56 }
57
58 // Action hook: Wordpress 'admin_init'
59 function insertPages_admin_init() {
60 // Get options set in WordPress dashboard (Settings > Insert Pages).
61 $options = get_option( 'wpip_settings' );
62 if ( $options === FALSE ) {
63 $options = wpip_set_defaults();
64 }
65
66 // Add TinyMCE toolbar button filters only if current user has permissions
67 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && get_user_option( 'rich_editing' )=='true' ) {
68
69 // Register the TinyMCE toolbar button script
70 wp_enqueue_script(
71 'wpinsertpages',
72 plugins_url( '/js/wpinsertpages.js', __FILE__ ),
73 array( 'wpdialogs' ),
74 '20151022'
75 );
76 wp_localize_script(
77 'wpinsertpages',
78 'wpInsertPagesL10n',
79 array(
80 'update' => __( 'Update' ),
81 'save' => __( 'Insert Page' ),
82 'noTitle' => __( '(no title)' ),
83 'noMatchesFound' => __( 'No matches found.' ),
84 'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};',
85 'format' => $options['wpip_format'],
86 )
87 );
88
89 // Register the TinyMCE toolbar button styles
90 wp_enqueue_style(
91 'wpinsertpagescss',
92 plugins_url( '/css/wpinsertpages.css', __FILE__ ),
93 array( 'wp-jquery-ui-dialog' ),
94 '20151022'
95 );
96
97 add_filter( 'mce_external_plugins', array( $this, 'insertPages_handleFilter_mceExternalPlugins' ) );
98 add_filter( 'mce_buttons', array( $this, 'insertPages_handleFilter_mceButtons' ) );
99
100 //load_plugin_textdomain('insert-pages', false, dirname(plugin_basename(__FILE__)).'/languages/');
101 }
102
103 }
104
105
106 // Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content
107 function insertPages_handleShortcode_insert( $atts, $content = null ) {
108 global $wp_query, $post, $wp_current_filter;
109 extract( shortcode_atts( array(
110 'page' => '0',
111 'display' => 'all',
112 'class' => '',
113 'inline' => false,
114 ), $atts ) );
115
116 // Get options set in WordPress dashboard (Settings > Insert Pages).
117 $options = get_option( 'wpip_settings' );
118 if ( $options === FALSE ) {
119 $options = wpip_set_defaults();
120 }
121
122 // Validation checks.
123 if ( $page === '0' ) {
124 return $content;
125 }
126
127 // Trying to embed same page in itself.
128 if ( $page == $post->ID || $page == $post->post_name ) {
129 return $content;
130 }
131
132 $should_apply_nesting_check = true;
133 /**
134 * Filter the flag indicating whether to apply deep nesting check
135 * that can prevent circular loops. Note that some use cases rely
136 * on inserting pages that themselves have inserted pages, so this
137 * check should be disabled for those individuals.
138 *
139 * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
140 */
141 $should_apply_nesting_check = apply_filters( 'insert_pages_apply_nesting_check', $should_apply_nesting_check );
142
143 // Don't allow inserted pages to be added to the_content more than once (prevent infinite loops).
144 if ( $should_apply_nesting_check ) {
145 $done = false;
146 foreach ( $wp_current_filter as $filter ) {
147 if ( 'the_content' == $filter ) {
148 if ( $done ) {
149 return $content;
150 } else {
151 $done = true;
152 }
153 }
154 }
155 }
156
157 // Convert slugs to page IDs to standardize query_posts() lookup below.
158 if ( ! is_numeric( $page ) ) {
159 $page_object = get_page_by_path( $page, OBJECT, get_post_types() );
160 $page = $page_object ? $page_object->ID : $page;
161 }
162
163 if ( is_numeric( $page ) ) {
164 $args = array(
165 'p' => intval( $page ),
166 'post_type' => get_post_types(),
167 );
168 } else {
169 $args = array(
170 'name' => esc_attr( $page ),
171 'post_type' => get_post_types(),
172 );
173 }
174
175 query_posts( $args );
176
177 $should_apply_the_content_filter = true;
178 /**
179 * Filter the flag indicating whether to apply the_content filter to post
180 * contents and excerpts that are being inserted.
181 *
182 * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
183 */
184 $should_apply_the_content_filter = apply_filters( 'insert_pages_apply_the_content_filter', $should_apply_the_content_filter );
185
186 $should_use_inline_wrapper = ( $inline !== false && $inline !== 'false' ) || array_search( 'inline', $atts ) === 0 || ( array_key_exists( 'wpip_wrapper', $options ) && $options['wpip_wrapper'] === 'inline' );
187 /**
188 * Filter the flag indicating whether to wrap the inserted content in inline tags (span).
189 *
190 * @param bool $use_inline_wrapper Indicates whether to wrap the content in span tags.
191 */
192 $should_use_inline_wrapper = apply_filters( 'insert_pages_use_inline_wrapper', $should_use_inline_wrapper );
193
194 // Disable the_content filter if using inline tags, since wpautop
195 // inserts p tags and we can't have any inside inline elements.
196 if ( $should_use_inline_wrapper ) {
197 $should_apply_the_content_filter = false;
198 }
199
200 // Start our new Loop (only iterate once).
201 if ( have_posts() ) {
202 ob_start(); // Start output buffering so we can save the output to string
203
204 // If Beaver Builder plugin is enabled, load any cached styles associated with the inserted page.
205 // Note: Temporarily set the global $post->ID to the inserted page ID,
206 // since Beaver Builder relies on it to load the appropraite styles.
207 if ( class_exists( 'FLBuilder' ) ) {
208 $old_post_id = $post->ID;
209 $post->ID = $page;
210 FLBuilder::enqueue_layout_styles_scripts( $page );
211 $post->ID = $old_post_id;
212 }
213
214 // Show either the title, link, content, everything, or everything via a custom template
215 // Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled;
216 // This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters
217 // are only getting called once. The fix here is to disable processing of filters on the_content in
218 // the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
219 switch ( $display ) {
220 case "title":
221 the_post();
222 $title_tag = $should_use_inline_wrapper ? 'span' : 'h1';
223 echo "<$title_tag class='insert-page-title'>";
224 the_title();
225 echo "</$title_tag>";
226 break;
227 case "link":
228 the_post();
229 ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
230 break;
231 case "excerpt":
232 the_post();
233 ?><h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1><?php
234 if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt();
235 break;
236 case "excerpt-only":
237 the_post();
238 if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt();
239 break;
240 case "content":
241 the_post();
242 if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content();
243 break;
244 case "all":
245 the_post();
246 $title_tag = $should_use_inline_wrapper ? 'span' : 'h1';
247 echo "<$title_tag class='insert-page-title'>";
248 the_title();
249 echo "</$title_tag>";
250 if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content();
251 the_meta();
252 break;
253 default: // display is either invalid, or contains a template file to use
254 $template = locate_template( $display );
255 if ( strlen( $template ) > 0 ) {
256 include $template; // execute the template code
257 } else { // Couldn't find template, so fall back to printing a link to the page.
258 the_post();
259 ?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
260 }
261 break;
262 }
263
264 $content = ob_get_contents(); // Save off output buffer
265 ob_end_clean(); // End output buffering
266 } else {
267 /**
268 * Filter the html that should be displayed if an inserted page was not found.
269 *
270 * @param string $content html to be displayed. Defaults to an empty string.
271 */
272 $content = apply_filters( 'insert_pages_not_found_message', $content );
273 }
274
275 wp_reset_query();
276
277 $wrapper_tag = $should_use_inline_wrapper ? 'span' : 'div';
278 $content = "<$wrapper_tag data-post-id='$page' class='insert-page insert-page-$page $class'>$content</$wrapper_tag>";
279 return $content;
280 //return do_shortcode($content); // careful: watch for infinite loops with nested inserts
281 }
282
283
284 // Filter hook: Add a button to the TinyMCE toolbar for our insert page tool
285 function insertPages_handleFilter_mceButtons( $buttons ) {
286 array_push( $buttons, 'wpInsertPages_button' ); // add a separator and button to toolbar
287 return $buttons;
288 }
289
290 // Filter hook: Load the javascript for our custom toolbar button
291 function insertPages_handleFilter_mceExternalPlugins( $plugins ) {
292 $plugins['wpInsertPages'] = plugins_url( '/js/wpinsertpages_plugin.js', __FILE__ );
293 return $plugins;
294 }
295
296 /**
297 * Modified from /wp-admin/includes/internal-linking.php, function wp_link_dialog()
298 * Dialog for internal linking.
299 *
300 * @since 3.1.0
301 */
302 function insertPages_wp_tinymce_dialog() {
303 // If wp_editor() is being called outside of an admin context,
304 // required dependencies for Insert Pages will be missing (e.g.,
305 // wp-admin/includes/template.php will not be loaded, admin_head
306 // action will not be fired). If that's the case, just skip loading
307 // the Insert Pages tinymce button.
308 if ( ! is_admin() || ! function_exists( 'page_template_dropdown' ) ) {
309 return;
310 }
311
312 $options_panel_visible = '1' == get_user_setting( 'wpinsertpage', '0' ) ? ' options-panel-visible' : '';
313
314 // Get ID of post currently being edited.
315 $post_id = array_key_exists( 'post', $_REQUEST ) && intval( $_REQUEST['post'] ) > 0 ? intval( $_REQUEST['post'] ) : '';
316
317 // display: none is required here, see #WP27605
318 ?><div id="wp-insertpage-backdrop" style="display: none"></div>
319 <div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $options_panel_visible; ?>" style="display: none">
320 <form id="wp-insertpage" tabindex="-1">
321 <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
322 <input type="hidden" id="insertpage-parent-pageID" value="<?php echo $post_id; ?>" />
323 <div id="insertpage-modal-title">
324 <?php _e( 'Insert page' ) ?>
325 <div id="wp-insertpage-close" tabindex="0"></div>
326 </div>
327 <div id="insertpage-selector">
328 <div id="insertpage-search-panel">
329 <div class="insertpage-search-wrapper">
330 <label>
331 <span class="search-label"><?php _e( 'Search' ); ?></span>
332 <input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" />
333 <span class="spinner"></span>
334 </label>
335 </div>
336 <div id="insertpage-search-results" class="query-results">
337 <ul></ul>
338 <div class="river-waiting">
339 <span class="spinner"></span>
340 </div>
341 </div>
342 <div id="insertpage-most-recent-results" class="query-results">
343 <div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div>
344 <ul></ul>
345 <div class="river-waiting">
346 <span class="spinner"></span>
347 </div>
348 </div>
349 </div>
350 <p class="howto" id="insertpage-options-toggle"><?php _e( 'Options' ); ?></p>
351 <div id="insertpage-options-panel">
352 <div class="insertpage-options-wrapper">
353 <label for="insertpage-slug-field">
354 <span><?php _e( 'Slug or ID' ); ?></span>
355 <input id="insertpage-slug-field" type="text" tabindex="10" autocomplete="off" />
356 <input id="insertpage-pageID" type="hidden" />
357 </label>
358 </div>
359 <div class="insertpage-format">
360 <label for="insertpage-format-select">
361 <?php _e( 'Display' ); ?>
362 <select name="insertpage-format-select" id="insertpage-format-select">
363 <option value='title'>Title</option>
364 <option value='link'>Link</option>
365 <option value='excerpt'>Excerpt</option>
366 <option value='excerpt-only'>Excerpt only (no title)</option>
367 <option value='content'>Content</option>
368 <option value='all'>All (includes custom fields)</option>
369 <option value='template'>Use a custom template &raquo;</option>
370 </select>
371 <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
372 <option value='all'><?php _e( 'Default Template' ); ?></option>
373 <?php page_template_dropdown(); ?>
374 </select>
375 </label>
376 </div>
377 </div>
378 </div>
379 <div class="submitbox">
380 <div id="wp-insertpage-update">
381 <input type="submit" value="<?php esc_attr_e( 'Insert Page' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit">
382 </div>
383 <div id="wp-insertpage-cancel">
384 <a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
385 </div>
386 </div>
387 </form>
388 </div>
389 <?php
390 }
391
392 /** Modified from:
393 * Internal linking functions.
394 *
395 * @package WordPress
396 * @subpackage Administration
397 * @since 3.1.0
398 */
399 function insertPages_insert_page_callback() {
400 check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
401 $args = array();
402 if ( isset( $_POST['search'] ) ) {
403 $args['s'] = stripslashes( $_POST['search'] );
404 }
405 $args['pagenum'] = !empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
406 $args['pageID'] = !empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0;
407
408 // Change search to slug or post ID if we're not doing a plaintext
409 // search (e.g., if we're editing an existing shortcode and the
410 // search field is populated with the post's slug or ID).
411 if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'slug' ) {
412 $args['name'] = $args['s'];
413 unset( $args['s'] );
414 } else if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'post_id' ) {
415 $args['p'] = $args['s'];
416 unset( $args['s'] );
417 }
418
419 $results = $this->insertPages_wp_query( $args );
420
421 // Fail if our query didn't work.
422 if ( ! isset( $results ) ) {
423 die( '0' );
424 }
425
426 echo json_encode( $results );
427 echo "\n";
428 die();
429 }
430
431 /** Modified from:
432 * Performs post queries for internal linking.
433 *
434 * @since 3.1.0
435 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
436 * @return array Results.
437 */
438 function insertPages_wp_query( $args = array() ) {
439 $pts = get_post_types( array( 'public' => true ), 'objects' );
440 $post_types = array_keys( $pts );
441
442 /**
443 * Filter the post types that appear in the list of pages to insert.
444 *
445 * By default, all post types will apear.
446 *
447 * @since 2.0
448 *
449 * @param array $post_types Array of post type names to include.
450 */
451 $post_types = apply_filters( 'insert_pages_available_post_types', $post_types );
452
453 $query = array(
454 'post_type' => $post_types,
455 'suppress_filters' => true,
456 'update_post_term_cache' => false,
457 'update_post_meta_cache' => false,
458 'post_status' => 'publish',
459 'order' => 'DESC',
460 'orderby' => 'post_date',
461 'posts_per_page' => 20,
462 'post__not_in' => array( $args['pageID'] ),
463 );
464
465 $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
466 $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
467
468 // Search post content and post title.
469 if ( isset( $args['s'] ) ) {
470 $query['s'] = $args['s'];
471 }
472
473 // Search post_name (post slugs).
474 if ( isset( $args['name'] ) ) {
475 $query['name'] = $args['name'];
476 }
477
478 // Search post ids.
479 if ( isset( $args['p'] ) ) {
480 $query['p'] = $args['p'];
481 }
482
483 // Do main query.
484 $get_posts = new WP_Query;
485 $posts = $get_posts->query( $query );
486 // Check if any posts were found.
487 if ( ! $get_posts->post_count ) {
488 return false;
489 }
490
491 // Build results.
492 $results = array();
493 foreach ( $posts as $post ) {
494 if ( 'post' == $post->post_type ) {
495 $info = mysql2date( __( 'Y/m/d' ), $post->post_date );
496 } else {
497 $info = $pts[ $post->post_type ]->labels->singular_name;
498 }
499 $results[] = array(
500 'ID' => $post->ID,
501 'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
502 'permalink' => get_permalink( $post->ID ),
503 'slug' => $post->post_name,
504 'info' => $info,
505 );
506 }
507 return $results;
508 }
509
510 function insertPages_add_quicktags() {
511 if ( wp_script_is( 'quicktags' ) ) : ?>
512 <script type="text/javascript">
513 QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|all']\n", '', '', 'Insert Page', 999 );
514 </script>
515 <?php endif;
516 }
517
518 }
519 }
520
521 // Initialize InsertPagesPlugin object
522 if ( class_exists( 'InsertPagesPlugin' ) ) {
523 $insertPages_plugin = new InsertPagesPlugin();
524 }
525
526 // Actions and Filters handled by InsertPagesPlugin class
527 if ( isset( $insertPages_plugin ) ) {
528 // Actions
529 add_action( 'init', array( $insertPages_plugin, 'insertPages_init' ), 1 ); // Register Shortcodes here
530 add_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 ); // Add TinyMCE buttons here
531 add_action( 'before_wp_tiny_mce', array( $insertPages_plugin, 'insertPages_wp_tinymce_dialog' ), 1 ); // Preload TinyMCE popup
532 add_action( 'wp_ajax_insertpage', array( $insertPages_plugin, 'insertPages_insert_page_callback' ) ); // Populate page search in TinyMCE button popup in this ajax call
533 add_action( 'admin_print_footer_scripts', array( $insertPages_plugin, 'insertPages_add_quicktags' ) );
534 }
535