Here's the default_filter_nodeapi() function:

/**
  * On node insert, get the lightest-weighted default filter for the user's
  * roles and set the node's format to that value. This handles cases in which
  * the user bypasses the node form (e.g. by using a blog editing client).
  */
function default_filter_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){
        if($op == 'insert'){
                $format = default_filter_retrieve($node->type);
                file_put_contents('C:\Debug.txt', "Format = $format\n", FILE_APPEND);
                if($format > 0){
                        $node->format = $format;
                }
        }
}

Actually, you can see that I added a debug statement to the function.

When I use w.bloggar to post a new blog entry, I get "Format = 2". When I look directly at the node_revisions table's 'format' field, I see '0'. It appears that what the code is trying to do is not working.

On display, a format of 0 is displayed by getting the variable 'filter_default_format' , which bypasses the default_filter module. If I thought about this for a while, I might be able to find some security problem. Personally, I like what default_filter_nodeapi is trying to do; it's just too bad that it isn't working.

Comments

dllh’s picture

What version of Drupal are you using? There appear to be some differences between how 5.1 and 5.2 handle the name of the format/filter attribute. I've corrected this in parts of the code, but perhaps this is another part of the code that needs to be updated. That said, I've had this working recently in both 5.1 and 5.2.

If you post through the Drupal UI, does it work as expected? Is this perhaps a w.bloggar (or other blog client) issue? Part of the aim of the module is to make this functionality work for client-side blog editors, but I don't believe I tested any, so it's distinctly possible this is an issue.

DriesK’s picture

Status: Active » Needs review
StatusFileSize
new698 bytes

I was having the same problem when using a blog client.

node_save() (node.module) only calls node_invoke_nodeapi($node, 'insert') _after_ the node has been inserted into the database. Therefore, changes made to the node object on $op == 'insert' though hook_nodeapi will not be saved automatically.

The attached patch directly changes the node_revisions table. I tested it with an external blog client, and it works.

freixas’s picture

In answer to the question by dllh, I am using Drupal 5.2.

DriesK’s picture

@freixas: thanks for getting back about this.

However, it really doesn't make a difference: node_invoke_nodeapi($op = 'insert') has always been called after database insertion, it's not version specific. The current code in default_filter_nodeapi() would never have worked I'm afraid...

DriesK’s picture

Status: Needs review » Needs work

Hold on. The fact that hook_nodeapi now works with this patch, means that the node will actually _always_ have the default input format after inserting it, no matter which checkbox the user selected (this would have happened as well if the original code would have worked by the way).

This isn't good -- and it's related to this issue as well. I'll try to work out a solution for both.

DriesK’s picture

Assigned: Unassigned » DriesK
Priority: Normal » Critical
Status: Needs work » Needs review
StatusFileSize
new3.29 KB

In attachment is a patch that solves this issue, together with this issue, and with another yet unreported issue. The reason I didn't prepare three separate patches is that they are all related, and that some patches are on the same line. Therefore, this one patch makes committing easier.

Here is an overview of what has been changed:

$form['default_filter_passed_form'] = array(
  '#type' => 'value',
  '#value' => 1,
);

has been added to default_filter_form_alter(). It allows default_filter_nodeapi to distinguish between nodes that are being inserted through the node editing form, and nodes being inserted otherwise. As explained above, this is needed, because otherwise the input format that is saved into the db is always the default format, irrespective of whether the user changed this in the node editing form.

if(array_key_exists($format_key, $form['body_filter']) && $format && !isset($form['nid']['#value'])){

here, $format is added earlier on because there was a bug that caused _no_ input format at all to be selected for all node types for which no explicit setting had been saved with default_filter.module. Obviously, if no specific settings have been made, nothing in the node form should be unset to start with. The second addition is that we now also check for the presence of a nid. If there is one, the node has been saved before. In that case, we also don't want to select the default input format, but the one that the user choose when creating or updating the node.

if(isset($form['body_filter'][$format_key][$format])){

here, $format > 0 has been removed, because the format check has been moved over to the enclosing if-statement (see above)

$form['body_filter'][$format_key][$format]['#default_value'] = $format;

this solves the preview-issue. #value has been changed to #default_value, so the user can actually choose his input format :-)

if($format && !isset($node->default_filter_passed_form)){
  db_query('UPDATE {node_revisions} SET format = %d WHERE nid = %d', $format, $node->nid);

here, in default_filter_nodeapi, the $format check is extended with the default_filter_passed_form check that was introduced earlier. Furthermore, the $node->format = $format code was removed as explained in an earlier post: hook_nodeapi() is called _after_ node_save().

$format = 0;	
if(sizeof($roles) > 0){

this code has been removed entirely. First, in Drupal every user _always_ has at least 1 role (anonymous or authenticated). This is _also_ true for user 1. The check is redundant.
Furthermore, db_result returns FALSE if there is no result. A boolean is better than the > 0 trick, so why not just use the default return value? This is also the reason that all >0 statements have been removed in the code above and replaced with just $format (which is typecast to TRUE when containing an integer).

All code has been tested: using the node editing form, doing previews, doing updates, with and without explicit settings, with various roles, and also with an external blog client.

DriesK’s picture

StatusFileSize
new19.61 KB

To conclude.

This patch is an identical copy of the previous patch, code-wise. The only difference is that this patch also does a big code cleanup, to make this module compliant with the Drupal coding standards (tabs are replaced by double spaces, arrays end with a comma, $Id$ has been inserted, indenting has been improved, ...)

The previous patch is there to show you what has been changed. This patch doesn't change anything else, but this is the one that should be committed ;-)

dllh’s picture

Status: Needs review » Fixed

I've applied these changes, in addition to a postgres compatibility check submitted elsewhere. Thanks for your work!

Anonymous’s picture

Status: Fixed » Closed (fixed)