Wprdpressからdrupal 8(pathauto module enabled)への用語とノードの移行があります。移行テンプレートのURLエイリアスを次のように設定します:
process:
path/alias: source_path
path/pathauto:
plugin: default_value
default_value: 0
そのようにパスを設定すると、drush mi term
を使用してコンテンツをインポートするときにうまく機能します。しかし、用語をdrush mi term --update
で更新すると、新しい(同じ)パスがurl_aliasテーブルに挿入されます。たとえば、tid 1の用語は1回インポートされ、2回更新されます。url_aliasテーブルには次のエイリアスがあります。
select * from url_alias where source = '/taxonomy/term/1';
+------+------------------+---------------+----------+
| pid | source | alias | langcode |
+------+------------------+---------------+----------+
| 1514 | /taxonomy/term/1 | /term-1-alias | de |
| 2731 | /taxonomy/term/1 | /term-1-alias | de |
| 3632 | /taxonomy/term/1 | /term-1-alias | de |
+------+------------------+---------------+----------+
ところで、pathautoモジュールを有効にしていますが、アンインストールしても同じ動作になります。
コアパスモジュールのバグのようです: https://www.drupal.org/node/2350135
この問題を回避するために、次の回避策を講じました。
$ value /ノードの組み合わせに対してurl_aliasレコードがすでに挿入されているかどうかをチェックするカスタムプロセスプラグインを作成します。そうであればNULLを返し、そうでなければ$ valueを返します。
<?php
/**
* @file
* Contains \Drupal\your_migrate_module\Plugin\migrate\process\EmptyIfUrlAliasExists.
*
*/
namespace Drupal\your_migrate_module\Plugin\migrate\process;
use Drupal\Core\Database\Database;
use Drupal\migrate\Annotation\MigrateProcessPlugin;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* This process plugin can be used for path/alias fields as long as the following issues are not resolved. It is a workaround for:
*
* https://www.drupal.org/node/2350135#comment-9476629
* https://drupal.stackexchange.com/questions/238393/migrate-duplicate-entries-in-url-alias-after-update-migrations)
*
* @MigrateProcessPlugin(
* id = "empty_if_url_alias_exists",
* )
*/
class EmptyIfUrlAliasExists extends ProcessPluginBase
{
/**
* {@inheritdoc}
*/
public function transform(
$value,
MigrateExecutableInterface $migrate_executable,
Row $row,
$destination_property
) {
// Retrieves a \Drupal\Core\Database\Connection which is a PDO instance
$db = Database::getConnection();
$sth = $db->select('url_alias', 'u')
->fields('u', ['pid']);
$and = $sth->andConditionGroup()
->condition('u.source', '/node/' . $row->getIdMap()['destid1'])
->condition('u.alias', $value);
$sth->condition($and);
$data = $sth->execute();
$results = $data->fetch(\PDO::FETCH_NUM);
//when no url_alias record found, return the url, so it can be added.
if ($results === false || count($results) === 0) {
return $value;
}
//when an url_alias record is already present, return null, so the migration does not add it again
return null;
}
}
次に、ノード移行ymlのプロセス部分で、以下を使用します。
process:
'path/pathauto':
plugin: default_value
default_value: 0 # Disable pathauto.
'path/alias':
-
plugin: empty_if_url_alias_exists
source: public_url
-
plugin: skip_on_empty
method: process