I am trying to use hook_form_alter() to hide the input format selection fields on CCK text areas for some of my users, but I have yet to find a way of doing this that didn't also disable my WYSIWYG editor on the field. Can you provide a documented method for achieving this? The need to hide these options is not uncommon.

For instance, what if WYSIWYG recognized that $form['field_page_body'][0]['format']['#type']='hidden' and $form['field_page_body'][0]['format']['#value']=3. Then it could just assume it should use input format 3 for the field_page_body text area and not try to attach anything to the radio buttons. That would allow me to unset everything else in that variable.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

TwoD’s picture

Category: feature » support
Status: Active » Fixed

Check out how the Better Formats module does this. They imitate what filter_form() does when there's only one format available. The trick is to make the format setting a hidden value like you do, but also add the div normally used to show the format description. It can be empty but it's needed so Wysiwyg has something to attach field-specific information to (in the form of CSS classes parsed to 'parameters' when attaching an editor).

jstoller’s picture

Status: Fixed » Active

Can you please be more specific? I've looked at Better Formats (in fact I have it enabled), but I'm having some trouble following the code. And this is complicated somewhat, as I am working with CCK fields, rather than the default Body field. In my module, I've set up something like the following:

<?php
/**
 * Implement hook_form_alter()
 */
function csc_page_form_alter(&$form, $form_state, $form_id) {
  // Alter visibility of fields on node edit forms
  if ($form['#id']=='node-form') {
    // Add an after_build function to process when everything's complete.
    $form['#after_build'][] = 'csc_page_form_alter_after_build';
  }
}


/**
 * Modify CCK form elements on node forms
 */
function csc_page_form_alter_after_build($form, &$form_state) {
  switch($form['type']['#value']){
    case 'page':
      $form['field_page_body'][0]['format'] = csc_page_hide_node_format($form['field_page_body'][0]['format']);
      break;
  }
  return $form;
}


/**
 * Hide formats fieldset for node fields.
 */
function csc_page_hide_node_format($format) {
  $new_format = array();
  // What goes here?????
  return $new_format;
}
?>

What should I put in that csc_page_hide_node_format() function to both hide the fieldset and permit WYSIWYG to function?

TwoD’s picture

Status: Active » Fixed

CCK fields use filter_form() just like the body field does, so I think Better Formats should be able to hide the format selectors there too - without the need for this hook_form_alter code, but you can't set different defaults for body and CCK fields until #350696: Per field format settings with full BF options via CCK widget is fixed.

In better_formats.module (line 491) you can see their version of filter_form(), which would be the equivalent of your csc_page_hide_node_format() function.
The important part is in the else statement for if (count($formats) > 1 && $show_selection) { - that is when there's only one format or the selection shouldn't be shown:

  $formats = filter_formats(); // Gets a list of all available formats, keyed by their id.
  $default = FILTER_FORMAT_DEFAULT // The id number of the input format which should be used.
  // .......
 
  $format = $formats[$default];
  $form[$format->format] = array(
    '#type' => 'value',
    '#value' => $format->format,
    '#parents' => $parents,
  );

  if ($show_tips) { // If you don't want format tips, just add the guidelines part in the else case, which is an empty '#type' => 'markup' "field" rendered as a div.
    $tips = _filter_tips($format->format, FALSE);
    $form['format']['guidelines'] = array(
      '#title' => t('Formatting guidelines'),
      '#value' => theme('filter_tips', $tips, FALSE),
    );
  }
  else {
    // Ensure expected filter_form() structure.
    // see drupal.org/node/344169
    $form['format']['guidelines'] = array(
      '#title' => t('Formatting guidelines'),
      '#value' => '',
    );
  }

  // Only show long tips link if there are guidelines to the format.
  if ($show_tips_link) {
    $extra = theme('better_formats_filter_tips_more_info');
    $form[] = array('#value' => $extra);
  }
  else {
    // Ensure expected filter_form() structure.
    // see drupal.org/node/344169
    $form[] = array('#value' => '');
  }
jstoller’s picture

Status: Fixed » Active

I started modifying the code from Better Formats, as you suggested, but when I realized that Better Formats provides permissions settings to enable/disable the visibility of this element (I don't know how I missed this before), I thought I'd give that a try. Unfortunately, it doesn't work.

I created a user with an Editor role that can edit node content, but does not have the "show format selection for nodes" permission provided by Better Formats. The format selection fields are hidden as promised, but my WYSIWYG editor is disabled as well. If I grant the Editor role permission to "show format selection for nodes" then both the format selection field and the WYSIWYG editor return.

So it seems the method used by Better Formats to hid the input format selection fields does not preserve WYSIWYG functionality after all. Now I seem to be back where I started. Am I missing something, or are there any other methods I could use to hide these fields?

TwoD’s picture

That should indeed have worked, I use that configuration myself on several sites.
Are you able and willing to give me access to the site and role that so I can debug the issue? I'll only need access to somewhere where the editor should show up.

TwoD’s picture

Status: Active » Postponed (maintainer needs more info)
Francewhoa’s picture

Status: Postponed (maintainer needs more info) » Active

Confirming #4. "hid the input format selection fields does not preserve WYSIWYG functionality"

Steps to reproduce
1. Created a user with an Editor role that can edit node content, but does not have the "show format selection for nodes" permission provided by Better Formats.
2. Go to admin/settings/filters set only ONE input format for the user role.
3. Test. WYSIWYG is not display. Expected result is to display WYSIWYG.

If you redo above steps but set TWO input format for the same user role WYSIWYG is display.

So it seems that WYSIWYG is not display when only one input format is authorized for a given user/role, but it is display when two input formats are authorized

Related issue with FCKeditor https://community.openatrium.com/issues/node/2561

TwoD’s picture

Are you sure that the role really has a single format available? When format selection is disabled you might not realize that the role also has access to the site default format, as all roles do.
If the role's format is not also the site's default format you must also ensure that the format you assigned the editor to is the default format for that role in Better Formats.

On admin/settings/filters/defaults rearrange the roles so the role you created/used for the user is above that of anonymous, authenticated or other roles of lesser importance. The first role held by the user, from top down in that list, determines which format is the default one.

We did identify a problem when having just format enabled, but that was for D7 and happened because of changes in FAPI - and the "selected format was disabled" functionality when editing an existing node.
In D6 I've not been able to verify this issue.

Francewhoa’s picture

Are you sure that the role really has a single format available.
Yes I triple checked and can confirm that the role has a single format.

Steps to set the role with a single format:
1. Go to admin/settings/filters
2. Click on the top first 'configure' link
3. Under 'Roles' section uncheck all boxes so no role are selected
4. Redo above step 2 and 3 for each input format at admin/settings/filters
5. Go to admin/settings/filters
6. Chose one input format you want to use. Click on 'configure' link next to it. Under 'Roles' section uncheck only one role
7. Test. WYSIWYG will not display.

Redo all above steps except at step 6 check two input formats for the same role. Test. WYSIWYG will be display.

It seems that WYSIWYG depends on the input format

TwoD’s picture

Sorry to be a nitpick, but those steps cannot be followed.
Step 4 says to redo step 2 and 3 so all formats will have all roles unchecked. That is not possible because the site's default format has all roles checked and the boxes are disabled.
If the format chosen for testing is the site's default format - which is the only way to have just one format active for a role - step 6 is not possible to do as no checkboxes can be changed. (Btw, I'm assuming you meant "check only one role" as the previous steps already unchecked them all.)

If the steps don't include going to admin/settings/filters/defaults and re-arranging the roles, so that the role used to test with is above the others, the default settings means the role in question is prioritized lower than say "authenticated user". As all users are authenticated, that will match the current user and the default format set there will be used. If the first encountered format valid for a role is set to the site's default format, what's actually set on the role's row doesn't matter.

If Better Formats has also been set to not show the format selector for the given role, it'll look as if there's only a single format available, but it'll most likely be the site's default role, not the default set for the role, due to the priorities on admin/settings/filters/defaults.

sun’s picture

The patch over in #950216: No editor for singular filter format might help to resolve this issue.

Francewhoa’s picture

Thanks sun :)

sun’s picture

#1065672: Compatibility with better_formats has been marked as duplicate. Contains a patch attempt. However, let's try to think some more about the changes in #950216: No editor for singular filter format and whether they are able to help to resolve this.

Agileware’s picture

Version: 6.x-2.1 » 6.x-2.3

Subscribing...

Still an issue with the current version.

If this issue is now for better_formats integration it probably should be a feature request or bug report.

kclarkson’s picture

Has this feature been incorporated with Better formats ?

I too am having issues removing the input filter link, with WYSIWYG.

Funny thing is that drupal.org is working perfectly so I wonder how they do it. As I write this post there is a WYSIWYG but not input format link.

TwoD’s picture

@kclarkson, Drupal.org does not use wysiwyg.module. But it has nothing to do with whether an input format is available or not so that doesn't matter.

When you say "input format link", don't you mean "input format selectbox"?
I can clearly see the "More information about formatting options" link below the format description, but I do not see a selectbox to pick a different input format since I do not have access to more than one.

Please see my post in #8. The selectbox will only disappear if the user's role(s) only has access to a single format or they don't have the "show format selection for [nodes|blocks|comments]" permission.

If you really meant the "More information about formatting options"-link, Better Formats can hide that and/or the description above it regardless of how many formats are available by checking the "show more format tips link" and "show format tips" permissions.

If you get Better Formats to not show the selectbox, a format with an assigned editor is the default format, but no editor shows up, then you have the problem discussed here. That should have been fixed by #950216: No editor for singular filter format, but we might have missed something.

RobW’s picture

Status: Fixed » Active

Bumping to 7.x, if that's cool. I'm running into the same/similar problem, using a custom module to create a permission to restrict access to the format selector.

But it seems like WYSIWYG needs the format select box in order to attach the correct editor. I can hide the select with css, or remove it with js after the wysiwyg loads, but I can't remove it serverside with something like:

  $element['format']['format']['#access'] = FALSE;

Is there any way to let WYSIWYG know what the default format for that role/field is without the selectbox?

sun’s picture

Version: 6.x-2.3 » 7.x-2.1
Status: Active » Fixed

#950216: No editor for singular filter format fixed this issue for D7, allowing the server-side code as shown in #17.

There's no equivalent solution for D6 other than better_formats. Thus, marking as fixed.

RobW’s picture

Status: Active » Fixed

Thanks for the quick response. You're right, works fine.

My problem was setting #access to false when there are multiple available text formats causes WYSIWYG to default to plaintext (or the universally available text format) which I didn't have an editor on. Resetting the #options array so it only contains the user's default format gave me the result I was looking for.

If anyone else wants to do the same:

$element['format']['format']['#access'] = FALSE;

// Get the top choice in the #options array.
$options_array = $element['format']['format']['#options'];
reset($options_array);
$first_key = key($options_array);
$first_value = $element['format']['format']['#options'][$first_key];

// Overwrite everything else.
$element['format']['format']['#options'] = array(
  $first_key => $first_value,
);

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

rocketeerbkw’s picture

Status: Closed (fixed) » Active
FileSize
684 bytes

I think what RobW found is a subtle bug. There is a foreach loop over the text formats that sets $format_id which is used later, outside the loop.

There are two instances (I can think of now) where $element['format']['format']['#access'] = FALSE;; When the user has access to only one text format (core) and when another module sets it (better formats, custom, etc). In the latter case, there may be more than one format available to the user, but the loop makes WYSIWYG use the least specific instead of the most specific.

Here's a patch that forces selecting the most specific format.

rocketeerbkw’s picture

Version: 7.x-2.1 » 7.x-2.x-dev
Category: support » bug
Status: Active » Needs review

I've been using #21 for awhile and I haven't seen any negative side effects.

TwoD’s picture

@rocketeerbkw, Ok, I see what you mean. But if you also remove the "unavailable" formats from #options Wysiwyg will pick the correct format, and there's less potential that the user could perhaps exploit a loophole and pick one of the other formats that are still valid. (Note: that would only apply in cases where forms are submitted with drupal_form_submit(), which bypasses #access restrictions.)

But still, I think we should look at the actual value of the format selector to determine which format to use, as it may not be the first or last format in the list (btw, reset() returns the first value in the array so no need to also call key()).

This takes care of the case when $element['format']['format']['#access'] = FALSE; has been set (in a #pre_render callback), but if we also want to cover when $element['format']['#access'] = FALSE; has been set, we'll need to use the -alt patch which moves the hidden input field Wysiwyg creates to hold the selected format to a higher level.

I've tested this with user 1 having access to all formats and a "Simple" user with permission to a subset of those formats but always permission to edit the nodes created by user 1. A node was created with fields using a couple of different formats Simple has permissions to use.

In the case without custom access restrictions Simple gets to use the same format/editor and is allowed to pick any of the other formats available to that user. This also worked before the patch.
In the case where Simple only has access to the site default format and that format is in use for a field, Wysiwyg is still able to initialize the correct editor.

In the case where there is custom code to restrict access to the format selectors, and the node uses a format Simple normally has permission to use, Simple is no longer allowed to pick a different format but the editor associated with the current format is initialized properly.
This is where it was previously required to reduce the #options array to the currently used format to be sure Wysiwyg would always try to initialize the correct one.

The -alt patch needs to move the hidden element inserted by Wysiwyg when $element['format']['#access'] = FALSE; is set (to disable both the selector and the guidelines in one go) because the hidden element is normally placed below $element['format'], which is no longer rendered. I'm not sure if this is very useful since the guidelines could be disabled separately, but it's a pretty small change anyway.

I would like sun to take a look to see if I missed something when moving the hidden field.

rocketeerbkw’s picture

I tested both patches separately and they worked for me.

I agree that setting $format_id = $format_field['format']['#value']; is a better approach than just picking the first #options and still works as I expect in my use case (using Better Formats to hide format selection).

The -alt patch also looks OK to me and I tested it by patching Better Formats to use $element['format']['#access'] = FALSE; instead of $element['format']['#type'] = 'container';. The WYSIWYG editor still loads correctly and it even fixes a bug where you get an empty container shown w/border.

My vote is to for -alt patch.

berenddeboer’s picture

Status: Needs review » Reviewed & tested by the community

I've applied patch #23, wysiwyg started working immediately again.

jenlampton’s picture

+1 for the -alt patch.
I have this patch, plus #1706130: Strange blank border under the element with enabled better formats (as mentioned in #24) working together on my site.
Thanks everyone.

vinoth.3v’s picture

I run into this same issue, and I fixed it with my custom module. It simply hides the format selection. It may helps someone who don't need more control over better formats.


// hide_format.module

function hide_format_element_info_alter(&$type) {
  $filter_process_format_location = array_search('filter_process_format', $type['text_format']['#process']);
  $replacement = array('filter_process_format', 'hide_format_filter_process_format');
  array_splice($type['text_format']['#process'], $filter_process_format_location, 1, $replacement);
}

function hide_format_filter_process_format($element) {
  $element['format']['guidelines']['#access'] = FALSE;
  $element['format']['help']['#access'] = FALSE;

  if (!user_access('administer site configuration')) {
    $element['format']['format']['#prefix'] = '<div class="element-invisible">';
    $element['format']['format']['#suffix'] = '</div>';
  }
  return $element;
}

kclarkson’s picture

Is there a reason that patch #23 is not being committed ?

TwoD’s picture

Assigned: Unassigned » sun

I wanted sun to have a look at the two patches in #23 and get his input before committing either one, but I forgot to actually assign it to him...

I personally prefer the larger patch since it covers more cases that I think would seem logical to do from the perspective of other modules when wanting to remove the whole format selector. The first patch only allows denying access to the format selector (while keeping Wysiwyg functional) if you explicitly set the '#access' key on a level lower than would normally be required without seeing any side-effects (like Wysiwyg suddenly not working).

I'll commit the second patch if sun doesn't have time to dig into this.

TwoD’s picture

Switching back to "Needs review" just to see if it get's sun's attention. If not, I'll commit the -alt patch before the next release.

TwoD’s picture

Status: Reviewed & tested by the community » Needs review

Trying again...

matthiasm11’s picture

Is it possible to add the patch to the dev-release?

Thanks!

rfsbsb’s picture

Status: Needs review » Reviewed & tested by the community

I changed it back to RTBC since patch #23 alt version is working perfectly.
I hope it get into a release soon.

ryan.gibson’s picture

Thanks for this! :D

TwoD’s picture

Status: Reviewed & tested by the community » Fixed

Committed the -alt patch from #23 to 7.x-2.x. The -dev snapshots will be updated within 12 hours and this will be part of the next release.

Commit: 439b02f

Thank you all for reporting, patching, testing and commenting!

joachim’s picture

Given this is a major bug when using Better Formats module (#1687956: wysiwyg not shown when no permission to select text format), it would be great to see a new release with this fix quite soon.

muschpusch’s picture

+ 1 for a new release since wysiwyg is bundled in different distributions

TwoD’s picture

I agree a new release would be very handy, but we still have a couple of big problems to fix (mainly CKEditor ACF, TinyMCE 4 support) before a new release would be safe.

rocketeerbkw’s picture

You can follow and help on issues that need to get in before a new release at #1953106: Roll 7.x-2.3 release of Wysiwyg

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

brad.bulger’s picture

Issue summary: View changes
Status: Closed (fixed) » Fixed

This is in the git repository, but it is not in the version that is available as 7.x-2.x-dev - can that be fixed?

rocketeerbkw’s picture

I just checked, this is in the latest dev release marked

; Information added by Drupal.org packaging script on 2014-05-08
version = "7.x-2.2+34-dev"

TwoD’s picture

Status: Fixed » Closed (fixed)

The -dev snapshots are repackaged automatically based on the 5.x-2.x, 6.x-2.x, and 7.x-2.x branches. Don't think I can do anything on my end if that doesn't work.

Closing again since I can confirm what @rocketeerbkw said.

agerson’s picture

I am experiencing this issue with the current versions.

fonant’s picture

I too still need to apply this patch, to stable release WYSIWYG version 7.x-2.2 which is very old now.

Any chance of an official WYSIWYG 7.x-2.3 release?