| 1 |
<?php |
| 2 |
namespace PostSnippets; |
| 3 |
|
| 4 |
if ( ! defined( 'ABSPATH' ) ) exit; |
| 5 |
|
| 6 |
/** |
| 7 |
* Post Snippets WP Editor. |
| 8 |
* |
| 9 |
*/ |
| 10 |
class WPEditor |
| 11 |
{ |
| 12 |
const TINYMCE_PLUGIN_NAME = 'post_snippets'; |
| 13 |
|
| 14 |
/** |
| 15 |
* Encode a snippet value so it is safe to embed in an inline script. |
| 16 |
* |
| 17 |
* @param string $value Snippet content or shortcode. |
| 18 |
* @return string JSON string literal. |
| 19 |
*/ |
| 20 |
private function encodeSnippetForInlineScript($value) |
| 21 |
{ |
| 22 |
return wp_json_encode( |
| 23 |
(string) $value, |
| 24 |
JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT |
| 25 |
); |
| 26 |
} |
| 27 |
|
| 28 |
public function __construct() |
| 29 |
{ |
| 30 |
// TinyMCE button must not appear in description editor of ps code, css and js edit pages. |
| 31 |
$page = isset($_REQUEST['page']) ? sanitize_text_field( $_REQUEST['page'] ) :''; |
| 32 |
if ( |
| 33 |
'post-snippets-edit'!= $page && |
| 34 |
'post-snippets-edit-css'!= $page && |
| 35 |
'post-snippets-edit-js'!= $page) { |
| 36 |
// Add TinyMCE button |
| 37 |
add_action('init', array(&$this, 'addTinymceButton')); |
| 38 |
} |
| 39 |
// Add Editor QuickTag button: |
| 40 |
add_action( |
| 41 |
'admin_print_footer_scripts', |
| 42 |
array(&$this, 'addQuicktagButton'), |
| 43 |
100 |
| 44 |
); |
| 45 |
|
| 46 |
add_action('admin_head', array(&$this, 'jqueryUiDialog')); |
| 47 |
add_action('admin_footer', array(&$this, 'addJqueryUiDialog')); |
| 48 |
|
| 49 |
// Adds the JS and HTML code in the header and footer for the jQuery |
| 50 |
// insert UI dialog in the editor |
| 51 |
add_action('admin_init', array(&$this, 'enqueueAssets')); |
| 52 |
} |
| 53 |
|
| 54 |
|
| 55 |
// ------------------------------------------------------------------------- |
| 56 |
// WordPress Editor Buttons |
| 57 |
// ------------------------------------------------------------------------- |
| 58 |
|
| 59 |
/** |
| 60 |
* Add TinyMCE button. |
| 61 |
* |
| 62 |
* Adds filters to add custom buttons to the TinyMCE editor (Visual Editor) |
| 63 |
* in WordPress. |
| 64 |
* |
| 65 |
* @since Post Snippets 1.8.7 |
| 66 |
*/ |
| 67 |
public function addTinymceButton() |
| 68 |
{ |
| 69 |
// Don't bother doing this stuff if the current user lacks permissions |
| 70 |
if (!current_user_can('edit_posts') && !current_user_can('edit_pages')) { |
| 71 |
return; |
| 72 |
} |
| 73 |
|
| 74 |
// Add only in Rich Editor mode |
| 75 |
if (get_user_option('rich_editing') == 'true') { |
| 76 |
add_filter( |
| 77 |
'mce_external_plugins', |
| 78 |
array(&$this, 'registerTinymcePlugin') |
| 79 |
); |
| 80 |
add_filter( |
| 81 |
'mce_buttons', |
| 82 |
array(&$this, 'registerTinymceButton') |
| 83 |
); |
| 84 |
} |
| 85 |
} |
| 86 |
|
| 87 |
/** |
| 88 |
* Register TinyMCE button. |
| 89 |
* |
| 90 |
* Pushes the custom TinyMCE button into the array of with button names. |
| 91 |
* 'separator' or '|' can be pushed to the array as well. See the link |
| 92 |
* for all available TinyMCE controls. |
| 93 |
* |
| 94 |
* @see wp-includes/class-wp-editor.php |
| 95 |
* @link http://www.tinymce.com/wiki.php/Buttons/controls |
| 96 |
* @since Post Snippets 1.8.7 |
| 97 |
* |
| 98 |
* @param array $buttons Filter supplied array of buttons to modify |
| 99 |
* @return array The modified array with buttons |
| 100 |
*/ |
| 101 |
public function registerTinymceButton($buttons) |
| 102 |
{ |
| 103 |
if (!$this->isEditingPost()) { |
| 104 |
return $buttons; |
| 105 |
} |
| 106 |
|
| 107 |
array_push($buttons, 'separator', self::TINYMCE_PLUGIN_NAME); |
| 108 |
return $buttons; |
| 109 |
} |
| 110 |
|
| 111 |
/** |
| 112 |
* Register TinyMCE plugin. |
| 113 |
* |
| 114 |
* Adds the absolute URL for the TinyMCE plugin to the associative array of |
| 115 |
* plugins. Array structure: 'plugin_name' => 'plugin_url' |
| 116 |
* |
| 117 |
* @see wp-includes/class-wp-editor.php |
| 118 |
* @since Post Snippets 1.8.7 |
| 119 |
* |
| 120 |
* @param array $plugins Filter supplied array of plugins to modify |
| 121 |
* @return array The modified array with plugins |
| 122 |
*/ |
| 123 |
public function registerTinymcePlugin($plugins) |
| 124 |
{ |
| 125 |
if (!$this->isEditingPost()) { |
| 126 |
return $plugins; |
| 127 |
} |
| 128 |
|
| 129 |
// Load the TinyMCE plugin, editor_plugin.js, into the array |
| 130 |
$plugins[self::TINYMCE_PLUGIN_NAME] = |
| 131 |
plugins_url('/tinymce/editor_plugin.js?ver=1.9', \PostSnippets::FILE); |
| 132 |
|
| 133 |
return $plugins; |
| 134 |
} |
| 135 |
|
| 136 |
|
| 137 |
/** |
| 138 |
* Adds a QuickTag button to the HTML editor. |
| 139 |
* |
| 140 |
* Compatible with WordPress 3.3 and newer. |
| 141 |
* |
| 142 |
* @see wp-includes/js/quicktags.dev.js -> qt.addButton() |
| 143 |
* @since Post Snippets 1.8.6 |
| 144 |
*/ |
| 145 |
public function addQuicktagButton() |
| 146 |
{ |
| 147 |
if (!$this->isEditingPost()) { |
| 148 |
return; |
| 149 |
} |
| 150 |
|
| 151 |
echo "\n<!-- START: Add QuickTag button for Post Snippets -->\n"; |
| 152 |
?> |
| 153 |
<script type="text/javascript" charset="utf-8"> |
| 154 |
if (typeof QTags != 'undefined') { |
| 155 |
function qt_post_snippets() { |
| 156 |
post_snippets_caller = 'html'; |
| 157 |
jQuery("#post-snippets-dialog").dialog("open"); |
| 158 |
} |
| 159 |
QTags.addButton('post_snippets_id', 'Post Snippets', qt_post_snippets); |
| 160 |
} |
| 161 |
</script> |
| 162 |
<?php |
| 163 |
echo "\n<!-- END: Add QuickTag button for Post Snippets -->\n"; |
| 164 |
} |
| 165 |
|
| 166 |
|
| 167 |
// ------------------------------------------------------------------------- |
| 168 |
// JavaScript / jQuery handling for the post editor |
| 169 |
// ------------------------------------------------------------------------- |
| 170 |
|
| 171 |
/** |
| 172 |
* Enqueues the necessary scripts and styles for the plugins |
| 173 |
* |
| 174 |
* @since Post Snippets 1.7 |
| 175 |
*/ |
| 176 |
public function enqueueAssets() |
| 177 |
{ |
| 178 |
wp_enqueue_script('jquery-ui-dialog'); |
| 179 |
wp_enqueue_script('jquery-ui-tabs'); |
| 180 |
wp_enqueue_style('wp-jquery-ui-dialog'); |
| 181 |
|
| 182 |
# Adds the CSS stylesheet for the jQuery UI dialog |
| 183 |
$style_url = plugins_url('/assets/post-snippets.css', \PostSnippets::FILE); |
| 184 |
wp_register_style( 'post-snippets', $style_url, false, PS_VERSION ); |
| 185 |
wp_enqueue_style('post-snippets'); |
| 186 |
} |
| 187 |
|
| 188 |
/** |
| 189 |
* jQuery control for the dialog and Javascript needed to insert snippets into the editor |
| 190 |
* |
| 191 |
* @since Post Snippets 1.7 |
| 192 |
*/ |
| 193 |
public function jqueryUiDialog() |
| 194 |
{ |
| 195 |
if (!$this->isEditingPost()) { |
| 196 |
return; |
| 197 |
} |
| 198 |
global $wpdb; |
| 199 |
$table_name = $wpdb->prefix.\PostSnippets::TABLE_NAME; |
| 200 |
$snippets = $wpdb->get_results($wpdb->prepare("SELECT * from %1s", $table_name ), ARRAY_A ); |
| 201 |
|
| 202 |
//Let other plugins change the snippets array |
| 203 |
$snippets = apply_filters('post_snippets_snippets_list', $snippets); |
| 204 |
|
| 205 |
$snippetStack = array(); |
| 206 |
|
| 207 |
if (!empty($snippets) && is_array($snippets) || is_object($snippets)) { |
| 208 |
foreach ( $snippets as $key => $snippet ) { |
| 209 |
if ( isset($snippet['snippet_shortcode']) && ! empty($snippet['snippet_shortcode']) && $snippet['snippet_shortcode'] == 1) { |
| 210 |
# Build a long string of the variables, ie: varname1={varname1} varname2={varname2} |
| 211 |
# so {varnameX} can be replaced at runtime. |
| 212 |
|
| 213 |
$snippet_vars = Shortcode::filterVars( $snippet['snippet_vars'] ); |
| 214 |
$variables = ''; |
| 215 |
if ( !empty($snippet_vars) ) { |
| 216 |
foreach ($snippet_vars as $name => $val){ |
| 217 |
$variables .= ' ' . $name . '="{' . $name . '}"'; |
| 218 |
} |
| 219 |
} |
| 220 |
$shortcode = $snippet['snippet_title'] . $variables; |
| 221 |
array_push( $snippetStack, "var postsnippet_{$key} = " . $this->encodeSnippetForInlineScript( '[' . $shortcode . ']' ) . ";\n" ); |
| 222 |
} else if(isset($snippet['snippet_content'])) { |
| 223 |
// To use $snippet is probably not a good naming convention here. |
| 224 |
// rename to js_snippet or something? |
| 225 |
$snippet = stripslashes( $snippet['snippet_content'] ); |
| 226 |
# Print out the variable containing the snippet |
| 227 |
array_push( $snippetStack, "var postsnippet_{$key} = " . $this->encodeSnippetForInlineScript( $snippet ) . ";\n" ); |
| 228 |
} |
| 229 |
} |
| 230 |
} |
| 231 |
?> |
| 232 |
|
| 233 |
<?php |
| 234 |
$data = array( |
| 235 |
'methods' => $this, |
| 236 |
'snippets' => $snippets, |
| 237 |
'snippetStack' => $snippetStack |
| 238 |
); |
| 239 |
echo View::render('jquery_ui_dialog_head', $data); |
| 240 |
} |
| 241 |
|
| 242 |
/** |
| 243 |
* Build jQuery UI Window. |
| 244 |
* |
| 245 |
* Creates the jQuery for Post Editor popup window, its snippet tabs and the |
| 246 |
* form fields to enter variables. |
| 247 |
* |
| 248 |
* @since Post Snippets 1.7 |
| 249 |
*/ |
| 250 |
public function addJqueryUiDialog() |
| 251 |
{ |
| 252 |
if (!$this->isEditingPost()) { |
| 253 |
return; |
| 254 |
} |
| 255 |
|
| 256 |
global $wpdb; |
| 257 |
$table_name = $wpdb->prefix.\PostSnippets::TABLE_NAME; |
| 258 |
$snippets = $wpdb->get_results($wpdb->prepare("SELECT * from %1s", $table_name ), ARRAY_A ); |
| 259 |
|
| 260 |
|
| 261 |
//Let other plugins change the snippets array |
| 262 |
$snippets = apply_filters('post_snippets_snippets_list', $snippets); |
| 263 |
$data = array('snippets' => $snippets); |
| 264 |
|
| 265 |
echo View::render('jquery_ui_dialog_footer', $data); |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Determine if current screen is a post editing screen. |
| 270 |
* |
| 271 |
* @return boolean |
| 272 |
*/ |
| 273 |
protected function isEditingPost() |
| 274 |
{ |
| 275 |
$settings = get_option(\PostSnippets::SETTINGS); |
| 276 |
$exclude = isset($settings['exclude_from_custom_editors']) ? |
| 277 |
$settings['exclude_from_custom_editors'] : |
| 278 |
false; |
| 279 |
|
| 280 |
// If we are not excluding from custom editors, always return true. |
| 281 |
if (!$exclude) { |
| 282 |
return true; |
| 283 |
} |
| 284 |
|
| 285 |
// If get_current_screen doesn't exist, we're on the frontend, |
| 286 |
// so return false, as it's then definately a custom editor |
| 287 |
if (function_exists('get_current_screen')) { |
| 288 |
$screen = get_current_screen(); |
| 289 |
} else { |
| 290 |
$screen = false; |
| 291 |
} |
| 292 |
|
| 293 |
if ( isset($screen) && $screen->is_block_editor() && $screen->post_type !='post' && $screen->post_type!='page') { |
| 294 |
add_filter('allowed_block_types_all', 'ps_block_remove_from_gutenbergEditor', 10, 2); |
| 295 |
} |
| 296 |
|
| 297 |
return is_object($screen) ? ( $screen->post_type == 'post' || $screen->post_type == 'page') : false; |
| 298 |
} |
| 299 |
|
| 300 |
/** |
| 301 |
* Strip Default Value. |
| 302 |
* |
| 303 |
* Checks if a variable string contains a default value, and if it does it |
| 304 |
* will strip it away and return the string with only the variable name |
| 305 |
* kept. |
| 306 |
* |
| 307 |
* @since Post Snippets 1.9.3 |
| 308 |
* @param string $variable The variable to check for default value |
| 309 |
* @return string The variable without any default value |
| 310 |
*/ |
| 311 |
public function stripDefaultVal($variable) |
| 312 |
{ |
| 313 |
// Check if variable contains a default defintion |
| 314 |
$def_pos = strpos($variable, '='); |
| 315 |
|
| 316 |
if ($def_pos !== false) { |
| 317 |
$split = str_split($variable, $def_pos); |
| 318 |
$variable = $split[0]; |
| 319 |
} |
| 320 |
return $variable; |
| 321 |
} |
| 322 |
} |
| 323 |
|