Idea for how to get blocks to ‘dock’ automatically.

Idea for how to get blocks to ‘dock’ automatically.

by Joe Cape -
Number of replies: 14
Picture of Plugin developers

In the database, go to the mdl_user_preferences table. Notice the tuples where the name field is of the form ‘blockXhidden’ where X is any number and the value field is either 1 or 0. Changing the value of this hides or shows (docks or undocks) the block in question. X does not refer to the id of the block and it is unclear what it refers to. However, docking and undocking the block in the front end and refreshing the database will let you map each block to the number stored in the database.

For example, by docking the navigation block in the front end, I see that the value of ‘block4hidden’ changes from 0 to 1.

By adding a DML query to insert a new row into mdl_user_preferences whenever a new user is created, blocks can be automatically docked. This has the form:

INSERT INTO `mdl_user_preferences` (`userid`, `name`, `value`) VALUES (30, 'block4hidden', '1');

If this is executed at the point of user creation, then when they log on for the first time, they should access the course and find that the block that corresponds to whatever X-number was in the query executed has been docked.

So all that is needed now is to identify a php script that is executed every time a user is created and add in some code that executes this SQL query.

Average of ratings: -
In reply to Joe Cape

Re: Idea for how to get blocks to ‘dock’ automatically.

by Joe Cape -
Picture of Plugin developers

A function that is always executed when a new user is created can be found @ user/profile/lib.php line 407. So to get this to work I am trying the following:

global $DB;

$insertUndockPreference="INSERT INTO `mdl_user_preferences` (`userid`, `name`, `value`) VALUES ($usernew->id, 'block4hidden', '1');";

$DB->run_query($insertUndockPreference);

Of course run_query does not exist so this will not do. Is there any function which can do what I want?

I have also tried an alternativel, based on what I've seen in other bits of core Moodle code:

$user_preferences->userid=$usernew->id;
$user_preferences->name='block4hidden';
$user_preferences->value=1;
$insertUndockPreference=$DB->insert_record('user_preferences', $user_preferences);

But this isn't working either. I am pretty sure that my idea works in principle and there are other people looking for a way to do this too so any advice on how this can be done using the Moodle API would be useful.

In reply to Joe Cape

Re: Idea for how to get blocks to ‘dock’ automatically.

by Joe Cape -
Picture of Plugin developers

This is working now so that once any student is registered on the course, blocks can be automatically 'docked' (hidden or collapsed). This was done by changing the function profile_save_data (user/profile/lib.php line 407) to look like this:

function profile_save_data($usernew) {

global $CFG, $DB;

$user_preferences->userid=$usernew->id;
$user_preferences->name='block4hidden';
$user_preferences->value='1';
$DB->insert_record('user_preferences', $user_preferences);

if ($fields = $DB->get_records('user_info_field')) {
foreach ($fields as $field) {
require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
$newfield = 'profile_field_'.$field->datatype;
$formfield = new $newfield($field->id, $usernew->id);
$formfield->edit_save_data($usernew);
}

}   
}

 

 

You might need to change this line:

$user_preferences->name='block4hidden';

To refer to the block that you want to hide automatically. You can do this by manually changing the database (user preferences table) and watching how this affects the front end.

Average of ratings: Useful (3)
In reply to Joe Cape

Re: Idea for how to get blocks to ‘dock’ automatically.

by Lucas Arantes -

Good tip Jos,

But when a do this change, arises an error on profile users edit (I can't update the user datas). Any idea to correct this error? Maybe must be insert an "if" to update the record that exists yet?

Lucas

In reply to Lucas Arantes

Re: Idea for how to get blocks to ‘dock’ automatically.

by David Gilardi -

You are correct Lucas that you do need a conditional statement.  Something like the following:

	$user_preferences->userid = $usernew->id;
$user_preferences->name = 'docked_block_instance_5';
$user_preferences->value = '1';
$query = 'select id from mdl_user_preferences where userid='.$user_preferences->userid.' and name=\''.$user_preferences->name.'\';';
$result = $DB->get_record_sql($query);
if ($result) { // update
$user_preferences->id = $result->id;
$DB->update_record('user_preferences', $user_preferences);

} else { // insert
$DB->insert_record('user_preferences', $user_preferences);

}

 The error that you are seeing is being raised because you are trying to insert a row over a row that already exists. So a check must be put in place to determine if the information you are trying to edit already exists and if it does update instead of insert.  I found this error by turning on all levels of debugging from Site administration -> Development -> Debugging.

 Of course though, as I was digging into this there seem to be some caveats worth mentioning IMO. For one, this all works based off of when a user is enrolled in a course or user information is changed. What happens if an admin adds another instance of a block through the admin interface, but never interacts with the user once said user is enrolled? I am thinking of something like the settings block where you can end up with multiple instances within one user interface.  Also, the number in something like "docked_block_instance_5" comes from the instance of the block itself from the mdl_block_instances table and is generated as blocks are added throughout the life of the system.  So unless you are going to periodically check your DB for new instances there must be an instance of code somewhere that automatically handles re-docking if you will anytime a change is made otherwise you might end up with some odd circumstances.

Interestingly, I am working on all of the caveats I just mentioned because I am looking for a solution to this as well.  Ian my particular case I would like to dock the settings block for all students, but not for admins, teachers, etc...  I am new to all of this, but from what I can tell the settings block seems unique compared to other blocks in the way it is propagated across my site and even though I can find the instance of settings that applies to all pages and auto-dock for students it would only take on admin to add another settings block with a slightly different pagetypepattern to throw it all off.  

Average of ratings: Useful (2)
In reply to Joe Cape

Re: Idea for how to get blocks to ‘dock’ automatically.

by Miss Moeller -

I would like to have ALL blocks docked for users by default.

The reason for this is that I am using Joomdle to integrate my Moodle site with Joomla, and I need to display some of my Moodle pages in a wrapper/iframe on some pages on my Joomla site.

(As can be seen here: http://www.missmoeller.com/index.php?option=com_joomdle&view=wrapper&moodle_page_type=course&id=2&Itemid=72 )

Moodle Site: http://missmoeller.com/school

Joomla Site: http://missmoeller.com

However, in order to do this, I really need all the blocks to be placed in the dock by default for all users.

I have tried the strategy mentioned by jos cape, but I am not seeing any changes.

I have attached a screen shot of my mdl_user_preferences table in my MySQL Databases section, as well as of the code I used (I changed "block4hidden" to "block3hidden," but I'm not sure if I did that correctly).

Can anyone tell me what I'm doing wrong, or what I need to do?

Thank you so much to anyone who can help me. I really appreciate it. smile

In reply to Miss Moeller

Re: Idea for how to get blocks to ‘dock’ automatically.

by Ruth Cheesley -

This solution (using the conditional if statement) worked perfectly for us - many thanks!

Ruth

In reply to Miss Moeller

Re: Idea for how to get blocks to ‘dock’ automatically.

by Onno Schuit -

Hi,

If you want all of your blocks docked by default, go to this file:

blocks/moodleblock.class.php

On line 402 (inside the function html_attributes), change the 0 to 1:

        if ($this->instance_can_be_docked() && get_user_preferences('docked_block_instance_'.$this->instance->id, 1)) {

 

Onno

Average of ratings: Useful (6)
In reply to Onno Schuit

Re: Idea for how to get blocks to ‘dock’ automatically.

by Peter DeBruyn -

I would like all my blocks in the left column docked by default and have the right column blocks undocked by default - is there a way to do this? 

I am very surprised that in a blocks settings you can allow a block to be docked by the user but no setting to have a particular block docked by default.

In reply to Peter DeBruyn

Re: Idea for how to get blocks to ‘dock’ automatically.

by Ivan Torres -

Hi friend

Do you found a solution to get blocks to dock permantlye?

Thanks.

In reply to Onno Schuit

Re: Idea for how to get blocks to ‘dock’ automatically.

by Carlos Sánchez Martín -

Hello Onne,

We applied this a while back and it works... but now that we want to use myMoodle as the default page, it seems to interfere with the settings, and the desired undocked blocks are docked as well. Any ideas? Do you use myMoodle?

Carlos

In reply to Onno Schuit

Re: Idea for how to get blocks to ‘dock’ automatically.

by Denko Showa -

Hi Onno,

 

I had tried using your method.. but it don't work for me.. any other method to recommend? Thx

In reply to Onno Schuit

This forum post has been removed

The content of this forum post has been removed and can no longer be accessed.
In reply to Onno Schuit

Re: Idea for how to get blocks to ‘dock’ automatically.

by Ivan Torres -

Hi dude

Do you know how to add new dock position in moodle to the dock ?

Thanks.

Attachment properties.jpg