diff --git a/ckeditor.api.php b/ckeditor.api.php
index 58e251e..77caa16 100644
--- a/ckeditor.api.php
+++ b/ckeditor.api.php
@@ -44,11 +44,12 @@ function hook_ckeditor_plugin() {
'name' => 'plugin_name',
// Description of the plugin - it would be displayed in the plugins management section of profile settings.
'desc' => t('Plugin description'),
- // The full path to the CKEditor plugins directory, with the trailing slash.
- 'path' => drupal_get_path('module', 'my_module') . '/plugin_dir/',
+ // The full URL to the CKEditor plugins directory, with the trailing slash.
+ 'path' => base_path() . drupal_get_path('module', 'my_module') . '/plugin_dir/',
'buttons' => array(
'button_name' => array(
- 'icon' => 'path to button icon',
+ // Path to an icon relative to the plugins folder.
+ 'icon' => 'icon/plugin_name.png',
'label' => 'Button Label',
)
)
@@ -57,6 +58,17 @@ function hook_ckeditor_plugin() {
}
/**
+ * Hook to extend/change CKEditor plugins.
+ *
+ * @param $plugins
+ * An associative array of plugins.
+ */
+function hook_ckeditor_plugin_alter(&$plugins) {
+ // Remove a plugin button.
+ unset($plugins['plugin_name']['buttons']['button']);
+}
+
+/**
* Hook to register the CKEditor security filter - it would appear in the security filters list on the profile setting page.
*/
function hook_ckeditor_security_filter() {
diff --git a/ckeditor.ckeditor.inc b/ckeditor.ckeditor.inc
new file mode 100644
index 0000000..572ae5b
--- /dev/null
+++ b/ckeditor.ckeditor.inc
@@ -0,0 +1,222 @@
+') {
+ if (file_exists($_editor_path . '/plugins/tableresize/plugin.js')) {
+ $plugins['tableresize'] = array(
+ 'name' => 'tableresize',
+ 'desc' => t('Table Resize plugin'),
+ 'path' => $editor_path . '/plugins/tableresize/',
+ 'buttons' => FALSE,
+ 'default' => 't'
+ );
+ }
+
+ if (file_exists($_editor_path . '/plugins/autogrow/plugin.js')) {
+ $plugins['autogrow'] = array(
+ 'name' => 'autogrow',
+ 'desc' => t('Auto Grow plugin'),
+ 'path' => $editor_path . '/plugins/autogrow/',
+ 'buttons' => FALSE,
+ 'default' => 'f'
+ );
+ }
+
+ if (file_exists($_editor_path . '/plugins/stylesheetparser/plugin.js')) {
+ $plugins['stylesheetparser'] = array(
+ 'name' => 'stylesheetparser',
+ 'desc' => t('Stylesheet Parser plugin'),
+ 'path' => $editor_path . '/plugins/stylesheetparser/',
+ 'buttons' => FALSE,
+ 'default' => 'f'
+ );
+ }
+ }
+ else {
+ $_editor_url = ckeditor_path('url');
+ if (preg_match("/\/(standard|full)-all/", $_editor_url)) {
+ $plugins['tableresize'] = array(
+ 'name' => 'tableresize',
+ 'desc' => t('Table Resize plugin. See !link for more details.', array(
+ '!link' => l(t('addon page'), 'http://ckeditor.com/addon/tableresize')
+ )),
+ 'path' => $_editor_url . '/plugins/tableresize/',
+ 'buttons' => FALSE,
+ 'default' => 't'
+ );
+ $plugins['autogrow'] = array(
+ 'name' => 'autogrow',
+ 'desc' => t('Auto Grow plugin. See !link for more details.', array(
+ '!link' => l(t('addon page'), 'http://ckeditor.com/addon/autogrow')
+ )),
+ 'path' => $_editor_url . '/plugins/autogrow/',
+ 'buttons' => FALSE,
+ 'default' => 'f'
+ );
+ $plugins['stylesheetparser'] = array(
+ 'name' => 'stylesheetparser',
+ 'desc' => t('Stylesheet Parser plugin. See !link for more details.', array(
+ '!link' => l(t('addon page'), 'http://ckeditor.com/addon/stylesheetparser')
+ )),
+ 'path' => $_editor_url . '/plugins/stylesheetparser/',
+ 'buttons' => FALSE,
+ 'default' => 'f'
+ );
+ $plugins['codesnippet'] = array(
+ 'name' => 'codesnippet',
+ 'desc' => t('Plugin for inserting Code Snippets. See !link for more details. See !help for additional instructions.', array(
+ '!link' => l(t('addon page'), 'http://ckeditor.com/addon/codesnippet'),
+ '!help' => l(t('help'), 'admin/help/ckeditor', array('fragment' => 'codesnippet'))
+ )),
+ 'path' => $_editor_url . '/plugins/codesnippet/',
+ 'buttons' => array(
+ 'CodeSnippet' => array(
+ 'icon' => 'icons/codesnippet.png',
+ 'label' => 'Insert Code Snippet',
+ )
+ ),
+ 'default' => 'f'
+ );
+ $plugins['mathjax'] = array(
+ 'name' => 'mathjax',
+ 'desc' => t('Plugin for inserting Mathematical Formula (MathJax). See !link for more details. See !help for additional instructions.', array(
+ '!link' => l(t('addon page'), 'http://ckeditor.com/addon/mathjax'),
+ '!help' => l(t('help'), 'admin/help/ckeditor', array('fragment' => 'mathjax'))
+ )),
+ 'path' => $_editor_url . '/plugins/mathjax/',
+ 'buttons' => array(
+ 'Mathjax' => array(
+ 'icon' => 'icons/mathjax.png',
+ 'label' => 'Insert Mathematical Formulas',
+ )
+ ),
+ 'default' => 'f'
+ );
+ }
+ }
+
+ /*
+ * Plugins located directly in the CKEditor module folder.
+ */
+ $_plugin_dir = ckeditor_module_path('local') . '/plugins/';
+ if ($handle = opendir($_plugin_dir)) {
+ while (false !== ($file = readdir($handle))) {
+ if (is_dir($_plugin_dir . $file) && file_exists($_plugin_dir . $file . '/plugin.js')) {
+ $source = file_get_contents($_plugin_dir . $file . '/plugin.js');
+ $buttons = array();
+ if (preg_match_all($pattern, $source, $matches)) {
+ foreach ($matches[1] as $i => $button_name) {
+ if (preg_match('#(icon)[\s]*\:[\s]*([^\,\n]*)#', $matches[2][$i], $matches2)) {
+ $buttons[$button_name] = array();
+ $buttons[$button_name]['label'] = $button_name;
+ $matches2[2] = str_replace(array('this.path', '+', '\'', '"'), array('', '', '', ''), $matches2[2]);
+ $buttons[$button_name]['icon'] = trim($matches2[2]);
+ }
+ }
+ }
+ if (preg_match('#@file ([^\n\r]*)#', $source, $matches)) {
+ $plugins[$file] = array(
+ 'name' => $file,
+ 'desc' => t($matches[1]),
+ 'path' => $plugin_dir . $file . '/',
+ 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
+ 'default' => 'f'
+ );
+ }
+ else {
+ $plugins[$file] = array(
+ 'name' => $file,
+ 'desc' => t('Plugin file: ' . $file),
+ 'path' => $plugin_dir . $file . '/',
+ 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
+ 'default' => 'f'
+ );
+ }
+ }
+ }
+ closedir($handle);
+ }
+
+ /*
+ * Plugins located in a folder specified in the CKEditor Global Profile.
+ */
+ $_plugin_dir_additional = ckeditor_plugins_path('local') . '/';
+ if ($_plugin_dir != $_plugin_dir_additional && is_dir($_plugin_dir_additional) && $handle = opendir($_plugin_dir_additional)) {
+ while (false !== ($file = readdir($handle))) {
+ if (is_dir($_plugin_dir_additional . $file) && file_exists($_plugin_dir_additional . $file . '/plugin.js')) {
+ $source = file_get_contents($_plugin_dir_additional . $file . '/plugin.js');
+ $buttons = array();
+ if (preg_match_all($pattern, $source, $matches)) {
+ foreach ($matches[1] as $i => $button_name) {
+ if (preg_match('#(icon)[\s]*\:[\s]*([^\,\n]*)#', $matches[2][$i], $matches2)) {
+ $buttons[$button_name] = array();
+ $buttons[$button_name]['label'] = $button_name;
+ $matches2[2] = str_replace(array('this.path', '+', '\'', '"'), array('', '', '', ''), $matches2[2]);
+ $buttons[$button_name]['icon'] = trim($matches2[2]);
+ }
+ }
+ }
+ if (preg_match('#@file ([^\n\r]*)#', $source, $matches)) {
+ $plugins[$file] = array(
+ 'name' => $file,
+ 'desc' => t($matches[1]),
+ 'path' => $plugin_dir_additional . $file . '/',
+ 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
+ 'default' => 'f'
+ );
+ }
+ else {
+ $plugins[$file] = array(
+ 'name' => $file,
+ 'desc' => t('Plugin file: ' . $file),
+ 'path' => $plugin_dir_additional . $file . '/',
+ 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
+ 'default' => 'f'
+ );
+ }
+ }
+ }
+
+ closedir($handle);
+ }
+
+ // Remove the Media plugin if the Media module isn't installed.
+ if (isset($plugins['media']) && module_exists('media') == FALSE) {
+ unset($plugins['media']);
+ }
+
+ // Remove the IMCE plugin if the IMCE module isn't installed.
+ if (isset($plugins['imce']) && module_exists('imce') == FALSE) {
+ unset($plugins['imce']);
+ }
+
+ // Enable the Drupal Breaks plugin by default if the plugin is available.
+ if (isset($plugins['drupalbreaks'])) {
+ $plugins['drupalbreaks']['default'] = 't';
+
+ // Remove the page break button if there is no module to handle it.
+ if (isset($plugins['drupalbreaks']['buttons']['DrupalPageBreak']) && !module_exists('paging') && !module_exists('pagebreak')) {
+ unset($plugins['drupalbreaks']['buttons']['DrupalPageBreak']);
+ }
+ }
+
+ return $plugins;
+}
diff --git a/ckeditor.module b/ckeditor.module
index 630714d..da64f3e 100644
--- a/ckeditor.module
+++ b/ckeditor.module
@@ -51,6 +51,21 @@ $_ckeditor_configuration = array();
$_ckeditor_ids = array();
/**
+ * Implements hook_hook_info().
+ */
+function ckeditor_hook_info() {
+ $hooks = array(
+ 'ckeditor_plugin',
+ 'ckeditor_plugin_alter',
+ 'ckeditor_security_filter',
+ 'ckeditor_security_filter_alter',
+ 'ckeditor_settings_alter',
+ );
+
+ return array_fill_keys($hooks, array('group' => 'ckeditor'));
+}
+
+/**
* Implementation of hook_menu().
*/
function ckeditor_menu() {
diff --git a/includes/ckeditor.lib.inc b/includes/ckeditor.lib.inc
index e2395f3..c384b49 100644
--- a/includes/ckeditor.lib.inc
+++ b/includes/ckeditor.lib.inc
@@ -330,286 +330,25 @@ function ckeditor_scayt_langcode($lang) {
* @return array
*/
function ckeditor_load_plugins($render = FALSE) {
- $arr = array();
- $base_path = '%base_path%';
- $editor_path = '%editor_path%';
- $plugin_dir = '%plugin_dir%';
- $plugin_dir_additional = '%plugin_dir_extra%';
- $pattern = '#\.addButton\([\s]*[\'"](.*?)[\'"][\s]*\,[\s]*\{[\s]*(.*?)[\s]*\}#s';
-
- /*
- * External plugins
- */
- if (module_exists('ckeditor_swf') && file_exists(drupal_get_path('module', 'ckeditor_swf') . '/plugins/swf/plugin.js')) {
- $arr['ckeditor_swf'] = array(
- 'name' => 'swf',
- 'desc' => t('Support for the CKEditor SWF module'),
- 'path' => $base_path . drupal_get_path('module', 'ckeditor_swf') . '/plugins/swf/',
- 'buttons' => FALSE,
- 'default' => 't'
- );
- }
-
- if (module_exists('ckeditor_link') && file_exists(drupal_get_path('module', 'ckeditor_link') . '/plugins/link/plugin.js')) {
- $arr['ckeditor_link'] = array(
- 'name' => 'drupal_path',
- 'desc' => t('Support for the CKEditor Link module'),
- 'path' => $base_path . drupal_get_path('module', 'ckeditor_link') . '/plugins/link/',
- 'buttons' => FALSE,
- 'default' => 't'
- );
- }
-
- if (module_exists('linkit') && file_exists(drupal_get_path('module', 'linkit') . '/editors/ckeditor/plugin.js')) {
- $arr['linkit'] = array(
- 'name' => 'Linkit',
- 'desc' => t('Support for the Linkit module (buttons: Linkit)'),
- 'path' => $base_path . drupal_get_path('module', 'linkit') . '/editors/ckeditor/',
- 'buttons' => array(
- 'Linkit' => array(
- 'title' => 'Linkit',
- 'icon' => $base_path . drupal_get_path('module', 'linkit') . '/editors/ckeditor/linkit.png'
- )
- ),
- 'default' => 't'
- );
- }
-
- /*
- * CKEditor build-in plugins
- */
- $_editor_path = ckeditor_path('local');
- //die($editor_path);
- if ($_editor_path != '') {
- if (file_exists($_editor_path . '/plugins/tableresize/plugin.js')) {
- $arr['tableresize'] = array(
- 'name' => 'tableresize',
- 'desc' => t('Table Resize plugin'),
- 'path' => $editor_path . '/plugins/tableresize/',
- 'buttons' => FALSE,
- 'default' => 't'
- );
- }
-
- if (file_exists($_editor_path . '/plugins/autogrow/plugin.js')) {
- $arr['autogrow'] = array(
- 'name' => 'autogrow',
- 'desc' => t('Auto Grow plugin'),
- 'path' => $editor_path . '/plugins/autogrow/',
- 'buttons' => FALSE,
- 'default' => 'f'
- );
- }
-
- if (file_exists($_editor_path . '/plugins/stylesheetparser/plugin.js')) {
- $arr['stylesheetparser'] = array(
- 'name' => 'stylesheetparser',
- 'desc' => t('Stylesheet Parser plugin'),
- 'path' => $editor_path . '/plugins/stylesheetparser/',
- 'buttons' => FALSE,
- 'default' => 'f'
- );
- }
- }
- else {
- $_editor_url = ckeditor_path('url');
- if (preg_match("/\/(standard|full)-all/", $_editor_url)) {
- $arr['tableresize'] = array(
- 'name' => 'tableresize',
- 'desc' => t('Table Resize plugin. See !link for more details.', array(
- '!link' => l(t('addon page'), 'http://ckeditor.com/addon/tableresize')
- )),
- 'path' => $_editor_url . '/plugins/tableresize/',
- 'buttons' => FALSE,
- 'default' => 't'
- );
- $arr['autogrow'] = array(
- 'name' => 'autogrow',
- 'desc' => t('Auto Grow plugin. See !link for more details.', array(
- '!link' => l(t('addon page'), 'http://ckeditor.com/addon/autogrow')
- )),
- 'path' => $_editor_url . '/plugins/autogrow/',
- 'buttons' => FALSE,
- 'default' => 'f'
- );
- $arr['stylesheetparser'] = array(
- 'name' => 'stylesheetparser',
- 'desc' => t('Stylesheet Parser plugin. See !link for more details.', array(
- '!link' => l(t('addon page'), 'http://ckeditor.com/addon/stylesheetparser')
- )),
- 'path' => $_editor_url . '/plugins/stylesheetparser/',
- 'buttons' => FALSE,
- 'default' => 'f'
- );
- $arr['codesnippet'] = array(
- 'name' => 'codesnippet',
- 'desc' => t('Plugin for inserting Code Snippets. See !link for more details. See !help for additional instructions.', array(
- '!link' => l(t('addon page'), 'http://ckeditor.com/addon/codesnippet'),
- '!help' => l(t('help'), 'admin/help/ckeditor', array('fragment' => 'codesnippet'))
- )),
- 'path' => $_editor_url . '/plugins/codesnippet/',
- 'buttons' => array(
- 'CodeSnippet' => array(
- 'icon' => 'icons/codesnippet.png',
- 'label' => 'Insert Code Snippet',
- )
- ),
- 'default' => 'f'
- );
- $arr['mathjax'] = array(
- 'name' => 'mathjax',
- 'desc' => t('Plugin for inserting Mathematical Formula (MathJax). See !link for more details. See !help for additional instructions.', array(
- '!link' => l(t('addon page'), 'http://ckeditor.com/addon/mathjax'),
- '!help' => l(t('help'), 'admin/help/ckeditor', array('fragment' => 'mathjax'))
- )),
- 'path' => $_editor_url . '/plugins/mathjax/',
- 'buttons' => array(
- 'Mathjax' => array(
- 'icon' => 'icons/mathjax.png',
- 'label' => 'Insert Mathematical Formulas',
- )
- ),
- 'default' => 'f'
- );
- }
- }
-
- /*
- * CKEditor module plugins
- */
- $_plugin_dir = ckeditor_module_path('local') . '/plugins/';
- if ($handle = opendir($_plugin_dir)) {
- while (false !== ($file = readdir($handle))) {
- if (is_dir($_plugin_dir . $file) && file_exists($_plugin_dir . $file . '/plugin.js')) {
- $source = file_get_contents($_plugin_dir . $file . '/plugin.js');
- $buttons = array();
- if (preg_match_all($pattern, $source, $matches)) {
- foreach ($matches[1] as $i => $button_name) {
- if (preg_match('#(icon)[\s]*\:[\s]*([^\,\n]*)#', $matches[2][$i], $matches2)) {
- $buttons[$button_name] = array();
- $buttons[$button_name]['label'] = $button_name;
- $matches2[2] = str_replace(array('this.path', '+', '\'', '"'), array('', '', '', ''), $matches2[2]);
- $buttons[$button_name]['icon'] = trim($matches2[2]);
- }
- }
- }
- if (preg_match('#@file ([^\n\r]*)#', $source, $matches)) {
- $arr[$file] = array(
- 'name' => $file,
- 'desc' => t($matches[1]),
- 'path' => $plugin_dir . $file . '/',
- 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
- 'default' => 'f'
- );
- }
- else {
- $arr[$file] = array(
- 'name' => $file,
- 'desc' => t('Plugin file: ' . $file),
- 'path' => $plugin_dir . $file . '/',
- 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
- 'default' => 'f'
- );
- }
- }
- }
- closedir($handle);
- }
-
- /*
- * CKEditor module plugins - additional directory
- */
- $_plugin_dir_additional = ckeditor_plugins_path('local') . '/';
- if ($_plugin_dir != $_plugin_dir_additional && is_dir($_plugin_dir_additional) && $handle = opendir($_plugin_dir_additional)) {
- while (false !== ($file = readdir($handle))) {
- if (is_dir($_plugin_dir_additional . $file) && file_exists($_plugin_dir_additional . $file . '/plugin.js')) {
- $source = file_get_contents($_plugin_dir_additional . $file . '/plugin.js');
- $buttons = array();
- if (preg_match_all($pattern, $source, $matches)) {
- foreach ($matches[1] as $i => $button_name) {
- if (preg_match('#(icon)[\s]*\:[\s]*([^\,\n]*)#', $matches[2][$i], $matches2)) {
- $buttons[$button_name] = array();
- $buttons[$button_name]['label'] = $button_name;
- $matches2[2] = str_replace(array('this.path', '+', '\'', '"'), array('', '', '', ''), $matches2[2]);
- $buttons[$button_name]['icon'] = trim($matches2[2]);
- }
- }
- }
- if (preg_match('#@file ([^\n\r]*)#', $source, $matches)) {
- $arr[$file] = array(
- 'name' => $file,
- 'desc' => t($matches[1]),
- 'path' => $plugin_dir_additional . $file . '/',
- 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
- 'default' => 'f'
- );
- }
- else {
- $arr[$file] = array(
- 'name' => $file,
- 'desc' => t('Plugin file: ' . $file),
- 'path' => $plugin_dir_additional . $file . '/',
- 'buttons' => (count($buttons) > 0) ? $buttons : FALSE,
- 'default' => 'f'
- );
- }
- }
- }
-
- closedir($handle);
- }
-
- /*
- * CKEditor plugins registered by hook
- */
$plugins = module_invoke_all('ckeditor_plugin');
+ // [#2159403] introduced a slight change in CKEditor API, expecting the path to a plugin returned by hook_ckeditor_plugin() to be a full URL.
+ // This breaks backwards compatibility for external plugins, so we're fixing it below.
foreach ($plugins as $i => $plugin) {
- if (file_exists($plugin['path'] . 'plugin.js')) {
- $source = file_get_contents($plugin['path'] . 'plugin.js');
- $plugins[$i]['path'] = $base_path . $plugin['path'];
- if (!isset($plugin['buttons']) || count($plugin['buttons']) == 0) {
- $buttons = array();
- if (preg_match_all($pattern, $source, $matches)) {
- foreach ($matches[1] as $j => $button_name) {
- if (preg_match('#(icon)[\s]*\:[\s]*([^\,\n]*)#', $matches[2][$j], $matches2)) {
- $buttons[$button_name] = array();
- $buttons[$button_name]['label'] = $button_name;
- $matches2[2] = str_replace(array('this.path', '+', '\'', '"'), array('', '', '', ''), $matches2[2]);
- $buttons[$button_name]['icon'] = trim($matches2[2]);
- }
- }
- }
- $plugins[$i]['buttons'] = (count($buttons) > 0) ? $buttons : FALSE;
- }
- }
- else {
- unset($plugins[$i]);
+ if (strpos($plugin['path'], '%') !== 0 && !preg_match('|^(http(s)?:)?\/?\/|i', $plugin['path'])) {
+ $plugins[$i]['path'] = '%base_path%' . $plugin['path'];
}
}
- $arr = array_merge($arr, $plugins);
- if (isset($arr['media']) && module_exists('media') == FALSE) {
- unset($arr['media']);
- }
+ drupal_alter('ckeditor_plugin', $plugins);
- if (isset($arr['imce']) && module_exists('imce') == FALSE) {
- unset($arr['imce']);
- }
- //remove page break button if there is no module to do this
- if (isset($arr['drupalbreaks']['buttons']['DrupalPageBreak']) && !module_exists('paging') && !module_exists('pagebreak') && !module_exists('smart_paging')) {
- unset($arr['drupalbreaks']['buttons']['DrupalPageBreak']);
- }
-
- if (isset($arr['drupalbreaks'])) {
- $arr['drupalbreaks']['default'] = 't';
- }
+ ksort($plugins);
- ksort($arr);
if ($render === TRUE) {
- $arr = ckeditor_plugins_render($arr);
+ $plugins = ckeditor_plugins_render($plugins);
}
- return $arr;
+
+ return $plugins;
}
/**
@@ -888,7 +627,7 @@ function ckeditor_profile_settings_compile($global_profile, $profile) {
if (isset($conf['loadPlugins'])) {
$settings['loadPlugins'] = ckeditor_plugins_render($conf['loadPlugins']);
- if (array_key_exists('media', $settings['loadPlugins']) && module_exists('media')) {
+ if (array_key_exists('media', $settings['loadPlugins']) && module_exists('media') && module_hook('media', 'filter_info')) {
module_load_include('inc', 'media', 'includes/media.browser');
$javascript = media_browser_js();
foreach ($javascript as $key => $definitions) {
diff --git a/plugins/mediaembed/plugin.js b/plugins/mediaembed/plugin.js
index e617008..7e93dc3 100644
--- a/plugins/mediaembed/plugin.js
+++ b/plugins/mediaembed/plugin.js
@@ -4,7 +4,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
*/
/**
- * @file Plugin for inserting Drupal embeded media
+ * @file Plugin for inserting embeded media
*/
( function() {
var numberRegex = /^\d+(?:\.\d+)?$/;