get_data() is not working

get_data() is not working

by Alexander Dominicus -
Number of replies: 14
Picture of Testers

Hi moodlers,

I try to build a block plugin where you can type some text and this text should be the added to some URL. My current code is like

I have a "my_form.php" containing


class myblock_form extends moodleform {

[...]

$mform->addElement('text', 'txt1', get_string('txt1', 'block_myblock'), array('rows' => 1, 'cols' => 6));
 $mform->setType('txt1', PARAM_RAW);
     
 $this->add_action_buttons($cancel = false, $submitlabel="Kurs suchen!");


}

and I have "block_myblock.php" containing

       
 $mform = new myblock_form();
     


        //Form processing and displaying is done here
        if ($mform->is_cancelled()) {
            //Handle form cancel operation, if cancel button is present on form
        } else if ($data = $mform->get_data()) {
           redirect(new moodle_url('Some_url_here', $data));
           
   
        } else {
         
            $this->content->text = $mform->render();
        }

        return $this->content;
    }


But after pressing the submit button I will be redirected to "MY_MOODLE_URL/course/view.php"

How can I use the entered text?


Best,

Alex


Average of ratings: -
In reply to Alexander Dominicus

Re: get_data() is not working

by Davo Smith -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
I'm assuming that 'Some_url_here' is an actual URL, not the literal text you've listed?

The moodle_url() constructor expects the second param to be an array of param => value pairs, whereas $data is an object that contains each of the values from the form (including the value of the 'submit' button).

Maybe you wanted to do something like:
redirect(new moodle_url('/page/within/moodle.php', ['txt1' => $data->txt1]));

Or maybe, it would be better to initialise the form to submit to the correct URL in the first place?

$mform = new myblock_form(null, new moodle_url('/page/within/moodle.php'));

(although you should be careful with that, as it will not work properly with any form validation, as the form will literally submit to the given URL, it will not stay on the current page to check any validation rules)
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Dear Davo,
thank you for your information. Unfortunately, there is the same result in both cases you postet above. For testing I did the following:

$mform = new myblock_form();


//Form processing and displaying is done here
if ($mform->is_cancelled()) {

echo "canceled";
//Handle form cancel operation, if cancel button is present on form
} else if ($data = $mform->get_data()) {
echo "get data";

} else {
echo "else";

//displays the form
$this->content->text = $mform->render();
}


And I'm allways in the "else" case (last case/ Even without pressing the submit button). So the data will never be submitted. But why?

Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Update:

Now,it is partially working when I initialise the form like this:

$mform = new myblock_form( new moodle_url('/page/within/moodle.php'));

So, when I press the submit button then I will get to the URL of moodle_url('....').
Unfortunately, there's not data submitted, i.e. the is no php error but also no data in the resulting URL.
Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Davo Smith -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Well the brief snippets of code you've shown look like they should work, which suggests that there is some sort of subtle problem in the full code.

Do you have Debugging enabled for your site (as that often shows up issues)?

Where is the full code for your plugin (is it available in github or similar)?
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Yes, debugging is enabled but no error is thrown.
I've creaetd the block via moosh and the code behind is coming from here
https://github.com/danielneis/moodle-block_newblock

Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Davo Smith -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
That link shows the newblock code, but where is the version with your code in it?
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
In reply to Alexander Dominicus

Re: get_data() is not working

by Davo Smith -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
OK - I had a quick look at the code and can spot a number of issues.

The primary one is that the block form submits to the current page, but without including any of the page parameters.

So, if the block is added onto the /course/view.php page, then submitting it leads to an error, because the ?id=X parameter is not included.

So, you'll need to add something like this to your form definition function:

global $PAGE;
        foreach ($PAGE->url->params() as $name => $value) {
            $mform->addElement('hidden', $name, $value);
            $mform->setType($name, PARAM_RAW);
        }
        

There are also a lot of other issues you need to look at - edit_form.php should contain the form for the settings you see when you click on the 'edit settings' icon in the block - you need to rename edit_form.php to something else (preferably using automatic class loading to load it from the classes/ subfolder within your plugin).

get_content() should return $this->content if it is not null (this is to avoid re-generating the content when the function is called a second time - the code is there, but you've commented it out).

$this->content->items / $this->content->icons - only used by block_list, irrelevant when using block_base.

The param is called 'txt1', but you call optional_param() and clean it as PARAM_INT - this will convert anything not starting with a digit into 0.

There is a lot of other tidy-up that needs doing, but hopefully that's enough to get you started.

Average of ratings: Useful (1)
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Hi Davo,

thank you very much for your post. The crucial mistake was the missing $PAGE definiton as you explained. Now, the code is running and I can start cleaning smile
Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Hi Davo,

one additional issue: The code is working in Moodle 3.9, but if I use Moodle 3.10/3.11 then I get the following error after submitting:

You cannot redirect while printing the page header
Debug info:
Error code: codingerror
Stack trace:

line 1233 of /lib/outputrenderers.php: coding_exception thrown
line 2983 of /lib/weblib.php: call to core_renderer->redirect_message()
line 100 of /blocks/idfinder/block_idfinder.php: call to redirect()
line 341 of /blocks/moodleblock.class.php: call to block_idfinder->get_content()
line 235 of /blocks/moodleblock.class.php: call to block_base->formatted_contents()
line 1181 of /lib/blocklib.php: call to block_base->get_content_for_output()
line 1239 of /lib/blocklib.php: call to block_manager->create_block_contents()
line 642 of /lib/outputrenderers.php: call to block_manager->ensure_content_created()
line 83 of /theme/adaptable/layout/includes/head.php: call to core_renderer->standard_head_html()
line 130 of /theme/adaptable/layout/includes/header.php: call to require_once()
line 32 of /theme/adaptable/layout/course.php: call to require_once()
line 1374 of /lib/outputrenderers.php: call to include()
line 1304 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
line 253 of /course/view.php: call to core_renderer->header()

Any idea whats going wrong here?

Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Davo Smith -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
Ah, yes.

Forms are usually designed to be processed before the page output starts - which means they can redirect if they want to.

Unfortunately, Moodle doesn't give blocks a chance to do anything until after the page has started output, so you get a problem where you cannot use redirect.

There are a couple of solutions. One is to handle the form submission within the page and not redirect. The other solution is to get the form to submit to a new page (an extra PHP file within your block's folder). On that new page, you can then instantiate a new copy of the same form class and use that to process the submission. If there is a validation error, you can redisplay the form (although it will be on this new page, on its own, rather than being embedded in the block); if there is no validation error, you can do whatever processing of the data you want.
Average of ratings: Useful (1)
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Dear Davos,

in fact I'm trying to realise a block, where a user enter a course ID an then will be redirected to the specific course after submitting. So, in pricipal I have to use your second solution, since I don't want to stay within the current page ;).

Best,
Alex
In reply to Davo Smith

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Dear Davo,

I fixed the issue via your second solution: I created a view.php as mentioned here
https://docs.moodle.org/dev/Blocks_Advanced
So you have to click a link on the newly created block leading to a new page containing the form. Now, starting from here redirection is no longer a problem and the code is running as expected.

Thank you!!
Best,
Alex
In reply to Alexander Dominicus

Re: get_data() is not working

by Alexander Dominicus -
Picture of Testers
Hi Davos,
one last thing:
How could I add my own created block to the dashboard? There is only a restricted amount of blocks available on the dashboard. Is it controlled by db/access.php?

Best,
Alex