'',
'editor' => '',
);
if (empty($profile['settings'])) {
$profile['settings'] = array();
}
$profile['settings'] += array(
'default' => TRUE,
'user_choose' => FALSE,
'show_toggle' => TRUE,
'theme' => 'advanced',
'language' => 'en',
'access' => 1,
'access_pages' => "node/*\nuser/*\ncomment/*",
'buttons' => array(),
'toolbar_loc' => 'top',
'toolbar_align' => 'left',
'path_loc' => 'bottom',
'resizing' => TRUE,
// Also available, but buggy in TinyMCE 2.x: blockquote,code,dt,dd,samp.
'block_formats' => 'p,address,pre,h2,h3,h4,h5,h6,div',
'verify_html' => TRUE,
'preformatted' => FALSE,
'convert_fonts_to_spans' => TRUE,
'remove_linebreaks' => TRUE,
'apply_source_formatting' => FALSE,
'paste_auto_cleanup_on_paste' => FALSE,
'css_setting' => 'theme',
'css_path' => NULL,
'css_classes' => NULL,
);
$profile = (object) $profile;
$formats = filter_formats();
$editor = wysiwyg_get_editor($profile->editor);
drupal_set_title(t('%editor profile for %format', array('%editor' => $editor['title'], '%format' => $formats[$profile->format]->name)), PASS_THROUGH);
$form['format'] = array('#type' => 'value', '#value' => $profile->format);
$form['input_format'] = array('#type' => 'value', '#value' => $formats[$profile->format]->name);
$form['editor'] = array('#type' => 'value', '#value' => $profile->editor);
$form['basic'] = array(
'#type' => 'fieldset',
'#title' => t('Basic setup'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['basic']['default'] = array(
'#type' => 'checkbox',
'#title' => t('Enabled by default'),
'#default_value' => $profile->settings['default'],
'#return_value' => 1,
'#description' => t('The default editor state for users having access to this profile. Users are able to override this state if the next option is enabled.'),
);
$form['basic']['user_choose'] = array(
'#type' => 'checkbox',
'#title' => t('Allow users to choose default'),
'#default_value' => $profile->settings['user_choose'],
'#return_value' => 1,
'#description' => t('If allowed, users will be able to choose their own editor default state in their user account settings.'),
);
$form['basic']['show_toggle'] = array(
'#type' => 'checkbox',
'#title' => t('Show enable/disable rich text toggle link'),
'#default_value' => $profile->settings['show_toggle'],
'#return_value' => 1,
'#description' => t('Whether or not to show the enable/disable rich text toggle link below a textarea. If disabled, the user setting or global default is used (see above).'),
);
$form['basic']['theme'] = array(
'#type' => 'hidden',
'#value' => $profile->settings['theme'],
);
$form['basic']['language'] = array(
'#type' => 'select',
'#title' => t('Interface language'),
'#default_value' => $profile->settings['language'],
);
// @see _locale_prepare_predefined_list()
require_once DRUPAL_ROOT . '/includes/iso.inc';
$predefined = _locale_get_predefined_list();
foreach ($predefined as $key => $value) {
// Include native name in output, if possible
if (count($value) > 1) {
$tname = t($value[0]);
$predefined[$key] = ($tname == $value[1]) ? $tname : "$tname ($value[1])";
}
else {
$predefined[$key] = t($value[0]);
}
}
asort($predefined);
$form['basic']['language']['#options'] = $predefined;
$form['buttons'] = array(
'#type' => 'fieldset',
'#title' => t('Buttons and plugins'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
'#theme' => 'wysiwyg_admin_button_table',
);
$plugins = wysiwyg_get_plugins($profile->editor);
// Generate the button list.
foreach ($plugins as $name => $meta) {
if (isset($meta['buttons']) && is_array($meta['buttons'])) {
foreach ($meta['buttons'] as $button => $title) {
$icon = '';
if (!empty($meta['path'])) {
// @todo Button icon locations are different in editors, editor versions,
// and contrib/custom plugins (like Image Assist, f.e.).
$img_src = $meta['path'] . "/images/$name.gif";
// Handle plugins that have more than one button.
if (!file_exists($img_src)) {
$img_src = $meta['path'] . "/images/$button.gif";
}
$icon = file_exists($img_src) ? '' : '';
}
$title = (!empty($icon) ? $icon . ' ' . check_plain($title) : check_plain($title));
$form['buttons'][$name][$button] = array(
'#type' => 'checkbox',
'#title' => $title,
'#default_value' => !empty($profile->settings['buttons'][$name][$button]) ? $profile->settings['buttons'][$name][$button] : FALSE,
'#description' => isset($meta['url']) ? l($meta['url'], $meta['url']) : NULL,
);
}
}
elseif (isset($meta['extensions']) && is_array($meta['extensions'])) {
foreach ($meta['extensions'] as $extension => $title) {
$form['buttons'][$name][$extension] = array(
'#type' => 'checkbox',
'#title' => check_plain($title),
'#default_value' => !empty($profile->settings['buttons'][$name][$extension]) ? $profile->settings['buttons'][$name][$extension] : FALSE,
'#description' => isset($meta['url']) ? l($meta['url'], $meta['url']) : NULL,
);
}
}
}
$form['appearance'] = array(
'#type' => 'fieldset',
'#title' => t('Editor appearance'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['appearance']['toolbar_loc'] = array(
'#type' => 'select',
'#title' => t('Toolbar location'),
'#default_value' => $profile->settings['toolbar_loc'],
'#options' => array('bottom' => t('Bottom'), 'top' => t('Top')),
'#description' => t('This option controls whether the editor toolbar is displayed above or below the editing area.'),
);
$form['appearance']['toolbar_align'] = array(
'#type' => 'select',
'#title' => t('Button alignment'),
'#default_value' => $profile->settings['toolbar_align'],
'#options' => array('center' => t('Center'), 'left' => t('Left'), 'right' => t('Right')),
'#description' => t('This option controls the alignment of icons in the editor toolbar.'),
);
$form['appearance']['path_loc'] = array(
'#type' => 'select',
'#title' => t('Path location'),
'#default_value' => $profile->settings['path_loc'],
'#options' => array('none' => t('Hide'), 'top' => t('Top'), 'bottom' => t('Bottom')),
'#description' => t('Where to display the path to HTML elements (i.e. body > table > tr > td
).'),
);
$form['appearance']['resizing'] = array(
'#type' => 'checkbox',
'#title' => t('Enable resizing button'),
'#default_value' => $profile->settings['resizing'],
'#return_value' => 1,
'#description' => t('This option gives you the ability to enable/disable the resizing button. If enabled, the Path location toolbar must be set to "Top" or "Bottom" in order to display the resize icon.'),
);
$form['output'] = array(
'#type' => 'fieldset',
'#title' => t('Cleanup and output'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['output']['verify_html'] = array(
'#type' => 'checkbox',
'#title' => t('Verify HTML'),
'#default_value' => $profile->settings['verify_html'],
'#return_value' => 1,
'#description' => t('If enabled, potentially malicious code like <HEAD>
tags will be removed from HTML contents.'),
);
$form['output']['preformatted'] = array(
'#type' => 'checkbox',
'#title' => t('Preformatted'),
'#default_value' => $profile->settings['preformatted'],
'#return_value' => 1,
'#description' => t('If enabled, the editor will insert TAB characters on tab and preserve other whitespace characters just like a PRE element in HTML does.'),
);
$form['output']['convert_fonts_to_spans'] = array(
'#type' => 'checkbox',
'#title' => t('Convert <font> tags to styles'),
'#default_value' => $profile->settings['convert_fonts_to_spans'],
'#return_value' => 1,
'#description' => t('If enabled, HTML tags declaring the font size, font family, font color and font background color will be replaced by inline CSS styles.'),
);
$form['output']['remove_linebreaks'] = array(
'#type' => 'checkbox',
'#title' => t('Remove linebreaks'),
'#default_value' => $profile->settings['remove_linebreaks'],
'#return_value' => 1,
'#description' => t('If enabled, the editor will remove most linebreaks from contents. Disabling this option could avoid conflicts with other input filters.'),
);
$form['output']['apply_source_formatting'] = array(
'#type' => 'checkbox',
'#title' => t('Apply source formatting'),
'#default_value' => $profile->settings['apply_source_formatting'],
'#return_value' => 1,
'#description' => t('If enabled, the editor will re-format the HTML source code. Disabling this option could avoid conflicts with other input filters.'),
);
$form['output']['paste_auto_cleanup_on_paste'] = array(
'#type' => 'checkbox',
'#title' => t('Force cleanup on standard paste'),
'#default_value' => $profile->settings['paste_auto_cleanup_on_paste'],
'#return_value' => 1,
'#description' => t('If enabled, the default paste function (CTRL-V or SHIFT-INS) behaves like the "paste from word" plugin function.'),
);
$form['css'] = array(
'#type' => 'fieldset',
'#title' => t('CSS'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['css']['block_formats'] = array(
'#type' => 'textfield',
'#title' => t('Block formats'),
'#default_value' => $profile->settings['block_formats'],
'#size' => 40,
'#maxlength' => 250,
'#description' => t('Comma separated list of HTML block formats. Possible values: @format-list
.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,div,blockquote,address,pre,code,dt,dd')),
);
$form['css']['css_setting'] = array(
'#type' => 'select',
'#title' => t('Editor CSS'),
'#default_value' => $profile->settings['css_setting'],
'#options' => array('theme' => t('Use theme CSS'), 'self' => t('Define CSS'), 'none' => t('Editor default CSS')),
'#description' => t('Defines the CSS to be used in the editor area.
Use theme CSS - loads stylesheets from current site theme.
Define CSS - enter path for stylesheet files below.
Editor default CSS - uses default stylesheets from editor.'),
);
$form['css']['css_path'] = array(
'#type' => 'textfield',
'#title' => t('CSS path'),
'#default_value' => $profile->settings['css_path'],
'#size' => 40,
'#maxlength' => 255,
'#description' => t('If "Define CSS" was selected above, enter path to a CSS file or a list of CSS files separated by a comma.') . '
' . t('Available tokens: %b
(base path, eg: /
), %t
(path to theme, eg: themes/garland
)') . '
' . t('Example:') . ' css/editor.css,/themes/garland/style.css,%b%t/style.css,http://example.com/external.css',
);
$form['css']['css_classes'] = array(
'#type' => 'textarea',
'#title' => t('CSS classes'),
'#default_value' => $profile->settings['css_classes'],
'#description' => t('Optionally define CSS classes for the "Font style" dropdown list.
Enter one class on each line in the format: !format. Example: !example
If left blank, CSS classes are automatically imported from all loaded stylesheet(s).', array('!format' => '[title]=[class]
', '!example' => 'My heading=header1')),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#weight' => 100,
);
$form['cancel'] = array(
'#value' => l(t('Cancel'), 'admin/config/content/wysiwyg'),
'#weight' => 110,
);
// Supply contextual information for other callbacks and handlers.
// @todo Modernize this form for D7+ and declare these earlier.
// $profile is the primary object of this form, and as an entity, usually
// expected to live in $form_state[$entity_type].
$form_state['wysiwyg_profile'] = $profile;
$form_state['wysiwyg']['editor'] = $editor;
$form_state['wysiwyg']['plugins'] = $plugins;
// Allow editor library specific changes to be made to the form.
if (isset($editor['settings form callback'])) {
$editor['settings form callback']($form, $form_state);
}
return $form;
}
/**
* Submit callback for Wysiwyg profile form.
*
* @see wysiwyg_profile_form()
*/
function wysiwyg_profile_form_submit($form, &$form_state) {
$values = $form_state['values'];
if (isset($values['buttons'])) {
// Store only enabled buttons for each plugin.
foreach ($values['buttons'] as $plugin => $buttons) {
$values['buttons'][$plugin] = array_filter($values['buttons'][$plugin]);
}
// Store only enabled plugins.
$values['buttons'] = array_filter($values['buttons']);
}
// Remove any white-space from 'block_formats' setting, since editor
// implementations rely on a comma-separated list to explode().
$values['block_formats'] = preg_replace('@\s+@', '', $values['block_formats']);
// Remove input format name.
$format = $values['format'];
$input_format = $values['input_format'];
$editor = $values['editor'];
unset($values['format'], $values['input_format'], $values['editor']);
// Remove FAPI values.
// @see system_settings_form_submit()
unset($values['submit'], $values['form_id'], $values['op'], $values['form_token'], $values['form_build_id']);
// Insert new profile data.
db_merge('wysiwyg')
->key(array('format' => $format))
->fields(array(
'editor' => $editor,
'settings' => serialize($values),
))
->execute();
wysiwyg_profile_cache_clear();
drupal_set_message(t('Wysiwyg profile for %format has been saved.', array('%format' => $input_format)));
$form_state['redirect'] = 'admin/config/content/wysiwyg';
}
/**
* Layout for the buttons in the Wysiwyg Editor profile form.
*/
function theme_wysiwyg_admin_button_table($variables) {
$form = $variables['form'];
$buttons = array();
// Flatten forms array.
foreach (element_children($form) as $name) {
foreach (element_children($form[$name]) as $button) {
$buttons[] = drupal_render($form[$name][$button]);
}
}
// Split checkboxes into rows with 3 columns.
$total = count($buttons);
$rows = array();
for ($i = 0; $i < $total; $i += 3) {
$row = array();
$row_buttons = array_slice($buttons, $i, 3) + array_fill(0, 3, array());
foreach ($row_buttons as $row_button) {
$row[] = array('data' => $row_button);
}
$rows[] = $row;
}
$output = theme('table', array('rows' => $rows, 'attributes' => array('width' => '100%')));
return $output;
}
/**
* Display overview of setup Wysiwyg Editor profiles; menu callback.
*/
function wysiwyg_profile_overview($form, &$form_state) {
include_once './includes/install.inc';
// Check which wysiwyg editors are installed.
$editors = wysiwyg_get_all_editors();
$count = count($editors);
$status = array();
$options = array('' => t('No editor'));
// D7's seven theme displays links in table headers as block elements.
drupal_add_css('table.system-status-report th a {display: inline;}', 'inline');
foreach ($editors as $name => $editor) {
$status[$name] = array(
'severity' => (isset($editor['error']) ? REQUIREMENT_ERROR : ($editor['installed'] ? REQUIREMENT_OK : REQUIREMENT_INFO)),
'title' => t('@editor (Download)', array('!vendor-url' => $editor['vendor url'], '@editor' => $editor['title'], '!download-url' => $editor['download url'])),
'value' => (isset($editor['installed version']) ? $editor['installed version'] : t('Not installed.')),
'description' => (isset($editor['error']) ? $editor['error'] : ''),
);
if ($editor['installed']) {
$options[$name] = $editor['title'] . (isset($editor['installed version']) ? ' ' . $editor['installed version'] : '');
}
else {
// Build on-site installation instructions.
// @todo Setup $library in wysiwyg_load_editor() already.
$library = (isset($editor['library']) ? $editor['library'] : key($editor['libraries']));
$targs = array(
'@editor-path' => $editor['editor path'],
'@library-filepath' => $editor['library path'] . '/' . (isset($editor['libraries'][$library]['files'][0]) ? $editor['libraries'][$library]['files'][0] : key($editor['libraries'][$library]['files'])),
);
$instructions = '
' . t('Extract the archive and copy its contents into a new folder in the following location:@editor-path
', $targs) . '
' . t('So the actual library can be found at:@library-filepath
', $targs) . '