Skip to content
Snippets Groups Projects
Commit 9c803d43 authored by Tim Rohaly's avatar Tim Rohaly Committed by Tim Rohaly
Browse files

Issue #3121331 by TR: Drupal Core (8.8.4) Update Forces Honeypot to Recall Hook_Update_N

parent a82bf811
No related branches found
Tags 6.x-1.19
No related merge requests found
......@@ -47,7 +47,7 @@ function honeypot_schema() {
function honeypot_install() {
if (PHP_SAPI !== 'cli') {
// Rebuild so that routes defined in honeypot.routing.yml become available.
\Drupal::service("router.builder")->rebuild();
\Drupal::service('router.builder')->rebuild();
// Prompt the user to configure Honeypot.
\Drupal::messenger()->addMessage(t('Honeypot installed successfully. Please <a href=":url">configure Honeypot</a> to protect your forms from spam bots.', [
':url' => Url::fromRoute('honeypot.config')->toString(),
......@@ -68,8 +68,38 @@ function honeypot_uninstall() {
* Adds the 'hostname' column to the {honeypot_user} table.
*/
function honeypot_update_8100() {
$schema = honeypot_schema();
$spec = $schema['honeypot_user']['fields']['hostname'];
$spec['initial'] = '';
\Drupal::database()->schema()->addField('honeypot_user', 'hostname', $spec);
// The body of this update function has been removed.
//
// hook_update_8100() does not technically comply with the update hook
// numbering scheme. This may cause various problems when updating.
//
// To ensure that all sites get properly updated, a new hook_update_8101()
// is added to conditionally perform the updates that used to be here.
// - For new sites, update hooks aren't run. The schema will already be
// correct upon install.
// - For existings sites that have already run hook_update_8100(), the new
// update hook won't make any changes.
// - For existing sites that try to re-execute hook_update_8100() as
// described in https://www.drupal.org/project/honeypot/issues/3121331,
// this empty hook won't fail.
// - For existing sites that haven't yet been updated, the new update hook
// will make the necessary changes.
//
// This is what honeypot_update_8100() used to do:
// $schema = honeypot_schema();
// $spec = $schema['honeypot_user']['fields']['hostname'];
// $spec['initial'] = '';
// \Drupal::database()->schema()->addField('honeypot_user', 'hostname', $spec);
}
/**
* Corrects a sometimes-missing 'hostname' column in the {honeypot_user} table.
*/
function honeypot_update_8101() {
if (!\Drupal::database()->schema()->fieldExists('honeypot_user', 'hostname')) {
$schema = honeypot_schema();
$spec = $schema['honeypot_user']['fields']['hostname'];
$spec['initial'] = '';
\Drupal::database()->schema()->addField('honeypot_user', 'hostname', $spec);
}
}
<?php
/**
* @file
* Contains database additions to drupal-9.4.0.bare.standard.php.gz.
*
* This fixture enables the honeypot module by setting system configuration
* values in the {config} and {key_value} tables, then adds the Honeypot
* tables to the database using the schema from Honeypot version 8.x-1.22.
*
* This fixture is intended for use in testing honeypot_update_8100() and
* honeypot_update_8101().
*
* @see https://www.drupal.org/node/3121331.
*/
use Drupal\Core\Database\Database;
$connection = Database::getConnection();
// Create the Honeypot tables. This is from Honeypot version 8.x-1.22.
$connection->schema()->createTable('honeypot_user', [
'description' => 'Table that stores failed attempts to submit a form.',
'fields' => [
'uid' => [
'description' => 'Foreign key to {users}.uid; uniquely identifies a Drupal user to whom this ACL data applies.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
'timestamp' => [
'description' => 'Date/time when the form submission failed, as Unix timestamp.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
],
'indexes' => [
'uid' => ['uid'],
'timestamp' => ['timestamp'],
],
]);
// Set the honeypot DB schema version.
$connection->insert('key_value')
->fields([
'collection' => 'system.schema',
'name' => 'honeypot',
'value' => 'i:8000;',
])
->execute();
// Update core.extension to enable honeypot.
$extensions = $connection->select('config')
->fields('config', ['data'])
->condition('collection', '')
->condition('name', 'core.extension')
->execute()
->fetchField();
$extensions = unserialize($extensions);
$extensions['module']['honeypot'] = 0;
$connection->update('config')
->fields([
'data' => serialize($extensions),
])
->condition('collection', '')
->condition('name', 'core.extension')
->execute();
<?php
namespace Drupal\Tests\honeypot\Functional\Update;
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
/**
* Tests that honeypot settings are properly updated during database updates.
*
* @group honeypot
* @group legacy
*/
class HoneypotUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles(): void {
$d9_specific_dump = DRUPAL_ROOT . '/core/modules/system/tests/fixtures/update/drupal-9.3.0.bare.standard.php.gz';
$d10_specific_dump = DRUPAL_ROOT . '/core/modules/system/tests/fixtures/update/drupal-9.4.0.bare.standard.php.gz';
// Can't use the same dump in D9 and D10.
if (file_exists($d9_specific_dump)) {
$core_dump = $d9_specific_dump;
}
else {
$core_dump = $d10_specific_dump;
}
// Use core fixture and Honeypot-specific fixture.
$this->databaseDumpFiles = [
$core_dump,
__DIR__ . '/../../../fixtures/update/drupal-8.honeypot-add-hostname-column-3121331.php',
];
}
/**
* Tests honeypot_update_8100() and honeypot_update_8101().
*
* @see honeypot_update_8100()
* @see honeypot_update_8101()
*/
public function testHookUpdate8101(): void {
// Check that the {honeypot_user} table does not contain the 'hostname'
// column before the update.
$this->assertSame(8000, \Drupal::keyValue('system.schema')->get('honeypot'));
// Note: Its VERY important to use \Drupal::database() here to get the
// database connection. Other methods like $this->getDatabaseConnection()
// will give you the WRONG connection.
$schema = \Drupal::database()->schema();
$exists = $schema->tableExists('honeypot_user');
$this->assertTrue($exists);
$exists = $schema->fieldExists('honeypot_user', 'uid');
$this->assertTrue($exists);
$exists = $schema->fieldExists('honeypot_user', 'timestamp');
$this->assertTrue($exists);
$exists = $schema->fieldExists('honeypot_user', 'hostname');
$this->assertFalse($exists);
// Run updates.
$this->runUpdates();
// Check that the {honeypot_user} table now contains the 'hostname' column
// with the expected schema definition after the update.
$exists = $schema->fieldExists('honeypot_user', 'hostname');
$this->assertTrue($exists);
$install_schema = honeypot_schema();
$column_schema = $install_schema['honeypot_user']['fields']['hostname'];
$this->assertEquals('varchar', $column_schema['type']);
$this->assertEquals('128', $column_schema['length']);
$this->assertTrue($column_schema['not null']);
$this->assertEquals('Hostname of user that that triggered honeypot.', $column_schema['description']);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment