PluginProbe
Insert Pages / 2.7
Insert Pages v2.7
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.7, at insert-pages.php

456 lines 15.8 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.7
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 //$this->pageID = '1'; echo $_GET['post'];
42 }
43
44 // Getter/Setter for pageID
45 function getPageID() {
46 return $this->pageID;
47 }
48 function setPageID( $id ) {
49 return $this->pageID = $id;
50 }
51
52 // Action hook: Wordpress 'init'
53 function insertPages_init() {
54 add_shortcode( 'insert', array( $this, 'insertPages_handleShortcode_insert' ) );
55 }
56
57 // Action hook: Wordpress 'admin_init'
58 function insertPages_admin_init() {
59 // Add TinyMCE toolbar button filters only if current user has permissions
60 if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) && get_user_option( 'rich_editing' )=='true' ) {
61
62 // Register the TinyMCE toolbar button script
63 wp_enqueue_script(
64 'wpinsertpages',
65 plugins_url( '/js/wpinsertpages.js', __FILE__ ),
66 array( 'wpdialogs' ),
67 '20140819'
68 );
69 wp_localize_script(
70 'wpinsertpages',
71 'wpInsertPagesL10n',
72 array(
73 'update' => __( 'Update' ),
74 'save' => __( 'Insert Page' ),
75 'noTitle' => __( '(no title)' ),
76 'noMatchesFound' => __( 'No matches found.' ),
77 'l10n_print_after' => 'try{convertEntities(wpLinkL10n);}catch(e){};',
78 )
79 );
80
81 // Register the TinyMCE toolbar button styles
82 wp_enqueue_style(
83 'wpinsertpagescss',
84 plugins_url( '/css/wpinsertpages.css', __FILE__ ),
85 array( 'wp-jquery-ui-dialog' ),
86 '20140819'
87 );
88
89 add_filter( 'mce_external_plugins', array( $this, 'insertPages_handleFilter_mceExternalPlugins' ) );
90 add_filter( 'mce_buttons', array( $this, 'insertPages_handleFilter_mceButtons' ) );
91
92 //load_plugin_textdomain('insert-pages', false, dirname(plugin_basename(__FILE__)).'/languages/');
93 }
94
95 }
96
97
98 // Shortcode hook: Replace the [insert ...] shortcode with the inserted page's content
99 function insertPages_handleShortcode_insert( $atts, $content = null ) {
100 global $wp_query, $post, $wp_current_filter;
101 extract( shortcode_atts( array(
102 'page' => '0',
103 'display' => 'all',
104 'class' => '',
105 ), $atts ) );
106
107 // Validation checks.
108 if ( $page === '0' ) {
109 return $content;
110 }
111
112 // Trying to embed same page in itself.
113 if ( $page == $post->ID || $page == $post->post_name ) {
114 return $content;
115 }
116
117 $should_apply_nesting_check = true;
118 /**
119 * Filter the flag indicating whether to apply deep nesting check
120 * that can prevent circular loops. Note that some use cases rely
121 * on inserting pages that themselves have inserted pages, so this
122 * check should be disabled for those individuals.
123 *
124 * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
125 */
126 $should_apply_nesting_check = apply_filters( 'insert_pages_apply_nesting_check', $should_apply_nesting_check );
127
128 // Don't allow inserted pages to be added to the_content more than once (prevent infinite loops).
129 if ( $should_apply_nesting_check ) {
130 $done = false;
131 foreach ( $wp_current_filter as $filter ) {
132 if ( 'the_content' == $filter ) {
133 if ( $done ) {
134 return $content;
135 } else {
136 $done = true;
137 }
138 }
139 }
140 }
141
142 // Convert slugs to page IDs to standardize query_posts() lookup below.
143 if ( ! is_numeric( $page ) ) {
144 $page_object = get_page_by_path( $page, OBJECT, get_post_types() );
145 $page = $page_object ? $page_object->ID : $page;
146 }
147
148 if ( is_numeric( $page ) ) {
149 $args = array(
150 'p' => intval( $page ),
151 'post_type' => get_post_types(),
152 );
153 } else {
154 $args = array(
155 'name' => esc_attr( $page ),
156 'post_type' => get_post_types(),
157 );
158 }
159
160 query_posts( $args );
161
162 $should_apply_the_content_filter = true;
163 /**
164 * Filter the flag indicating whether to apply the_content filter to post
165 * contents and excerpts that are being inserted.
166 *
167 * @param bool $apply_the_content_filter Indicates whether to apply the_content filter.
168 */
169 $should_apply_the_content_filter = apply_filters( 'insert_pages_apply_the_content_filter', $should_apply_the_content_filter );
170
171 // Start our new Loop (only iterate once).
172 if ( have_posts() ) {
173 ob_start(); // Start output buffering so we can save the output to string
174
175 // Show either the title, link, content, everything, or everything via a custom template
176 // Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled;
177 // This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters
178 // are only getting called once. The fix here is to disable processing of filters on the_content in
179 // the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage
180 switch ( $display ) {
181 case "title":
182 the_post(); ?>
183 <h1><?php the_title(); ?></h1>
184 <?php break;
185 case "link":
186 the_post(); ?>
187 <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
188 <?php break;
189 case "excerpt":
190 the_post(); ?>
191 <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
192 <?php if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt(); ?>
193 <?php break;
194 case "excerpt-only":
195 the_post(); ?>
196 <?php if ( $should_apply_the_content_filter ) the_excerpt(); else echo get_the_excerpt(); ?>
197 <?php break;
198 case "content":
199 the_post(); ?>
200 <?php if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content(); ?>
201 <?php break;
202 case "all":
203 the_post(); ?>
204 <h1><?php the_title(); ?></h1>
205 <?php if ( $should_apply_the_content_filter ) the_content(); else echo get_the_content(); ?>
206 <?php the_meta(); ?>
207 <?php break;
208 default: // display is either invalid, or contains a template file to use
209 $template = locate_template( $display );
210 if ( strlen( $template ) > 0 ) {
211 include $template; // execute the template code
212 } else { // Couldn't find template, so fall back to printing a link to the page.
213 the_post(); ?>
214 <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php
215 }
216 break;
217 }
218
219 $content = ob_get_contents(); // Save off output buffer
220 ob_end_clean(); // End output buffering
221 }
222
223 wp_reset_query();
224
225 $content = "<div data-post-id='$page' class='insert-page insert-page-$page $class'>$content</div>";
226 return $content;
227 //return do_shortcode($content); // careful: watch for infinite loops with nested inserts
228 }
229
230
231 // Filter hook: Add a button to the TinyMCE toolbar for our insert page tool
232 function insertPages_handleFilter_mceButtons( $buttons ) {
233 array_push( $buttons, 'wpInsertPages_button' ); // add a separator and button to toolbar
234 return $buttons;
235 }
236
237 // Filter hook: Load the javascript for our custom toolbar button
238 function insertPages_handleFilter_mceExternalPlugins( $plugins ) {
239 $plugins['wpInsertPages'] = plugins_url( '/js/wpinsertpages_plugin.js', __FILE__ );
240 return $plugins;
241 }
242
243 /**
244 * Modified from /wp-admin/includes/internal-linking.php, function wp_link_dialog()
245 * Dialog for internal linking.
246 *
247 * @since 3.1.0
248 */
249 function insertPages_wp_tinymce_dialog() {
250 // If wp_editor() is being called outside of an admin context,
251 // required dependencies for Insert Pages will be missing (e.g.,
252 // wp-admin/includes/template.php will not be loaded, admin_head
253 // action will not be fired). If that's the case, just skip loading
254 // the Insert Pages tinymce button.
255 if ( ! is_admin() || ! function_exists( 'page_template_dropdown' ) ) {
256 return;
257 }
258
259 $options_panel_visible = '1' == get_user_setting( 'wplink', '0' ) ? ' options-panel-visible' : '';
260
261 // display: none is required here, see #WP27605
262 ?><div id="wp-insertpage-backdrop" style="display: none"></div>
263 <div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $options_panel_visible; ?>" style="display: none">
264 <form id="wp-insertpage" tabindex="-1">
265 <?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?>
266 <input type="hidden" id="insertpage-parent-pageID" value="<?php echo $_GET['post'] ?>" />
267 <div id="insertpage-modal-title">
268 <?php _e( 'Insert page' ) ?>
269 <div id="wp-insertpage-close" tabindex="0"></div>
270 </div>
271 <div id="insertpage-selector">
272 <div id="insertpage-search-panel">
273 <div class="insertpage-search-wrapper">
274 <label>
275 <span class="search-label"><?php _e( 'Search' ); ?></span>
276 <input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" />
277 <span class="spinner"></span>
278 </label>
279 </div>
280 <div id="insertpage-search-results" class="query-results">
281 <ul></ul>
282 <div class="river-waiting">
283 <span class="spinner"></span>
284 </div>
285 </div>
286 <div id="insertpage-most-recent-results" class="query-results">
287 <div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div>
288 <ul></ul>
289 <div class="river-waiting">
290 <span class="spinner"></span>
291 </div>
292 </div>
293 </div>
294 <p class="howto" id="insertpage-options-toggle"><?php _e( 'Options' ); ?></p>
295 <div id="insertpage-options-panel">
296 <div class="insertpage-options-wrapper">
297 <label for="insertpage-slug-field">
298 <span><?php _e( 'Slug or ID' ); ?></span>
299 <input id="insertpage-slug-field" type="text" tabindex="10" autocomplete="off" />
300 <input id="insertpage-pageID" type="hidden" />
301 </label>
302 </div>
303 <div class="insertpage-format">
304 <label for="insertpage-format-select">
305 <?php _e( 'Display' ); ?>
306 <select name="insertpage-format-select" id="insertpage-format-select">
307 <option value='title'>Title</option>
308 <option value='link'>Link</option>
309 <option value='excerpt'>Excerpt</option>
310 <option value='excerpt-only'>Excerpt only (no title)</option>
311 <option value='content'>Content</option>
312 <option value='all'>All (includes custom fields)</option>
313 <option value='template'>Use a custom template &raquo;</option>
314 </select>
315 <select name="insertpage-template-select" id="insertpage-template-select" disabled="true">
316 <option value='all'><?php _e( 'Default Template' ); ?></option>
317 <?php page_template_dropdown(); ?>
318 </select>
319 </label>
320 </div>
321 </div>
322 </div>
323 <div class="submitbox">
324 <div id="wp-insertpage-update">
325 <input type="submit" value="<?php esc_attr_e( 'Insert Page' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit">
326 </div>
327 <div id="wp-insertpage-cancel">
328 <a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a>
329 </div>
330 </div>
331 </form>
332 </div>
333 <?php
334 }
335
336 /** Modified from:
337 * Internal linking functions.
338 *
339 * @package WordPress
340 * @subpackage Administration
341 * @since 3.1.0
342 */
343 function insertPages_insert_page_callback() {
344 check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' );
345 $args = array();
346 if ( isset( $_POST['search'] ) ) {
347 $args['s'] = stripslashes( $_POST['search'] );
348 }
349 $args['pagenum'] = !empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
350 $args['pageID'] = !empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0;
351
352 $results = $this->insertPages_wp_query( $args );
353
354 if ( !isset( $results ) ) {
355 die( '0' );
356 }
357 echo json_encode( $results );
358 echo "\n";
359 die();
360 }
361
362 /** Modified from:
363 * Performs post queries for internal linking.
364 *
365 * @since 3.1.0
366 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
367 * @return array Results.
368 */
369 function insertPages_wp_query( $args = array() ) {
370 $pts = get_post_types( array( 'public' => true ), 'objects' );
371 $post_types = array_keys( $pts );
372
373 /**
374 * Filter the post types that appear in the list of pages to insert.
375 *
376 * By default, all post types will apear.
377 *
378 * @since 2.0
379 *
380 * @param array $post_types Array of post type names to include.
381 */
382 $post_types = apply_filters( 'insert_pages_available_post_types', $post_types );
383
384 $query = array(
385 'post_type' => $post_types,
386 'suppress_filters' => true,
387 'update_post_term_cache' => false,
388 'update_post_meta_cache' => false,
389 'post_status' => 'publish',
390 'order' => 'DESC',
391 'orderby' => 'post_date',
392 'posts_per_page' => 20,
393 'post__not_in' => array( $args['pageID'] ),
394 );
395
396 $args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
397
398 if ( isset( $args['s'] ) ) {
399 $query['s'] = $args['s'];
400 }
401
402 $query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
403
404 // Do main query.
405 $get_posts = new WP_Query;
406 $posts = $get_posts->query( $query );
407 // Check if any posts were found.
408 if ( ! $get_posts->post_count ) {
409 return false;
410 }
411
412 // Build results.
413 $results = array();
414 foreach ( $posts as $post ) {
415 if ( 'post' == $post->post_type ) {
416 $info = mysql2date( __( 'Y/m/d' ), $post->post_date );
417 } else {
418 $info = $pts[ $post->post_type ]->labels->singular_name;
419 }
420 $results[] = array(
421 'ID' => $post->ID,
422 'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ),
423 'permalink' => get_permalink( $post->ID ),
424 'slug' => $post->post_name,
425 'info' => $info,
426 );
427 }
428 return $results;
429 }
430
431 function insertPages_add_quicktags() {
432 if ( wp_script_is( 'quicktags' ) ) : ?>
433 <script type="text/javascript">
434 QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|all']\n", '', '', 'Insert Page', 999 );
435 </script>
436 <?php endif;
437 }
438
439 }
440 }
441
442 // Initialize InsertPagesPlugin object
443 if ( class_exists( 'InsertPagesPlugin' ) ) {
444 $insertPages_plugin = new InsertPagesPlugin();
445 }
446
447 // Actions and Filters handled by InsertPagesPlugin class
448 if ( isset( $insertPages_plugin ) ) {
449 // Actions
450 add_action( 'init', array( $insertPages_plugin, 'insertPages_init' ), 1 ); // Register Shortcodes here
451 add_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 ); // Add TinyMCE buttons here
452 add_action( 'before_wp_tiny_mce', array( $insertPages_plugin, 'insertPages_wp_tinymce_dialog' ), 1 ); // Preload TinyMCE popup
453 add_action( 'wp_ajax_insertpage', array( $insertPages_plugin, 'insertPages_insert_page_callback' ) ); // Populate page search in TinyMCE button popup in this ajax call
454 add_action( 'admin_print_footer_scripts', array( $insertPages_plugin, 'insertPages_add_quicktags' ) );
455 }
456