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
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | context.block_role.patch | 1.96 KB | brad.bulger |
Comments
Comment #1
loze commentedIt 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?
Comment #2
roychri commentedI fixed this issue with this patch:
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?
Comment #3
pasquallethe visibility settings on admin/build/block page are not used with context. That's not a bug, that is by design..
Comment #4
roychri commented@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?
Comment #5
pasqualleCurrently there is no way how to restrict the full context, or restrict a reaction..
Comment #6
brad.bulger commentedthe 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:
and then add a check on the test results:
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.
Comment #7
brad.bulger commentedbzzzzzt, 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.
Comment #8
buddaI 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.
Comment #9
loze commentedHere'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.
Comment #10
Wappie08 commentedYes, 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
Comment #11
socialnicheguru commentedis there a fix for this?
Comment #12
Anonymous (not verified) commentedLooking 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.
Comment #13
pasqualle"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.
Comment #14
brad.bulger commentedit 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.
Comment #15
pasqualleComment #16
socialnicheguru commenteddid 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));
+
Comment #17
brad.bulger commentedthat'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.
Comment #18
Stalski commentedsubscribing , i will use preprocess_block for now.
Comment #19
ppatriotis commentedsubscribing, going to try brad's patch out.
Comment #20
michesubscribing
Comment #21
socialnicheguru commentedWhile 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 :)
Comment #22
bibstha commentedAgree 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?
Comment #23
yhahn commentedIn 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.
Comment #24
socialnicheguru commentedAnother 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.
Comment #25
socialnicheguru commented@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.
Comment #26
yhahn commentedYes, you could do this if you like. Your overriding reaction class can override any of the methods in the default context_reaction_block class.
Comment #27
socialnicheguru commentedThis 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?
Comment #28
darkodev commentedSimilar 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
Comment #29
darkodev commentedyhahn, feel like throwing us a bone with some pseudo-code for the override? Would like to the know the correct way of approaching this.
Comment #30
iLLin commentedThis 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.
Comment #31
himerus commentedSubscribing.
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.
Comment #32
iNade commentedSubsribing too..
Comment #33
socialnicheguru commentedis 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?
Comment #34
kinaya commentedI 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:
}Comment #35
FreeFox commented+1 subscribing
Comment #36
steveoliver commentedWhat a bummer. :(
Comment #37
mrtorrent commentedSubscribing
Comment #38
kyle_mathews commentedSomething 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.
Comment #39
yhahn commentedAs 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.
Comment #40
jhodgdonAs 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.
Comment #41
jhodgdonNever mind. I am using Context 2.x, so I am just going to use the patch in #14 above, which I think will work.
Comment #42
Yuri commentedsubscribing
Comment #43
martysteer commentedHas 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.)?
Comment #44
Yuri commentedI totally agree, the current blocks/context management sucks. I am switching back to core drupal block settings if this doesn't improve.
Comment #45
kevinwal commentedI 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.
Comment #46
ressaI 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.
Comment #47
Michsk commentedno, 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.
Comment #48
hedac commentedI don't understand why we have to install respect small module... and not patching context.
Context Respect works
but.. why?
Comment #49
Grayside commentedBecause 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.
Comment #50
Michsk commentedGrayside: strong argument.