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

.

Please login or register to post a comment.