How to set a default publish_on field when creating a node in drupal 9
Via chatgpt.
An easier example is to set the default title first:
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
* Implements hook_form_FORM_ID_alter() for the article node form.
*/
function MYMODULE_form_node_article_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
/** @var \Drupal\node\Entity\Node $node */
$node = $form_state->getFormObject()->getEntity();
// Only set the default for new nodes.
if ($node->isNew()) {
$form['title']['widget'][0]['value']['#default_value'] = 'Default Article Title';
}
}
Here is an example of how to acheive this using HOOK_form_alter :
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
* Implements hook_form_FORM_ID_alter().
*/
function MYMODULE_form_node_article_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/** @var \Drupal\node\Entity\Node $node */
$node = $form_state->getFormObject()->getEntity();
// Only set the default value for new nodes.
if ($node->isNew()) {
$timestamp = strtotime('+2 days');
$default_date = \Drupal::service('date.formatter')->format($timestamp, 'custom', 'Y-m-d\TH:i:s');
// Ensure the publish_on field exists and set its default value.
if (isset($form['publish_on']['widget'][0]['value'])) {
$form['publish_on']['widget'][0]['value']['#default_value'] = $default_date;
}
}
}
And a functional test:
<?php
// tests/src/Functional/PublishOnDefaultValueTest.php
namespace Drupal\Tests\mymodule\Functional;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\BrowserTestBase;
/**
* Tests default value on the "publish_on" field of node form.
*
* @group mymodule
*/
class PublishOnDefaultValueTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'node',
'scheduler',
'mymodule', // Replace with your actual module name.
];
protected function setUp(): void {
parent::setUp();
// Create a content type with Scheduler enabled.
$type = NodeType::create([
'type' => 'article',
'name' => 'Article',
]);
$type->save();
// Enable Scheduler for this content type.
\Drupal::service('config.factory')
->getEditable('scheduler.settings_article')
->set('publish_enable', TRUE)
->save();
// Create a user with permission to create content.
$this->drupalLogin($this->drupalCreateUser([
'create article content',
'edit any article content',
]));
}
/**
* Test that the publish_on field has the default value.
*/
public function testPublishOnDefaultValue() {
// Visit the node creation form.
$this->drupalGet('node/add/article');
// Assert that the publish_on field exists.
$this->assertSession()->fieldExists('Publish on');
// Get the value from the field.
$value = $this->getSession()->getPage()->findField('Publish on')->getValue();
// Parse the value and check it's within an acceptable default range.
$defaultTimestamp = strtotime('+2 days');
$actualTimestamp = strtotime($value);
// Allow a margin of error (e.g., 5 minutes).
$this->assertTrue(
abs($defaultTimestamp - $actualTimestamp) < 300,
'The publish_on default value is approximately 2 days from now.'
);
}
}
You can run the test by pasting the ^ above to tests/src/Functional/PublishOnDefaultValueTest.php and running:
phpunit -c core modules/custom/mymodule/tests/src/Functional/PublishOnDefaultValueTest.php
Alternatively, you can run the whole test suite:
phpunit -c core --group mymodule
# or
ddev phpunit --group mymodule
.