diff --git a/src/Plugin.php b/src/Plugin.php index 8ad03cc5a4..a3cb94b187 100755 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -257,7 +257,7 @@ public static function editions(): array /** * @inheritDoc */ - public string $schemaVersion = '5.4.0.5'; + public string $schemaVersion = '5.5.0'; /** * @inheritdoc diff --git a/src/controllers/ProductTypesController.php b/src/controllers/ProductTypesController.php index 718f2b6266..698ebc01fa 100644 --- a/src/controllers/ProductTypesController.php +++ b/src/controllers/ProductTypesController.php @@ -137,6 +137,9 @@ public function actionSaveProductType(): void $productType->productTitleFormat = $this->request->getBodyParam('productTitleFormat'); $productType->productTitleTranslationMethod = $this->request->getBodyParam('productTitleTranslationMethod', $productType->productTitleTranslationMethod); $productType->productTitleTranslationKeyFormat = $this->request->getBodyParam('productTitleTranslationKeyFormat', $productType->productTitleTranslationKeyFormat); + $productType->showSlugField = (bool)$this->request->getBodyParam('showSlugField', $productType->showSlugField); + $productType->slugTranslationMethod = $this->request->getBodyParam('slugTranslationMethod', $productType->slugTranslationMethod); + $productType->slugTranslationKeyFormat = $this->request->getBodyParam('slugTranslationKeyFormat', $productType->slugTranslationKeyFormat); $productType->maxVariants = $this->request->getBodyParam('maxVariants') ?: null; $productType->hasVariantTitleField = $this->request->getBodyParam('hasVariantTitleField', false); $productType->variantTitleFormat = $this->request->getBodyParam('variantTitleFormat'); diff --git a/src/elements/Product.php b/src/elements/Product.php index 16be909ac4..cff28d5c1c 100644 --- a/src/elements/Product.php +++ b/src/elements/Product.php @@ -862,6 +862,31 @@ public function getTitleTranslationKey(): string return ElementHelper::translationKey($this, $type->productTitleTranslationMethod, $type->productTitleTranslationKeyFormat); } + /** + * @inheritdoc + */ + public function getIsSlugTranslatable(): bool + { + return ($this->getType()->slugTranslationMethod !== Field::TRANSLATION_METHOD_NONE); + } + + /** + * @inheritdoc + */ + public function getSlugTranslationDescription(): ?string + { + return ElementHelper::translationDescription($this->getType()->slugTranslationMethod); + } + + /** + * @inheritdoc + */ + public function getSlugTranslationKey(): string + { + $type = $this->getType(); + return ElementHelper::translationKey($this, $type->slugTranslationMethod, $type->slugTranslationKeyFormat); + } + /** * @inheritdoc */ @@ -1373,7 +1398,9 @@ protected function metaFieldsHtml(bool $static): string $view = Craft::$app->getView(); $productType = $this->getType(); // Slug - $fields[] = $this->slugFieldHtml($static); + if ($productType->showSlugField) { + $fields[] = $this->slugFieldHtml($static); + } if ($productType->isStructure && $productType->maxLevels !== 1) { $fields[] = (function() use ($static, $productType) { diff --git a/src/migrations/m250731_020627_add_slug_options_to_product_types.php b/src/migrations/m250731_020627_add_slug_options_to_product_types.php new file mode 100644 index 0000000000..ad4f23c96a --- /dev/null +++ b/src/migrations/m250731_020627_add_slug_options_to_product_types.php @@ -0,0 +1,43 @@ +db->columnExists(Table::PRODUCTTYPES, 'showSlugField')) { + $this->addColumn(Table::PRODUCTTYPES, 'showSlugField', $this->boolean()->notNull()->defaultValue(true)->after('productTitleTranslationKeyFormat')); + } + + // Add slugTranslationMethod column + if (!$this->db->columnExists(Table::PRODUCTTYPES, 'slugTranslationMethod')) { + $this->addColumn(Table::PRODUCTTYPES, 'slugTranslationMethod', $this->string()->notNull()->defaultValue('site')->after('showSlugField')); + } + + // Add slugTranslationKeyFormat column + if (!$this->db->columnExists(Table::PRODUCTTYPES, 'slugTranslationKeyFormat')) { + $this->addColumn(Table::PRODUCTTYPES, 'slugTranslationKeyFormat', $this->string()->after('slugTranslationMethod')); + } + + return true; + } + + /** + * @inheritdoc + */ + public function safeDown(): bool + { + return true; + } +} \ No newline at end of file diff --git a/src/models/ProductType.php b/src/models/ProductType.php index 841fb37a9e..5d4a2f7f19 100644 --- a/src/models/ProductType.php +++ b/src/models/ProductType.php @@ -131,6 +131,25 @@ class ProductType extends Model implements FieldLayoutProviderInterface */ public ?string $productTitleTranslationKeyFormat = null; + /** + * @var bool Whether to show the Slug field + * @since 5.3.0 + */ + public bool $showSlugField = true; + + /** + * @var string Slug translation method + * @phpstan-var Field::TRANSLATION_METHOD_NONE|Field::TRANSLATION_METHOD_SITE|Field::TRANSLATION_METHOD_SITE_GROUP|Field::TRANSLATION_METHOD_LANGUAGE|Field::TRANSLATION_METHOD_CUSTOM + * @since 5.3.0 + */ + public string $slugTranslationMethod = Field::TRANSLATION_METHOD_SITE; + + /** + * @var string|null Slug translation key format + * @since 5.3.0 + */ + public ?string $slugTranslationKeyFormat = null; + /** * @var string|null SKU format */ @@ -216,6 +235,26 @@ class ProductType extends Model implements FieldLayoutProviderInterface */ public PropagationMethod $propagationMethod = PropagationMethod::All; + /** + * @inheritdoc + */ + public function init(): void + { + parent::init(); + + if ($this->productTitleTranslationKeyFormat === '') { + $this->productTitleTranslationKeyFormat = null; + } + + if ($this->variantTitleTranslationKeyFormat === '') { + $this->variantTitleTranslationKeyFormat = null; + } + + if ($this->slugTranslationKeyFormat === '') { + $this->slugTranslationKeyFormat = null; + } + } + /** * @return null|string */ @@ -589,6 +628,11 @@ public function getConfig(): array 'productTitleTranslationMethod' => $this->productTitleTranslationMethod, 'productTitleTranslationKeyFormat' => $this->productTitleTranslationKeyFormat, + // Slug field + 'showSlugField' => $this->showSlugField, + 'slugTranslationMethod' => $this->slugTranslationMethod, + 'slugTranslationKeyFormat' => $this->slugTranslationKeyFormat, + 'propagationMethod' => $this->propagationMethod->value, 'skuFormat' => $this->skuFormat, diff --git a/src/records/ProductType.php b/src/records/ProductType.php index d229ce391a..a420f017fa 100644 --- a/src/records/ProductType.php +++ b/src/records/ProductType.php @@ -37,6 +37,9 @@ * @property string $productTitleFormat * @property string $productTitleTranslationMethod * @property string $productTitleTranslationKeyFormat + * @property bool $showSlugField + * @property string $slugTranslationMethod + * @property string $slugTranslationKeyFormat * @property string $propagationMethod * @property ActiveQueryInterface $variantFieldLayout * @property int|null $variantFieldLayoutId diff --git a/src/services/ProductTypes.php b/src/services/ProductTypes.php index a0e0ff2bf9..c5ed52cb2b 100755 --- a/src/services/ProductTypes.php +++ b/src/services/ProductTypes.php @@ -419,6 +419,11 @@ public function handleChangedProductType(ConfigEvent $event): void $productTypeRecord->productTitleFormat = $productTitleFormat; $productTypeRecord->hasProductTitleField = $hasProductTitleField; + // Slug fields + $productTypeRecord->showSlugField = $data['showSlugField'] ?? true; + $productTypeRecord->slugTranslationMethod = $data['slugTranslationMethod'] ?? 'site'; + $productTypeRecord->slugTranslationKeyFormat = $data['slugTranslationKeyFormat'] ?? ''; + if ($productTypeRecord->maxVariants != $data['maxVariants']) { $shouldResaveProducts = true; } @@ -961,6 +966,21 @@ private function _createProductTypeQuery(): Query $query->addSelect('productTypes.propagationMethod'); } + /** @since 5.3 */ + if ($db->columnExists(Table::PRODUCTTYPES, 'showSlugField')) { + $query->addSelect('productTypes.showSlugField'); + } + + /** @since 5.3 */ + if ($db->columnExists(Table::PRODUCTTYPES, 'slugTranslationMethod')) { + $query->addSelect('productTypes.slugTranslationMethod'); + } + + /** @since 5.3 */ + if ($db->columnExists(Table::PRODUCTTYPES, 'slugTranslationKeyFormat')) { + $query->addSelect('productTypes.slugTranslationKeyFormat'); + } + return $query; } diff --git a/src/templates/settings/producttypes/_edit.twig b/src/templates/settings/producttypes/_edit.twig index 28db8cefa1..98cbcda34c 100644 --- a/src/templates/settings/producttypes/_edit.twig +++ b/src/templates/settings/producttypes/_edit.twig @@ -191,7 +191,66 @@ {% endmacro %} - {% from _self import variantTitleFormatField, productTitleFormatField, uriFormatText %} + {% macro productSlugField(productType, disabled) %} + {% import '_includes/forms' as forms %} + + {{ forms.lightswitchField({ + label: "Show the Slug field"|t('app'), + name: 'showSlugField', + toggle: 'slug-container', + reverseToggle: '#slugFormat-container, #field-layout .fld-slug-field-icon', + on: productType.showSlugField, + disabled: disabled, + }) }} + + {% if craft.app.getIsMultiSite() %} + + {% endif %} + + {% endmacro %} + + {% from _self import variantTitleFormatField, productTitleFormatField, uriFormatText, productSlugField %} {{ forms.textField({ @@ -264,6 +323,7 @@ }) }} {{ productTitleFormatField(productType, readOnly) }} + {{ productSlugField(productType, readOnly) }} {{ forms.textField({ label: "Automatic SKU Format"|t('commerce'),