diff --git a/src/config/app.php b/src/config/app.php index 65c787cc2c8..a287a68cd3f 100644 --- a/src/config/app.php +++ b/src/config/app.php @@ -4,7 +4,7 @@ 'id' => 'CraftCMS', 'name' => 'Craft CMS', 'version' => '5.8.8', - 'schemaVersion' => '5.8.0.3', + 'schemaVersion' => '5.9.0.0', 'minVersionRequired' => '4.5.0', 'basePath' => dirname(__DIR__), // Defines the @app alias 'runtimePath' => '@storage/runtime', // Defines the @runtime alias diff --git a/src/controllers/EntryTypesController.php b/src/controllers/EntryTypesController.php index e1ce35b33e1..880386fb2aa 100644 --- a/src/controllers/EntryTypesController.php +++ b/src/controllers/EntryTypesController.php @@ -228,6 +228,8 @@ public function actionSave(): ?Response $entryType->slugTranslationMethod = $this->request->getBodyParam('slugTranslationMethod', $entryType->slugTranslationMethod); $entryType->slugTranslationKeyFormat = $this->request->getBodyParam('slugTranslationKeyFormat', $entryType->slugTranslationKeyFormat); $entryType->showStatusField = $this->request->getBodyParam('showStatusField', $entryType->showStatusField); + $entryType->showPostDateField = $this->request->getBodyParam('showPostDateField', $entryType->showPostDateField); + $entryType->showExpiryDateField = $this->request->getBodyParam('showExpiryDateField', $entryType->showExpiryDateField); // If we're duplicating the entry type and the handle hasn't changed, find a unique one if ($entryType->handle === ($originalEntryType->handle ?? null)) { diff --git a/src/elements/Entry.php b/src/elements/Entry.php index 0b6d992aeaf..a481d8110b1 100644 --- a/src/elements/Entry.php +++ b/src/elements/Entry.php @@ -2538,8 +2538,10 @@ public function metaFieldsHtml(bool $static): string $view->registerDeltaName('postDate'); $view->registerDeltaName('expiryDate'); $view->setIsDeltaRegistrationActive($isDeltaRegistrationActive); + } - // Post Date + // Post Date + if ($this->getType()->showPostDateField) { $fields[] = Cp::dateTimeFieldHtml([ 'status' => $this->getAttributeStatus('postDate'), 'label' => Craft::t('app', 'Post Date'), @@ -2549,8 +2551,10 @@ public function metaFieldsHtml(bool $static): string 'errors' => $this->getErrors('postDate'), 'disabled' => $static, ]); + } - // Expiry Date + // Expiry Date + if ($this->getType()->showExpiryDateField) { $fields[] = Cp::dateTimeFieldHtml([ 'status' => $this->getAttributeStatus('expiryDate'), 'label' => Craft::t('app', 'Expiry Date'), diff --git a/src/gql/resolvers/mutations/Entry.php b/src/gql/resolvers/mutations/Entry.php index 67f42261895..c826af51fc2 100644 --- a/src/gql/resolvers/mutations/Entry.php +++ b/src/gql/resolvers/mutations/Entry.php @@ -73,6 +73,32 @@ public function saveEntry(mixed $source, array $arguments, mixed $context, Resol unset($arguments['enabled']); } + // If saving an entry and the postDate is provided, check if we should allow changing it. + if (array_key_exists('postDate', $arguments)) { + try { + $showPostDateField = $entry->getType()->showPostDateField; + } catch (InvalidConfigException) { + $showPostDateField = true; + } + + if (!$showPostDateField) { + unset($arguments['postDate']); + } + } + + // If saving an entry and the expiryDate is provided, check if we should allow changing it. + if (array_key_exists('expiryDate', $arguments)) { + try { + $showExpiryDateField = $entry->getType()->showExpiryDateField; + } catch (InvalidConfigException) { + $showExpiryDateField = true; + } + + if (!$showExpiryDateField) { + unset($arguments['expiryDate']); + } + } + // If saving an entry the slug is provided, check if we should allow changing it. if (array_key_exists('slug', $arguments)) { try { diff --git a/src/migrations/Install.php b/src/migrations/Install.php index 08c742429a5..692f1a85ffc 100644 --- a/src/migrations/Install.php +++ b/src/migrations/Install.php @@ -455,6 +455,8 @@ public function createTables(): void 'slugTranslationMethod' => $this->string()->notNull()->defaultValue(Field::TRANSLATION_METHOD_SITE), 'slugTranslationKeyFormat' => $this->text(), 'showStatusField' => $this->boolean()->defaultValue(true), + 'showPostDateField' => $this->boolean()->defaultValue(true), + 'showExpiryDateField' => $this->boolean()->defaultValue(true), 'dateCreated' => $this->dateTime()->notNull(), 'dateUpdated' => $this->dateTime()->notNull(), 'dateDeleted' => $this->dateTime()->null(), diff --git a/src/migrations/m250723_091011_add_entry_type_show_post_and_expiry_dates.php b/src/migrations/m250723_091011_add_entry_type_show_post_and_expiry_dates.php new file mode 100644 index 00000000000..5db56b10e56 --- /dev/null +++ b/src/migrations/m250723_091011_add_entry_type_show_post_and_expiry_dates.php @@ -0,0 +1,38 @@ +addColumn(Table::ENTRYTYPES, 'showExpiryDateField', $this->boolean()->defaultValue(true)->after('showStatusField')); + $this->addColumn(Table::ENTRYTYPES, 'showPostDateField', $this->boolean()->defaultValue(true)->after('showStatusField')); + + return true; + } + + /** + * @inheritdoc + */ + public function safeDown(): bool + { + if ($this->db->columnExists(Table::ENTRYTYPES, 'showExpiryDateField')) { + $this->dropColumn(Table::ENTRYTYPES, 'showExpiryDateField'); + } + if ($this->db->columnExists(Table::ENTRYTYPES, 'showPostDateField')) { + $this->dropColumn(Table::ENTRYTYPES, 'showPostDateField'); + } + + return true; + } +} diff --git a/src/models/EntryType.php b/src/models/EntryType.php index 888a5f200d6..939fe070770 100644 --- a/src/models/EntryType.php +++ b/src/models/EntryType.php @@ -165,6 +165,18 @@ public static function get(int|string $id): ?static */ public ?self $original = null; + /** + * @var bool Whether to show the Post Date field + * @since 5.9.0 + */ + public bool $showPostDateField = true; + + /** + * @var bool Whether to show the Expiry Date field + * @since 5.9.0 + */ + public bool $showExpiryDateField = true; + /** * @inheritdoc */ @@ -323,6 +335,8 @@ public function attributeLabels(): array 'titleFormat' => Craft::t('app', 'Default Title Format'), 'showStatusField' => Craft::t('app', 'Show the Status field'), 'showSlugField' => Craft::t('app', 'Show the Slug field'), + 'showPostDateField' => Craft::t('app', 'Show the Post Date field'), + 'showExpiryDateField' => Craft::t('app', 'Show the Expiry Date field'), ]; } @@ -459,6 +473,8 @@ public function getConfig(): array 'slugTranslationMethod' => $this->slugTranslationMethod, 'slugTranslationKeyFormat' => $this->slugTranslationKeyFormat ?: null, 'showStatusField' => $this->showStatusField, + 'showPostDateField' => $this->showPostDateField, + 'showExpiryDateField' => $this->showExpiryDateField, ]; $fieldLayout = $this->getFieldLayout(); diff --git a/src/records/EntryType.php b/src/records/EntryType.php index 58efc5b3485..f48fe272d66 100644 --- a/src/records/EntryType.php +++ b/src/records/EntryType.php @@ -31,6 +31,8 @@ * @property string $slugTranslationMethod Slug translation method * @property string|null $slugTranslationKeyFormat Slug translation key format * @property bool $showStatusField Whether to show the Status field + * @property bool $showPostDateField Whether to show the Post Date field + * @property bool $showExpiryDateField Whether to show the Expiry Date field * @property FieldLayout $fieldLayout Field layout * @mixin SoftDeleteBehavior * @author Pixel & Tonic, Inc. diff --git a/src/services/Entries.php b/src/services/Entries.php index c1cc181f26f..6b351908b2f 100644 --- a/src/services/Entries.php +++ b/src/services/Entries.php @@ -1452,6 +1452,12 @@ private function _createEntryTypeQuery(): Query if ($db->columnExists(Table::ENTRYTYPES, 'color')) { $query->addSelect('color'); } + if ($db->columnExists(Table::ENTRYTYPES, 'showPostDateField')) { + $query->addSelect('showPostDateField'); + } + if ($db->columnExists(Table::ENTRYTYPES, 'showExpiryDateField')) { + $query->addSelect('showExpiryDateField'); + } return $query; } @@ -1677,6 +1683,16 @@ public function handleChangedEntryType(ConfigEvent $event): void $entryTypeRecord->description = $data['description'] ?? null; } + // todo: remove after the next breakpoint + if (Craft::$app->getDb()->columnExists(Table::ENTRYTYPES, 'showPostDateField')) { + $entryTypeRecord->showPostDateField = $data['showPostDateField'] ?? true; + } + + // todo: remove after the next breakpoint + if (Craft::$app->getDb()->columnExists(Table::ENTRYTYPES, 'showExpiryDateField')) { + $entryTypeRecord->showExpiryDateField = $data['showExpiryDateField'] ?? true; + } + if (!empty($data['fieldLayouts'])) { // Save the field layout $layout = FieldLayout::createFromConfig(reset($data['fieldLayouts'])); diff --git a/src/templates/settings/entry-types/_edit.twig b/src/templates/settings/entry-types/_edit.twig index a79bbfec914..8376a76317d 100644 --- a/src/templates/settings/entry-types/_edit.twig +++ b/src/templates/settings/entry-types/_edit.twig @@ -192,6 +192,32 @@ disabled: readOnly, }) }} +{{ forms.lightswitchField({ + label: "Show the Post Date field"|t('app'), + instructions: "Whether to show the Post Date field."|t('app'), + id: 'showPostDateField', + name: 'showPostDateField', + on: entryType.showPostDateField, + errors: entryType.getErrors('showPostDateField'), + data: { + 'error-key': 'showPostDateField', + }, + disabled: readOnly, +}) }} + +{{ forms.lightswitchField({ + label: "Show the Expiry Date field"|t('app'), + instructions: "Whether to show the Expiry Date field."|t('app'), + id: 'showExpiryDateField', + name: 'showExpiryDateField', + on: entryType.showExpiryDateField, + errors: entryType.getErrors('showExpiryDateField'), + data: { + 'error-key': 'showExpiryDateField', + }, + disabled: readOnly, +}) }} +
{{ forms.fieldLayoutDesignerField({ diff --git a/src/translations/en/app.php b/src/translations/en/app.php index 43635c9a284..b8b98eb502f 100644 --- a/src/translations/en/app.php +++ b/src/translations/en/app.php @@ -1531,6 +1531,8 @@ 'Show nav' => 'Show nav', 'Show nested sources' => 'Show nested sources', 'Show sidebar' => 'Show sidebar', + 'Show the Expiry Date field' => 'Show the Expiry Date field', + 'Show the Post Date field' => 'Show the Post Date field', 'Show the Slug field' => 'Show the Slug field', 'Show the Status field' => 'Show the Status field', 'Show the debug toolbar in the control panel' => 'Show the debug toolbar in the control panel', @@ -2059,6 +2061,8 @@ 'Whether to show entries that the user doesn’t have permission to view, per the “View other users’ entries” permission.' => 'Whether to show entries that the user doesn’t have permission to view, per the “View other users’ entries” permission.', 'Whether to show files that the user doesn’t have permission to view, per the “View files uploaded by other users” permission.' => 'Whether to show files that the user doesn’t have permission to view, per the “View files uploaded by other users” permission.', 'Whether to show sections that the user doesn’t have permission to view.' => 'Whether to show sections that the user doesn’t have permission to view.', + 'Whether to show the Expiry Date field.' => 'Whether to show the Expiry Date field.', + 'Whether to show the Post Date field.' => 'Whether to show the Post Date field.', 'Whether to show volumes that the user doesn’t have permission to view.' => 'Whether to show volumes that the user doesn’t have permission to view.', 'Whether validation errors on the related {type} should prevent the source element from being saved.' => 'Whether validation errors on the related {type} should prevent the source element from being saved.', 'Whether {type} elements should be allowed to relate to themselves.' => 'Whether {type} elements should be allowed to relate to themselves.',