2009-05-14 07:26:47 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A PHP version of TinyMCE's configuration, to allow various parameters to be configured on a site or section basis
|
|
|
|
*
|
|
|
|
* There can be multiple HtmlEditorConfig's, which should always be created / accessed using HtmlEditorConfig::get. You can then set
|
|
|
|
* the currently active config using set_active. Whichever config is active when HtmlEditorField#Field is called wins.
|
|
|
|
*
|
|
|
|
* @author "Hamish Friedlander" <hamish@silverstripe.com>
|
2010-04-23 02:11:41 +02:00
|
|
|
* @package forms
|
|
|
|
* @subpackage fields-formattedinput
|
2009-05-14 07:26:47 +02:00
|
|
|
*/
|
|
|
|
class HtmlEditorConfig {
|
|
|
|
|
|
|
|
static $configs = array();
|
|
|
|
static $current = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the HtmlEditorConfig object for the given identifier. This is a correct way to get an HtmlEditorConfig instance - do not call 'new'
|
|
|
|
* @param $identifier string - the identifier for the config set
|
|
|
|
* @return HtmlEditorConfig - the configuration object. This will be created if it does not yet exist for that identifier
|
|
|
|
*/
|
|
|
|
static function get($identifier = 'default') {
|
|
|
|
if (!array_key_exists($identifier, self::$configs)) self::$configs[$identifier] = new HtmlEditorConfig();
|
|
|
|
return self::$configs[$identifier];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the currently active configuration object
|
|
|
|
* @param $identifier string - the identifier for the config set
|
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
static function set_active($identifier = null) {
|
|
|
|
self::$current = $identifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the currently active configuration object
|
|
|
|
* @return HtmlEditorConfig - the active configuration object
|
|
|
|
*/
|
|
|
|
static function get_active() {
|
|
|
|
$identifier = self::$current ? self::$current : 'default';
|
|
|
|
return self::get($identifier);
|
|
|
|
}
|
|
|
|
|
2009-08-10 06:32:39 +02:00
|
|
|
/**
|
|
|
|
* Get the available configurations as a map of friendly_name to
|
|
|
|
* configuration name.
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
static function get_available_configs_map() {
|
|
|
|
$configs = array();
|
|
|
|
|
|
|
|
foreach(self::$configs as $identifier => $config) {
|
|
|
|
$configs[$identifier] = $config->getOption('friendly_name');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $configs;
|
|
|
|
}
|
|
|
|
|
2009-05-14 07:26:47 +02:00
|
|
|
/**
|
|
|
|
* Holder for all TinyMCE settings _except_ plugins and buttons
|
|
|
|
*/
|
|
|
|
protected $settings = array(
|
2009-08-10 06:32:39 +02:00
|
|
|
'friendly_name' => '(Please set a friendly name for this config)',
|
|
|
|
'priority' => 0,
|
2009-05-14 07:26:47 +02:00
|
|
|
'mode' => "specific_textareas",
|
|
|
|
'editor_selector' => "htmleditor",
|
|
|
|
'width' => "100%",
|
|
|
|
'auto_resize' => false,
|
|
|
|
'theme' => "advanced",
|
|
|
|
|
|
|
|
'theme_advanced_layout_manager' => "SimpleLayout",
|
|
|
|
'theme_advanced_toolbar_location' => "top",
|
|
|
|
'theme_advanced_toolbar_align' => "left",
|
|
|
|
'theme_advanced_toolbar_parent' => "right",
|
|
|
|
|
|
|
|
'blockquote_clear_tag' => "p",
|
|
|
|
'table_inline_editing' => true,
|
|
|
|
|
|
|
|
'safari_warning' => false,
|
|
|
|
'relative_urls' => true,
|
2009-11-21 03:29:59 +01:00
|
|
|
'verify_html' => true,
|
|
|
|
|
2009-11-21 03:30:02 +01:00
|
|
|
'spellchecker_rpc_url' => 'sapphire/thirdparty/tinymce-spellchecker/rpc.php'
|
2009-05-14 07:26:47 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Holder list of enabled plugins
|
|
|
|
*/
|
|
|
|
protected $plugins = array(
|
2009-12-16 06:30:46 +01:00
|
|
|
'contextmenu' => null,
|
|
|
|
'table' => null,
|
|
|
|
'emotions' => null,
|
|
|
|
'paste' => null,
|
|
|
|
'spellchecker' => null
|
2009-05-14 07:26:47 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Holder list of buttons, organised by line
|
|
|
|
*/
|
|
|
|
protected $buttons = array(
|
|
|
|
1 => array('bold','italic','underline','strikethrough','separator','justifyleft','justifycenter','justifyright','justifyfull','formatselect','separator','bullist','numlist','outdent','indent','blockquote','hr','charmap'),
|
|
|
|
2 => array('undo','redo','separator','cut','copy','paste','pastetext','pasteword','spellchecker','separator','advcode','search','replace','selectall','visualaid','separator','tablecontrols'),
|
|
|
|
3 => array()
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the current value of an option
|
|
|
|
* @param $k string - The key of the option to get
|
|
|
|
* @return mixed - The value of the specified option
|
|
|
|
*/
|
|
|
|
function getOption($k) {
|
2009-12-16 06:38:56 +01:00
|
|
|
if(isset($this->settings[$k])) return $this->settings[$k];
|
2009-05-14 07:26:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the value of one option
|
|
|
|
* @param $k string - The key of the option to set
|
|
|
|
* @param $v mixed - The value of the option to set
|
|
|
|
* @return mixed - $v returned for chaining
|
|
|
|
*/
|
|
|
|
function setOption($k,$v) {
|
|
|
|
return $this->settings[$k] = $v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set multiple options
|
|
|
|
* @param $a array - The options to set, as keys and values of the array
|
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function setOptions($a) {
|
|
|
|
foreach ($a as $k=>$v) {
|
|
|
|
$this->settings[$k] = $v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-12-16 06:30:46 +01:00
|
|
|
* Enable one or several plugins. Will maintain unique list if already
|
|
|
|
* enabled plugin is re-passed. If passed in as a map of plugin-name to path,
|
|
|
|
* the plugin will be loaded by tinymce.PluginManager.load() instead of through tinyMCE.init().
|
|
|
|
* Keep in mind that these externals plugins require a dash-prefix in their name.
|
|
|
|
*
|
|
|
|
* @see http://wiki.moxiecode.com/index.php/TinyMCE:API/tinymce.PluginManager/load
|
|
|
|
*
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param String [0..] a string, or several strings, or a single array of strings - The plugins to enable
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function enablePlugins() {
|
|
|
|
$plugins = func_get_args();
|
2009-12-16 06:30:46 +01:00
|
|
|
if (is_array(current($plugins))) $plugins = current($plugins);
|
|
|
|
foreach ($plugins as $plugin => $path) {
|
|
|
|
// if plugins are passed without a path
|
|
|
|
if(is_numeric($plugin)) {
|
|
|
|
$plugin = $path;
|
|
|
|
$path = null;
|
|
|
|
}
|
|
|
|
if (!array_key_exists($plugin, $this->plugins)) $this->plugins[$plugin] = $path;
|
2009-05-14 07:26:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enable one or several plugins. Will properly handle being passed a plugin that is already disabled
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param String [0..] a string, or several strings, or a single array of strings - The plugins to disable
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function disablePlugins() {
|
|
|
|
$plugins = func_get_args();
|
2009-12-16 06:30:46 +01:00
|
|
|
if (is_array(current($plugins))) $plugins = current($plugins);
|
2009-05-14 07:26:47 +02:00
|
|
|
|
|
|
|
foreach ($plugins as $plugin) {
|
2009-12-16 06:30:46 +01:00
|
|
|
if(array_key_exists($plugin, $this->plugins)) {
|
|
|
|
unset($this->plugins[$plugin]);
|
2009-05-14 07:26:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-16 06:30:46 +01:00
|
|
|
/**
|
|
|
|
* @return Array
|
|
|
|
*/
|
|
|
|
function getPlugins() {
|
|
|
|
return $this->plugins;
|
|
|
|
}
|
|
|
|
|
2009-05-14 07:26:47 +02:00
|
|
|
/**
|
|
|
|
* Totally re-set the buttons on a given line
|
2010-04-23 02:11:41 +02:00
|
|
|
*
|
|
|
|
* @param integer from 1..3 - The line number to redefine
|
|
|
|
* @param string a string or several strings, or a single array of strings - The button names to make this line contain
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function setButtonsForLine() {
|
|
|
|
if (func_num_args() == 2) {
|
|
|
|
list($line, $buttons) = func_get_args();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$buttons = func_get_args();
|
|
|
|
$line = array_shift($buttons);
|
|
|
|
}
|
|
|
|
$this->buttons[$line] = is_array($buttons) ? $buttons : array($buttons);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add buttons to the end of a line
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param integer from 1..3
|
|
|
|
* @param string a string, or several strings, or a single array of strings - The button names to add to the end of this line
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function addButtonsToLine() {
|
|
|
|
$inserts = func_get_args();
|
|
|
|
$line = array_shift($inserts);
|
|
|
|
if (is_array($inserts[0])) $inserts = $inserts[0];
|
|
|
|
|
|
|
|
foreach ($inserts as $button) {
|
|
|
|
$this->buttons[$line][] = $button;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal function for adding and removing buttons related to another button
|
|
|
|
* @param $name string - the name of the button to modify
|
|
|
|
* @param $offset integer - the offset relative to that button to perform an array_splice at - 0 for before $name, 1 for after
|
|
|
|
* @param $del integer - the number of buttons to remove at the position given by index(string) + offset
|
|
|
|
* @param $add mixed - an array or single item to insert at the position given by index(string) + offset, or null for no insertion
|
|
|
|
* @return boolean - true if $name matched a button, false otherwise
|
|
|
|
*/
|
|
|
|
protected function modifyButtons($name, $offset, $del=0, $add=null) {
|
|
|
|
foreach ($this->buttons as &$buttons) {
|
|
|
|
if (($idx = array_search($name, $buttons)) !== false) {
|
|
|
|
if ($add) array_splice($buttons, $idx+$offset, $del, $add);
|
|
|
|
else array_splice($buttons, $idx+$offset, $del, $add);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert buttons before the first occurance of another button
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param string - the name of the button to insert other buttons before
|
|
|
|
* @param string a string, or several strings, or a single array of strings - the button names to insert before that button
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return boolean - true if insertion occured, false if it did not (because the given button name was not found)
|
|
|
|
*/
|
|
|
|
function insertButtonsBefore() {
|
|
|
|
$inserts = func_get_args();
|
|
|
|
$before = array_shift($inserts);
|
|
|
|
return $this->modifyButtons($before, 0, 0, $inserts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert buttons after the first occurance of another button
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param string - the name of the button to insert other buttons after
|
|
|
|
* @param string a string, or several strings, or a single array of strings - the button names to insert after that button
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return boolean - true if insertion occured, false if it did not (because the given button name was not found)
|
|
|
|
*/
|
|
|
|
function insertButtonsAfter() {
|
|
|
|
$inserts = func_get_args();
|
|
|
|
$after = array_shift($inserts);
|
|
|
|
return $this->modifyButtons($after, 1, 0, $inserts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the first occurance of buttons
|
2010-04-23 02:11:41 +02:00
|
|
|
* @param string one or more strings - the name of the buttons to remove
|
2009-05-14 07:26:47 +02:00
|
|
|
* @return null
|
|
|
|
*/
|
|
|
|
function removeButtons() {
|
|
|
|
$removes = func_get_args();
|
|
|
|
foreach ($removes as $button) {
|
|
|
|
$this->modifyButtons($button, 0, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate the javascript that will set tinyMCE's configuration to that of the current settings of this object
|
|
|
|
* @return string - the javascript
|
|
|
|
*/
|
|
|
|
function generateJS() {
|
|
|
|
$config = $this->settings;
|
2009-12-16 06:30:46 +01:00
|
|
|
|
|
|
|
// plugins
|
|
|
|
$internalPlugins = array();
|
|
|
|
$externalPluginsJS = '';
|
|
|
|
foreach($this->plugins as $plugin => $path) {
|
|
|
|
if(!$path) {
|
|
|
|
$internalPlugins[] = $plugin;
|
|
|
|
} else {
|
|
|
|
$internalPlugins[] = '-' . $plugin;
|
|
|
|
$externalPluginsJS .= sprintf(
|
|
|
|
'tinymce.PluginManager.load("%s", "%s");' . "\n",
|
|
|
|
$plugin,
|
|
|
|
$path
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$config['plugins'] = implode(',', $internalPlugins);
|
2009-05-14 07:26:47 +02:00
|
|
|
|
|
|
|
foreach ($this->buttons as $i=>$buttons) {
|
|
|
|
$config['theme_advanced_buttons'.$i] = implode(',', $buttons);
|
|
|
|
}
|
|
|
|
|
|
|
|
return "
|
|
|
|
if((typeof tinyMCE != 'undefined')) {
|
2009-12-16 06:30:46 +01:00
|
|
|
$externalPluginsJS
|
2011-12-13 14:56:35 +01:00
|
|
|
var ssTinyMceConfig = " . Convert::raw2json($config) . ";
|
|
|
|
tinyMCE.init(ssTinyMceConfig);
|
2009-05-18 02:19:47 +02:00
|
|
|
}
|
|
|
|
";
|
2009-05-14 07:26:47 +02:00
|
|
|
}
|
|
|
|
}
|