| 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 |
Version: 3.0.1 |
| 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 || ! is_array( $options ) || ! array_key_exists( 'wpip_format', $options ) || ! array_key_exists( 'wpip_wrapper', $options ) || ! array_key_exists( 'wpip_insert_method', $options ) ) { |
| 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 |
'20151230' |
| 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 |
'20151230' |
| 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 |
|
| 110 |
// Shortcode attributes. |
| 111 |
$attributes = shortcode_atts( array( |
| 112 |
'page' => '0', |
| 113 |
'display' => 'all', |
| 114 |
'class' => '', |
| 115 |
'inline' => false, |
| 116 |
), $atts ); |
| 117 |
|
| 118 |
// Validation checks. |
| 119 |
if ( $attributes['page'] === '0' ) { |
| 120 |
return $content; |
| 121 |
} |
| 122 |
|
| 123 |
// Trying to embed same page in itself. |
| 124 |
if ( $attributes['page'] == $post->ID || $attributes['page'] == $post->post_name ) { |
| 125 |
return $content; |
| 126 |
} |
| 127 |
|
| 128 |
// Get options set in WordPress dashboard (Settings > Insert Pages). |
| 129 |
$options = get_option( 'wpip_settings' ); |
| 130 |
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 ) ) { |
| 131 |
$options = wpip_set_defaults(); |
| 132 |
} |
| 133 |
|
| 134 |
$attributes['inline'] = ( $attributes['inline'] !== false && $attributes['inline'] !== 'false' ) || array_search( 'inline', $atts ) === 0 || ( array_key_exists( 'wpip_wrapper', $options ) && $options['wpip_wrapper'] === 'inline' ); |
| 135 |
/** |
| 136 |
* Filter the flag indicating whether to wrap the inserted content in inline tags (span). |
| 137 |
* |
| 138 |
* @param bool $use_inline_wrapper Indicates whether to wrap the content in span tags. |
| 139 |
*/ |
| 140 |
$attributes['inline'] = apply_filters( 'insert_pages_use_inline_wrapper', $attributes['inline'] ); |
| 141 |
$attributes['wrapper_tag'] = $attributes['inline'] ? 'span' : 'div'; |
| 142 |
|
| 143 |
$attributes['should_apply_the_content_filter'] = true; |
| 144 |
/** |
| 145 |
* Filter the flag indicating whether to apply the_content filter to post |
| 146 |
* contents and excerpts that are being inserted. |
| 147 |
* |
| 148 |
* @param bool $apply_the_content_filter Indicates whether to apply the_content filter. |
| 149 |
*/ |
| 150 |
$attributes['should_apply_the_content_filter'] = apply_filters( 'insert_pages_apply_the_content_filter', $attributes['should_apply_the_content_filter'] ); |
| 151 |
|
| 152 |
// Disable the_content filter if using inline tags, since wpautop |
| 153 |
// inserts p tags and we can't have any inside inline elements. |
| 154 |
if ( $attributes['inline'] ) { |
| 155 |
$attributes['should_apply_the_content_filter'] = false; |
| 156 |
} |
| 157 |
|
| 158 |
$attributes['should_apply_nesting_check'] = true; |
| 159 |
/** |
| 160 |
* Filter the flag indicating whether to apply deep nesting check |
| 161 |
* that can prevent circular loops. Note that some use cases rely |
| 162 |
* on inserting pages that themselves have inserted pages, so this |
| 163 |
* check should be disabled for those individuals. |
| 164 |
* |
| 165 |
* @param bool $apply_the_content_filter Indicates whether to apply the_content filter. |
| 166 |
*/ |
| 167 |
$attributes['should_apply_nesting_check'] = apply_filters( 'insert_pages_apply_nesting_check', $attributes['should_apply_nesting_check'] ); |
| 168 |
|
| 169 |
// Don't allow inserted pages to be added to the_content more than once (prevent infinite loops). |
| 170 |
if ( $attributes['should_apply_nesting_check'] ) { |
| 171 |
$done = false; |
| 172 |
foreach ( $wp_current_filter as $filter ) { |
| 173 |
if ( 'the_content' == $filter ) { |
| 174 |
if ( $done ) { |
| 175 |
return $content; |
| 176 |
} else { |
| 177 |
$done = true; |
| 178 |
} |
| 179 |
} |
| 180 |
} |
| 181 |
} |
| 182 |
|
| 183 |
// Get the WP_Post object from the provided slug or ID. |
| 184 |
if ( ! is_numeric( $attributes['page'] ) ) { |
| 185 |
$inserted_page = get_page_by_path( $attributes['page'], OBJECT, get_post_types() ); |
| 186 |
$attributes['page'] = $inserted_page ? $inserted_page->ID : $attributes['page']; |
| 187 |
} else { |
| 188 |
$inserted_page = get_post( intval( $attributes['page'] ) ); |
| 189 |
} |
| 190 |
|
| 191 |
// If we couldn't retrieve the page, fire the filter hook showing a not-found message. |
| 192 |
if ( $inserted_page === null ) { |
| 193 |
/** |
| 194 |
* Filter the html that should be displayed if an inserted page was not found. |
| 195 |
* |
| 196 |
* @param string $content html to be displayed. Defaults to an empty string. |
| 197 |
*/ |
| 198 |
$content = apply_filters( 'insert_pages_not_found_message', $content ); |
| 199 |
|
| 200 |
// Short-circuit since we didn't find the page. |
| 201 |
return $content; |
| 202 |
} |
| 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 appropriate styles. |
| 207 |
if ( class_exists( 'FLBuilder' ) ) { |
| 208 |
$old_post_id = $post->ID; |
| 209 |
$post->ID = $inserted_page->ID; |
| 210 |
FLBuilder::enqueue_layout_styles_scripts( $inserted_page->ID ); |
| 211 |
$post->ID = $old_post_id; |
| 212 |
} |
| 213 |
|
| 214 |
// Use "Normal" insert method (get_post()). |
| 215 |
if ( $options['wpip_insert_method'] !== 'legacy' ) { |
| 216 |
// Start output buffering so we can save the output to a string. |
| 217 |
ob_start(); |
| 218 |
|
| 219 |
// Show either the title, link, content, everything, or everything via a custom template |
| 220 |
// Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled; |
| 221 |
// This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters |
| 222 |
// are only getting called once. The fix here is to disable processing of filters on the_content in |
| 223 |
// the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage |
| 224 |
switch ( $attributes['display'] ) { |
| 225 |
|
| 226 |
case "title": |
| 227 |
$title_tag = $attributes['inline'] ? 'span' : 'h1'; |
| 228 |
echo "<$title_tag class='insert-page-title'>"; |
| 229 |
echo get_the_title( $inserted_page->ID ); |
| 230 |
echo "</$title_tag>"; |
| 231 |
break; |
| 232 |
|
| 233 |
case "link": |
| 234 |
?><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a><?php |
| 235 |
break; |
| 236 |
|
| 237 |
case "excerpt": |
| 238 |
?><h1><a href="<?php echo esc_url( get_permalink( $inserted_page->ID ) ); ?>"><?php echo get_the_title( $inserted_page->ID ); ?></a></h1><?php |
| 239 |
echo $this->insertPages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] ); |
| 240 |
break; |
| 241 |
|
| 242 |
case "excerpt-only": |
| 243 |
echo $this->insertPages_trim_excerpt( get_post_field( 'post_excerpt', $inserted_page->ID ), $inserted_page->ID, $attributes['should_apply_the_content_filter'] ); |
| 244 |
break; |
| 245 |
|
| 246 |
case "content": |
| 247 |
$content = get_post_field( 'post_content', $inserted_page->ID ); |
| 248 |
if ( $attributes['should_apply_the_content_filter'] ) { |
| 249 |
$content = apply_filters( 'the_content', $content ); |
| 250 |
} |
| 251 |
echo $content; |
| 252 |
break; |
| 253 |
|
| 254 |
case "all": |
| 255 |
// Title. |
| 256 |
$title_tag = $attributes['inline'] ? 'span' : 'h1'; |
| 257 |
echo "<$title_tag class='insert-page-title'>"; |
| 258 |
echo get_the_title( $inserted_page->ID ); |
| 259 |
echo "</$title_tag>"; |
| 260 |
// Content. |
| 261 |
$content = get_post_field( 'post_content', $inserted_page->ID ); |
| 262 |
if ( $attributes['should_apply_the_content_filter'] ) { |
| 263 |
$content = apply_filters( 'the_content', $content ); |
| 264 |
} |
| 265 |
echo $content; |
| 266 |
// Meta. |
| 267 |
// @ref https://core.trac.wordpress.org/browser/tags/4.4/src/wp-includes/post-template.php#L968 |
| 268 |
if ( $keys = get_post_custom_keys( $inserted_page->ID ) ) { |
| 269 |
echo "<ul class='post-meta'>\n"; |
| 270 |
foreach ( (array) $keys as $key ) { |
| 271 |
$keyt = trim( $key ); |
| 272 |
if ( is_protected_meta( $keyt, 'post' ) ) { |
| 273 |
continue; |
| 274 |
} |
| 275 |
$values = array_map( 'trim', get_post_custom_values( $key ) ); |
| 276 |
$value = implode( $values, ', ' ); |
| 277 |
|
| 278 |
/** |
| 279 |
* Filter the HTML output of the li element in the post custom fields list. |
| 280 |
* |
| 281 |
* @since 2.2.0 |
| 282 |
* |
| 283 |
* @param string $html The HTML output for the li element. |
| 284 |
* @param string $key Meta key. |
| 285 |
* @param string $value Meta value. |
| 286 |
*/ |
| 287 |
echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value ); |
| 288 |
} |
| 289 |
echo "</ul>\n"; |
| 290 |
} |
| 291 |
break; |
| 292 |
|
| 293 |
default: // display is either invalid, or contains a template file to use |
| 294 |
// Legacy/compatibility code: In order to use custom templates, |
| 295 |
// we use query_posts() to provide the template with the global |
| 296 |
// state it requires for the inserted page (in other words, all |
| 297 |
// template tags will work with respect to the inserted page |
| 298 |
// instead of the parent page / main loop). Note that this may |
| 299 |
// cause some compatibility issues with other plugins. |
| 300 |
// @ref https://codex.wordpress.org/Function_Reference/query_posts |
| 301 |
if ( is_numeric( $attributes['page'] ) ) { |
| 302 |
$args = array( |
| 303 |
'p' => intval( $attributes['page'] ), |
| 304 |
'post_type' => get_post_types(), |
| 305 |
); |
| 306 |
} else { |
| 307 |
$args = array( |
| 308 |
'name' => esc_attr( $attributes['page'] ), |
| 309 |
'post_type' => get_post_types(), |
| 310 |
); |
| 311 |
} |
| 312 |
$inserted_page = query_posts( $args ); |
| 313 |
if ( have_posts() ) { |
| 314 |
$template = locate_template( $attributes['display'] ); |
| 315 |
if ( strlen( $template ) > 0 ) { |
| 316 |
include $template; // execute the template code |
| 317 |
} else { // Couldn't find template, so fall back to printing a link to the page. |
| 318 |
the_post(); |
| 319 |
?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php |
| 320 |
} |
| 321 |
} |
| 322 |
wp_reset_query(); |
| 323 |
|
| 324 |
} |
| 325 |
|
| 326 |
// Save output buffer contents. |
| 327 |
$content = ob_get_clean(); |
| 328 |
|
| 329 |
// Use "Legacy" insert method (query_posts()). |
| 330 |
} else { |
| 331 |
if ( is_numeric( $attributes['page'] ) ) { |
| 332 |
$args = array( |
| 333 |
'p' => intval( $attributes['page'] ), |
| 334 |
'post_type' => get_post_types(), |
| 335 |
); |
| 336 |
} else { |
| 337 |
$args = array( |
| 338 |
'name' => esc_attr( $attributes['page'] ), |
| 339 |
'post_type' => get_post_types(), |
| 340 |
); |
| 341 |
} |
| 342 |
$posts = query_posts( $args ); |
| 343 |
if ( have_posts() ) { |
| 344 |
// Start output buffering so we can save the output to string |
| 345 |
ob_start(); |
| 346 |
// Show either the title, link, content, everything, or everything via a custom template |
| 347 |
// Note: if the sharing_display filter exists, it means Jetpack is installed and Sharing is enabled; |
| 348 |
// This plugin conflicts with Sharing, because Sharing assumes the_content and the_excerpt filters |
| 349 |
// are only getting called once. The fix here is to disable processing of filters on the_content in |
| 350 |
// the inserted page. @see https://codex.wordpress.org/Function_Reference/the_content#Alternative_Usage |
| 351 |
switch ( $attributes['display'] ) { |
| 352 |
case "title": |
| 353 |
the_post(); |
| 354 |
$title_tag = $attributes['inline'] ? 'span' : 'h1'; |
| 355 |
echo "<$title_tag class='insert-page-title'>"; |
| 356 |
the_title(); |
| 357 |
echo "</$title_tag>"; |
| 358 |
break; |
| 359 |
case "link": |
| 360 |
the_post(); |
| 361 |
?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php |
| 362 |
break; |
| 363 |
case "excerpt": |
| 364 |
the_post(); |
| 365 |
?><h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1><?php |
| 366 |
if ( $attributes['should_apply_the_content_filter'] ) the_excerpt(); else echo get_the_excerpt(); |
| 367 |
break; |
| 368 |
case "excerpt-only": |
| 369 |
the_post(); |
| 370 |
if ( $attributes['should_apply_the_content_filter'] ) the_excerpt(); else echo get_the_excerpt(); |
| 371 |
break; |
| 372 |
case "content": |
| 373 |
the_post(); |
| 374 |
if ( $attributes['should_apply_the_content_filter'] ) the_content(); else echo get_the_content(); |
| 375 |
break; |
| 376 |
case "all": |
| 377 |
the_post(); |
| 378 |
$title_tag = $attributes['inline'] ? 'span' : 'h1'; |
| 379 |
echo "<$title_tag class='insert-page-title'>"; |
| 380 |
the_title(); |
| 381 |
echo "</$title_tag>"; |
| 382 |
if ( $attributes['should_apply_the_content_filter'] ) the_content(); else echo get_the_content(); |
| 383 |
the_meta(); |
| 384 |
break; |
| 385 |
default: // display is either invalid, or contains a template file to use |
| 386 |
$template = locate_template( $attributes['display'] ); |
| 387 |
if ( strlen( $template ) > 0 ) { |
| 388 |
include $template; // execute the template code |
| 389 |
} else { // Couldn't find template, so fall back to printing a link to the page. |
| 390 |
the_post(); |
| 391 |
?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><?php |
| 392 |
} |
| 393 |
break; |
| 394 |
} |
| 395 |
// Save output buffer contents. |
| 396 |
$content = ob_get_clean(); |
| 397 |
|
| 398 |
} |
| 399 |
wp_reset_query(); |
| 400 |
} |
| 401 |
|
| 402 |
/** |
| 403 |
* Filter the markup generated for the inserted page. |
| 404 |
* |
| 405 |
* @param string $content The post content of the inserted page. |
| 406 |
* @param object $inserted_page The post object returned from querying the inserted page. |
| 407 |
* @param array $attributes Extra parameters modifying the inserted page. |
| 408 |
* page: Page ID or slug of page to be inserted. |
| 409 |
* display: Content to display from inserted page. |
| 410 |
* class: Extra classes to add to inserted page wrapper element. |
| 411 |
* inline: Boolean indicating wrapper element should be a span. |
| 412 |
* should_apply_nesting_check: Whether to disable nested inserted pages. |
| 413 |
* should_apply_the_content_filter: Whether to apply the_content filter to post contents and excerpts. |
| 414 |
* wrapper_tag: Tag to use for the wrapper element (e.g., div, span). |
| 415 |
*/ |
| 416 |
$content = apply_filters( 'insert_pages_wrap_content', $content, $inserted_page, $attributes ); |
| 417 |
|
| 418 |
return $content; |
| 419 |
} |
| 420 |
|
| 421 |
// Default filter for insert_pages_wrap_content. |
| 422 |
function insertPages_wrap_content( $content, $posts, $attributes ) { |
| 423 |
return "<{$attributes['wrapper_tag']} data-post-id='{$attributes['page']}' class='insert-page insert-page-{$attributes['page']} {$attributes['class']}'>{$content}</{$attributes['wrapper_tag']}>"; |
| 424 |
} |
| 425 |
|
| 426 |
// Filter hook: Add a button to the TinyMCE toolbar for our insert page tool |
| 427 |
function insertPages_handleFilter_mceButtons( $buttons ) { |
| 428 |
array_push( $buttons, 'wpInsertPages_button' ); // add a separator and button to toolbar |
| 429 |
return $buttons; |
| 430 |
} |
| 431 |
|
| 432 |
// Filter hook: Load the javascript for our custom toolbar button |
| 433 |
function insertPages_handleFilter_mceExternalPlugins( $plugins ) { |
| 434 |
$plugins['wpInsertPages'] = plugins_url( '/js/wpinsertpages_plugin.js', __FILE__ ); |
| 435 |
return $plugins; |
| 436 |
} |
| 437 |
|
| 438 |
// Helper function to generate an excerpt (outside of the Loop) for a given ID. |
| 439 |
// @ref wp_trim_excerpt() |
| 440 |
function insertPages_trim_excerpt( $text = '', $post_id = 0, $apply_the_content_filter = true ) { |
| 441 |
$post_id = intval( $post_id ); |
| 442 |
if ( $post_id < 1 ) { |
| 443 |
return ''; |
| 444 |
} |
| 445 |
|
| 446 |
$raw_excerpt = $text; |
| 447 |
if ( '' == $text ) { |
| 448 |
$text = get_post_field( 'post_content', $post_id ); |
| 449 |
|
| 450 |
$text = strip_shortcodes( $text ); |
| 451 |
|
| 452 |
/** This filter is documented in wp-includes/post-template.php */ |
| 453 |
if ( $apply_the_content_filter ) { |
| 454 |
$text = apply_filters( 'the_content', $text ); |
| 455 |
} |
| 456 |
$text = str_replace( ']]>', ']]>', $text ); |
| 457 |
|
| 458 |
/** |
| 459 |
* Filter the number of words in an excerpt. |
| 460 |
* |
| 461 |
* @since 2.7.0 |
| 462 |
* |
| 463 |
* @param int $number The number of words. Default 55. |
| 464 |
*/ |
| 465 |
$excerpt_length = apply_filters( 'excerpt_length', 55 ); |
| 466 |
/** |
| 467 |
* Filter the string in the "more" link displayed after a trimmed excerpt. |
| 468 |
* |
| 469 |
* @since 2.9.0 |
| 470 |
* |
| 471 |
* @param string $more_string The string shown within the more link. |
| 472 |
*/ |
| 473 |
$excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); |
| 474 |
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more ); |
| 475 |
} |
| 476 |
/** |
| 477 |
* Filter the trimmed excerpt string. |
| 478 |
* |
| 479 |
* @since 2.8.0 |
| 480 |
* |
| 481 |
* @param string $text The trimmed text. |
| 482 |
* @param string $raw_excerpt The text prior to trimming. |
| 483 |
*/ |
| 484 |
return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt ); |
| 485 |
} |
| 486 |
|
| 487 |
/** |
| 488 |
* Modified from /wp-admin/includes/internal-linking.php, function wp_link_dialog() |
| 489 |
* Dialog for internal linking. |
| 490 |
* |
| 491 |
* @since 3.1.0 |
| 492 |
*/ |
| 493 |
function insertPages_wp_tinymce_dialog() { |
| 494 |
// If wp_editor() is being called outside of an admin context, |
| 495 |
// required dependencies for Insert Pages will be missing (e.g., |
| 496 |
// wp-admin/includes/template.php will not be loaded, admin_head |
| 497 |
// action will not be fired). If that's the case, just skip loading |
| 498 |
// the Insert Pages tinymce button. |
| 499 |
if ( ! is_admin() || ! function_exists( 'page_template_dropdown' ) ) { |
| 500 |
return; |
| 501 |
} |
| 502 |
|
| 503 |
$options_panel_visible = '1' == get_user_setting( 'wpinsertpage', '0' ) ? ' options-panel-visible' : ''; |
| 504 |
|
| 505 |
// Get ID of post currently being edited. |
| 506 |
$post_id = array_key_exists( 'post', $_REQUEST ) && intval( $_REQUEST['post'] ) > 0 ? intval( $_REQUEST['post'] ) : ''; |
| 507 |
|
| 508 |
// display: none is required here, see #WP27605 |
| 509 |
?><div id="wp-insertpage-backdrop" style="display: none"></div> |
| 510 |
<div id="wp-insertpage-wrap" class="wp-core-ui<?php echo $options_panel_visible; ?>" style="display: none"> |
| 511 |
<form id="wp-insertpage" tabindex="-1"> |
| 512 |
<?php wp_nonce_field( 'internal-inserting', '_ajax_inserting_nonce', false ); ?> |
| 513 |
<input type="hidden" id="insertpage-parent-pageID" value="<?php echo $post_id; ?>" /> |
| 514 |
<div id="insertpage-modal-title"> |
| 515 |
<?php _e( 'Insert page' ) ?> |
| 516 |
<div id="wp-insertpage-close" tabindex="0"></div> |
| 517 |
</div> |
| 518 |
<div id="insertpage-selector"> |
| 519 |
<div id="insertpage-search-panel"> |
| 520 |
<div class="insertpage-search-wrapper"> |
| 521 |
<label> |
| 522 |
<span class="search-label"><?php _e( 'Search' ); ?></span> |
| 523 |
<input type="search" id="insertpage-search-field" class="insertpage-search-field" autocomplete="off" /> |
| 524 |
<span class="spinner"></span> |
| 525 |
</label> |
| 526 |
</div> |
| 527 |
<div id="insertpage-search-results" class="query-results"> |
| 528 |
<ul></ul> |
| 529 |
<div class="river-waiting"> |
| 530 |
<span class="spinner"></span> |
| 531 |
</div> |
| 532 |
</div> |
| 533 |
<div id="insertpage-most-recent-results" class="query-results"> |
| 534 |
<div class="query-notice"><em><?php _e( 'No search term specified. Showing recent items.' ); ?></em></div> |
| 535 |
<ul></ul> |
| 536 |
<div class="river-waiting"> |
| 537 |
<span class="spinner"></span> |
| 538 |
</div> |
| 539 |
</div> |
| 540 |
</div> |
| 541 |
<p class="howto" id="insertpage-options-toggle"><?php _e( 'Options' ); ?></p> |
| 542 |
<div id="insertpage-options-panel"> |
| 543 |
<div class="insertpage-options-wrapper"> |
| 544 |
<label for="insertpage-slug-field"> |
| 545 |
<span><?php _e( 'Slug or ID' ); ?></span> |
| 546 |
<input id="insertpage-slug-field" type="text" autocomplete="off" /> |
| 547 |
<input id="insertpage-pageID" type="hidden" /> |
| 548 |
</label> |
| 549 |
</div> |
| 550 |
<div class="insertpage-format"> |
| 551 |
<label for="insertpage-format-select"> |
| 552 |
<?php _e( 'Display' ); ?> |
| 553 |
<select name="insertpage-format-select" id="insertpage-format-select"> |
| 554 |
<option value='title'>Title</option> |
| 555 |
<option value='link'>Link</option> |
| 556 |
<option value='excerpt'>Excerpt with title</option> |
| 557 |
<option value='excerpt-only'>Excerpt only (no title)</option> |
| 558 |
<option value='content'>Content</option> |
| 559 |
<option value='all'>All (includes custom fields)</option> |
| 560 |
<option value='template'>Use a custom template »</option> |
| 561 |
</select> |
| 562 |
<select name="insertpage-template-select" id="insertpage-template-select" disabled="true"> |
| 563 |
<option value='all'><?php _e( 'Default Template' ); ?></option> |
| 564 |
<?php page_template_dropdown(); ?> |
| 565 |
</select> |
| 566 |
</label> |
| 567 |
</div> |
| 568 |
<div class="insertpage-extra"> |
| 569 |
<label for="insertpage-extra-classes"> |
| 570 |
<?php _e( 'Extra Classes' ); ?> |
| 571 |
<input id="insertpage-extra-classes" type="text" autocomplete="off" /> |
| 572 |
</label> |
| 573 |
<label for="insertpage-extra-inline"> |
| 574 |
<?php _e( 'Inline?' ); ?> |
| 575 |
<input id="insertpage-extra-inline" type="checkbox" /> |
| 576 |
</label> |
| 577 |
</div> |
| 578 |
</div> |
| 579 |
</div> |
| 580 |
<div class="submitbox"> |
| 581 |
<div id="wp-insertpage-update"> |
| 582 |
<input type="submit" value="<?php esc_attr_e( 'Insert Page' ); ?>" class="button button-primary" id="wp-insertpage-submit" name="wp-insertpage-submit"> |
| 583 |
</div> |
| 584 |
<div id="wp-insertpage-cancel"> |
| 585 |
<a class="submitdelete deletion" href="#"><?php _e( 'Cancel' ); ?></a> |
| 586 |
</div> |
| 587 |
</div> |
| 588 |
</form> |
| 589 |
</div> |
| 590 |
<?php |
| 591 |
} |
| 592 |
|
| 593 |
/** Modified from: |
| 594 |
* Internal linking functions. |
| 595 |
* |
| 596 |
* @package WordPress |
| 597 |
* @subpackage Administration |
| 598 |
* @since 3.1.0 |
| 599 |
*/ |
| 600 |
function insertPages_insert_page_callback() { |
| 601 |
check_ajax_referer( 'internal-inserting', '_ajax_inserting_nonce' ); |
| 602 |
$args = array(); |
| 603 |
if ( isset( $_POST['search'] ) ) { |
| 604 |
$args['s'] = stripslashes( $_POST['search'] ); |
| 605 |
} |
| 606 |
$args['pagenum'] = !empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; |
| 607 |
$args['pageID'] = !empty( $_POST['pageID'] ) ? absint( $_POST['pageID'] ) : 0; |
| 608 |
|
| 609 |
// Change search to slug or post ID if we're not doing a plaintext |
| 610 |
// search (e.g., if we're editing an existing shortcode and the |
| 611 |
// search field is populated with the post's slug or ID). |
| 612 |
if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'slug' ) { |
| 613 |
$args['name'] = $args['s']; |
| 614 |
unset( $args['s'] ); |
| 615 |
} else if ( array_key_exists( 'type', $_POST ) && $_POST['type'] === 'post_id' ) { |
| 616 |
$args['p'] = $args['s']; |
| 617 |
unset( $args['s'] ); |
| 618 |
} |
| 619 |
|
| 620 |
$results = $this->insertPages_wp_query( $args ); |
| 621 |
|
| 622 |
// Fail if our query didn't work. |
| 623 |
if ( ! isset( $results ) ) { |
| 624 |
die( '0' ); |
| 625 |
} |
| 626 |
|
| 627 |
echo json_encode( $results ); |
| 628 |
echo "\n"; |
| 629 |
die(); |
| 630 |
} |
| 631 |
|
| 632 |
/** Modified from: |
| 633 |
* Performs post queries for internal linking. |
| 634 |
* |
| 635 |
* @since 3.1.0 |
| 636 |
* @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments. |
| 637 |
* @return array Results. |
| 638 |
*/ |
| 639 |
function insertPages_wp_query( $args = array() ) { |
| 640 |
$pts = get_post_types( array( 'public' => true ), 'objects' ); |
| 641 |
$post_types = array_keys( $pts ); |
| 642 |
|
| 643 |
/** |
| 644 |
* Filter the post types that appear in the list of pages to insert. |
| 645 |
* |
| 646 |
* By default, all post types will apear. |
| 647 |
* |
| 648 |
* @since 2.0 |
| 649 |
* |
| 650 |
* @param array $post_types Array of post type names to include. |
| 651 |
*/ |
| 652 |
$post_types = apply_filters( 'insert_pages_available_post_types', $post_types ); |
| 653 |
|
| 654 |
$query = array( |
| 655 |
'post_type' => $post_types, |
| 656 |
'suppress_filters' => true, |
| 657 |
'update_post_term_cache' => false, |
| 658 |
'update_post_meta_cache' => false, |
| 659 |
'post_status' => 'publish', |
| 660 |
'order' => 'DESC', |
| 661 |
'orderby' => 'post_date', |
| 662 |
'posts_per_page' => 20, |
| 663 |
'post__not_in' => array( $args['pageID'] ), |
| 664 |
); |
| 665 |
|
| 666 |
$args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1; |
| 667 |
$query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0; |
| 668 |
|
| 669 |
// Search post content and post title. |
| 670 |
if ( isset( $args['s'] ) ) { |
| 671 |
$query['s'] = $args['s']; |
| 672 |
} |
| 673 |
|
| 674 |
// Search post_name (post slugs). |
| 675 |
if ( isset( $args['name'] ) ) { |
| 676 |
$query['name'] = $args['name']; |
| 677 |
} |
| 678 |
|
| 679 |
// Search post ids. |
| 680 |
if ( isset( $args['p'] ) ) { |
| 681 |
$query['p'] = $args['p']; |
| 682 |
} |
| 683 |
|
| 684 |
// Do main query. |
| 685 |
$get_posts = new WP_Query; |
| 686 |
$posts = $get_posts->query( $query ); |
| 687 |
// Check if any posts were found. |
| 688 |
if ( ! $get_posts->post_count ) { |
| 689 |
return false; |
| 690 |
} |
| 691 |
|
| 692 |
// Build results. |
| 693 |
$results = array(); |
| 694 |
foreach ( $posts as $post ) { |
| 695 |
if ( 'post' == $post->post_type ) { |
| 696 |
$info = mysql2date( __( 'Y/m/d' ), $post->post_date ); |
| 697 |
} else { |
| 698 |
$info = $pts[ $post->post_type ]->labels->singular_name; |
| 699 |
} |
| 700 |
$results[] = array( |
| 701 |
'ID' => $post->ID, |
| 702 |
'title' => trim( esc_html( strip_tags( get_the_title( $post ) ) ) ), |
| 703 |
'permalink' => get_permalink( $post->ID ), |
| 704 |
'slug' => $post->post_name, |
| 705 |
'info' => $info, |
| 706 |
); |
| 707 |
} |
| 708 |
return $results; |
| 709 |
} |
| 710 |
|
| 711 |
function insertPages_add_quicktags() { |
| 712 |
if ( wp_script_is( 'quicktags' ) ) : ?> |
| 713 |
<script type="text/javascript"> |
| 714 |
QTags.addButton( 'ed_insert_page', '[insert page]', "[insert page='your-page-slug' display='title|link|excerpt|excerpt-only|content|all']\n", '', '', 'Insert Page', 999 ); |
| 715 |
</script> |
| 716 |
<?php endif; |
| 717 |
} |
| 718 |
|
| 719 |
} |
| 720 |
} |
| 721 |
|
| 722 |
// Initialize InsertPagesPlugin object |
| 723 |
if ( class_exists( 'InsertPagesPlugin' ) ) { |
| 724 |
$insertPages_plugin = new InsertPagesPlugin(); |
| 725 |
} |
| 726 |
|
| 727 |
// Actions and Filters handled by InsertPagesPlugin class |
| 728 |
if ( isset( $insertPages_plugin ) ) { |
| 729 |
// Register shortcode [insert ...]. |
| 730 |
add_action( 'init', array( $insertPages_plugin, 'insertPages_init' ), 1 ); |
| 731 |
|
| 732 |
// Add TinyMCE button for shortcode. |
| 733 |
add_action( 'admin_head', array( $insertPages_plugin, 'insertPages_admin_init' ), 1 ); |
| 734 |
|
| 735 |
// Add quicktags button for shortcode. |
| 736 |
add_action( 'admin_print_footer_scripts', array( $insertPages_plugin, 'insertPages_add_quicktags' ) ); |
| 737 |
|
| 738 |
// Preload TinyMCE popup. |
| 739 |
add_action( 'before_wp_tiny_mce', array( $insertPages_plugin, 'insertPages_wp_tinymce_dialog' ), 1 ); |
| 740 |
|
| 741 |
// Ajax: Populate page search in TinyMCE button popup. |
| 742 |
add_action( 'wp_ajax_insertpage', array( $insertPages_plugin, 'insertPages_insert_page_callback' ) ); |
| 743 |
|
| 744 |
// Use internal filter to wrap inserted content in a div or span. |
| 745 |
add_filter( 'insert_pages_wrap_content', array( $insertPages_plugin, 'insertPages_wrap_content' ), 10, 3 ); |
| 746 |
} |
| 747 |
|