Optimizely Forms for CMS 12 での FormContainerBlock タイプの変換

1711436006
2024-03-24 00:00:00

これは一般的に行うことではありませんが、私が行った方法は次のとおりです。 FormContainerBlock 私たちのカスタムに合わせて入力します ExtendedFormContainerBlock Optimizely Forms for CMS 12 の場合。カスタム プロパティまたは機能を標準に追加する場合は、これを実行する必要がある場合があります。 FormContainerBlock タイプを選択し、以前に作成したすべてのフォームを再構築または再作成したくない場合。

免責事項

このコードは概念実証として扱ってください。 本番環境に対応していないものとして扱います。 これを基礎として構築するための出発点として使用する必要があります。 データが失われる可能性があります。 データベースをバックアップします。 ローカルで複数回テストします。 ステージング環境でテストします。 もう一度テストしてください。 そしてもう一度テストしてみます。 私のマシンでは動作します。 あなたのものでは機能しないかもしれません。

FormContainerBlock の変換

このアプローチでは、スケジュールされたジョブを使用してコードを実行しました。 こうすることで、ジョブを 1 回実行し、変換が完了したらジョブを削除できます。

コードを見ると、更新していることがわかります。 tblContenttblContentProperty、 そして tblWorkContentProperty テーブルに直接アクセスできます。 明らかに、直接 SQL コマンドを実行することはお勧めできませんが、Optimizely が提供する API を使用する以外にこれを実行するより良い方法はありません。

私が作成したスケジュールされたジョブは次のとおりです。

[ScheduledPlugIn(DisplayName = "Convert FormContainerBlocks", GUID = "00000000-0000-0000-0000-000000000000", Description = "Converts all FormContainerBlock instances to ExtendedFormContainerBlock.")]
public class ConvertFormContainerBlocksScheduledJob : ScheduledJobBase
{
	private readonly IConfiguration _configuration;
	private readonly IContentTypeRepository _contentTypeRepository;
	private readonly IContentModelUsage _contentModelUsage;
	private readonly IContentVersionRepository _contentVersionRepository;
	private readonly IPropertyDefinitionRepository _propertyDefinitionRepository;
	private readonly IContentRepository _contentRepository;

	private bool _stopSignaled;

	public ConvertFormContainerBlocksScheduledJob(
		IConfiguration configuration,
		IContentTypeRepository contentTypeRepository,
		IContentModelUsage contentModelUsage,
		IPropertyDefinitionRepository propertyDefinitionRepository,
		IContentRepository contentRepository,
		IContentVersionRepository contentVersionRepository)
    {
        _configuration = configuration;
        _contentTypeRepository = contentTypeRepository;
        _contentModelUsage = contentModelUsage;
        _propertyDefinitionRepository = propertyDefinitionRepository;
        _contentRepository = contentRepository;
        _contentVersionRepository = contentVersionRepository;

        IsStoppable = true;
    }

    
    
    
    public override void Stop()
    {
        _stopSignaled = true;
    }

    
    
    
    
    public override string Execute()
    {
        
        OnStatusChanged($"Starting execution of {GetType()}");

        
        throw new Exception("Don't run untested code");

        var formContainersContentLinks = GetFormContainerContentLinks();

        if (formContainersContentLinks == null || !formContainersContentLinks.Any())
        {
            return "No FormContainerBlocks found";
        }

        OnStatusChanged($"Found {formContainersContentLinks.Count()} FormContainerBlocks");

        var connectionString = _configuration.GetConnectionString("EPiServerDB");
        var extendedFormContainerBlockContentType = _contentTypeRepository.Load<ExtendedFormContainerBlock>();

        int total = formContainersContentLinks.Count();
        int succeeded = 0;
        int failed = 0;

        foreach (var contentLink in formContainersContentLinks)
        {
            OnStatusChanged($"Converting FormContainerBlock with ID {contentLink.ID}");

            var fcbInstance = _contentRepository.Get<FormContainerBlock>(contentLink);

            var fcbContentType = _contentTypeRepository.Load<FormContainerBlock>();
            var efcbContentType = _contentTypeRepository.Load<ExtendedFormContainerBlock>();

            var fcbPropertyDefinitionList = _propertyDefinitionRepository.List(fcbContentType.ID);
            var efcbPropertyDefinitionList = _propertyDefinitionRepository.List(efcbContentType.ID);

            try
            {
                using var connection = new SqlConnection(connectionString);

                connection.Open();

                using var updateContentCommand = new SqlCommand("UPDATE tblContent SET fkContentTypeID = @ContentTypeID WHERE pkID = @ContentLinkID", connection);

                updateContentCommand.Parameters.AddWithValue("@ContentTypeID", extendedFormContainerBlockContentType.ID);
                updateContentCommand.Parameters.AddWithValue("@ContentLinkID", contentLink.ID);

                updateContentCommand.ExecuteNonQuery();
                updateContentCommand.Dispose();

                foreach (var propertyDefinition in fcbPropertyDefinitionList)
                {
                    var newPropertyDefinition = efcbPropertyDefinitionList.FirstOrDefault(pd => pd.Name == propertyDefinition.Name);

                    if (newPropertyDefinition == null)
                    {
                        continue;
                    }

                    using var updatePropertyCommand = new SqlCommand("UPDATE tblContentProperty SET fkPropertyDefinitionID = @NewPropertyDefinitionId WHERE fkPropertyDefinitionID = @OldPropertyDefinitionId AND fkContentID = @ContentLinkId", connection);

                    updatePropertyCommand.Parameters.AddWithValue("@NewPropertyDefinitionId", newPropertyDefinition.ID);
                    updatePropertyCommand.Parameters.AddWithValue("@OldPropertyDefinitionId", propertyDefinition.ID);
                    updatePropertyCommand.Parameters.AddWithValue("@ContentLinkID", contentLink.ID);

                    updatePropertyCommand.ExecuteNonQuery();
                    updatePropertyCommand.Dispose();

                    var versions = _contentVersionRepository.List(contentLink);

                    foreach (var version in versions)
                    {
                        using var updateWorkPropertyCommand = new SqlCommand("UPDATE tblWorkContentProperty SET fkPropertyDefinitionID = @NewPropertyDefinitionId WHERE fkPropertyDefinitionID = @OldPropertyDefinitionId AND fkWorkContentID = @WorkContentLinkId", connection);

                        updateWorkPropertyCommand.Parameters.AddWithValue("@NewPropertyDefinitionId", newPropertyDefinition.ID);
                        updateWorkPropertyCommand.Parameters.AddWithValue("@OldPropertyDefinitionId", propertyDefinition.ID);
                        updateWorkPropertyCommand.Parameters.AddWithValue("@WorkContentLinkID", version.ContentLink.WorkID);

                        updateWorkPropertyCommand.ExecuteNonQuery();
                        updateWorkPropertyCommand.Dispose();
                    }
                }

                OnStatusChanged($"Converted FormContainerBlock with ID {contentLink.ID}");

                succeeded++;
            }
            catch (Exception ex)
            {
                
                OnStatusChanged($"Failed to convert FormContainerBlock with ID {contentLink.ID} - {ex.Message}");

                failed++;
            }

            

            if (_stopSignaled)
            {
                return $"Stop of job was called. Found {total} FormContainerBlocks. Converting {succeeded} succeeded, {failed} failed.";
            }
        }

        return $"Job completed. Found {total} FormContainerBlocks. Converting {succeeded} succeeded, {failed} failed.";
    }

    private IEnumerable<ContentReference> GetFormContainerContentLinks()
    {
        var formContainerBlockContentType = _contentTypeRepository.Load<FormContainerBlock>();

        if (formContainerBlockContentType == null)
        {
            return Enumerable.Empty<ContentReference>();
        }

        var formContainerBlockUsage = _contentModelUsage.ListContentOfContentType(formContainerBlockContentType);

        if (formContainerBlockUsage == null || !formContainerBlockUsage.Any())
        {
            return Enumerable.Empty<ContentReference>();
        }

        return formContainerBlockUsage.DistinctBy(usage => usage.ContentLink.ID).Select(usage => usage.ContentLink);
    }
}

このコードを実稼働環境で実行する前に複数回テストする必要があると言いましたか? やった? 良い。

#Optimizely #Forms #CMS #での #FormContainerBlock #タイプの変換

Related News

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent News

Editor's Pick