-
Notifications
You must be signed in to change notification settings - Fork 64
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
This plugin is no longer maintained. #286
Comments
You won't be able to upgrade to Craft 5. |
That's unlikely, you'll need to convert it to something else. V1 of the Hyper (a link field) plugin has the ability to migrate from this plugin https://verbb.io/craft-plugins/hyper/docs/v1/guides/migrating-from-typed-link |
@sebastian-lenz Is the 3.0.0-beta release tested? |
We've been facing the same challenge with the now-unmaintained Typed Link Field module. As Craft 5.3 now provides a native Link Field, we decided to migrate to it. Here’s how we approached it:
Here’s the migration code we used (stored in <?php
namespace craft\contentmigrations;
use Craft;
use craft\base\ElementInterface;
use craft\base\FieldInterface;
use craft\db\Migration;
use craft\db\Query;
use craft\db\Table;
use craft\fields\Link;
use craft\helpers\Db;
use craft\helpers\Json;
use craft\helpers\StringHelper;
/**
* m250102_202812_typed_link_field_to_craft_link_field migration.
*/
class m250102_202812_typed_link_field_to_craft_link_field extends Migration
{
public array $allowedTypes = [
'asset',
'email',
'entry',
'url',
];
/**
* @inheritdoc
*/
public function safeUp(): bool
{
$fieldService = Craft::$app->getFields();
$fields = (new Query())
->from('{{%fields}}')
->where(['type' => Link::class])
->all();
foreach ($fields as $field) {
echo "Preparing to migrate field “{$field['handle']}” ({$field['uid']}) content.\n";
$fieldModel = Craft::$app->getFields()->getFieldById($field['id']);
if ($fieldModel) {
$contentRows = (new Query())
->select(['*'])
->from('{{%lenz_linkfield}}')
->where(['fieldId' => $fieldModel['id']])
->all();
if ($fieldModel->context === 'global') {
foreach ($contentRows as $row) {
$settings = $this->convertLinkContent($fieldModel, $row);
$element = Craft::$app->getElements()->getElementById($row['elementId'], null, $row['siteId']);
if ($element) {
if ($settings) {
$newContent = $this->getElementContentForField($element, $fieldModel, $settings);
Db::update('{{%elements_sites}}', ['content' => $newContent], ['elementId' => $row['elementId'], 'siteId' => $row['siteId']]);
echo " > Migrated content for element #{$row['elementId']}\n";
} else {
if ($settings !== null) {
echo " > Unable to convert content for element #{$row['elementId']}\n";
}
}
} else {
echo " > Unable to find element #{$row['elementId']} and site #{$row['siteId']}\n";
}
}
}
}
echo "> Field “{$field['handle']}” content migrated.\n\n";
}
return true;
}
/**
* @inheritdoc
*/
public function safeDown(): bool
{
echo "m250102_202812_typed_link_field_to_craft_link_field cannot be reverted.\n";
return false;
}
public function convertLinkContent($field, array $settings): bool|array|null
{
$linkType = $settings['type'] ?? null;
if (!$linkType) {
return null;
}
if (!in_array($linkType, $this->allowedTypes)) {
return false;
}
$advanced = Json::decode($settings['payload']);
$linkValue = $settings['linkedUrl'] ?? null;
$linkText = $advanced['customText'] ?? null;
$linkSiteId = $settings['siteId'] ?? null;
$linkId = $settings['linkedId'] ?? null;
if (($linkType === 'entry' || $linkType === 'asset') && (!$linkId || !$linkSiteId)) {
return false;
}
if ($linkType === 'entry') {
$linkValue = "{entry:{$linkId}@{$linkSiteId}:url}";
} else if ($linkType === 'asset') {
$linkValue = "{asset:{$linkId}@{$linkSiteId}:url}";
} else if ($linkType === 'email') {
$linkValue = 'mailto:' . $linkValue;
}
return [
'value' => $linkValue,
'type' => $linkType,
'label' => $linkText,
'target' => null,
];
}
// From:
// https://github.com/verbb/hyper/blob/craft-5/src/migrations/PluginContentMigration.php#L141
protected function getElementContentForField(ElementInterface $element, FieldInterface $field, array $fieldValue): array
{
$fieldContent = [];
// Get the field content as JSON, indexed by field layout element UID
if ($fieldLayout = $element->getFieldLayout()) {
foreach ($fieldLayout->getCustomFields() as $fieldLayoutField) {
$sourceHandle = $fieldLayoutField->layoutElement?->getOriginalHandle() ?? $fieldLayoutField->handle;
if ($field->handle === $sourceHandle) {
$fieldContent[$fieldLayoutField->layoutElement->uid] = $fieldValue;
}
}
}
// Fetch the current JSON content so we can merge in the new field content
$oldContent = Json::decode((new Query())
->select(['content'])
->from('{{%elements_sites}}')
->where(['elementId' => $element->id, 'siteId' => $element->siteId])
->scalar() ?? '') ?? [];
// Another sanity check just in cases where content is double encoded
if (is_string($oldContent) && Json::isJsonObject($oldContent)) {
$oldContent = Json::decode($oldContent);
}
return array_merge($oldContent, $fieldContent);
}
}
|
Here's an updated version of the above which also migrates the link field settings:
It can certainly be improved, for example, I have just hard coded $nativeFieldSettings array based on what the CURRENT defaults are, rather than getting the actual defaults from craft\fields\Link, so if P&T tweak the defaults, this migration will be off. This is also hot off the press, and we are just testing our various link field settings now to ensure the settings are migrated properly. If anybody finds any issues with this, please let me know. |
When I check for updates in Craft CMS, the plugin 'craft-linkfield' indicates that it is no longer maintained, but its features are still working fine. Will this affect my site? If I upgrade to Craft CMS 5, will it still work, and if I deactivate this plugin, will its features still work?
Craft Cms version: 4.10.4

Typed-link-field version: 2.1.5
The text was updated successfully, but these errors were encountered: