A block included with context, role visibility isn't respected.
I see that in context.core.inc around line 420

    // It's possible that there are still some leftover blocks in the enabled contexts.
    // Add these in as well.
    if (!empty($context_blocks)) {
      foreach ($context_blocks as $block) {
        $block = (object) $block;
        $block->status = 1;
        $block->enabled = TRUE;
        $block->page_match = TRUE;
        $block->throttle = FALSE;
        $block->title = '';
        $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
      }
    }

This piece of code is including any blocks that were originially excluded by the block _list query. Im not sure why this would be here. I commented this out and it appears to work, I'm not sure if it will screw something else up tho.

thanks

CommentFileSizeAuthor
#14 context.block_role.patch1.96 KBbrad.bulger

Comments

loze’s picture

It does screw other things up. So taking it out is no good.

It should probably check for roles here, instead of automatically setting status to 1. right?

roychri’s picture

Version: 6.x-2.0-beta5 » 6.x-2.0-beta7

I fixed this issue with this patch:

--- ./sites/all/modules/context/context.core.inc~       2009-08-25 21:38:14.000000000 -0700
+++ ./sites/all/modules/context/context.core.inc        2009-09-29 07:31:06.000000000 -0700
@@ -423,12 +423,14 @@ function context_block_list($region) {
     if (!empty($context_blocks)) {
       foreach ($context_blocks as $block) {
         $block = (object) $block;
-        $block->status = 1;
+        $block->status = db_result(db_query("select IF(count(*),1,0) from {blocks_roles} where module='%s' AND delta='%s' AND rid in (". db_placeholders($rids) .")", $block->module, $block->delta));
         $block->enabled = TRUE;
         $block->page_match = TRUE;
         $block->throttle = FALSE;
         $block->title = '';
-        $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
+        if ($block->status) {
+          $blocks[$block->region]["{$block->module}_{$block->delta}"] = $block;
+        }
       }
     }

What do you think?

Does this work with postgresql?
Is there a more efficient way of doing it? (To avoid the extra SQL queries).

Maybe we need to check the status in one query for all blocks, store that in some structure (array?) and then check the array in this loop rather than running the same query multiple times?

pasqualle’s picture

the visibility settings on admin/build/block page are not used with context. That's not a bug, that is by design..

roychri’s picture

@Pasqualle Interesting.... Then how would you suggest that I restrict access to a block (provided by a contrib module) to a role when this block is added using context?

pasqualle’s picture

Currently there is no way how to restrict the full context, or restrict a reaction..

brad.bulger’s picture

the role-based visibility is the only criterion that's ignored from the standard block configuration. at least, that's what it looks like to me. the context code is checking the page match and the enabled settings.

i changed the query to not exclude blocks which fail the role-based test, but instead return the role-based test results:

$result = db_query(db_rewrite_sql("SELECT DISTINCT b.*, CASE WHEN (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) THEN 1 ELSE 0 END AS role_matched FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge($rids, array($theme_key)));

and then add a check on the test results:

if (!$block->role_matched) {
  $enabled = FALSE;
}

that does the trick. the only leftover blocks, as far as i can see, would have been the role-disabled ones, so that code doesn't do anything anymore.

brad.bulger’s picture

bzzzzzt, no. that query is wrong, sorry. my test cases were too simple. multiple roles where some but not all match break it. there is (i hope) still a way to make it work but i am back at the starting line with it.

budda’s picture

I hate to say it, but.... subscribing. As I just came across this "feature" of context today.

The PHP visibility code doesn't work, nor the role tick box visibility.

The context admin page states "Selected blocks will be shown when this context is set provided that custom block visibility settings and/or throttling do not hide them." which isn't true.

loze’s picture

Here's what I have been using as a workaround:

1. I removed the snippet originally posted above (around 420 in context.core.inc)
2. Context then respects roles for your existing blocks. however, when you add a new block or install a module that adds blocks, They wont display using context.
3. So ... Go to the block admin page /admin/build/block/list and click save
4. then go back to context_ui and set your blocks, the new blocks will show up in the context_ui and they will respect role and PHP visibility.

Im assuming that when you save from the blocks admin page, some sort of cache gets built, or weights are assigned to new blocks, or something like that, which allows context_ui to then see them.

Its pretty annoying.

I think i remember reading another issue about this a while back, but i could be mistaken.

Wappie08’s picture

Yes, the same problems are also stated in http://drupal.org/node/345050

Still I think that it is very important that there is at least a workaround so I'll try the one from loze, thanks!.

In my opinion every site I build needs block visibility by role -> different menu's/blocks for logged in users and also different ones for admins..

Would really like to know the opinion of the development team on this, maybe a workaround by implementing visibility by role in Context itself is a solution having less downsides..

Greetings Wappi

socialnicheguru’s picture

is there a fix for this?

Anonymous’s picture

Looking for some clarity and developer approved workaround/fix for this.

Pasqualle #3 suggests that not respecting block visibility by role is by design. However in this thread: http://drupal.org/node/345050 yhahn #5 indicates that a patch was introduced to fix this issue and "Updated context_ui_block_list() to respect visibility and customization settings made through the block module", back in 2008: http://drupal.org/cvs?commit=158876. And as someone else pointed out module itself states "Control block visibility using context. Selected blocks will be shown when this context is set provided that custom block visibility settings and/or throttling do not hide them."

Thoroughly confused, which is it, a bug or by design?

Context is a great module but if by design I can't control visibility of blocks by role then it renders it fairly redundant, unless there is a workaround I am not aware of? For example, I use context to define a section on the site, there is a block on that page which is relevant to anonymous users, but completely irrelevant to authenticated users. How can I hide that block when authenticated users are viewing that page, without using block role visibility, or views block display access (which incidentally also doesn't appear to be respected)?

Many thanks in advance for clarification and guidance on this issue.

pasqualle’s picture

"Grayed out blocks are those provided by Drupal's standard block settings." Only for these blocks should be the block visibility setting respected. If you control a block with context, then the context setting is used, because you can easily create an opposite condition. And that would not make any sense.
for example:
block settings page: do not show for paths: user/*
context settings: paths: user/*

block visibility by role is generally a bug in Drupal. It should be replaced with a correct access check, then it will be respected by every contrib module.

the views access check should be always respected. if it is not, then it is a bug.

brad.bulger’s picture

StatusFileSize
new1.96 KB

it might not make sense but making sense has never been a necessary precondition for using software.

it does in fact check the pages condition right now. and it will exclude the block if it fails that condition. it also checks the user visibility setting. it does that after removing the block from the list in $context_blocks. the reason that role visibility is not respected is that those blocks are not returned by the query, and so they are left in $context_blocks, and automatically enabled - with their titles cut off for some reason.

i'm attaching the patch that i'm using to deal with this, which does seem to be working. i have never run into any of the problems like what @loze and @budda describe above. i do use admin_theme to run the context admin screens in my site's theme, not in the admin themes, that might be related.

pasqualle’s picture

Status: Active » Needs review
socialnicheguru’s picture

did you mean to comment out the following in your patch. I don't think $result is defined in this function before this.

--- 358,374 ----

+ // $result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b
LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.
theme = '%s' AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDE
R BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key),
$rids));
+

brad.bulger’s picture

that's the original line of code. this was not intended to be a complete fix to the issues raised here, it's just the workaround that i am using at the moment. i don't get the problems of having the page visibility settings be ignored, for instance, that some people have reported above. so this does not address that. i only posted it here as an example that i thought might be useful.

Stalski’s picture

subscribing , i will use preprocess_block for now.

ppatriotis’s picture

subscribing, going to try brad's patch out.

miche’s picture

subscribing

socialnicheguru’s picture

Version: 6.x-3.0-beta3 » 6.x-2.0-beta7

While the patch above worked well for me and version 2. I still am having the same issue in beta 3 of context :(

Edit:
I would like to keep the block behavior consistent ie. role and where it shows up. This will give greater control for visibility within a space. In addition it keep the block paradigm which I have come to love :)

bibstha’s picture

Version: 6.x-2.0-beta7 » 6.x-3.0-beta3

Agree with @SocialNicheGuru having problem with 3-beta.
The problem is, say in front page, i want to display 5 blocks but control visibility of 2 of the blocks by role.
There however is not possible without creating two different contexts, and that too will not allow ordering of the blocks.
Also in 3-beta, the default drupal blocks are not shown at all.

Any solution?

yhahn’s picture

Version: 6.x-2.0-beta7 » 6.x-3.0-beta3
Status: Needs review » Closed (won't fix)

In the 3.x branch there is now a generic user role condition. This combined with the AND/OR condition support should get your pretty far in terms of controlling block visibility using context.

I won't be adding support to context for handling the Drupal core block visibility settings (PHP eval, path, user role, etc.) but you are welcome to implement your own reaction plugin override. See API.txt for how override or replace a context plugin.

socialnicheguru’s picture

Another use case.

Using exposed filter block for views is an example.

I have a view with page 1, page 2, and page 3.

I have exposed filter on each of them.

how do you suggest that I arrange it so that only exposed filter block for page 1 just shows up on page 1 since no block visibility settings are respected? Right now, all exposed filters show up regardless of what page I set for visibility.

Your guidance would be very helpful.

socialnicheguru’s picture

@yhahn, can the reaction plugin override be written to just adhere the Drupal core block visibility settings (PHP eval, path, user role, etc.)? I am not a programmer but will take a stab at this but i would like to know the parameters.

Thanks.

yhahn’s picture

Yes, you could do this if you like. Your overriding reaction class can override any of the methods in the default context_reaction_block class.

socialnicheguru’s picture

Status: Closed (won't fix) » Active

This is what I have done.

I redefined block_list in context_reaction_block class

I tried to make sure that $block->visibility is correctly set.
I took a look at the structure for block in the database and I did not see $block->enabled. But I kept it in anyway just in case.

I used dsm ($block) to see which values were enabled.
I see this:
enabled (Boolean) FALSE
visibility (Boolean) FALSE
page_match (Boolean) TRUE

I can't figure out why the block is still appearing if the values for enabled and visibility are false as defined above

Is context looking at something else to determine the visibility of blocks on the page?

darkodev’s picture

Similar to #27, set $block to false in mymodule_block_preprocess(), but block still shows

I just want a block to show for admin role with a link to /admin, for example

As with most things Drupal, there's a hackish method to get this working with views (since context does obey view access settings):
- create a view that returns empty result set (I created an argument that will never exist, and set "display empty text")
- create a block display, and set some empty text (link to /admin, for example)
- set the display's access settings for whichever role(s) you want
- display the block in a region on the context settings page

This method stops me from abandoning the much-beloved context module

darkodev’s picture

yhahn, feel like throwing us a bone with some pseudo-code for the override? Would like to the know the correct way of approaching this.

iLLin’s picture

This also affects blocks that have BLOCK_NO_CACHE. I am using the menu_block module and its not supposed to cache the blocks. By using context and turning on block caching on the performance page, the blocks still get cached.

himerus’s picture

Subscribing.

I'm just now running into issues with this.

I would just use the block manager to manually place the block(s) in question, BUT they need to be placed in different regions based on context... hence where context is valuable.
This is a MUST have for this module. I've had a developer friend that has mentioned this flaw to me, and I had not until now had the need for it to work this way as I rarely use blocks placed by role in certain circumstances.

iNade’s picture

Subsribing too..

socialnicheguru’s picture

is there any guidance on this one?

Can I chipin with someone? This is a major hold up for me. anyone else in the same situation?

kinaya’s picture

I used a workaround where I created custom template for the block, ie "block-menu-menu-nameofmenu.tpl.php". In this template file i put a condition around the content to check if the current user is logged in or not:

 global $user; 
if($user->uid != 0) { 

}

FreeFox’s picture

+1 subscribing

steveoliver’s picture

What a bummer. :(

mrtorrent’s picture

Subscribing

kyle_mathews’s picture

Something else I just noticed perhaps relevant to this issue. I create a custom block on the site and added it to a context. This block wasn't visible to anonymous users until I explicitly gave that role permission in the block edit form.

yhahn’s picture

Status: Active » Closed (won't fix)

As described above, you can extend the context block reaction class using your own plugin and implement as many or as few of Drupal core's block visibility handling rules as you like.

Please see API.txt in context for how to add your own plugins.

jhodgdon’s picture

As a note, the "above" is in comments #25 and #26. Someone failed to make it work in #27. I'm going to try again in a few days (I also need this for a site), and will attach code if I find something that works.

jhodgdon’s picture

Never mind. I am using Context 2.x, so I am just going to use the patch in #14 above, which I think will work.

Yuri’s picture

subscribing

martysteer’s picture

Has anyone had a stab at extending the context block reactions yet?

I'm finding certain situations where the core drupal block visibility handling would be much simpler than refactoring blocks/contexts to govern visibility.

Perhaps the Context 3 module setting for disabling/enabling the Drupal core block module system could also enable/disable the processing of Drupal core block visibility settings (PHP eval, path, user role, etc.)?

Yuri’s picture

I totally agree, the current blocks/context management sucks. I am switching back to core drupal block settings if this doesn't improve.

kevinwal’s picture

I just made a module that extends the context reaction class to do this per the suggested correct solution at:

http://drupal.org/project/context_respect

The initial release should be available soon.

ressa’s picture

Version: 6.x-3.0-beta3 » 6.x-3.0

I think this has been fixed now, in version 6.x-3.0? I had forgotten to add the administrator role to user #1 (the admin) so the blocks didn't show up, even though I had set a condition "User role" to "administrator".
After adding the administrator role to user #1 the blocks now only show for user's with the administrator role.

Michsk’s picture

no, this is not fixed in v3.

context_respect module does the trick, tough i'm still waiting for a context fix for this to be comitted.

hedac’s picture

I don't understand why we have to install respect small module... and not patching context.
Context Respect works
but.. why?

Grayside’s picture

Because if you configure block visibility using Drupal's Core conditions, they won't export when you build a feature.

However, if you use Context's conditions which do or can easily match all of core's block visibility settings, you can not only control visibility just as effectively, but you can package it up as a feature for deployment.

Supporting this is a nice-to-have, but it will potentially confuse site-builders in the process of switching from core block configuration to using Context.

Not quite sure what @Yuri does not like about Context UI. I am in favor of hiding settings from Core block configuration, but it may end up being deceptive since Block modules can technically set non-vanilla defaults.

Maybe the answer there is actually to pursue the "Context Respect", but to lock down or hide the Block Visibility settings as much as seems reasonable.

Michsk’s picture

Grayside: strong argument.