NodeTypeForm.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. namespace Drupal\node;
  3. use Drupal\Core\Entity\BundleEntityFormBase;
  4. use Drupal\Core\Entity\EntityManagerInterface;
  5. use Drupal\Core\Entity\EntityTypeInterface;
  6. use Drupal\Core\Form\FormStateInterface;
  7. use Drupal\language\Entity\ContentLanguageSettings;
  8. use Symfony\Component\DependencyInjection\ContainerInterface;
  9. /**
  10. * Form handler for node type forms.
  11. *
  12. * @internal
  13. */
  14. class NodeTypeForm extends BundleEntityFormBase {
  15. /**
  16. * The entity manager.
  17. *
  18. * @var \Drupal\Core\Entity\EntityManagerInterface
  19. */
  20. protected $entityManager;
  21. /**
  22. * Constructs the NodeTypeForm object.
  23. *
  24. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
  25. * The entity manager.
  26. */
  27. public function __construct(EntityManagerInterface $entity_manager) {
  28. $this->entityManager = $entity_manager;
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public static function create(ContainerInterface $container) {
  34. return new static(
  35. $container->get('entity.manager')
  36. );
  37. }
  38. /**
  39. * {@inheritdoc}
  40. */
  41. public function form(array $form, FormStateInterface $form_state) {
  42. $form = parent::form($form, $form_state);
  43. $type = $this->entity;
  44. if ($this->operation == 'add') {
  45. $form['#title'] = $this->t('Add content type');
  46. $fields = $this->entityManager->getBaseFieldDefinitions('node');
  47. // Create a node with a fake bundle using the type's UUID so that we can
  48. // get the default values for workflow settings.
  49. // @todo Make it possible to get default values without an entity.
  50. // https://www.drupal.org/node/2318187
  51. $node = $this->entityManager->getStorage('node')->create(['type' => $type->uuid()]);
  52. }
  53. else {
  54. $form['#title'] = $this->t('Edit %label content type', ['%label' => $type->label()]);
  55. $fields = $this->entityManager->getFieldDefinitions('node', $type->id());
  56. // Create a node to get the current values for workflow settings fields.
  57. $node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]);
  58. }
  59. $form['name'] = [
  60. '#title' => t('Name'),
  61. '#type' => 'textfield',
  62. '#default_value' => $type->label(),
  63. '#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the <em>Add content</em> page. This name must be unique.'),
  64. '#required' => TRUE,
  65. '#size' => 30,
  66. ];
  67. $form['type'] = [
  68. '#type' => 'machine_name',
  69. '#default_value' => $type->id(),
  70. '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
  71. '#disabled' => $type->isLocked(),
  72. '#machine_name' => [
  73. 'exists' => ['Drupal\node\Entity\NodeType', 'load'],
  74. 'source' => ['name'],
  75. ],
  76. '#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the %node-add page, in which underscores will be converted into hyphens.', [
  77. '%node-add' => t('Add content'),
  78. ]),
  79. ];
  80. $form['description'] = [
  81. '#title' => t('Description'),
  82. '#type' => 'textarea',
  83. '#default_value' => $type->getDescription(),
  84. '#description' => t('This text will be displayed on the <em>Add new content</em> page.'),
  85. ];
  86. $form['additional_settings'] = [
  87. '#type' => 'vertical_tabs',
  88. '#attached' => [
  89. 'library' => ['node/drupal.content_types'],
  90. ],
  91. ];
  92. $form['submission'] = [
  93. '#type' => 'details',
  94. '#title' => t('Submission form settings'),
  95. '#group' => 'additional_settings',
  96. '#open' => TRUE,
  97. ];
  98. $form['submission']['title_label'] = [
  99. '#title' => t('Title field label'),
  100. '#type' => 'textfield',
  101. '#default_value' => $fields['title']->getLabel(),
  102. '#required' => TRUE,
  103. ];
  104. $form['submission']['preview_mode'] = [
  105. '#type' => 'radios',
  106. '#title' => t('Preview before submitting'),
  107. '#default_value' => $type->getPreviewMode(),
  108. '#options' => [
  109. DRUPAL_DISABLED => t('Disabled'),
  110. DRUPAL_OPTIONAL => t('Optional'),
  111. DRUPAL_REQUIRED => t('Required'),
  112. ],
  113. ];
  114. $form['submission']['help'] = [
  115. '#type' => 'textarea',
  116. '#title' => t('Explanation or submission guidelines'),
  117. '#default_value' => $type->getHelp(),
  118. '#description' => t('This text will be displayed at the top of the page when creating or editing content of this type.'),
  119. ];
  120. $form['workflow'] = [
  121. '#type' => 'details',
  122. '#title' => t('Publishing options'),
  123. '#group' => 'additional_settings',
  124. ];
  125. $workflow_options = [
  126. 'status' => $node->status->value,
  127. 'promote' => $node->promote->value,
  128. 'sticky' => $node->sticky->value,
  129. 'revision' => $type->isNewRevision(),
  130. ];
  131. // Prepare workflow options to be used for 'checkboxes' form element.
  132. $keys = array_keys(array_filter($workflow_options));
  133. $workflow_options = array_combine($keys, $keys);
  134. $form['workflow']['options'] = [
  135. '#type' => 'checkboxes',
  136. '#title' => t('Default options'),
  137. '#default_value' => $workflow_options,
  138. '#options' => [
  139. 'status' => t('Published'),
  140. 'promote' => t('Promoted to front page'),
  141. 'sticky' => t('Sticky at top of lists'),
  142. 'revision' => t('Create new revision'),
  143. ],
  144. '#description' => t('Users with the <em>Administer content</em> permission will be able to override these options.'),
  145. ];
  146. if ($this->moduleHandler->moduleExists('language')) {
  147. $form['language'] = [
  148. '#type' => 'details',
  149. '#title' => t('Language settings'),
  150. '#group' => 'additional_settings',
  151. ];
  152. $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('node', $type->id());
  153. $form['language']['language_configuration'] = [
  154. '#type' => 'language_configuration',
  155. '#entity_information' => [
  156. 'entity_type' => 'node',
  157. 'bundle' => $type->id(),
  158. ],
  159. '#default_value' => $language_configuration,
  160. ];
  161. }
  162. $form['display'] = [
  163. '#type' => 'details',
  164. '#title' => t('Display settings'),
  165. '#group' => 'additional_settings',
  166. ];
  167. $form['display']['display_submitted'] = [
  168. '#type' => 'checkbox',
  169. '#title' => t('Display author and date information'),
  170. '#default_value' => $type->displaySubmitted(),
  171. '#description' => t('Author username and publish date will be displayed.'),
  172. ];
  173. return $this->protectBundleIdElement($form);
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. protected function actions(array $form, FormStateInterface $form_state) {
  179. $actions = parent::actions($form, $form_state);
  180. $actions['submit']['#value'] = t('Save content type');
  181. $actions['delete']['#value'] = t('Delete content type');
  182. return $actions;
  183. }
  184. /**
  185. * {@inheritdoc}
  186. */
  187. public function validateForm(array &$form, FormStateInterface $form_state) {
  188. parent::validateForm($form, $form_state);
  189. $id = trim($form_state->getValue('type'));
  190. // '0' is invalid, since elsewhere we check it using empty().
  191. if ($id == '0') {
  192. $form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", ['%invalid' => $id]));
  193. }
  194. }
  195. /**
  196. * {@inheritdoc}
  197. */
  198. public function save(array $form, FormStateInterface $form_state) {
  199. $type = $this->entity;
  200. $type->setNewRevision($form_state->getValue(['options', 'revision']));
  201. $type->set('type', trim($type->id()));
  202. $type->set('name', trim($type->label()));
  203. $status = $type->save();
  204. $t_args = ['%name' => $type->label()];
  205. if ($status == SAVED_UPDATED) {
  206. $this->messenger()->addStatus($this->t('The content type %name has been updated.', $t_args));
  207. }
  208. elseif ($status == SAVED_NEW) {
  209. node_add_body_field($type);
  210. $this->messenger()->addStatus($this->t('The content type %name has been added.', $t_args));
  211. $context = array_merge($t_args, ['link' => $type->link($this->t('View'), 'collection')]);
  212. $this->logger('node')->notice('Added content type %name.', $context);
  213. }
  214. $fields = $this->entityManager->getFieldDefinitions('node', $type->id());
  215. // Update title field definition.
  216. $title_field = $fields['title'];
  217. $title_label = $form_state->getValue('title_label');
  218. if ($title_field->getLabel() != $title_label) {
  219. $title_field->getConfig($type->id())->setLabel($title_label)->save();
  220. }
  221. // Update workflow options.
  222. // @todo Make it possible to get default values without an entity.
  223. // https://www.drupal.org/node/2318187
  224. $node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]);
  225. foreach (['status', 'promote', 'sticky'] as $field_name) {
  226. $value = (bool) $form_state->getValue(['options', $field_name]);
  227. if ($node->$field_name->value != $value) {
  228. $fields[$field_name]->getConfig($type->id())->setDefaultValue($value)->save();
  229. }
  230. }
  231. $this->entityManager->clearCachedFieldDefinitions();
  232. $form_state->setRedirectUrl($type->urlInfo('collection'));
  233. }
  234. }