MDL-68645 output: Make other generators fail if they init the output too

Identically to what we've added to the module generators, let's raise a
coding exception if generating a block or a repository triggers the
theme and output initialisation.
This commit is contained in:
David Mudrák 2020-05-14 07:55:19 +02:00
parent 005b00dd9b
commit 866ce1fbe9
2 changed files with 35 additions and 2 deletions

View File

@ -114,10 +114,14 @@ abstract class testing_block_generator extends component_generator_base {
* @return stdClass the block_instance record that has just been created.
*/
public function create_instance($record = null, $options = array()) {
global $DB;
global $DB, $PAGE;
$this->instancecount++;
// Creating a block is a back end operation, which should not cause any output to happen.
// This will allow us to check that the theme was not initialised while creating the block instance.
$outputstartedbefore = $PAGE->get_where_theme_was_initialised();
$record = (object)(array)$record;
$this->preprocess_record($record, $options);
$record = $this->prepare_record($record);
@ -133,6 +137,19 @@ abstract class testing_block_generator extends component_generator_base {
context_block::instance($id);
$instance = $DB->get_record('block_instances', array('id' => $id), '*', MUST_EXIST);
// If the theme was initialised while creating the block instance, something somewhere called an output
// function. Rather than leaving this as a hard-to-debug situation, let's make it fail with a clear error.
$outputstartedafter = $PAGE->get_where_theme_was_initialised();
if ($outputstartedbefore === null && $outputstartedafter !== null) {
throw new coding_exception('Creating a block_' . $this->get_blockname() . ' initialised the theme and output!',
'This should not happen. Creating a block should be a pure back-end operation. Unnecessarily initialising ' .
'the output mechanism at the wrong time can cause subtle bugs and is a significant performance hit. There is ' .
'likely a call to an output function that caused it:' . PHP_EOL . PHP_EOL .
format_backtrace($outputstartedafter, true));
}
return $instance;
}

View File

@ -111,12 +111,16 @@ class testing_repository_generator extends component_generator_base {
* @return stdClass repository instance record
*/
public function create_instance($record = null, array $options = null) {
global $CFG, $DB;
global $CFG, $DB, $PAGE;
require_once($CFG->dirroot . '/repository/lib.php');
$this->instancecount++;
$record = (array) $record;
// Creating a repository is a back end operation, which should not cause any output to happen.
// This will allow us to check that the theme was not initialised while creating the repository instance.
$outputstartedbefore = $PAGE->get_where_theme_was_initialised();
$typeid = $DB->get_field('repository', 'id', array('type' => $this->get_typename()), MUST_EXIST);
$instanceoptions = repository::static_function($this->get_typename(), 'get_instance_option_names');
@ -146,6 +150,18 @@ class testing_repository_generator extends component_generator_base {
$id = repository::static_function($this->get_typename(), 'create', $this->get_typename(), 0, $context, $record);
}
// If the theme was initialised while creating the repository instance, something somewhere called an output
// function. Rather than leaving this as a hard-to-debug situation, let's make it fail with a clear error.
$outputstartedafter = $PAGE->get_where_theme_was_initialised();
if ($outputstartedbefore === null && $outputstartedafter !== null) {
throw new coding_exception('Creating a repository_' . $this->get_typename() . ' initialised the theme and output!',
'This should not happen. Creating a repository should be a pure back-end operation. Unnecessarily initialising ' .
'the output mechanism at the wrong time can cause subtle bugs and is a significant performance hit. There is ' .
'likely a call to an output function that caused it:' . PHP_EOL . PHP_EOL .
format_backtrace($outputstartedafter, true));
}
return $DB->get_record('repository_instances', array('id' => $id), '*', MUST_EXIST);
}