Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fields/merge command #15454

Merged
merged 5 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- Entry types created from Matrix block types no longer show the Slug field by default, after upgrading to Craft 5. ([#15379](https://github.com/craftcms/cms/issues/15379))
- Global sets listed within fields’ “Used by” lists now link to their settings page, rather than their edit page. ([#15423](https://github.com/craftcms/cms/discussions/15423))
- Added the `entry-types/merge` command. ([#15444](https://github.com/craftcms/cms/pull/15444))
- Added the `fields/merge` command. ([#15454](https://github.com/craftcms/cms/pull/15454))

### Development
- Added support for application-type based `general` and `db` configs (e.g. `config/general.web.php`). ([#15346](https://github.com/craftcms/cms/pull/15346))
Expand All @@ -51,9 +52,17 @@
- Added `craft\base\ApplicationTrait::getDb2()`. ([#15384](https://github.com/craftcms/cms/pull/15384))
- Added `craft\base\ElementInterface::addInvalidNestedElementIds()`.
- Added `craft\base\ElementInterface::getInvalidNestedElementIds()`.
- Added `craft\base\Field::EVENT_AFTER_MERGE_FROM`.
- Added `craft\base\Field::EVENT_AFTER_MERGE_INTO`.
- Added `craft\base\Field::afterMergeFrom()`. ([#15454](https://github.com/craftcms/cms/pull/15454))
- Added `craft\base\Field::afterMergeInto()`. ([#15454](https://github.com/craftcms/cms/pull/15454))
- Added `craft\base\Field::canMergeFrom()`. ([#15454](https://github.com/craftcms/cms/pull/15454))
- Added `craft\base\Field::canMergeInto()`. ([#15454](https://github.com/craftcms/cms/pull/15454))
- Added `craft\base\FieldLayoutComponent::EVENT_DEFINE_SHOW_IN_FORM`. ([#15260](https://github.com/craftcms/cms/issues/15260))
- Added `craft\base\FieldLayoutElement::$dateAdded`.
- Added `craft\base\FieldTrait::$dateDeleted`.
- Added `craft\base\Grippable`.
- Added `craft\base\MergeableFieldInterface`. ([#15454](https://github.com/craftcms/cms/pull/15454))
- Added `craft\base\RelationFieldInterface`. ([#15400](https://github.com/craftcms/cms/pull/15400))
- Added `craft\base\RelationFieldTrait`. ([#15400](https://github.com/craftcms/cms/pull/15400))
- Added `craft\config\GeneralConfig::addAlias()`. ([#15346](https://github.com/craftcms/cms/pull/15346))
Expand All @@ -80,6 +89,7 @@
- Added `craft\services\Entries::EVENT_AFTER_MOVE_TO_SECTION`.
- Added `craft\services\Entries::EVENT_BEFORE_MOVE_TO_SECTION`.
- Added `craft\services\Entries::moveEntryToSection()`.
- Added `craft\services\Fields::areFieldTypesCompatible()`.
- Added `craft\web\View::clearAssetBundleBuffer()`.
- Added `craft\web\View::startAssetBundleBuffer()`.
- `craft\helpers\DateTimeHelper::toIso8601()` now has a `$setToUtc` argument.
Expand Down Expand Up @@ -110,6 +120,7 @@
- Craft no longer ensures that the `cpresources` folder is writable.
- Front-end queue runner scripts are now injected before the `</body>` tag, rather than at the end of the response HTML.
- Nested entries created for Matrix fields set to inline-editable block mode now begin life as unpublished drafts. ([#15418](https://github.com/craftcms/cms/issues/15418))
- Custom fields are now soft-deleted initially.
- Updated Yii to 2.0.51.
- Updated yii2-debug to 2.1.25.
- Updated svg-sanitizer to 0.19.
Expand Down
76 changes: 76 additions & 0 deletions src/base/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
namespace craft\base;

use Craft;
use craft\db\Table as DbTable;
use craft\elements\db\ElementQueryInterface;
use craft\enums\AttributeStatus;
use craft\events\DefineFieldHtmlEvent;
use craft\events\DefineFieldKeywordsEvent;
use craft\events\FieldElementEvent;
use craft\events\FieldEvent;
use craft\gql\types\QueryArgument;
use craft\helpers\ArrayHelper;
use craft\helpers\DateTimeHelper;
Expand Down Expand Up @@ -127,6 +129,20 @@ abstract class Field extends SavableComponent implements FieldInterface
*/
public const EVENT_DEFINE_INPUT_HTML = 'defineInputHtml';

/**
* @event FieldEvent The event that is triggered after the field has been merged into another.
* @see afterMergeInto()
* @since 5.3.0
*/
public const EVENT_AFTER_MERGE_INTO = 'afterMergeInto';

/**
* @event FieldEvent The event that is triggered after another field has been merged into this one.
* @see afterMergeFrom()
* @since 5.3.0
*/
public const EVENT_AFTER_MERGE_FROM = 'afterMergeFrom';

// Translation methods
// -------------------------------------------------------------------------

Expand Down Expand Up @@ -784,6 +800,66 @@ public function getSortOption(): array
];
}

/**
* Returns whether the field can be merged into the given field.
*
* @param FieldInterface $persistingField
* @param string|null $reason
* @return bool
* @since 5.3.0
*/
public function canMergeInto(FieldInterface $persistingField, ?string &$reason): bool
{
// Go with whether the DB types are compatible by default
return Craft::$app->getFields()->areFieldTypesCompatible(static::class, $persistingField::class);
}

/**
* Returns whether the given field can be merged into this one.
*
* @param FieldInterface $outgoingField
* @param string|null $reason
* @return bool
* @since 5.3.0
*/
public function canMergeFrom(FieldInterface $outgoingField, ?string &$reason): bool
{
// Go with whether the DB types are compatible by default
return Craft::$app->getFields()->areFieldTypesCompatible(static::class, $outgoingField::class);
}

/**
* Performs actions after the field has been merged into the given field.
*
* @param FieldInterface $persistingField
* @since 5.3.0
*/
public function afterMergeInto(FieldInterface $persistingField)
{
// Fire an 'afterMergeInto' event
if ($this->hasEventHandlers(self::EVENT_AFTER_MERGE_INTO)) {
$this->trigger(self::EVENT_AFTER_MERGE_INTO, new FieldEvent(['field' => $persistingField]));
}
}

/**
* Performs actions after the given field has been merged into this one.
*
* @param FieldInterface $outgoingField
* @since 5.3.0
*/
public function afterMergeFrom(FieldInterface $outgoingField)
{
if ($this instanceof RelationalFieldInterface) {
Db::update(DbTable::RELATIONS, ['fieldId' => $this->id], ['fieldId' => $outgoingField->id]);
}

// Fire an 'afterMergeFrom' event
if ($this->hasEventHandlers(self::EVENT_AFTER_MERGE_FROM)) {
$this->trigger(self::EVENT_AFTER_MERGE_FROM, new FieldEvent(['field' => $outgoingField]));
}
}

/**
* @inheritdoc
*/
Expand Down
7 changes: 7 additions & 0 deletions src/base/FieldTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace craft\base;

use craft\fieldlayoutelements\CustomField;
use DateTime;

/**
* FieldTrait implements the common methods and properties for field classes.
Expand Down Expand Up @@ -89,6 +90,12 @@ trait FieldTrait
*/
public ?bool $required = null;

/**
* @var DateTime|null The date that the field was trashed
* @since 5.3.0
*/
public ?DateTime $dateDeleted = null;

/**
* @var CustomField|null The field layout element
* @since 5.0.0
Expand Down
51 changes: 51 additions & 0 deletions src/base/MergeableFieldInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\base;

/**
* MergeableFieldInterface defines the common interface to be implemented by field classes
* that can be merged with other fields.
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 5.3.0
* @mixin Field
*/
interface MergeableFieldInterface extends FieldInterface
{
/**
* Returns whether the field can be merged into the given field.
*
* @param FieldInterface $persistingField
* @param string|null $reason
* @return bool
*/
public function canMergeInto(FieldInterface $persistingField, ?string &$reason): bool;

/**
* Returns whether the given field can be merged into this one.
*
* @param FieldInterface $outgoingField
* @param string|null $reason
* @return bool
*/
public function canMergeFrom(FieldInterface $outgoingField, ?string &$reason): bool;

/**
* Performs actions after the field has been merged into the given field.
*
* @param FieldInterface $persistingField
*/
public function afterMergeInto(FieldInterface $persistingField);

/**
* Performs actions after the given field has been merged into this one.
*
* @param FieldInterface $outgoingField
*/
public function afterMergeFrom(FieldInterface $outgoingField);
}
2 changes: 1 addition & 1 deletion src/config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'id' => 'CraftCMS',
'name' => 'Craft CMS',
'version' => '5.2.9',
'schemaVersion' => '5.3.0.0',
'schemaVersion' => '5.3.0.1',
'minVersionRequired' => '4.5.0',
'basePath' => dirname(__DIR__), // Defines the @app alias
'runtimePath' => '@storage/runtime', // Defines the @runtime alias
Expand Down
Loading