diff --git a/database/database.mysql b/database/database.mysql index 3895fa336036cda955f8984d6abe9fafe5a6d781..78b7f58654ae7889a8bcfd759172832fa7969c58 100644 --- a/database/database.mysql +++ b/database/database.mysql @@ -308,7 +308,8 @@ CREATE TABLE filter_formats ( name varchar(255) NOT NULL default '', roles varchar(255) NOT NULL default '', cache tinyint(2) NOT NULL default '0', - PRIMARY KEY (format) + PRIMARY KEY (format), + UNIQUE KEY (name) ) /*!40100 DEFAULT CHARACTER SET utf8 */ ; diff --git a/database/database.pgsql b/database/database.pgsql index a8339394535e8cba34b6598b602a87bb096ac814..1628a4b74fcd2b5c10534cee66d3c0e2c170fdde 100644 --- a/database/database.pgsql +++ b/database/database.pgsql @@ -293,7 +293,8 @@ CREATE TABLE filter_formats ( name varchar(255) NOT NULL default '', roles varchar(255) NOT NULL default '', cache smallint NOT NULL default '0', - PRIMARY KEY (format) + PRIMARY KEY (format), + UNIQUE (name) ); -- diff --git a/database/updates.inc b/database/updates.inc index f43cf57e5a8b380034523d0eca60661de388288e..ddf3c450084344cdf217387f9f60d16a4637ae24 100644 --- a/database/updates.inc +++ b/database/updates.inc @@ -1669,3 +1669,8 @@ function system_update_175() { } return array(); } + +function system_update_176() { + $ret[] = update_sql('ALTER TABLE {filter_formats} ADD UNIQUE KEY (name)'); + return $ret; +} diff --git a/modules/filter.module b/modules/filter.module index 3eabbf2de28ed613dc7c8daecb4c01c507162d4a..40f53dbd05a781b92246e09e5e26d66f5371d9e5 100644 --- a/modules/filter.module +++ b/modules/filter.module @@ -56,6 +56,93 @@ function filter_help($section) { } } +/** + * Implementation of hook_menu(). + */ +function filter_menu($may_cache) { + $items = array(); + + if ($may_cache) { + $items[] = array('path' => 'admin/filters', + 'title' => t('input formats'), + 'callback' => 'filter_admin_overview', + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/list', + 'title' => t('list'), + 'callback' => 'filter_admin_overview', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/add', + 'title' => t('add input format'), + 'callback' => 'filter_admin_format_form', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/delete', + 'title' => t('delete input format'), + 'callback' => 'filter_admin_delete', + 'type' => MENU_CALLBACK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'filter/tips', + 'title' => t('compose tips'), + 'callback' => 'filter_tips_long', + 'access' => TRUE, + 'type' => MENU_SUGGESTED_ITEM, + ); + } + else { + if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) { + $formats = filter_formats(); + + if (isset($formats[arg(2)])) { + $items[] = array('path' => 'admin/filters/'. arg(2), + 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)), + 'callback' => 'filter_admin_format_form', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_CALLBACK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', + 'title' => t('view'), + 'callback' => 'filter_admin_format_form', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', + 'title' => t('configure'), + 'callback' => 'filter_admin_configure', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', + 'title' => t('rearrange'), + 'callback' => 'filter_admin_order', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + 'access' => user_access('administer filters'), + ); + } + } + } + + return $items; +} + +/** + * Implementation of hook_perm(). + */ +function filter_perm() { + return array('administer filters'); +} + /** * Implementation of hook_filter_tips(). */ @@ -198,74 +285,6 @@ function filter_filter_tips($delta, $format, $long = false) { } } - -/** - * Implementation of hook_menu(). - */ -function filter_menu($may_cache) { - $items = array(); - - if ($may_cache) { - $items[] = array('path' => 'admin/filters', 'title' => t('input formats'), - 'callback' => 'filter_admin_overview', - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/list', 'title' => t('list'), - 'callback' => 'filter_admin_overview', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/add', 'title' => t('add input format'), - 'callback' => 'filter_admin_add', - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'), - 'callback' => 'filter_admin_delete', - 'type' => MENU_CALLBACK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'), - 'callback' => 'filter_tips_long', 'access' => TRUE, - 'type' => MENU_SUGGESTED_ITEM); - } - else { - if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) { - $formats = filter_formats(); - - if (isset($formats[arg(2)])) { - $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)), - 'callback' => 'filter_admin_format', - 'callback arguments' => array('format' => $formats[arg(2)]), - 'type' => MENU_CALLBACK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('view'), - 'callback' => 'filter_admin_format', - 'callback arguments' => array('format' => $formats[arg(2)]), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => 0, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure'), - 'callback' => 'filter_admin_configure', - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange'), - 'callback' => 'filter_admin_order', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, - 'access' => user_access('administer filters')); - } - } - } - - return $items; -} - -/** - * Implementation of hook_perm(). - */ -function filter_perm() { - return array('administer filters'); -} - /** * Displays a list of all input formats and which one is the default */ @@ -279,7 +298,7 @@ function filter_admin_overview() { foreach ($formats as $id => $format) { $roles = array(); foreach (user_roles() as $rid => $name) { - //prepare a roles array with roles that may access the filter + // Prepare a roles array with roles that may access the filter if (strstr($format->roles, ",$rid,")) { $roles[] = $name; } @@ -287,10 +306,10 @@ function filter_admin_overview() { $row = array(); $default = ($id == variable_get('filter_default_format', 1)); $options[$id] = ''; - $form[$format->name]['id'] = array('#type' => 'markup', '#value' => $id); - $form[$format->name]['roles'] = array('#type' => 'markup', '#value' => $default ? t('All roles may use default format') : ($roles ? implode(', ',$roles) : t('No roles may use this format'))); - $form[$format->name]['configure'] = array('#type' => 'markup', '#value' => l(t('configure'), 'admin/filters/'. $id)); - $form[$format->name]['delete'] = array('#type' => 'markup', '#value' => $default ? '' : l(t('delete'), 'admin/filters/delete/'. $id)); + $form[$format->name]['id'] = array('#value' => $id); + $form[$format->name]['roles'] = array('#value' => $default ? t('All roles may use default format') : ($roles ? implode(', ',$roles) : t('No roles may use this format'))); + $form[$format->name]['configure'] = array('#value' => l(t('configure'), 'admin/filters/'. $id)); + $form[$format->name]['delete'] = array('#value' => $default ? '' : l(t('delete'), 'admin/filters/delete/'. $id)); } $form['default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('filter_default_format', 1)); $form['submit'] = array('#type' => 'submit', '#value' => t('Set default format')); @@ -310,7 +329,7 @@ function theme_filter_admin_overview($form) { if (isset($element['roles']) && is_array($element['roles'])) { $rows[] = array( form_render($form['default'][$element['id']['#value']]), - $name, + check_plain($name), form_render($element['roles']), form_render($element['configure']), form_render($element['delete']) @@ -325,100 +344,79 @@ function theme_filter_admin_overview($form) { return $output; } -/** - * Add a new input format. - */ -function filter_admin_add() { - if ($_POST['op']) { - $edit = $_POST['edit']; - - filter_admin_filters_save($format->format, $edit); - } - - $output = filter_admin_format_form($format); - return $output; -} - /** * Menu callback; confirm deletion of a format. */ function filter_admin_delete() { - $edit = $_POST['edit']; - if ($edit['confirm']) { - if ($edit['format'] != variable_get('filter_default_format', 1)) { - db_query("DELETE FROM {filter_formats} WHERE format = %d", $edit['format']); - db_query("DELETE FROM {filters} WHERE format = %d", $edit['format']); - - $default = variable_get('filter_default_format', 1); - db_query("UPDATE {node_revisions} SET format = %d WHERE format = %d", $default, $edit['format']); - db_query("UPDATE {comments} SET format = %d WHERE format = %d", $default, $edit['format']); - db_query("UPDATE {boxes} SET format = %d WHERE format = %d", $default, $edit['format']); - - cache_clear_all('filter:'. $edit['format'], true); - - drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $edit['name'])))); - } - drupal_goto('admin/filters'); - } - $format = arg(3); $format = db_fetch_object(db_query('SELECT * FROM {filter_formats} WHERE format = %d', $format)); - $form['format'] = array('#type' => 'hidden', '#value' => $format->format); - $form['name'] = array('#type' => 'hidden', '#value' => $format->name); - - return confirm_form('filter_admin_delete', $form, t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))), 'admin/filters', t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'), t('Delete'), t('Cancel')); - + if ($format) { + if ($format->format != variable_get('filter_default_format', 1)) { + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); + $form['name'] = array('#type' => 'hidden', '#value' => $format->name); + return confirm_form('filter_admin_delete', $form, t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))), 'admin/filters', t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'), t('Delete'), t('Cancel')); + } + else { + drupal_set_message('The default format cannot be deleted.'); + drupal_goto('admin/filters'); + } + } + else { + drupal_not_found(); + } } /** - * Menu callback; configure the filters for a format. + * Process filter delete form submission. */ -function filter_admin_format($format) { - if ($_POST['op']) { - $edit = $_POST['edit']; - filter_admin_filters_save($format->format, $edit); - } +function filter_admin_delete_submit($form_id, $form_values) { + db_query("DELETE FROM {filter_formats} WHERE format = %d", $form_values['format']); + db_query("DELETE FROM {filters} WHERE format = %d", $form_values['format']); - $output = filter_admin_format_form($format); + $default = variable_get('filter_default_format', 1); + // Replace existing instances of the deleted format with the default format. + db_query("UPDATE {node_revisions} SET format = %d WHERE format = %d", $default, $form_values['format']); + db_query("UPDATE {comments} SET format = %d WHERE format = %d", $default, $form_values['format']); + db_query("UPDATE {boxes} SET format = %d WHERE format = %d", $default, $form_values['format']); - // Composition tips (guidelines) - $tips = _filter_tips($format->format, false); - $extra = l(t('More information about formatting options'), 'filter/tips'); - $tiplist = theme('filter_tips', $tips, false, $extra); - if (!$tiplist) { - $tiplist = t('<p>No guidelines available.</p>'); - } - $group = t('<p>These are the guidelines that users will see for posting in this input format. They are automatically generated from the filter settings.</p>'); - $group .= $tiplist; - $output .= '<h2>'. t('Formatting guidelines') .'</h2>'. $group; + cache_clear_all('filter:'. $form_values['format'], true); + drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $form_values['name'])))); - return $output; + return 'admin/filters'; } /** - * Renders a form for a format + * Generate a filter format form. */ -function filter_admin_format_form($format) { - $edit = $_POST['edit']; - +function filter_admin_format_form($format = NULL) { $default = ($format->format == variable_get('filter_default_format', 1)); if ($default) { $help = t('All roles for the default format must be enabled and cannot be changed.'); $form['default_format'] = array('#type' => 'hidden', '#value' => 1); } - //Add the name of the object - $form['name'] = array('#type' => 'fieldset', '#title' => t('Name')); - $form['name']['name'] = array('#type' => 'textfield', '#default_value' => $format->name, '#description' => t('Give the name of this filter format'), '#required' => TRUE); + $form['name'] = array('#type' => 'textfield', + '#title' => 'Name', + '#default_value' => $format->name, + '#description' => t('Specify a unique name for this filter format.'), + '#required' => TRUE, + ); + + // Add a row of checkboxes for form group. + $form['roles'] = array('#type' => 'fieldset', + '#title' => t('Roles'), + '#description' => $default ? $help : t('Choose which roles may use this filter format. Note that roles with the "administer filters" permission can always use all the filter formats.'), + '#tree' => TRUE, + ); - //Add a row of checkboxes for form group - $form['roles'] = array('#type' => 'fieldset', '#title' => t('Roles'), '#description' => $default ? $help : t('Choose which roles may use this filter format. Note that roles with the "administer filters" permission can always use all the filter formats.'), '#tree' => TRUE); - $form['roles']['hidden'] = array(); foreach (user_roles() as $rid => $name) { $checked = strstr($format->roles, ",$rid,"); - $form['roles'][$rid] = array('#type' => 'checkbox', '#title' => $name, '#default_value' => ($default || $checked)); + $form['roles'][$rid] = array('#type' => 'checkbox', + '#title' => $name, + '#default_value' => ($default || $checked), + ); if ($default) { $form['roles'][$rid]['#attributes'] = array('disabled' => 'disabled'); } @@ -427,124 +425,160 @@ function filter_admin_format_form($format) { $all = filter_list_all(); $enabled = filter_list_format($format->format); - $form['filters'] = array('#type' => 'fieldset', '#title' => t('Filters'), '#description' => t('Choose the filters that will be used in this filter format')); + $form['filters'] = array('#type' => 'fieldset', + '#title' => t('Filters'), + '#description' => t('Choose the filters that will be used in this filter format.'), + '#tree' => TRUE, + ); foreach ($all as $id => $filter) { - $form['filters'][$id] = array('#type' => 'checkbox', '#title' => $filter->name, '#default_value' => isset($enabled[$id]), '#description' => module_invoke($filter->module, 'filter', 'description', $filter->delta)); + $form['filters'][$id] = array('#type' => 'checkbox', + '#title' => $filter->name, + '#default_value' => isset($enabled[$id]), + '#description' => module_invoke($filter->module, 'filter', 'description', $filter->delta), + ); } - $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration')); - return drupal_get_form('filter_admin_format_form', $form); + if (isset($format)) { + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); + + // Composition tips (guidelines) + $tips = _filter_tips($format->format, false); + $extra = l(t('More information about formatting options'), 'filter/tips'); + $tiplist = theme('filter_tips', $tips, false, $extra); + if (!$tiplist) { + $tiplist = t('<p>No guidelines available.</p>'); + } + $group = t('<p>These are the guidelines that users will see for posting in this input format. They are automatically generated from the filter settings.</p>'); + $group .= $tiplist; + $output = '<h2>'. t('Formatting guidelines') .'</h2>'. $group; + } + $output = drupal_get_form('filter_admin_format_form', $form) . $output; + + return $output; +} + +/** + * Validate filter format form submissions. + */ +function filter_admin_format_form_validate($form_id, $form_values) { + if (!isset($form_values['format'])) { + $name = trim($form_values['name']); + $result = db_fetch_object(db_query("SELECT format FROM {filter_formats} WHERE name='%s'", $name)); + if ($result) { + form_set_error('name', t('Filter format names need to be unique. A format named %name already exists.', array('%name' => theme('placeholder', $name)))); + } + } } /** - * Save enabled/disabled status for filters in a format. + * Process filter format form submissions. */ -function filter_admin_filters_save($format, $toggles) { +function filter_admin_format_form_submit($form_id, $form_values) { + $format = isset($form_values['format']) ? $form_values['format'] : NULL; $current = filter_list_format($format); - $edit = $_POST['edit']; - $name = trim($edit['name']); - $cache = true; - - //make sure a title is specified - if (strlen($name) == 0) { - form_set_error('name', t('You must enter a name for this input format.')); - return; - } + $name = trim($form_values['name']); + $cache = TRUE; - if (!$format) { //add a new filter format. - $new = true; + // Add a new filter format. + if (!$format) { + $new = TRUE; db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name); $result = db_fetch_object(db_query("SELECT MAX(format) AS format FROM {filter_formats}")); $format = $result->format; - drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $edit['name'])))); + drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $name)))); } else { drupal_set_message(t('The input format settings have been updated.')); } db_query("DELETE FROM {filters} WHERE format = %d", $format); - foreach ($toggles as $id => $checked) { + foreach ($form_values['filters'] as $id => $checked) { if ($checked) { list($module, $delta) = explode('/', $id); - // Add new filters to the bottom + // Add new filters to the bottom. $weight = isset($current[$id]->weight) ? $current[$id]->weight : 10; db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $format, $module, $delta, $weight); - // Check if there are any 'no cache' filters + // Check if there are any 'no cache' filters. $cache &= !module_invoke($module, 'filter', 'no cache', $delta); } } // We store the roles as a string for ease of use. - // we should always set all roles to true when saving a default role. + // We should always set all roles to true when saving a default role. // We use leading and trailing comma's to allow easy substring matching. - $roles = isset($edit['roles']) ? array_keys($edit['roles']) : array(); - $roles = ','. implode(',', ($edit['default_format'] ? user_roles() : $roles)) .','; + $roles = array(); + if (isset($form_values['roles'])) { + foreach ($form_values['roles'] as $id => $checked) { + if ($checked) { + $roles[] = $id; + } + } + } + $roles = ','. implode(',', ($form_values['default_format'] ? user_roles() : $roles)) .','; db_query("UPDATE {filter_formats} SET cache = %d, name='%s', roles = '%s' WHERE format = %d", $cache, $name, $roles, $format); cache_clear_all('filter:'. $format, true); - // if a new filter was added, return to the main list of filters, otherwise stay on edit filter page to show new changes + // If a new filter was added, return to the main list of filters. Otherwise, stay on edit filter page to show new changes. if ($new) { - drupal_goto('admin/filters/'); + return 'admin/filters/'; } else { - drupal_goto('admin/filters/' . arg(2)) ; + return 'admin/filters/'. $format; } } /** * Menu callback; display form for ordering filters for a format. */ -function filter_admin_order() { - $format = arg(2); - if ($_POST['op']) { - filter_admin_order_save($format, $_POST['edit']); - } - +function filter_admin_order($format = NULL) { // Get list (with forced refresh) - $filters = filter_list_format($format); + $filters = filter_list_format($format->format); + $form['weights'] = array('#tree' => TRUE); foreach ($filters as $id => $filter) { - $form['name'][$id] = array('#type' => 'markup', '#value' => $filter->name); - $form['weight'][$id] = array('#type' => 'weight', '#default_value' => $filter->weight); + $form['names'][$id] = array('#value' => $filter->name); + $form['weights'][$id] = array('#type' => 'weight', '#default_value' => $filter->weight); } + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration')); return drupal_get_form('filter_admin_order', $form); } +/** + * Theme filter order configuration form. + */ function theme_filter_admin_order($form) { $header = array(t('Name'), t('Weight')); $rows = array(); - foreach (element_children($form['name']) as $id) { + foreach (element_children($form['names']) as $id) { // Don't take form control structures - if (is_array($form['name'][$id])) { - $rows[] = array( - form_render($form['name'][$id]), - form_render($form['weight'][$id])); + if (is_array($form['names'][$id])) { + $rows[] = array(form_render($form['names'][$id]), form_render($form['weights'][$id])); } } $output = theme('table', $header, $rows); $output .= form_render($form); + return $output; } /** - * Save the weights of filters in a format. + * Process filter order configuration form submission. */ -function filter_admin_order_save($format, $weights) { - foreach ($weights as $id => $weight) { +function filter_admin_order_submit($form_id, $form_values) { + foreach ($form_values['weights'] as $id => $weight) { list($module, $delta) = explode('/', $id); - db_query("UPDATE {filters} SET weight = %d WHERE format = %d AND module = '%s' AND delta = %d", $weight, $format, $module, $delta); + db_query("UPDATE {filters} SET weight = %d WHERE format = %d AND module = '%s' AND delta = %d", $weight, $form_values['format'], $module, $delta); } drupal_set_message(t('The filter ordering has been saved.')); - cache_clear_all('filter:'. $format, true); - drupal_goto($_GET['q']); + cache_clear_all('filter:'. $form_values['format'], true); } /** diff --git a/modules/filter/filter.module b/modules/filter/filter.module index 3eabbf2de28ed613dc7c8daecb4c01c507162d4a..40f53dbd05a781b92246e09e5e26d66f5371d9e5 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -56,6 +56,93 @@ function filter_help($section) { } } +/** + * Implementation of hook_menu(). + */ +function filter_menu($may_cache) { + $items = array(); + + if ($may_cache) { + $items[] = array('path' => 'admin/filters', + 'title' => t('input formats'), + 'callback' => 'filter_admin_overview', + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/list', + 'title' => t('list'), + 'callback' => 'filter_admin_overview', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/add', + 'title' => t('add input format'), + 'callback' => 'filter_admin_format_form', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/delete', + 'title' => t('delete input format'), + 'callback' => 'filter_admin_delete', + 'type' => MENU_CALLBACK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'filter/tips', + 'title' => t('compose tips'), + 'callback' => 'filter_tips_long', + 'access' => TRUE, + 'type' => MENU_SUGGESTED_ITEM, + ); + } + else { + if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) { + $formats = filter_formats(); + + if (isset($formats[arg(2)])) { + $items[] = array('path' => 'admin/filters/'. arg(2), + 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)), + 'callback' => 'filter_admin_format_form', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_CALLBACK, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', + 'title' => t('view'), + 'callback' => 'filter_admin_format_form', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', + 'title' => t('configure'), + 'callback' => 'filter_admin_configure', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + 'access' => user_access('administer filters'), + ); + $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', + 'title' => t('rearrange'), + 'callback' => 'filter_admin_order', + 'callback arguments' => array('format' => $formats[arg(2)]), + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + 'access' => user_access('administer filters'), + ); + } + } + } + + return $items; +} + +/** + * Implementation of hook_perm(). + */ +function filter_perm() { + return array('administer filters'); +} + /** * Implementation of hook_filter_tips(). */ @@ -198,74 +285,6 @@ function filter_filter_tips($delta, $format, $long = false) { } } - -/** - * Implementation of hook_menu(). - */ -function filter_menu($may_cache) { - $items = array(); - - if ($may_cache) { - $items[] = array('path' => 'admin/filters', 'title' => t('input formats'), - 'callback' => 'filter_admin_overview', - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/list', 'title' => t('list'), - 'callback' => 'filter_admin_overview', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/add', 'title' => t('add input format'), - 'callback' => 'filter_admin_add', - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/delete', 'title' => t('delete input format'), - 'callback' => 'filter_admin_delete', - 'type' => MENU_CALLBACK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'filter/tips', 'title' => t('compose tips'), - 'callback' => 'filter_tips_long', 'access' => TRUE, - 'type' => MENU_SUGGESTED_ITEM); - } - else { - if (arg(0) == 'admin' && arg(1) == 'filters' && is_numeric(arg(2))) { - $formats = filter_formats(); - - if (isset($formats[arg(2)])) { - $items[] = array('path' => 'admin/filters/'. arg(2), 'title' => t("'%format' input format", array('%format' => $formats[arg(2)]->name)), - 'callback' => 'filter_admin_format', - 'callback arguments' => array('format' => $formats[arg(2)]), - 'type' => MENU_CALLBACK, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/list', 'title' => t('view'), - 'callback' => 'filter_admin_format', - 'callback arguments' => array('format' => $formats[arg(2)]), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => 0, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/configure', 'title' => t('configure'), - 'callback' => 'filter_admin_configure', - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - 'access' => user_access('administer filters')); - $items[] = array('path' => 'admin/filters/'. arg(2) .'/order', 'title' => t('rearrange'), - 'callback' => 'filter_admin_order', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, - 'access' => user_access('administer filters')); - } - } - } - - return $items; -} - -/** - * Implementation of hook_perm(). - */ -function filter_perm() { - return array('administer filters'); -} - /** * Displays a list of all input formats and which one is the default */ @@ -279,7 +298,7 @@ function filter_admin_overview() { foreach ($formats as $id => $format) { $roles = array(); foreach (user_roles() as $rid => $name) { - //prepare a roles array with roles that may access the filter + // Prepare a roles array with roles that may access the filter if (strstr($format->roles, ",$rid,")) { $roles[] = $name; } @@ -287,10 +306,10 @@ function filter_admin_overview() { $row = array(); $default = ($id == variable_get('filter_default_format', 1)); $options[$id] = ''; - $form[$format->name]['id'] = array('#type' => 'markup', '#value' => $id); - $form[$format->name]['roles'] = array('#type' => 'markup', '#value' => $default ? t('All roles may use default format') : ($roles ? implode(', ',$roles) : t('No roles may use this format'))); - $form[$format->name]['configure'] = array('#type' => 'markup', '#value' => l(t('configure'), 'admin/filters/'. $id)); - $form[$format->name]['delete'] = array('#type' => 'markup', '#value' => $default ? '' : l(t('delete'), 'admin/filters/delete/'. $id)); + $form[$format->name]['id'] = array('#value' => $id); + $form[$format->name]['roles'] = array('#value' => $default ? t('All roles may use default format') : ($roles ? implode(', ',$roles) : t('No roles may use this format'))); + $form[$format->name]['configure'] = array('#value' => l(t('configure'), 'admin/filters/'. $id)); + $form[$format->name]['delete'] = array('#value' => $default ? '' : l(t('delete'), 'admin/filters/delete/'. $id)); } $form['default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('filter_default_format', 1)); $form['submit'] = array('#type' => 'submit', '#value' => t('Set default format')); @@ -310,7 +329,7 @@ function theme_filter_admin_overview($form) { if (isset($element['roles']) && is_array($element['roles'])) { $rows[] = array( form_render($form['default'][$element['id']['#value']]), - $name, + check_plain($name), form_render($element['roles']), form_render($element['configure']), form_render($element['delete']) @@ -325,100 +344,79 @@ function theme_filter_admin_overview($form) { return $output; } -/** - * Add a new input format. - */ -function filter_admin_add() { - if ($_POST['op']) { - $edit = $_POST['edit']; - - filter_admin_filters_save($format->format, $edit); - } - - $output = filter_admin_format_form($format); - return $output; -} - /** * Menu callback; confirm deletion of a format. */ function filter_admin_delete() { - $edit = $_POST['edit']; - if ($edit['confirm']) { - if ($edit['format'] != variable_get('filter_default_format', 1)) { - db_query("DELETE FROM {filter_formats} WHERE format = %d", $edit['format']); - db_query("DELETE FROM {filters} WHERE format = %d", $edit['format']); - - $default = variable_get('filter_default_format', 1); - db_query("UPDATE {node_revisions} SET format = %d WHERE format = %d", $default, $edit['format']); - db_query("UPDATE {comments} SET format = %d WHERE format = %d", $default, $edit['format']); - db_query("UPDATE {boxes} SET format = %d WHERE format = %d", $default, $edit['format']); - - cache_clear_all('filter:'. $edit['format'], true); - - drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $edit['name'])))); - } - drupal_goto('admin/filters'); - } - $format = arg(3); $format = db_fetch_object(db_query('SELECT * FROM {filter_formats} WHERE format = %d', $format)); - $form['format'] = array('#type' => 'hidden', '#value' => $format->format); - $form['name'] = array('#type' => 'hidden', '#value' => $format->name); - - return confirm_form('filter_admin_delete', $form, t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))), 'admin/filters', t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'), t('Delete'), t('Cancel')); - + if ($format) { + if ($format->format != variable_get('filter_default_format', 1)) { + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); + $form['name'] = array('#type' => 'hidden', '#value' => $format->name); + return confirm_form('filter_admin_delete', $form, t('Are you sure you want to delete the input format %format?', array('%format' => theme('placeholder', $format->name))), 'admin/filters', t('If you have any content left in this input format, it will be switched to the default input format. This action cannot be undone.'), t('Delete'), t('Cancel')); + } + else { + drupal_set_message('The default format cannot be deleted.'); + drupal_goto('admin/filters'); + } + } + else { + drupal_not_found(); + } } /** - * Menu callback; configure the filters for a format. + * Process filter delete form submission. */ -function filter_admin_format($format) { - if ($_POST['op']) { - $edit = $_POST['edit']; - filter_admin_filters_save($format->format, $edit); - } +function filter_admin_delete_submit($form_id, $form_values) { + db_query("DELETE FROM {filter_formats} WHERE format = %d", $form_values['format']); + db_query("DELETE FROM {filters} WHERE format = %d", $form_values['format']); - $output = filter_admin_format_form($format); + $default = variable_get('filter_default_format', 1); + // Replace existing instances of the deleted format with the default format. + db_query("UPDATE {node_revisions} SET format = %d WHERE format = %d", $default, $form_values['format']); + db_query("UPDATE {comments} SET format = %d WHERE format = %d", $default, $form_values['format']); + db_query("UPDATE {boxes} SET format = %d WHERE format = %d", $default, $form_values['format']); - // Composition tips (guidelines) - $tips = _filter_tips($format->format, false); - $extra = l(t('More information about formatting options'), 'filter/tips'); - $tiplist = theme('filter_tips', $tips, false, $extra); - if (!$tiplist) { - $tiplist = t('<p>No guidelines available.</p>'); - } - $group = t('<p>These are the guidelines that users will see for posting in this input format. They are automatically generated from the filter settings.</p>'); - $group .= $tiplist; - $output .= '<h2>'. t('Formatting guidelines') .'</h2>'. $group; + cache_clear_all('filter:'. $form_values['format'], true); + drupal_set_message(t('Deleted input format %format.', array('%format' => theme('placeholder', $form_values['name'])))); - return $output; + return 'admin/filters'; } /** - * Renders a form for a format + * Generate a filter format form. */ -function filter_admin_format_form($format) { - $edit = $_POST['edit']; - +function filter_admin_format_form($format = NULL) { $default = ($format->format == variable_get('filter_default_format', 1)); if ($default) { $help = t('All roles for the default format must be enabled and cannot be changed.'); $form['default_format'] = array('#type' => 'hidden', '#value' => 1); } - //Add the name of the object - $form['name'] = array('#type' => 'fieldset', '#title' => t('Name')); - $form['name']['name'] = array('#type' => 'textfield', '#default_value' => $format->name, '#description' => t('Give the name of this filter format'), '#required' => TRUE); + $form['name'] = array('#type' => 'textfield', + '#title' => 'Name', + '#default_value' => $format->name, + '#description' => t('Specify a unique name for this filter format.'), + '#required' => TRUE, + ); + + // Add a row of checkboxes for form group. + $form['roles'] = array('#type' => 'fieldset', + '#title' => t('Roles'), + '#description' => $default ? $help : t('Choose which roles may use this filter format. Note that roles with the "administer filters" permission can always use all the filter formats.'), + '#tree' => TRUE, + ); - //Add a row of checkboxes for form group - $form['roles'] = array('#type' => 'fieldset', '#title' => t('Roles'), '#description' => $default ? $help : t('Choose which roles may use this filter format. Note that roles with the "administer filters" permission can always use all the filter formats.'), '#tree' => TRUE); - $form['roles']['hidden'] = array(); foreach (user_roles() as $rid => $name) { $checked = strstr($format->roles, ",$rid,"); - $form['roles'][$rid] = array('#type' => 'checkbox', '#title' => $name, '#default_value' => ($default || $checked)); + $form['roles'][$rid] = array('#type' => 'checkbox', + '#title' => $name, + '#default_value' => ($default || $checked), + ); if ($default) { $form['roles'][$rid]['#attributes'] = array('disabled' => 'disabled'); } @@ -427,124 +425,160 @@ function filter_admin_format_form($format) { $all = filter_list_all(); $enabled = filter_list_format($format->format); - $form['filters'] = array('#type' => 'fieldset', '#title' => t('Filters'), '#description' => t('Choose the filters that will be used in this filter format')); + $form['filters'] = array('#type' => 'fieldset', + '#title' => t('Filters'), + '#description' => t('Choose the filters that will be used in this filter format.'), + '#tree' => TRUE, + ); foreach ($all as $id => $filter) { - $form['filters'][$id] = array('#type' => 'checkbox', '#title' => $filter->name, '#default_value' => isset($enabled[$id]), '#description' => module_invoke($filter->module, 'filter', 'description', $filter->delta)); + $form['filters'][$id] = array('#type' => 'checkbox', + '#title' => $filter->name, + '#default_value' => isset($enabled[$id]), + '#description' => module_invoke($filter->module, 'filter', 'description', $filter->delta), + ); } - $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration')); - return drupal_get_form('filter_admin_format_form', $form); + if (isset($format)) { + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); + + // Composition tips (guidelines) + $tips = _filter_tips($format->format, false); + $extra = l(t('More information about formatting options'), 'filter/tips'); + $tiplist = theme('filter_tips', $tips, false, $extra); + if (!$tiplist) { + $tiplist = t('<p>No guidelines available.</p>'); + } + $group = t('<p>These are the guidelines that users will see for posting in this input format. They are automatically generated from the filter settings.</p>'); + $group .= $tiplist; + $output = '<h2>'. t('Formatting guidelines') .'</h2>'. $group; + } + $output = drupal_get_form('filter_admin_format_form', $form) . $output; + + return $output; +} + +/** + * Validate filter format form submissions. + */ +function filter_admin_format_form_validate($form_id, $form_values) { + if (!isset($form_values['format'])) { + $name = trim($form_values['name']); + $result = db_fetch_object(db_query("SELECT format FROM {filter_formats} WHERE name='%s'", $name)); + if ($result) { + form_set_error('name', t('Filter format names need to be unique. A format named %name already exists.', array('%name' => theme('placeholder', $name)))); + } + } } /** - * Save enabled/disabled status for filters in a format. + * Process filter format form submissions. */ -function filter_admin_filters_save($format, $toggles) { +function filter_admin_format_form_submit($form_id, $form_values) { + $format = isset($form_values['format']) ? $form_values['format'] : NULL; $current = filter_list_format($format); - $edit = $_POST['edit']; - $name = trim($edit['name']); - $cache = true; - - //make sure a title is specified - if (strlen($name) == 0) { - form_set_error('name', t('You must enter a name for this input format.')); - return; - } + $name = trim($form_values['name']); + $cache = TRUE; - if (!$format) { //add a new filter format. - $new = true; + // Add a new filter format. + if (!$format) { + $new = TRUE; db_query("INSERT INTO {filter_formats} (name) VALUES ('%s')", $name); $result = db_fetch_object(db_query("SELECT MAX(format) AS format FROM {filter_formats}")); $format = $result->format; - drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $edit['name'])))); + drupal_set_message(t('Added input format %format.', array('%format' => theme('placeholder', $name)))); } else { drupal_set_message(t('The input format settings have been updated.')); } db_query("DELETE FROM {filters} WHERE format = %d", $format); - foreach ($toggles as $id => $checked) { + foreach ($form_values['filters'] as $id => $checked) { if ($checked) { list($module, $delta) = explode('/', $id); - // Add new filters to the bottom + // Add new filters to the bottom. $weight = isset($current[$id]->weight) ? $current[$id]->weight : 10; db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $format, $module, $delta, $weight); - // Check if there are any 'no cache' filters + // Check if there are any 'no cache' filters. $cache &= !module_invoke($module, 'filter', 'no cache', $delta); } } // We store the roles as a string for ease of use. - // we should always set all roles to true when saving a default role. + // We should always set all roles to true when saving a default role. // We use leading and trailing comma's to allow easy substring matching. - $roles = isset($edit['roles']) ? array_keys($edit['roles']) : array(); - $roles = ','. implode(',', ($edit['default_format'] ? user_roles() : $roles)) .','; + $roles = array(); + if (isset($form_values['roles'])) { + foreach ($form_values['roles'] as $id => $checked) { + if ($checked) { + $roles[] = $id; + } + } + } + $roles = ','. implode(',', ($form_values['default_format'] ? user_roles() : $roles)) .','; db_query("UPDATE {filter_formats} SET cache = %d, name='%s', roles = '%s' WHERE format = %d", $cache, $name, $roles, $format); cache_clear_all('filter:'. $format, true); - // if a new filter was added, return to the main list of filters, otherwise stay on edit filter page to show new changes + // If a new filter was added, return to the main list of filters. Otherwise, stay on edit filter page to show new changes. if ($new) { - drupal_goto('admin/filters/'); + return 'admin/filters/'; } else { - drupal_goto('admin/filters/' . arg(2)) ; + return 'admin/filters/'. $format; } } /** * Menu callback; display form for ordering filters for a format. */ -function filter_admin_order() { - $format = arg(2); - if ($_POST['op']) { - filter_admin_order_save($format, $_POST['edit']); - } - +function filter_admin_order($format = NULL) { // Get list (with forced refresh) - $filters = filter_list_format($format); + $filters = filter_list_format($format->format); + $form['weights'] = array('#tree' => TRUE); foreach ($filters as $id => $filter) { - $form['name'][$id] = array('#type' => 'markup', '#value' => $filter->name); - $form['weight'][$id] = array('#type' => 'weight', '#default_value' => $filter->weight); + $form['names'][$id] = array('#value' => $filter->name); + $form['weights'][$id] = array('#type' => 'weight', '#default_value' => $filter->weight); } + $form['format'] = array('#type' => 'hidden', '#value' => $format->format); $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration')); return drupal_get_form('filter_admin_order', $form); } +/** + * Theme filter order configuration form. + */ function theme_filter_admin_order($form) { $header = array(t('Name'), t('Weight')); $rows = array(); - foreach (element_children($form['name']) as $id) { + foreach (element_children($form['names']) as $id) { // Don't take form control structures - if (is_array($form['name'][$id])) { - $rows[] = array( - form_render($form['name'][$id]), - form_render($form['weight'][$id])); + if (is_array($form['names'][$id])) { + $rows[] = array(form_render($form['names'][$id]), form_render($form['weights'][$id])); } } $output = theme('table', $header, $rows); $output .= form_render($form); + return $output; } /** - * Save the weights of filters in a format. + * Process filter order configuration form submission. */ -function filter_admin_order_save($format, $weights) { - foreach ($weights as $id => $weight) { +function filter_admin_order_submit($form_id, $form_values) { + foreach ($form_values['weights'] as $id => $weight) { list($module, $delta) = explode('/', $id); - db_query("UPDATE {filters} SET weight = %d WHERE format = %d AND module = '%s' AND delta = %d", $weight, $format, $module, $delta); + db_query("UPDATE {filters} SET weight = %d WHERE format = %d AND module = '%s' AND delta = %d", $weight, $form_values['format'], $module, $delta); } drupal_set_message(t('The filter ordering has been saved.')); - cache_clear_all('filter:'. $format, true); - drupal_goto($_GET['q']); + cache_clear_all('filter:'. $form_values['format'], true); } /**